/*
# Licensed Materials - Property of IBM
# Copyright IBM Corp. 2016
*/
package com.ibm.streamsx.topology.jobconfig;
import static com.ibm.streamsx.topology.context.ContextProperties.SUBMISSION_PARAMS;
import static com.ibm.streamsx.topology.context.ContextProperties.TRACING_LEVEL;
import static com.ibm.streamsx.topology.context.JobProperties.CONFIG;
import static com.ibm.streamsx.topology.context.JobProperties.DATA_DIRECTORY;
import static com.ibm.streamsx.topology.context.JobProperties.GROUP;
import static com.ibm.streamsx.topology.context.JobProperties.NAME;
import static com.ibm.streamsx.topology.context.JobProperties.OVERRIDE_RESOURCE_LOAD_PROTECTION;
import static com.ibm.streamsx.topology.context.JobProperties.PRELOAD_APPLICATION_BUNDLES;
import static com.ibm.streamsx.topology.internal.streams.Util.getConfigEntry;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import com.ibm.json.java.JSONObject;
import com.ibm.streams.operator.logging.TraceLevel;
import com.ibm.streamsx.topology.context.JobProperties;
import com.ibm.streamsx.topology.internal.streams.Util;
/**
* A job configuration.
*
* Used to control the submission of a job to a distributed context.
*
*/
public class JobConfig {
private String jobName;
private String jobGroup;
private String dataDirectory;
private transient Boolean overrideResourceLoadProtection;
private Boolean preloadApplicationBundles;
private List<SubmissionParameter> submissionParameters;
private transient Level _tracing;
private String tracing;
/**
* An empty job configuration.
*/
public JobConfig() {
}
/**
* Job configuration with a job name and group.
* @param jobName Job group, can be {@code null}.
* @param jobGroup Job name, can be {@code null}.
*/
public JobConfig(String jobGroup, String jobName) {
setJobGroup(jobGroup);
setJobName(jobName);
}
public JobConfig addToConfig(Map<String, Object> config) {
config.put(JobProperties.CONFIG, this);
return this;
}
/**
* Get the job name.
* @return Job name, {@code null} if it is not set.
*/
public String getJobName() {
return jobName;
}
/**
* Set the job name.
* @param jobName Job name, {@code null} unsets the name.
*/
public void setJobName(String jobName) {
this.jobName = jobName;
}
/**
* Get the job group.
* @return Job group, {@code null} if it is not set.
*/
public String getJobGroup() {
return jobGroup;
}
/**
* Set the job group.
* @param jobGroup Job group, {@code null} unsets the group.
*/
public void setJobGroup(String jobGroup) {
this.jobGroup = jobGroup;
}
/**
* Get the data directory.
* @return Data directory, {@code null} if it is not set.
*/
public String getDataDirectory() {
return dataDirectory;
}
/**
* Set the data directory.
* The data directory must be a valid path on the
* IBM Streams instance the job will execute on.
* @param dataDirectory Data directory, {@code null} unsets the data directory.
*/
public void setDataDirectory(String dataDirectory) {
this.dataDirectory = dataDirectory;
}
public Boolean getOverrideResourceLoadProtection() {
return overrideResourceLoadProtection;
}
public void setOverrideResourceLoadProtection(Boolean overrideResourceLoadProtection) {
this.overrideResourceLoadProtection = overrideResourceLoadProtection;
}
/**
* @return the tracing
*/
public Level getTracing() {
return _tracing;
}
public String getStreamsTracing() {
return tracing;
}
/**
* @param tracing the tracing to set
*/
public void setTracing(Level tracing) {
if (tracing == null)
this.tracing = null;
else
this.tracing = toTracingLevel(tracing);
this._tracing = tracing;
}
public Boolean getPreloadApplicationBundles() {
return preloadApplicationBundles;
}
public void setPreloadApplicationBundles(Boolean preloadApplicationBundles) {
this.preloadApplicationBundles = preloadApplicationBundles;
}
/**
* Have any submission parameters been added.
* @return {@code true} if at least one submission exists, otherwise {@code false}.
*/
public boolean hasSubmissionParameters() {
return submissionParameters != null
&& !submissionParameters.isEmpty();
}
private List<SubmissionParameter> createSubmissionParameters() {
if (submissionParameters == null)
submissionParameters = new ArrayList<>();
return submissionParameters;
}
/**
* Get the submission parameters.
* Any modifications to the returned list modify the submission
* parameters for this object.
* @return Submission parameters, will be empty if none have been set.
*/
public List<SubmissionParameter> getSubmissionParameters() {
return createSubmissionParameters();
}
public void addSubmissionParameter(String name, boolean value) {
createSubmissionParameters().add(new SubmissionParameter(name, value));
}
public void addSubmissionParameter(String name, String value) {
createSubmissionParameters().add(new SubmissionParameter(name, value));
}
public void addSubmissionParameter(String name, Number value) {
createSubmissionParameters().add(new SubmissionParameter(name, value));
}
/**
* Create a {@code JobConfig} from a configuration map.
* If {@code config} contains {@link JobProperties#CONFIG} and
* it is an instance of {@code JobConfig} then it is returned.
* <BR>
* Otherwise a {@code JobConfig} object is created from other
* {@code JobProperties} in {@code config}. If none exist then
* an empty {@code JobConfig} is returned.
* @param config Submission configuration.
* @return JobConfig from {@code config}.
*
* @see JobProperties
*/
@SuppressWarnings("unchecked")
public static JobConfig fromProperties(Map<String,? extends Object> config) {
if (config.containsKey(CONFIG)) {
if (config.get(CONFIG) instanceof JSONObject) {
JSONObject json = getConfigEntry(config, CONFIG, JSONObject.class);
return fromJSON(json);
}
return getConfigEntry(config, CONFIG, JobConfig.class);
}
JobConfig jc = fromPrimitiveValues(config);
if (config.containsKey(SUBMISSION_PARAMS)) {
Map<String,Object> params = (Map<String,Object>) config.get(SUBMISSION_PARAMS);
for (String name : params.keySet()) {
jc.addSubmissionParameter(name, params.get(name).toString());
}
}
if (config.containsKey(TRACING_LEVEL))
jc.setTracing(Util.getConfigEntry(config, TRACING_LEVEL, Level.class));
return jc;
}
/**
* Works from a set of individual values in a config
* and from a JSON config.
*/
private static JobConfig fromPrimitiveValues(Map<String,? extends Object> config) {
JobConfig jc = new JobConfig();
if (config.containsKey(NAME))
jc.setJobName(getConfigEntry(config, NAME, String.class));
if (config.containsKey(GROUP))
jc.setJobGroup(getConfigEntry(config, GROUP, String.class));
if (config.containsKey(DATA_DIRECTORY))
jc.setDataDirectory(getConfigEntry(config, DATA_DIRECTORY, String.class));
if (config.containsKey(OVERRIDE_RESOURCE_LOAD_PROTECTION))
jc.setOverrideResourceLoadProtection(Util.getConfigEntry(config,
OVERRIDE_RESOURCE_LOAD_PROTECTION, Boolean.class));
if (config.containsKey(PRELOAD_APPLICATION_BUNDLES))
jc.setPreloadApplicationBundles(Util.getConfigEntry(config,
PRELOAD_APPLICATION_BUNDLES, Boolean.class));
return jc;
}
/**
* Works from a set of individual values in a config
* and from a JSON config.
*/
private static JobConfig fromJSON(JSONObject config) {
JobConfig jc = new JobConfig();
if (config.containsKey("jobName"))
jc.setJobName(config.get("jobName").toString());
if (config.containsKey("jobGroup"))
jc.setJobGroup(config.get("jobGroup").toString());
if (config.containsKey("dataDirectory"))
jc.setDataDirectory(config.get("dataDirectory").toString());
if (config.containsKey("overrideResourceLoadProtection"))
jc.setOverrideResourceLoadProtection((Boolean) config.get("overrideResourceLoadProtection"));
if (config.containsKey("preloadApplicationBundles"))
jc.setPreloadApplicationBundles((Boolean) config.get("preloadApplicationBundles"));
return jc;
}
private static String toTracingLevel(Level level) {
int tli = level.intValue();
String tls;
if (tli == Level.OFF.intValue())
tls = "off";
else if (tli == Level.ALL.intValue())
tls = "debug";
else if (tli >= TraceLevel.ERROR.intValue())
tls = "error";
else if (tli >= TraceLevel.WARN.intValue())
tls = "warn";
else if (tli >= TraceLevel.INFO.intValue())
tls = "info";
else if (tli >= TraceLevel.DEBUG.intValue())
tls = "debug";
else if (tli >= TraceLevel.TRACE.intValue())
tls = "trace";
else
tls = "trace";
return tls;
}
}