All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.camunda.bpm.engine.impl.cmd.SignalEventReceivedCmd Maven / Gradle / Ivy

There is a newer version: 7.22.0-alpha1
Show newest version
/*
 * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
 * under one or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership. Camunda licenses this file to you under the Apache License,
 * Version 2.0; you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     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.camunda.bpm.engine.impl.cmd;

import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotEmpty;
import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotNull;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.camunda.bpm.engine.exception.NotFoundException;
import org.camunda.bpm.engine.impl.ProcessEngineLogger;
import org.camunda.bpm.engine.impl.SignalEventReceivedBuilderImpl;
import org.camunda.bpm.engine.impl.cfg.CommandChecker;
import org.camunda.bpm.engine.impl.context.Context;
import org.camunda.bpm.engine.impl.interceptor.Command;
import org.camunda.bpm.engine.impl.interceptor.CommandContext;
import org.camunda.bpm.engine.impl.persistence.deploy.cache.DeploymentCache;
import org.camunda.bpm.engine.impl.persistence.entity.EventSubscriptionEntity;
import org.camunda.bpm.engine.impl.persistence.entity.EventSubscriptionManager;
import org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity;
import org.camunda.bpm.engine.impl.persistence.entity.ExecutionManager;
import org.camunda.bpm.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.camunda.bpm.engine.impl.pvm.PvmProcessInstance;
import org.camunda.bpm.engine.impl.pvm.process.ActivityImpl;


/**
 * @author Daniel Meyer
 * @author Joram Barrez
 */
public class SignalEventReceivedCmd implements Command {

  protected final static CommandLogger LOG = ProcessEngineLogger.CMD_LOGGER;

  protected final SignalEventReceivedBuilderImpl builder;

  public SignalEventReceivedCmd(SignalEventReceivedBuilderImpl builder) {
    this.builder = builder;
  }

  @Override
  public Void execute(final CommandContext commandContext) {

    String signalName = builder.getSignalName();
    String executionId = builder.getExecutionId();

    if(executionId == null) {
      sendSignal(commandContext, signalName);

    } else {
      sendSignalToExecution(commandContext, signalName, executionId);
    }
    return null;
  }

  protected void sendSignal(CommandContext commandContext, String signalName) {

    List signalEventSubscriptions = findSignalEventSubscriptions(commandContext, signalName);

    List catchSignalEventSubscription = filterIntermediateSubscriptions(signalEventSubscriptions);
    List startSignalEventSubscriptions = filterStartSubscriptions(signalEventSubscriptions);
    Map processDefinitions = getProcessDefinitionsOfSubscriptions(startSignalEventSubscriptions);

    checkAuthorizationOfCatchSignals(commandContext, catchSignalEventSubscription);
    checkAuthorizationOfStartSignals(commandContext, startSignalEventSubscriptions, processDefinitions);

    notifyExecutions(catchSignalEventSubscription);
    startProcessInstances(startSignalEventSubscriptions, processDefinitions);
  }

  protected List findSignalEventSubscriptions(CommandContext commandContext, String signalName) {
    EventSubscriptionManager eventSubscriptionManager = commandContext.getEventSubscriptionManager();

    if (builder.isTenantIdSet()) {
      return eventSubscriptionManager.findSignalEventSubscriptionsByEventNameAndTenantId(signalName, builder.getTenantId());

    } else {
      return eventSubscriptionManager.findSignalEventSubscriptionsByEventName(signalName);
    }
  }

  protected Map getProcessDefinitionsOfSubscriptions(List startSignalEventSubscriptions) {
    DeploymentCache deploymentCache = Context.getProcessEngineConfiguration().getDeploymentCache();

    Map processDefinitions = new HashMap();

    for (EventSubscriptionEntity eventSubscription : startSignalEventSubscriptions) {

      String processDefinitionId = eventSubscription.getConfiguration();
      ensureNotNull("Configuration of signal start event subscription '" + eventSubscription.getId() + "' contains no process definition id.",
          processDefinitionId);

      ProcessDefinitionEntity processDefinition = deploymentCache.findDeployedProcessDefinitionById(processDefinitionId);
      if (processDefinition != null && !processDefinition.isSuspended()) {
        processDefinitions.put(eventSubscription.getId(), processDefinition);
      }
    }

    return processDefinitions;
  }

  protected void sendSignalToExecution(CommandContext commandContext, String signalName, String executionId) {

    ExecutionManager executionManager = commandContext.getExecutionManager();
    ExecutionEntity execution = executionManager.findExecutionById(executionId);
    ensureNotNull("Cannot find execution with id '" + executionId + "'", "execution", execution);

    EventSubscriptionManager eventSubscriptionManager = commandContext.getEventSubscriptionManager();
    List signalEvents = eventSubscriptionManager.findSignalEventSubscriptionsByNameAndExecution(signalName, executionId);
    ensureNotEmpty(NotFoundException.class, "Execution '" + executionId + "' has not subscribed to a signal event with name '" + signalName + "'.", signalEvents);

    checkAuthorizationOfCatchSignals(commandContext, signalEvents);
    notifyExecutions(signalEvents);
  }

  protected void checkAuthorizationOfCatchSignals(final CommandContext commandContext, List catchSignalEventSubscription) {
    // check authorization for each fetched signal event
    for (EventSubscriptionEntity event : catchSignalEventSubscription) {
      String processInstanceId = event.getProcessInstanceId();
      for(CommandChecker checker : commandContext.getProcessEngineConfiguration().getCommandCheckers()) {
        checker.checkUpdateProcessInstanceById(processInstanceId);
      }
    }
  }

  private void checkAuthorizationOfStartSignals(final CommandContext commandContext,
      List startSignalEventSubscriptions, Map processDefinitions) {
    // check authorization for process definition
    for (EventSubscriptionEntity signalStartEventSubscription : startSignalEventSubscriptions) {
      ProcessDefinitionEntity processDefinition = processDefinitions.get(signalStartEventSubscription.getId());
      if (processDefinition != null) {

        for(CommandChecker checker : commandContext.getProcessEngineConfiguration().getCommandCheckers()) {
          checker.checkCreateProcessInstance(processDefinition);
        }

      }
    }
  }

  private void notifyExecutions(List catchSignalEventSubscription) {

    for (EventSubscriptionEntity signalEventSubscriptionEntity : catchSignalEventSubscription) {
      if (isActiveEventSubscription(signalEventSubscriptionEntity)) {
        signalEventSubscriptionEntity.eventReceived(builder.getVariables(), false);
      }
    }
  }

  private boolean isActiveEventSubscription(EventSubscriptionEntity signalEventSubscriptionEntity) {
    ExecutionEntity execution = signalEventSubscriptionEntity.getExecution();
    return !execution.isEnded() && !execution.isCanceled();
  }

  private void startProcessInstances(List startSignalEventSubscriptions, Map processDefinitions) {
    for (EventSubscriptionEntity signalStartEventSubscription : startSignalEventSubscriptions) {
      ProcessDefinitionEntity processDefinition = processDefinitions.get(signalStartEventSubscription.getId());
      if (processDefinition != null) {

        ActivityImpl signalStartEvent = processDefinition.findActivity(signalStartEventSubscription.getActivityId());
        PvmProcessInstance processInstance = processDefinition.createProcessInstanceForInitial(signalStartEvent);
        processInstance.start(builder.getVariables());
      }
    }
  }

  protected List filterIntermediateSubscriptions(List subscriptions) {
    List result = new ArrayList();

    for (EventSubscriptionEntity subscription : subscriptions) {
      if (subscription.getExecutionId() != null) {
        result.add(subscription);
      }
    }

    return result;
  }

  protected List filterStartSubscriptions(List subscriptions) {
    List result = new ArrayList();

    for (EventSubscriptionEntity subscription : subscriptions) {
      if (subscription.getExecutionId() == null) {
        result.add(subscription);
      }
    }

    return result;
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy