private Long findExecutionId(List<Execution> executions, String splitId) { for (Execution execution : executions) { if (execution.getSystemContext().getSplitId().equals(splitId)) { return execution.getExecutionId(); } } return null; }
@Override public FinishedBranch convert(Execution execution) { boolean isBranchCancelled = ExecutionStatus.CANCELED.equals(execution.getSystemContext().getFlowTerminationType()); return new FinishedBranch(execution.getExecutionId().toString(), execution.getSystemContext().getBranchId(), execution.getSystemContext().getSplitId(), execution.getSystemContext().getStepErrorKey(), new BranchContexts(isBranchCancelled, execution.getContexts(), execution.getSystemContext())); } };
protected boolean handleCancelledFlow(Execution execution) { boolean executionIsCancelled = workerConfigurationService.isExecutionCancelled(execution .getExecutionId()); // in this case - just check if need to cancel. It will set as cancelled later on QueueEventListener // Another scenario of getting canceled - it was cancelled from the SplitJoinService (the configuration can still be not updated). Defect #:22060 if (ExecutionStatus.CANCELED.equals(execution.getSystemContext().getFlowTerminationType())) { executionIsCancelled = true; } if (executionIsCancelled) { // NOTE: an execution can be cancelled directly from CancelExecutionService, if it's currently paused. // Thus, if you change the code here, please check CancelExecutionService as well. execution.getSystemContext().setFlowTerminationType(ExecutionStatus.CANCELED); execution.setPosition(null); return true; } return false; }
private static void addContextData(Map<String, Object> data, Execution execution) { data.putAll(execution.getContexts()); data.put(ExecutionParametersConsts.SYSTEM_CONTEXT, execution.getSystemContext()); data.put(ExecutionParametersConsts.EXECUTION_RUNTIME_SERVICES, execution.getSystemContext()); data.put(ExecutionParametersConsts.EXECUTION, execution); data.put(ExecutionParametersConsts.EXECUTION_CONTEXT, execution.getContexts()); data.put(ExecutionParametersConsts.RUNNING_EXECUTION_PLAN_ID, execution.getRunningExecutionPlanId()); }
private Serializable createFailureEventData(Execution execution) { Map<String, Serializable> eventData = new HashMap<>(); eventData.put(ExecutionParametersConsts.SYSTEM_CONTEXT, execution.getSystemContext()); eventData.put(EventConstants.EXECUTION_ID_CONTEXT, execution.getExecutionId()); eventData.put(EventConstants.BRANCH_ID, execution.getSystemContext().getBranchId()); eventData.put(ExecutionParametersConsts.RUNNING_EXECUTION_PLAN_ID, execution.getRunningExecutionPlanId()); return (Serializable) eventData; }
private boolean checkContainsSensitiveData(Execution execution) { return sensitiveDataHandler != null && sensitiveDataHandler.containsSensitiveData(execution.getSystemContext(), execution.getContexts()); }
private static boolean useDefaultGroup(Execution execution) { Boolean useDefaultGroup = (Boolean) execution.getSystemContext().get(TempConstants.USE_DEFAULT_GROUP); if (useDefaultGroup == null) { return false; } return useDefaultGroup; }
private void returnCanceledRunToQueue(ExecutionState executionStateToCancel) { // set the context and return the run to the queue. It will be handled on "finishFlow" (QueueEventListener). Execution executionObj = executionSerializationUtil.objFromBytes(executionStateToCancel.getExecutionObject()); if (executionObj == null) { logger.error("Run Object is null. Execution Id = " + executionStateToCancel.getExecutionId() + "; Branch Id = " + executionStateToCancel.getBranchId()); return; } executionObj.getSystemContext().setFlowTerminationType(ExecutionStatus.CANCELED); executionObj.setPosition(null); // just in case - we shouldn't need it, because the Execution is back to the queue as "Terminated" executionStateToCancel.setStatus(ExecutionStatus.PENDING_CANCEL); // clean the DB field executionStateToCancel.setExecutionObject(null); // return execution to queue, as "Terminated" queueDispatcherService.dispatch( String.valueOf(executionObj.getExecutionId()), executionObj.getGroupName(), ExecStatus.TERMINATED, executionMessageConverter.createPayload(executionObj) ); }
if (!isDebuggerMode(execution.getSystemContext()) && handlePausedFlow(execution)) { return null; return doWaitForCancel(execution); } catch (TimeoutException timeout) { logger.error("Timed out waiting for cancel for execution id " + execution.getExecutionId()); execution.getSystemContext().setStepErrorKey(timeoutMessage); if (execution.getSystemContext().isPaused()) { if (handlePausedFlowAfterStep(execution)) { return null; if (logger.isDebugEnabled()) { logger.debug( "End of step: " + execution.getPosition() + " in execution id: " + execution.getExecutionId()); } catch (Exception ex) { logger.error("Error during execution: ", ex); execution.getSystemContext().setStepErrorKey(ex.getMessage()); // this is done only fo reporting execution.getSystemContext().setFlowTerminationType(ExecutionStatus.SYSTEM_FAILURE); execution.setPosition(null); // this ends the flow!!! return execution;
protected ExecutionStep loadExecutionStep(Execution execution) { RunningExecutionPlan runningExecutionPlan; if (execution != null) { // Optimization for external workers - run the content only without loading the execution plan if (execution.getSystemContext().get(TempConstants.CONTENT_EXECUTION_STEP) != null) { return (ExecutionStep) execution.getSystemContext().get(TempConstants.CONTENT_EXECUTION_STEP); } Long position = execution.getPosition(); if (position != null) { runningExecutionPlan = workerDbSupportService .readExecutionPlanById(execution.getRunningExecutionPlanId()); if (runningExecutionPlan != null) { updateMetadata(execution, runningExecutionPlan); ExecutionStep currStep = runningExecutionPlan.getExecutionPlan().getStep(position); if (logger.isDebugEnabled()) { logger.debug("Begin step: " + position + " in flow " + runningExecutionPlan.getExecutionPlan() .getFlowUuid() + " [" + execution.getExecutionId() + "]"); } if (currStep != null) { return currStep; } } } } // If we got here - one of the objects was null throw new RuntimeException("Failed to load ExecutionStep!"); }
@Override public Long reTrigger(SystemContext newSystemContext, byte[] executionObj) { Execution execution = executionMessageConverter.extractExecution(new Payload(executionObj)); //We must refresh the system context with the new one in order to re-trigger execution.getSystemContext().clear(); execution.getSystemContext().putAll(newSystemContext); //generate new execution id Long newExecutionId = idGenerator.next(); execution.getSystemContext().setExecutionId(newExecutionId); execution.setExecutionId(newExecutionId); // create execution record in ExecutionSummary table executionStateService.createParentExecution(execution.getExecutionId()); // create execution message ExecutionMessage message = createExecutionMessage(execution); queueDispatcher.dispatch(Collections.singletonList(message)); return newExecutionId; }
@Override // returns null in case the split was not done - flow is paused or cancelled public List<Execution> executeSplit(Execution execution) throws InterruptedException { try { ExecutionStep currStep = loadExecutionStep(execution); // Check if this execution was paused if (!isDebuggerMode(execution.getSystemContext()) && handlePausedFlow(execution)) { return null; } // dum bus event dumpBusEvents(execution); executeSplitStep(execution, currStep); failFlowIfSplitStepFailed(execution); dumpBusEvents(execution); // Run the split step List<StartBranchDataContainer> newBranches = execution.getSystemContext().removeBranchesData(); List<Execution> newExecutions = createChildExecutions(execution.getExecutionId(), newBranches); // Run the navigation navigate(execution, currStep); dumpBusEvents(execution); if (logger.isDebugEnabled()) { logger.debug( "End of step: " + execution.getPosition() + " in execution id: " + execution.getExecutionId()); } return newExecutions; } catch (Exception ex) { logger.error("Exception during the split step!", ex); throw ex; } }
@Override public ExecutionMessage convert(Execution execution) { return new ExecutionMessage(execution.getExecutionId().toString(), converter.createPayload(execution)); } };
private void failFlowIfSplitStepFailed(Execution execution) throws InterruptedException { if (execution.getSystemContext().hasStepErrorKey()) { String exception = execution.getSystemContext().getStepErrorKey(); execution.getSystemContext().setFlowTerminationType(ExecutionStatus.SYSTEM_FAILURE); execution.setPosition(null); // this ends the flow!!! try { createErrorEvent(exception, "Error occurred during split step ", EventConstants.SCORE_STEP_SPLIT_ERROR, execution.getSystemContext()); } catch (RuntimeException eventEx) { logger.error("Failed to create event: ", eventEx); } throw new RuntimeException(exception); } }
protected static void postExecutionSettings(Execution execution) { // Decide on Group String group = (String) execution.getSystemContext().get(TempConstants.ACTUALLY_OPERATION_GROUP); execution.setGroupName(group); if (isDebuggerMode(execution.getSystemContext())) { if (!StringUtils.isEmpty(group) && useDefaultGroup(execution)) { execution.setGroupName(null); } } //if there is a request to change the running execution plan id, we update the execution to the new execution plan ID Long requestForChangingExecutionPlan = execution.getSystemContext().pullRequestForChangingExecutionPlan(); if (requestForChangingExecutionPlan != null) { execution.setRunningExecutionPlanId(requestForChangingExecutionPlan); } }
@Override public Long trigger(Long executionId, TriggeringProperties triggeringProperties) { SystemContext scoreSystemContext = new SystemContext(triggeringProperties.getRuntimeValues()); Long runningExecutionPlanId = saveRunningExecutionPlans(triggeringProperties.getExecutionPlan(), triggeringProperties.getDependencies(), scoreSystemContext, String.valueOf(executionId)); scoreSystemContext.setExecutionId(executionId); Map<String,Serializable> executionMetadata = createMetadata(triggeringProperties); scoreSystemContext.putMetaData(executionMetadata); Execution execution = new Execution(executionId, runningExecutionPlanId, triggeringProperties.getStartStep(), triggeringProperties.getContext(), scoreSystemContext); // create execution record in ExecutionSummary table executionStateService.createParentExecution(execution.getExecutionId()); // create execution message ExecutionMessage message = createExecutionMessage(execution); enqueue(message); return executionId; }
private static List<Execution> createChildExecutions(Long executionId, List<StartBranchDataContainer> newBranches) { List<Execution> newExecutions = new ArrayList<>(); String splitId = UUID.randomUUID().toString(); for (int i = 0; i < newBranches.size(); i++) { StartBranchDataContainer from = newBranches.get(i); Execution to = new Execution(executionId, from.getExecutionPlanId(), from.getStartPosition(), from.getContexts(), from.getSystemContext()); to.getSystemContext().setSplitId(splitId); to.getSystemContext().setBranchId(splitId + ":" + (i + 1)); newExecutions.add(to); } return newExecutions; }
private boolean shouldChangeWorkerGroup(Execution nextStepExecution) { //Here we check if we can continue to run in current thread - depends on the group if (nextStepExecution.getSystemContext().containsKey(TempConstants.SHOULD_CHECK_GROUP)) { //take care of worker group id String groupName = nextStepExecution.getGroupName(); //clean key nextStepExecution.getSystemContext().remove(TempConstants.SHOULD_CHECK_GROUP); boolean canRunInThisWorker = groupName== null || //does not really matter on what worker to run workerConfigurationService.isMemberOf(groupName) || //this worker is member of the group isStickyToThisWorker(groupName); //next step should run in this worker because of "sticky worker" feature if(!canRunInThisWorker){ //set current step to finished executionMessage.setStatus(ExecStatus.FINISHED); executionMessage.incMsgSeqId(); executionMessage.setPayload(null); ExecutionMessage pendingMessage = createPendingExecutionMessage(nextStepExecution); ExecutionMessage[] executionMessagesToSend = new ExecutionMessage[]{executionMessage, pendingMessage};//Messages that we will send to OutBuffer try { outBuffer.put(executionMessagesToSend); } catch (InterruptedException e) { logger.warn("Thread was interrupted! Exiting the execution... ", e); return true; } return true; } } return false; }
private ExecutionMessage createPendingExecutionMessage(Execution nextStepExecution) { //take care of worker group String groupName = nextStepExecution.getGroupName(); if (groupName == null) { groupName = WorkerNode.DEFAULT_WORKER_GROUPS[0]; } return new ExecutionMessage(ExecutionMessage.EMPTY_EXEC_STATE_ID, ExecutionMessage.EMPTY_WORKER, groupName, executionMessage.getMsgId(), ExecStatus.PENDING, converter.createPayload(nextStepExecution), 0).setWorkerKey(executionMessage.getWorkerKey()); }
private boolean isExecutionTerminating(Execution nextStepExecution) { if(nextStepExecution.getPosition() == null) { //set current step to finished executionMessage.setStatus(ExecStatus.FINISHED); executionMessage.incMsgSeqId(); executionMessage.setPayload(null); //Flow is finished - does not matter if successfully or not ExecutionMessage terminationMessage = createTerminatedExecutionMessage(nextStepExecution); ExecutionMessage[] executionMessagesToSend = new ExecutionMessage[]{executionMessage, terminationMessage}; //Messages that we will send to OutBuffer try { outBuffer.put(executionMessagesToSend); } catch (InterruptedException e) { logger.warn("Thread was interrupted! Exiting the execution... ", e); return true; } return true; } else { return false; } }