Commit 5a16c8f0 authored by gavin2lee's avatar gavin2lee
Browse files

#2109 handle user task output

Showing with 234 additions and 92 deletions
+234 -92
package com.webank.wecube.platform.core.service.workflow;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
......@@ -18,11 +19,14 @@ import com.webank.wecube.platform.core.commons.ApplicationProperties;
import com.webank.wecube.platform.core.commons.WecubeCoreException;
import com.webank.wecube.platform.core.entity.plugin.PluginConfigInterfaceParameters;
import com.webank.wecube.platform.core.entity.plugin.PluginConfigInterfaces;
import com.webank.wecube.platform.core.entity.workflow.ProcDefInfoEntity;
import com.webank.wecube.platform.core.entity.workflow.ProcExecBindingEntity;
import com.webank.wecube.platform.core.entity.workflow.ProcExecContextEntity;
import com.webank.wecube.platform.core.entity.workflow.ProcInstInfoEntity;
import com.webank.wecube.platform.core.entity.workflow.TaskNodeDefInfoEntity;
import com.webank.wecube.platform.core.entity.workflow.TaskNodeInstInfoEntity;
import com.webank.wecube.platform.core.model.workflow.PluginInvocationCommand;
import com.webank.wecube.platform.core.model.workflow.WorkflowInstCreationContext;
import com.webank.wecube.platform.core.model.workflow.WorkflowNotifyEvent;
import com.webank.wecube.platform.core.repository.workflow.ExtraTaskMapper;
import com.webank.wecube.platform.core.repository.workflow.ProcDefInfoMapper;
......@@ -51,7 +55,7 @@ public abstract class AbstractPluginInvocationService extends AbstractWorkflowSe
protected static final String RESULT_CODE_OK = "0";
protected static final String RESULT_CODE_ERR = "1";
protected static final String PLUGIN_RESULT_CODE_FAIL = "1";
protected static final String PLUGIN_RESULT_CODE_PARTIALLY_FAIL = "1";
protected static final String PLUGIN_RESULT_CODE_PARTIALLY_KEY = "errorCode";
......@@ -63,10 +67,10 @@ public abstract class AbstractPluginInvocationService extends AbstractWorkflowSe
protected static final int DEFAULT_VALUE_DATA_TYPE_NUMBER = 0;
protected static final int MAX_PARAM_VAL_SIZE = 3000;
protected static final String PARAM_NAME_TASK_FORM_INPUT = "taskFormInput";
protected static final String PARAM_NAME_TASK_FORM_OUTPUT = "taskFormOutput";
protected static final String TEMPORARY_ENTITY_ID_PREFIX = "OID-";
protected final Logger log = LoggerFactory.getLogger(this.getClass());
......@@ -91,13 +95,13 @@ public abstract class AbstractPluginInvocationService extends AbstractWorkflowSe
@Autowired
protected StandardEntityOperationService entityOperationService;
@Autowired
protected ApplicationProperties applicationProperties;
@Autowired
protected SimpleEncryptionService simpleEncryptionService;
@Autowired
protected PluginInvocationRestClient pluginInvocationRestClient;
......@@ -130,27 +134,25 @@ public abstract class AbstractPluginInvocationService extends AbstractWorkflowSe
@Autowired
protected ExtraTaskMapper extraTaskMapper;
@Autowired
protected EntityQueryExpressionParser entityQueryExpressionParser;
@Autowired
protected PluginTaskFormRestClient pluginTaskFormRestClient;
@Autowired
protected ProcExecContextMapper procExecContextMapper;
@Autowired
protected EntityDataRouteFactory entityDataRouteFactory;
@Autowired
@Qualifier(value = "jwtSsoRestTemplate")
protected RestTemplate jwtSsoRestTemplate;
protected ObjectMapper objectMapper = new ObjectMapper();
/**
*
* @param cmd
......@@ -219,7 +221,7 @@ public abstract class AbstractPluginInvocationService extends AbstractWorkflowSe
workflowProcInstEndEventNotifier.notify(WorkflowNotifyEvent.PROCESS_INSTANCE_END, cmd, procInstEntity);
}
protected void refreshStatusOfPreviousNodes(List<TaskNodeInstInfoEntity> nodeInstEntities,
TaskNodeDefInfoEntity currNodeDefInfo) {
List<String> previousNodeIds = unmarshalNodeIds(currNodeDefInfo.getPrevNodeIds());
......@@ -345,7 +347,7 @@ public abstract class AbstractPluginInvocationService extends AbstractWorkflowSe
if (!(obj instanceof Map)) {
log.error("unexpected data type:returned object is not a instance of map, obj={}", obj);
throw new WecubeCoreException("3163","Unexpected data type");
throw new WecubeCoreException("3163", "Unexpected data type");
}
@SuppressWarnings("unchecked")
......@@ -368,32 +370,32 @@ public abstract class AbstractPluginInvocationService extends AbstractWorkflowSe
return null;
}
protected String tryEncodeParamDataValue(String rawDataValue){
if(StringUtils.isBlank(rawDataValue)){
protected String tryEncodeParamDataValue(String rawDataValue) {
if (StringUtils.isBlank(rawDataValue)) {
return rawDataValue;
}
String cipherDataValue = simpleEncryptionService.encodeToAesBase64(rawDataValue);
return cipherDataValue;
}
protected String tryDecodeParamDataValue(String cipherDataValue){
if(StringUtils.isBlank(cipherDataValue)){
protected String tryDecodeParamDataValue(String cipherDataValue) {
if (StringUtils.isBlank(cipherDataValue)) {
return cipherDataValue;
}
String rawDataValue = null;
try{
try {
rawDataValue = simpleEncryptionService.decodeFromAesBase64(cipherDataValue);
}catch(Exception e){
} catch (Exception e) {
log.info("errors while decode cipher data value:{},error:{}", cipherDataValue, e.getMessage());
rawDataValue = cipherDataValue;
}
return rawDataValue;
}
protected boolean isSystemAutomationTaskNode(TaskNodeDefInfoEntity taskNodeDefEntity) {
return TASK_CATEGORY_SSTN.equalsIgnoreCase(taskNodeDefEntity.getTaskCategory());
}
......@@ -405,7 +407,7 @@ public abstract class AbstractPluginInvocationService extends AbstractWorkflowSe
protected boolean isDataOperationTaskNode(TaskNodeDefInfoEntity taskNodeDefEntity) {
return TASK_CATEGORY_SDTN.equalsIgnoreCase(taskNodeDefEntity.getTaskCategory());
}
protected boolean isDynamicBindTaskNode(TaskNodeDefInfoEntity taskNodeDef) {
return TaskNodeDefInfoEntity.DYNAMIC_BIND_YES.equalsIgnoreCase(taskNodeDef.getDynamicBind());
}
......@@ -413,7 +415,7 @@ public abstract class AbstractPluginInvocationService extends AbstractWorkflowSe
protected boolean isBoundTaskNodeInst(TaskNodeInstInfoEntity taskNodeInst) {
return TaskNodeInstInfoEntity.BIND_STATUS_BOUND.equalsIgnoreCase(taskNodeInst.getBindStatus());
}
protected void storeProcExecBindingEntities(List<ProcExecBindingEntity> nodeObjectBindings) {
if (nodeObjectBindings == null || nodeObjectBindings.isEmpty()) {
return;
......@@ -424,6 +426,44 @@ public abstract class AbstractPluginInvocationService extends AbstractWorkflowSe
}
}
protected WorkflowInstCreationContext tryFetchWorkflowInstCreationContext(
TaskNodeInstInfoEntity taskNodeInstEntity) {
List<ProcExecContextEntity> procExecContextEntities = this.procExecContextMapper.selectAllContextByCtxType(
taskNodeInstEntity.getProcDefId(), taskNodeInstEntity.getProcInstId(),
ProcExecContextEntity.CTX_TYPE_PROCESS);
if (procExecContextEntities == null || procExecContextEntities.isEmpty()) {
log.info("Cannot find any process creation context infomation for {} {}", taskNodeInstEntity.getProcDefId(),
taskNodeInstEntity.getProcInstId());
return null;
}
ProcExecContextEntity procExecContextEntity = procExecContextEntities.get(0);
String ctxJsonData = procExecContextEntity.getCtxData();
if (StringUtils.isBlank(ctxJsonData)) {
log.info("Context data is blank for {} {}", taskNodeInstEntity.getProcDefId(),
taskNodeInstEntity.getProcInstId());
return null;
}
WorkflowInstCreationContext ctx = convertJsonToWorkflowInstCreationContext(ctxJsonData.trim());
return ctx;
}
protected WorkflowInstCreationContext convertJsonToWorkflowInstCreationContext(String ctxJsonData) {
try {
WorkflowInstCreationContext ctx = objectMapper.readValue(ctxJsonData, WorkflowInstCreationContext.class);
return ctx;
} catch (IOException e) {
log.error("Failed to read json value:" + ctxJsonData, e);
throw new WecubeCoreException("Failed to read JSON to object.");
}
}
protected String marshalPluginInvocationCommand(PluginInvocationCommand cmd) {
String json;
try {
......@@ -433,7 +473,7 @@ public abstract class AbstractPluginInvocationService extends AbstractWorkflowSe
throw new WecubeCoreException("Failed to marshal plugin invocation command.", e);
}
}
protected String calculateDataModelExpression(TaskNodeDefInfoEntity f) {
if (StringUtils.isBlank(f.getRoutineExp())) {
return null;
......@@ -457,4 +497,14 @@ public abstract class AbstractPluginInvocationService extends AbstractWorkflowSe
return expr + inter.getFilterRule();
}
protected String convertWorkflowInstCreationContextToJson(WorkflowInstCreationContext ctx) {
try {
String json = this.objectMapper.writeValueAsString(ctx);
return json;
} catch (JsonProcessingException e) {
log.error("Failed to write object to string.", e);
throw new WecubeCoreException("JSON convertion exception.");
}
}
}
package com.webank.wecube.platform.core.service.workflow;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;
......@@ -11,14 +12,21 @@ import com.webank.wecube.platform.core.commons.WecubeCoreException;
import com.webank.wecube.platform.core.dto.workflow.PluginAsyncInvocationResultDto;
import com.webank.wecube.platform.core.entity.plugin.PluginConfigInterfaceParameters;
import com.webank.wecube.platform.core.entity.plugin.PluginConfigInterfaces;
import com.webank.wecube.platform.core.entity.workflow.ProcExecContextEntity;
import com.webank.wecube.platform.core.entity.workflow.TaskNodeDefInfoEntity;
import com.webank.wecube.platform.core.entity.workflow.TaskNodeExecParamEntity;
import com.webank.wecube.platform.core.entity.workflow.TaskNodeExecRequestEntity;
import com.webank.wecube.platform.core.entity.workflow.TaskNodeInstInfoEntity;
import com.webank.wecube.platform.core.model.workflow.PluginInvocationCommand;
import com.webank.wecube.platform.core.model.workflow.PluginInvocationResult;
import com.webank.wecube.platform.core.model.workflow.WorkflowInstCreationContext;
import com.webank.wecube.platform.core.service.dme.EntityOperationRootCondition;
import com.webank.wecube.platform.core.service.workflow.PluginInvocationProcessor.PluginInterfaceInvocationContext;
import com.webank.wecube.platform.core.support.plugin.dto.DynamicEntityAttrValueDto;
import com.webank.wecube.platform.core.support.plugin.dto.DynamicEntityValueDto;
import com.webank.wecube.platform.core.support.plugin.dto.TaskFormDataEntityDto;
import com.webank.wecube.platform.core.support.plugin.dto.TaskFormItemValueDto;
import com.webank.wecube.platform.core.support.plugin.dto.TaskFormValueDto;
import com.webank.wecube.platform.workflow.WorkflowConstants;
/**
......@@ -106,8 +114,6 @@ public class AsyncPluginInvocationService extends AbstractPluginInvocationServic
ctx.getRequestId());
throw new WecubeCoreException("3157", "Task node definition does not exist.");
}
//TODO #2109 handle user task output
PluginConfigInterfaces pluginConfigInterface = pluginConfigMgmtService
.getPluginConfigInterfaceByServiceName(nodeDefEntity.getServiceId());
......@@ -231,7 +237,16 @@ public class AsyncPluginInvocationService extends AbstractPluginInvocationServic
}
private void handleResultData(PluginInterfaceInvocationContext ctx, List<Object> resultData) {
TaskNodeDefInfoEntity taskNodeDefEntity = ctx.getTaskNodeDefEntity();
if (isUserTaskNode(taskNodeDefEntity)) {
handleUserTaskResultData(ctx, resultData);
} else {
handleNormalResultData(ctx, resultData);
}
}
private void handleNormalResultData(PluginInterfaceInvocationContext ctx, List<Object> resultData) {
List<Map<String, Object>> outputParameterMaps = validateAndCastResultData(resultData);
storeOutputParameterMaps(ctx, outputParameterMaps);
......@@ -250,6 +265,131 @@ public class AsyncPluginInvocationService extends AbstractPluginInvocationServic
return;
}
private void handleUserTaskResultData(PluginInterfaceInvocationContext ctx, List<Object> resultData) {
List<Map<String, Object>> outputParameterMaps = validateAndCastResultData(resultData);
storeOutputParameterMaps(ctx, outputParameterMaps);
for (Map<String, Object> outputParameterMap : outputParameterMaps) {
handleSingleOutputMapForUserTask(ctx, outputParameterMap);
}
}
private void handleSingleOutputMapForUserTask(PluginInterfaceInvocationContext ctx,
Map<String, Object> outputParameterMap) {
PluginConfigInterfaces intf = ctx.getPluginConfigInterface();
List<PluginConfigInterfaceParameters> outputParameters = intf.getOutputParameters();
if (outputParameters == null || outputParameters.isEmpty()) {
return;
}
boolean hasTaskFormOutputParam = false;
for (PluginConfigInterfaceParameters outputParamDef : outputParameters) {
if (PARAM_NAME_TASK_FORM_OUTPUT.equals(outputParamDef.getName())) {
hasTaskFormOutputParam = true;
break;
}
}
if (!hasTaskFormOutputParam) {
return;
}
Object taskFormOutputValue = outputParameterMap.get(PARAM_NAME_TASK_FORM_OUTPUT);
if (taskFormOutputValue == null) {
return;
}
String taskFormOutputValueAsJson = (String) taskFormOutputValue;
if (StringUtils.isBlank(taskFormOutputValueAsJson)) {
return;
}
TaskNodeInstInfoEntity nodeInstInfo = ctx.getTaskNodeInstEntity();
List<ProcExecContextEntity> procExecContextEntities = this.procExecContextMapper.selectAllContextByCtxType(
nodeInstInfo.getProcDefId(), nodeInstInfo.getProcInstId(), ProcExecContextEntity.CTX_TYPE_PROCESS);
if (procExecContextEntities == null || procExecContextEntities.isEmpty()) {
log.info("Cannot find any process creation context infomation for {} {}", nodeInstInfo.getProcDefId(),
nodeInstInfo.getProcInstId());
return;
}
ProcExecContextEntity procExecContextEntity = procExecContextEntities.get(0);
String ctxJsonData = procExecContextEntity.getCtxData();
if (StringUtils.isBlank(ctxJsonData)) {
log.info("Context data is blank for {} {}", nodeInstInfo.getProcDefId(), nodeInstInfo.getProcInstId());
return;
}
WorkflowInstCreationContext creationCtx = convertJsonToWorkflowInstCreationContext(ctxJsonData.trim());
if (creationCtx == null) {
return;
}
TaskFormValueDto taskFormValueDto = convertJsonToTaskFormValueDto(taskFormOutputValueAsJson);
List<TaskFormDataEntityDto> formDataEntities = taskFormValueDto.getFormDataEntities();
if (formDataEntities == null || formDataEntities.isEmpty()) {
return;
}
for (TaskFormDataEntityDto formDataEntity : formDataEntities) {
DynamicEntityValueDto existingEntityValue = creationCtx.findByOid(formDataEntity.getOid());
if (existingEntityValue == null) {
continue;
}
refreshDynamicEntityValueDto(existingEntityValue, formDataEntity);
}
String creationCtxUpdate = convertWorkflowInstCreationContextToJson(creationCtx);
procExecContextEntity.setUpdatedBy(WorkflowConstants.DEFAULT_USER);
procExecContextEntity.setUpdatedTime(new Date());
procExecContextEntity.setCtxData(creationCtxUpdate);
this.procExecContextMapper.updateByPrimaryKeySelective(procExecContextEntity);
}
private void refreshDynamicEntityValueDto(DynamicEntityValueDto existingEntityValue,
TaskFormDataEntityDto formDataEntity) {
List<TaskFormItemValueDto> formItemValues = formDataEntity.getFormItemValues();
if (formItemValues == null || formItemValues.isEmpty()) {
return;
}
for (TaskFormItemValueDto formItemValue : formItemValues) {
String attrName = formItemValue.getAttrName();
DynamicEntityAttrValueDto existingAttrValue = existingEntityValue.findAttrValue(attrName);
if (existingAttrValue == null) {
existingAttrValue = new DynamicEntityAttrValueDto();
existingAttrValue.setAttrDefId(null);
existingAttrValue.setAttrName(attrName);
existingAttrValue.setDataType(null);
existingAttrValue.setDataValue(formItemValue.getAttrValue());
existingEntityValue.addAttrValue(existingAttrValue);
} else {
existingAttrValue.setDataValue(formItemValue.getAttrValue());
}
}
}
private TaskFormValueDto convertJsonToTaskFormValueDto(String jsonData) {
try {
TaskFormValueDto dto = objectMapper.readValue(jsonData, TaskFormValueDto.class);
return dto;
} catch (IOException e) {
log.error("Failed to read value from json.", e);
throw new WecubeCoreException("Failed to read value from json.");
}
}
private void handleSingleOutputMap(PluginInterfaceInvocationContext ctx, Map<String, Object> outputParameterMap) {
PluginConfigInterfaces pci = ctx.getPluginConfigInterface();
......@@ -264,7 +404,6 @@ public class AsyncPluginInvocationService extends AbstractPluginInvocationServic
return;
}
//TODO #2169 to support entity creation
String nodeEntityId = (String) outputParameterMap.get(CALLBACK_PARAMETER_KEY);
if (StringUtils.isBlank(nodeEntityId)) {
......@@ -277,12 +416,11 @@ public class AsyncPluginInvocationService extends AbstractPluginInvocationServic
&& PLUGIN_RESULT_CODE_PARTIALLY_FAIL.equalsIgnoreCase(errorCodeOfSingleRecord)) {
log.info("such request is partially failed for request:{} and {}:{}", ctx.getRequestId(),
CALLBACK_PARAMETER_KEY, nodeEntityId);
//TODO to store status
// TODO to store status
return;
}
//TODO #2169 to support entity creation
for (PluginConfigInterfaceParameters pciParam : outputParameters) {
String paramName = pciParam.getName();
String paramExpr = pciParam.getMappingEntityExpression();
......
......@@ -7,7 +7,6 @@ import static com.webank.wecube.platform.core.utils.Constants.MAPPING_TYPE_CONTE
import static com.webank.wecube.platform.core.utils.Constants.MAPPING_TYPE_ENTITY;
import static com.webank.wecube.platform.core.utils.Constants.MAPPING_TYPE_SYSTEM_VARIABLE;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
......@@ -309,8 +308,7 @@ public class PluginInvocationService extends AbstractPluginInvocationService {
return;
}
WorkflowInstCreationContext ctx = tryFetchWorkflowInstCreationContext(procInstEntity, taskNodeInstEntity,
procDefInfoEntity, taskNodeDefEntity, cmd);
WorkflowInstCreationContext ctx = tryFetchWorkflowInstCreationContext(taskNodeInstEntity);
if (ctx == null) {
return;
}
......@@ -624,42 +622,8 @@ public class PluginInvocationService extends AbstractPluginInvocationService {
return taskFormValueDto;
}
private WorkflowInstCreationContext tryFetchWorkflowInstCreationContext(ProcInstInfoEntity procInstEntity,
TaskNodeInstInfoEntity taskNodeInstEntity, ProcDefInfoEntity procDefInfoEntity,
TaskNodeDefInfoEntity taskNodeDefEntity, PluginInvocationCommand cmd) {
List<ProcExecContextEntity> procExecContextEntities = this.procExecContextMapper.selectAllContextByCtxType(
procDefInfoEntity.getId(), procInstEntity.getId(), ProcExecContextEntity.CTX_TYPE_PROCESS);
if (procExecContextEntities == null || procExecContextEntities.isEmpty()) {
log.info("Cannot find any process creation context infomation for {} {}", procDefInfoEntity.getId(),
procInstEntity.getId());
return null;
}
ProcExecContextEntity procExecContextEntity = procExecContextEntities.get(0);
String ctxJsonData = procExecContextEntity.getCtxData();
if (StringUtils.isBlank(ctxJsonData)) {
log.info("Context data is blank for {} {}", procDefInfoEntity.getId(), procInstEntity.getId());
return null;
}
WorkflowInstCreationContext ctx = convertJsonToWorkflowInstCreationContext(ctxJsonData.trim());
return ctx;
}
private String convertWorkflowInstCreationContextToJson(WorkflowInstCreationContext ctx) {
try {
String json = this.objectMapper.writeValueAsString(ctx);
return json;
} catch (JsonProcessingException e) {
log.error("Failed to write object to string.", e);
throw new WecubeCoreException("JSON convertion exception.");
}
}
private List<TaskFormDataEntityDto> calculateFormDataEntities(ProcInstInfoEntity procInstEntity,
TaskNodeInstInfoEntity taskNodeInstEntity, ProcDefInfoEntity procDefInfoEntity,
......@@ -673,8 +637,7 @@ public class PluginInvocationService extends AbstractPluginInvocationService {
return formDataEntities;
}
WorkflowInstCreationContext ctx = tryFetchWorkflowInstCreationContext(procInstEntity, taskNodeInstEntity,
procDefInfoEntity, taskNodeDefEntity, cmd);
WorkflowInstCreationContext ctx = tryFetchWorkflowInstCreationContext(taskNodeInstEntity);
if (ctx == null) {
return formDataEntities;
}
......@@ -776,15 +739,7 @@ public class PluginInvocationService extends AbstractPluginInvocationService {
return nodeBindObjectIds;
}
private WorkflowInstCreationContext convertJsonToWorkflowInstCreationContext(String ctxJsonData) {
try {
WorkflowInstCreationContext ctx = objectMapper.readValue(ctxJsonData, WorkflowInstCreationContext.class);
return ctx;
} catch (IOException e) {
log.error("Failed to read json value:" + ctxJsonData, e);
throw new WecubeCoreException("Failed to read JSON to object.");
}
}
/**
* SSTN Handling system automation task node
......
......@@ -88,6 +88,10 @@ public class DynamicEntityValueDto {
this.attrValues = attrValues;
}
public void addAttrValue(DynamicEntityAttrValueDto attrValue) {
this.attrValues.add(attrValue);
}
public DynamicEntityAttrValueDto findAttrValue(String attrName){
for(DynamicEntityAttrValueDto attrValue : attrValues){
if(attrName.equals(attrValue.getAttrName())){
......
package com.webank.wecube.platform.core.support.plugin.dto;
public class TaskFormDataOutpoutDto {
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment