This project has retired. For details please refer to its Attic page.
UDDIServiceCounter xref
View Javadoc
1   /*
2    * Copyright 2001-2008 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   */
17  package org.apache.juddi.api.impl;
18  
19  import java.io.Serializable;
20  import java.util.ArrayList;
21  import java.util.Hashtable;
22  import java.util.List;
23  
24  import javax.management.Attribute;
25  import javax.management.AttributeList;
26  import javax.management.AttributeNotFoundException;
27  import javax.management.DynamicMBean;
28  import javax.management.InstanceAlreadyExistsException;
29  import javax.management.InvalidAttributeValueException;
30  import javax.management.MBeanAttributeInfo;
31  import javax.management.MBeanException;
32  import javax.management.MBeanInfo;
33  import javax.management.MBeanOperationInfo;
34  import javax.management.MBeanRegistrationException;
35  import javax.management.MBeanServer;
36  import javax.management.MBeanServerFactory;
37  import javax.management.MalformedObjectNameException;
38  import javax.management.NotCompliantMBeanException;
39  import javax.management.ObjectName;
40  import javax.management.ReflectionException;
41  
42  import org.apache.commons.logging.Log;
43  import org.apache.commons.logging.LogFactory;
44  import org.apache.juddi.api.util.QueryStatus;
45  import org.apache.juddi.api.util.UDDIQuery;
46  
47  /**
48   * This class provides MBean functionality that offers metrics on UDDI service method invocations
49   * and various management functions (documented by Alex O'Ree)
50   * @author Tom Cunningham
51   */
52  public class UDDIServiceCounter implements DynamicMBean, Serializable {
53  
54      private static Log log = LogFactory.getLog(UDDIServiceCounter.class);
55  
56      private Hashtable <String, LongHolder> queryProcessingTime;
57      private Hashtable <String, IntHolder> totalQueryCounter;
58      private Hashtable <String, IntHolder> successQueryCounter;
59      private Hashtable <String, IntHolder> faultQueryCounter;
60  
61      private ObjectName listObjectName = null;
62      
63      private int totalApiCounter;
64      private int successApiCounter;
65      private int faultApiCounter;
66      
67      private static final String PROCESSING_TIME = "processing time";
68      private static final String TOTAL_QUERIES = "total queries";
69      private static final String SUCCESSFUL_QUERIES = "successful queries";
70      private static final String FAILED_QUERIES = "failed queries";
71      
72      private static final String TOTAL_API_QUERIES = "Total API Queries";
73      private static final String SUCCESSFUL_API_QUERIES = "Successful API Queries";
74      private static final String FAILED_API_QUERIES = "Failed API Queries";
75      
76      public static final String RESET_COUNTER = "resetCounts";
77          
78      public void initList(Class klass, List<String> queries) {
79          try {
80              listObjectName = new ObjectName("apache.juddi:" + "counter=" + klass.getName());
81          } catch (MalformedObjectNameException mone) {
82              log.error(mone);
83          }
84          
85          queryProcessingTime = new Hashtable<String,LongHolder>();
86          totalQueryCounter = new Hashtable<String, IntHolder>();
87          successQueryCounter = new Hashtable<String, IntHolder>();
88          faultQueryCounter = new Hashtable<String, IntHolder>();
89              
90          for (String query : queries) {
91              queryProcessingTime.put(query + " " +  PROCESSING_TIME, new LongHolder());
92              totalQueryCounter.put(query + " " + TOTAL_QUERIES, new IntHolder());
93              successQueryCounter.put(query + " " + SUCCESSFUL_QUERIES, new IntHolder());
94              faultQueryCounter.put(query + " " + FAILED_QUERIES, new IntHolder());
95          }
96          
97          totalApiCounter = 0;
98          successApiCounter = 0;
99          faultApiCounter = 0;
100 
101     }
102     
103     protected void registerMBean() {
104         MBeanServer mbeanServer = null;
105         
106         mbeanServer = getServer();
107         if (mbeanServer == null) {
108             try {
109 //                mbeanServer = MBeanServerLocator.locateJBoss();
110             } catch (IllegalStateException ise) {
111                 // If we can't find a JBoss MBeanServer, just return
112                 // Needed for unit tests
113                 return;
114             }            
115         }
116         
117         try {
118         	if (! mbeanServer.isRegistered(listObjectName))
119         		mbeanServer.registerMBean(this, listObjectName);
120         } catch (InstanceAlreadyExistsException e) {
121             log.warn("", e);
122         } catch (MBeanRegistrationException e) {
123             log.warn("", e);
124         } catch (NotCompliantMBeanException e) {
125             log.warn("", e);
126         }   
127     }
128         
129     private MBeanServer getServer() {
130         MBeanServer mbserver = null;
131 
132         ArrayList mbservers = MBeanServerFactory.findMBeanServer(null);
133 
134         if (mbservers.size() > 0) {
135           mbserver = (MBeanServer) mbservers.get(0);
136         }
137 
138         if (mbserver != null) {
139 	  log.info("Found MBean server");
140         } else {
141           mbserver = MBeanServerFactory.createMBeanServer();
142         } 
143 
144         return mbserver;
145     }
146     
147     public void resetCounts() {
148         for (String key : queryProcessingTime.keySet()) {
149             queryProcessingTime.put(key, new LongHolder());
150         }
151         
152         for (String key : totalQueryCounter.keySet()) {
153             totalQueryCounter.put(key, new IntHolder());
154         }
155         
156         for (String key : successQueryCounter.keySet()) {
157             successQueryCounter.put(key, new IntHolder());
158         }
159         
160         for (String key : faultQueryCounter.keySet()) {
161             faultQueryCounter.put(key, new IntHolder());
162         }
163         
164         totalApiCounter = 0;
165         successApiCounter = 0;
166         faultApiCounter = 0;
167 
168     }
169 
170     /**
171      * This updates the performance metrics for a given service.
172      * 
173      * Note, as of jUDDI 3.2, procTime MUST be in milliseconds. Prior to 3.2 used nanoseconds
174      * @param queryObject the item that was executed
175      * @param queryStatus success or fail status
176      * @param procTime Expects time in milliseconds
177      */
178     public synchronized void update(UDDIQuery queryObject, QueryStatus queryStatus, 
179             long procTime) {        
180         //log.info("Updating " + queryObject.getQuery() + " time " + procTime);
181         String query = queryObject.getQuery();
182         
183         LongHolder totalProcTime = queryProcessingTime.get(query + " " +  PROCESSING_TIME);
184         if (totalProcTime != null) {
185             totalProcTime.value += procTime;
186             totalApiCounter++;
187         } else {
188             throw new RuntimeException("Exception in Update : " + queryObject.getQuery() 
189                     + " time " + procTime + " queryprocessingtime.size() + "
190                     + queryProcessingTime.size());
191         }
192         
193         IntHolder queryCounter = totalQueryCounter.get(query + " " + TOTAL_QUERIES);
194         if (queryCounter != null) { 
195             queryCounter.value++;
196         } else {
197             throw new RuntimeException("Exception in Update : " + queryObject.getQuery() 
198                     + " time " + procTime + " totalQueryCounter.size() + "
199                     + totalQueryCounter.size());
200         }
201 
202         if (queryStatus == QueryStatus.SUCCESS) {
203             IntHolder successQuery = successQueryCounter.get(query + " " + SUCCESSFUL_QUERIES);
204             if (successQuery != null) {
205                 successQuery.value++;
206                 successApiCounter++;
207             } else {
208                 throw new RuntimeException("Exception in Update : " + queryObject.getQuery() 
209                         + " time " + procTime + " successQueryCounter.size() "
210                         + successQueryCounter.size());
211             }
212         } else if (queryStatus == queryStatus.FAILED) {
213             IntHolder faultQuery = faultQueryCounter.get(query + " " + FAILED_QUERIES);
214             if (faultQuery != null) {
215                 faultQuery.value++;
216                 faultApiCounter++;
217             } else {
218                 throw new RuntimeException("Exception in Update : " + queryObject.getQuery() 
219                         + " time " + procTime + " faultQueryCounter.size() "
220                         + faultQueryCounter.size());
221             }            
222         }        
223     }
224     
225     @Override
226     public Object getAttribute(String attribute)
227             throws AttributeNotFoundException, MBeanException,
228             ReflectionException {
229         if (queryProcessingTime.containsKey(attribute)) {
230             return queryProcessingTime.get(attribute);
231         } else if (totalQueryCounter.containsKey(attribute)) {
232             return totalQueryCounter.get(attribute);
233         } else if (successQueryCounter.containsKey(attribute)) {
234             return successQueryCounter.get(attribute);
235         } else if (faultQueryCounter.containsKey(attribute)) {
236             return faultQueryCounter.get(attribute);
237         } else if (attribute.equals(TOTAL_API_QUERIES)) {
238             return totalApiCounter;
239         } else if (attribute.equals(SUCCESSFUL_API_QUERIES)) {
240             return successApiCounter;
241         } else if (attribute.equals(FAILED_API_QUERIES)) {
242             return faultApiCounter;
243         }
244         return null;
245     }
246 
247     @Override
248     public void setAttribute(Attribute attribute)
249             throws AttributeNotFoundException, InvalidAttributeValueException,
250             MBeanException, ReflectionException {
251         
252     }
253 
254     @Override
255     public AttributeList getAttributes(String[] attributes) {
256         AttributeList attributeList = new AttributeList();
257 
258         attributeList.add(new Attribute(TOTAL_API_QUERIES, totalApiCounter));
259         attributeList.add(new Attribute(SUCCESSFUL_API_QUERIES, successApiCounter));
260         attributeList.add(new Attribute(FAILED_API_QUERIES, faultApiCounter));
261 
262         for (String key : queryProcessingTime.keySet()) {
263             Attribute at = new Attribute(key, queryProcessingTime.get(key).toString());
264             attributeList.add(at);
265         }
266                 
267         for (String key : totalQueryCounter.keySet()) {
268             Attribute at = new Attribute(key, totalQueryCounter.get(key).toString());
269             attributeList.add(at);
270         }
271         
272         for (String key : successQueryCounter.keySet()) {
273             Attribute at = new Attribute(key, successQueryCounter.get(key).toString());
274             attributeList.add(at);
275         }
276 
277         for (String key : faultQueryCounter.keySet()) {
278             Attribute at = new Attribute(key, faultQueryCounter.get(key).toString());
279             attributeList.add(at);
280         }
281         
282         return attributeList;
283     }
284 
285     @Override
286     public AttributeList setAttributes(AttributeList attributes) {
287         return null;
288     }
289 
290     @Override
291     public Object invoke(String actionName, Object[] params, String[] signature)
292             throws MBeanException, ReflectionException {
293         if (actionName.equalsIgnoreCase(RESET_COUNTER)) {
294             resetCounts();
295             return "Invoking the " + actionName + " on the lifecycle.";
296         } else {
297             throw new ReflectionException(new NoSuchMethodException(actionName));
298         }
299     }
300 
301     @Override
302     public MBeanInfo getMBeanInfo() {
303         // the extra 3 added are for totalApiQueries, faultApiQueries, and
304         // successfulApiQueries
305         int count = queryProcessingTime.size() + totalQueryCounter.size() +
306             successQueryCounter.size() + faultQueryCounter.size() + 3;  
307 
308         MBeanAttributeInfo[] attrs = new MBeanAttributeInfo[count];
309         int counter = 0;
310 
311         attrs[counter] = new MBeanAttributeInfo(
312                 TOTAL_API_QUERIES, "java.lang.Integer", "Property " + TOTAL_API_QUERIES,
313                 true, false, false);
314         counter++;
315         
316         attrs[counter] = new MBeanAttributeInfo(
317                 SUCCESSFUL_API_QUERIES, "java.lang.Integer", "Property " + SUCCESSFUL_API_QUERIES,
318                 true, false, false);
319         counter++;
320         
321         attrs[counter] =  new MBeanAttributeInfo(
322                 FAILED_API_QUERIES, "java.lang.Integer", "Property " + FAILED_API_QUERIES,
323                 true, false, false);
324         counter++;
325         
326         for (String key : queryProcessingTime.keySet()) {
327             attrs[counter] = new MBeanAttributeInfo(
328                     key, "java.lang.Double", "Property " + key, true, false, false);
329             counter++;
330         }
331 
332         for (String key : totalQueryCounter.keySet()) {
333             attrs[counter] = new MBeanAttributeInfo(
334                     key, "java.lang.Integer", "Property " + key, true, false, false);
335             counter++;
336         }
337 
338         for (String key : successQueryCounter.keySet()) {
339             attrs[counter] = new MBeanAttributeInfo(
340                     key, "java.lang.Integer", "Property " + key, true, false, false);
341             counter++;
342         }
343 
344         for (String key : faultQueryCounter.keySet()) {
345             attrs[counter] = new MBeanAttributeInfo(
346                     key, "java.lang.Integer", "Property " + key, true, false, false);
347             counter++;
348         }
349         
350         MBeanOperationInfo[] opers = {
351                 new MBeanOperationInfo(
352                         RESET_COUNTER, "Reset the counter",
353                         null, "void", MBeanOperationInfo.ACTION)
354         };        
355         
356         return new MBeanInfo(this.getClass().getName(), "Service Counter MBean", 
357                 attrs, null, opers, null);
358     }
359     
360     private static final class IntHolder implements Serializable
361     {
362             int value ;
363             @Override
364             public String toString() {
365                     return Integer.toString(value);
366             }
367     }
368 
369     private static final class LongHolder implements Serializable
370     {
371             long value ;
372             @Override
373             public String toString() {
374                     return Long.toString(value);
375             }
376     }
377 }