summaryrefslogtreecommitdiffstats
path: root/vespaclient-java/src/main/java/com/yahoo/vespavisit/VdsVisitTarget.java
diff options
context:
space:
mode:
Diffstat (limited to 'vespaclient-java/src/main/java/com/yahoo/vespavisit/VdsVisitTarget.java')
-rw-r--r--vespaclient-java/src/main/java/com/yahoo/vespavisit/VdsVisitTarget.java286
1 files changed, 286 insertions, 0 deletions
diff --git a/vespaclient-java/src/main/java/com/yahoo/vespavisit/VdsVisitTarget.java b/vespaclient-java/src/main/java/com/yahoo/vespavisit/VdsVisitTarget.java
new file mode 100644
index 00000000000..3ef0619cfd8
--- /dev/null
+++ b/vespaclient-java/src/main/java/com/yahoo/vespavisit/VdsVisitTarget.java
@@ -0,0 +1,286 @@
+// Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespavisit;
+
+import com.yahoo.documentapi.DocumentAccess;
+import com.yahoo.documentapi.VisitorControlHandler;
+import com.yahoo.documentapi.VisitorDataHandler;
+import com.yahoo.documentapi.VisitorDestinationParameters;
+import com.yahoo.documentapi.VisitorDestinationSession;
+import com.yahoo.documentapi.messagebus.MessageBusDocumentAccess;
+import com.yahoo.documentapi.messagebus.MessageBusParams;
+import com.yahoo.documentapi.messagebus.loadtypes.LoadTypeSet;
+import com.yahoo.log.LogLevel;
+import com.yahoo.log.LogSetup;
+import com.yahoo.messagebus.network.Identity;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+
+import java.lang.reflect.Constructor;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.logging.Logger;
+
+/**
+ * Example client using visiting
+ *
+ * @author <a href="mailto:einarmr@yahoo-inc.com">Einar M R Rosenvinge</a>, based on work by <a href="mailto:humbe@yahoo-inc.com">H&aring;kon Humberset</a>
+ */
+public class VdsVisitTarget {
+ private static final Logger log = Logger.getLogger(VdsVisitTarget.class.getName());
+
+ private boolean printIds = false;
+ DocumentAccess access;
+ VisitorDestinationSession session;
+ String slobrokAddress = null;
+ int port = -1;
+ private boolean verbose = false;
+ private int processTime = 0;
+ private String handlerClassName = StdOutVisitorHandler.class.getName();
+ private String[] handlerArgs = null;
+
+ public boolean isPrintIds() {
+ return printIds;
+ }
+
+ public String getSlobrokAddress() {
+ return slobrokAddress;
+ }
+
+ public boolean isVerbose() {
+ return verbose;
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ public int getProcessTime() {
+ return processTime;
+ }
+
+ public String getHandlerClassName() {
+ return handlerClassName;
+ }
+
+ public String[] getHandlerArgs() {
+ return handlerArgs;
+ }
+
+ public static void main(String args[]) {
+ LogSetup.initVespaLogging("vespavisittarget");
+ VdsVisitTarget visitTarget = new VdsVisitTarget();
+
+
+ try {
+ visitTarget.parseArguments(args);
+ visitTarget.initShutdownHook();
+ visitTarget.run();
+ System.exit(0);
+ } catch (HelpShownException e) {
+ System.exit(0);
+ } catch (IllegalArgumentException e) {
+ System.err.println(e.getMessage());
+ System.exit(1);
+ } catch (org.apache.commons.cli.ParseException e) {
+ System.err.println("Failed to parse arguments. Try --help for syntax. " + e.getMessage());
+ System.exit(1);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static Options createOptions() {
+ Options options = new Options();
+
+ options.addOption("h", "help", false, "Show this syntax page.");
+
+ options.addOption(Option.builder("s")
+ .longOpt("bindtoslobrok")
+ .hasArg(true)
+ .argName("address")
+ .desc("Bind to the given slobrok address.")
+ .build());
+
+ options.addOption(Option.builder("t")
+ .longOpt("bindtosocket")
+ .hasArg(true)
+ .argName("port")
+ .desc("Bind to the given TCP port")
+ .type(Number.class)
+ .build());
+
+ options.addOption(Option.builder("p")
+ .longOpt("processtime")
+ .hasArg(true)
+ .argName("msecs")
+ .desc("Sleep this amount of millisecs before processing message. (Debug option for pretending to be slow client).")
+ .type(Number.class)
+ .build());
+
+ options.addOption(Option.builder("c")
+ .longOpt("visithandler")
+ .hasArg(true)
+ .argName("classname")
+ .desc("Use the given class as a visit handler (defaults to StdOutVisitorHandler)")
+ .build());
+
+ options.addOption(Option.builder("o")
+ .longOpt("visitoptions")
+ .hasArg(true)
+ .argName("args")
+ .desc("Option arguments to pass through to the visitor handler instance")
+ .build());
+
+ options.addOption("i", "printids", false, "Display only document identifiers.");
+ options.addOption("v", "verbose", false, "Indent XML, show progress and info on STDERR.");
+
+ return options;
+ }
+
+ private void printSyntax(Options options) {
+ HelpFormatter formatter = new HelpFormatter();
+ formatter.printHelp("vespavisittarget <options>", "Retrieve results from a visitor", options ,
+ "One, and only one, of the binding options must be present.\n" +
+ "\n" +
+ "For more detailed information, such as defaults and format of\n" +
+ "arguments, refer to 'man vespavisittarget'.\n");
+ }
+
+ class HelpShownException extends Exception {}
+
+ void parseArguments(String args[]) throws ParseException, HelpShownException {
+ Options options = createOptions();
+
+ CommandLineParser parser = new DefaultParser();
+ CommandLine line = parser.parse(options, args);
+
+ if (line.hasOption("h")) {
+ printSyntax(options);
+ throw new HelpShownException();
+ }
+ if (line.hasOption("s")) {
+ slobrokAddress = line.getOptionValue("s");
+ }
+ if (line.hasOption("t")) {
+ port = ((Number) line.getParsedOptionValue("t")).intValue();
+ }
+ if (line.hasOption("i")) {
+ printIds = true;
+ }
+ if (line.hasOption("p")) {
+ processTime = ((Number) line.getParsedOptionValue("p")).intValue();
+ }
+ if (line.hasOption("v")) {
+ verbose = true;
+ }
+ if (line.hasOption("c")) {
+ handlerClassName = line.getOptionValue("c");
+ }
+ if (line.hasOption("o")) {
+ handlerArgs = line.getOptionValue("o").split(" ");
+ }
+
+ if (!(slobrokAddress == null ^ port == -1)) {
+ throw new IllegalArgumentException("You must specify one, and only one, binding option");
+ }
+ if (port != -1 && port < 0 || port > 65535) {
+ throw new IllegalArgumentException("The port must be in the range 0-65535");
+ }
+ if (verbose) {
+ if (port != -1) {
+ System.err.println("Binding to socket " + getTcpAddress());
+ } else {
+ System.err.println("Binding to slobrok address: " + slobrokAddress + "/visit-destination");
+ }
+ }
+ }
+
+ private String getTcpAddress() {
+ try {
+ InetAddress addr = InetAddress.getLocalHost();
+ String hostname = addr.getHostName();
+ return "tcp/" + hostname + ":" + port + "/visit-destination";
+ } catch (UnknownHostException e) {
+ System.err.println("Failed to detect hostname.");
+ System.exit(1);
+ }
+ return "";
+ }
+
+ @SuppressWarnings("unchecked")
+ public void run() throws Exception {
+ initShutdownHook();
+ log.log(LogLevel.DEBUG, "Starting VdsVisitTarget");
+ MessageBusParams mbusParams = new MessageBusParams(new LoadTypeSet());
+ mbusParams.getRPCNetworkParams().setIdentity(new Identity(slobrokAddress));
+
+ if (port > 0) {
+ mbusParams.getRPCNetworkParams().setListenPort(port);
+ }
+
+ access = new MessageBusDocumentAccess(mbusParams);
+
+ VdsVisitHandler handler;
+
+ Class<?> cls = Thread.currentThread().getContextClassLoader()
+ .loadClass(handlerClassName);
+ try {
+ // Any custom data handlers may have a constructor that takes in args,
+ // so that the user can pass cmd line options to them
+ Class<?>[] consTypes = new Class<?>[] { boolean.class, boolean.class,
+ boolean.class, boolean.class, boolean.class,
+ boolean.class, int.class, String[].class };
+ Constructor<?> cons = cls.getConstructor(consTypes);
+ handler = (VdsVisitHandler)cons.newInstance(
+ printIds, verbose, verbose, verbose, false, false,
+ processTime, handlerArgs);
+ } catch (NoSuchMethodException e) {
+ // Retry, this time matching the StdOutVisitorHandler constructor
+ // arg list
+ Class<?>[] consTypes = new Class<?>[] { boolean.class, boolean.class,
+ boolean.class, boolean.class, boolean.class,
+ boolean.class, int.class, boolean.class };
+ Constructor<?> cons = cls.getConstructor(consTypes);
+ handler = (VdsVisitHandler)cons.newInstance(
+ printIds, verbose, verbose, verbose, false, false, processTime, false);
+ }
+
+ VisitorDataHandler dataHandler = handler.getDataHandler();
+ VisitorControlHandler controlHandler = handler.getControlHandler();
+
+ VisitorDestinationParameters params = new VisitorDestinationParameters(
+ "visit-destination", dataHandler);
+ session = access.createVisitorDestinationSession(params);
+ while (!controlHandler.isDone()) {
+ Thread.sleep(1000);
+ }
+ }
+
+ private void initShutdownHook() {
+ Runtime.getRuntime().addShutdownHook(new CleanUpThread());
+ }
+
+ class CleanUpThread extends Thread {
+ public void run() {
+ try {
+ if (session != null) {
+ session.destroy();
+ }
+ } catch (IllegalStateException ise) {
+ //ignore this
+ }
+ try {
+ if (access != null) {
+ access.shutdown();
+ }
+ } catch (IllegalStateException ise) {
+ //ignore this too
+ }
+ }
+ }
+}