org.jbpm.process.workitem.jms.JMSSignalReceiver.java Source code

Java tutorial

Introduction

Here is the source code for org.jbpm.process.workitem.jms.JMSSignalReceiver.java

Source

/*
 * Copyright 2015 JBoss by Red Hat.
 *
 * 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.jbpm.process.workitem.jms;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.HashMap;
import java.util.Map;

import javax.jms.BytesMessage;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;

import org.apache.commons.io.input.ClassLoaderObjectInputStream;
import org.kie.api.runtime.manager.RuntimeEngine;
import org.kie.api.runtime.manager.RuntimeManager;
import org.kie.internal.runtime.manager.InternalRuntimeManager;
import org.kie.internal.runtime.manager.RuntimeManagerRegistry;
import org.kie.internal.runtime.manager.context.ProcessInstanceIdContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class JMSSignalReceiver implements MessageListener {

    private static final Logger logger = LoggerFactory.getLogger(JMSSignalReceiver.class);

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    public void onMessage(Message message) {
        if (message instanceof BytesMessage) {

            String deploymentId;
            Long processInstanceId;
            String signal;
            Long workItemId;

            Object data;

            BytesMessage bytesMessage = (BytesMessage) message;

            RuntimeManager runtimeManager = null;
            RuntimeEngine engine = null;
            try {
                deploymentId = (String) bytesMessage.getObjectProperty("KIE_SignalDeploymentId");
                if (deploymentId == null) {
                    deploymentId = (String) bytesMessage.getObjectProperty("KIE_DeploymentId");
                }
                signal = (String) bytesMessage.getObjectProperty("KIE_Signal");
                processInstanceId = (Long) bytesMessage.getObjectProperty("KIE_SignalProcessInstanceId");
                workItemId = (Long) bytesMessage.getObjectProperty("KIE_SignalWorkItemId");

                logger.debug("Deployment id '{}', signal '{}', processInstanceId '{}', workItemId '{}'",
                        deploymentId, signal, processInstanceId, workItemId);

                runtimeManager = RuntimeManagerRegistry.get().getManager(deploymentId);

                if (runtimeManager == null) {
                    throw new IllegalStateException("There is no runtime manager for deployment " + deploymentId);
                }
                logger.debug(
                        "RuntimeManager found for deployment id {}, reading message content with custom class loader of the deployment",
                        deploymentId);
                data = readData(bytesMessage,
                        ((InternalRuntimeManager) runtimeManager).getEnvironment().getClassLoader());
                logger.debug("Data read successfully with output {}", data);
                engine = runtimeManager.getRuntimeEngine(ProcessInstanceIdContext.get(processInstanceId));

                // perform operation either signal or complete work item
                if (workItemId != null) {
                    Map<String, Object> results = new HashMap<String, Object>();
                    if (data != null) {
                        if (data instanceof Map) {
                            results.putAll((Map) data);
                        } else {
                            results.put("Data", data);
                        }
                    }
                    logger.debug("About to complete work item with id {} and data {}", workItemId, results);
                    engine.getKieSession().getWorkItemManager().completeWorkItem(workItemId, results);
                    logger.debug("Successfully completed work item with id {}", workItemId);
                } else if (signal != null) {
                    if (processInstanceId != null) {
                        logger.debug("About to signal process instance with id {} and event data {} with signal {}",
                                processInstanceId, data, signal);
                        engine.getKieSession().signalEvent(signal, data, processInstanceId);
                    } else {
                        logger.debug("About to broadcast signal {} and event data {}", signal, data);
                        runtimeManager.signalEvent(signal, data);
                    }
                    logger.debug("Signal completed successfully for signal {} with data {}", signal, data);
                } else {
                    logger.warn("No signal or workitem id is given, skipping this message");
                }

            } catch (Exception e) {
                logger.error("Unexpected exception while processing signal JMS message: {}", e.getMessage(), e);
            } finally {
                if (runtimeManager != null && engine != null) {
                    runtimeManager.disposeRuntimeEngine(engine);
                }
            }

        }
    }

    protected Object readData(BytesMessage message, ClassLoader cl) throws JMSException, Exception {
        Object data = null;
        if (message.getBodyLength() > 0) {
            byte[] reqData = new byte[(int) message.getBodyLength()];

            message.readBytes(reqData);
            if (reqData != null) {
                ObjectInputStream in = null;
                try {
                    in = new ClassLoaderObjectInputStream(cl, new ByteArrayInputStream(reqData));
                    data = in.readObject();
                } catch (IOException e) {
                    logger.warn("Exception while serializing context data", e);

                } finally {
                    if (in != null) {
                        in.close();
                    }
                }
            }
        }
        return data;
    }

}