使用Java Camunda Springboot启动器创建多个DMN



我想创建一个Java服务,通过代码构建Camunda DMN。我使用的是camunda-springboot启动器依赖项,我能够生成DMN决策表,并且一个决策的输出用于另一个决策。我使用InformationRequirement进行同样的操作,但当我将模型写入文件并在建模器中打开该文件时,箭头不会指向信息需求,并且在部署决策后无法获得该输出。

<

public String generateDMN(String name, String title) throws FileNotFoundException {
DmnModelInstance modelInstance = initializeEmptyDmnModel();
Decision decision = modelInstance.newInstance(Decision.class);
decision.setId(title);
decision.setName(name);
modelInstance.getDefinitions().addChildElement(decision);
List<String[]> rules = new ArrayList<>();
try (CSVReader reader = new CSVReader(new FileReader("/Users/rahulnehete/IdeaProjects/java-rules-engine/src/main/resources/file.csv"))) {
rules = reader.readAll();
} catch (Exception e) {
log.error("Error reading CSV file ", e);
}
DecisionTable decisionTable = modelInstance.newInstance(DecisionTable.class);
decisionTable.setId("DecisionTable_"+name+"_"+title);
decisionTable.setHitPolicy(HitPolicy.COLLECT);
decision.addChildElement(decisionTable);
Decision decision2 = modelInstance.newInstance(Decision.class);
decision2.setId(title + "_2");
decision2.setName(name + "_2");
modelInstance.getDefinitions().addChildElement(decision2);
DecisionTable decisionTable2 = modelInstance.newInstance(DecisionTable.class);
decisionTable2.setId("DecisionTable_"+name+"_"+title+"_2");
decisionTable2.setHitPolicy(HitPolicy.COLLECT);
decision2.addChildElement(decisionTable2);
InformationRequirement infoRequirement = modelInstance.newInstance(InformationRequirement.class, "info1");
decision2.getInformationRequirements().add(infoRequirement);
infoRequirement.setRequiredDecision(decision);
String[] header = rules.remove(0);
String[] varTypes = rules.remove(0);
String[] variables = rules.remove(0);
Long numOfInputs = Arrays.stream(header).filter(k -> k.equalsIgnoreCase("input")).count();
Long numOfOutputs = Arrays.stream(header).filter(k -> k.equalsIgnoreCase("output")).count();
for(int i=0; i<numOfInputs; i++) {
Input ip = generateElement(modelInstance, Input.class, "Input_"+i);
InputExpression inputExpression = generateElement(modelInstance, InputExpression.class);
Text text = modelInstance.newInstance(Text.class);
inputExpression.setText(text);
inputExpression.setTypeRef(varTypes[i]);
ip.setLabel("Input " + i);
ip.setCamundaInputVariable(variables[i]);
ip.setInputExpression(inputExpression);
decisionTable.addChildElement(ip);
}
for(int i=numOfInputs.intValue(); i<=numOfOutputs; i++) {
Output op = generateElement(modelInstance, Output.class, "Output_"+i);
op.setLabel("Output " + i);
op.setName(variables[i]);
op.setTypeRef(varTypes[i]);
decisionTable.addChildElement(op);
}
for(int i = 1; i<rules.size(); i++) {
String[] rule = rules.get(i);
Rule dmnRule = createRule(modelInstance, numOfInputs.intValue(), numOfOutputs.intValue(), rule);
decisionTable.addChildElement(dmnRule);
log.info("Rule {} added", i);
}
Input ip = generateElement(modelInstance, Input.class, "Input_A");
InputExpression inputExpression = generateElement(modelInstance, InputExpression.class);
Text text = modelInstance.newInstance(Text.class);
inputExpression.setText(text);
inputExpression.setTypeRef("string");
ip.setLabel("Input A");
ip.setCamundaInputVariable("minPlafond");
ip.setInputExpression(inputExpression);
decisionTable2.addChildElement(ip);
Output op = generateElement(modelInstance, Output.class, "Output_A");
op.setLabel("Output A");
op.setName("FinalOutput");
op.setTypeRef("string");
decisionTable2.addChildElement(op);
// TODO: variable names
String[] rule = new String[] {"-", "$(minPlafond + " + ""_Success")"};
Rule dmnRule = createRule(modelInstance, 1, 1, rule);
decisionTable2.addChildElement(dmnRule);
log.info("Rule {} added", "new");
Dmn.validateModel(modelInstance);
try {
FileOutputStream fos = null;
fos = new FileOutputStream(name + "_" + title + ".dmn");
Dmn.writeModelToStream(fos, modelInstance);
fos.close();
} catch (IOException e) {
log.error("Error writing model instance ", e);
return REConstants.FAILED;
}
return "DMN GENERATED";
}
private DmnModelInstance initializeEmptyDmnModel() {
DmnModelInstance dmnModel = Dmn.createEmptyModel();
Definitions definitions = generateNamedElement(dmnModel, Definitions.class, "definitions", "definitions");
definitions.setNamespace(DmnModelConstants.CAMUNDA_NS);
dmnModel.setDefinitions(definitions);
return dmnModel;
}
private <E extends DmnElement> E generateElement(DmnModelInstance modelInstance, Class<E> elementClass, String id) {
E element = modelInstance.newInstance(elementClass);
element.setId(id);
return element;
}
private <E extends NamedElement> E generateNamedElement(DmnModelInstance modelInstance, Class<E> elementClass, String name, String id) {
E element = generateElement(modelInstance, elementClass, id);
element.setName(name);
return element;
}
private <E extends DmnElement> E generateElement(DmnModelInstance modelInstance, Class<E> elementClass) {
String generatedId = elementClass.getSimpleName() + UUID.randomUUID();
return generateElement(modelInstance, elementClass, generatedId);
}
private Rule createRule(DmnModelInstance dmnModelInstance, int numberOfInputs, int numberOfOutputs, String[] ruleInput) {
Rule rule = dmnModelInstance.newInstance(Rule.class);
for(int i=0; i<numberOfOutputs; i++) {
OutputEntry outputEntry = createOutputEntry(dmnModelInstance, ruleInput[numberOfInputs + i]);
rule.getOutputEntries().add(outputEntry);
}
for (int i = 0; i < numberOfInputs; i++) {
InputEntry inputEntry = createInputEntry(dmnModelInstance, ruleInput[i]);
rule.getInputEntries().add(inputEntry);
}
return rule;
}
private InputEntry createInputEntry(DmnModelInstance dmnModelInstance, String expression) {
Text text = dmnModelInstance.newInstance(Text.class);
text.setTextContent(expression);
InputEntry inputEntry = dmnModelInstance.newInstance(InputEntry.class);
inputEntry.setText(text);
return inputEntry;
}
private OutputEntry createOutputEntry(DmnModelInstance dmnModelInstance, String expression) {
Text text = dmnModelInstance.newInstance(Text.class);
text.setTextContent(expression);
OutputEntry outputEntry = dmnModelInstance.newInstance(OutputEntry.class);
outputEntry.setText(text);
return outputEntry;
}

}

您在模型级别正确地实现了决策、决策表、输入和输出以及信息需求(xmlns="https://www.omg.org/spec/DMN/20191111/MODEL/"(。(Dmn.writeModelToFile(新文件("src/main/resources/my.Dmn"(,modelInstance(;比自己编写流稍微紧凑一点。(

当您与Modeler创建的模型进行比较时,您会发现它使用了额外的名称空间,如xmlns:dmndi="https://www.omg.org/spec/DMN/20191111/DMNDI/"。此名称空间将图表信息与模型分开定义,例如:

<dmndi:DMNDI>
<dmndi:DMNDiagram id="DMNDiagram_12sfwjw">
<dmndi:DMNShape id="DMNShape_1m8k4eq" dmnElementRef="Decision1">
<dc:Bounds height="80" width="180" x="150" y="80" />
</dmndi:DMNShape>
<dmndi:DMNShape id="DMNShape_15h0omx" dmnElementRef="Decision2">
<dc:Bounds height="80" width="180" x="240" y="200" />
</dmndi:DMNShape>
<dmndi:DMNEdge id="DMNEdge_15fnvnh" dmnElementRef="InformationRequirement_0a97hay">
<di:waypoint x="330" y="200" />
<di:waypoint x="240" y="180" />
<di:waypoint x="240" y="160" />
</dmndi:DMNEdge>
</dmndi:DMNDiagram>
</dmndi:DMNDI>

不幸的是,Camunda API目前无法自动生成或创建此图表信息。您必须使用XML库将其降低一个级别。

该模型在没有图表信息的情况下是可执行的。所以,你将有一个工作模式。也许这是可以接受的,只有当人类关心DRD时,它才能手动创建?

另一种选择是放弃Java方法,尝试https://bpmn.io/toolkit/dmn-js/.

最新更新