/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.processFlow.knowledgeService; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.annotation.Resource; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Default; import javax.jms.*; import org.apache.commons.pool.PoolableObjectFactory; import org.apache.commons.pool.impl.GenericObjectPool; import org.apache.log4j.Logger; import org.jboss.processFlow.util.MessagingUtil; import org.jboss.processFlow.bam.IBAMService; @ApplicationScoped @Default public class AsyncBAMProducerPool implements PoolableObjectFactory { private static Logger log = Logger.getLogger("AsyncBAMProducerPool"); private static Connection connectObj; private static Destination dQueue; private GenericObjectPool producerPool; // failed: Error looking up java:comp/env/java:/JmsXA in JNDI // @Resource(name="java:/JmsXA") private ConnectionFactory cFactory; @PostConstruct public void start() { // 1) grab JMS objects try { cFactory = MessagingUtil.grabConnectionFactory(); connectObj = cFactory.createConnection(); dQueue = (Destination)MessagingUtil.grabDestination(IBAMService.BAM_QUEUE); } catch(Exception x) { throw new RuntimeException(x); } // 2) create a FIFO pool to manage 'PoolWrapper' objects producerPool = new GenericObjectPool(this); // 3) set settings on pool int poolMaxIdle = 10; if(System.getProperty("org.jboss.processFlow.bam.AsyncBAMProducerPool.poolMaxIdle") != null) poolMaxIdle = Integer.parseInt(System.getProperty("org.jboss.processFlow.bam.AsyncBAMProducerPool.poolMaxIdle")); producerPool.setMaxIdle(poolMaxIdle); producerPool.setMaxActive(-1); producerPool.setLifo(false); log.info("start() just created AsyncBAMProducerPool with poolMaxIdle = "+poolMaxIdle); } public BAMProducerWrapper borrowObject() throws Exception { return (BAMProducerWrapper)producerPool.borrowObject(); } public void returnObject(BAMProducerWrapper pWrapper) throws Exception { producerPool.returnObject(pWrapper); } @PreDestroy public void close() throws Exception { log.info("close() "); if(producerPool != null) producerPool.close(); producerPool = null; if(connectObj != null) connectObj.close(); } public int getNumActive() { return producerPool.getNumActive(); } public int getNumIdle() { return producerPool.getNumIdle(); } //Instances returned from this method should be in the same state as if they had been activated //They will not be activated before being served by the pool public Object makeObject() throws JMSException { log.info("makeObject() "); Session pSession = connectObj.createSession(true, Session.AUTO_ACKNOWLEDGE); return new BAMProducerWrapper(pSession, dQueue); } // (re)initialize a instance from the pool // this method is invoked directly after makeObject() or when previously passivated object is being again borrowed from the pool public void activateObject(Object obj) throws Exception { //log.info("passivateObject() "); } public void passivateObject(Object obj) throws Exception { //log.info("passivateObject() "); Session pSession = ((BAMProducerWrapper)obj).getSession(); pSession.commit(); } // Ensures that the instance is safe to be returned by the pool. Returns false if obj should be destroyed public boolean validateObject(Object obj) { log.info("destroyObject() "); return true; } // invoked on every instance when it is being 'dropped' from the pool public void destroyObject(Object obj) throws Exception{ log.info("destroyObject() "); } } class BAMProducerWrapper { Session sessionObj; MessageProducer producerObj; BAMProducerWrapper(Session sessionObj, Destination dQueue) throws JMSException { this.sessionObj = sessionObj; this.producerObj = sessionObj.createProducer(dQueue); this.producerObj.setDeliveryMode(DeliveryMode.PERSISTENT); } public Session getSession() { return sessionObj; } public MessageProducer getProducer() { return producerObj; } public void destroy() throws JMSException { producerObj.close(); sessionObj.close(); } }