/* * 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. * * 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.audit.jms; import java.util.List; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageListener; import javax.jms.TextMessage; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import org.jbpm.process.audit.AbstractAuditLogger; import org.jbpm.process.audit.NodeInstanceLog; import org.jbpm.process.audit.ProcessInstanceLog; import com.thoughtworks.xstream.XStream; /** * Asynchronous audit event receiver. Receives messages from JMS queue * that it is attached to as <code>MessageListener</code>. * This is the second part of asynchronous BAM support backed by JMS * (producer is provide by <code>AsyncAuditLogProducer</code> class). * Thus it shares the same message format that is TextMessage with * Xstream serialized *Log classes (ProcessInstanceLog, * NodeInstanceLog, VaraiableInstanceLog) as content. * * by default it uses entity manager factory and creates entity manager for each message * although it provides getEntityManager method that can be overloaded by extensions to supply * entity managers instead of creating it for every message. * * For more enterprise based solution this class can be extended by MDB implementations to * provide additional details that are required by MDB such as: * <ul> * <li>annotations - @MessageDriven, @ActivationConfigurationProperty</li> * <li>dependency injection - inject entity manager factory or entity manager by annotating methods</li> * </ul> */ public class AsyncAuditLogReceiver implements MessageListener { private EntityManagerFactory entityManagerFactory; public AsyncAuditLogReceiver(EntityManagerFactory entityManagerFactory) { this.entityManagerFactory = entityManagerFactory; } @SuppressWarnings("unchecked") @Override public void onMessage(Message message) { if (message instanceof TextMessage) { EntityManager em = getEntityManager(); TextMessage textMessage = (TextMessage) message; try { String messageContent = textMessage.getText(); Integer eventType = textMessage.getIntProperty("EventType"); XStream xstram = new XStream(); Object event = xstram.fromXML(messageContent); switch (eventType) { case AbstractAuditLogger.AFTER_NODE_ENTER_EVENT_TYPE: NodeInstanceLog nodeAfterEnterEvent = (NodeInstanceLog) event; if (nodeAfterEnterEvent.getWorkItemId() != null) { List<NodeInstanceLog> result = em.createQuery( "from NodeInstanceLog as log where log.nodeInstanceId = :nodeId and log.type = 0") .setParameter("nodeId", nodeAfterEnterEvent.getNodeInstanceId()).getResultList(); if (result != null && result.size() != 0) { NodeInstanceLog log = result.get(result.size() - 1); log.setWorkItemId(nodeAfterEnterEvent.getWorkItemId()); em.merge(log); } } break; case AbstractAuditLogger.AFTER_COMPLETE_EVENT_TYPE: ProcessInstanceLog processCompletedEvent = (ProcessInstanceLog) event; List<ProcessInstanceLog> result = em.createQuery( "from ProcessInstanceLog as log where log.processInstanceId = :piId and log.end is null") .setParameter("piId", processCompletedEvent.getProcessInstanceId()).getResultList(); if (result != null && result.size() != 0) { ProcessInstanceLog log = result.get(result.size() - 1); log.setOutcome(processCompletedEvent.getOutcome()); log.setStatus(processCompletedEvent.getStatus()); log.setEnd(processCompletedEvent.getEnd()); log.setDuration(processCompletedEvent.getDuration()); em.merge(log); } break; default: em.persist(event); break; } em.flush(); em.close(); } catch (JMSException e) { e.printStackTrace(); throw new RuntimeException("Exception when receiving audit event event", e); } } } public EntityManagerFactory getEntityManagerFactory() { return entityManagerFactory; } public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) { this.entityManagerFactory = entityManagerFactory; } public EntityManager getEntityManager() { return entityManagerFactory.createEntityManager(); } }