com.marklogic.hub.step.impl.StepRunnerUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of marklogic-data-hub Show documentation
Show all versions of marklogic-data-hub Show documentation
Library for Creating an Operational Data Hub on MarkLogic
package com.marklogic.hub.step.impl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.TextNode;
import com.marklogic.hub.flow.Flow;
import com.marklogic.hub.step.RunStepResponse;
import com.marklogic.hub.step.StepDefinition;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class StepRunnerUtil {
protected static RunStepResponse getResponse(JsonNode jobNode, String step) {
RunStepResponse stepDoc;
ObjectMapper objectMapper = new ObjectMapper();
try {
stepDoc = objectMapper.treeToValue(jobNode.get("job").get("stepResponses").get(step), RunStepResponse.class);
} catch (Exception e) {
throw new RuntimeException(e);
}
return stepDoc;
}
protected static RunStepResponse createStepResponse(Flow flow, String step, String jobId) {
RunStepResponse runStepResponse = RunStepResponse.withFlow(flow).withStep(step);
if (jobId == null) {
jobId = UUID.randomUUID().toString();
}
runStepResponse.withJobId(jobId);
return runStepResponse;
}
protected static String jsonToString(JsonNode node) {
try {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.writeValueAsString(node);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
protected static String objectToString(Object obj) {
String objStr = null;
if (obj instanceof String) {
objStr = (String) obj;
} else if (obj instanceof TextNode) {
objStr = ((TextNode) obj).textValue();
} else if (obj != null) {
objStr = obj.toString();
}
return objStr;
}
/**
* Note that this logic exists in flow-utils.mjs as well; this is apparently because FlowRunner needs to combine
* options before it runs any steps. But each call to process a batch of items also needs to combine steps, as
* it's not always invoked by FlowRunner. So there's some duplication that would be good to get rid of, possibly
* by having FlowRunner make a call to ML to combine options.
*
* @param flow
* @param stepDef
* @param stepNumber
* @param runtimeOptions
* @return
*/
public static Map makeCombinedOptions(Flow flow, StepDefinition stepDef, String stepNumber, Map runtimeOptions) {
ObjectMapper mapper = new ObjectMapper();
Map stepDefMap = null;
if (stepDef != null) {
stepDefMap = mapper.convertValue(stepDef.getOptions(), Map.class);
}
Map stepMap = null;
if (flow.getStep(stepNumber) != null) {
stepMap = mapper.convertValue(flow.getStep(stepNumber).getOptions(), Map.class);
}
Map flowMap = mapper.convertValue(flow.getOptions(), Map.class);
Map combinedOptions = new HashMap<>();
if (stepDefMap != null) {
combinedOptions.putAll(stepDefMap);
}
if (flowMap != null) {
combinedOptions.putAll(flowMap);
}
if (stepMap != null) {
combinedOptions.putAll(stepMap);
}
if (runtimeOptions != null) {
combinedOptions.putAll(runtimeOptions);
applyStepSpecificOptions(combinedOptions, stepNumber, runtimeOptions);
}
return combinedOptions;
}
/**
* Introduced in 5.5 as a way for step-specific options to be provided in the runtime options. A try/catch is used
* here in case the user does not conform to the schema of:
* - stepOptions must be a JSON object
* - each key should be a step number
* - the value of each key should be a JSON object containing the options specific to that step
*
* @param combinedOptions
* @param stepNumber
* @param runtimeOptions
*/
private static void applyStepSpecificOptions(Map combinedOptions, String stepNumber, Map runtimeOptions) {
if (runtimeOptions.containsKey("stepOptions")) {
try {
Map stepOptions = (Map) runtimeOptions.get("stepOptions");
if (stepOptions.containsKey(stepNumber)) {
Map stepSpecificOptions = (Map) stepOptions.get(stepNumber);
combinedOptions.putAll(stepSpecificOptions);
}
} catch (Exception ex) {
String message = "Unable to apply step-specific options found in 'stepOptions' in runtime options; " +
"stepOptions must be a JSON object whose keys are step numbers, and each key has a JSON object as its value, which contains " +
"the options specific to that step; error cause: " + ex.getMessage();
throw new IllegalArgumentException(message);
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy