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");
+            }
+        };
+    }
+
+
+}


Reply via email to