/*
*
* Copyright 2015 the original author or authors.
*
* 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 org.springframework.xd.dirt.job.dsl;
import java.util.Collection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author Glenn Renfro
*/
public class ComposedJobUtil {
public static final String MODULE_SUFFIX = "_COMPOSED";
private static String orchestrationPatternString = "(\\|\\|" +//search for || in the definition
"(?=([^\\\"']*[\\\"'][^\\\"']*[\\\"'])*[^\\\"']*$))" + //make sure its not in quotes
"|(\\&" + //or find a & in the definition
"(?=([^\\\"']*[\\\"'][^\\\"']*[\\\"'])*[^\\\"']*$))";// make sure its not in quotes
private static String parameterPatternString = "(--" +//search for -- in the definition
"(?=([^\\\"']*[\\\"'][^\\\"']*[\\\"'])*[^\\\"']*$))"; //make sure its not in quotes
private static Pattern orchestrationPattern = Pattern.compile(orchestrationPatternString);
private static Pattern parameterPattern = Pattern.compile(parameterPatternString);
/**
* Returns the composed module name for the job
* @param jobName - base name for the job
* @return the fully qualified name for composed job module
*/
public static String getComposedJobModuleName(String jobName){
return jobName + MODULE_SUFFIX;
}
/**
* Is this definition a composed job definition
* @param definition the definition the user specified
* @return true if a valid composed job definition else false.
*/
public static boolean isComposedJobDefinition(String definition){
boolean result = false;
try {
JobParser parser = new JobParser();
JobSpecification jobSpecification = parser.parse(definition);
if (jobSpecification.getJobReferences().size() > 1) {
result = true;
}
//Check for single instanceof job with a transition
if (jobSpecification.getJobReferences().size() == 1){
JobReference reference = jobSpecification.getJobReferences().get(0);
if( reference.transitions != null && reference.transitions.size() > 0){
result = true;
}
}
} catch (JobSpecificationException e) {
//failed to parse, could still be a composed job. Look for basic components
// such as || or & if found return true.
Matcher matcher = orchestrationPattern.matcher(definition);
result = matcher.find();
}
return result;
}
/**
* Throws exception if user tries to create a single job instance with no transitions.
* @param definition the definition to be validated
* @param jobInstances collection of available job instances
*/
public static void validateNotSingleJobInstance(String definition, Collection<String> jobInstances) {
JobSpecification jobSpecification = null;
try {
JobParser parser = new JobParser();
jobSpecification = parser.parse(definition);
} catch (JobSpecificationException e) {
return; //failed to parse.
}
if (jobSpecification.getJobReferences().size() == 1) {
String jobName = jobSpecification.getJobReferences().get(0).getName();
if (jobInstances.contains(jobName)) {
throw new IllegalStateException(String.format(
"Job Instance specified %s must use transitions. Or just " +
"launch the job instance directly", jobName));
}
}
}
public static String getPropertyDefinition() {
return "options.timeout.description=The timeout for the slave jobs within this orchestration. -1 indicates no timeout. \n" +
"options.timeout.default=-1\n" +
"options.timeout.type=long";
}
public static String getDefinitionParameters(String definition) {
Matcher matcher = parameterPattern.matcher(definition);
String result = "";
if (matcher.find()){
result = " " + definition.substring(matcher.start());
}
return result;
}
}