protected void removeObsoleteTimers(ProcessDefinitionEntity processDefinition) { List<Job> jobsToDelete = null; if (processDefinition.getTenantId() != null && !ProcessEngineConfiguration.NO_TENANT_ID.equals(processDefinition.getTenantId())) { jobsToDelete = Context.getCommandContext() .getJobEntityManager() .findJobsByTypeAndProcessDefinitionKeyAndTenantId( TimerStartEventJobHandler.TYPE, processDefinition.getKey(), processDefinition.getTenantId()); } else { jobsToDelete = Context.getCommandContext() .getJobEntityManager() .findJobsByTypeAndProcessDefinitionKeyNoTenantId( TimerStartEventJobHandler.TYPE, processDefinition.getKey()); } if (jobsToDelete != null) { for (Job job : jobsToDelete) { new CancelJobsCmd(job.getId()).execute(Context.getCommandContext()); } } }
@SuppressWarnings("unchecked") protected void addSignalEventSubscriptions(ProcessDefinitionEntity processDefinition) { List<EventSubscriptionDeclaration> eventDefinitions = (List<EventSubscriptionDeclaration>) processDefinition.getProperty(BpmnParse.PROPERTYNAME_EVENT_SUBSCRIPTION_DECLARATION); if (eventDefinitions != null) { for (EventSubscriptionDeclaration eventDefinition : eventDefinitions) { if (eventDefinition.getEventType().equals("signal") && eventDefinition.isStartEvent()) { SignalEventSubscriptionEntity subscriptionEntity = new SignalEventSubscriptionEntity(); subscriptionEntity.setEventName(eventDefinition.getEventName()); subscriptionEntity.setActivityId(eventDefinition.getActivityId()); subscriptionEntity.setProcessDefinitionId(processDefinition.getId()); if (processDefinition.getTenantId() != null) { subscriptionEntity.setTenantId(processDefinition.getTenantId()); } subscriptionEntity.insert(); } } } }
@SuppressWarnings("unchecked") protected void addTimerDeclarations( ProcessDefinitionEntity processDefinition, List<TimerEntity> timers) { List<TimerDeclarationImpl> timerDeclarations = (List<TimerDeclarationImpl>) processDefinition.getProperty(BpmnParse.PROPERTYNAME_START_TIMER); if (timerDeclarations != null) { for (TimerDeclarationImpl timerDeclaration : timerDeclarations) { TimerEntity timer = timerDeclaration.prepareTimerEntity(null); if (timer != null) { timer.setProcessDefinitionId(processDefinition.getId()); // Inherit timer (if appliccable) if (processDefinition.getTenantId() != null) { timer.setTenantId(processDefinition.getTenantId()); } timers.add(timer); } } } }
protected void removeExistingSignalEventSubScription( ProcessDefinitionEntity processDefinition, ProcessDefinitionEntity latestProcessDefinition) { if (latestProcessDefinition != null) { CommandContext commandContext = Context.getCommandContext(); List<EventSubscriptionEntity> subscriptionsToDisable = commandContext .getEventSubscriptionEntityManager() .findEventSubscriptionsByTypeAndProcessDefinitionId( SignalEventHandler.EVENT_HANDLER_TYPE, latestProcessDefinition.getId(), latestProcessDefinition.getTenantId()); for (EventSubscriptionEntity eventSubscriptionEntity : subscriptionsToDisable) { eventSubscriptionEntity.delete(); } } }
public void deploy(DeploymentEntity deployment, Map<String, Object> deploymentSettings) { log.debug("Processing deployment {}", deployment.getName()); List<ProcessDefinitionEntity> processDefinitions = new ArrayList<ProcessDefinitionEntity>(); Map<String, ResourceEntity> resources = deployment.getResources(); Map<String, BpmnModel> bpmnModelMap = new HashMap<String, BpmnModel>(); final ProcessEngineConfigurationImpl processEngineConfiguration = Context.getProcessEngineConfiguration(); for (String resourceName : resources.keySet()) { log.info("Processing resource {}", resourceName); if (isBpmnResource(resourceName)) { ResourceEntity resource = resources.get(resourceName); byte[] bytes = resource.getBytes(); ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); BpmnParse bpmnParse = bpmnParser .createParse() .sourceInputStream(inputStream) .setSourceSystemId(resourceName) .deployment(deployment) .name(resourceName); if (deploymentSettings != null) { // Schema validation if needed if (deploymentSettings.containsKey(DeploymentSettings.IS_BPMN20_XSD_VALIDATION_ENABLED)) { bpmnParse.setValidateSchema( (Boolean) deploymentSettings.get(DeploymentSettings.IS_BPMN20_XSD_VALIDATION_ENABLED)); } // Process validation if needed if (deploymentSettings.containsKey(DeploymentSettings.IS_PROCESS_VALIDATION_ENABLED)) { bpmnParse.setValidateProcess( (Boolean) deploymentSettings.get(DeploymentSettings.IS_PROCESS_VALIDATION_ENABLED)); } } else { // On redeploy, we assume it is validated at the first deploy bpmnParse.setValidateSchema(false); bpmnParse.setValidateProcess(false); } bpmnParse.execute(); for (ProcessDefinitionEntity processDefinition : bpmnParse.getProcessDefinitions()) { processDefinition.setResourceName(resourceName); if (deployment.getTenantId() != null) { processDefinition.setTenantId( deployment.getTenantId()); // process definition inherits the tenant id } String diagramResourceName = getDiagramResourceForProcess(resourceName, processDefinition.getKey(), resources); // Only generate the resource when deployment is new to prevent modification of deployment // resources // after the process-definition is actually deployed. Also to prevent resource-generation // failure every // time the process definition is added to the deployment-cache when diagram-generation // has failed the first time. if (deployment.isNew()) { if (processEngineConfiguration.isCreateDiagramOnDeploy() && diagramResourceName == null && processDefinition.isGraphicalNotationDefined()) { try { byte[] diagramBytes = IoUtil.readInputStream( processEngineConfiguration .getProcessDiagramGenerator() .generateDiagram( bpmnParse.getBpmnModel(), "png", processEngineConfiguration.getActivityFontName(), processEngineConfiguration.getLabelFontName(), processEngineConfiguration.getClassLoader()), null); diagramResourceName = getProcessImageResourceName(resourceName, processDefinition.getKey(), "png"); createResource(diagramResourceName, diagramBytes, deployment); } catch ( Throwable t) { // if anything goes wrong, we don't store the image (the process will // still be executable). log.warn( "Error while generating process diagram, image will not be stored in repository", t); } } } processDefinition.setDiagramResourceName(diagramResourceName); processDefinitions.add(processDefinition); bpmnModelMap.put(processDefinition.getKey(), bpmnParse.getBpmnModel()); } } } // check if there are process definitions with the same process key to prevent database unique // index violation List<String> keyList = new ArrayList<String>(); for (ProcessDefinitionEntity processDefinition : processDefinitions) { if (keyList.contains(processDefinition.getKey())) { throw new ActivitiException( "The deployment contains process definitions with the same key (process id atrribute), this is not allowed"); } keyList.add(processDefinition.getKey()); } CommandContext commandContext = Context.getCommandContext(); ProcessDefinitionEntityManager processDefinitionManager = commandContext.getProcessDefinitionEntityManager(); DbSqlSession dbSqlSession = commandContext.getSession(DbSqlSession.class); for (ProcessDefinitionEntity processDefinition : processDefinitions) { List<TimerEntity> timers = new ArrayList<TimerEntity>(); if (deployment.isNew()) { int processDefinitionVersion; ProcessDefinitionEntity latestProcessDefinition = null; if (processDefinition.getTenantId() != null && !ProcessEngineConfiguration.NO_TENANT_ID.equals(processDefinition.getTenantId())) { latestProcessDefinition = processDefinitionManager.findLatestProcessDefinitionByKeyAndTenantId( processDefinition.getKey(), processDefinition.getTenantId()); } else { latestProcessDefinition = processDefinitionManager.findLatestProcessDefinitionByKey(processDefinition.getKey()); } if (latestProcessDefinition != null) { processDefinitionVersion = latestProcessDefinition.getVersion() + 1; } else { processDefinitionVersion = 1; } processDefinition.setVersion(processDefinitionVersion); processDefinition.setDeploymentId(deployment.getId()); String nextId = idGenerator.getNextId(); String processDefinitionId = processDefinition.getKey() + ":" + processDefinition.getVersion() + ":" + nextId; // ACT-505 // ACT-115: maximum id length is 64 charcaters if (processDefinitionId.length() > 64) { processDefinitionId = nextId; } processDefinition.setId(processDefinitionId); if (commandContext.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) { commandContext .getProcessEngineConfiguration() .getEventDispatcher() .dispatchEvent( ActivitiEventBuilder.createEntityEvent( ActivitiEventType.ENTITY_CREATED, processDefinition)); } removeObsoleteTimers(processDefinition); addTimerDeclarations(processDefinition, timers); removeExistingMessageEventSubscriptions(processDefinition, latestProcessDefinition); addMessageEventSubscriptions(processDefinition); removeExistingSignalEventSubScription(processDefinition, latestProcessDefinition); addSignalEventSubscriptions(processDefinition); dbSqlSession.insert(processDefinition); addAuthorizations(processDefinition); if (commandContext.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) { commandContext .getProcessEngineConfiguration() .getEventDispatcher() .dispatchEvent( ActivitiEventBuilder.createEntityEvent( ActivitiEventType.ENTITY_INITIALIZED, processDefinition)); } scheduleTimers(timers); } else { String deploymentId = deployment.getId(); processDefinition.setDeploymentId(deploymentId); ProcessDefinitionEntity persistedProcessDefinition = null; if (processDefinition.getTenantId() == null || ProcessEngineConfiguration.NO_TENANT_ID.equals(processDefinition.getTenantId())) { persistedProcessDefinition = processDefinitionManager.findProcessDefinitionByDeploymentAndKey( deploymentId, processDefinition.getKey()); } else { persistedProcessDefinition = processDefinitionManager.findProcessDefinitionByDeploymentAndKeyAndTenantId( deploymentId, processDefinition.getKey(), processDefinition.getTenantId()); } if (persistedProcessDefinition != null) { processDefinition.setId(persistedProcessDefinition.getId()); processDefinition.setVersion(persistedProcessDefinition.getVersion()); processDefinition.setSuspensionState(persistedProcessDefinition.getSuspensionState()); } } // Add to cache DeploymentManager deploymentManager = processEngineConfiguration.getDeploymentManager(); deploymentManager .getProcessDefinitionCache() .add(processDefinition.getId(), processDefinition); addDefinitionInfoToCache(processDefinition, processEngineConfiguration, commandContext); // Add to deployment for further usage deployment.addDeployedArtifact(processDefinition); createLocalizationValues( processDefinition.getId(), bpmnModelMap.get(processDefinition.getKey()).getProcessById(processDefinition.getKey())); } }
@SuppressWarnings("unchecked") protected void addMessageEventSubscriptions(ProcessDefinitionEntity processDefinition) { CommandContext commandContext = Context.getCommandContext(); List<EventSubscriptionDeclaration> eventDefinitions = (List<EventSubscriptionDeclaration>) processDefinition.getProperty(BpmnParse.PROPERTYNAME_EVENT_SUBSCRIPTION_DECLARATION); if (eventDefinitions != null) { Set<String> messageNames = new HashSet<String>(); for (EventSubscriptionDeclaration eventDefinition : eventDefinitions) { if (eventDefinition.getEventType().equals("message") && eventDefinition.isStartEvent()) { if (!messageNames.contains(eventDefinition.getEventName())) { messageNames.add(eventDefinition.getEventName()); } else { throw new ActivitiException( "Cannot deploy process definition '" + processDefinition.getResourceName() + "': there are multiple message event subscriptions for the message with name '" + eventDefinition.getEventName() + "'."); } // look for subscriptions for the same name in db: List<EventSubscriptionEntity> subscriptionsForSameMessageName = commandContext .getEventSubscriptionEntityManager() .findEventSubscriptionsByName( MessageEventHandler.EVENT_HANDLER_TYPE, eventDefinition.getEventName(), processDefinition.getTenantId()); // also look for subscriptions created in the session: List<MessageEventSubscriptionEntity> cachedSubscriptions = commandContext.getDbSqlSession().findInCache(MessageEventSubscriptionEntity.class); for (MessageEventSubscriptionEntity cachedSubscription : cachedSubscriptions) { if (eventDefinition.getEventName().equals(cachedSubscription.getEventName()) && !subscriptionsForSameMessageName.contains(cachedSubscription)) { subscriptionsForSameMessageName.add(cachedSubscription); } } // remove subscriptions deleted in the same command subscriptionsForSameMessageName = commandContext .getDbSqlSession() .pruneDeletedEntities(subscriptionsForSameMessageName); for (EventSubscriptionEntity eventSubscriptionEntity : subscriptionsForSameMessageName) { // throw exception only if there's already a subscription as start event // no process instance-id = it's a message start event if (StringUtils.isEmpty(eventSubscriptionEntity.getProcessInstanceId())) { throw new ActivitiException( "Cannot deploy process definition '" + processDefinition.getResourceName() + "': there already is a message event subscription for the message with name '" + eventDefinition.getEventName() + "'."); } } MessageEventSubscriptionEntity newSubscription = new MessageEventSubscriptionEntity(); newSubscription.setEventName(eventDefinition.getEventName()); newSubscription.setActivityId(eventDefinition.getActivityId()); newSubscription.setConfiguration(processDefinition.getId()); newSubscription.setProcessDefinitionId(processDefinition.getId()); if (processDefinition.getTenantId() != null) { newSubscription.setTenantId(processDefinition.getTenantId()); } newSubscription.insert(); } } } }