You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by ch...@apache.org on 2013/03/10 16:43:04 UTC
svn commit: r1454866 [1/4] -
/uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/
Author: challngr
Date: Sun Mar 10 15:43:03 2013
New Revision: 1454866
URL: http://svn.apache.org/r1454866
Log:
UIMA-2687
Frist pass, all of CLI except for DuccServiceApi is refactored to use common code and implement
an API.
Added:
uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/IConsoleCallback.java
uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/IUiOptions.java
uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/MonitorListener.java
Removed:
uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccProcessSubmit.java
Modified:
uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/CliBase.java
uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/ConsoleListener.java
uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccJobCancel.java
uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccJobMonitor.java
uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccJobSubmit.java
uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccProcessCancel.java
uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccReservationCancel.java
uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccReservationSubmit.java
uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceApi.java
uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceCancel.java
uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceSubmit.java
uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccUiUtilities.java
uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccletSubmit.java
uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/IServiceApi.java
Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/CliBase.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/CliBase.java?rev=1454866&r1=1454865&r2=1454866&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/CliBase.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/CliBase.java Sun Mar 10 15:43:03 2013
@@ -1,4 +1,3 @@
-
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -20,27 +19,39 @@
package org.apache.uima.ducc.cli;
import java.io.File;
+import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
+import java.lang.management.ManagementFactory;
import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
import java.util.Properties;
+import java.util.concurrent.CountDownLatch;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.PosixParser;
import org.apache.uima.ducc.common.IDucc;
+import org.apache.uima.ducc.common.NodeIdentity;
+import org.apache.uima.ducc.common.crypto.Crypto;
import org.apache.uima.ducc.common.utils.DuccProperties;
+import org.apache.uima.ducc.common.utils.DuccPropertiesResolver;
import org.apache.uima.ducc.common.utils.Utils;
import org.apache.uima.ducc.transport.dispatcher.DuccEventHttpDispatcher;
-import org.apache.uima.ducc.transport.event.cli.SpecificationProperties;
+import org.apache.uima.ducc.transport.event.AbstractDuccOrchestratorEvent;
public abstract class CliBase
- extends DuccUi
+ implements IUiOptions
{
+ private String myClassName = "N/A";
private boolean init_done = false;
protected String ducc_home;
protected DuccProperties ducc_properties;
@@ -49,89 +60,282 @@ public abstract class CliBase
protected Options options;
protected CommandLineParser parser;
protected CommandLine commandLine;
-
+ protected Map<String, UiOption> reverseOptions = new HashMap<String, UiOption>(); // for lookup by string-name
+
protected long friendlyId = -1;
+ protected int returnCode = -1;
- protected Properties cli_props;
+ protected DuccProperties cli_props;
protected ArrayList<String> errors = new ArrayList<String>();
protected ArrayList<String> warnings = new ArrayList<String>();
protected ArrayList<String> messages = new ArrayList<String>();
-
- abstract void addOptions(Options options);
+
+ protected boolean debug = false;
+
abstract boolean execute() throws Exception;
protected ConsoleListener console_listener = null;
+ protected String host_address = "N/A";
+ protected boolean console_attach = false;
+ protected IConsoleCallback consoleCb = null;
+ protected MonitorListener monitor_listener = null;
- String getLogDirectory(DuccProperties properties)
+ CountDownLatch waiter = null;
+
+ String getLogDirectory(String extension)
{
/*
* employ default log directory if not specified
*/
- String log_directory = properties.getProperty("log_directory");
+ String log_directory = cli_props.getProperty(UiOption.LogDirectory.pname());
if(log_directory == null) {
// no log directory was specified - default to user's home + "/ducc/logs"
- log_directory = System.getProperty("user.home")+IDucc.userLogsSubDirectory;
+ log_directory = System.getProperty("user.home") + IDucc.userLogsSubDirectory;
} else {
if(log_directory.startsWith(File.separator)) {
// absolute log directory was specified
} else {
// relative log directory was specified - default to user's home + relative directory
if(log_directory.endsWith(File.separator)) {
- log_directory = System.getProperty("user.home")+log_directory;
+ log_directory = System.getProperty("user.home") + log_directory;
}
else {
- log_directory = System.getProperty("user.home")+File.separator+log_directory;
+ log_directory = System.getProperty("user.home") + File.separator+log_directory;
}
}
}
- properties.setProperty("log_directory", log_directory);
+ if ( extension != null ) {
+ log_directory = log_directory + File.separator + extension;
+ }
+
+ cli_props.setProperty(UiOption.LogDirectory.pname(), log_directory);
/*
* make sure the logdir is actually legal.
*/
File f = new File(log_directory);
- if ( f.exists() ) {
- if ( !f.isDirectory() ) {
- addError("Specified log_directory is not a directory: " + log_directory);
- return null;
- }
- } else if ( !f.mkdirs() ) {
- addError("Cannot create log_directory: " + log_directory);
- return null;
+
+ if ( ! f.exists() ) {
+ if (! f.mkdirs() ) {
+ throw new IllegalArgumentException("Cannot create log directory " + log_directory);
+ }
+ }
+
+ if ( ! f.isDirectory() ) {
+ throw new IllegalArgumentException("Specified log_directory is not a directory: " + log_directory);
}
if ( ! f.canWrite() ) {
- addError("Log directory exists but cannot be written: " + f);
- return null;
+ throw new IllegalArgumentException("Log directory exists but cannot be written: " + f);
+ }
+
+ if ( ! f.canExecute() ) {
+ throw new IllegalArgumentException("Log directory exists but cannot be accessed (must be writable and executable): " + f);
}
+
return log_directory;
}
-
- synchronized void init(String[] args, Properties cli_props, String host_s, String port_s, String servlet)
+ void setWorkingDirectory()
+ {
+ String working_directory = cli_props.getProperty(UiOption.WorkingDirectory.pname());
+ if(working_directory == null) {
+ working_directory = System.getProperty("user.dir");
+ cli_props.setProperty(UiOption.WorkingDirectory.pname(), working_directory);
+ }
+ File f = new File(working_directory);
+ if ( ! f.exists() ) {
+ throw new IllegalArgumentException("Working directory " + working_directory + " does not exist.");
+ }
+ if ( ! f.canExecute() ) {
+ throw new IllegalArgumentException("Working directory " + working_directory + " exists but cannot be accessed.");
+ }
+ }
+
+ /*
+ * resolve ${defaultBrokerURL} in service dependencies - must fail if resolution needed but can't resolve
+ */
+ boolean resolve_service_dependencies(String endpoint, Properties props)
+ {
+ String jvmargs = props.getProperty(UiOption.ProcessJvmArgs.pname());
+ Properties jvmprops = DuccUiUtilities.jvmArgsToProperties(jvmargs);
+
+ String deps = props.getProperty(UiOption.ServiceDependency.pname());
+ try {
+ deps = DuccUiUtilities.resolve_service_dependencies(endpoint, deps, jvmprops);
+ if ( deps != null ) {
+ props.setProperty(UiOption.ServiceDependency.pname(), deps);
+ }
+ return true;
+ } catch ( Throwable t ) {
+ addThrowable(t);
+ return false;
+ }
+ }
+
+ void setUser()
+ throws Exception
+ {
+ /*
+ * marshal user
+ */
+ String user = DuccUiUtilities.getUser();
+ cli_props.setProperty(UiOption.User.pname(), user);
+ String property = DuccPropertiesResolver.getInstance().getProperty(DuccPropertiesResolver.ducc_signature_required);
+ if(property != null) {
+ String signatureRequiredProperty = property.trim().toLowerCase();
+ if(signatureRequiredProperty.equals("on")) {
+ Crypto crypto = new Crypto(System.getProperty("user.home"));
+ byte[] cypheredMessage = crypto.encrypt(user);
+ cli_props.put(UiOption.Signature.pname(), cypheredMessage);
+ }
+ }
+ }
+
+ /**
+ * @param args - array of arguments to the cli parser
+ * @param boolean - if true, then add tick to insure required args are present
+ */
+ private Options makeOptions(UiOption[] optlist, boolean strict)
+ {
+ Options opts = new Options();
+ for ( UiOption opt : optlist ) {
+ OptionBuilder.withDescription(opt.makeDesc());
+ OptionBuilder.withLongOpt (opt.pname());
+
+ if ( opt.argname() == null ) {
+ OptionBuilder.hasOptionalArg(); // permissive, these are booleans or inferred and we'll just ignore
+ // spurious true, false, or other values
+ } else {
+ OptionBuilder.withArgName(opt.argname());
+ if ( opt.multiargs() ) {
+ OptionBuilder.hasArgs();
+ } else {
+ OptionBuilder.hasArgs(1);
+ }
+ }
+
+ if ( strict && opt.required() ) OptionBuilder.isRequired();
+
+ Option o = OptionBuilder.create();
+ opts.addOption(o);
+ }
+ return opts;
+ }
+
+ private String[] mkArgs(DuccProperties props)
+ {
+ List<String> arglist = new ArrayList<String>();
+ for ( Object o : props.keySet() ) {
+ String k = (String) o;
+ String v = props.getStringProperty(k, "");
+
+ arglist.add("--" + k);
+ arglist.add(v);
+ }
+ return arglist.toArray(new String[arglist.size()]);
+ }
+
+ private void enhanceProperties(CommandLine commandLine, boolean showdebug)
+ {
+ Option[] cliopts = commandLine.getOptions();
+ for ( Option o : cliopts ) {
+ if ( debug && showdebug ) {
+ System.out.println("CLI Override: " + o.toString());
+ }
+ String k = o.getLongOpt().trim();
+ String v = o.getValue();
+ if ( v == null ) v = "";
+ v = v.trim();
+
+ cli_props.put(k, v);
+ }
+ }
+
+
+ /**
+ * Use this init if you use the default log location and don't need a console callback.
+ */
+ protected synchronized void init(String myClassName, UiOption[] opts, String[] args, DuccProperties cli_props, String host_s, String port_s, String servlet)
+ throws Exception
+ {
+ this.init(myClassName, opts, args, cli_props, host_s, port_s, servlet, null, null);
+ }
+
+ /**
+ * Use this init if you you need a console callback and use the default log location.
+ */
+ protected synchronized void init(String myClassName, UiOption[] opts, String[] args, DuccProperties cli_props, String host_s, String port_s, String servlet, IConsoleCallback consoleCb)
+ throws Exception
+ {
+ this.init(myClassName, opts, args, cli_props, host_s, port_s, servlet, consoleCb, null);
+ }
+
+ protected synchronized void init(String myClassName, UiOption[] opts, String[] args, DuccProperties cli_props, String host_s, String port_s, String servlet, IConsoleCallback consoleCb, String logExtension)
throws Exception
{
if ( init_done ) return;
+
+ if ( consoleCb == null ) {
+ consoleCb = new DefaultConsoleCallback();
+ }
+ this.consoleCb = consoleCb;
+ this.myClassName = myClassName;
ducc_home = Utils.findDuccHome();
this.cli_props = cli_props;
- options = new Options();
parser = new PosixParser();
- addOptions(options);
+
+ // Set up for reverse lookup
+// for (UiOption opt : UiOption.values() ) {
+// reverseOptions.put(opt.pname(), opt);
+// }
+
+// options.addOption(OptionBuilder
+// .withArgName(DuccUiConstants.parm_driver_descriptor_CR)
+// .withDescription(makeDesc(DuccUiConstants.desc_driver_descriptor_CR,DuccUiConstants.exmp_driver_descriptor_CR)).hasArg()
+// .withLongOpt(DuccUiConstants.name_driver_descriptor_CR).create());
+
+ options = makeOptions(opts, false);
commandLine = parser.parse(options, args);
- if (commandLine.hasOption(DuccUiConstants.name_help)) {
+ if (commandLine.hasOption(UiOption.Help.pname())) {
usage(null);
}
+ if (commandLine.hasOption(UiOption.Debug.pname())) {
+ debug = true;
+ }
if(commandLine.getOptions().length == 0) {
usage(null);
}
+ // Load the specificaiton file, if given on the command line
+ String spec = UiOption.Specification.pname();
+ if ( commandLine.hasOption(spec) ) {
+ String val = commandLine.getOptionValue(spec);
+ File file = new File(val);
+ FileInputStream fis = new FileInputStream(file);
+ cli_props.load(fis);
+
+ // Loop through options and enhance / override things from cl options
+ enhanceProperties(commandLine, true);
+
+ // Now a trick - we'll rebuild the command line with the props as well as the cli args
+ // and reparse strictly.
+ args = mkArgs(cli_props);
+ cli_props.clear();
+ }
+
+ options = makeOptions(opts, true);
+ commandLine = parser.parse(options, args);
+ enhanceProperties(commandLine, false);
+
String propsfile = ducc_home + "/resources/ducc.properties";
ducc_properties = new DuccProperties();
ducc_properties.load(propsfile);
+ cli_props.setProperty(UiOption.SubmitPid.pname(), ManagementFactory.getRuntimeMXBean().getName()); // my pid
String host = ducc_properties.getStringProperty(host_s);
String port = ducc_properties.getStringProperty(port_s);
@@ -147,16 +351,29 @@ public abstract class CliBase
String targetUrl = "http://"+ host + ":" + port + "/" + servlet;
dispatcher = new DuccEventHttpDispatcher(targetUrl);
+ if ( getLogDirectory(logExtension) == null ) {
+ throw new IllegalArgumentException("Cannot access log directory.");
+ }
+ setWorkingDirectory();
+ setUser();
+
+ NodeIdentity ni = new NodeIdentity();
+ this.host_address = ni.getIp();
+
+ initConsoleListener();
+
init_done = true;
}
- void saveSpec(String id, String name, DuccProperties props)
+ void saveSpec(String name, DuccProperties props)
throws Exception
{
- String directory = props.getProperty("log_directory") + File.separator + id;
+ String directory = props.getProperty("log_directory") + File.separator + friendlyId;
String fileName = directory + File.separator + name;
File f = new File(directory);
- f.mkdirs();
+ if ( ! f.mkdirs() ) {
+ throw new IllegalStateException("Cannot create log directory: " + f.toString());
+ }
String comments = null;
FileOutputStream fos = null;
@@ -164,7 +381,7 @@ public abstract class CliBase
fos = new FileOutputStream(fileName);
out = new OutputStreamWriter(fos);
- String key = SpecificationProperties.key_signature;
+ String key = UiOption.Signature.pname();
if ( props.containsKey(key) ) {
Object value = props.remove(key);
props.store(out, comments);
@@ -194,6 +411,54 @@ public abstract class CliBase
}
}
+ /**
+ * Extract messages and job pid from reply. This sets messages and errors into the appropriate
+ * structures for the API, and extracts the numeric id of the [job, ducclet, reservation, service]
+ * returned by the Orchestrator.
+ *
+ * @returns true if the action succeeded and false otherwise. The action in this case, is whatever
+ * the Orchestrator was asked to do: submit something, cancel something, etc.
+ */
+ boolean extractReply(AbstractDuccOrchestratorEvent reply)
+ {
+ /*
+ * process reply
+ */
+ boolean rc = true;
+ Properties properties = reply.getProperties();
+ @SuppressWarnings("unchecked")
+ ArrayList<String> value_submit_warnings = (ArrayList<String>) properties.get(UiOption.SubmitWarnings.pname());
+ if(value_submit_warnings != null) {
+ addMessage("Job"+" "+"warnings:");
+ Iterator<String> reasons = value_submit_warnings.iterator();
+ while(reasons.hasNext()) {
+ addMessage(reasons.next());
+ }
+ }
+ @SuppressWarnings("unchecked")
+ ArrayList<String> value_submit_errors = (ArrayList<String>) properties.get(UiOption.SubmitErrors.pname());
+ if(value_submit_errors != null) {
+ addError("Job"+" "+"errors:");
+ Iterator<String> reasons = value_submit_errors.iterator();
+ while(reasons.hasNext()) {
+ addError(reasons.next());
+ }
+ rc = false;
+ }
+
+ String pid = reply.getProperties().getProperty(UiOption.JobId.pname());
+ if (pid == null ) {
+ rc = false;
+ } else {
+ friendlyId = Long.parseLong(pid);
+ if ( friendlyId < 0 ) {
+ rc = false;
+ }
+ }
+
+ return rc;
+ }
+
void usage(String message)
{
if ( message != null ) {
@@ -201,7 +466,7 @@ public abstract class CliBase
}
HelpFormatter formatter = new HelpFormatter();
formatter.setWidth(DuccUiConstants.help_width);
- formatter.printHelp(DuccletSubmit.class.getName(), options);
+ formatter.printHelp(myClassName, options);
System.exit(1);
}
@@ -228,11 +493,26 @@ public abstract class CliBase
return true;
}
+ public boolean isDebug()
+ {
+ return debug;
+ }
+
+ public void setDebug(boolean val)
+ {
+ this.debug = val;
+ }
+
+ public String getHostAddress()
+ {
+ return host_address;
+ }
+
public boolean hasProperty(String key)
{
return cli_props.containsKey(key);
}
-
+
public String getProperty(String key)
{
return (String) cli_props.getProperty(key);
@@ -249,12 +529,19 @@ public abstract class CliBase
this.errors.add(e);
}
-
synchronized void addMessage(String m)
{
this.messages.add(m);
}
+ synchronized void addThrowable(Throwable t)
+ {
+ this.errors.add(t.toString());
+ if ( debug ) {
+ t.printStackTrace();
+ }
+ }
+
synchronized void addErrors(ArrayList<String> e)
{
@@ -281,25 +568,118 @@ public abstract class CliBase
return errors.toArray(new String[errors.size()]);
}
+ public int getReturnCode()
+ {
+ return returnCode;
+ }
+
synchronized public long getDuccId()
{
return friendlyId;
}
- protected void startConsoleListener()
- throws Throwable
+ synchronized void consoleExits()
+ {
+ if ( waiter != null ) waiter.countDown();
+ }
+
+ synchronized void monitorExits(int rc)
+ {
+ if ( waiter != null ) waiter.countDown();
+ if ( console_listener != null ) {
+ console_listener.shutdown();
+ }
+ this.returnCode = rc;
+ }
+
+ // TODO TODO TODO - do we have to support lots of these for multi-threaded stuff? Hope not ...
+ protected synchronized void startMonitors()
+ throws Exception
+ {
+ int wait_count = 0;
+
+ if ( console_listener != null ) {
+ startConsoleListener();
+ wait_count++;
+ }
+
+ if ( cli_props.containsKey(UiOption.ServiceTypeOther.pname() ) ) {
+ if ( debug ) addMessage("Bypassing monitor for ducclet.");
+ } else {
+ boolean monitor_attach =
+ (cli_props.containsKey(UiOption.WaitForCompletion.pname()) || ( console_attach ));
+
+ if ( monitor_attach ) {
+ wait_count++;
+ startJobMonitor(console_attach && !cli_props.containsKey(UiOption.WaitForCompletion.pname()));
+ }
+ }
+
+ if ( wait_count > 0 ) {
+ waiter = new CountDownLatch(wait_count);
+ }
+ }
+
+ protected synchronized void startJobMonitor(boolean quiet)
{
- console_listener = new ConsoleListener(this);
- Thread t = new Thread(console_listener);
- t.start();
+ monitor_listener = new MonitorListener(this, friendlyId, cli_props, quiet);
+
+ if (cli_props.containsKey(UiOption.WaitForCompletion.pname()) || ( console_listener != null) ) {
+ Thread mlt = new Thread(monitor_listener); //MonitorListenerThread
+ mlt.start();
+ }
}
- protected void stopConsoleListener()
+ /**
+ * Needs to be done before submitting the job because the job needs the ports. We'll
+ * just define the listener, but not start it untile the job monitor starts, in case the
+ * submission fails.
+ */
+ protected void initConsoleListener()
+ throws Exception
+ {
+ console_attach =
+ cli_props.containsKey(UiOption.ProcessAttachConsole.pname()) ||
+ cli_props.containsKey(UiOption.DriverAttachConsole.pname());
+
+ if ( console_attach ) {
+ console_listener = new ConsoleListener(this, consoleCb);
+
+ if ( cli_props.containsKey(UiOption.ProcessAttachConsole.pname()) ) {
+ set_console_port(cli_props, UiOption.ProcessEnvironment.pname());
+ }
+
+ if (cli_props.containsKey(UiOption.DriverAttachConsole.pname()) ) {
+ set_console_port(cli_props, UiOption.DriverEnvironment.pname());
+ }
+ }
+ }
+
+ /**
+ * Be sure to call this BEFORE submission, to insure the callback address is set in properties.
+ */
+ protected synchronized void startConsoleListener()
+ throws Exception
+ {
+ if ( console_attach ) {
+ Thread t = new Thread(console_listener);
+ t.start();
+ } else {
+ addWarning("Attermpt to start console but no console listener is defined.");
+ }
+ }
+
+ protected void stopListeners()
{
if ( console_listener != null ) {
console_listener.shutdown();
console_listener = null;
}
+
+ if ( monitor_listener != null ) {
+ monitor_listener.shutdown();
+ monitor_listener = null;
+ }
}
protected void set_console_port(DuccProperties props, String key)
@@ -332,20 +712,63 @@ public abstract class CliBase
return ( (console_listener != null ) && ( !console_listener.isShutdown()));
}
- public void waitForCompletion()
+ /**
+ * Wait for the listeners - maybe a console listener, maybe a job listener.
+ * @returns true if a monitor wait was done, false otherwise. A monitor wait
+ * results in a return code from the process. In all other cases
+ * the return code is spurious.
+ */
+ public boolean waitForCompletion()
{
- if ( console_listener != null ) {
- console_listener.waitForCompletion();
- }
- console_listener = null;
+ try {
+ if ( waiter != null ) {
+ waiter.await();
+ return true;
+ }
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return false;
}
- public void closeConsole()
+ class DefaultConsoleCallback
+ implements IConsoleCallback
{
- if ( console_listener != null ) {
- console_listener.shutdown();
+
+// try {
+// if ((logfile == null) && line.startsWith(console_tag)) {
+// filename = line.substring(tag_len);
+// logfile = new BufferedOutputStream(new FileOutputStream(filename));
+
+// if ( debug ) System.out.println("Create logfile " + filename);
+// }
+// if (logfile != null) {
+// logfile.write(leader.getBytes());
+// logfile.write(' ');
+// logfile.write(line.getBytes());
+// logfile.write('\n');
+// logfile.flush();
+// } else {
+// if ( debug ) System.out.println("Bypass logfile");
+// }
+// } catch (Exception e) {
+// if ( first_error ) {
+// submit.addError("Cannot create or write log file[" + filename + "]: " + e.getMessage());
+// }
+// first_error = false;
+// }
+// consoleCb(leader + line);
+
+ public void stdout(String host, String logfile, String s)
+ {
+ //System.out.println("[" + host + "." + logfile + "] " + s);
+ System.out.println("[" + host + "] " + s);
+ }
+ public void stderr(String host, String logfile, String s)
+ {
+ System.out.println("[" + host + "." + logfile + "] " + s);
}
- console_listener = null;
}
}
Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/ConsoleListener.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/ConsoleListener.java?rev=1454866&r1=1454865&r2=1454866&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/ConsoleListener.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/ConsoleListener.java Sun Mar 10 15:43:03 2013
@@ -19,8 +19,6 @@
*/
package org.apache.uima.ducc.cli;
-import java.io.BufferedOutputStream;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
@@ -42,18 +40,24 @@ class ConsoleListener
private String console_host_address;
private boolean in_shutdown = false;
- private int callers; // number of remote processes we expect to listen for
- ConsoleListener(CliBase submit)
- throws Throwable
+ private IConsoleCallback consoleCb;
+ // private int callers; // number of remote processes we expect to listen for
+
+ boolean debug = false;
+ ConsoleListener(CliBase submit, IConsoleCallback consoleCb)
+ throws Exception
{
this.submit = submit;
this.sock = new ServerSocket(0);
this.console_listener_port = sock.getLocalPort();
-
+ this.consoleCb = consoleCb;
+
NodeIdentity ni = new NodeIdentity();
this.console_host_address = ni.getIp();
- this.callers = 1; // assume we'll get at least one listener, else we would not have been called.
+
+ debug = submit.isDebug();
+ // this.callers = 1; // assume we'll get at least one listener, else we would not have been called.
}
String getConsoleHostAddress()
@@ -66,33 +70,33 @@ class ConsoleListener
return console_listener_port;
}
- /**
- * The caller knows there may be more than one remote process calling us but
- * we've no clue when or if they will show up. We assume here they do, and
- * rely on some external influence to correct us if not.
- */
- synchronized void incrementCallers()
- {
- callers++;
- }
-
- synchronized void waitForCompletion()
- {
- try {
- while ( (callers > 0) && ( !in_shutdown) ) {
- wait();
- }
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
-
- private synchronized void releaseWait()
- {
- callers--;
- notify();
- }
+// /**
+// * The caller knows there may be more than one remote process calling us but
+// * we've no clue when or if they will show up. We assume here they do, and
+// * rely on some external influence to correct us if not.
+// */
+// synchronized void incrementCallers()
+// {
+// callers++;
+// }
+
+// synchronized void waitForCompletion()
+// {
+// try {
+// while ( (callers > 0) && ( !in_shutdown) ) {
+// wait();
+// }
+// } catch (InterruptedException e) {
+// // TODO Auto-generated catch block
+// e.printStackTrace();
+// }
+// }
+
+// private synchronized void releaseWait()
+// {
+// callers--;
+// notify();
+// }
synchronized boolean isShutdown()
{
@@ -101,6 +105,7 @@ class ConsoleListener
void shutdown()
{
+ if ( debug ) System.out.println("console listener: Shutdown starts");
in_shutdown = true;
try {
sock.close();
@@ -114,32 +119,39 @@ class ConsoleListener
private void delete(int port)
{
- listeners.remove(port);
- if ( listeners.size() == 0 ) {
- synchronized(submit) {
- releaseWait();
- }
+ int count;
+ synchronized(this) {
+ listeners.remove(port);
+ count = listeners.size();
+ }
+
+ if ( debug ) System.out.println("console listener: Removed listener, size = " + listeners.size());
+ if ( count == 0 ) {
shutdown();
}
}
public void run()
{
- System.out.println("Listening on " + console_host_address + " " + console_listener_port);
+ if ( debug ) System.out.println("Listening on " + console_host_address + " " + console_listener_port);
while ( true ) {
try {
Socket s = sock.accept();
StdioListener sl = new StdioListener(s, this);
int p = s.getPort();
- listeners.put(p, sl);
+ synchronized(this) {
+ listeners.put(p, sl);
+ }
Thread t = new Thread(sl);
t.start();
} catch (Throwable t) {
if ( ! in_shutdown ) shutdown();
+ if ( debug ) System.out.println("console listener returns");
+ submit.consoleExits();
return;
- }
+ }
}
}
@@ -151,13 +163,11 @@ class ConsoleListener
boolean done = false;
ConsoleListener cl;
String remote_host;
- String leader;
+ String logfile = "N/A";
- BufferedOutputStream logfile = null;
- String filename = null;
static final String console_tag = "1002 CONSOLE_REDIRECT ";
int tag_len = 0;
- boolean first_error = true;
+
StdioListener(Socket sock, ConsoleListener cl)
{
@@ -166,56 +176,31 @@ class ConsoleListener
InetAddress ia = sock.getInetAddress();
remote_host = ia.getHostName();
- System.out.println("===== Listener starting: " + remote_host + ":" + sock.getPort());
- int ndx = remote_host.indexOf('.');
- if ( ndx >= 0 ) {
- // this is just for console decoration, keep it short, who cares about the domain
- remote_host = remote_host.substring(0, ndx);
- }
- leader = "[" + remote_host + "] ";
tag_len = console_tag.length();
+
+ if ( debug ) System.out.println("===== Listener starting: " + remote_host + ":" + sock.getPort());
}
public void close()
throws Throwable
{
- System.out.println("===== Listener completing: " + remote_host + ":" + sock.getPort());
+ if ( debug ) System.out.println("===== Listener completing: " + remote_host + ":" + sock.getPort());
this.done = true;
is.close();
cl.delete(sock.getPort());
-
- logfile.flush();
- logfile.close();
}
- void tee(String leader, String line)
+ void doWrite(String line)
{
- try {
- if ((logfile == null) && line.startsWith(console_tag)) {
- filename = line.substring(tag_len);
- logfile = new BufferedOutputStream(new FileOutputStream(filename));
-
- System.out.println("Create logfile " + filename);
- }
- if (logfile != null) {
- logfile.write(leader.getBytes());
- logfile.write(' ');
- logfile.write(line.getBytes());
- logfile.write('\n');
- logfile.flush();
- } else {
- System.out.println("Bypass logfile");
- }
- } catch (Exception e) {
- if ( first_error ) {
- System.out.println("Cannot create or write log file[" + filename + "]: " + e.getMessage());
- e.printStackTrace();
- }
- first_error = false;
- }
- System.out.println(leader + line);
+ if ( line.startsWith(console_tag) ) {
+ logfile = line.substring(tag_len);
+ return; // don't echo this
+ }
+ if ( logfile.equals("N/A") ) return; // don't log until we get a log name
+ if ( line.startsWith("1001 Command launching...") && ( !debug) ) return; // don't log duccling noise
+ consoleCb.stdout(remote_host, logfile, line);
}
-
+
/**
* We received a buffer of bytes that needs to be put into a string and printed. We want
* to split along \n boundaries so we can insert the host name at the start of every line.
@@ -235,7 +220,7 @@ class ConsoleListener
if ( len < 0 ) {
// this is a lone linend. Spew the partial if it exists and just return.
if ( partial != null ) {
- tee(leader, partial);
+ doWrite(partial);
partial = null;
}
return;
@@ -250,12 +235,12 @@ class ConsoleListener
for ( int i = 0; i < len; i++ ) {
// spew everything but the last line
- tee(leader, lines[i]);
+ doWrite(lines[i]);
}
if ( tmp.endsWith("\n") ) {
// if the last line ends with linend, there is no partial, just spew
- tee(leader, lines[len]);
+ doWrite(lines[len]);
partial = null;
} else {
// otherwise, wait for the next buffer
@@ -279,7 +264,7 @@ class ConsoleListener
while ( (count = is.read(buf)) > 0 ) {
printlines(buf, count);
}
- System.out.println(leader + "EOF: exiting");
+ if ( debug ) System.out.println(remote_host + ": EOF: exiting");
} catch ( Throwable t ) {
t.printStackTrace();
}
Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccJobCancel.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccJobCancel.java?rev=1454866&r1=1454865&r2=1454866&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccJobCancel.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccJobCancel.java Sun Mar 10 15:43:03 2013
@@ -18,186 +18,146 @@
*/
package org.apache.uima.ducc.cli;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.CommandLineParser;
-import org.apache.commons.cli.HelpFormatter;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionBuilder;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.PosixParser;
-import org.apache.uima.ducc.api.DuccMessage;
-import org.apache.uima.ducc.api.IDuccMessageProcessor;
-import org.apache.uima.ducc.common.crypto.Crypto;
-import org.apache.uima.ducc.common.exception.DuccRuntimeException;
-import org.apache.uima.ducc.common.utils.DuccPropertiesResolver;
-import org.apache.uima.ducc.common.utils.Utils;
-import org.apache.uima.ducc.transport.dispatcher.DuccEventHttpDispatcher;
+import java.util.List;
+import java.util.Properties;
+
import org.apache.uima.ducc.transport.event.CancelJobDuccEvent;
import org.apache.uima.ducc.transport.event.CancelJobReplyDuccEvent;
-import org.apache.uima.ducc.transport.event.DuccEvent;
-import org.apache.uima.ducc.transport.event.cli.JobReplyProperties;
import org.apache.uima.ducc.transport.event.cli.JobRequestProperties;
-import org.apache.uima.ducc.transport.event.cli.JobSpecificationProperties;
/**
* Cancel a DUCC job
*/
-public class DuccJobCancel extends DuccUi {
-
- private IDuccMessageProcessor duccMessageProcessor = new DuccMessage();
+public class DuccJobCancel
+ extends CliBase
+{
+
+ JobRequestProperties jobRequestProperties = new JobRequestProperties();
+ static String or_port = "ducc.orchestrator.http.port";
+ static String or_host = "ducc.orchestrator.node";
+
+ long canceledPid = -1;
+ String responseMessage = null;
+
+ UiOption[] opts = new UiOption []
+ {
+ UiOption.Help,
+ UiOption.Debug,
+
+ UiOption.JobId,
+ UiOption.DjPid,
+ UiOption.Reason,
+ };
+
- public DuccJobCancel() {
+ public DuccJobCancel(String [] args)
+ throws Exception
+ {
+ init(this.getClass().getName(), opts, args, jobRequestProperties, or_host, or_port, "or", null);
}
-
- public DuccJobCancel(IDuccMessageProcessor duccMessageProcessor) {
- this.duccMessageProcessor = duccMessageProcessor;
+
+ public DuccJobCancel(List<String> args)
+ throws Exception
+ {
+ String[] arg_array = args.toArray(new String[args.size()]);
+ init(this.getClass().getName(), opts, arg_array, jobRequestProperties, or_host, or_port, "or", null);
}
-
- @SuppressWarnings("static-access")
- private void addOptions(Options options) {
- options.addOption(OptionBuilder
- .withDescription(DuccUiConstants.desc_help).hasArg(false)
- .withLongOpt(DuccUiConstants.name_help).create());
- options.addOption(OptionBuilder
- .withDescription(DuccUiConstants.desc_role_administrator).hasArg(false)
- .withLongOpt(DuccUiConstants.name_role_administrator).create());
- options.addOption(OptionBuilder
- .withArgName(DuccUiConstants.parm_job_id)
- .withDescription(makeDesc(DuccUiConstants.desc_job_id,DuccUiConstants.exmp_job_id)).hasArg()
- .withLongOpt(DuccUiConstants.name_job_id).create());
- options.addOption(OptionBuilder
- .withArgName(DuccUiConstants.parm_djpid)
- .withDescription(makeDesc(DuccUiConstants.desc_djpid,DuccUiConstants.exmp_djpid)).hasArg()
- .withLongOpt(DuccUiConstants.name_djpid).create());
- options.addOption(OptionBuilder
- .withArgName(DuccUiConstants.parm_reason)
- .withDescription(makeDesc(DuccUiConstants.desc_reason,DuccUiConstants.exmp_reason)).hasArg()
- .withLongOpt(DuccUiConstants.name_reason).create());
+
+ public DuccJobCancel(Properties props)
+ throws Exception
+ {
+ for ( Object k : props.keySet() ) {
+ Object v = props.get(k);
+ jobRequestProperties.put(k, v);
+ }
+ init(this.getClass().getName(), opts, null, jobRequestProperties, or_host, or_port, "or", null, null);
}
-
- protected int help(Options options) {
- HelpFormatter formatter = new HelpFormatter();
- formatter.setWidth(DuccUiConstants.help_width);
- formatter.printHelp(DuccJobCancel.class.getName(), options);
- return 1;
+
+ public long getCanceledPid()
+ {
+ return canceledPid;
+ }
+ public String getResponseMessage()
+ {
+ return responseMessage;
}
-
- public int run(String[] args) throws Exception {
- JobRequestProperties jobRequestProperties = new JobRequestProperties();
- /*
- * parser is not thread safe?
- */
- synchronized(DuccUi.class) {
- Options options = new Options();
- addOptions(options);
- CommandLineParser parser = new PosixParser();
- CommandLine commandLine = parser.parse(options, args);
- /*
- * give help & exit when requested
- */
- if (commandLine.hasOption(DuccUiConstants.name_help)) {
- return help(options);
- }
- if(commandLine.getOptions().length == 0) {
- return help(options);
- }
- /*
- * require DUCC_HOME
- */
- String ducc_home = Utils.findDuccHome();
- if(ducc_home == null) {
- duccMessageProcessor.err("missing required environment variable: DUCC_HOME");
- return 1;
- }
- /*
- * detect duplicate options
- */
- if (DuccUiUtilities.duplicate_options(duccMessageProcessor, commandLine)) {
- return 1;
- }
- /*
- * marshal user
- */
- String user = DuccUiUtilities.getUser();
- jobRequestProperties.setProperty(JobSpecificationProperties.key_user, user);
- String property = DuccPropertiesResolver.getInstance().getProperty(DuccPropertiesResolver.ducc_signature_required);
- if(property != null) {
- String signatureRequiredProperty = property.trim().toLowerCase();
- if(signatureRequiredProperty.equals("on")) {
- Crypto crypto = new Crypto(System.getProperty("user.home"));
- byte[] cypheredMessage = crypto.encrypt(user);
- jobRequestProperties.put(JobSpecificationProperties.key_signature, cypheredMessage);
- }
- }
- /*
- * marshal command line options into properties
- */
- Option[] optionList = commandLine.getOptions();
- for (int i=0; i<optionList.length; i++) {
- Option option = optionList[i];
- String name = option.getLongOpt();
- String value = option.getValue();
- if(value == null) {
- value = "";
- }
- jobRequestProperties.setProperty(name, value);
- }
- }
- // trim
- DuccUiUtilities.trimProperties(jobRequestProperties);
- String port =
- DuccPropertiesResolver.
- getInstance().
- getProperty(DuccPropertiesResolver.ducc_orchestrator_http_port);
- if ( port == null ) {
- throw new DuccRuntimeException("Unable to Cancel a Job. Ducc Orchestrator HTTP Port Not Defined. Add ducc.orchestrator.http.port ducc.properties");
- }
- String orNode =
- DuccPropertiesResolver.
- getInstance().
- getProperty(DuccPropertiesResolver.ducc_orchestrator_node);
- if ( orNode == null ) {
- throw new DuccRuntimeException("Unable to Cancel a Job. Ducc Orchestrator Node Not Defined. Add ducc.orchestrator.node to ducc.properties");
- }
-
- String targetUrl = "http://"+orNode+":"+port+"/or";
- DuccEventHttpDispatcher duccEventDispatcher = new DuccEventHttpDispatcher(targetUrl);
- CancelJobDuccEvent cancelJobDuccEvent = new CancelJobDuccEvent();
- cancelJobDuccEvent.setProperties(jobRequestProperties);
- DuccEvent duccRequestEvent = cancelJobDuccEvent;
- DuccEvent duccReplyEvent = null;
+ public boolean execute()
+ throws Exception
+ {
+
+ CancelJobDuccEvent cancelJobDuccEvent = new CancelJobDuccEvent(jobRequestProperties);
CancelJobReplyDuccEvent cancelJobReplyDuccEvent = null;
try {
- duccReplyEvent = duccEventDispatcher.dispatchAndWaitForDuccReply(duccRequestEvent);
- }
- finally {
- duccEventDispatcher.close();
- //context.stop();
+ cancelJobReplyDuccEvent = (CancelJobReplyDuccEvent) dispatcher.dispatchAndWaitForDuccReply(cancelJobDuccEvent);
+ } catch (Exception e) {
+ addError("Job not submitted: " + e.getMessage());
+ return false;
+ } finally {
+ dispatcher.close();
}
+
/*
* process reply
*/
- cancelJobReplyDuccEvent = (CancelJobReplyDuccEvent) duccReplyEvent;
- // TODO handle null & rejected possibilities here
- String jobId = cancelJobReplyDuccEvent.getProperties().getProperty(JobReplyProperties.key_id);
- String dpId = cancelJobReplyDuccEvent.getProperties().getProperty(JobReplyProperties.key_dpid);
- if(dpId != null) {
- jobId+="."+dpId;
- }
- String msg = cancelJobReplyDuccEvent.getProperties().getProperty(JobReplyProperties.key_message);
- duccMessageProcessor.out("Job"+" "+jobId+" "+msg);
- return 0;
+ boolean rc = extractReply(cancelJobReplyDuccEvent);
+
+ String dpId = cancelJobReplyDuccEvent.getProperties().getProperty(UiOption.DjPid.pname());
+ if(dpId != null) {
+ canceledPid = Long.parseLong(dpId);
+ }
+
+ responseMessage = cancelJobReplyDuccEvent.getProperties().getProperty(UiOption.Message.pname());
+
+ // need : getResponseMessage
+ // : canceled Pids
+ // : getDuccId
+ // duccMessageProcessor.out("Job"+" "+jobId+" "+msg);
+ return rc;
}
public static void main(String[] args) {
try {
- DuccJobCancel duccJobCancel = new DuccJobCancel();
- int rc = duccJobCancel.run(args);
- System.exit(rc == 0 ? 0 : 1);
+ DuccJobCancel djc = new DuccJobCancel(args);
+ boolean rc = djc.execute();
+
+ // Fetch messages if any. null means none
+ String [] messages = djc.getMessages();
+ String [] warnings = djc.getWarnings();
+ String [] errors = djc.getErrors();
+
+ if ( messages != null ) {
+ for (String s : messages ) {
+ System.out.println(s);
+ }
+ }
+
+ if ( warnings != null ) {
+ for (String s : warnings ) {
+ System.out.println("WARN: " + s);
+ }
+ }
+
+ if ( errors != null ) {
+ for (String s : errors ) {
+ System.out.println("ERROR: " + s);
+ }
+ }
+
+ long id = djc.getDuccId();
+ String msg = djc.getResponseMessage();
+ long dpid = djc .getCanceledPid();
+
+ if ( dpid == -1 ) {
+ System.out.println("Job " + id + " " + msg);
+ } else {
+ System.out.println("Process " + id + "." + dpid + " " + msg);
+ }
+
+ System.exit(rc ? 0 : 1);
} catch (Exception e) {
- e.printStackTrace();
+ System.out.println("Cannot cancel: " + e.getMessage());
System.exit(1);
}
}
Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccJobMonitor.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccJobMonitor.java?rev=1454866&r1=1454865&r2=1454866&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccJobMonitor.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccJobMonitor.java Sun Mar 10 15:43:03 2013
@@ -71,7 +71,7 @@ private Thread main = null;
private boolean info = true;
private boolean error = true;
private boolean debug = false;
-
+ private boolean quiet = false;
private boolean timestamp = false;
private int milliseconds = 1;
@@ -97,7 +97,7 @@ private Thread main = null;
}
private void info(String message) {
- if(info) {
+ if(info && !quiet) {
duccMessageProcessor.out(timestamp(message));
}
}
@@ -117,10 +117,12 @@ private Thread main = null;
return tMessage;
}
- public DuccJobMonitor() {
+ public DuccJobMonitor(boolean quiet) {
+ this.quiet = quiet;
}
- public DuccJobMonitor(IDuccMessageProcessor duccMessageProcessor) {
+ public DuccJobMonitor(IDuccMessageProcessor duccMessageProcessor, boolean quiet) {
+ this.quiet = quiet;
this.duccMessageProcessor = duccMessageProcessor;
}
@@ -242,12 +244,12 @@ private Thread main = null;
help(options);
return rc.get();
}
- /*
- * detect duplicate options
- */
- if (DuccUiUtilities.duplicate_options(duccMessageProcessor, commandLine)) {
- return 1;
- }
+// /*
+// * detect duplicate options
+// */
+// if (DuccUiUtilities.duplicate_options(duccMessageProcessor, commandLine)) {
+// return 1;
+// }
/*
* timestamp
*/
@@ -418,9 +420,9 @@ private Thread main = null;
arrayList.add("--"+DuccUiConstants.name_reason);
arrayList.add("\"submitter was terminated via interrupt\"");
String[] argList = arrayList.toArray(new String[0]);
- DuccJobCancel duccJobCancel = new DuccJobCancel();
- int retVal = duccJobCancel.run(argList);
- if(retVal == 0) {
+ DuccJobCancel duccJobCancel = new DuccJobCancel(argList);
+ boolean retVal = duccJobCancel.execute();
+ if(retVal) {
}
else {
}
@@ -430,7 +432,7 @@ private Thread main = null;
}
public static void main(String[] args) {
try {
- DuccJobMonitor duccJobMonitor = new DuccJobMonitor();
+ DuccJobMonitor duccJobMonitor = new DuccJobMonitor(false);
int rc = duccJobMonitor.run(args);
System.exit(rc == 0 ? 0 : 1);
} catch (Exception e) {