/* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.addthis.hydra.data.query.source; import java.io.File; import java.util.Iterator; import java.util.Map; import java.nio.file.PathMatcher; import com.addthis.basis.util.Parameter; import com.addthis.meshy.VirtualFileFilter; import com.addthis.meshy.VirtualFileInput; import com.addthis.meshy.VirtualFileReference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.netty.channel.DefaultChannelProgressivePromise; import io.netty.util.concurrent.ImmediateEventExecutor; /** * virtualizes queries * <p/> * This class's getInput method is the main entry point for all queries to this mqworker. It is the first class in the three * step query process. * <p/> * By virtualizes queries, we mean that it performs queries and gets a response in a way that meshy can understand. As the * class is named 'MeshQuerySource', this makes sense. As the primary class and entry point for mq worker function, it might be * worth this explanation to prevent any confusion. */ class QueryReference implements VirtualFileReference { private static final Logger log = LoggerFactory.getLogger(QueryReference.class); static final String queryRoot = Parameter.value("mesh.query.root", "query"); //File that contains the next parent id to be assigned in the query tree, but this parameter does not // actually control that. private static final String queryReferenceFileName = Parameter.value("meshQuerySource.queryReferenceFile", "nextID"); final File dir; final String dirString; final File queryReferenceFile; QueryReference(final File dir) { try { this.dir = dir.getCanonicalFile(); this.dirString = dir.toString(); queryReferenceFile = new File(dir, queryReferenceFileName); } catch (Exception ex) { throw new RuntimeException(ex); } } @Override public String toString() { return dirString; } @Override public String getName() { return queryRoot; } @Override public long getLastModified() { return queryReferenceFile.lastModified(); } @Override public long getLength() { return queryReferenceFile.length(); } @Override public Iterator<VirtualFileReference> listFiles(PathMatcher filter) { return null; } @Override public VirtualFileReference getFile(String name) { return null; } /** * Submits the query to the query search pool as a SearchRunner and creates the bridge that will * hand the query response data to meshy. * * @param options * @return the response bridge (DataChannelToInputStream) */ @Override public VirtualFileInput getInput(Map<String, String> options) { try { // ideally the channel here would be some kind of meshy construct, but null should // be fine for now -- we never call await/sync etc in the worker final DataChannelToInputStream bridge = new DataChannelToInputStream( new DefaultChannelProgressivePromise(null, ImmediateEventExecutor.INSTANCE)); if (options == null) { log.warn("Invalid request to getInput. Options cannot be null"); return null; } final String flag = options.get("flag"); if (flag != null) { if (flag.equals("die")) { System.exit(1); } else if (flag.equals("DIE")) { Runtime.getRuntime().halt(1); } } SearchRunner.querySearchPool.execute(new SearchRunner(options, dirString, bridge)); return bridge; } catch (Exception ex) { throw new RuntimeException(ex); } } }