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