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

org.camunda.bpm.camel.component.producer.MessageProducer Maven / Gradle / Ivy

There is a newer version: 0.8.0
Show newest version
/* Licensed under the Apache License, Version 2.0 (the "License");
 * 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.camel.component.producer;

import static org.camunda.bpm.camel.component.CamundaBpmConstants.ACTIVITY_ID_PARAMETER;
import static org.camunda.bpm.camel.component.CamundaBpmConstants.CAMUNDA_BPM_BUSINESS_KEY;
import static org.camunda.bpm.camel.component.CamundaBpmConstants.CAMUNDA_BPM_CORRELATION_KEY;
import static org.camunda.bpm.camel.component.CamundaBpmConstants.CAMUNDA_BPM_PROCESS_INSTANCE_ID;
import static org.camunda.bpm.camel.component.CamundaBpmConstants.CORRELATION_KEY_NAME_PARAMETER;
import static org.camunda.bpm.camel.component.CamundaBpmConstants.MESSAGE_NAME_PARAMETER;
import static org.camunda.bpm.camel.component.CamundaBpmConstants.PROCESS_DEFINITION_KEY_PARAMETER;

import java.util.HashMap;
import java.util.Map;

import org.apache.camel.Exchange;
import org.camunda.bpm.camel.common.ExchangeUtils;
import org.camunda.bpm.camel.component.CamundaBpmEndpoint;
import org.camunda.bpm.engine.runtime.Execution;
import org.camunda.bpm.engine.runtime.ExecutionQuery;
import org.camunda.bpm.engine.runtime.ProcessInstance;
import org.camunda.bpm.engine.runtime.ProcessInstanceQuery;

/**
 * Sends a message (or signals a ReceiveTask) to a waiting process instance or
 * start a new process instance by message.
 * 
 * Example: camunda-bpm://message?messageName=someMessage
 * 
 * Example: camunda-bpm://message?activityId=receiveTask
 * 
 * @author Rafael Cordones (@rafacm)
 * @author Bernd Ruecker
 */
public class MessageProducer extends CamundaBpmProducer {

  private final String messageName;
  private final String activityId;
  private final String processDefinitionKey;
  private final String correlationKeyName;

  public MessageProducer(CamundaBpmEndpoint endpoint,
      Map parameters) {
    super(endpoint, parameters);

    if (parameters.containsKey(MESSAGE_NAME_PARAMETER)) {
      this.messageName = (String) parameters.get(MESSAGE_NAME_PARAMETER);
      this.activityId = null;
    } else if (parameters.containsKey(ACTIVITY_ID_PARAMETER)) {
      this.messageName = null;
      this.activityId = (String) parameters.get(ACTIVITY_ID_PARAMETER);
    } else {
      this.messageName = null;
      this.activityId = null;
      throw new IllegalArgumentException("You need to pass the '"
          + MESSAGE_NAME_PARAMETER + "' parameter! Parameters received: "
          + parameters);
    }
    if (parameters.containsKey(PROCESS_DEFINITION_KEY_PARAMETER)) {
      this.processDefinitionKey = (String) parameters
          .get(PROCESS_DEFINITION_KEY_PARAMETER);
    } else {
      this.processDefinitionKey = null;
    }
    if (parameters.containsKey(CORRELATION_KEY_NAME_PARAMETER)) {
      this.correlationKeyName = (String) parameters
          .get(CORRELATION_KEY_NAME_PARAMETER);
    } else {
      this.correlationKeyName = null;
    }
  }

  @Override
  public void process(Exchange exchange) throws Exception {
    String processInstanceId = exchange.getProperty(
        CAMUNDA_BPM_PROCESS_INSTANCE_ID, String.class);
    String businessKey = exchange.getProperty(CAMUNDA_BPM_BUSINESS_KEY,
        String.class);

    Map processVariables = ExchangeUtils.prepareVariables(
        exchange, parameters);

    if (messageName != null) {
      HashMap correlationKeys = new HashMap();
      if (correlationKeyName != null) {
        String correlationKey = exchange.getProperty(
            CAMUNDA_BPM_CORRELATION_KEY, String.class);
        if (correlationKey == null) {
          throw new RuntimeException(
              "Missing value for correlation key for message '" + messageName
                  + "'");
        }
        correlationKeys.put(correlationKeyName, correlationKey);
      }

      // if we have process instance we try to send the message to this one:
      if (processInstanceId != null) {
        ExecutionQuery query = runtimeService.createExecutionQuery() //
            .processInstanceId(processInstanceId) //
            .messageEventSubscriptionName(messageName);
        if (processDefinitionKey != null) {
          query.processDefinitionKey(processDefinitionKey);
        }
        Execution execution = query.singleResult();

        if (execution == null) {
          throw new RuntimeException(
              "Couldn't find waiting process instance with id '"
                  + processInstanceId + "' for message '" + messageName + "'");
        }

        runtimeService.messageEventReceived(messageName, execution.getId(),
            processVariables);
      } else if (businessKey != null) {
        // if we have businessKey, use it to correlate
        runtimeService.correlateMessage(messageName, businessKey,
            correlationKeys, processVariables);
      } else {
        // otherwise we just send the message to the engine to let the engine
        // decide what to do
        // this can either correlate to a waiting instance or start a new
        // process Instance

        runtimeService.correlateMessage(messageName, correlationKeys,
            processVariables);
      }
    } else {
      // signal a ReceiveTask needs a processInstance to be addressed
      // (hint: this should be best done by a message in the ReceiveTask
      // as this is possible from 7.1 on - this was introduced with 7.0
      // where this was not yet possible)
      if (processInstanceId == null && businessKey != null) {
        ProcessInstanceQuery query = runtimeService
            .createProcessInstanceQuery().processInstanceBusinessKey(
                businessKey);
        if (processDefinitionKey != null) {
          query.processDefinitionKey(processDefinitionKey);
        }
        ProcessInstance processInstance = query.singleResult();
        if (processInstance != null) {
          processInstanceId = processInstance.getId();
        }
      }

      if (processInstanceId == null) {
        throw new RuntimeException(
            "Could not find the process instance via the provided properties ("
                + CAMUNDA_BPM_PROCESS_INSTANCE_ID + "= '" + processInstanceId
                + "', " + CAMUNDA_BPM_BUSINESS_KEY + "= '" + businessKey + "'");
      }

      ExecutionQuery query = runtimeService.createExecutionQuery()
          .processInstanceId(processInstanceId).activityId(activityId);

      if (processDefinitionKey != null) {
        query.processDefinitionKey(processDefinitionKey);
      }
      Execution execution = query.singleResult();

      if (execution == null) {
        throw new RuntimeException("Couldn't find process instance with id '"
            + processInstanceId + "' waiting in activity '" + activityId + "'");
      }

      runtimeService.signal(execution.getId(), processVariables);
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy