001: /*
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 1999 Bull S.A.
004: * Contact: jonas-team@objectweb.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * --------------------------------------------------------------------------
022: * $Id: JmsAdminForJoram.java 8704 2006-06-29 14:56:17Z pelletib $
023: * --------------------------------------------------------------------------
024: */
025:
026: package org.objectweb.jonas_jms;
027:
028: import java.util.StringTokenizer;
029: import java.util.Vector;
030:
031: import javax.jms.ConnectionFactory;
032: import javax.jms.Queue;
033: import javax.jms.QueueConnectionFactory;
034: import javax.jms.Topic;
035: import javax.jms.TopicConnectionFactory;
036: import javax.jms.XAConnectionFactory;
037: import javax.jms.XAQueueConnectionFactory;
038: import javax.jms.XATopicConnectionFactory;
039: import javax.naming.InitialContext;
040: import javax.naming.NamingException;
041:
042: import org.objectweb.common.Env;
043: import org.objectweb.jonas_jms.api.JmsAdministration;
044: import org.objectweb.joram.client.jms.admin.AdminModule;
045: import org.objectweb.joram.client.jms.admin.User;
046: import org.objectweb.joram.client.jms.local.XALocalConnectionFactory;
047: import org.objectweb.joram.client.jms.local.XAQueueLocalConnectionFactory;
048: import org.objectweb.joram.client.jms.local.XATopicLocalConnectionFactory;
049: import org.objectweb.joram.client.jms.tcp.QueueTcpConnectionFactory;
050: import org.objectweb.joram.client.jms.tcp.TcpConnectionFactory;
051: import org.objectweb.joram.client.jms.tcp.TopicTcpConnectionFactory;
052: import org.objectweb.joram.client.jms.tcp.XAQueueTcpConnectionFactory;
053: import org.objectweb.joram.client.jms.tcp.XATcpConnectionFactory;
054: import org.objectweb.joram.client.jms.tcp.XATopicTcpConnectionFactory;
055: import org.objectweb.util.monolog.api.BasicLevel;
056:
057: import fr.dyade.aaa.agent.AgentServer;
058:
059: /**
060: * Joram administration. This JORAM specific class allows to administer a JORAM server
061: * when JORAM has been declared as a service.
062: *
063: * @author Philippe Coq
064: * Contributor(s):
065: * Philippe Durieux<p>
066: * Jeff Mesnil: for JORAM 3.x integration<p>
067: * Frederic Maistre for JORAM 4.x integration<p>
068: * 03/05/25 Adriana Danes : JMS resource monitoring
069: *
070: */
071: public class JmsAdminForJoram implements JmsAdministration {
072:
073: private static String QUEUE_CONN_FACT_NAME = "JQCF";
074: private static String TOPIC_CONN_FACT_NAME = "JTCF";
075: private static String CONN_FACT_NAME = "JCF";
076: private boolean collocatedmom = false;
077: private InitialContext ictx = null;
078: private Vector namelist = new Vector();
079: private XAConnectionFactory xacf = null;
080: private XATopicConnectionFactory xatcf = null;
081: private XAQueueConnectionFactory xaqcf = null;
082: private ConnectionFactory jcf = null;
083: private TopicConnectionFactory jtcf = null;
084: private QueueConnectionFactory jqcf = null;
085: private org.objectweb.joram.client.jms.admin.User user = null;
086: private org.objectweb.joram.client.jms.admin.User jonasUser = null;
087: private String host = null;
088: private int port;
089:
090: /**
091: * default constructor.
092: * This class will be created with newInstance().
093: */
094: public JmsAdminForJoram() {
095: }
096:
097: // ------------------------------------------------------------
098: // private methods
099: // ------------------------------------------------------------
100:
101: /**
102: * start the MOM in the same JVM than the current
103: *
104: * Start the A3 AgentServer with the default configuration
105: * in transient mode and with the a3servers.xml file located into $JONAS_BASE/conf
106: * what it is made here is equivalent to
107: * java -Djonas.base=$JONAS_BASE -DTransaction=fr.dyade.aaa.util.NullTransaction
108: * -Dfr.dyade.aaa.agent.A3CONF_DIR=$JONAS_ROOT/config
109: * fr.dyade.aaa.agent.AgentServer 0 ./s0&
110: */
111: private void startMOM() throws Exception {
112: TraceJms.logger.log(BasicLevel.DEBUG, "");
113:
114: try {
115: // -DTransaction=fr.dyade.aaa.util.NullTransaction
116: String TRANSACTION_PROP = "Transaction";
117: String s1 = System.getProperty(TRANSACTION_PROP);
118: if (s1 == null) {
119: System.setProperty(TRANSACTION_PROP,
120: "fr.dyade.aaa.util.NullTransaction");
121: }
122:
123: // -Dfr.dyade.aaa.agent.A3CONF_DIR=$JONAS_BASE/conf
124: String A3CONF_DIR_PROP = "fr.dyade.aaa.agent.A3CONF_DIR";
125: String a3config_dir = System.getProperty(A3CONF_DIR_PROP);
126: if (a3config_dir == null) {
127: System
128: .setProperty(A3CONF_DIR_PROP, System
129: .getProperty("jonas.base")
130: + System.getProperty("file.separator")
131: + "conf");
132: }
133:
134: if (TraceJms.isDebug())
135: TraceJms.logger.log(BasicLevel.DEBUG, "a3config_dir= "
136: + a3config_dir);
137: // java fr.dyade.aaa.agent.AgentServer 0 s0
138: // 0 identifies wich server to run among those described in config file.
139: // s0 is a directory used for persistence.
140: short serverId = 0;
141: AgentServer.init(serverId, "s0", TraceJms
142: .getLoggerFactory());
143: AgentServer.start();
144:
145: // wait 10 millisec for the MOM to start ???
146: Thread.sleep(10);
147:
148: // Get host and port that must be used to start Admin
149: // mainly to get the port number set in a3servers.xml
150: short sid = AgentServer.getServerId(); // should be 0
151: host = AgentServer.getHostname(sid); // should be localhost
152: port = 16010;
153: try {
154: String s = AgentServer
155: .getServiceArgs(sid,
156: "org.objectweb.joram.mom.proxies.tcp.TcpProxyService");
157: StringTokenizer st = new StringTokenizer(s);
158: port = Integer.parseInt(st.nextToken());
159: } catch (NumberFormatException exc) {
160: TraceJms.logger.log(BasicLevel.ERROR, "exception: "
161: + exc);
162: } catch (Exception e) {
163: TraceJms.logger.log(BasicLevel.ERROR, "MOM exception:"
164: + e);
165: throw e;
166: }
167: TraceJms.logger.log(BasicLevel.INFO,
168: "starting MOM on host " + host + ", port " + port);
169:
170: } catch (Exception ex) {
171: TraceJms.logger.log(BasicLevel.ERROR, "exception: " + ex);
172: throw ex;
173: }
174: }
175:
176: // ------------------------------------------------------------
177: // JmsAdministration implementation
178: // ------------------------------------------------------------
179:
180: /**
181: * Jms Administrator is created with newInstance().
182: * initialization is done later with this method.
183: * The MOM will be started if collocated.
184: * This method should create an XATopicConnectionFactory and
185: * an XAQueueConnectionFactory
186: * @param boolean true for if the MOM in run in the current JVM
187: * @param String url connexion that must be used if not collocated
188: */
189: public void start(boolean collocated, String url) throws Exception {
190:
191: // Start the MOM in this JVM if collocated.
192: if (collocated) {
193: collocatedmom = true;
194: startMOM();
195: }
196:
197: // Create an InitialContext
198: ictx = new InitialContext();
199:
200: // Start jms admin
201: if (host != null) {
202: // collocated: use url got from the MOM
203: TraceJms.logger.log(BasicLevel.INFO,
204: "starting JmsAdmin with host " + host + ", port "
205: + port);
206: AdminModule.collocatedConnect("root", "root");
207: } else if (url != null && url.length() > 0) {
208: // not collocated: use url from jonas.properties
209: int indexOfHost = url.indexOf("//") + 2;
210: int indexOfPort = url.indexOf(":", indexOfHost) + 1;
211: host = url.substring(indexOfHost, indexOfPort - 1);
212: port = Integer.parseInt(url.substring(indexOfPort));
213: TraceJms.logger.log(BasicLevel.WARN,
214: "starting JmsAdmin with host " + host + ", port "
215: + port);
216: AdminModule.connect(host, port, "root", "root", 100);
217: } else {
218: // use default url
219: TraceJms.logger.log(BasicLevel.WARN,
220: "starting JmsAdmin with default url");
221: AdminModule.connect("root", "root", 100);
222: }
223:
224: user = User.create("anonymous", "anonymous");
225: jonasUser = User.create("jonas", "jonas");
226:
227: // Create connection factories that will be used by the EJB components.
228: // An anticipation window is enabled for improving the performance
229: if (collocated) {
230: xacf = XALocalConnectionFactory.create();
231: ((org.objectweb.joram.client.jms.XAConnectionFactory) xacf)
232: .getParameters().queueMessageReadMax = 2;
233: xatcf = XATopicLocalConnectionFactory.create();
234: ((org.objectweb.joram.client.jms.XATopicConnectionFactory) xatcf)
235: .getParameters().queueMessageReadMax = 2;
236: xaqcf = XAQueueLocalConnectionFactory.create();
237: ((org.objectweb.joram.client.jms.XAQueueConnectionFactory) xaqcf)
238: .getParameters().queueMessageReadMax = 2;
239: } else {
240: xacf = XATcpConnectionFactory.create(host, port);
241: ((org.objectweb.joram.client.jms.XAConnectionFactory) xacf)
242: .getParameters().queueMessageReadMax = 2;
243: xatcf = XATopicTcpConnectionFactory.create(host, port);
244: ((org.objectweb.joram.client.jms.XATopicConnectionFactory) xatcf)
245: .getParameters().queueMessageReadMax = 2;
246: xaqcf = XAQueueTcpConnectionFactory.create(host, port);
247: ((org.objectweb.joram.client.jms.XAQueueConnectionFactory) xaqcf)
248: .getParameters().queueMessageReadMax = 2;
249: }
250:
251: // Create connection factories that will be used by a pure JMS Client
252: String name = CONN_FACT_NAME;
253: try {
254: jcf = TcpConnectionFactory.create(host, port);
255: ictx.rebind(name, jcf);
256: namelist.addElement(name);
257: } catch (NamingException e) {
258: TraceJms.logger.log(BasicLevel.ERROR, "cannot register "
259: + name);
260: }
261:
262: name = QUEUE_CONN_FACT_NAME;
263: try {
264: jqcf = QueueTcpConnectionFactory.create(host, port);
265: ictx.rebind(name, jqcf);
266: namelist.addElement(name);
267: } catch (NamingException e) {
268: TraceJms.logger.log(BasicLevel.ERROR, "cannot register "
269: + name);
270: }
271:
272: name = TOPIC_CONN_FACT_NAME;
273: try {
274: jtcf = TopicTcpConnectionFactory.create(host, port);
275: ictx.rebind(name, jtcf);
276: namelist.addElement(name);
277: } catch (NamingException e) {
278: TraceJms.logger.log(BasicLevel.ERROR, "cannot register "
279: + name);
280: }
281: }
282:
283: /**
284: * Stop the Jms Administrator
285: */
286: public void stop() {
287: if (Env.isJAVA4()) {
288: // workaround against bug in SUN JVM JDK1.3 on Linux
289: try {
290: AdminModule.disconnect();
291: } catch (Exception ex) {
292: TraceJms.logger.log(BasicLevel.ERROR,
293: "problem for closing admin object " + ex);
294: }
295: if (collocatedmom) {
296: AgentServer.stop();
297: if (TraceJms.isDebug())
298: TraceJms.logger.log(BasicLevel.DEBUG,
299: "agentServer stopped");
300: }
301: }
302: // clean up JNDI
303: try {
304: ictx.unbind(CONN_FACT_NAME);
305: ictx.unbind(QUEUE_CONN_FACT_NAME);
306: ictx.unbind(TOPIC_CONN_FACT_NAME);
307: if (TraceJms.isDebug())
308: TraceJms.logger.log(BasicLevel.DEBUG,
309: "unbind connection factories");
310: } catch (Exception ex) {
311: TraceJms.logger.log(BasicLevel.ERROR,
312: "cannot unbind connection factories");
313: }
314: }
315:
316: /**
317: * Get the XAConnectionFactory
318: */
319: public XAConnectionFactory getXAConnectionFactory() {
320: return xacf;
321: }
322:
323: /**
324: * Get the XATopicConnectionFactory
325: */
326: public XATopicConnectionFactory getXATopicConnectionFactory() {
327: return xatcf;
328: }
329:
330: /**
331: * Get the XAQueueConnectionFactory
332: */
333: public XAQueueConnectionFactory getXAQueueConnectionFactory() {
334: return xaqcf;
335: }
336:
337: /**
338: * Create a Queue and bind it to the registry
339: */
340: public Queue createQueue(String name) throws Exception {
341: TraceJms.logger.log(BasicLevel.DEBUG, "");
342: org.objectweb.joram.client.jms.Queue queue = null;
343: try {
344: queue = (org.objectweb.joram.client.jms.Queue) ictx
345: .lookup(name);
346: } catch (Exception e) {
347: queue = org.objectweb.joram.client.jms.Queue.create(name);
348: ictx.rebind(name, queue);
349: }
350: queue.setWriter(user);
351: queue.setReader(user);
352: queue.setWriter(jonasUser);
353: queue.setReader(jonasUser);
354: return queue;
355: }
356:
357: /**
358: * Create a Topic and bind it to the registry
359: */
360: public Topic createTopic(String name) throws Exception {
361: TraceJms.logger.log(BasicLevel.DEBUG, "");
362: org.objectweb.joram.client.jms.Topic topic = null;
363: try {
364: topic = (org.objectweb.joram.client.jms.Topic) ictx
365: .lookup(name);
366: } catch (Exception e) {
367: topic = org.objectweb.joram.client.jms.Topic.create(name);
368: ictx.rebind(name, topic);
369: }
370: topic.setWriter(user);
371: topic.setReader(user);
372: topic.setWriter(jonasUser);
373: topic.setReader(jonasUser);
374: return topic;
375: }
376:
377: /**
378: * Delete a destination.
379: */
380: public void deleteDestination(String name) throws Exception {
381: TraceJms.logger.log(BasicLevel.DEBUG, "");
382: try {
383: org.objectweb.joram.client.jms.Destination dest = (org.objectweb.joram.client.jms.Destination) ictx
384: .lookup(name);
385: dest.delete();
386: } catch (Exception e) {
387: }
388: }
389:
390: /**
391: * Get number of pending messages on a queue
392: * @param queue the monitored queue
393: * @exception Exception if could not get info (queue not valid or connection failed or monitoring request failed)
394: */
395: public int getPendingMessages(javax.jms.Queue queue)
396: throws Exception {
397: return ((org.objectweb.joram.client.jms.Queue) queue)
398: .getPendingMessages();
399: }
400:
401: /**
402: * Get number of pending requests on a queue
403: * @param queue the monitored queue
404: * @exception Exception if could not get info (queue not valid or connection failed or monitoring request failed)
405: */
406: public int getPendingRequests(javax.jms.Queue queue)
407: throws Exception {
408: return ((org.objectweb.joram.client.jms.Queue) queue)
409: .getPendingRequests();
410: }
411:
412: /**
413: * Get number of subscriptions on a topic
414: * @param topic the monitored topic
415: * @exception Exception if could not get info (topic not valid or connection failed or monitoring request failed)
416: */
417: public int getSubscriptions(javax.jms.Topic topic) throws Exception {
418: return ((org.objectweb.joram.client.jms.Topic) topic)
419: .getSubscriptions();
420: }
421: }
|