You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2011/11/04 11:19:12 UTC

svn commit: r1197486 - in /camel/trunk: camel-core/src/main/java/org/apache/camel/management/ components/camel-jms/src/test/java/org/apache/camel/component/jms/

Author: davsclaus
Date: Fri Nov  4 10:19:11 2011
New Revision: 1197486

URL: http://svn.apache.org/viewvc?rev=1197486&view=rev
Log:
CAMEL-4615: Default mbean assembler should mixin JMX methods/attributes from the default ManagedXXX mbeans and any custom instance which may have additional JMX annotations. Use Set instead of List to avoid duplicates.

Added:
    camel/trunk/components/camel-jms/src/test/java/org/apache/camel/component/jms/ManagedJmsEndpointTest.java
Modified:
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementMBeanAssembler.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/MBeanInfoAssembler.java

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementMBeanAssembler.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementMBeanAssembler.java?rev=1197486&r1=1197485&r2=1197486&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementMBeanAssembler.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementMBeanAssembler.java Fri Nov  4 10:19:11 2011
@@ -50,22 +50,23 @@ public class DefaultManagementMBeanAssem
     public ModelMBean assemble(MBeanServer mBeanServer, Object obj, ObjectName name) throws JMException {
         ModelMBeanInfo mbi = null;
 
-        // prefer to use the managed instance if it has been annotated with Spring JMX annotations
+        // prefer to use the managed instance if it has been annotated with JMX annotations
         if (obj instanceof ManagedInstance) {
+            // there may be a custom embedded instance which have additional methods
             Object custom = ((ManagedInstance) obj).getInstance();
             if (custom != null && ObjectHelper.hasAnnotation(custom.getClass().getAnnotations(), ManagedResource.class)) {
                 log.trace("Assembling MBeanInfo for: {} from custom @ManagedResource object: {}", name, custom);
                 // get the mbean info from the custom managed object
-                mbi = assembler.getMBeanInfo(custom, name.toString());
+                mbi = assembler.getMBeanInfo(obj, custom, name.toString());
                 // and let the custom object be registered in JMX
                 obj = custom;
             }
         }
 
         if (mbi == null) {
-            // use the default provided mbean which has been annotated with Spring JMX annotations
+            // use the default provided mbean which has been annotated with JMX annotations
             log.trace("Assembling MBeanInfo for: {} from @ManagedResource object: {}", name, obj);
-            mbi = assembler.getMBeanInfo(obj, name.toString());
+            mbi = assembler.getMBeanInfo(obj, null, name.toString());
         }
 
         RequiredModelMBean mbean = (RequiredModelMBean) mBeanServer.instantiate(RequiredModelMBean.class.getName());

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/management/MBeanInfoAssembler.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/management/MBeanInfoAssembler.java?rev=1197486&r1=1197485&r2=1197486&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/management/MBeanInfoAssembler.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/management/MBeanInfoAssembler.java Fri Nov  4 10:19:11 2011
@@ -17,10 +17,10 @@
 package org.apache.camel.management;
 
 import java.lang.reflect.Method;
-import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.List;
+import java.util.LinkedHashSet;
 import java.util.Map;
+import java.util.Set;
 import javax.management.Descriptor;
 import javax.management.IntrospectionException;
 import javax.management.JMException;
@@ -51,28 +51,37 @@ public class MBeanInfoAssembler {
     /**
      * Gets the {@link ModelMBeanInfo} for the given managed bean
      *
-     * @param managedBean  the managed bean
+     * @param defaultManagedBean  the default managed bean
+     * @param customManagedBean   an optional custom managed bean
      * @param objectName   the object name
      * @return the model info
      * @throws JMException is thrown if error creating the model info
      */
-    public ModelMBeanInfo getMBeanInfo(Object managedBean, String objectName) throws JMException {
+    public ModelMBeanInfo getMBeanInfo(Object defaultManagedBean, Object customManagedBean, String objectName) throws JMException {
         // maps and lists to contain information about attributes and operations
         Map<String, ManagedAttributeInfo> attributes = new HashMap<String, ManagedAttributeInfo>();
-        List<ManagedOperationInfo> operations = new ArrayList<ManagedOperationInfo>();
-        List<ModelMBeanAttributeInfo> mBeanAttributes = new ArrayList<ModelMBeanAttributeInfo>();
-        List<ModelMBeanOperationInfo> mBeanOperations = new ArrayList<ModelMBeanOperationInfo>();
-        
-
-        // extract details
-        extractAttributesAndOperations(managedBean, attributes, operations);
-        extractMbeanAttributes(managedBean, attributes, mBeanAttributes, mBeanOperations);
-        extractMbeanOperations(managedBean, operations, mBeanOperations);
-        List<ModelMBeanNotificationInfo> mBeanNotifications = extractMbeanNotifiations(managedBean);
+        Set<ManagedOperationInfo> operations = new LinkedHashSet<ManagedOperationInfo>();
+        Set<ModelMBeanAttributeInfo> mBeanAttributes = new LinkedHashSet<ModelMBeanAttributeInfo>();
+        Set<ModelMBeanOperationInfo> mBeanOperations = new LinkedHashSet<ModelMBeanOperationInfo>();
+        Set<ModelMBeanNotificationInfo> mBeanNotifications = new LinkedHashSet<ModelMBeanNotificationInfo>();
+
+        // extract details from default managed bean
+        extractAttributesAndOperations(defaultManagedBean, attributes, operations);
+        extractMbeanAttributes(defaultManagedBean, attributes, mBeanAttributes, mBeanOperations);
+        extractMbeanOperations(defaultManagedBean, operations, mBeanOperations);
+        extractMbeanNotifications(defaultManagedBean, mBeanNotifications);
+
+        // extract details from custom managed bean
+        if (customManagedBean != null) {
+            extractAttributesAndOperations(customManagedBean, attributes, operations);
+            extractMbeanAttributes(customManagedBean, attributes, mBeanAttributes, mBeanOperations);
+            extractMbeanOperations(customManagedBean, operations, mBeanOperations);
+            extractMbeanNotifications(customManagedBean, mBeanNotifications);
+        }
 
         // create the ModelMBeanInfo
-        String name = getName(managedBean, objectName);
-        String description = getDescription(managedBean, objectName);
+        String name = getName(customManagedBean != null ? customManagedBean : defaultManagedBean, objectName);
+        String description = getDescription(customManagedBean != null ? customManagedBean : defaultManagedBean, objectName);
         ModelMBeanAttributeInfo[] arrayAttributes = mBeanAttributes.toArray(new ModelMBeanAttributeInfo[mBeanAttributes.size()]);
         ModelMBeanOperationInfo[] arrayOperations = mBeanOperations.toArray(new ModelMBeanOperationInfo[mBeanOperations.size()]);
         ModelMBeanNotificationInfo[] arrayNotifications = mBeanNotifications.toArray(new ModelMBeanNotificationInfo[mBeanNotifications.size()]);
@@ -82,19 +91,9 @@ public class MBeanInfoAssembler {
         return info;
     }
 
-    private List<ModelMBeanNotificationInfo> extractMbeanNotifiations(Object managedBean) {
-        List<ModelMBeanNotificationInfo> mBeanNotifications = new ArrayList<ModelMBeanNotificationInfo>();
-        ManagedNotifications notifications = managedBean.getClass().getAnnotation(ManagedNotifications.class);
-        if (notifications != null) {
-            for (ManagedNotification notification : notifications.value()) {
-                mBeanNotifications.add(new ModelMBeanNotificationInfo(notification.notificationTypes(), notification.name(), notification.description()));
-            }
-        }
-        return mBeanNotifications;
-    }
-
-    private void extractAttributesAndOperations(Object managedBean, Map<String, ManagedAttributeInfo> attributes, List<ManagedOperationInfo> operations) {
+    private void extractAttributesAndOperations(Object managedBean, Map<String, ManagedAttributeInfo> attributes, Set<ManagedOperationInfo> operations) {
         for (Method method : managedBean.getClass().getMethods()) {
+            LOG.trace("Extracting attributes and operations from method: {}", method);
 
             ManagedAttribute ma = method.getAnnotation(ManagedAttribute.class);
             if (ma != null) {
@@ -142,7 +141,7 @@ public class MBeanInfoAssembler {
     }
 
     private void extractMbeanAttributes(Object managedBean, Map<String, ManagedAttributeInfo> attributes,
-                                        List<ModelMBeanAttributeInfo> mBeanAttributes, List<ModelMBeanOperationInfo> mBeanOperations) throws IntrospectionException {
+                                        Set<ModelMBeanAttributeInfo> mBeanAttributes, Set<ModelMBeanOperationInfo> mBeanOperations) throws IntrospectionException {
 
         for (ManagedAttributeInfo info : attributes.values()) {
             ModelMBeanAttributeInfo mbeanAttribute = new ModelMBeanAttributeInfo(info.getKey(), info.getDescription(), info.getGetter(), info.getSetter());
@@ -168,7 +167,7 @@ public class MBeanInfoAssembler {
         }
     }
 
-    private void extractMbeanOperations(Object managedBean, List<ManagedOperationInfo> operations, List<ModelMBeanOperationInfo> mBeanOperations) {
+    private void extractMbeanOperations(Object managedBean, Set<ManagedOperationInfo> operations, Set<ModelMBeanOperationInfo> mBeanOperations) {
         for (ManagedOperationInfo info : operations) {
             ModelMBeanOperationInfo mbean = new ModelMBeanOperationInfo(info.getDescription(), info.getOperation());
             mBeanOperations.add(mbean);
@@ -176,6 +175,17 @@ public class MBeanInfoAssembler {
         }
     }
 
+    private void extractMbeanNotifications(Object managedBean, Set<ModelMBeanNotificationInfo> mBeanNotifications) {
+        ManagedNotifications notifications = managedBean.getClass().getAnnotation(ManagedNotifications.class);
+        if (notifications != null) {
+            for (ManagedNotification notification : notifications.value()) {
+                ModelMBeanNotificationInfo info = new ModelMBeanNotificationInfo(notification.notificationTypes(), notification.name(), notification.description());
+                mBeanNotifications.add(info);
+                LOG.trace("Assembled notification: {}", info);
+            }
+        }
+    }
+
     private String getDescription(Object managedBean, String objectName) {
         ManagedResource mr = ObjectHelper.getAnnotation(managedBean, ManagedResource.class);
         return mr != null ? mr.description() : "";

Added: camel/trunk/components/camel-jms/src/test/java/org/apache/camel/component/jms/ManagedJmsEndpointTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jms/src/test/java/org/apache/camel/component/jms/ManagedJmsEndpointTest.java?rev=1197486&view=auto
==============================================================================
--- camel/trunk/components/camel-jms/src/test/java/org/apache/camel/component/jms/ManagedJmsEndpointTest.java (added)
+++ camel/trunk/components/camel-jms/src/test/java/org/apache/camel/component/jms/ManagedJmsEndpointTest.java Fri Nov  4 10:19:11 2011
@@ -0,0 +1,100 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.jms;
+
+import javax.jms.ConnectionFactory;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.management.DefaultManagementNamingStrategy;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+
+import static org.apache.camel.component.jms.JmsComponent.jmsComponentAutoAcknowledge;
+
+/**
+ *
+ */
+public class ManagedJmsEndpointTest extends CamelTestSupport {
+
+    @Override
+    protected boolean useJmx() {
+        return true;
+    }
+
+    protected CamelContext createCamelContext() throws Exception {
+        CamelContext context = new DefaultCamelContext();
+        DefaultManagementNamingStrategy naming = (DefaultManagementNamingStrategy) context.getManagementStrategy().getManagementNamingStrategy();
+        naming.setHostName("localhost");
+        naming.setDomainName("org.apache.camel");
+
+        ConnectionFactory connectionFactory = CamelJmsTestHelper.createConnectionFactory();
+        context.addComponent("activemq", jmsComponentAutoAcknowledge(connectionFactory));
+
+        return context;
+    }
+
+    protected MBeanServer getMBeanServer() {
+        return context.getManagementStrategy().getManagementAgent().getMBeanServer();
+    }
+
+    @Test
+    public void testJmsEndpoint() throws Exception {
+        MBeanServer mbeanServer = getMBeanServer();
+
+        ObjectName name = ObjectName.getInstance("org.apache.camel:context=localhost/camel-1,type=endpoints,name=\"activemq://queue:start\"");
+        String uri = (String) mbeanServer.getAttribute(name, "EndpointUri");
+        assertEquals("activemq://queue:start", uri);
+
+        Boolean singleton = (Boolean) mbeanServer.getAttribute(name, "Singleton");
+        assertTrue(singleton.booleanValue());
+
+        Long size = (Long) mbeanServer.invoke(name, "queueSize", null, null);
+        assertEquals(0, size.intValue());
+
+        getMockEndpoint("mock:result").expectedMessageCount(2);
+
+        template.sendBody("activemq:queue:start", "Hello World");
+        template.sendBody("activemq:queue:start", "Bye World");
+
+        assertMockEndpointsSatisfied();
+
+        // stop route
+        context.stopRoute("foo");
+
+        // send a message to queue
+        template.sendBody("activemq:queue:start", "Hi World");
+
+        size = (Long) mbeanServer.invoke(name, "queueSize", null, null);
+        assertEquals(1, size.intValue());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("activemq:queue:start").routeId("foo").to("log:foo").to("mock:result");
+            }
+        };
+    }
+
+
+}