View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 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   * AttrEventTrigger
37   * <p>
38   * Event trigger that polls a value of an MXBean attribute
39   * and matches every invocation of this trigger. It can be
40   * used to send notifications of the value of an attribute
41   * of the MXBean being polled at a certain interval, or as
42   * a base class for the event triggers that match the 
43   * value of an attribute of the MXBean being polled against
44   * some specified criteria.
45   * @param <TYPE> the event trigger type
46   */
47  public class AttrEventTrigger<TYPE extends Comparable<TYPE>> 
48      extends EventTrigger
49  {
50      private static final Logger LOG = Log.getLogger(AttrEventTrigger.class);
51     
52      private final ObjectName _nameObject;
53  
54      protected final String _objectName;
55      protected final String _attributeName;
56      protected Map<Long, EventState<TYPE>> _states;
57      
58      /* ------------------------------------------------------------ */
59      /**
60       * Construct event trigger and specify the MXBean attribute
61       * that will be polled by this event trigger.
62       * 
63       * @param objectName object name of an MBean to be polled
64       * @param attributeName name of an MBean attribute to be polled
65       * 
66       * @throws MalformedObjectNameException if unable to find object due to malformed name reference
67       * @throws IllegalArgumentException if parameters are invalid
68       */
69      public AttrEventTrigger(String objectName, String attributeName)
70          throws MalformedObjectNameException, IllegalArgumentException
71      {
72          if (objectName == null)
73              throw new IllegalArgumentException("Object name cannot be null");
74          if (attributeName == null)
75              throw new IllegalArgumentException("Attribute name cannot be null");
76          
77          _states =  new ConcurrentHashMap<Long,EventState<TYPE>>();
78          
79          _objectName = objectName;
80          _attributeName = attributeName;
81          
82          _nameObject = new ObjectName(_objectName);
83      }
84  
85      /* ------------------------------------------------------------ */
86      /**
87       * Construct event trigger and specify the MXBean attribute
88       * that will be polled by this event trigger.
89       * 
90       * @param nameObject object name of an MBean to be polled
91       * @param attributeName name of an MBean attribute to be polled
92       * 
93       * @throws IllegalArgumentException if parameters are invalid
94       */
95      public AttrEventTrigger(ObjectName nameObject, String attributeName)
96          throws IllegalArgumentException
97      {
98          if (nameObject == null)
99              throw new IllegalArgumentException("Object name cannot be null");
100         if (attributeName == null)
101             throw new IllegalArgumentException("Attribute name cannot be null");
102         
103         _states =  new ConcurrentHashMap<Long,EventState<TYPE>>();
104         
105         _objectName = nameObject.toString();
106         _attributeName = attributeName;
107         
108         _nameObject = nameObject;
109     }
110 
111     /* ------------------------------------------------------------ */
112     /**
113      * Verify if the event trigger conditions are in the 
114      * appropriate state for an event to be triggered.
115      * This event trigger uses the match(Comparable&lt;TYPE&gt;)
116      * method to compare the value of the MXBean attribute
117      * to the conditions specified by the subclasses.
118      * 
119      * @see org.eclipse.jetty.monitor.jmx.EventTrigger#match(long)
120      */
121     @SuppressWarnings("unchecked")
122     public final boolean match(long timestamp) 
123         throws Exception
124     {
125         MBeanServerConnection serverConnection = JMXMonitor.getServiceConnection();
126 
127         TYPE value = null;
128         try
129         {
130             int pos = _attributeName.indexOf('.');
131             if (pos < 0)
132                 value = (TYPE)serverConnection.getAttribute(_nameObject,_attributeName);
133             else
134                 value =  getValue((CompositeData)serverConnection.getAttribute(_nameObject, _attributeName.substring(0, pos)),
135                                   _attributeName.substring(pos+1));
136         }
137         catch (Exception ex)
138         {
139             LOG.debug(ex);
140         }
141 
142         boolean result = false;
143         if (value != null)
144         {
145             result = match(value);
146             
147             if (result || getSaveAll())
148             {
149                 _states.put(timestamp, 
150                             new EventState<TYPE>(this.getID(), this.getNameString(), value));
151             }
152         }
153             
154         return result;
155     }
156     
157     
158     /* ------------------------------------------------------------ */
159     /**
160      * Verify if the event trigger conditions are in the 
161      * appropriate state for an event to be triggered.
162      * Allows subclasses to override the default behavior
163      * that matches every invocation of this trigger
164      * @param value the value to match
165      * @return always true
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 }