Author: davsclaus
Date: Mon Dec  6 08:02:24 2010
New Revision: 1042541

URL: http://svn.apache.org/viewvc?rev=1042541&view=rev
Log:
CAMEL-3279, CAMEL-3392: Improved JMX. Any processor used in the route DSL will 
be managed. Allow custom Processor to be ManagementAware and expose its own set 
of attributes/operations with Spring JMX annotations, and have those enlisted 
instead of the default ManagedProcessor mbean. Using node id for ObjectName for 
managed processor.

Added:
    
camel/trunk/camel-core/src/main/java/org/apache/camel/management/JmxMBeanAssembler.java
    
camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCustomProcessor.java
    
camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedCustomProcessorTest.java
Modified:
    
camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementAgent.java
    
camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementLifecycleStrategy.java
    
camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementNamingStrategy.java
    
camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessDefinition.java
    
camel/trunk/camel-core/src/main/java/org/apache/camel/util/IntrospectionSupport.java
    
camel/trunk/camel-core/src/test/java/org/apache/camel/builder/RouteBuilderTest.java
    
camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationCustomMBeanTest.java
    
camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationUsingDefaultsTest.java
    
camel/trunk/camel-core/src/test/java/org/apache/camel/management/MultiInstanceProcessorTest.java
    
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/TraceInterceptorFactoryCreatesHandlerTest.java
    
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/TraceInterceptorSubclassFactory.java
    
camel/trunk/camel-core/src/test/java/org/apache/camel/util/IntrospectionSupportTest.java
    camel/trunk/examples/pom.xml

Modified: 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementAgent.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementAgent.java?rev=1042541&r1=1042540&r2=1042541&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementAgent.java
 (original)
+++ 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementAgent.java
 Mon Dec  6 08:02:24 2010
@@ -32,9 +32,6 @@ import javax.management.MBeanServerFacto
 import javax.management.NotCompliantMBeanException;
 import javax.management.ObjectInstance;
 import javax.management.ObjectName;
-import javax.management.modelmbean.InvalidTargetObjectTypeException;
-import javax.management.modelmbean.ModelMBeanInfo;
-import javax.management.modelmbean.RequiredModelMBean;
 import javax.management.remote.JMXConnectorServer;
 import javax.management.remote.JMXConnectorServerFactory;
 import javax.management.remote.JMXServiceURL;
@@ -46,8 +43,6 @@ import org.apache.camel.spi.ManagementAg
 import org.apache.camel.util.ObjectHelper;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource;
-import org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler;
 
 /**
  * Default implementation of the Camel JMX service agent
@@ -65,7 +60,7 @@ public class DefaultManagementAgent exte
     private ExecutorService executorService;
     private MBeanServer server;
     private final Set<ObjectName> mbeansRegistered = new HashSet<ObjectName>();
-    private MetadataMBeanInfoAssembler assembler;
+    private JmxMBeanAssembler assembler;
     private JMXConnectorServer cs;
 
     private Integer registryPort;
@@ -216,15 +211,8 @@ public class DefaultManagementAgent exte
             registerMBeanWithServer(obj, name, forceRegistration);
         } catch (NotCompliantMBeanException e) {
             // If this is not a "normal" MBean, then try to deploy it using 
JMX annotations
-            ModelMBeanInfo mbi;
-            mbi = assembler.getMBeanInfo(obj, name.toString());
-            RequiredModelMBean mbean = 
(RequiredModelMBean)server.instantiate(RequiredModelMBean.class.getName());
-            mbean.setModelMBeanInfo(mbi);
-            try {
-                mbean.setManagedResource(obj, "ObjectReference");
-            } catch (InvalidTargetObjectTypeException itotex) {
-                throw new JMException(itotex.getMessage());
-            }
+            Object mbean = assembler.assemble(obj, name);
+            // and register the mbean
             registerMBeanWithServer(mbean, name, forceRegistration);
         }
     }
@@ -245,8 +233,6 @@ public class DefaultManagementAgent exte
 
     protected void doStart() throws Exception {
         ObjectHelper.notNull(camelContext, "CamelContext");
-        assembler = new MetadataMBeanInfoAssembler();
-        assembler.setAttributeSource(new AnnotationJmxAttributeSource());
 
         // create mbean server if is has not be injected.
         if (server == null) {
@@ -254,6 +240,8 @@ public class DefaultManagementAgent exte
             createMBeanServer();
         }
 
+        assembler = new JmxMBeanAssembler(server);
+
         if (LOG.isDebugEnabled()) {
             LOG.debug("Starting JMX agent on server: " + getMBeanServer());
         }

Modified: 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementLifecycleStrategy.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementLifecycleStrategy.java?rev=1042541&r1=1042540&r2=1042541&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementLifecycleStrategy.java
 (original)
+++ 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementLifecycleStrategy.java
 Mon Dec  6 08:02:24 2010
@@ -28,6 +28,7 @@ import javax.management.ObjectName;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.CamelContextAware;
+import org.apache.camel.Channel;
 import org.apache.camel.Component;
 import org.apache.camel.Consumer;
 import org.apache.camel.Endpoint;
@@ -48,6 +49,7 @@ import org.apache.camel.management.mbean
 import org.apache.camel.management.mbean.ManagedCamelContext;
 import org.apache.camel.management.mbean.ManagedComponent;
 import org.apache.camel.management.mbean.ManagedConsumer;
+import org.apache.camel.management.mbean.ManagedCustomProcessor;
 import org.apache.camel.management.mbean.ManagedDelayer;
 import org.apache.camel.management.mbean.ManagedEndpoint;
 import org.apache.camel.management.mbean.ManagedErrorHandler;
@@ -73,9 +75,12 @@ import org.apache.camel.model.PolicyDefi
 import org.apache.camel.model.ProcessorDefinition;
 import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.processor.Delayer;
+import org.apache.camel.processor.DelegateAsyncProcessor;
+import org.apache.camel.processor.DelegateProcessor;
 import org.apache.camel.processor.ErrorHandler;
 import org.apache.camel.processor.SendProcessor;
 import org.apache.camel.processor.Throttler;
+import org.apache.camel.processor.WrapProcessor;
 import org.apache.camel.processor.interceptor.Tracer;
 import org.apache.camel.spi.BrowsableEndpoint;
 import org.apache.camel.spi.CamelContextNameStrategy;
@@ -84,6 +89,7 @@ import org.apache.camel.spi.LifecycleStr
 import org.apache.camel.spi.ManagementAware;
 import org.apache.camel.spi.ManagementStrategy;
 import org.apache.camel.spi.RouteContext;
+import org.apache.camel.spi.UnitOfWork;
 import org.apache.camel.util.KeyValueHolder;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.commons.logging.Log;
@@ -371,6 +377,11 @@ public class DefaultManagementLifecycleS
 
     @SuppressWarnings("unchecked")
     private Object getManagedObjectForService(CamelContext context, Service 
service, Route route) {
+        // skip channel, UoW and dont double wrap instrumentation
+        if (service instanceof Channel || service instanceof UnitOfWork || 
service instanceof InstrumentationProcessor) {
+            return null;
+        }
+
         ManagedService answer = null;
 
         if (service instanceof ManagementAware) {
@@ -440,20 +451,46 @@ public class DefaultManagementLifecycleS
         return managedObject;
     }
 
+    @SuppressWarnings("unchecked")
     private Object createManagedObjectForProcessor(CamelContext context, 
Processor processor,
                                                    ProcessorDefinition 
definition, Route route) {
-        // skip error handlers
-        if (processor instanceof ErrorHandler) {
-            return false;
-        }
-
         ManagedProcessor answer = null;
-        if (processor instanceof Delayer) {
-            answer = new ManagedDelayer(context, (Delayer) processor, 
definition);
-        } else if (processor instanceof Throttler) {
-            answer = new ManagedThrottler(context, (Throttler) processor, 
definition);
-        } else if (processor instanceof SendProcessor) {
-            answer = new ManagedSendProcessor(context, (SendProcessor) 
processor, definition);
+
+        // unwrap delegates as we want the real target processor
+        Processor target = processor;
+        while (target != null) {
+
+            // skip error handlers
+            if (target instanceof ErrorHandler) {
+                return false;
+            }
+
+            // look for specialized processor which we should prefer to use
+            if (target instanceof Delayer) {
+                answer = new ManagedDelayer(context, (Delayer) target, 
definition);
+            } else if (target instanceof Throttler) {
+                answer = new ManagedThrottler(context, (Throttler) target, 
definition);
+            } else if (target instanceof SendProcessor) {
+                answer = new ManagedSendProcessor(context, (SendProcessor) 
target, definition);
+            } else if (target instanceof ManagementAware) {
+                Object managedObject = ((ManagementAware) 
target).getManagedObject(processor);
+                answer = new ManagedCustomProcessor(context, managedObject, 
target, definition);
+            }
+
+            if (answer != null) {
+                // break out as we found an answer
+                break;
+            }
+
+            // no answer yet, so unwrap any delegates and try again
+            if (target instanceof DelegateProcessor) {
+                target = ((DelegateProcessor) target).getProcessor();
+            } else if (target instanceof DelegateAsyncProcessor) {
+                target = ((DelegateAsyncProcessor) target).getProcessor();
+            } else {
+                // no delegate so we dont have any target to try next
+                target = null;
+            }
         }
 
         if (answer == null) {

Modified: 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementNamingStrategy.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementNamingStrategy.java?rev=1042541&r1=1042540&r2=1042541&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementNamingStrategy.java
 (original)
+++ 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementNamingStrategy.java
 Mon Dec  6 08:02:24 2010
@@ -119,17 +119,7 @@ public class DefaultManagementNamingStra
         buffer.append(domainName).append(":");
         buffer.append(KEY_CONTEXT + 
"=").append(getContextId(context)).append(",");
         buffer.append(KEY_TYPE + "=").append(TYPE_PROCESSOR).append(",");
-
-        if (definition.hasCustomIdAssigned()) {
-            // use id in name
-            String nodeId = definition.getId();
-            buffer.append(KEY_NAME + "=").append(ObjectName.quote(nodeId));
-        } else {
-            // create a name based on its instance
-            buffer.append(KEY_NAME + "=")
-                .append(processor.getClass().getSimpleName())
-                
.append("(").append(ObjectHelper.getIdentityHashCode(processor)).append(")");
-        }
+        buffer.append(KEY_NAME + 
"=").append(ObjectName.quote(definition.getId()));
         return createObjectName(buffer);
     }
 

Added: 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/JmxMBeanAssembler.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/management/JmxMBeanAssembler.java?rev=1042541&view=auto
==============================================================================
--- 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/JmxMBeanAssembler.java
 (added)
+++ 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/JmxMBeanAssembler.java
 Mon Dec  6 08:02:24 2010
@@ -0,0 +1,73 @@
+/**
+ * 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.management;
+
+import javax.management.JMException;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.modelmbean.InvalidTargetObjectTypeException;
+import javax.management.modelmbean.ModelMBeanInfo;
+import javax.management.modelmbean.RequiredModelMBean;
+
+import org.apache.camel.management.mbean.ManagedCustomProcessor;
+import org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource;
+import org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler;
+
+/**
+ * An assembler to assemble a {...@link 
javax.management.modelmbean.RequiredModelMBean} which can be used
+ * to register the object in JMX. The assembler is capable of using the Spring 
JMX annotations to
+ * gather the list of JMX operations and attributes.
+ *
+ * @version $Revision$
+ */
+public class JmxMBeanAssembler {
+
+    private final MetadataMBeanInfoAssembler assembler;
+    private final MBeanServer server;
+
+    public JmxMBeanAssembler(MBeanServer server) {
+        this.server = server;
+        this.assembler = new MetadataMBeanInfoAssembler();
+        this.assembler.setAttributeSource(new AnnotationJmxAttributeSource());
+    }
+
+    public RequiredModelMBean assemble(Object obj, ObjectName name) throws 
JMException {
+        ModelMBeanInfo mbi;
+
+        if (obj instanceof ManagedCustomProcessor) {
+            Object custom = ((ManagedCustomProcessor) obj).getManagedObject();
+            // get the mbean info from the custom managed object
+            mbi = assembler.getMBeanInfo(custom, name.toString());
+            // and let the custom object be registered in JMX
+            obj = custom;
+        } else {
+            mbi = assembler.getMBeanInfo(obj, name.toString());
+        }
+
+        RequiredModelMBean mbean = (RequiredModelMBean) 
server.instantiate(RequiredModelMBean.class.getName());
+        mbean.setModelMBeanInfo(mbi);
+
+        try {
+            mbean.setManagedResource(obj, "ObjectReference");
+        } catch (InvalidTargetObjectTypeException itotex) {
+            throw new JMException(itotex.getMessage());
+        }
+
+        return mbean;
+    }
+
+}

Added: 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCustomProcessor.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCustomProcessor.java?rev=1042541&view=auto
==============================================================================
--- 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCustomProcessor.java
 (added)
+++ 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCustomProcessor.java
 Mon Dec  6 08:02:24 2010
@@ -0,0 +1,42 @@
+/**
+ * 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.management.mbean;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Processor;
+import org.apache.camel.model.ProcessorDefinition;
+
+/**
+ * A managed custom processor is a processor which implements the {...@link 
org.apache.camel.spi.ManagementAware}
+ * interface.
+ *
+ * @version $Revision$
+ */
+public class ManagedCustomProcessor extends ManagedProcessor {
+    private final Object managedObject;
+
+    public ManagedCustomProcessor(CamelContext context, Object managedObject, 
Processor processor,
+                                  ProcessorDefinition<?> definition) {
+        super(context, processor, definition);
+        this.managedObject = managedObject;
+    }
+
+    public Object getManagedObject() {
+        return managedObject;
+    }
+
+}

Modified: 
camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessDefinition.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessDefinition.java?rev=1042541&r1=1042540&r2=1042541&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessDefinition.java
 (original)
+++ 
camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessDefinition.java
 Mon Dec  6 08:02:24 2010
@@ -23,6 +23,8 @@ import javax.xml.bind.annotation.XmlRoot
 import javax.xml.bind.annotation.XmlTransient;
 
 import org.apache.camel.Processor;
+import org.apache.camel.Service;
+import org.apache.camel.processor.WrapProcessor;
 import org.apache.camel.spi.RouteContext;
 import org.apache.camel.util.ObjectHelper;
 
@@ -84,6 +86,12 @@ public class ProcessDefinition extends O
             processor = routeContext.lookup(getRef(), Processor.class);
             ObjectHelper.notNull(processor, "registry entry called " + 
getRef(), this);
         }
+
+        // ensure its wrapped in a Service so we can manage it from eg. JMX
+        // (a Processor must be a Service to be enlisted in JMX)
+        if (!(processor instanceof Service)) {
+            processor = new WrapProcessor(processor, processor);
+        }
         return processor;
     }
 }

Modified: 
camel/trunk/camel-core/src/main/java/org/apache/camel/util/IntrospectionSupport.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/util/IntrospectionSupport.java?rev=1042541&r1=1042540&r2=1042541&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/main/java/org/apache/camel/util/IntrospectionSupport.java
 (original)
+++ 
camel/trunk/camel-core/src/main/java/org/apache/camel/util/IntrospectionSupport.java
 Mon Dec  6 08:02:24 2010
@@ -219,6 +219,16 @@ public final class IntrospectionSupport 
         }
     }
 
+    public static Method getPropertySetter(Class<?> type, String propertyName) 
throws NoSuchMethodException {
+        String name = "set" + ObjectHelper.capitalize(propertyName);
+        for (Method method : type.getMethods()) {
+            if (isSetter(method) && method.getName().equals(name)) {
+                return method;
+            }
+        }
+        throw new NoSuchMethodException(type.getCanonicalName() + "." + name);
+    }
+
     public static boolean isPropertyIsGetter(Class<?> type, String 
propertyName) {
         try {
             Method method = type.getMethod("is" + 
ObjectHelper.capitalize(propertyName));

Modified: 
camel/trunk/camel-core/src/test/java/org/apache/camel/builder/RouteBuilderTest.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/builder/RouteBuilderTest.java?rev=1042541&r1=1042540&r2=1042541&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/test/java/org/apache/camel/builder/RouteBuilderTest.java
 (original)
+++ 
camel/trunk/camel-core/src/test/java/org/apache/camel/builder/RouteBuilderTest.java
 Mon Dec  6 08:02:24 2010
@@ -194,10 +194,6 @@ public class RouteBuilderTest extends Te
         for (Route route : routes) {
             Endpoint key = route.getEndpoint();
             assertEquals("From endpoint", "seda://a", key.getEndpointUri());
-            EventDrivenConsumerRoute consumer = 
assertIsInstanceOf(EventDrivenConsumerRoute.class, route);
-            Channel channel = unwrapChannel(consumer.getProcessor());
-
-            assertEquals("Should be called with my processor", myProcessor, 
channel.getNextProcessor());
         }
     }
 
@@ -225,12 +221,6 @@ public class RouteBuilderTest extends Te
         for (Route route : routes) {
             Endpoint key = route.getEndpoint();
             assertEquals("From endpoint", "seda://a", key.getEndpointUri());
-
-            EventDrivenConsumerRoute consumer = 
assertIsInstanceOf(EventDrivenConsumerRoute.class, route);
-            Channel channel = unwrapChannel(consumer.getProcessor());
-
-            FilterProcessor filterProcessor = 
assertIsInstanceOf(FilterProcessor.class, channel.getNextProcessor());
-            assertEquals("Should be called with my processor", myProcessor, 
unwrapChannel(filterProcessor.getProcessor()).getNextProcessor());
         }
     }
 

Modified: 
camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationCustomMBeanTest.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationCustomMBeanTest.java?rev=1042541&r1=1042540&r2=1042541&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationCustomMBeanTest.java
 (original)
+++ 
camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationCustomMBeanTest.java
 Mon Dec  6 08:02:24 2010
@@ -100,7 +100,7 @@ public class JmxInstrumentationCustomMBe
         assertEquals("Could not find 1 context: " + s, 1, s.size());
 
         s = CastUtils.cast(mbsc.queryNames(new ObjectName(domainName + 
":type=processors,*"), null));
-        assertEquals("Could not find 2 processors: " + s, 2, s.size());
+        assertEquals("Could not find 1 processors: " + s, 1, s.size());
 
         s = CastUtils.cast(mbsc.queryNames(new ObjectName(domainName + 
":type=routes,*"), null));
         assertEquals("Could not find 1 route: " + s, 1, s.size());

Modified: 
camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationUsingDefaultsTest.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationUsingDefaultsTest.java?rev=1042541&r1=1042540&r2=1042541&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationUsingDefaultsTest.java
 (original)
+++ 
camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationUsingDefaultsTest.java
 Mon Dec  6 08:02:24 2010
@@ -69,7 +69,7 @@ public class JmxInstrumentationUsingDefa
         assertEquals("Could not find 1 context: " + s, 1, s.size());
 
         s = mbsc.queryNames(new ObjectName(domainName + ":type=processors,*"), 
null);
-        assertEquals("Could not find 2 processors: " + s, 2, s.size());
+        assertEquals("Could not find 1 processors: " + s, 1, s.size());
 
         s = mbsc.queryNames(new ObjectName(domainName + ":type=consumers,*"), 
null);
         assertEquals("Could not find 1 consumers: " + s, 1, s.size());

Added: 
camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedCustomProcessorTest.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedCustomProcessorTest.java?rev=1042541&view=auto
==============================================================================
--- 
camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedCustomProcessorTest.java
 (added)
+++ 
camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedCustomProcessorTest.java
 Mon Dec  6 08:02:24 2010
@@ -0,0 +1,113 @@
+/**
+ * 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.management;
+
+import javax.management.Attribute;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.spi.ManagementAware;
+import org.springframework.jmx.export.annotation.ManagedAttribute;
+import org.springframework.jmx.export.annotation.ManagedResource;
+
+/**
+ * @version $Revision: 950375 $
+ */
+public class ManagedCustomProcessorTest extends ContextTestSupport {
+
+    @Override
+    protected boolean useJmx() {
+        return true;
+    }
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        CamelContext context = super.createCamelContext();
+        DefaultManagementNamingStrategy naming = 
(DefaultManagementNamingStrategy) 
context.getManagementStrategy().getManagementNamingStrategy();
+        naming.setHostName("localhost");
+        naming.setDomainName("org.apache.camel");
+        return context;
+    }
+
+    public void testManageCustomProcessor() throws Exception {
+        MBeanServer mbeanServer = 
context.getManagementStrategy().getManagementAgent().getMBeanServer();
+        ObjectName on = 
ObjectName.getInstance("org.apache.camel:context=localhost/camel-1,type=processors,name=\"custom\"");
+
+        getMockEndpoint("mock:result").expectedMessageCount(1);
+        getMockEndpoint("mock:result").expectedHeaderReceived("foo", "hey");
+        template.sendBody("direct:start", "Hello World");
+        assertMockEndpointsSatisfied();
+
+        String foo = (String) mbeanServer.getAttribute(on, "Foo");
+        assertEquals("hey", foo);
+
+        // change foo
+        mbeanServer.setAttribute(on, new Attribute("Foo", "changed"));
+
+        resetMocks();
+
+        getMockEndpoint("mock:result").expectedMessageCount(1);
+        getMockEndpoint("mock:result").expectedHeaderReceived("foo", 
"changed");
+        template.sendBody("direct:start", "Bye World");
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start").routeId("foo")
+                    .process(new MyCustomProcessor()).id("custom")
+                    .to("mock:result");
+            }
+        };
+    }
+
+    // START SNIPPET: e1
+    @ManagedResource
+    public static class MyCustomProcessor implements 
ManagementAware<Processor>, Processor {
+        private String foo = "hey";
+
+        public Object getManagedObject(Processor object) {
+            // just return this as we use Spring JMX annotations to define 
which attributes/operations
+            // to be enlisted in JMX
+            return this;
+        }
+
+        @ManagedAttribute
+        public String getFoo() {
+            return foo;
+        }
+
+        @ManagedAttribute
+        public void setFoo(String foo) {
+            this.foo = foo;
+        }
+
+        public void process(Exchange exchange) throws Exception {
+            exchange.getIn().setHeader("foo", getFoo());
+        }
+    }
+    // END SNIPPET: e1
+
+}

Modified: 
camel/trunk/camel-core/src/test/java/org/apache/camel/management/MultiInstanceProcessorTest.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/management/MultiInstanceProcessorTest.java?rev=1042541&r1=1042540&r2=1042541&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/test/java/org/apache/camel/management/MultiInstanceProcessorTest.java
 (original)
+++ 
camel/trunk/camel-core/src/test/java/org/apache/camel/management/MultiInstanceProcessorTest.java
 Mon Dec  6 08:02:24 2010
@@ -66,7 +66,7 @@ public class MultiInstanceProcessorTest 
         assertEquals("Could not find 1 context: " + s, 1, s.size());
 
         s = mbsc.queryNames(new ObjectName(domainName + ":type=processors,*"), 
null);
-        assertEquals("Could not find 2 processor: " + s, 2, s.size());
+        assertEquals("Could not find 3 processor: " + s, 3, s.size());
 
         s = mbsc.queryNames(new ObjectName(domainName + ":type=routes,*"), 
null);
         assertEquals("Could not find 1 route: " + s, 1, s.size());

Modified: 
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/TraceInterceptorFactoryCreatesHandlerTest.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/TraceInterceptorFactoryCreatesHandlerTest.java?rev=1042541&r1=1042540&r2=1042541&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/TraceInterceptorFactoryCreatesHandlerTest.java
 (original)
+++ 
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/TraceInterceptorFactoryCreatesHandlerTest.java
 Mon Dec  6 08:02:24 2010
@@ -22,7 +22,9 @@ import java.util.List;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Processor;
 import org.apache.camel.model.ProcessorDefinition;
+import org.apache.camel.processor.DelegateAsyncProcessor;
 import org.apache.camel.processor.DelegateProcessor;
+import org.apache.camel.processor.WrapProcessor;
 
 public class TraceInterceptorFactoryCreatesHandlerTest extends TracingTestBase 
{
 
@@ -38,8 +40,11 @@ public class TraceInterceptorFactoryCrea
         public Processor createTraceInterceptor(ProcessorDefinition node, 
Processor target, TraceFormatter formatter, Tracer tracer) {
             TraceInterceptor interceptor = new TraceInterceptor(node, target, 
formatter, tracer);
 
+            if (target instanceof WrapProcessor) {
+                target = ((WrapProcessor) target).getProcessor();
+            }
             while (target instanceof DelegateProcessor) {
-                target = 
((org.apache.camel.management.InstrumentationProcessor) target).getProcessor();
+                target = ((DelegateProcessor) target).getProcessor();
             }
             if (traceAllNodes || 
!target.getClass().equals(TraceTestProcessor.class)) {
                 TraceHandlerTestHandler traceHandler = new 
TraceHandlerTestHandler(eventMessages);

Modified: 
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/TraceInterceptorSubclassFactory.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/TraceInterceptorSubclassFactory.java?rev=1042541&r1=1042540&r2=1042541&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/TraceInterceptorSubclassFactory.java
 (original)
+++ 
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/TraceInterceptorSubclassFactory.java
 Mon Dec  6 08:02:24 2010
@@ -22,6 +22,7 @@ import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
 import org.apache.camel.model.ProcessorDefinition;
 import org.apache.camel.processor.DelegateProcessor;
+import org.apache.camel.processor.WrapProcessor;
 
 public class TraceInterceptorSubclassFactory implements 
TraceInterceptorFactory {
     private List<StringBuilder> eventMessages;
@@ -53,8 +54,11 @@ public class TraceInterceptorSubclassFac
             super(node, target, formatter, tracer);
             this.eventMessages = eventMessages;
             this.factory = factory;
+            if (target instanceof WrapProcessor) {
+                target = ((WrapProcessor) target).getProcessor();
+            }
             while (target instanceof DelegateProcessor) {
-                target = 
((org.apache.camel.management.InstrumentationProcessor) target).getProcessor();
+                target = ((DelegateProcessor) target).getProcessor();
             }
             if (target.getClass().equals(TraceTestProcessor.class)) {
                 traceThisNode = false;

Modified: 
camel/trunk/camel-core/src/test/java/org/apache/camel/util/IntrospectionSupportTest.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/util/IntrospectionSupportTest.java?rev=1042541&r1=1042540&r2=1042541&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/test/java/org/apache/camel/util/IntrospectionSupportTest.java
 (original)
+++ 
camel/trunk/camel-core/src/test/java/org/apache/camel/util/IntrospectionSupportTest.java
 Mon Dec  6 08:02:24 2010
@@ -162,6 +162,16 @@ public class IntrospectionSupportTest ex
         assertEquals("Claus", name);
     }
 
+    public void testSetProperty() throws Exception {
+        ExampleBean bean = new ExampleBean();
+        bean.setId("123");
+        bean.setName("Claus");
+        bean.setPrice(10.0);
+
+        IntrospectionSupport.setProperty(bean, "name", "James");
+        assertEquals("James", bean.getName());
+    }
+
     public void testAnotherGetProperty() throws Exception {
         AnotherExampleBean bean = new AnotherExampleBean();
         bean.setName("Claus");
@@ -181,7 +191,7 @@ public class IntrospectionSupportTest ex
         assertEquals(Boolean.TRUE, IntrospectionSupport.getProperty(bean, 
"little"));
     }
 
-    public void testGetPropertyLocaleIndependend() throws Exception {
+    public void testGetPropertyLocaleIndependent() throws Exception {
         Locale oldLocale = Locale.getDefault();
         Locale.setDefault(new Locale("tr", "TR"));
 
@@ -210,6 +220,29 @@ public class IntrospectionSupportTest ex
 
         Method name = 
IntrospectionSupport.getPropertyGetter(ExampleBean.class, "name");
         assertEquals("getName", name.getName());
+
+        try {
+            IntrospectionSupport.getPropertyGetter(ExampleBean.class, "xxx");
+            fail("Should have thrown exception");
+        } catch (NoSuchMethodException e) {
+            assertEquals("org.apache.camel.util.jndi.ExampleBean.getXxx()", 
e.getMessage());
+        }
+    }
+
+    public void testGetPropertySetter() throws Exception {
+        ExampleBean bean = new ExampleBean();
+        bean.setName("Claus");
+        bean.setPrice(10.0);
+
+        Method name = 
IntrospectionSupport.getPropertySetter(ExampleBean.class, "name");
+        assertEquals("setName", name.getName());
+
+        try {
+            IntrospectionSupport.getPropertySetter(ExampleBean.class, "xxx");
+            fail("Should have thrown exception");
+        } catch (NoSuchMethodException e) {
+            assertEquals("org.apache.camel.util.jndi.ExampleBean.setXxx", 
e.getMessage());
+        }
     }
 
     public void testIsGetter() throws Exception {

Modified: camel/trunk/examples/pom.xml
URL: 
http://svn.apache.org/viewvc/camel/trunk/examples/pom.xml?rev=1042541&r1=1042540&r2=1042541&view=diff
==============================================================================
--- camel/trunk/examples/pom.xml (original)
+++ camel/trunk/examples/pom.xml Mon Dec  6 08:02:24 2010
@@ -77,14 +77,14 @@
       <repositories>
         <repository>
           <id>dynamic.repo</id>
-          <name>Repository Dynamicly Added Via the Command Line</name>
+          <name>Repository Dynamically Added Via the Command Line</name>
           <url>$remoteRepo</url>
         </repository>
       </repositories>
       <pluginRepositories>
         <pluginRepository>
           <id>dynamic.repo</id>
-          <name>Repository Dynamicly Added Via the Command Line</name>
+          <name>Repository Dynamically Added Via the Command Line</name>
           <url>$remoteRepo</url>
         </pluginRepository>
       </pluginRepositories>


Reply via email to