View Javadoc

1   /****************************************************************************
2    * Copyright (c) 2005, 2006, 2007, 2008, 2009 Imola Informatica.
3    * All rights reserved. This program and the accompanying materials
4    * are made available under the terms of the LGPL License v2.1
5    * which accompanies this distribution, and is available at
6    * http://www.gnu.org/licenses/lgpl.html
7    ****************************************************************************/
8   /*
9    * AbstractComponentLifeCycle.java
10   *
11   */
12  
13  package it.imolinfo.jbi4corba.jbi.component.runtime;
14  
15  import it.imolinfo.jbi4corba.Logger;
16  import it.imolinfo.jbi4corba.LoggerFactory;
17  import it.imolinfo.jbi4corba.jbi.component.Jbi4CorbaPerformanceMeasurement;
18  import it.imolinfo.jbi4corba.jbi.component.ReadWriteTextFile;
19  
20  import java.io.File;
21  
22  import javax.jbi.JBIException;
23  import javax.jbi.component.ComponentContext;
24  import javax.jbi.component.ComponentLifeCycle;
25  import javax.jbi.management.MBeanNames;
26  import javax.management.MBeanServer;
27  import javax.management.ObjectName;
28  import javax.management.StandardMBean;
29  
30  import com.sun.jbi.configuration.RuntimeConfigurationHelper;
31  import com.sun.jbi.eManager.provider.StatusProviderHelper;
32  import com.sun.jbi.internationalization.Messages;
33  
34  /**
35   * This class is an abstract implemenation of the ComponentLifeCycle. It
36   * implements the component lifecycle methods and provides necessary hooks to
37   * the extended classes to supply the component specific implemenation for the
38   * lifecycle functionality.
39   * 
40   * @see javax.jbi.ComponentLifeCycle
41   * 
42   * @author <a href="mailto:mpiraccini@imolinfo.it">Marco Piraccini</a>
43   */
44  public abstract class AbstractComponentLifeCycle implements ComponentLifeCycle {
45  
46  	/** The logger. */
47  	private static final Logger LOG = LoggerFactory
48  			.getLogger(AbstractComponentLifeCycle.class);
49  
50  	private static final Messages MESSAGES = Messages
51  			.getMessages(AbstractComponentLifeCycle.class);
52  
53  	/** reference to the component runtime */
54  	private ComponentRuntime mCompRuntime;
55  	/** Extension Mbean Name */
56  	private ObjectName mExtensionMBeanName;
57  	/** Extension Mbean Implemenation */
58  	private StandardMBean mExtensionMBeanImpl;
59  	/** a message receiver that accepts messages from delivery channel */
60  	private MessageExchangeReceiver mMsgExchReceiver;
61  
62  	protected RuntimeConfiguration mRuntimeConfig;
63  	protected RuntimeConfigurationHelper mRuntimeConfigHelper;
64  
65  	/** A short display Name **/
66  	public static final String SHORT_DISPLAY_NAME = "sun-jbi4corba-bc";
67  
68  	// "Official" Performance Instrumentation Categories
69  	public static final String PERF_CAT_NORMALIZATION = "Normalization"; // NOI18N
70  	public static final String PERF_CAT_DENORMALIZATION = "Denormalization"; // NOI18N
71  	public static final String[] JBI4CORBABC_PERF_CATEGORIES = new String[] {
72  			PERF_CAT_NORMALIZATION, PERF_CAT_DENORMALIZATION };
73  	protected ComponentContext jbiContext = null;
74  	protected StatusProviderHelper mStatusProviderHelper;
75  
76  	/**
77  	 * constructor for the ComponentLifecycle implementation.
78  	 * 
79  	 * @param compRuntime
80  	 */
81  	protected AbstractComponentLifeCycle(ComponentRuntime compRuntime) {
82  		this.mCompRuntime = compRuntime;
83  	}
84  
85  	// /////////////////////////////////////////////////////////////////////////
86  	// ComponentLifeCycle interface implemenation
87  	// /////////////////////////////////////////////////////////////////////////
88  
89  	/**
90  	 * Initialize the component.
91  	 * 
92  	 * @param context
93  	 * @throws javax.jbi.JBIException
94  	 * @see javax.jbi.component.ComponentLifeCycle#init(javax.jbi.component.ComponentContext)
95  	 */
96  	public final void init(ComponentContext context) throws JBIException {
97  
98  		if (context == null) {
99  			String msg = MESSAGES
100 					.getString("CRB000429_Null_Component_Context_received_in_Component_Lifecycle_init");
101 			LOG.error(msg);
102 			throw new JBIException(msg);
103 		}
104 		// register ComponentContext for retrieving component logger
105 		Messages.registerContext(context);
106 		// initialize the content
107 		initContext(context);
108 
109 		// create and register extension mbean
110 		registerExtensionMBean();
111 		// create and register monitoring and management mbean
112 		registerMonitoringMbean();
113 		// create and register RuntimeConfig mbean
114 		registerRuntimeConfigurationMBean();
115 
116 		// initialize the message exchange handler factory
117 		initMessageExchangeHandlerFactory();
118 		// initialize the message receiver
119 		initMessageExchangeReceiver(mRuntimeConfig);
120 
121 		// call the onInit to allow other initialization that is specific to the
122 		// component
123 		onInit();
124 
125 		LOG.info("CRB000401_Component_initialized",
126 				new Object[] { RuntimeHelper.getComponentName() });
127 	}
128 
129 	/**
130 	 * Start the component.
131 	 * 
132 	 * @throws javax.jbi.JBIException
133 	 * @see javax.jbi.component.ComponentLifeCycle#start()
134 	 */
135 	public final void start() throws JBIException {
136 
137 		// open the delivery channel from the component context
138 		openDeliveryChannel();
139 
140 		activateServiceProviders();
141 		activateServiceConsumers();
142 
143 		startMessageExchangeProcessing();
144 		// call onStart to perform component specific tasks on start
145 		onStart();
146 		LOG.info("CRB000402_Component_started", new Object[] { RuntimeHelper
147 				.getComponentName() });
148 	}
149 
150 	/**
151 	 * Stop the component.
152 	 * 
153 	 * @throws javax.jbi.JBIException
154 	 * @see javax.jbi.component.ComponentLifeCycle#stop()
155 	 */
156 	public final void stop() throws JBIException {
157 
158 		stopMessageExchangeProcessing();
159 		// deactivate endpoints
160 		deactivateServiceConsumers();
161 		deactivateServiceProviders();
162 		// close channel. No further messages to be processed.
163 		closeDeliveryChannel();
164 		// call onStop to perform component specific tasks on stop
165 		onStop();
166 		LOG.info("CRB000403_Component_stopped", new Object[] { RuntimeHelper
167 				.getComponentName() });
168 	}
169 
170 	/**
171 	 * Shut down the component.
172 	 * 
173 	 * @throws javax.jbi.JBIException
174 	 * @see javax.jbi.component.ComponentLifeCycle#shutDown()
175 	 */
176 	public final void shutDown() throws JBIException {
177 		// remove the message receiver.
178 		shutdownMessageExchangeReceiver();
179 		// unregister extension mbean and remove it
180 		unregisterExtensionMBean();
181 		// unregister ManagementMbean and remove it
182 		unregisterManagementMbean();
183 		// unregister runtimeConfig mbean and remove it
184 		unregisterRuntimeConfigurationMBean();
185 		// call onShutdown to perform component specific tasks on shutdown
186 		onShutDown();
187 		LOG.info("CRB000404_Component_shut_downd", new Object[] { RuntimeHelper
188 				.getComponentName() });
189 	}
190 
191 	/**
192 	 * this is a default implementation which does not have any extension
193 	 * mbeans. extended classes can return the mbean name for the extension
194 	 * mbeans if the component supports.
195 	 * 
196 	 * 
197 	 * @see javax.jbi.component.ComponentLifeCycle#getExtensionMBeanName()
198 	 * @return
199 	 */
200 	public final ObjectName getExtensionMBeanName() {
201 		return this.mExtensionMBeanName;
202 	}
203 
204 	/**
205 	 * if there is an extension mbean supported by the component, then register
206 	 * it with the mbean server.
207 	 */
208 	private void registerExtensionMBean() throws JBIException {
209 
210 		this.mExtensionMBeanName = this.createExtensionMBeanName();
211 
212 		if (this.mExtensionMBeanName == null) {
213 			RuntimeHelper
214 					.logDebug("No Extension MBean is registerd with MBeanServer for "
215 							+ RuntimeHelper.getComponentName());
216 			return;
217 		}
218 		// create the extension mbean implemenation if the object name is
219 		// created.
220 		this.mExtensionMBeanImpl = this.createExtensionMBean();
221 
222 		if (this.mExtensionMBeanImpl == null) {
223 			this.mExtensionMBeanName = null;
224 			RuntimeHelper
225 					.logDebug("No Extension MBean is registerd with MBeanServer for "
226 							+ RuntimeHelper.getComponentName());
227 			return;
228 		}
229 		// register with mbean only if object name and implementation are non
230 		// null
231 		try {
232 			MBeanServer mbServer = RuntimeHelper.getComponentContext()
233 					.getMBeanServer();
234 			mbServer.registerMBean(this.mExtensionMBeanImpl,
235 					this.mExtensionMBeanName);
236 		} catch (Exception e) {
237 			this.mExtensionMBeanName = null;
238 			this.mExtensionMBeanImpl = null;
239 			String msg = MESSAGES
240 					.getString(
241 							"CRB000405_Cannot_register_Extension_MBean_with_MBeanServer",
242 							new Object[] { RuntimeHelper.getComponentName() });
243 			LOG.error(msg, e);
244 			throw new JBIException(msg, e);
245 		}
246 	}
247 
248 	private void registerMonitoringMbean() throws JBIException {
249 		MBeanNames mbnHndl = null;
250 		/** Runtime Monitoring Mbean **/
251 		try {
252 			jbiContext = RuntimeContext.getInstance().getComponentContext();
253 			mbnHndl = jbiContext.getMBeanNames();
254 			if (mbnHndl != null) {
255 				ObjectName statusMBeanObjName = mbnHndl
256 						.createCustomComponentMBeanName("Statistics");
257 				mStatusProviderHelper = new StatusProviderHelper(
258 						SHORT_DISPLAY_NAME, statusMBeanObjName, jbiContext
259 								.getMBeanServer());
260 				mStatusProviderHelper.registerMBean(
261 						JBI4CORBABC_PERF_CATEGORIES,
262 						new Jbi4CorbaPerformanceMeasurement());
263 			}
264 			LOG.info("CRB000406_Jbi4Corba_Register_mbean",
265 					new Object[] { jbiContext.getComponentName() });
266 		} catch (final Exception ex) {
267 			String msg = MESSAGES.getString(
268 					"CRB000407_Jbi4Corba_Failed_register_mbean",
269 					new Object[] { RuntimeHelper.getComponentName() });
270 			LOG.error(msg, ex);
271 			throw new JBIException(msg, ex);
272 		}
273 	}
274 
275 	/**
276 	 * if there is an extension mbean supported by the component, then register
277 	 * it with the mbean server.
278 	 */
279 	private void registerRuntimeConfigurationMBean() throws JBIException {
280 		try {
281 			ComponentContext context = RuntimeContext.getInstance()
282 					.getComponentContext();
283 			String configData = "";
284 			String configSchema = "";
285 			String configDataFileLoc = context.getInstallRoot()
286 					+ File.separator + "META-INF" + File.separator
287 					+ "componentConfiguration.xml";
288 			File configDataFile = new File(configDataFileLoc);
289 			if (configDataFile.exists()) {
290 				configData = ReadWriteTextFile.getContents(configDataFile);
291 				String configSchemaFileLoc = context.getInstallRoot()
292 						+ File.separator + "META-INF" + File.separator
293 						+ "componentConfiguration.xsd";
294 				File configSchemaFile = new File(configSchemaFileLoc);
295 				if (configSchemaFile.exists()) {
296 					configSchema = ReadWriteTextFile
297 							.getContents(configSchemaFile);
298 				}
299 				mRuntimeConfig = new RuntimeConfiguration(context
300 						.getWorkspaceRoot(), configData, configSchema);
301 			} else {
302 				// if the file doesn't exists we assume we aren't running in
303 				// openesb and so create an empty runtime configuration
304 				mRuntimeConfig = new RuntimeConfiguration(context
305 						.getWorkspaceRoot(), configSchema);
306 				String msg = MESSAGES
307 						.getString("CRB000408_Failed_to_locate_configuration_file");
308 				LOG.warn(msg);
309 
310 			}
311 
312 			mRuntimeConfigHelper = new RuntimeConfigurationHelper(
313 					RuntimeConfigurationHelper.COMPONENT_TYPE_BINDING, context
314 							.getComponentName(), context.getMBeanServer());
315 			mRuntimeConfigHelper.registerMBean(mRuntimeConfig);
316 			RuntimeHelper.logInfo("Registering runtime config mbean for"
317 					+ RuntimeHelper.getComponentName());
318 
319 		} catch (final Exception ex) {
320 			String msg = MESSAGES.getString(
321 					"CRB000409_Failed_to_register_runtime_configuration_mbean",
322 					new Object[] { ex.toString() });
323 			LOG.error(msg, ex);
324 			throw new JBIException(msg, ex);
325 		}
326 	}
327 
328 	/**
329 	 * remove the registered extension mbean from the mbean server.
330 	 */
331 	private void unregisterExtensionMBean() throws JBIException {
332 		if (this.mExtensionMBeanName != null) {
333 			try {
334 				MBeanServer mbServer = RuntimeHelper.getComponentContext()
335 						.getMBeanServer();
336 				mbServer.unregisterMBean(this.mExtensionMBeanName);
337 			} catch (Exception e) {
338 				String msg = MESSAGES
339 						.getString(
340 								"CRB000410_Cannot_unregister_Extension_MBean_with_MBeanServer",
341 								new Object[] { RuntimeHelper.getComponentName() });
342 				LOG.error(msg, e);
343 				throw new JBIException(msg, e);
344 			} finally {
345 				this.mExtensionMBeanName = null;
346 				this.mExtensionMBeanImpl = null;
347 			}
348 		}
349 	}
350 
351 	private void unregisterManagementMbean() throws JBIException {
352 		try {
353 			mStatusProviderHelper.unregisterMBean();
354 		} catch (final Exception ex) {
355 			String msg = MESSAGES.getString(
356 					"CRB000430_Failed_to_unregister_statusProviderMBean",
357 					new Object[] { jbiContext.getComponentName() });
358 			LOG.error(msg, ex);
359 			throw new JBIException(msg, ex);
360 		}
361 	}
362 
363 	/**
364 	 * remove the registered extension mbean from the mbean server.
365 	 */
366 	private void unregisterRuntimeConfigurationMBean() throws JBIException {
367 		try {
368 			if (mRuntimeConfigHelper != null) {
369 				mRuntimeConfigHelper.unregisterMBean();
370 			}
371 		} catch (Exception ex) {
372 			LOG.info("CRB000425_Exception_during_runtimecfg_mbean_deregister",
373 					new Object[] { ex.getLocalizedMessage() });
374 
375 		}
376 	}
377 
378 	/**
379 	 * 
380 	 * @return
381 	 */
382 	public final ComponentRuntime getComponentRuntime() {
383 		return this.mCompRuntime;
384 	}
385 
386 	/**
387 	 * initializes the RuntimeContext using ComponentContext passed by init
388 	 * method.
389 	 * 
390 	 * @param context
391 	 */
392 	private void initContext(ComponentContext context) {
393 		RuntimeContext.getInstance().setComponentContext(context);
394 		RuntimeContext.getInstance().setLogger(
395 				this.getClass().getPackage().getName(), null);
396 	}
397 
398 	/**
399 	 * creates a message receiver object as part of the component
400 	 * initialization.
401 	 * 
402 	 * @throws javax.jbi.JBIException
403 	 */
404 	private void initMessageExchangeReceiver(RuntimeConfiguration mRuntimeConfig)
405 			throws JBIException {
406 		try {
407 
408 			// create message receiver
409 			this.mMsgExchReceiver = createMessageExchangeReceiver();
410 			if (this.mMsgExchReceiver != null) {
411 				this.mMsgExchReceiver.initReceiver(mRuntimeConfig);
412 			}
413 		} catch (Exception ex) {
414 			String msg = MESSAGES
415 					.getString("CRB000426_Failure_in_init_MessageExchangeReceiver");
416 			LOG.error(msg, ex);
417 			throw new JBIException(msg, ex);
418 
419 		}
420 	}
421 
422 	/**
423 	 * removes the message receiver as part of the component shutdown process
424 	 * 
425 	 * @throws javax.jbi.JBIException
426 	 */
427 	private void shutdownMessageExchangeReceiver() throws JBIException {
428 		try {
429 			if (this.mMsgExchReceiver != null) {
430 				this.mMsgExchReceiver.shutdownReceiver();
431 			}
432 		} catch (Exception ex) {
433 			ex.printStackTrace();
434 		} finally {
435 			this.mMsgExchReceiver = null;
436 		}
437 	}
438 
439 	/**
440 	 * allows the component to accept the message exchange objects from the
441 	 * delivery channel and process it as part of the component startup process.
442 	 * 
443 	 * @throws javax.jbi.JBIException
444 	 */
445 	private void startMessageExchangeProcessing() throws JBIException {
446 		try {
447 			// start message processing
448 			if (this.mMsgExchReceiver != null) {
449 				this.mMsgExchReceiver.startProcessing();
450 			}
451 		} catch (Exception ex) {
452 			String msg = MESSAGES
453 					.getString("CRB000427_Failure_in_start_MessageExchangeProcessing");
454 			LOG.error(msg, ex);
455 			throw new JBIException(msg, ex);
456 		}
457 	}
458 
459 	/**
460 	 * stops the component from accepting the message exchange objects from the
461 	 * delivery channel as part of the component stop process
462 	 * 
463 	 * @throws javax.jbi.JBIException
464 	 */
465 	private void stopMessageExchangeProcessing() throws JBIException {
466 		try {
467 			// stop message processing
468 			if (this.mMsgExchReceiver != null) {
469 				this.mMsgExchReceiver.stopProcessing();
470 			}
471 		} catch (Exception ex) {
472 			String msg = MESSAGES
473 					.getString("CRB000428_Failure_in_stop_MessageExchangeProcessing");
474 			LOG.error(msg, ex);
475 			throw new JBIException(msg, ex);
476 		}
477 
478 	}
479 
480 	/**
481 	 * opens the delivery channel to accept the message exchange objects or send
482 	 * the message exchange objects
483 	 */
484 	private void openDeliveryChannel() {
485 		RuntimeContext.getInstance().openDeliveryChannel();
486 	}
487 
488 	/**
489 	 * closes the delivery channel as part of the component shutdown process.
490 	 */
491 	private void closeDeliveryChannel() {
492 		RuntimeContext.getInstance().closeDeliveryChannel();
493 	}
494 
495 	/**
496 	 * create jmx object name for the extension mbean
497 	 */
498 	protected abstract ObjectName createExtensionMBeanName();
499 
500 	/**
501 	 * create mbean implemenation for the extension mbean as a StandardMBean
502 	 */
503 	protected abstract StandardMBean createExtensionMBean();
504 
505 	/**
506 	 * initializes the message exchange handler factory. components implement
507 	 * this method to provide their own handler factory
508 	 * 
509 	 * @throws javax.jbi.JBIException
510 	 */
511 	protected abstract void initMessageExchangeHandlerFactory()
512 			throws JBIException;
513 
514 	/**
515 	 * creates a message receiver object that handles receiving and processing
516 	 * the message exchanges from the delivery channel. Component should
517 	 * implement this method to provide the MessageReceiver.
518 	 * 
519 	 * Component may return null indicating that they don't need the message
520 	 * receiver that can receive and process message exchanges from delivery
521 	 * channel. For example, components that have only service consumers which
522 	 * send a synchronous messages to providers don't need this.
523 	 * 
524 	 * @throws java.lang.Exception
525 	 * @return
526 	 */
527 	protected abstract MessageExchangeReceiver createMessageExchangeReceiver()
528 			throws Exception;
529 
530 	/**
531 	 * service providers initialization such as creating the service
532 	 * descriptions and activating the service endpoints should be done. If the
533 	 * component supports deployment, deployment manager should be notified to
534 	 * active service providers from the deployed service units. This method is
535 	 * invoked in the implementation of ComponentLifeCycle start method
536 	 * 
537 	 * @throws javax.jbi.JBIException
538 	 */
539 	protected abstract void activateServiceProviders() throws JBIException;
540 
541 	/**
542 	 * disable the service providers so that the service consumers can not find
543 	 * the service endpoints for this service provider. This method is invoked
544 	 * in the implementation of ComponentLifeCycle stop method
545 	 * 
546 	 * @throws javax.jbi.JBIException
547 	 */
548 	protected abstract void deactivateServiceProviders() throws JBIException;
549 
550 	/**
551 	 * service consumer initialization such as creating the service descriptions
552 	 * and activating the protocol specific external endpoints should be done.
553 	 * If the component supports deployment, deployment manager should be
554 	 * notified to initialize service consumers from the deployed service units.
555 	 * This method is invoked in the implementation of ComponentLifeCycle start
556 	 * method
557 	 * 
558 	 * @throws javax.jbi.JBIException
559 	 */
560 	protected abstract void activateServiceConsumers() throws JBIException;
561 
562 	/**
563 	 * disables the service consumers so that the service consumer can not send
564 	 * message exchange to the providers. This is called in the implemenation of
565 	 * component lifecycle stop method This method is invoked in the
566 	 * implementation of ComponentLifeCycle stop method
567 	 * 
568 	 * @throws javax.jbi.JBIException
569 	 */
570 	protected abstract void deactivateServiceConsumers() throws JBIException;
571 
572 	/**
573 	 * chance to extended classes to do the component specific init
574 	 * 
575 	 * @throws javax.jbi.JBIException
576 	 */
577 	protected void onInit() throws JBIException {
578 		// NOOP
579 	}
580 
581 	/**
582 	 * chance to extended classes to do the component specific start
583 	 * 
584 	 * @throws javax.jbi.JBIException
585 	 */
586 	protected void onStart() throws JBIException {
587 		// NOOP
588 	}
589 
590 	/**
591 	 * chance to extended classes to do the component specific stop
592 	 * 
593 	 * @throws javax.jbi.JBIException
594 	 */
595 	protected void onStop() throws JBIException {
596 		// NOOP
597 	}
598 
599 	/**
600 	 * chance to extended classes to do the component specific shutdown
601 	 * 
602 	 * @throws javax.jbi.JBIException
603 	 */
604 	protected void onShutDown() throws JBIException {
605 		// NOOP
606 	}
607 
608 }