/* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * 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.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import javax.jms.BytesMessage; import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageProducer; import javax.jms.Session; import javax.naming.InitialContext; import org.drools.core.process.instance.impl.WorkItemImpl; import org.jbpm.process.workitem.AbstractLogOrThrowWorkItemHandler; import org.kie.api.runtime.process.WorkItem; import org.kie.api.runtime.process.WorkItemManager; import org.kie.internal.runtime.Cacheable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class JMSSendTaskWorkItemHandler extends AbstractLogOrThrowWorkItemHandler implements Cacheable { private static final Logger logger = LoggerFactory.getLogger(JMSSendTaskWorkItemHandler.class); private String connectionFactoryName; private String destinationName; private ConnectionFactory connectionFactory; private Destination destination; private boolean transacted = false; public JMSSendTaskWorkItemHandler() { this.connectionFactoryName = "java:/JmsXA"; this.destinationName = "queue/KIE.SIGNAL"; init(); } public JMSSendTaskWorkItemHandler(String connectionFactoryName, String destinationName) { this.connectionFactoryName = connectionFactoryName; this.destinationName = destinationName; init(); } public JMSSendTaskWorkItemHandler(ConnectionFactory connectionFactory, Destination destination) { this.connectionFactory = connectionFactory; this.destination = destination; init(); } public JMSSendTaskWorkItemHandler(String connectionFactoryName, String destinationName, boolean transacted) { this.connectionFactoryName = connectionFactoryName; this.destinationName = destinationName; this.transacted = transacted; init(); } public JMSSendTaskWorkItemHandler(ConnectionFactory connectionFactory, Destination destination, boolean transacted) { this.connectionFactory = connectionFactory; this.destination = destination; this.transacted = transacted; init(); } protected void init() { try { InitialContext ctx = new InitialContext(); if (this.connectionFactory == null) { this.connectionFactory = (ConnectionFactory) ctx.lookup(connectionFactoryName); } if (this.destination == null) { this.destination = (Destination) ctx.lookup(destinationName); } logger.info("JMS based work item handler successfully activated on destination {}", destination); } catch (Exception e) { logger.error("Unable to initialize JMS send work item handler due to {}", e.getMessage(), e); } } protected Message createMessage(WorkItem workItem, Session session) throws JMSException { BytesMessage message = session.createBytesMessage(); // set properties addPropertyIfExists("KIE_Signal", workItem.getParameter("Signal"), message); addPropertyIfExists("KIE_SignalProcessInstanceId", workItem.getParameter("SignalProcessInstanceId"), message); addPropertyIfExists("KIE_SignalWorkItemId", workItem.getParameter("SignalWorkItemId"), message); addPropertyIfExists("KIE_SignalDeploymentId", workItem.getParameter("SignalDeploymentId"), message); addPropertyIfExists("KIE_ProcessInstanceId", workItem.getProcessInstanceId(), message); addPropertyIfExists("KIE_DeploymentId", ((WorkItemImpl)workItem).getDeploymentId(), message); Object data = workItem.getParameter("Data"); if (data != null) { try { ByteArrayOutputStream bout = new ByteArrayOutputStream(); ObjectOutputStream oout = new ObjectOutputStream(bout); oout.writeObject(data); message.writeBytes(bout.toByteArray()); } catch (IOException e) { logger.warn("Error serializing context data", e); } } return message; } @Override public void executeWorkItem(WorkItem workItem, WorkItemManager manager) { if (connectionFactory == null || destination == null) { throw new RuntimeException("Connection factory and destination must be set for JMS send task handler"); } Connection connection = null; Session session = null; MessageProducer producer = null; try { connection = connectionFactory.createConnection(); session = connection.createSession(transacted, Session.AUTO_ACKNOWLEDGE); Message message = createMessage(workItem, session); producer = session.createProducer(destination); producer.send(message); } catch (Exception e) { handleException(e); } finally { if (producer != null) { try { producer.close(); } catch (JMSException e) { logger.warn("Error when closing producer", e); } } if (session != null) { try { session.close(); } catch (JMSException e) { logger.warn("Error when closing queue session", e); } } if (connection != null) { try { connection.close(); } catch (JMSException e) { logger.warn("Error when closing queue connection", e); } } } } @Override public void abortWorkItem(WorkItem workItem, WorkItemManager manager) { // no-op } @Override public void close() { connectionFactory = null; destination = null; } protected void addPropertyIfExists(String propertyName, Object properyValue, Message msg) throws JMSException { if (properyValue != null) { msg.setObjectProperty(propertyName, properyValue); } } }