View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.module.management.agent;
8   
9   import org.mule.agent.AbstractNotificationLoggerAgent;
10  import org.mule.api.context.notification.ServerNotification;
11  import org.mule.api.lifecycle.InitialisationException;
12  import org.mule.config.i18n.CoreMessages;
13  import org.mule.module.management.support.AutoDiscoveryJmxSupportFactory;
14  import org.mule.module.management.support.JmxSupport;
15  import org.mule.module.management.support.JmxSupportFactory;
16  
17  import java.util.ArrayList;
18  import java.util.List;
19  
20  import javax.management.MBeanServer;
21  import javax.management.MBeanServerFactory;
22  import javax.management.Notification;
23  import javax.management.NotificationBroadcasterSupport;
24  import javax.management.NotificationEmitter;
25  import javax.management.ObjectName;
26  
27  /**
28   * An agent that propergates Mule Server notifications to Jmx.
29   *
30   */
31  public class JmxServerNotificationAgent extends AbstractNotificationLoggerAgent
32  {
33  
34      public static final String LISTENER_JMX_OBJECT_NAME = "type=org.mule.Notification,name=MuleNotificationListener";
35      public static final String BROADCASTER_JMX_OBJECT_NAME = "type=org.mule.Notification,name=MuleNotificationBroadcaster";
36      public static final String DEFAULT_AGENT_NAME = "Jmx Notification Agent";
37  
38      private MBeanServer mBeanServer;
39      private BroadcastNotificationService broadcastNotificationMbean;
40      private boolean registerListenerMbean = true;
41      private ObjectName listenerObjectName;
42      private ObjectName broadcasterObjectName;
43  
44      private JmxSupportFactory jmxSupportFactory = AutoDiscoveryJmxSupportFactory.getInstance();
45      private JmxSupport jmxSupport;
46  
47  
48      public JmxServerNotificationAgent()
49      {
50          super(DEFAULT_AGENT_NAME);
51      }
52  
53      /**
54       * {@inheritDoc}
55       */
56      protected void doInitialise() throws InitialisationException
57      {
58          try
59          {
60              jmxSupport = jmxSupportFactory.getJmxSupport();
61              mBeanServer = (MBeanServer) MBeanServerFactory.findMBeanServer(null).get(0);
62              broadcasterObjectName = ObjectName.getInstance(jmxSupport.getDomainName(muleContext) + ":" + BROADCASTER_JMX_OBJECT_NAME);
63              broadcastNotificationMbean = new BroadcastNotificationService();
64              mBeanServer.registerMBean(broadcastNotificationMbean, broadcasterObjectName);
65              if (registerListenerMbean)
66              {
67                  listenerObjectName = ObjectName.getInstance(jmxSupport.getDomainName(muleContext) + ":" + LISTENER_JMX_OBJECT_NAME);
68                  NotificationListener mbean = new NotificationListener();
69                  broadcastNotificationMbean.addNotificationListener(mbean, null, null);
70                  mBeanServer.registerMBean(mbean, listenerObjectName);
71              }
72          }
73          catch (Exception e)
74          {
75              throw new InitialisationException(CoreMessages.failedToStart("JMX Server Notification Agent"), e, this);
76          }
77      }
78  
79  
80      /**
81       * {@inheritDoc}
82       */
83      public void dispose()
84      {
85          if (listenerObjectName != null && mBeanServer.isRegistered(listenerObjectName))
86          {
87              try
88              {
89                  mBeanServer.unregisterMBean(listenerObjectName);
90              }
91              catch (Exception e)
92              {
93                  logger.warn(e.getMessage(), e);
94              }
95          }
96  
97          if (broadcasterObjectName != null && mBeanServer.isRegistered(broadcasterObjectName))
98          {
99              try
100             {
101                 mBeanServer.unregisterMBean(broadcasterObjectName);
102             }
103             catch (Exception e)
104             {
105                 logger.warn(e.getMessage(), e);
106             }
107         }        super.dispose();
108     }
109 
110     /**
111      * {@inheritDoc}
112      */
113     protected void logEvent(ServerNotification e)
114     {
115         broadcastNotificationMbean.sendNotification(new Notification(e.getClass().getName(), e, e.getTimestamp(), e.toString()));
116     }
117 
118     /**
119      * Should be a 1 line description of the agent.
120      *
121      * @return description
122      */
123     public String getDescription()
124     {
125         return DEFAULT_AGENT_NAME + (registerListenerMbean ? " (Listener MBean registered)" : "");
126     }
127 
128 
129     /**
130      * Getter for property 'jmxSupportFactory'.
131      *
132      * @return Value for property 'jmxSupportFactory'.
133      */
134     public JmxSupportFactory getJmxSupportFactory()
135     {
136         return jmxSupportFactory;
137     }
138 
139     /**
140      * Setter for property 'jmxSupportFactory'.
141      *
142      * @param jmxSupportFactory Value to set for property 'jmxSupportFactory'.
143      */
144     public void setJmxSupportFactory(JmxSupportFactory jmxSupportFactory)
145     {
146         this.jmxSupportFactory = jmxSupportFactory;
147     }
148 
149     public static interface BroadcastNotificationServiceMBean extends NotificationEmitter
150     {
151         // no methods
152     }
153 
154     public static class BroadcastNotificationService extends NotificationBroadcasterSupport implements BroadcastNotificationServiceMBean
155     {
156         // no methods
157     }
158 
159     public static interface NotificationListenerMBean
160     {
161         /**
162          * Getter for property 'notificsationList'.
163          *
164          * @return Value for property 'notificsationList'.
165          */
166         List getNotificationsList();
167 
168         /**
169          * Getter for property 'listSize'.
170          *
171          * @return Value for property 'listSize'.
172          */
173         int getListSize();
174 
175         /**
176          * Setter for property 'listSize'.
177          *
178          * @param listSize Value to set for property 'listSize'.
179          */
180         void setListSize(int listSize);
181     }
182 
183     public static class NotificationListener implements NotificationListenerMBean, javax.management.NotificationListener
184     {
185         private int listSize = 100;
186 
187         private List notifs;
188 
189         /**
190          * {@inheritDoc}
191          */
192         public void handleNotification(Notification notification, Object o)
193         {
194             if (getList().size() == listSize)
195             {
196                 getList().remove(listSize - 1);
197             }
198             getList().add(0, notification);
199         }
200 
201         /**
202          * {@inheritDoc}
203          */
204         public List getNotificationsList()
205         {
206             return notifs;
207         }
208 
209         /**
210          * {@inheritDoc}
211          */
212         public int getListSize()
213         {
214             return listSize;
215         }
216 
217         /**
218          * {@inheritDoc}
219          */
220         public void setListSize(int listSize)
221         {
222             this.listSize = listSize;
223         }
224 
225         /**
226          * Getter for property 'list'.
227          *
228          * @return Value for property 'list'.
229          */
230         protected List getList()
231         {
232             if (notifs == null)
233             {
234                 notifs = new ArrayList(listSize);
235             }
236             return notifs;
237         }
238 
239     }
240 
241 }