001: /*
002: * BEGIN_HEADER - DO NOT EDIT
003: *
004: * The contents of this file are subject to the terms
005: * of the Common Development and Distribution License
006: * (the "License"). You may not use this file except
007: * in compliance with the License.
008: *
009: * You can obtain a copy of the license at
010: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
011: * See the License for the specific language governing
012: * permissions and limitations under the License.
013: *
014: * When distributing Covered Code, include this CDDL
015: * HEADER in each file and include the License file at
016: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
017: * If applicable add the following below this CDDL HEADER,
018: * with the fields enclosed by brackets "[]" replaced with
019: * your own identifying information: Portions Copyright
020: * [year] [name of copyright owner]
021: */
022:
023: /*
024: * @(#)EventNotifier.java
025: * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
026: *
027: * END_HEADER - DO NOT EDIT
028: */
029: package com.sun.jbi.framework;
030:
031: import com.sun.jbi.management.MBeanNames;
032: import com.sun.jbi.platform.PlatformContext;
033:
034: import java.util.concurrent.atomic.AtomicLong;
035: import java.util.concurrent.Executors;
036: import java.util.concurrent.ExecutorService;
037: import java.util.logging.Level;
038: import java.util.logging.Logger;
039: import javax.management.MBeanNotificationInfo;
040: import javax.management.MBeanServerConnection;
041: import javax.management.Notification;
042: import javax.management.NotificationBroadcasterSupport;
043: import javax.management.ObjectName;
044: import javax.management.StandardMBean;
045: import javax.management.openmbean.CompositeData;
046: import javax.management.openmbean.CompositeDataSupport;
047: import javax.management.openmbean.CompositeType;
048: import javax.management.openmbean.OpenType;
049: import javax.management.openmbean.SimpleType;
050:
051: /**
052: * This is the instance Event Notifier MBean that generates notifications for
053: * the entire JBI runtime. There is one of these MBeans per runtime instance,
054: * and it is called to emit notifications for all applicable events in the
055: * runtime. This MBean is registered with ServiceName=Framework,
056: * ControlType=Notification, and ComponentType=System.
057: *
058: * Notifications that are currently supported by this implementation include:
059: * <ul>
060: * <li>JBI Runtime:
061: * <ul>
062: * <li>Ready</li>
063: * <li>Started</li>
064: * <li>Stopped</li>
065: * </ul></li>
066: * <li>Component (Binding Component / Service Engine):
067: * <ul>
068: * <li>Installed</li>
069: * <li>Started</li>
070: * <li>Stopped</li>
071: * <li>Shut down</li>
072: * <li>Uninstalled</li>
073: * </ul></li>
074: * <li>Shared Library:
075: * <ul>
076: * <li>Installed</li>
077: * <li>Uninstalled</li>
078: * </ul></li>
079: * <li>Service Assembly:
080: * <ul>
081: * <li>Deployed</li>
082: * <li>Started</li>
083: * <li>Stopped</li>
084: * <li>Shut down</li>
085: * <li>Undeployed</li>
086: * </ul></li>
087: * <li>Service Unit:
088: * <ul>
089: * <li>Deployed</li>
090: * <li>Started</li>
091: * <li>Stopped</li>
092: * <li>Shut down</li>
093: * <li>Undeployed</li>
094: * </ul></li>
095: * </ul>
096: *
097: * All notifications emitted by this MBean are instances of the
098: * <code>javax.management.Notification</code> class, and include following
099: * information:
100: *
101: * <ul>
102: * <li>
103: * type - a dotted string describing the notification, such as
104: * "com.sun.jbi.started.binding.component"
105: * </li>
106: * <li>
107: * msg - a message resulting from the operation, such as
108: * "Binding sun-http-binding started successfully"
109: * </li>
110: * <li>
111: * seqNo - a sequence number which is unique for the current execution of the
112: * runtime
113: * </li>
114: * <li>
115: * timeStamp - a timestamp indicating the time the notification was created
116: * </li>
117: * <li>
118: * userData - a <code>javax.management.openmbean.CompositeData</code> object
119: * which contains the following:
120: * <ul>
121: * <li>
122: * Event type: Deployed, Undeployed, Installed, Uninstalled, Started,
123: * Stopped, or ShutDown
124: * </li>
125: * <li>
126: * Source type: BindingComponent, ServiceEngine, SharedLibrary,
127: * ServiceAssembly, ServiceUnit, or JBIRuntime
128: * </li>
129: * <li>
130: * Source name: component name, shared library name, service assembly name,
131: * or service unit name
132: * </li>
133: * <li>
134: * Target name: instance name or cluster name + instance name, such as
135: * "server", "instance1", or "cluster1-instance1"
136: * </li>
137: * <li>
138: * Component name: this is present only for Service Unit notifications
139: * </li>
140: * <li>
141: * Service Assembly name: this is present only for Service Unit notifications
142: * </li>
143: * <li>
144: * </ul>
145: * </li>
146: * </ul>
147: *
148: * Note that this class extends the NotificationBroadcasterSupport class
149: * provided by the JDK, and there is no guarantee that the calls to send
150: * notifications are asynchronous. Therefore, all sending of notifications
151: * is done on separate threads to ensure that an ill-behaved client cannot
152: * block the thread on which the call to this class was made. This is done
153: * using the facilities provided by the java.util.concurrent package. In the
154: * constructor for this class, a thread pool is created, and all calls to
155: * the sendNotification() method are made using this thread pool. The Notify
156: * class contained in this class implements the Runnable interface and is
157: * used to make the sendNotification() calls.
158: *
159: * @author Mark S White
160: */
161: public class EventNotifier extends NotificationBroadcasterSupport
162: implements EventNotifierCommon, EventNotifierMBean {
163: /**
164: * Global sequence number for notifications from this MBean.
165: */
166: private static AtomicLong sSeqNo = new AtomicLong();
167:
168: /**
169: * Flag for enabling / disabling event notifications.
170: */
171: private boolean mNotificationsEnabled;
172:
173: /**
174: * Logger for messages.
175: */
176: private Logger mLog;
177:
178: /**
179: * Translator / formatter for messages.
180: */
181: private StringTranslator mTranslator;
182:
183: /**
184: * Instance name where this MBean is running.
185: */
186: private String mInstanceName;
187:
188: /**
189: * Combined cluster and instance name. If this is a clustered instance,
190: * this is "clusterName-instanceName"; otherwise it's "instanceName".
191: */
192: private String mCombinedName;
193:
194: /**
195: * JMX ObjectName of this MBean.
196: */
197: private ObjectName mObjName;
198:
199: /**
200: * JMX ObjectName of the DAS event notifier MBean. This is required for
201: * invoking operations to inform the MBean when this instance event
202: * notifier MBean starts up and shuts down.
203: */
204: private ObjectName mDASMBeanName;
205:
206: /**
207: * Platform Context for the runtime environment.
208: */
209: private PlatformContext mPlatformContext;
210:
211: /**
212: * Executor service to send notifications on threads from a pool.
213: */
214: private ExecutorService mExecSvc;
215:
216: /**
217: * CompositeType used to describe CompositeData representing user data
218: * in notifications for runtime, component, shared library, and service
219: * assembly events.
220: */
221: private CompositeType mUserDataType1;
222:
223: /**
224: * CompositeType used to describe CompositeData representing user data
225: * in notifications for service unit events.
226: */
227: private CompositeType mUserDataType2;
228:
229: /**
230: * Source name for JBI runtime notification messages. Package-visible for
231: * unit testing.
232: */
233: static final String JBI_FRAMEWORK = "JBIFramework";
234:
235: /*
236: * Item name key for event type. Package-visible for unit testing.
237: */
238: static final String EVENT_TYPE_KEY = "EventType";
239:
240: /**
241: * Item name key for source type. Package-visible for unit testing.
242: */
243: static final String SOURCE_TYPE_KEY = "SourceType";
244:
245: /**
246: * Item name key for target name. Package-visible for unit testing.
247: */
248: static final String TARGET_NAME_KEY = "TargetName";
249:
250: /**
251: * Item name key for source type. Package-visible for unit testing.
252: */
253: static final String SOURCE_NAME_KEY = "SourceName";
254:
255: /**
256: * Item name key for component name. Package-visible for unit testing.
257: */
258: static final String COMPONENT_NAME_KEY = "ComponentName";
259:
260: /**
261: * Item name key for service assembly name. Package-visible for unit testing.
262: */
263: static final String SERVICE_ASSEMBLY_NAME_KEY = "ServiceAssemblyName";
264:
265: /**
266: * Item name key for service unit name. Package-visible for unit testing.
267: */
268: static final String SERVICE_UNIT_NAME_KEY = "ServiceUnitName";
269:
270: /**
271: * List of item names for CompositeData construction for runtime, component,
272: * shared library, and service assembly notifications. Package-visible for
273: * unit testing.
274: */
275: static final String[] ITEM_NAMES_1 = { EVENT_TYPE_KEY,
276: SOURCE_TYPE_KEY, TARGET_NAME_KEY, SOURCE_NAME_KEY };
277:
278: /**
279: * List of item names for CompositeData construction for service unit
280: * notifications. Package-visible for unit testing.
281: */
282: static final String[] ITEM_NAMES_2 = { EVENT_TYPE_KEY,
283: SOURCE_TYPE_KEY, TARGET_NAME_KEY, SOURCE_NAME_KEY,
284: SERVICE_ASSEMBLY_NAME_KEY, COMPONENT_NAME_KEY };
285:
286: /**
287: * List of descriptions of items for CompositeData construction for
288: * runtime, component, shared library, and service assembly notifications.
289: * Package-visible for unit testing.
290: */
291: static final String[] ITEM_DESCRIPTIONS_1 = {
292: "Type of event that occurred",
293: "Type of entity on which the event occurred",
294: "Name of the target where the event occurred",
295: "Name of the entity affected by the event" };
296:
297: /**
298: * List of descriptions of items for CompositeData construction for service
299: * unit notifications. Package-visible for unit testing.
300: */
301: static final String[] ITEM_DESCRIPTIONS_2 = {
302: "Type of event that occurred",
303: "Type of entity on which the event occurred",
304: "Name of the target where the event occurred",
305: "Name of the service unit affected by the event",
306: "Name of the service assembly to which the service unit belongs",
307: "Name of the component to which the service unit is deployed" };
308:
309: /**
310: * List of types of items for CompositeData construction for runtime,
311: * component, shared library, and service assembly notifications. Package-
312: * visible for unit testing.
313: */
314: static final OpenType[] ITEM_TYPES_1 = { SimpleType.STRING,
315: SimpleType.STRING, SimpleType.STRING, SimpleType.STRING };
316:
317: /**
318: * List of types of items for CompositeData construction for service unit
319: * notifications. Package-visible for unit testing.
320: */
321: static final OpenType[] ITEM_TYPES_2 = { SimpleType.STRING,
322: SimpleType.STRING, SimpleType.STRING, SimpleType.STRING,
323: SimpleType.STRING, SimpleType.STRING };
324:
325: /**
326: * Constructor to set up local constants.
327: *
328: * @param ctx the environment context for the JBI runtime.
329: */
330: EventNotifier(EnvironmentContext ctx) throws javax.jbi.JBIException {
331: super ();
332: mLog = ctx.getLogger();
333: mTranslator = (StringTranslator) ctx
334: .getStringTranslatorFor(this );
335: mPlatformContext = ctx.getPlatformContext();
336: mInstanceName = mPlatformContext.getInstanceName();
337: mNotificationsEnabled = true; // Default to enabled for now
338:
339: if (mPlatformContext.isInstanceClustered(mInstanceName)) {
340: mCombinedName = mInstanceName + "-"
341: + mPlatformContext.getTargetName();
342: } else {
343: mCombinedName = mInstanceName;
344: }
345:
346: // Create the thread pool to be used for sending notifications
347:
348: mExecSvc = Executors.newCachedThreadPool();
349:
350: // Initialize the composite data types used in the notifications sent
351: // by this MBean.
352: try {
353: mUserDataType1 = new CompositeType("UserData",
354: "notification user data", ITEM_NAMES_1,
355: ITEM_DESCRIPTIONS_1, ITEM_TYPES_1);
356: mUserDataType2 = new CompositeType("UserData",
357: "notification user data", ITEM_NAMES_2,
358: ITEM_DESCRIPTIONS_2, ITEM_TYPES_2);
359: } catch (javax.management.openmbean.OpenDataException odEx) {
360: String msg = mTranslator.getString(
361: LocalStringKeys.FN_USER_DATA_CREATE_FAILED, odEx
362: .getClass().getName());
363: mLog.log(Level.WARNING, msg, odEx);
364: throw new javax.jbi.JBIException(msg, odEx);
365: }
366:
367: // Construct the EventNotifierMBean name for this instance.
368: mObjName = ctx.getMBeanNames().getSystemServiceMBeanName(
369: MBeanNames.SERVICE_NAME_FRAMEWORK,
370: MBeanNames.CONTROL_TYPE_NOTIFICATION);
371:
372: // Construct the DAS EventNotifierMBean name.
373: mDASMBeanName = ctx.getMBeanNames().getSystemServiceMBeanName(
374: MBeanNames.ServiceName.Framework,
375: MBeanNames.ServiceType.Notification, "domain");
376: }
377:
378: //
379: // Overridden methods of the NotificationBroadcasterSupport class
380: //
381:
382: /**
383: * Returns an array indicating, for each notification this MBean may send,
384: * the notification type, the name of the Java class of the notification,
385: * and a description of the notification.
386: *
387: * @return an array of <code>javax.managagement.MBeanNotificationInfo</code>
388: * objects which describe the notifications.
389: */
390: public MBeanNotificationInfo[] getNotificationInfo() {
391: MBeanNotificationInfo[] notifs = { new MBeanNotificationInfo(
392: NOTIFICATION_TYPES, NOTIFICATION_CLASS_NAME,
393: NOTIFICATION_DESCRIPTION) };
394: return notifs;
395: }
396:
397: //
398: // Methods in the EventNotifierMBean interface
399: //
400:
401: /**
402: * Disable event notifications from being emitted by this MBean.
403: */
404: public void disableNotifications() {
405: mNotificationsEnabled = false;
406: mLog.fine("Event notifications disabled for instance "
407: + mCombinedName);
408: }
409:
410: /**
411: * Enable event notifications to be emitted by this MBean.
412: */
413: public void enableNotifications() {
414: mNotificationsEnabled = true;
415: mLog.fine("Event notifications enabled for instance "
416: + mCombinedName);
417: }
418:
419: //
420: // Methods in the EventNotifierBase interface. These methods are callable from
421: // any service in the JBI runtime and are not exposed as MBean operations.
422: //
423:
424: /**
425: * Emit a notification for an event on the JBI runtime. The caller provides
426: * information that determines the content of of the notification. The
427: * event type for a JBI runtime notification can be Ready, Started, or
428: * Stopped. The source type is always JBIRuntime.
429: *
430: * @param eventType the type of event that occurred.
431: * @param msg a message associated with the event.
432: * @return the actual Notification sent (this is used primarily for unit
433: * testing).
434: */
435: public Notification emitRuntimeNotification(EventType eventType,
436: String msg) {
437: if (mNotificationsEnabled) {
438: String type = JBI_PREFIX + eventType + "."
439: + SourceType.JBIRuntime;
440: Notification notif = new Notification(type, mObjName,
441: sSeqNo.incrementAndGet(), msg);
442: CompositeData userData = toCompositeData1(eventType
443: .toString(), SourceType.JBIRuntime.toString(),
444: JBI_FRAMEWORK);
445: if (null != userData) {
446: mLog.finest("Created notification userdata: "
447: + userData.toString());
448: notif.setUserData(userData);
449: }
450: mLog.finer("Sending notification: " + notif.toString()
451: + " sequence number " + notif.getSequenceNumber());
452: mExecSvc.execute(new Notify(this , notif));
453: return notif;
454: } else {
455: return null;
456: }
457: }
458:
459: /**
460: * Emit a notification for an event on either a binding component or a
461: * service engine. The caller provides information that determines the
462: * content of the notification. The event type for a component notification
463: * can be Installed, Uninstalled, Started, Stopped, or ShutDown. The source
464: * type is either BindingComponent or ServiceEngine.
465: *
466: * @param eventType the type of event that occurred.
467: * @param sourceType the type of component on which the event occurred.
468: * @param componentName the name of the component on which the event
469: * occurred.
470: * @param msg a message associated with the event.
471: * @return the actual Notification sent (this is used primarily for unit
472: * testing).
473: */
474: public Notification emitComponentNotification(EventType eventType,
475: SourceType sourceType, String componentName, String msg) {
476: if (mNotificationsEnabled) {
477: String type = JBI_PREFIX + eventType + "." + sourceType;
478: Notification notif = new Notification(type, mObjName,
479: sSeqNo.incrementAndGet(), msg);
480: CompositeData userData = toCompositeData1(eventType
481: .toString(), sourceType.toString(), componentName);
482: if (null != userData) {
483: mLog.finest("Created notification userdata: "
484: + userData.toString());
485: notif.setUserData(userData);
486: }
487: mLog.finer("Sending notification: " + notif.toString()
488: + " sequence number " + notif.getSequenceNumber());
489: mExecSvc.execute(new Notify(this , notif));
490: return notif;
491: } else {
492: return null;
493: }
494: }
495:
496: /**
497: * Emit a notification for an event on a shared library. The caller provides
498: * information that determines the content of the notification. The event
499: * type for a shared library notification can be either Installed or
500: * Uninstalled. The source type is always SharedLibrary.
501: *
502: * @param eventType the type of event that occurred.
503: * @param sharedLibraryName the name of the shared library on which the
504: * event occurred.
505: * @param msg a message associated with the event.
506: * @return the actual Notification sent (this is used primarily for unit
507: * testing).
508: */
509: public Notification emitSharedLibraryNotification(
510: EventType eventType, String sharedLibraryName, String msg) {
511: if (mNotificationsEnabled) {
512: String type = JBI_PREFIX + eventType + "."
513: + SourceType.SharedLibrary;
514: Notification notif = new Notification(type, mObjName,
515: sSeqNo.incrementAndGet(), msg);
516: CompositeData userData = toCompositeData1(eventType
517: .toString(), SourceType.SharedLibrary.toString(),
518: sharedLibraryName);
519: if (null != userData) {
520: mLog.finest("Created notification userdata: "
521: + userData.toString());
522: notif.setUserData(userData);
523: }
524: mLog.finer("Sending notification: " + notif.toString()
525: + " sequence number " + notif.getSequenceNumber());
526: mExecSvc.execute(new Notify(this , notif));
527: return notif;
528: } else {
529: return null;
530: }
531: }
532:
533: /**
534: * Emit a notification for an event on a service assembly. The caller
535: * provides information that determines the content of the notification.
536: * The event type for a service assembly notification can be Deployed,
537: * Undeployed, Started, Stopped, or ShutDown. The source type is always
538: * ServiceAssembly.
539: *
540: * @param eventType the type of event that occurred.
541: * @param serviceAssemblyName the name of the service assembly on which the
542: * event occurred.
543: * @param msg a message associated with the event.
544: * @return the actual Notification sent (this is used primarily for unit
545: * testing).
546: */
547: public Notification emitServiceAssemblyNotification(
548: EventType eventType, String serviceAssemblyName, String msg) {
549: if (mNotificationsEnabled) {
550: String type = JBI_PREFIX + eventType + "."
551: + SourceType.ServiceAssembly;
552: Notification notif = new Notification(type, mObjName,
553: sSeqNo.incrementAndGet(), msg);
554: CompositeData userData = toCompositeData1(eventType
555: .toString(), SourceType.ServiceAssembly.toString(),
556: serviceAssemblyName);
557: if (null != userData) {
558: mLog.finest("Created notification userdata: "
559: + userData.toString());
560: notif.setUserData(userData);
561: }
562: mLog.finer("Sending notification: " + notif.toString()
563: + " sequence number " + notif.getSequenceNumber());
564: mExecSvc.execute(new Notify(this , notif));
565: return notif;
566: } else {
567: return null;
568: }
569: }
570:
571: /**
572: * Emit a notification for an event on a service unit. The caller provides
573: * information that determines the content of the notification. The event
574: * type for a service unit notification can be Deployed, Undeployed,
575: * Started, Stopped, or ShutDown. The source type is always ServiceUnit.
576: *
577: * @param eventType the type of event that occurred.
578: * @param serviceUnitName the name of the service unit on which the event
579: * occurred.
580: * @param serviceAssemblyName the name of the service assembly to which the
581: * service unit belongs.
582: * @param componentName the name of the component to which the service unit
583: * is deployed.
584: * @param msg a message associated with the event.
585: * @return the actual Notification sent (this is used primarily for unit
586: * testing).
587: */
588: public Notification emitServiceUnitNotification(
589: EventType eventType, String serviceUnitName,
590: String serviceAssemblyName, String componentName, String msg) {
591: if (mNotificationsEnabled) {
592: String type = JBI_PREFIX + eventType + "."
593: + SourceType.ServiceUnit;
594: Notification notif = new Notification(type, mObjName,
595: sSeqNo.incrementAndGet(), msg);
596: CompositeData userData = toCompositeData2(eventType
597: .toString(), SourceType.ServiceUnit.toString(),
598: serviceUnitName, serviceAssemblyName, componentName);
599: if (null != userData) {
600: mLog.finest("Created notification userdata: "
601: + userData.toString());
602: notif.setUserData(userData);
603: }
604: mLog.finer("Sending notification: " + notif.toString()
605: + " sequence number " + notif.getSequenceNumber());
606: mExecSvc.execute(new Notify(this , notif));
607: return notif;
608: } else {
609: return null;
610: }
611: }
612:
613: //
614: // Package visible methods
615: //
616:
617: /**
618: * Inform the DAS Event Notifier MBean that this instance is starting. This
619: * causes the DAS MBean to invoke the <code>addNotificationListener()</code>
620: * operation on this instance MBean to register itself as a notification
621: * listener for notifications from this instance. This method is called by
622: * the framework during startup.
623: */
624: void instanceStarting() {
625: invokeDASMBean("instanceStarted");
626: }
627:
628: /**
629: * Inform the DAS Event Notifier MBean that this instance is stopping. This
630: * causes the DAS MBean to invoke the <code>removeNotificationListener</code>
631: * operation on this instance MBean to unregister itself as a notification
632: * listener for notifications from this instance. This method is called by
633: * the framework during shutdown.
634: */
635: void instanceStopping() {
636: invokeDASMBean("instanceStopped");
637:
638: // Shut down the ExecutorService. This is crucial to prevent any
639: // notification threads from hanging the shutdown of the runtime.
640: mExecSvc.shutdownNow();
641: }
642:
643: //
644: // Private methods
645: //
646:
647: /**
648: * Invoke an operation on the DAS Event Notifier MBean.
649: *
650: * @param operation the operation to be invoked, either "instanceStarted"
651: * or "instanceStopped".
652: */
653: private void invokeDASMBean(String operation) {
654: // Get an MBean server connection with the DAS
655:
656: MBeanServerConnection mbsConn = null;
657: try {
658: mbsConn = mPlatformContext
659: .getMBeanServerConnection(mPlatformContext
660: .getAdminServerName());
661: } catch (Throwable ex) {
662: // This means that the DAS is not currently running. This can be
663: // ignored, because when the DAS starts, it registers as a
664: // notification listener with any instances that are already up.
665: mLog.log(Level.FINE,
666: "Unable to get MBean server connection "
667: + " for admin server "
668: + mPlatformContext.getAdminServerName()
669: + ". Exception follows.", ex);
670: }
671:
672: // If we have a connection with the DAS, invoke the MBean operation.
673:
674: if (null != mbsConn) {
675: // Set up parameters for calling the MBean
676: String[] signature;
677: Object[] params;
678: signature = new String[] { "String", "String" };
679: params = new Object[] { mInstanceName, mObjName };
680:
681: // Invoke the specified operation on the DAS event notifier MBean
682: try {
683: mLog.finest("Invoking " + operation + " on MBean "
684: + mDASMBeanName);
685: mbsConn.invoke(mDASMBeanName, operation, params,
686: signature);
687: } catch (Throwable ex) {
688: Throwable actualEx = stripJmxException(ex);
689: mLog.log(Level.FINE,
690: "Failure invoking MBean operation " + operation
691: + ". Exception follows.", actualEx);
692: }
693: }
694: }
695:
696: /**
697: * Strip JMX Exceptions from the exception chain and return the actual
698: * embedded Exception thrown by the remote instance.
699: *
700: * @param ex the JMX exception caught.
701: * @return the actual exception thrown by the remote instance.
702: */
703: private Throwable stripJmxException(Throwable ex) {
704: Throwable currEx = ex;
705:
706: while (null != currEx.getCause()) {
707: if (!(currEx instanceof javax.management.JMException)
708: && !(currEx instanceof javax.management.JMRuntimeException)) {
709: return currEx;
710: }
711: currEx = currEx.getCause();
712: }
713: return currEx;
714: }
715:
716: /**
717: * Convert notification information to a CompositeData type. This version
718: * is for runtime, component, shared library, and service assembly events.
719: *
720: * @param eventType The type of event that occurred.
721: * @param sourceType The type entity on which the event occurred.
722: * @param sourceName The name of the entity on which the event occurred.
723: * @return The CompositeData constructed from the input parameters.
724: */
725: private CompositeData toCompositeData1(String eventType,
726: String sourceType, String sourceName) {
727: Object values[] = { eventType, sourceType, mCombinedName,
728: sourceName };
729:
730: CompositeData cd = null;
731: try {
732: cd = new CompositeDataSupport(mUserDataType1, ITEM_NAMES_1,
733: values);
734: } catch (javax.management.openmbean.OpenDataException odEx) {
735: mLog.log(Level.WARNING, mTranslator.getString(
736: LocalStringKeys.FN_USER_DATA_CREATE_FAILED, odEx
737: .getClass().getName()), odEx);
738: }
739: return cd;
740: }
741:
742: /**
743: * Convert notification information to a CompositeData type. This version
744: * is for service unit events.
745: *
746: * @param eventType The type of event that occurred.
747: * @param sourceType The type entity on which the event occurred.
748: * @param serviceUnitName The name of the service unit on which the event
749: * occurred.
750: * @param serviceAssemblyName The name of the service assembly to which the
751: * service unit belongs.
752: * @param componentName The name of the component to which the service unit
753: * is deployed.
754: * @return The CompositeData constructed from the input parameters.
755: */
756: private CompositeData toCompositeData2(String eventType,
757: String sourceType, String serviceUnitName,
758: String serviceAssemblyName, String componentName) {
759: Object values[] = { eventType, sourceType, mCombinedName,
760: serviceUnitName, serviceAssemblyName, componentName };
761:
762: CompositeData cd = null;
763: try {
764: cd = new CompositeDataSupport(mUserDataType2, ITEM_NAMES_2,
765: values);
766: } catch (javax.management.openmbean.OpenDataException odEx) {
767: mLog.log(Level.WARNING, mTranslator.getString(
768: LocalStringKeys.FN_USER_DATA_CREATE_FAILED, odEx
769: .getClass().getName()), odEx);
770: }
771: return cd;
772: }
773:
774: //
775: // Inner class to provide a Runnable implementation that can run notifications
776: // on threads from a pool.
777: //
778:
779: /**
780: * Runnable class to send a notification on a separate thread.
781: */
782: class Notify implements Runnable {
783: /**
784: * EventNotifier instance reference.
785: */
786: EventNotifier mEventNotifier;
787:
788: /**
789: * Notification instance to be sent.
790: */
791: Notification mNotification;
792:
793: /**
794: * Constructor.
795: *
796: * @param en the instance of EventNotifier that called this constructor.
797: * @param notif the JMX Notification to be sent.
798: */
799: Notify(EventNotifier en, Notification notif) {
800: mEventNotifier = en;
801: mNotification = notif;
802: }
803:
804: /**
805: * Run the actual sending of the notification. This runs on a thread
806: * from the pool created by Executors.newCachedThreadPool().
807: */
808: public void run() {
809: mEventNotifier.sendNotification(mNotification);
810: }
811: }
812:
813: }
|