我的Spring Boot应用程序连接到Camunda BPMN &静息。当用户单击UI屏幕上的批准/拒绝按钮时,REST调用触发一个BPMN工作流(在Camunda Spring Boot应用程序中),该工作流内部触发DMN根据DMN输入列中映射的一些业务规则查找输出。我们需要找到精确的匹配规则细节,比如匹配规则列表——输入值、输出值、匹配规则ID等。
流程引擎和dmn引擎中没有内置的方法,因此需要知道是否有一种方法可以手动将这些功能配置到Spring Boot自动配置的默认流程引擎中。
Camunda版本:7.13.0
在Spring Boot应用中,如果我们在pom.xml - camunda-bpm-spring-boot-starter, camunda-bpm-spring-boot-starter-webapp, camunda-bpm-spring-boot-starter-rest中设置了这些依赖项,那么在Spring Boot应用启动时,会自动配置一个默认的进程引擎。但是这个进程引擎默认不会启用规则细节。因此,我们配置了一个自定义的流程引擎插件,它将应用于默认的流程引擎之上,以便在每次命中DMN时获得匹配的规则细节。
import org.camunda.bpm.spring.boot.starter.annotation.EnableProcessApplication;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@EnableProcessApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}
自定义流程引擎:
import org.camunda.bpm.engine.impl.cfg.ProcessEnginePlugin;
import org.camunda.bpm.spring.boot.starter.configuration.Ordering;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
@Configuration
public class CamundaConfig {
@Bean
@Order(Ordering.DEFAULT_ORDER + 1)
public static ProcessEnginePlugin customProcessEnginePluginConfig() {
return new CustomProcessEnginePlugin();
}
}
我们的CustomProcessEnginePlugin
将扩展AbstractCamundaConfiguration
和override postInit()
方法。这个postInit()
方法增加了一个DmnDecisionTableEvaluationListener
。这个监听器触发一个事件,每次DMN命中匹配规则,并有notify()
方法与事件细节,其中包含所有的DMN细节,如dmnID
和匹配规则细节。
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.camunda.bpm.dmn.engine.delegate.DmnDecisionTableEvaluationEvent;
import org.camunda.bpm.dmn.engine.delegate.DmnDecisionTableEvaluationListener;
import org.camunda.bpm.dmn.engine.delegate.DmnEvaluatedDecisionRule;
import org.camunda.bpm.dmn.engine.delegate.DmnEvaluatedInput;
import org.camunda.bpm.dmn.engine.impl.DefaultDmnEngineConfiguration;
import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.camunda.bpm.engine.variable.value.TypedValue;
import org.camunda.bpm.spring.boot.starter.configuration.Ordering;
import org.camunda.bpm.spring.boot.starter.configuration.impl.AbstractCamundaConfiguration;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Component
@Order(Ordering.DEFAULT_ORDER + 1)
public class CustomProcessEnginePlugin extends AbstractCamundaConfiguration {
@Override
public void postInit(ProcessEngineConfigurationImpl processEngineConfig) {
DefaultDmnEngineConfiguration dmnEngineConfig = processEngineConfig.getDmnEngineConfiguration();
dmnEngineConfig.customPostDecisionTableEvaluationListeners(Collections.singletonList(new DmnDecisionTableEvaluationListener(){
@Override
public void notify(DmnDecisionTableEvaluationEvent event) {
String dmnID = event.getDecisionTable().getKey();
Map<String, TypedValue> dmnInput = event.getInputs().stream().collect(Collectors.toMap(DmnEvaluatedInput::getName, DmnEvaluatedInput::getValue));
List<DmnEvaluatedDecisionRule> matchingRuleList = new ArrayList<>();
matchingRuleList = event.getMatchingRules();
log.info("DMN ID = {}", dmnID);
log.info("DMN Input = {}", dmnInput);
if(null != matchingRuleList) {
log.info("DMN Matched Rules = {}", matchingRuleList.size());
if(!matchingRuleList.isEmpty()) {
for(DmnEvaluatedDecisionRule rule : matchingRuleList) {
log.info("DMN Matching Rule ID = {}", rule.getId());
log.info("DMN Output = {}", rule.getOutputEntries());
}
}
else {
log.info("DMN Output = No matching rule found");
}
}
log.info("************************************************************************************************");
}
}));
dmnEngineConfig.buildEngine();
processEngineConfig.setDmnEngineConfiguration(dmnEngineConfig);
}
}
还有另一种方法可以获得匹配规则的详细信息-通过实现ProcessEnginePlugin
和overriding postProcessEngineBuild()
和preInit()
方法,而不是像上面那样扩展AbstractCamundaConfiguration
和overriding postInit()
方法。