1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package org.apache.jmeter.protocol.jms.client; 20 21 import javax.naming.Context; 22 import javax.naming.NamingException; 23 24 import javax.jms.JMSException; 25 import javax.jms.QueueConnection; 26 import javax.jms.QueueConnectionFactory; 27 import javax.jms.TopicConnectionFactory; 28 import javax.jms.TopicConnection; 29 30 import org.apache.jmeter.testelement.TestListener; 31 import org.apache.jmeter.engine.event.LoopIterationEvent; 32 33 import org.apache.jorphan.logging.LoggingManager; 34 import org.apache.log.Logger; 35 36 /** 37 * 38 * ConnectionFactory is responsible for creating new connections. Eventually, 39 * the connection factory should read an external configuration file and create 40 * a pool of connections. The current implementation just does the basics. Once 41 * the tires get kicked a bit, we can add connection pooling support. 42 * 43 * Note: the connection factory will retry to get the connection factory 5 times 44 * before giving up. Thanks to Peter Johnson for catching the bug and providing 45 * the patch. 46 */ 47 public class ConnectionFactory implements TestListener { 48 49 private static final Logger log = LoggingManager.getLoggerForClass(); 50 51 //@GuardedBy("this") 52 private static TopicConnectionFactory factory = null; 53 54 //@GuardedBy("this") 55 private static QueueConnectionFactory qfactory = null; 56 57 /** 58 * Maximum number of times we will attempt to obtain a connection factory. 59 */ 60 private static final int MAX_RETRY = 5; 61 62 /** 63 * Amount of time to pause between connection factory lookup attempts. 64 */ 65 private static final int PAUSE_MILLIS = 100; 66 67 /** 68 * 69 */ 70 protected ConnectionFactory() { 71 super(); 72 } 73 74 public void testStarted(String test) { 75 } 76 77 public void testEnded(String test) { 78 testEnded(); 79 } 80 81 /** 82 * endTest cleans up the client 83 * 84 * @see junit.framework.TestListener#endTest(junit.framework.Test) 85 */ 86 public synchronized void testEnded() { 87 ConnectionFactory.factory = null;//N.B. static reference 88 } 89 90 /** 91 * startTest sets up the client and gets it ready for the test. Since async 92 * messaging is different than request/ response applications, the 93 * connection is created at the beginning of the test and closed at the end 94 * of the test. 95 */ 96 public void testStarted() { 97 } 98 99 public void testIterationStart(LoopIterationEvent event) { 100 } 101 102 public static synchronized TopicConnectionFactory getTopicConnectionFactory(Context ctx, String fac) { 103 int counter = MAX_RETRY; 104 while (factory == null && counter > 0) { 105 try { 106 Object objfac = ctx.lookup(fac); 107 if (objfac instanceof TopicConnectionFactory) { 108 factory = (TopicConnectionFactory) objfac; 109 } 110 } catch (NamingException e) { 111 if (counter == MAX_RETRY) { 112 log.error("Unable to find connection factory " + fac + ", will retry. Error: " + e.toString()); 113 } else if (counter == 1) { 114 log.error("Unable to find connection factory " + fac + ", giving up. Error: " + e.toString()); 115 } 116 counter--; 117 try { 118 Thread.currentThread().sleep(PAUSE_MILLIS); 119 } catch (InterruptedException ie) { 120 // do nothing, getting interrupted is acceptable 121 } 122 } 123 } 124 return factory; 125 } 126 127 public static synchronized QueueConnectionFactory getQueueConnectionFactory(Context ctx, String fac) { 128 int counter = MAX_RETRY; 129 while (qfactory == null && counter > 0) { 130 try { 131 Object objfac = ctx.lookup(fac); 132 if (objfac instanceof QueueConnectionFactory) { 133 qfactory = (QueueConnectionFactory) objfac; 134 } 135 } catch (NamingException e) { 136 if (counter == MAX_RETRY) { 137 log.error("Unable to find connection factory " + fac + ", will retry. Error: " + e.toString()); 138 } else if (counter == 1) { 139 log.error("Unable to find connection factory " + fac + ", giving up. Error: " + e.toString()); 140 } 141 counter--; 142 try { 143 Thread.currentThread().sleep(PAUSE_MILLIS); 144 } catch (InterruptedException ie) { 145 // do nothing, getting interrupted is acceptable 146 } 147 } 148 } 149 return qfactory; 150 } 151 152 public static synchronized TopicConnection getTopicConnection() { 153 if (factory != null) { 154 try { 155 return factory.createTopicConnection(); 156 } catch (JMSException e) { 157 log.error(e.getMessage()); 158 } 159 } 160 return null; 161 } 162 163 public static synchronized QueueConnection getQueueConnection(Context ctx, String queueConn) { 164 if (factory != null) { 165 try { 166 return qfactory.createQueueConnection(); 167 } catch (JMSException e) { 168 log.error(e.getMessage()); 169 } 170 } 171 return null; 172 } 173 }