KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > jms > JmsProviderLifecycle


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 /**
25  * PROPRIETARY/CONFIDENTIAL. Use of this product is subject to license terms.
26  *
27  * Copyright 2000-2001 by iPlanet/Sun Microsystems, Inc.,
28  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
29  * All rights reserved.
30  */

31
32 package com.sun.enterprise.jms;
33
34 import java.util.*;
35
36 import com.sun.appserv.server.ServerLifecycleException;
37 import com.sun.appserv.server.ServerLifecycle;
38 import com.sun.appserv.server.ServerLifecycleImpl;
39
40 import com.sun.enterprise.server.ServerContext;
41 import com.sun.enterprise.server.Constants;
42
43 import com.sun.enterprise.config.*;
44 import com.sun.enterprise.config.serverbeans.*;
45 import com.sun.enterprise.Switch;
46 import com.sun.enterprise.connectors.ConnectorConstants;
47 import com.sun.enterprise.connectors.ConnectorRuntime;
48 import com.sun.enterprise.connectors.ConnectorRuntimeException;
49 import com.sun.messaging.jmq.jmsspi.JMSAdmin;
50 import java.util.logging.*;
51 import com.sun.logging.LogDomains;
52
53 import com.sun.enterprise.instance.ServerManager;
54 import com.sun.enterprise.util.SystemPropertyConstants;
55 /**
56  * This class provides service for starting (currently only ping) the
57  * configured JMS provider at J2EE server intialization and stopping
58  * the configured JMS provider at J2EE server termination
59  *
60  */

61 public class JmsProviderLifecycle extends ServerLifecycleImpl {
62     private ConfigContext ctx = null;
63     private static JmsService jmsService_ =null;
64     //ROB: config changes
65
private JmsHost jmsHost_ =null;
66
67     private static JMSAdmin jmsAdmin_ = null;
68     private boolean onShutdown = false;
69
70     private static boolean startedByMe_ = false;
71
72     private boolean autoShutdown_ = true;
73
74     private static Logger _logger =
75         LogDomains.getLogger(LogDomains.JMS_LOGGER);
76     private static boolean debug = true;
77
78     private static final int NOTCHECKED = 1;
79     private static final int SUCCESSFUL = 2;
80     private static final int FAILED = 3;
81     private static final int REMOTESTARTUP = 4;
82     private static int startupStatus = NOTCHECKED;
83
84     private static String JavaDoc instanceName = null;
85     private static String JavaDoc iMQBin = null;
86
87     private static String JavaDoc exception = null;
88
89     private static String JavaDoc url = null;
90     
91     //Flag to set AS9 to use MQSPI. This flag could be used by users
92
//to revert to AS8.x behavior of using the MQ SPI for AS/MQ lifecycle
93
//integration. Setting a system variable to this value
94
//and to true, reverts to AS8.x behavior
95
private static final String JavaDoc AS_INTEGRATION_VIA_MQ_SPI
96                     = "com.sun.enterprise.jms.ASMQSPIIntegration";
97     
98     private static boolean useMQRAForBrokerLifecycle = true;
99     
100     //determine if MQ SPI needs to be used.
101
static {
102         try {
103             String JavaDoc s = System.getProperty(AS_INTEGRATION_VIA_MQ_SPI);
104             if (s != null) {
105                 useMQRAForBrokerLifecycle = !((new Boolean JavaDoc(s)).booleanValue());
106             }
107             String JavaDoc status = (useMQRAForBrokerLifecycle ? "Using MQ RA for Broker lifecycle control" :
108                 "Using MQ SPI for Broker Lifecycle control");
109             _logger.log(Level.INFO, status);
110         } catch (Exception JavaDoc ex) {
111             _logger.log(Level.WARNING, "Exception while reading "
112                     + AS_INTEGRATION_VIA_MQ_SPI + "property" + ex.getMessage());
113             _logger.log(Level.INFO, "Using MQ RA for Broker Lifecycle control");
114             _logger.log(Level.FINE, ex.getMessage());
115         }
116     }
117             
118
119     /**
120      * THIS METHOD MUST BE CALLED BEFORE any of the IASJmsUtil, IASJmsConfig
121      * method get called.
122      *
123      * Server is initializing subsystems and setting up the runtime
124      * environment.
125      *
126      * Prepare for the beginning of active use of the public methods
127      * of this subsystem. This method is called before any of the
128      * public methods of this subsystem are utilized.
129      *
130      * @param sc ServerContext the server runtime context.
131      *
132      * @exception IllegalStateException if this subsystem has already
133      * been started
134      * @exception ServerLifecycleException if this subsystem detects a
135      * fatal error that prevents this subsystem from being used
136      */

137     public void onInitialization(ServerContext sc)
138         throws ServerLifecycleException {
139         if (!shouldUseMQRAForLifecycleControl()) {
140
141             if (jmsService_ != null) {
142                 // Dont allow duplicate initializations.
143
return;
144             }
145
146             try {
147                 jmsAdmin_ = null;
148                 ctx = sc.getConfigContext();
149
150                 //ROB: config changes
151
//JavaConfig jc = ServerBeansFactory.getServerBean(
152
// ctx).getJavaConfig();
153
JavaConfig jc = ServerBeansFactory.getJavaConfigBean(ctx);
154
155                 String JavaDoc java_home = jc.getJavaHome();
156
157                 //ROB: config changes
158
//jmsService_ = ServerBeansFactory.getServerBean(ctx).getJmsService();
159
jmsService_ = ServerBeansFactory.getJmsServiceBean(ctx);
160                 String JavaDoc defaultJmsHost = jmsService_.getDefaultJmsHost();
161
162                 if (defaultJmsHost==null || defaultJmsHost.equals("")) {
163                     jmsHost_ = ServerBeansFactory.getJmsHostBean(ctx);
164                 } else {
165                     jmsHost_ = jmsService_.getJmsHostByName(defaultJmsHost);
166                 }
167
168     //ROB: config changes
169
/*
170                 if (jmsService_ != null && jmsService_.isEnabled()) {
171                     String portStr = jmsService_.getPort();
172                     String username = jmsService_.getAdminUserName();
173                     String password = jmsService_.getAdminPassword();
174     */

175                 String JavaDoc type = jmsService_.getType();
176                 if (!(type.equals("LOCAL"))) {
177                     startupStatus = REMOTESTARTUP;
178                     _logger.log(Level.INFO, "jms.broker_notlocal", type);
179                     return;
180                 }
181
182                 if (jmsHost_ != null && jmsHost_.isEnabled()) {
183                     String JavaDoc portStr = jmsHost_.getPort();
184                     String JavaDoc username = jmsHost_.getAdminUserName();
185                     String JavaDoc password = jmsHost_.getAdminPassword();
186
187                     Vector v = new Vector();
188                     if (java_home != null) {
189                         v.add("-javahome");
190                         v.add(java_home);
191                     }
192
193                     String JavaDoc mqInstanceDir =
194                            sc.getInstanceEnvironment().getInstancesRoot() +
195                            java.io.File.separator + IASJmsUtil.MQ_DIR_NAME;
196
197                     // If the directory doesnt exist, create it.
198
// It is necessary for windows.
199
java.io.File JavaDoc instanceDir = new java.io.File JavaDoc(mqInstanceDir);
200                     if (!(instanceDir.exists() && instanceDir.isDirectory())) {
201                         instanceDir.mkdirs();
202                     }
203
204                     v.add("-varhome");
205                     v.add(mqInstanceDir);
206
207
208                     String JavaDoc tmpstr = jmsService_.getStartArgs();
209                     if (tmpstr != null) {
210                         StringTokenizer st = new StringTokenizer(tmpstr, " ");
211                         while (st.hasMoreTokens()) {
212                             String JavaDoc t = st.nextToken();
213                             v.add(t);
214                         }
215                     }
216
217                     String JavaDoc[] startArgs = (String JavaDoc []) v.toArray(new String JavaDoc[0]);
218
219                     // Extract the information from the optional properties.
220
// Valid property names : "auto-shutdown"
221
ElementProperty[] jmsProperties =
222                         jmsService_.getElementProperty();
223
224                     if (jmsProperties != null) {
225                         for (int ii=0; ii < jmsProperties.length; ii++) {
226                             ElementProperty p = jmsProperties[ii];
227                             String JavaDoc name = p.getName();
228
229                             if (name.equals("auto-shutdown"))
230                                 autoShutdown_ =
231                                     Boolean.valueOf(p.getValue()).booleanValue();
232                         }
233                     }
234
235                     // If the property was not specified, then look for the
236
// imqRoot as defined by the com.sun.aas.imqRoot property
237
iMQBin = java.lang.System.getProperty(SystemPropertyConstants.IMQ_BIN_PROPERTY);
238
239                     // Finally if all else fails (though this should never happen)
240
// look for IMQ relative to the installation directory
241
if (iMQBin == null) {
242                         String JavaDoc IMQ_INSTALL_SUBDIR = java.io.File.separator +
243                             ".." + java.io.File.separator + ".." +
244                             java.io.File.separator + "imq" +
245                             java.io.File.separator + "bin";
246                         iMQBin = sc.getInstallRoot() + IMQ_INSTALL_SUBDIR;
247                     }
248
249                     //
250
// Calculate the imq broker executable path.
251
//
252
String JavaDoc asInstance = sc.getInstanceName();
253                     String JavaDoc domainName = ServerManager.instance().getDomainName();
254                     instanceName = IASJmsUtil.getBrokerInstanceName(
255                         domainName, asInstance, jmsService_);
256
257                     String JavaDoc localhost = "127.0.0.1";
258                     url = localhost + ((portStr == null) ?
259                         "" : ":" + portStr);
260                     if (username == null) {
261                         jmsAdmin_ =
262                             IASJmsUtil.getJMSAdminFactory().getJMSAdmin(url);
263                     }
264                     else {
265                         jmsAdmin_ =
266                             IASJmsUtil.getJMSAdminFactory().getJMSAdmin(url,
267                                 username, password);
268                     }
269
270                     // First ping the provider to see if it is already
271
// running.
272
boolean running;
273                     try {
274                         jmsAdmin_.pingProvider();
275                         running = true;
276                     }
277                     catch (Exception JavaDoc e) {
278                         running = false;
279                     }
280
281                     if (running) {
282                         _logger.fine(
283                             "Broker is already running. Trying to attach.");
284                         String JavaDoc s = null;
285                         try {
286                             s = attachToJmsProvider();
287                         }
288                         catch (Exception JavaDoc e) {
289                             _logger.log(Level.INFO, "jms.broker_attach_failed");
290                             _logger.log(Level.INFO,
291                                 "jms.broker_log_location", instanceName);
292                             throw new ServerLifecycleException(e.getMessage(), e);
293                         }
294                         if (s.equals(instanceName)) {
295                             // An iMQ broker instance with the same name
296
// is already running. Since the instance
297
// names match, it is probably a broker
298
// process left behind by the application
299
// server. Treat it as if it was started by
300
// this application server process...
301
startedByMe_ = true;
302                             _logger.log(Level.INFO, "jms.broker_found",
303                                 instanceName);
304                         }
305                         else {
306                             startedByMe_ = false;
307                             Object JavaDoc[] params = {s, portStr};
308                             _logger.log(Level.SEVERE, "jms.broker_already_up",
309                                 params);
310                             throw new ServerLifecycleException(
311                                 "JmsProviderLifecycle error.");
312                         }
313                     }
314                     else {
315                         _logger.fine("Starting JMS broker : imq-home=" + iMQBin +
316                             ", stargArgs=" + tmpstr +
317                             ", instanceName=" + instanceName);
318
319                         try {
320                             jmsAdmin_.startProvider(iMQBin,
321                                 startArgs, instanceName);
322                         }
323                         catch (Exception JavaDoc e) {
324                             _logger.log(Level.INFO, "jms.broker_exec_failed");
325                             _logger.log(Level.INFO,
326                                 "jms.broker_log_location", instanceName);
327                             throw new ServerLifecycleException(e.getMessage(), e);
328                         }
329
330
331                     }
332                 }
333             }
334             catch (Exception JavaDoc e) {
335                 jmsService_ = null;
336                 _logger.log(Level.SEVERE, "jms.broker_startup_failed");
337
338                 // The exception will be logged at the outer level...
339

340                 throw new ServerLifecycleException(e.getMessage(), e);
341             }
342         }
343     }
344
345     private String JavaDoc attachToJmsProvider() throws Exception JavaDoc {
346         jmsAdmin_.connectToProvider();
347         String JavaDoc name = jmsAdmin_.getProviderInstanceName();
348         jmsAdmin_.disconnectFromProvider();
349         return name;
350     }
351
352     private static void waitForJmsProvider
353                      (long initTimeout) throws Exception JavaDoc {
354
355         boolean ready = false;
356
357         // It is debatable where to put startTime. If we set the
358
// time right after startProvider as startTime, we may land into
359
// some issues. In a single CPU system, the startTime
360
// may not reflect the correct meaning. If we consider startTime
361
// as cpuTime, here it is assumed that there is no time spend
362
// for JMS startup until now. Actually CPU should have spend time.
363
long startTime = java.lang.System.currentTimeMillis();
364
365         while (true) {
366             try {
367                 jmsAdmin_.pingProvider();
368                 ready = true;
369                 break;
370             }
371             catch (Exception JavaDoc e) {}
372
373             if (java.lang.System.currentTimeMillis() - startTime >=
374                 initTimeout) {
375                 break;
376             }
377
378             try {
379                 Thread.sleep(2000);
380             }
381             catch (Exception JavaDoc e) {}
382         }
383
384         // If provider is not ready, call pingProvider again
385
// to generate the exception...
386
if (!ready)
387             jmsAdmin_.pingProvider();
388
389     }
390
391     //AS7.0 has one server instance per JVM
392
public static JMSAdmin getJMSAdmin() {
393         return jmsAdmin_;
394     }
395
396     public boolean isNOJMS() {
397         return false;
398     }
399
400     /**
401      * Server is starting up applications
402      *
403      * @param sc ServerContext the server runtime context.
404      *
405      * @exception ServerLifecycleException if this subsystem detects a fatal
406      * error that prevents this subsystem from being used
407      */

408     public void onStartup(ServerContext sc)
409         throws ServerLifecycleException {
410         //Start ActiveJMSRA
411
try {
412             String JavaDoc module = ConnectorConstants.DEFAULT_JMS_ADAPTER;
413             String JavaDoc loc = Switch.getSwitch().getResourceInstaller().
414                          getSystemModuleLocation(module);
415             ConnectorRuntime.getRuntime().createActiveResourceAdapter(
416                          loc, module,false);
417         } catch (ConnectorRuntimeException e) {
418             e.printStackTrace();
419             _logger.log(Level.INFO, "Failed to start JMS RA");
420             throw new ServerLifecycleException("Failed to start JMS RA", e);
421         }
422        
423     }
424
425     /**
426      * Check Jms Provider and make sure that it is started.
427      * When resource adapter starts up, it will also doublecheck
428      * using this static method.
429      */

430     public static void checkProviderStartup()
431         throws ServerLifecycleException {
432         if (shouldUseMQRAForLifecycleControl()) {
433             return;
434         }
435
436     switch (startupStatus) {
437         case NOTCHECKED : break;
438         case SUCCESSFUL : return;
439         case FAILED :
440              throw new ServerLifecycleException
441          ("MQ startup failed :" + exception);
442         case REMOTESTARTUP : return;
443     }
444
445     String JavaDoc iMQInstance = System.getProperty(Constants.INSTALL_ROOT) +
446                           java.io.File.separator + "imq" +
447                           java.io.File.separator + "var" +
448                           java.io.File.separator + "instances";
449
450         String JavaDoc initTimeoutStr = null;
451         long initTimeout = 30 * 1000;
452
453         initTimeoutStr = jmsService_.getInitTimeoutInSeconds();
454
455         if (initTimeoutStr != null)
456             initTimeout = Integer.parseInt(initTimeoutStr) * 1000;
457
458         Exception JavaDoc excp = null;
459         try {
460              waitForJmsProvider(initTimeout);
461          startupStatus = SUCCESSFUL;
462         }
463         catch (javax.jms.JMSSecurityException JavaDoc e) {
464         excp = e;
465
466         // Provider is up and we have a wrong username and password
467
// configured. We should shut this down. Recreate the admin
468
// with defult user and password.
469
startedByMe_ = true;
470         try {
471                 jmsAdmin_ =
472                     IASJmsUtil.getJMSAdminFactory().getJMSAdmin(url,
473             IASJmsUtil.DEFAULT_USER,
474             IASJmsUtil.DEFAULT_PASSWORD);
475         } catch (Exception JavaDoc ex) {
476         }
477     }
478         catch (Exception JavaDoc e1) {
479         excp = e1;
480         }
481
482     if (excp != null) {
483              startupStatus = FAILED;
484              _logger.log(Level.INFO, "jms.broker_ping_failed",
485                          Long.toString(initTimeout));
486              _logger.log(Level.INFO,
487                     "jms.broker_instance_dir", iMQInstance);
488              _logger.log(Level.INFO,
489                     "jms.broker_log_location",instanceName);
490          exception = excp.getMessage();
491              throw new ServerLifecycleException(excp.getMessage(), excp);
492     }
493
494         startedByMe_ = true;
495
496         Object JavaDoc[] params = {instanceName, iMQBin};
497             _logger.log(Level.INFO, "jms.broker_started", params);
498
499     }
500
501     /**
502      * Server is shutting down applications
503      *
504      * @exception ServerLifecycleException if this subsystem detects a fatal
505      * error that prevents this subsystem from being used
506      */

507     public void onShutdown()
508         throws ServerLifecycleException {
509         checkProviderStartup();
510         onShutdown = true;
511     }
512
513     /**
514      * Server is terminating the subsystems and the runtime environment.
515      * Gracefully terminate the active use of the public methods of this
516      * subsystem. This method should be the last one called on a given
517      * instance of this subsystem.
518      *
519      * @exception ServerLifecycleException if this subsystem detects a fatal
520      * error that prevents this subsystem from being used
521      */

522     public void onTermination()
523         throws ServerLifecycleException {
524         onShutdown = true;
525         //need not do anything if lifecycke managed by the RA.
526
if (!shouldUseMQRAForLifecycleControl()) {
527
528             try {
529                 if (startupStatus == REMOTESTARTUP ||
530                     autoShutdown_ == false ||
531                     jmsService_ == null ||
532                     jmsService_.isEnabled() == false)
533                     return;
534
535                 if (jmsAdmin_ == null || startedByMe_ == false)
536                     return;
537
538                 _logger.log(Level.INFO, "jms.broker_shutting_down");
539                 jmsAdmin_.connectToProvider();
540             }
541             catch (Exception JavaDoc e) {
542                 throw new ServerLifecycleException(e.getMessage(), e);
543             }
544
545             try {
546                 jmsAdmin_.shutdownProvider();
547                 _logger.log(Level.INFO, "jms.broker_shutdown_complete");
548             }
549             catch (Exception JavaDoc e) {} // Ignore this exception.
550
}
551     }
552     
553     public static boolean shouldUseMQRAForLifecycleControl() {
554         return JmsProviderLifecycle.useMQRAForBrokerLifecycle;
555     }
556
557 }
558
Popular Tags