View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.monitor.triggers;
20  
21  import java.util.Map;
22  import java.util.concurrent.ConcurrentHashMap;
23  
24  import javax.management.MBeanServerConnection;
25  import javax.management.MalformedObjectNameException;
26  import javax.management.ObjectName;
27  import javax.management.openmbean.CompositeData;
28  
29  import org.eclipse.jetty.monitor.JMXMonitor;
30  import org.eclipse.jetty.monitor.jmx.EventState;
31  import org.eclipse.jetty.monitor.jmx.EventTrigger;
32  import org.eclipse.jetty.util.log.Log;
33  import org.eclipse.jetty.util.log.Logger;
34  
35  
36  /* ------------------------------------------------------------ */
37  /**
38   * AttrEventTrigger
39   * 
40   * Event trigger that polls a value of an MXBean attribute
41   * and matches every invocation of this trigger. It can be
42   * used to send notifications of the value of an attribute
43   * of the MXBean being polled at a certain interval, or as
44   * a base class for the event triggers that match the 
45   * value of an attribute of the MXBean being polled against
46   * some specified criteria.
47   */
48  public class AttrEventTrigger<TYPE extends Comparable<TYPE>> 
49      extends EventTrigger
50  {
51      private static final Logger LOG = Log.getLogger(AttrEventTrigger.class);
52     
53      private final ObjectName _nameObject;
54  
55      protected final String _objectName;
56      protected final String _attributeName;
57      protected Map<Long, EventState<TYPE>> _states;
58      
59      /* ------------------------------------------------------------ */
60      /**
61       * Construct event trigger and specify the MXBean attribute
62       * that will be polled by this event trigger.
63       * 
64       * @param objectName object name of an MBean to be polled
65       * @param attributeName name of an MBean attribute to be polled
66       * 
67       * @throws MalformedObjectNameException
68       * @throws IllegalArgumentException
69       */
70      public AttrEventTrigger(String objectName, String attributeName)
71          throws MalformedObjectNameException, IllegalArgumentException
72      {
73          if (objectName == null)
74              throw new IllegalArgumentException("Object name cannot be null");
75          if (attributeName == null)
76              throw new IllegalArgumentException("Attribute name cannot be null");
77          
78          _states =  new ConcurrentHashMap<Long,EventState<TYPE>>();
79          
80          _objectName = objectName;
81          _attributeName = attributeName;
82          
83          _nameObject = new ObjectName(_objectName);
84      }
85  
86      /* ------------------------------------------------------------ */
87      /**
88       * Construct event trigger and specify the MXBean attribute
89       * that will be polled by this event trigger.
90       * 
91       * @param nameObject object name of an MBean to be polled
92       * @param attributeName name of an MBean attribute to be polled
93       * 
94       * @throws IllegalArgumentException
95       */
96      public AttrEventTrigger(ObjectName nameObject, String attributeName)
97          throws IllegalArgumentException
98      {
99          if (nameObject == null)
100             throw new IllegalArgumentException("Object name cannot be null");
101         if (attributeName == null)
102             throw new IllegalArgumentException("Attribute name cannot be null");
103         
104         _states =  new ConcurrentHashMap<Long,EventState<TYPE>>();
105         
106         _objectName = nameObject.toString();
107         _attributeName = attributeName;
108         
109         _nameObject = nameObject;
110     }
111 
112     /* ------------------------------------------------------------ */
113     /**
114      * Verify if the event trigger conditions are in the 
115      * appropriate state for an event to be triggered.
116      * This event trigger uses the match(Comparable<TYPE>)
117      * method to compare the value of the MXBean attribute
118      * to the conditions specified by the subclasses.
119      * 
120      * @see org.eclipse.jetty.monitor.jmx.EventTrigger#match(long)
121      */
122     @SuppressWarnings("unchecked")
123     public final boolean match(long timestamp) 
124         throws Exception
125     {
126         MBeanServerConnection serverConnection = JMXMonitor.getServiceConnection();
127 
128         TYPE value = null;
129         try
130         {
131             int pos = _attributeName.indexOf('.');
132             if (pos < 0)
133                 value = (TYPE)serverConnection.getAttribute(_nameObject,_attributeName);
134             else
135                 value =  getValue((CompositeData)serverConnection.getAttribute(_nameObject, _attributeName.substring(0, pos)),
136                                   _attributeName.substring(pos+1));
137         }
138         catch (Exception ex)
139         {
140             LOG.debug(ex);
141         }
142 
143         boolean result = false;
144         if (value != null)
145         {
146             result = match(value);
147             
148             if (result || getSaveAll())
149             {
150                 _states.put(timestamp, 
151                             new EventState<TYPE>(this.getID(), this.getNameString(), value));
152             }
153         }
154             
155         return result;
156     }
157     
158     
159     /* ------------------------------------------------------------ */
160     /**
161      * Verify if the event trigger conditions are in the 
162      * appropriate state for an event to be triggered.
163      * Allows subclasses to override the default behavior
164      * that matches every invocation of this trigger
165      */
166     public boolean match(Comparable<TYPE> value)
167     {
168         return true;
169     }
170     
171     /* ------------------------------------------------------------ */
172     /**
173      * Retrieve the event state associated with specified invocation
174      * of the event trigger match method. 
175      * 
176      * @param timestamp time stamp associated with invocation
177      * @return event state or null if not found
178      *
179      * @see org.eclipse.jetty.monitor.jmx.EventTrigger#getState(long)
180      */
181     @Override
182     public final EventState<TYPE> getState(long timestamp)
183     {
184         return _states.get(timestamp);
185     }
186     
187     /* ------------------------------------------------------------ */
188     /**
189      * Returns the string representation of this event trigger
190      * in the format "[object_name:attribute_name]". 
191      * 
192      * @return string representation of the event trigger
193      * 
194      * @see java.lang.Object#toString()
195      */
196     public String toString()
197     {
198         return getNameString();
199     }
200     
201     /* ------------------------------------------------------------ */
202     /**
203      * Returns the string representation of this event trigger
204      * in the format "[object_name:attribute_name]". Allows
205      * subclasses to override the name string used to identify
206      * this event trigger in the event state object as well as
207      * string representation of the subclasses.
208      * 
209      * @return string representation of the event trigger
210      */
211     protected String getNameString()
212     {
213         StringBuilder result = new StringBuilder();
214         
215         result.append('[');
216         result.append(_objectName);
217         result.append(":");
218         result.append(_attributeName);
219         result.append("]");
220         
221         return result.toString();
222     }
223 
224     protected boolean getSaveAll()
225     {
226         return true;
227     }
228     
229     protected TYPE getValue(CompositeData compValue, String fieldName)
230     {
231         int pos = fieldName.indexOf('.');
232         if (pos < 0)
233             return (TYPE)compValue.get(fieldName);
234         else
235             return getValue((CompositeData)compValue.get(fieldName.substring(0, pos)), 
236                             fieldName.substring(pos+1));
237           
238     }
239 }