blob: 2ee43a4da3b55b86c534086c7d1ade76812788b9 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.uima.ducc.cli;
import java.util.ArrayList;
import java.util.Map.Entry;
import java.util.Properties;
import org.apache.uima.ducc.common.utils.DuccPropertiesResolver;
import org.apache.uima.ducc.common.utils.IllegalConfigurationException;
import org.apache.uima.ducc.transport.event.IDuccContext.DuccContext;
import org.apache.uima.ducc.transport.event.SubmitServiceDuccEvent;
import org.apache.uima.ducc.transport.event.SubmitServiceReplyDuccEvent;
import org.apache.uima.ducc.transport.event.cli.ServiceRequestProperties;
/**
* Submit a DUCC Managed Reservation that runs JED
*/
public class DuccJedSubmit extends CliBase {
private static String dt = "Jed";
private ServiceRequestProperties serviceRequestProperties;
private UiOption[] opts = new UiOption[] {
UiOption.Help,
UiOption.Debug,
UiOption.Description,
UiOption.WorkingDirectory, // Must precede LogDirecory
UiOption.LogDirectory, // Must precede Environment
UiOption.Environment,
UiOption.ProcessExecutableArgsRequired,
UiOption.ProcessMemorySize,
UiOption.SchedulingClass,
UiOption.Specification,
};
/**
* @param args
* List of string arguments as described in the Command Line Interface section of the DuccBook
* @throws Exception
* if request fails
*/
public DuccJedSubmit(String[] args) throws Exception {
this(args, null);
}
/**
* @param args
* Array of string arguments as described in the Command Line Interface section of the DuccBook
* @throws Exception
* if request fails
*/
public DuccJedSubmit(ArrayList<String> args) throws Exception {
this(args, null);
}
/**
* @param props
* Properties file of arguments, as described in the Command Line Interface section of the DuccBook
* @throws Exception
* if request fails
*/
public DuccJedSubmit(Properties props) throws Exception {
this(props, null);
}
/**
* This form of the constructor allows the API user to capture messages, rather than directing them to stdout.
*
* @param args
* Array of string arguments as described in the Command Line Interface section of the DuccBook
* @param consoleCb
* If provided, messages are directed to it instead of stdout.
* @throws Exception
* if request fails
*/
public DuccJedSubmit(String[] args, IDuccCallback consoleCb) throws Exception {
serviceRequestProperties = new ServiceRequestProperties();
init(this.getClass().getName(), opts, args, serviceRequestProperties, consoleCb);
}
/**
* This form of the constructor allows the API user to capture messages, rather than directing them to stdout.
*
* @param args
* List of string arguments as described in the Command Line Interface section of the DuccBook
* @param consoleCb
* If provided, messages are directed to it instead of stdout.
* @throws Exception
* if request fails
*/
public DuccJedSubmit(ArrayList<String> args, IDuccCallback consoleCb) throws Exception {
String[] arg_array = args.toArray(new String[args.size()]);
serviceRequestProperties = new ServiceRequestProperties();
init(this.getClass().getName(), opts, arg_array, serviceRequestProperties, consoleCb);
}
/**
* This form of the constructor allows the API user to capture messages, rather than directing them to stdout.
*
* @param props
* Properties file contianing string arguments as described in the Command Line Interface section of the DuccBook
* @param consoleCb
* If provided, messages are directed to it instead of stdout.
* @throws Exception
* if request fails
*/
public DuccJedSubmit(Properties props, IDuccCallback consoleCb) throws Exception {
serviceRequestProperties = new ServiceRequestProperties();
init(this.getClass().getName(), opts, props, serviceRequestProperties, consoleCb);
}
/**
* Execute collects the job parameters, does basic error and correctness checking, and sends the job properties to the DUCC orchestrator for
* execution.
*
* @return True if the orchestrator accepts the job; false otherwise.
* @throws Exception
* if request fails
*/
public boolean execute() throws Exception {
// Check if the experiments page is enabled
if (DuccPropertiesResolver.get("ducc.experiments", "false").equalsIgnoreCase("false")) {
throw new IllegalConfigurationException("JED experiments not enabled in ducc.properties");
}
// Create a copy to be saved later without these 3 "ducclet" properties required by DUCC
ServiceRequestProperties userSpecifiedProperties = (ServiceRequestProperties) serviceRequestProperties.clone();
serviceRequestProperties.setProperty(UiOption.ProcessPipelineCount.pname(), "1");
serviceRequestProperties.setProperty(UiOption.ProcessDeploymentsMax.pname(), "1");
serviceRequestProperties.setProperty(UiOption.ServiceTypeOther.pname(), "");
// Create the AP properties for the JED call
// Specify java, classpath, JED class, users's args
// Explictly override any internal setting of the outputBaseDirectory
// Augment the environment ... the OR checks for env-var DUCC_JED_DIR
String javaHome = System.getProperty("java.home");
serviceRequestProperties.setProperty(UiOption.ProcessExecutable.pname(), javaHome + "/bin/java");
String jedArgs = "-cp " +
ducc_home + "/lib/jed/*:" +
ducc_home + "/lib/google-gson/*:" +
ducc_home + "/apache-uima/lib/*:" +
ducc_home + "/lib/uima-ducc-cli.jar " +
"com.ibm.watsonx.framework.jed.Driver ";
String userArgs = serviceRequestProperties.getProperty(UiOption.ProcessExecutableArgsRequired.pname());
String args = jedArgs + userArgs;
serviceRequestProperties.setProperty(UiOption.ProcessExecutableArgsRequired.pname(), args);
// Add the environment variable that tells the OR this is a JED AP
// Also add DUCC_HOME so the JED properties can reference it
String jedEnv = "DUCC_HOME="+ducc_home + " ";
String userEnv = serviceRequestProperties.getProperty(UiOption.Environment.pname());
if (userEnv != null) {
jedEnv += userEnv;
}
serviceRequestProperties.setProperty(UiOption.Environment.pname(), jedEnv);
// Create a description if none provided
String desc = serviceRequestProperties.getProperty(UiOption.Description.pname());
if (desc == null || desc.equals(UiOption.Description.deflt())) {
serviceRequestProperties.setProperty(UiOption.Description.pname(), "JED: " + userArgs);
}
// Keep list of user provided properties for WS display: user vs. system
for (Entry<Object, Object> entry : userSpecifiedProperties.entrySet()) {
String key = (String) entry.getKey();
serviceRequestProperties.addUserProvided(key);
}
// Note: context is provided for system event logger to disambiguate Service from ManagedReservation
SubmitServiceDuccEvent ev = new SubmitServiceDuccEvent(serviceRequestProperties, DuccContext.ManagedReservation, CliVersion.getVersion());
SubmitServiceReplyDuccEvent reply = null;
try {
reply = (SubmitServiceReplyDuccEvent) dispatcher.dispatchAndWaitForDuccReply(ev);
} finally {
dispatcher.close();
}
/*
* process reply
*/
boolean rc = extractReply(reply);
if (rc) {
saveSpec(DuccUiConstants.managed_reservation_properties, userSpecifiedProperties);
startMonitors(true, DuccContext.ManagedReservation); // starts conditionally, based on job spec and console listener present
}
return rc;
}
/**
* Main method, as used by the executable jar or direct java invocation.
*
* @param args
* arguments as described in the <a href="/doc/duccbook.html#DUCC_CLI_PROCESS_SUBMIT">DUCC CLI reference.</a>
*/
public static void main(String[] args) {
int code = 1; // Assume the worst
try {
// Instantiate the object with args similar to the CLI, or a pre-built properties file
DuccJedSubmit ds = new DuccJedSubmit(args);
// Run the API. If process_attach_console was specified in the args, a console listener is
// started but this call does NOT block on it.
boolean rc = ds.execute();
// If the return is 'true' then as best the API can tell, the submit worked
if (rc) {
System.out.println(dt + " " + ds.getDuccId() + " submitted.");
code = ds.getReturnCode();
} else {
System.out.println(dt + " Could not submit ");
}
} catch (Throwable e) {
System.out.println(dt + " Cannot initialize: " + e);
Throwable t = e;
while ((t = t.getCause()) != null) {
System.out.println(" ... " + t);
}
for (String arg : args) {
if (arg.equals("--debug")) {
e.printStackTrace();
break;
}
}
} finally {
// Set the process exit code
System.exit(code);
}
}
}