diff --git a/kie-remote/kie-remote-services/src/main/java/org/kie/remote/services/cdi/ProcessRequestBean.java b/kie-remote/kie-remote-services/src/main/java/org/kie/remote/services/cdi/ProcessRequestBean.java index 90aec4faa2..48eb21a45e 100644 --- a/kie-remote/kie-remote-services/src/main/java/org/kie/remote/services/cdi/ProcessRequestBean.java +++ b/kie-remote/kie-remote-services/src/main/java/org/kie/remote/services/cdi/ProcessRequestBean.java @@ -1,3 +1,18 @@ +/* + * Copyright 2015 JBoss Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * 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.kie.remote.services.cdi; import static org.kie.remote.services.cdi.DeploymentInfoBean.emptyDeploymentId; @@ -33,11 +48,14 @@ import org.jbpm.services.api.TaskNotFoundException; import org.jbpm.services.api.UserTaskService; import org.jbpm.services.task.commands.AddTaskCommand; +import org.jbpm.services.task.commands.CancelDeadlineCommand; import org.jbpm.services.task.commands.CompleteTaskCommand; +import org.jbpm.services.task.commands.CompositeCommand; import org.jbpm.services.task.commands.FailTaskCommand; import org.jbpm.services.task.commands.GetContentCommand; import org.jbpm.services.task.commands.GetTaskCommand; import org.jbpm.services.task.commands.GetTaskContentCommand; +import org.jbpm.services.task.commands.ProcessSubTaskCommand; import org.jbpm.services.task.commands.SkipTaskCommand; import org.jbpm.services.task.commands.TaskCommand; import org.jbpm.services.task.exception.PermissionDeniedException; @@ -81,7 +99,7 @@ public class ProcessRequestBean { private static final Logger logger = LoggerFactory.getLogger(ProcessRequestBean.class); - + /* KIE processing */ @Inject @@ -92,12 +110,12 @@ public class ProcessRequestBean { /** AuditLogService **/ private static final String PERSISTENCE_UNIT_NAME = "org.jbpm.domain"; - + @PersistenceUnit(unitName = PERSISTENCE_UNIT_NAME) private EntityManagerFactory emf; - + private AuditLogService auditLogService; - + // Injection methods for tests public void setProcessService(ProcessService processService) { @@ -112,67 +130,67 @@ public void setAuditLogService(AuditLogService auditLogService) { this.auditLogService = auditLogService; } - // Audit Log Service logic - + // Audit Log Service logic + @PostConstruct - public void initAuditLogService() { + public void initAuditLogService() { auditLogService = new JPAAuditLogService(emf); - if( emf == null ) { + if( emf == null ) { ((JPAAuditLogService) auditLogService).setPersistenceUnitName(PERSISTENCE_UNIT_NAME); } } - - public AuditLogService getAuditLogService() { + + public AuditLogService getAuditLogService() { return auditLogService; } - + // Methods used - - public void processCommand(Command cmd, JaxbCommandsRequest request, int i, JaxbCommandsResponse jaxbResponse) { + + public void processCommand(Command cmd, JaxbCommandsRequest request, int i, JaxbCommandsResponse jaxbResponse) { String version = request.getVersion(); - if( version == null ) { + if( version == null ) { version = "pre-6.0.3"; } - if( ! version.equals(VERSION) ) { + if( ! version.equals(VERSION) ) { logger.warn( "Request received from client version [{}] while server is version [{}]! THIS MAY CAUSE PROBLEMS!", version, VERSION); } jaxbResponse.setVersion(VERSION); - + String cmdName = cmd.getClass().getSimpleName(); logger.debug("Processing command " + cmdName); String errMsg = "Unable to execute " + cmdName + "/" + i; - + Object cmdResult = null; try { // check that all parameters have been correctly deserialized/unmarshalled preprocessCommand(cmd); - + String corrKeyString = request.getCorrelationKeyString(); List correlationKeyProps = null; - if( corrKeyString != null ) { + if( corrKeyString != null ) { String [] correlationKeyPropsArr = corrKeyString.split(":"); - if( correlationKeyPropsArr.length > 0 ) { + if( correlationKeyPropsArr.length > 0 ) { correlationKeyProps = Arrays.asList(correlationKeyPropsArr); } } - - if( cmd instanceof TaskCommand ) { + + if( cmd instanceof TaskCommand ) { TaskCommand taskCmd = (TaskCommand) cmd; // TODO: correlation key sessions and task completion! BZ-1245616-related cmdResult = doTaskOperation( - taskCmd.getTaskId(), - request.getDeploymentId(), - request.getProcessInstanceId(), - null, + taskCmd.getTaskId(), + request.getDeploymentId(), + request.getProcessInstanceId(), + null, taskCmd); - } else if( cmd instanceof AuditCommand) { + } else if( cmd instanceof AuditCommand) { AuditCommand auditCmd = ((AuditCommand) cmd); auditCmd.setAuditLogService(getAuditLogService()); cmdResult = auditCmd.execute(null); } else { cmdResult = doKieSessionOperation( - cmd, - request.getDeploymentId(), + cmd, + request.getDeploymentId(), correlationKeyProps, request.getProcessInstanceId()); } @@ -182,7 +200,7 @@ public void processCommand(Command cmd, JaxbCommandsRequest request, int } catch (Exception e) { logger.warn(errMsg, e); jaxbResponse.addException(e, i, cmd, FAILURE); - } + } if (cmdResult != null) { try { // addResult could possibly throw an exception, which is why it's here and not above @@ -194,9 +212,9 @@ public void processCommand(Command cmd, JaxbCommandsRequest request, int } } }; - - void preprocessCommand(Command cmd) { - if( AcceptedServerCommands.SEND_OBJECT_PARAMETER_COMMANDS.contains(cmd.getClass()) ) { + + void preprocessCommand(Command cmd) { + if( AcceptedServerCommands.SEND_OBJECT_PARAMETER_COMMANDS.contains(cmd.getClass()) ) { if( cmd instanceof CompleteWorkItemCommand ) { checkThatUserDefinedClassesWereUnmarshalled(((CompleteWorkItemCommand) cmd).getResults()); } else if( cmd instanceof SignalEventCommand ) { @@ -219,39 +237,39 @@ void preprocessCommand(Command cmd) { checkThatUserDefinedClassesWereUnmarshalled(((CompleteTaskCommand) cmd).getData()); } else if( cmd instanceof FailTaskCommand ) { checkThatUserDefinedClassesWereUnmarshalled(((FailTaskCommand) cmd).getData()); - } + } } } - - void checkThatUserDefinedClassesWereUnmarshalled(Object obj) { - if( obj != null ) { - if( obj instanceof List ) { - for( Object listElem : (List) obj ) { + + void checkThatUserDefinedClassesWereUnmarshalled(Object obj) { + if( obj != null ) { + if( obj instanceof List ) { + for( Object listElem : (List) obj ) { verifyObjectHasBeenUnmarshalled(listElem); } - } else if( obj instanceof Map ) { - for( Object mapVal : ((Map) obj).values() ) { + } else if( obj instanceof Map ) { + for( Object mapVal : ((Map) obj).values() ) { verifyObjectHasBeenUnmarshalled(mapVal); } - } else { + } else { verifyObjectHasBeenUnmarshalled(obj); } } } - - private void verifyObjectHasBeenUnmarshalled(Object obj) { - if( Element.class.isAssignableFrom(obj.getClass()) ) { + + private void verifyObjectHasBeenUnmarshalled(Object obj) { + if( Element.class.isAssignableFrom(obj.getClass()) ) { String typeName = ((Element) obj).getAttribute("xsi:type"); throw new IllegalStateException("Could not unmarshall user-defined class instance parameter of type '" + typeName + "'"); } } - + /** * Executes a command on the {@link KieSession} from the proper {@link RuntimeManager}. This method * ends up synchronizing around the retrieved {@link KieSession} in order to avoid race-conditions. - * + * * @param cmd The command to be executed. - * @param deploymentId The id of the runtim + * @param deploymentId The id of the runtim * @param correlationKeyProps The defining properties for a correlation key * @param processInstanceId The process instance id, if available (otherwise null). * @return The result of the {@link Command}. @@ -274,47 +292,47 @@ public T doKieSessionOperation(Command cmd, String deploymentId, List correlationKeyProps, Long processInstanceId, Command cmd) { - if( cmd instanceof StartCorrelatedProcessCommand || cmd instanceof StartProcessInstanceCommand ) { + private Context getDeploymentCommandContext(List correlationKeyProps, Long processInstanceId, Command cmd) { + if( cmd instanceof StartCorrelatedProcessCommand || cmd instanceof StartProcessInstanceCommand ) { return EmptyContext.get(); } // correlation key CorrelationKey correlationKey = null; - if( correlationKeyProps != null && ! correlationKeyProps.isEmpty() ) { - CorrelationKeyFactory factory = KieInternalServices.Factory.get().newCorrelationKeyFactory(); + if( correlationKeyProps != null && ! correlationKeyProps.isEmpty() ) { + CorrelationKeyFactory factory = KieInternalServices.Factory.get().newCorrelationKeyFactory(); correlationKey = factory.newCorrelationKey(correlationKeyProps); - } else if (cmd instanceof CorrelationKeyCommand ) { + } else if (cmd instanceof CorrelationKeyCommand ) { correlationKey = ((CorrelationKeyCommand) cmd).getCorrelationKey(); - } - if( correlationKey != null ) { + } + if( correlationKey != null ) { return CorrelationKeyContext.get(correlationKey); } - + // process instance - if( processInstanceId == null && cmd instanceof ProcessInstanceIdCommand ) { + if( processInstanceId == null && cmd instanceof ProcessInstanceIdCommand ) { processInstanceId = ((ProcessInstanceIdCommand) cmd).getProcessInstanceId(); - if( processInstanceId != null ) { + if( processInstanceId != null ) { return ProcessInstanceIdContext.get(processInstanceId); } } - if( processInstanceId != null ) { + if( processInstanceId != null ) { return ProcessInstanceIdContext.get(processInstanceId); } - + // empty return EmptyContext.get(); } - + /** * Returns the actual variable instance from the runtime (as opposed to retrieving the string value of the - * variable via the history/audit operations. - * + * variable via the history/audit operations. + * * @param deploymentId The id of the runtime * @param processInstanceId The process instance id (required) * @param varName The name of the variable * @return The variable object instance. */ - public Object getVariableObjectInstanceFromRuntime(String deploymentId, long processInstanceId, String varName) { + public Object getVariableObjectInstanceFromRuntime(String deploymentId, long processInstanceId, String varName) { try { Object procVar = processService.getProcessInstanceVariable(processInstanceId, varName); return procVar; @@ -335,14 +353,14 @@ public Object getVariableObjectInstanceFromRuntime(String deploymentId, long pro taskDeploymentIdCommands.add(FailTaskCommand.class); taskDeploymentIdCommands.add(SkipTaskCommand.class); } - + /** * There are 3 possibilities here:
    *
  1. This is an operation that should be done on a deployment if possible, but it's an independent task.
  2. *
  3. This is an operation that should be done on a deployment, and a deployment/runtime is available.
  4. *
  5. This is an operation that does not modify the {@link KieSession} and should be done via the injected {@link TaskService}.
  6. *
- * + * * @param taskId * @param deploymentId * @param processInstanceId @@ -351,19 +369,30 @@ public Object getVariableObjectInstanceFromRuntime(String deploymentId, long pro * @param errorMsg * @return */ - private T doTaskOperation(Long taskId, String deploymentId, Long processInstanceId, Task task, TaskCommand cmd) { + private T doTaskOperation(Long taskId, String deploymentId, Long processInstanceId, Task task, TaskCommand cmd) { // take care of serialization - if( cmd instanceof GetTaskCommand - || cmd instanceof GetContentCommand - || cmd instanceof GetTaskContentCommand ) { - cmd = new ExecuteAndSerializeCommand(cmd); + if( cmd instanceof GetTaskCommand + || cmd instanceof GetContentCommand + || cmd instanceof GetTaskContentCommand ) { + cmd = new ExecuteAndSerializeCommand(cmd); } if( emptyDeploymentId(deploymentId) && taskDeploymentIdCommands.contains(cmd.getClass()) ) { deploymentId = getDeploymentId(task,taskId, cmd); } + if( cmd instanceof CompleteTaskCommand ) { + CompleteTaskCommand completeCmd = (CompleteTaskCommand) cmd; + String userId = completeCmd.getUserId(); + Map data = completeCmd.getData(); + + cmd = new CompositeCommand( + new CompleteTaskCommand(taskId, userId, data), + new ProcessSubTaskCommand(taskId, userId, data), + new CancelDeadlineCommand(taskId, true, true)); + } + try { return userTaskService.execute(deploymentId, cmd); } catch (TaskNotFoundException e) { @@ -379,7 +408,7 @@ private T doTaskOperation(Long taskId, String deploymentId, Long processInst public T doRestTaskOperation(Long taskId, String deploymentId, Long processInstanceId, Task task, TaskCommand cmd) { - try { + try { return doTaskOperation(taskId, deploymentId, processInstanceId, task, cmd); } catch (PermissionDeniedException pde) { throw KieRemoteRestOperationException.conflict(pde.getMessage(), pde); @@ -396,7 +425,7 @@ private String getDeploymentId(Task task, Long taskId, TaskCommand cmd) { task = userTaskService.getTask(taskId); } String deploymentId = null; - if( task != null && task.getTaskData() != null ) { + if( task != null && task.getTaskData() != null ) { deploymentId = task.getTaskData().getDeploymentId(); } return deploymentId;