Java Code Examples for org.flowable.engine.impl.util.CommandContextUtil#getJobService()

The following examples show how to use org.flowable.engine.impl.util.CommandContextUtil#getJobService() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: DebugContinueProcessOperation.java    From flowable-engine with Apache License 2.0 6 votes vote down vote up
protected void breakExecution(FlowNode flowNode) {
    JobService jobService = CommandContextUtil.getJobService();
    JobEntity brokenJob = jobService.createJob();
    brokenJob.setJobType(JobEntity.JOB_TYPE_MESSAGE);
    brokenJob.setRevision(1);
    brokenJob.setRetries(1);
    brokenJob.setExecutionId(execution.getId());
    brokenJob.setProcessInstanceId(execution.getProcessInstanceId());
    brokenJob.setProcessDefinitionId(execution.getProcessDefinitionId());
    brokenJob.setExclusive(false);
    brokenJob.setJobHandlerType(HANDLER_TYPE_BREAK_POINT);

    // Inherit tenant id (if applicable)
    if (execution.getTenantId() != null) {
        brokenJob.setTenantId(execution.getTenantId());
    }

    jobService.insertJob(brokenJob);
    jobService.moveJobToSuspendedJob(brokenJob);
}
 
Example 2
Source File: ContinueMultiInstanceOperation.java    From flowable-engine with Apache License 2.0 6 votes vote down vote up
protected void executeAsynchronous(FlowNode flowNode) {
    JobService jobService = CommandContextUtil.getJobService(commandContext);
    
    JobEntity job = jobService.createJob();
    job.setExecutionId(execution.getId());
    job.setProcessInstanceId(execution.getProcessInstanceId());
    job.setProcessDefinitionId(execution.getProcessDefinitionId());
    job.setElementId(flowNode.getId());
    job.setElementName(flowNode.getName());
    job.setJobHandlerType(AsyncContinuationJobHandler.TYPE);

    // Inherit tenant id (if applicable)
    if (execution.getTenantId() != null) {
        job.setTenantId(execution.getTenantId());
    }
    
    execution.getJobs().add(job);
    
    jobService.createAsyncJob(job, flowNode.isExclusive());
    jobService.scheduleAsyncJob(job);
}
 
Example 3
Source File: EndExecutionOperation.java    From flowable-engine with Apache License 2.0 6 votes vote down vote up
protected void scheduleAsyncCompleteCallActivity(ExecutionEntity superExecutionEntity, ExecutionEntity childProcessInstanceExecutionEntity) {
    JobService jobService = CommandContextUtil.getJobService(commandContext);
    
    JobEntity job = jobService.createJob();
    
    // Needs to be the parent process instance, as the parent needs to be locked to avoid concurrency when multiple call activities are ended
    job.setExecutionId(superExecutionEntity.getId()); 
    
    // Child execution of subprocess is passed as configuration
    job.setJobHandlerConfiguration(childProcessInstanceExecutionEntity.getId());
    
    String processInstanceId = superExecutionEntity.getProcessInstanceId() != null ? superExecutionEntity.getProcessInstanceId() : superExecutionEntity.getId();
    job.setProcessInstanceId(processInstanceId);
    job.setProcessDefinitionId(childProcessInstanceExecutionEntity.getProcessDefinitionId());
    job.setElementId(superExecutionEntity.getCurrentFlowElement().getId());
    job.setElementName(superExecutionEntity.getCurrentFlowElement().getName());
    job.setTenantId(childProcessInstanceExecutionEntity.getTenantId());
    job.setJobHandlerType(AsyncCompleteCallActivityJobHandler.TYPE);
    
    superExecutionEntity.getJobs().add(job);
    
    jobService.createAsyncJob(job, true); // Always exclusive to avoid concurrency problems
    jobService.scheduleAsyncJob(job);
}
 
Example 4
Source File: StartProcessInstanceAsyncCmd.java    From flowable-engine with Apache License 2.0 6 votes vote down vote up
protected void executeAsynchronous(ExecutionEntity execution, Process process) {
    JobService jobService = CommandContextUtil.getJobService();

    JobEntity job = jobService.createJob();
    job.setExecutionId(execution.getId());
    job.setProcessInstanceId(execution.getProcessInstanceId());
    job.setProcessDefinitionId(execution.getProcessDefinitionId());
    job.setElementId(process.getId());
    job.setElementName(process.getName());
    job.setJobHandlerType(AsyncContinuationJobHandler.TYPE);

    // Inherit tenant id (if applicable)
    if (execution.getTenantId() != null) {
        job.setTenantId(execution.getTenantId());
    }

    execution.getJobs().add(job);

    jobService.createAsyncJob(job, false);
    jobService.scheduleAsyncJob(job);
}
 
Example 5
Source File: ContinueProcessOperation.java    From flowable-engine with Apache License 2.0 5 votes vote down vote up
protected void executeAsynchronous(FlowNode flowNode) {
    ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
    JobService jobService = CommandContextUtil.getJobService(commandContext);
    
    JobEntity job = jobService.createJob();
    job.setExecutionId(execution.getId());
    job.setProcessInstanceId(execution.getProcessInstanceId());
    job.setProcessDefinitionId(execution.getProcessDefinitionId());
    job.setElementId(flowNode.getId());
    job.setElementName(flowNode.getName());
    job.setJobHandlerType(AsyncContinuationJobHandler.TYPE);
    
    List<ExtensionElement> jobCategoryElements = flowNode.getExtensionElements().get("jobCategory");
    if (jobCategoryElements != null && jobCategoryElements.size() > 0) {
        ExtensionElement jobCategoryElement = jobCategoryElements.get(0);
        if (StringUtils.isNotEmpty(jobCategoryElement.getElementText())) {
            Expression categoryExpression = processEngineConfiguration.getExpressionManager().createExpression(jobCategoryElement.getElementText());
            Object categoryValue = categoryExpression.getValue(execution);
            if (categoryValue != null) {
                job.setCategory(categoryValue.toString());
            }
        }
    }

    // Inherit tenant id (if applicable)
    if (execution.getTenantId() != null) {
        job.setTenantId(execution.getTenantId());
    }
    
    execution.getJobs().add(job);
    
    jobService.createAsyncJob(job, flowNode.isExclusive());
    jobService.scheduleAsyncJob(job);
    
    if (processEngineConfiguration.isLoggingSessionEnabled()) {
        BpmnLoggingSessionUtil.addAsyncActivityLoggingData("Created async job for " + flowNode.getId() + ", with job id " + job.getId(),
                        LoggingSessionConstants.TYPE_SERVICE_TASK_ASYNC_JOB, job, flowNode, execution);
    }
}
 
Example 6
Source File: IntermediateCatchTimerEventActivityBehavior.java    From flowable-engine with Apache License 2.0 5 votes vote down vote up
@Override
public void eventCancelledByEventGateway(DelegateExecution execution) {
    JobService jobService = CommandContextUtil.getJobService();
    List<JobEntity> jobEntities = jobService.findJobsByExecutionId(execution.getId());

    for (JobEntity jobEntity : jobEntities) { // Should be only one
        jobService.deleteJob(jobEntity);
    }

    CommandContextUtil.getExecutionEntityManager().deleteExecutionAndRelatedData((ExecutionEntity) execution,
            DeleteReason.EVENT_BASED_GATEWAY_CANCEL, false);
}
 
Example 7
Source File: ProcessInstanceMigrationManagerImpl.java    From flowable-engine with Apache License 2.0 4 votes vote down vote up
@Override
public Batch batchMigrateProcessInstancesOfProcessDefinition(String sourceProcDefId, ProcessInstanceMigrationDocument document, CommandContext commandContext) {
    // Check of the target definition exists before submitting the batch
    ProcessDefinition targetProcessDefinition = resolveProcessDefinition(document, commandContext);

    ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager(commandContext);
    List<ProcessInstance> processInstances = executionEntityManager.findProcessInstanceByQueryCriteria( new ProcessInstanceQueryImpl().processDefinitionId(sourceProcDefId));

    BatchService batchService = CommandContextUtil.getBatchService(commandContext);
    Batch batch = batchService.createBatchBuilder().batchType(Batch.PROCESS_MIGRATION_TYPE)
        .searchKey(sourceProcDefId)
        .searchKey2(targetProcessDefinition.getId())
        .status(ProcessInstanceBatchMigrationResult.STATUS_IN_PROGRESS)
        .batchDocumentJson(document.asJsonString())
        .create();
    
    JobService jobService = CommandContextUtil.getJobService(commandContext);
    for (ProcessInstance processInstance : processInstances) {
        BatchPart batchPart = batchService.createBatchPart(batch, ProcessInstanceBatchMigrationResult.STATUS_WAITING, 
                        processInstance.getId(), null, ScopeTypes.BPMN);
        
        JobEntity job = jobService.createJob();
        job.setJobHandlerType(ProcessInstanceMigrationJobHandler.TYPE);
        job.setProcessInstanceId(processInstance.getId());
        job.setJobHandlerConfiguration(ProcessInstanceMigrationJobHandler.getHandlerCfgForBatchPartId(batchPart.getId()));
        jobService.createAsyncJob(job, false);
        jobService.scheduleAsyncJob(job);
    }
    
    if (!processInstances.isEmpty()) {
        TimerJobService timerJobService = CommandContextUtil.getTimerJobService(commandContext);
        TimerJobEntity timerJob = timerJobService.createTimerJob();
        timerJob.setJobType(JobEntity.JOB_TYPE_TIMER);
        timerJob.setRevision(1);
        timerJob.setJobHandlerType(ProcessInstanceMigrationStatusJobHandler.TYPE);
        timerJob.setJobHandlerConfiguration(ProcessInstanceMigrationJobHandler.getHandlerCfgForBatchId(batch.getId()));
        
        ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
        BusinessCalendar businessCalendar = processEngineConfiguration.getBusinessCalendarManager().getBusinessCalendar(CycleBusinessCalendar.NAME);
        timerJob.setDuedate(businessCalendar.resolveDuedate(processEngineConfiguration.getBatchStatusTimeCycleConfig()));
        timerJob.setRepeat(processEngineConfiguration.getBatchStatusTimeCycleConfig());
        
        timerJobService.scheduleTimerJob(timerJob);
    }

    return batch;
}
 
Example 8
Source File: TriggerExecutionOperation.java    From flowable-engine with Apache License 2.0 4 votes vote down vote up
@Override
public void run() {
    FlowElement currentFlowElement = getCurrentFlowElement(execution);
    if (currentFlowElement instanceof FlowNode) {

        ActivityBehavior activityBehavior = (ActivityBehavior) ((FlowNode) currentFlowElement).getBehavior();
        if (activityBehavior instanceof TriggerableActivityBehavior) {

            if (!triggerAsync) {
                ((TriggerableActivityBehavior) activityBehavior).trigger(execution, null, null);
                
            } else {
                JobService jobService = CommandContextUtil.getJobService();
                JobEntity job = jobService.createJob();
                job.setExecutionId(execution.getId());
                job.setProcessInstanceId(execution.getProcessInstanceId());
                job.setProcessDefinitionId(execution.getProcessDefinitionId());
                job.setElementId(currentFlowElement.getId());
                job.setElementName(currentFlowElement.getName());
                job.setJobHandlerType(AsyncTriggerJobHandler.TYPE);
                
                // Inherit tenant id (if applicable)
                if (execution.getTenantId() != null) {
                    job.setTenantId(execution.getTenantId());
                }

                jobService.createAsyncJob(job, true);
                jobService.scheduleAsyncJob(job);
            }


        } else {
            throw new FlowableException("Cannot trigger execution with id " + execution.getId()
                + " : the activityBehavior " + activityBehavior.getClass() + " does not implement the "
                + TriggerableActivityBehavior.class.getName() + " interface");

        }

    } else if (currentFlowElement == null) {
        throw new FlowableException("Cannot trigger execution with id " + execution.getId()
                + " : no current flow element found. Check the execution id that is being passed "
                + "(it should not be a process instance execution, but a child execution currently referencing a flow element).");

    } else {
        throw new FlowableException("Programmatic error: cannot trigger execution, invalid flowelement type found: "
                + currentFlowElement.getClass().getName() + ".");

    }
}
 
Example 9
Source File: ExecutionEntityManagerImpl.java    From flowable-engine with Apache License 2.0 4 votes vote down vote up
protected void deleteJobs(ExecutionEntity executionEntity, CommandContext commandContext, boolean enableExecutionRelationshipCounts, boolean eventDispatcherEnabled) {
    
    // Jobs have byte array references that don't store the execution id. 
    // This means a bulk delete is not done for jobs. Generally there aren't many jobs / execution either.
    
    if (!enableExecutionRelationshipCounts
            || (enableExecutionRelationshipCounts && ((CountingExecutionEntity) executionEntity).getTimerJobCount() > 0)) {
        CommandContextUtil.getTimerJobService().deleteTimerJobsByExecutionId(executionEntity.getId());
    }

    JobService jobService = CommandContextUtil.getJobService();
    if (!enableExecutionRelationshipCounts
            || (enableExecutionRelationshipCounts && ((CountingExecutionEntity) executionEntity).getJobCount() > 0)) {
        jobService.deleteJobsByExecutionId(executionEntity.getId());
    }

    if (!enableExecutionRelationshipCounts
            || (enableExecutionRelationshipCounts && ((CountingExecutionEntity) executionEntity).getSuspendedJobCount() > 0)) {
        jobService.deleteSuspendedJobsByExecutionId(executionEntity.getId());
    }

    if (!enableExecutionRelationshipCounts
            || (enableExecutionRelationshipCounts && ((CountingExecutionEntity) executionEntity).getDeadLetterJobCount() > 0)) {
        jobService.deleteDeadLetterJobsByExecutionId(executionEntity.getId());
    }

    if (!enableExecutionRelationshipCounts || ((CountingExecutionEntity) executionEntity).getExternalWorkerJobCount() > 0) {
        Collection<ExternalWorkerJobEntity> externalWorkerJobsForExecution = jobService.findExternalWorkerJobsByExecutionId(executionEntity.getId());

        ExternalWorkerJobEntityManager externalWorkerJobEntityManager = CommandContextUtil.getJobServiceConfiguration(commandContext)
                .getExternalWorkerJobEntityManager();
        IdentityLinkService identityLinkService = CommandContextUtil.getIdentityLinkService(commandContext);
        for (ExternalWorkerJobEntity job : externalWorkerJobsForExecution) {
            externalWorkerJobEntityManager.delete(job);
            identityLinkService.deleteIdentityLinksByScopeIdAndType(job.getCorrelationId(), ScopeTypes.EXTERNAL_WORKER);
            if (getEventDispatcher() != null && getEventDispatcher().isEnabled()) {
                getEventDispatcher().dispatchEvent(FlowableJobEventBuilder.createEntityEvent(FlowableEngineEventType.JOB_CANCELED, job));
            }
        }
    }
}
 
Example 10
Source File: AbstractSetProcessInstanceStateCmd.java    From flowable-engine with Apache License 2.0 4 votes vote down vote up
@Override
public Void execute(CommandContext commandContext) {

    if (processInstanceId == null) {
        throw new FlowableIllegalArgumentException("ProcessInstanceId cannot be null.");
    }

    ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager(commandContext);
    ExecutionEntity executionEntity = executionEntityManager.findById(processInstanceId);

    if (executionEntity == null) {
        throw new FlowableObjectNotFoundException("Cannot find processInstance for id '" + processInstanceId + "'.", Execution.class);
    }
    if (!executionEntity.isProcessInstanceType()) {
        throw new FlowableException("Cannot set suspension state for execution '" + processInstanceId + "': not a process instance.");
    }

    if (Flowable5Util.isFlowable5ProcessDefinitionId(commandContext, executionEntity.getProcessDefinitionId())) {
        if (getNewState() == SuspensionState.ACTIVE) {
            CommandContextUtil.getProcessEngineConfiguration().getFlowable5CompatibilityHandler().activateProcessInstance(processInstanceId);
        } else {
            CommandContextUtil.getProcessEngineConfiguration().getFlowable5CompatibilityHandler().suspendProcessInstance(processInstanceId);
        }
        return null;
    }

    SuspensionStateUtil.setSuspensionState(executionEntity, getNewState());
    executionEntityManager.update(executionEntity, false);

    // All child executions are suspended
    Collection<ExecutionEntity> childExecutions = executionEntityManager.findChildExecutionsByProcessInstanceId(processInstanceId);
    for (ExecutionEntity childExecution : childExecutions) {
        if (!childExecution.getId().equals(processInstanceId)) {
            SuspensionStateUtil.setSuspensionState(childExecution, getNewState());
            executionEntityManager.update(childExecution, false);
        }
    }

    // All tasks are suspended
    List<TaskEntity> tasks = CommandContextUtil.getTaskService().findTasksByProcessInstanceId(processInstanceId);
    for (TaskEntity taskEntity : tasks) {
        SuspensionStateUtil.setSuspensionState(taskEntity, getNewState());
        CommandContextUtil.getTaskService().updateTask(taskEntity, false);
    }

    // All jobs are suspended
    JobService jobService = CommandContextUtil.getJobService(commandContext);
    if (getNewState() == SuspensionState.ACTIVE) {
        List<SuspendedJobEntity> suspendedJobs = jobService.findSuspendedJobsByProcessInstanceId(processInstanceId);
        for (SuspendedJobEntity suspendedJob : suspendedJobs) {
            jobService.activateSuspendedJob(suspendedJob);
        }

    } else {
        TimerJobService timerJobService = CommandContextUtil.getTimerJobService(commandContext);
        List<TimerJobEntity> timerJobs = timerJobService.findTimerJobsByProcessInstanceId(processInstanceId);
        for (TimerJobEntity timerJob : timerJobs) {
            jobService.moveJobToSuspendedJob(timerJob);
        }

        List<JobEntity> jobs = jobService.findJobsByProcessInstanceId(processInstanceId);
        for (JobEntity job : jobs) {
            jobService.moveJobToSuspendedJob(job);
        }

        List<ExternalWorkerJobEntity> externalWorkerJobs = CommandContextUtil.getJobServiceConfiguration(commandContext)
                .getExternalWorkerJobEntityManager()
                .findJobsByProcessInstanceId(processInstanceId);

        for (ExternalWorkerJobEntity externalWorkerJob : externalWorkerJobs) {
            jobService.moveJobToSuspendedJob(externalWorkerJob);
        }

    }

    return null;
}
 
Example 11
Source File: JobRetryCmd.java    From flowable-engine with Apache License 2.0 4 votes vote down vote up
@Override
public Object execute(CommandContext commandContext) {
    JobService jobService = CommandContextUtil.getJobService(commandContext);
    TimerJobService timerJobService = CommandContextUtil.getTimerJobService(commandContext);
    
    JobEntity job = jobService.findJobById(jobId);
    if (job == null) {
        return null;
    }

    ProcessEngineConfiguration processEngineConfig = CommandContextUtil.getProcessEngineConfiguration(commandContext);

    ExecutionEntity executionEntity = fetchExecutionEntity(commandContext, job.getExecutionId());
    FlowElement currentFlowElement = executionEntity != null ? executionEntity.getCurrentFlowElement() : null;
    if (executionEntity != null) {
        executionEntity.setActive(false);
    }

    String failedJobRetryTimeCycleValue = null;
    if (currentFlowElement instanceof ServiceTask) {
        failedJobRetryTimeCycleValue = ((ServiceTask) currentFlowElement).getFailedJobRetryTimeCycleValue();
    }

    AbstractRuntimeJobEntity newJobEntity = null;
    if (currentFlowElement == null || failedJobRetryTimeCycleValue == null) {

        LOGGER.debug("activity or FailedJobRetryTimerCycleValue is null in job {}. Only decrementing retries.", jobId);

        if (job.getRetries() <= 1) {
            newJobEntity = jobService.moveJobToDeadLetterJob(job);
        } else {
            newJobEntity = timerJobService.moveJobToTimerJob(job);
        }

        newJobEntity.setRetries(job.getRetries() - 1);
        if (job.getDuedate() == null || JobEntity.JOB_TYPE_MESSAGE.equals(job.getJobType())) {
            // add wait time for failed async job
            newJobEntity.setDuedate(calculateDueDate(commandContext, processEngineConfig.getAsyncFailedJobWaitTime(), null));
        } else {
            // add default wait time for failed job
            newJobEntity.setDuedate(calculateDueDate(commandContext, processEngineConfig.getDefaultFailedJobWaitTime(), job.getDuedate()));
        }

    } else {
        try {
            DurationHelper durationHelper = new DurationHelper(failedJobRetryTimeCycleValue, processEngineConfig.getClock());
            int jobRetries = job.getRetries();
            if (job.getExceptionMessage() == null) {
                // change default retries to the ones configured
                jobRetries = durationHelper.getTimes();
            }

            if (jobRetries <= 1) {
                newJobEntity = jobService.moveJobToDeadLetterJob(job);
            } else {
                newJobEntity = timerJobService.moveJobToTimerJob(job);
            }

            newJobEntity.setDuedate(durationHelper.getDateAfter());

            if (job.getExceptionMessage() == null) { // is it the first exception
                LOGGER.debug("Applying JobRetryStrategy '{}' the first time for job {} with {} retries", failedJobRetryTimeCycleValue, job.getId(), durationHelper.getTimes());

            } else {
                LOGGER.debug("Decrementing retries of JobRetryStrategy '{}' for job {}", failedJobRetryTimeCycleValue, job.getId());
            }

            newJobEntity.setRetries(jobRetries - 1);

        } catch (Exception e) {
            throw new FlowableException("failedJobRetryTimeCycle has wrong format:" + failedJobRetryTimeCycleValue, exception);
        }
    }

    if (exception != null) {
        newJobEntity.setExceptionMessage(exception.getMessage());
        newJobEntity.setExceptionStacktrace(getExceptionStacktrace());
    }

    // Dispatch both an update and a retry-decrement event
    FlowableEventDispatcher eventDispatcher = CommandContextUtil.getEventDispatcher();
    if (eventDispatcher != null && eventDispatcher.isEnabled()) {
        eventDispatcher.dispatchEvent(FlowableEventBuilder.createEntityEvent(FlowableEngineEventType.ENTITY_UPDATED, newJobEntity));
        eventDispatcher.dispatchEvent(FlowableEventBuilder.createEntityEvent(FlowableEngineEventType.JOB_RETRIES_DECREMENTED, newJobEntity));
    }

    return null;
}
 
Example 12
Source File: SendEventTaskActivityBehavior.java    From flowable-engine with Apache License 2.0 4 votes vote down vote up
@Override
public void execute(DelegateExecution execution) {
    CommandContext commandContext = CommandContextUtil.getCommandContext();
    EventRegistry eventRegistry = CommandContextUtil.getEventRegistry(commandContext);

    EventModel eventModel = getEventModel(commandContext, execution);
    ExecutionEntity executionEntity = (ExecutionEntity) execution;

    boolean sendSynchronously = sendEventServiceTask.isSendSynchronously() || executedAsAsyncJob;
    if (!sendSynchronously) {
        JobService jobService = CommandContextUtil.getJobService(commandContext);

        JobEntity job = jobService.createJob();
        job.setExecutionId(execution.getId());
        job.setProcessInstanceId(execution.getProcessInstanceId());
        job.setProcessDefinitionId(execution.getProcessDefinitionId());
        job.setElementId(sendEventServiceTask.getId());
        job.setElementName(sendEventServiceTask.getName());
        job.setJobHandlerType(AsyncSendEventJobHandler.TYPE);

        // Inherit tenant id (if applicable)
        if (execution.getTenantId() != null) {
            job.setTenantId(execution.getTenantId());
        }

        executionEntity.getJobs().add(job);

        jobService.createAsyncJob(job, true);
        jobService.scheduleAsyncJob(job);

    } else {
        Collection<EventPayloadInstance> eventPayloadInstances = EventInstanceBpmnUtil.createEventPayloadInstances(executionEntity,
            CommandContextUtil.getProcessEngineConfiguration(commandContext).getExpressionManager(),
            execution.getCurrentFlowElement(),
            eventModel);

        boolean sendOnSystemChannel = isSendOnSystemChannel(execution);
        List<ChannelModel> channelModels = getChannelModels(commandContext, execution, sendOnSystemChannel);
        EventInstanceImpl eventInstance = new EventInstanceImpl(eventModel.getKey(), eventPayloadInstances, execution.getTenantId());
        if (!channelModels.isEmpty()) {
            eventRegistry.sendEventOutbound(eventInstance, channelModels);
        }

        if (sendOnSystemChannel) {
            eventRegistry.sendSystemEventOutbound(eventInstance);
        }

    }

    if (sendEventServiceTask.isTriggerable() && !executedAsAsyncJob) {
        String triggerEventDefinitionKey;
        if (StringUtils.isNotEmpty(sendEventServiceTask.getTriggerEventType())) {
            triggerEventDefinitionKey = sendEventServiceTask.getTriggerEventType();

        } else {
            triggerEventDefinitionKey = eventModel.getKey();
        }
        
        EventSubscriptionEntity eventSubscription = (EventSubscriptionEntity) CommandContextUtil
            .getEventSubscriptionService(commandContext).createEventSubscriptionBuilder()
                .eventType(triggerEventDefinitionKey)
                .executionId(execution.getId())
                .processInstanceId(execution.getProcessInstanceId())
                .activityId(execution.getCurrentActivityId())
                .processDefinitionId(execution.getProcessDefinitionId())
                .scopeType(ScopeTypes.BPMN)
                .tenantId(execution.getTenantId())
                .configuration(CorrelationUtil.getCorrelationKey(BpmnXMLConstants.ELEMENT_TRIGGER_EVENT_CORRELATION_PARAMETER, commandContext, executionEntity))
                .create();
        
        CountingEntityUtil.handleInsertEventSubscriptionEntityCount(eventSubscription);
        executionEntity.getEventSubscriptions().add(eventSubscription);

    } else if ( (sendSynchronously && !executedAsAsyncJob)
            || (!sendEventServiceTask.isTriggerable() && executedAsAsyncJob)) {
        // If this send task is specifically marked to send synchronously and is not triggerable then leave
        leave(execution);
    }
}