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 2009/08/25 13:57:55 UTC

svn commit: r807573 [1/3] - in /camel/trunk: camel-core/ camel-core/src/main/java/org/apache/camel/ camel-core/src/main/java/org/apache/camel/component/seda/ camel-core/src/main/java/org/apache/camel/impl/ camel-core/src/main/java/org/apache/camel/mana...

Author: davsclaus
Date: Tue Aug 25 11:57:51 2009
New Revision: 807573

URL: http://svn.apache.org/viewvc?rev=807573&view=rev
Log:
CAMEL-1933: First overhaul of JMX management in Camel. Introduced pluggable API. Much more details in mbeans and more mbeans registered. Also fixed routes not being performance counted correctly before. 

Added:
    camel/trunk/camel-core/src/main/java/org/apache/camel/impl/SimpleLifecycleStrategy.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultEventFactory.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultEventNotifier.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagedLifecycleStrategy.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementStrategy.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/ManagedManagementStrategy.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedBrowsableEndpoint.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedComponent.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedConsumer.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCounter.java   (contents, props changed)
      - copied, changed from r807501, camel/trunk/camel-core/src/main/java/org/apache/camel/management/ManagedCounter.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedDelayer.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedEndpoint.java   (contents, props changed)
      - copied, changed from r807501, camel/trunk/camel-core/src/main/java/org/apache/camel/management/ManagedEndpoint.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedPerformanceCounter.java   (contents, props changed)
      - copied, changed from r807501, camel/trunk/camel-core/src/main/java/org/apache/camel/management/ManagedPerformanceCounter.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedProcessor.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedProducer.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java   (contents, props changed)
      - copied, changed from r807501, camel/trunk/camel-core/src/main/java/org/apache/camel/management/ManagedRoute.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedService.java   (contents, props changed)
      - copied, changed from r807501, camel/trunk/camel-core/src/main/java/org/apache/camel/management/ManagedService.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedThrottler.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/spi/EventFactory.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/spi/EventNotifier.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/spi/ManagementNamingStrategy.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/spi/ManagementStrategy.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/util/EventHelper.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/util/KeyValueHolder.java   (with props)
    camel/trunk/camel-core/src/test/java/org/apache/camel/management/EventNotifierEventsTest.java   (with props)
    camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedBrowseableEndpointTest.java   (with props)
    camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedDelayerTest.java   (with props)
    camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedRegisterCamelContextTest.java   (with props)
    camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedRegisterEndpointTest.java   (with props)
    camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedRegisterExchangeStatisticsTest.java   (with props)
    camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedRegisterRouteTest.java   (with props)
    camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedRegisterTwoRoutesTest.java   (with props)
    camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedRoutePerformanceCounterTest.java   (with props)
    camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedThrottlerTest.java   (with props)
    camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedUnregisterCamelContextTest.java   (with props)
    camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedUnregisterComponentTest.java   (with props)
    camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedUnregisterConsumerTest.java   (with props)
    camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedUnregisterEndpointTest.java   (with props)
    camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedUnregisterRouteTest.java   (with props)
Removed:
    camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultLifecycleStrategy.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/InstrumentationLifecycleStrategy.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/ManagedCounter.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/ManagedEndpoint.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/ManagedPerformanceCounter.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/ManagedRoute.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/ManagedService.java
Modified:
    camel/trunk/camel-core/pom.xml
    camel/trunk/camel-core/src/main/java/org/apache/camel/CamelContext.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/Channel.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/Consumer.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/Service.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/seda/SedaConsumer.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/impl/CamelPostProcessorHelper.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultRouteContext.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultUnitOfWork.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/impl/EventDrivenConsumerRoute.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/impl/RouteService.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultInstrumentationAgent.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementNamingStrategy.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/InstrumentationInterceptStrategy.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/InstrumentationProcessor.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/processor/Delayer.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/spi/LifecycleStrategy.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/spi/ManagementAgent.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/component/dataset/CustomDataSetTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/impl/CustomIdFactoryTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/issues/TwoTimerWithJMXIssue.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/JmxInstrumentationOnlyRegisterProcessorWithCustomIdTest.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/JmxInstrumentationUsingPlatformMBSTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/management/JmxInstrumentationWithConnectorTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/management/MultiInstanceProcessorTest.java
    camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/CxfSoapConsumer.java
    camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java
    camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/DefaultJMXAgentTest.java
    camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/DummyLifecycleStrategy.java
    camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/JMXAgentTest.java
    camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/jmxConfig.xml
    camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/management/jmxInstrumentationWithConnector.xml

Modified: camel/trunk/camel-core/pom.xml
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/pom.xml?rev=807573&r1=807572&r2=807573&view=diff
==============================================================================
--- camel/trunk/camel-core/pom.xml (original)
+++ camel/trunk/camel-core/pom.xml Tue Aug 25 11:57:51 2009
@@ -71,9 +71,16 @@
     <dependency>
       <groupId>commons-logging</groupId>
       <artifactId>commons-logging-api</artifactId>
-    </dependency>    
+    </dependency>
+
+    <!-- required dependencies by camel-core -->
+    <dependency>
+      <groupId>org.fusesource.commonman</groupId>
+      <artifactId>commons-management</artifactId>
+      <version>1.0</version>
+    </dependency>
 
-    <!-- to allow Spring annotations to be used -->
+    <!-- to allow Spring annotations to be used for management -->
     <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-context</artifactId>

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/CamelContext.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/CamelContext.java?rev=807573&r1=807572&r2=807573&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/CamelContext.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/CamelContext.java Tue Aug 25 11:57:51 2009
@@ -32,6 +32,7 @@
 import org.apache.camel.spi.InterceptStrategy;
 import org.apache.camel.spi.Language;
 import org.apache.camel.spi.LifecycleStrategy;
+import org.apache.camel.spi.ManagementStrategy;
 import org.apache.camel.spi.NodeIdFactory;
 import org.apache.camel.spi.PackageScanClassResolver;
 import org.apache.camel.spi.Registry;
@@ -57,6 +58,14 @@
     //-----------------------------------------------------------------------
 
     /**
+     * Adds a service, starting it so that it will be stopped with this context
+     *
+     * @param object the service
+     * @throws Exception can be thrown when starting the service
+     */
+    void addService(Object object) throws Exception;
+
+    /**
      * Adds a component to the context.
      *
      * @param componentName  the name the component is registered as
@@ -478,4 +487,18 @@
      */
     NodeIdFactory getNodeIdFactory();
 
+    /**
+     * Gets the management strategy
+     *
+     * @return the management strategy
+     */
+    ManagementStrategy getManagementStrategy();
+
+    /**
+     * Sets the management strategy to use
+     *
+     * @param strategy the management strategy
+     */
+    void setManagementStrategy(ManagementStrategy strategy);
+
 }

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/Channel.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/Channel.java?rev=807573&r1=807572&r2=807573&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/Channel.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/Channel.java Tue Aug 25 11:57:51 2009
@@ -31,8 +31,6 @@
  */
 public interface Channel extends Processor, Navigate<Processor> {
 
-    List<Processor> next();
-
     /**
      * Sets the processor that the channel should route the {@link Exchange} to.
      *

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/Consumer.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/Consumer.java?rev=807573&r1=807572&r2=807573&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/Consumer.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/Consumer.java Tue Aug 25 11:57:51 2009
@@ -22,4 +22,11 @@
  * @version $Revision$
  */
 public interface Consumer extends Service {
+
+    /**
+     * Gets the endpoint this {@link Consumer} consumes from.
+     *
+     * @return the endpoint
+     */
+    Endpoint getEndpoint();
 }

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/Service.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/Service.java?rev=807573&r1=807572&r2=807573&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/Service.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/Service.java Tue Aug 25 11:57:51 2009
@@ -26,14 +26,14 @@
     /**
      * Starts the service
      * 
-     * @throws Exception
+     * @throws Exception is thrown if starting failed
      */
     void start() throws Exception;
 
     /**
      * Stops the service
      * 
-     * @throws Exception
+     * @throws Exception is thrown if stopping failed
      */
     void stop() throws Exception;
 }

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/seda/SedaConsumer.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/seda/SedaConsumer.java?rev=807573&r1=807572&r2=807573&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/seda/SedaConsumer.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/seda/SedaConsumer.java Tue Aug 25 11:57:51 2009
@@ -21,9 +21,9 @@
 import java.util.concurrent.TimeUnit;
 
 import org.apache.camel.Consumer;
+import org.apache.camel.Endpoint;
 import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
-import org.apache.camel.Endpoint;
 import org.apache.camel.impl.ServiceSupport;
 import org.apache.camel.util.concurrent.ExecutorServiceHelper;
 import org.apache.commons.logging.Log;

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/CamelPostProcessorHelper.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/CamelPostProcessorHelper.java?rev=807573&r1=807572&r2=807573&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/CamelPostProcessorHelper.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/CamelPostProcessorHelper.java Tue Aug 25 11:57:51 2009
@@ -104,13 +104,7 @@
     }
 
     public void startService(Service service) throws Exception {
-        CamelContext camelContext = getCamelContext();
-        if (camelContext instanceof DefaultCamelContext) {
-            DefaultCamelContext defaultCamelContext = (DefaultCamelContext) camelContext;
-            defaultCamelContext.addService(service);
-        } else {
-            service.start();
-        }
+        getCamelContext().addService(service);
     }
 
     /**

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java?rev=807573&r1=807572&r2=807573&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java Tue Aug 25 11:57:51 2009
@@ -18,13 +18,13 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
 import java.util.concurrent.Callable;
-
 import javax.naming.Context;
 
 import org.apache.camel.CamelContext;
@@ -45,8 +45,11 @@
 import org.apache.camel.TypeConverter;
 import org.apache.camel.builder.ErrorHandlerBuilder;
 import org.apache.camel.impl.converter.DefaultTypeConverter;
-import org.apache.camel.management.InstrumentationLifecycleStrategy;
+import org.apache.camel.management.DefaultInstrumentationAgent;
+import org.apache.camel.management.DefaultManagedLifecycleStrategy;
+import org.apache.camel.management.DefaultManagementStrategy;
 import org.apache.camel.management.JmxSystemPropertyKeys;
+import org.apache.camel.management.ManagedManagementStrategy;
 import org.apache.camel.model.DataFormatDefinition;
 import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.processor.interceptor.Delayer;
@@ -63,22 +66,22 @@
 import org.apache.camel.spi.Language;
 import org.apache.camel.spi.LanguageResolver;
 import org.apache.camel.spi.LifecycleStrategy;
+import org.apache.camel.spi.ManagementStrategy;
 import org.apache.camel.spi.NodeIdFactory;
 import org.apache.camel.spi.PackageScanClassResolver;
 import org.apache.camel.spi.Registry;
 import org.apache.camel.spi.RouteContext;
 import org.apache.camel.spi.ServicePool;
 import org.apache.camel.spi.TypeConverterRegistry;
+import org.apache.camel.util.EventHelper;
 import org.apache.camel.util.LRUCache;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.ReflectionInjector;
+import org.apache.camel.util.ServiceHelper;
 import org.apache.camel.util.URISupport;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
-import static org.apache.camel.util.ServiceHelper.startServices;
-import static org.apache.camel.util.ServiceHelper.stopServices;
-
 /**
  * Represents the context used to configure routes and the policies to use.
  *
@@ -104,6 +107,7 @@
     private final Map<String, Language> languages = new HashMap<String, Language>();
     private Registry registry;
     private LifecycleStrategy lifecycleStrategy;
+    private ManagementStrategy managementStrategy;
     private final List<RouteDefinition> routeDefinitions = new ArrayList<RouteDefinition>();
     private List<InterceptStrategy> interceptStrategies = new ArrayList<InterceptStrategy>();
     private Boolean trace = Boolean.FALSE;
@@ -129,12 +133,14 @@
         name = NAME_PREFIX + ++nameSuffix;
 
         if (Boolean.getBoolean(JmxSystemPropertyKeys.DISABLED)) {
-            LOG.info("JMX is disabled. Using DefaultLifecycleStrategy.");
-            lifecycleStrategy = new DefaultLifecycleStrategy();
+            LOG.info("JMX is disabled. Using SimpleLifecycleStrategy.");
+            lifecycleStrategy = new SimpleLifecycleStrategy();
+            managementStrategy = new DefaultManagementStrategy();
         } else {
             try {
-                LOG.info("JMX enabled. Using InstrumentationLifecycleStrategy.");
-                lifecycleStrategy = new InstrumentationLifecycleStrategy();
+                LOG.info("JMX enabled. Using DefaultManagedLifecycleStrategy.");
+                managementStrategy = new ManagedManagementStrategy(new DefaultInstrumentationAgent());
+                lifecycleStrategy = new DefaultManagedLifecycleStrategy(managementStrategy);
             } catch (NoClassDefFoundError e) {
                 // if we can't instantiate the JMX enabled strategy then fallback to default
                 // could be because of missing .jars on the classpath
@@ -147,8 +153,9 @@
             }
             // if not created then fallback to default
             if (lifecycleStrategy == null) {
-                LOG.warn("Cannot use JMX lifecycle strategy. Using DefaultLifecycleStrategy instead.");
-                lifecycleStrategy = new DefaultLifecycleStrategy();
+                LOG.warn("Cannot use JMX lifecycle strategy. Using SimpleLifecycleStrategy instead.");
+                managementStrategy = new DefaultManagementStrategy();
+                lifecycleStrategy = new SimpleLifecycleStrategy();
             }
         }
 
@@ -198,6 +205,7 @@
             }
             component.setCamelContext(this);
             components.put(componentName, component);
+            lifecycleStrategy.onComponentAdd(componentName, component);
         }
     }
 
@@ -212,8 +220,7 @@
                     if (component != null) {
                         addComponent(name, component);
                         if (isStarted() || isStarting()) {
-                            // If the component is looked up after the context is started,
-                            // lets start it up.
+                            // If the component is looked up after the context is started, lets start it up.
                             startServices(component);
                         }
                     }
@@ -235,9 +242,14 @@
         }
     }
 
+    @Deprecated
     public Component removeComponent(String componentName) {
         synchronized (components) {
-            return components.remove(componentName);
+            Component answer = components.remove(componentName);
+            if (answer != null) {
+                lifecycleStrategy.onComponentRemove(componentName, answer);
+            }
+            return answer;
         }
     }
 
@@ -253,6 +265,7 @@
                     }
                     components.put(componentName, component);
                     component.setCamelContext(this);
+                    lifecycleStrategy.onComponentAdd(componentName, component);
                 } catch (Exception e) {
                     throw new RuntimeCamelException("Factory failed to create the " + componentName
                             + " component", e);
@@ -324,6 +337,7 @@
         synchronized (endpoints) {
             startServices(endpoint);
             oldEndpoint = endpoints.remove(uri);
+            lifecycleStrategy.onEndpointAdd(endpoint);
             addEndpointToRegistry(uri, endpoint);
             if (oldEndpoint != null) {
                 stopServices(oldEndpoint);
@@ -332,6 +346,7 @@
         return oldEndpoint;
     }
 
+    @Deprecated
     public Collection<Endpoint> removeEndpoints(String uri) throws Exception {
         Collection<Endpoint> answer = new ArrayList<Endpoint>();
         synchronized (endpoints) {
@@ -339,6 +354,7 @@
             if (oldEndpoint != null) {
                 answer.add(oldEndpoint);
                 stopServices(oldEndpoint);
+                lifecycleStrategy.onEndpointRemove(oldEndpoint);
             } else {
                 for (Map.Entry entry : endpoints.entrySet()) {
                     oldEndpoint = (Endpoint) entry.getValue();
@@ -346,6 +362,7 @@
                         answer.add(oldEndpoint);
                         stopServices(oldEndpoint);
                         endpoints.remove(entry.getKey());
+                        lifecycleStrategy.onEndpointRemove(oldEndpoint);
                     }
                 }
             }
@@ -357,6 +374,7 @@
         return addEndpoint(uri, endpoint);
     }
 
+    @Deprecated
     public Endpoint removeSingletonEndpoint(String uri) throws Exception {
         Collection<Endpoint> answer = removeEndpoints(uri);
         return (Endpoint) (answer.size() > 0 ? answer.toArray()[0] : null);
@@ -406,9 +424,8 @@
 
                     if (answer != null) {
                         addService(answer);
-                        Endpoint newAnswer = addEndpointToRegistry(uri, answer);
                         lifecycleStrategy.onEndpointAdd(answer);
-                        answer = newAnswer;
+                        answer = addEndpointToRegistry(uri, answer);
                     }
                 } catch (Exception e) {
                     throw new ResolveEndpointFailedException(uri, e);
@@ -586,17 +603,13 @@
         }
     }
 
-
-    /**
-     * Adds a service, starting it so that it will be stopped with this context
-     */
     public void addService(Object object) throws Exception {
         if (object instanceof Service) {
             Service service = (Service) object;
             getLifecycleStrategy().onServiceAdd(this, service);
-            service.start();
             servicesToClose.add(service);
         }
+        startServices(object);
     }
 
     // Helper methods
@@ -833,13 +846,15 @@
         }
 
         LOG.info("Apache Camel " + getVersion() + " (CamelContext:" + getName() + ") started");
+        EventHelper.notifyCamelContextStarted(this);
     }
 
     // Implementation methods
     // -----------------------------------------------------------------------
 
-    protected void doStart() throws Exception {
+    protected synchronized void doStart() throws Exception {
         LOG.info("Apache Camel " + getVersion() + " (CamelContext:" + getName() + ") is starting");
+        EventHelper.notifyCamelContextStarting(this);
 
         startServices(producerServicePool);
 
@@ -882,40 +897,71 @@
         } catch (Exception e) {
             // not all containers allow access to its MBeanServer (such as OC4j)
             LOG.warn("Cannot start lifecycleStrategy: " + lifecycleStrategy + ". Cause: " + e.getMessage());
-            if (lifecycleStrategy instanceof InstrumentationLifecycleStrategy) {
+            if (!(lifecycleStrategy instanceof SimpleLifecycleStrategy)) {
                 // fallback to non JMX lifecycle to allow Camel to startup
-                LOG.warn("Will fallback to use default (non JMX) lifecycle strategy");
-                lifecycleStrategy = new DefaultLifecycleStrategy();
+                LOG.warn("Will fallback to use SimpleLifecycleStrategy (non JMX) lifecycle strategy");
+                lifecycleStrategy = new SimpleLifecycleStrategy();
                 lifecycleStrategy.onContextStart(this);
             }
         }
 
         forceLazyInitialization();
-        if (components != null) {
-            for (Component component : components.values()) {
-                startServices(component);
-            }
-        }
+        startServices(components.values());
+
          // To avoid initiating the routeDefinitions after stopping the camel context
         if (!routeDefinitionInitiated) {            
             startRouteDefinitions(routeDefinitions);
             routeDefinitionInitiated = true;
-        }        
+        }
+
+        // starting will continue in the start method
     }
 
     protected synchronized void doStop() throws Exception {
         LOG.info("Apache Camel " + getVersion() + " (CamelContext:" + getName() + ") is stopping");
+        EventHelper.notifyCamelContextStopping(this);
+
+        // the stop order is important
+        stopServices(endpoints.values());
+        endpoints.clear();
+
         stopServices(routeServices.values());
+        // do not clear route services as we can start Camel again and get the route back as before
+        stopServices(producerServicePool);
+
+        stopServices(components.values());
+        components.clear();
+
         stopServices(servicesToClose);
-        if (components != null) {
-            for (Component component : components.values()) {
-                stopServices(component);
-            }
-        }
         servicesToClose.clear();
-        stopServices(producerServicePool);
+
+        try {
+            lifecycleStrategy.onContextStop(this);
+        } catch (Exception e) {
+            LOG.warn("Cannot stop lifecycleStrategy: " + lifecycleStrategy + ". Cause: " + e.getMessage());
+        }
 
         LOG.info("Apache Camel " + getVersion() + " (CamelContext:" + getName() + ") stopped");
+        EventHelper.notifyCamelContextStopped(this);
+    }
+
+    private void stopServices(Object service) throws Exception {
+        // allow us to do custom work before delegating to service helper
+        ServiceHelper.stopService(service);
+    }
+
+    @SuppressWarnings("unchecked")
+    private void stopServices(Collection services) throws Exception {
+        // close them in reverse order as they where added
+        List reverse = new ArrayList(services);
+        Collections.reverse(reverse);
+        for (Object service : reverse) {
+            stopServices(service);
+        }
+    }
+
+    private void startServices(Object service) throws Exception {
+        ServiceHelper.startService(service);
     }
 
     protected void startRouteDefinitions(Collection<RouteDefinition> list) throws Exception {
@@ -1106,6 +1152,14 @@
         this.nodeIdFactory = idFactory;
     }
 
+    public ManagementStrategy getManagementStrategy() {
+        return managementStrategy;
+    }
+
+    public void setManagementStrategy(ManagementStrategy managementStrategy) {
+        this.managementStrategy = managementStrategy;
+    }
+
     protected synchronized String getEndpointKey(String uri, Endpoint endpoint) {
         if (endpoint.isSingleton()) {
             return uri;

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultRouteContext.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultRouteContext.java?rev=807573&r1=807572&r2=807573&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultRouteContext.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultRouteContext.java Tue Aug 25 11:57:51 2009
@@ -26,6 +26,7 @@
 import org.apache.camel.NoSuchEndpointException;
 import org.apache.camel.Processor;
 import org.apache.camel.Route;
+import org.apache.camel.management.InstrumentationProcessor;
 import org.apache.camel.model.DataFormatDefinition;
 import org.apache.camel.model.FromDefinition;
 import org.apache.camel.model.ProcessorDefinition;
@@ -137,8 +138,14 @@
             // and wrap it in a unit of work so the UoW is on the top, so the entire route will be in the same UoW
             Processor unitOfWorkProcessor = new UnitOfWorkProcessor(processor);
 
+            // and wrap it by a instrumentation processor that is to be used for performance stats
+            // for this particular route
+            InstrumentationProcessor wrapper = new InstrumentationProcessor();
+            wrapper.setType("route");
+            wrapper.setProcessor(unitOfWorkProcessor);
+
             // and create the route that wraps the UoW
-            Route edcr = new EventDrivenConsumerRoute(getEndpoint(), unitOfWorkProcessor);
+            Route edcr = new EventDrivenConsumerRoute(getEndpoint(), wrapper);
             edcr.getProperties().put(Route.ID_PROPERTY, route.idOrCreate(getCamelContext().getNodeIdFactory()));
             edcr.getProperties().put(Route.PARENT_PROPERTY, Integer.toHexString(route.hashCode()));
             if (route.getGroup() != null) {

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultUnitOfWork.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultUnitOfWork.java?rev=807573&r1=807572&r2=807573&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultUnitOfWork.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultUnitOfWork.java Tue Aug 25 11:57:51 2009
@@ -30,6 +30,7 @@
 import org.apache.camel.model.ProcessorDefinition;
 import org.apache.camel.spi.Synchronization;
 import org.apache.camel.spi.TraceableUnitOfWork;
+import org.apache.camel.util.EventHelper;
 import org.apache.camel.util.UuidGenerator;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -52,7 +53,7 @@
     public DefaultUnitOfWork(Exchange exchange) {
         // TODO: optimize to only copy original message if enabled to do so in the route
 
-        // special for JmsMessage as it can cause it to loose headers later. Yeah JMS suchs
+        // special for JmsMessage as it can cause it to loose headers later.
         if (exchange.getIn().getClass().getSimpleName().equals("JmsMessage")) {
             this.originalInMessage = new DefaultMessage();
             this.originalInMessage.setBody(exchange.getIn().getBody());
@@ -60,6 +61,9 @@
         } else {
             this.originalInMessage = exchange.getIn().copy();
         }
+
+        // fire event
+        EventHelper.notifyExchangeCreated(exchange.getContext(), exchange);
     }
 
     public void start() throws Exception {
@@ -105,8 +109,17 @@
     }
 
     public void done(Exchange exchange) {
+        boolean failed = exchange.isFailed();
+
+        // fire event to signal the exchange is done
+        if (failed) {
+            EventHelper.notifyExchangeFailed(exchange.getContext(), exchange);
+        } else {
+            EventHelper.notifyExchangeDone(exchange.getContext(), exchange);
+        }
+
         if (synchronizations != null && !synchronizations.isEmpty()) {
-            boolean failed = exchange.isFailed();
+            // invoke synchronization callbacks
             for (Synchronization synchronization : synchronizations) {
                 try {
                     if (failed) {
@@ -116,7 +129,7 @@
                     }
                 } catch (Exception e) {
                     // must catch exceptions to ensure all synchronizations have a chance to run
-                    LOG.error("Exception occured during onCompletion. This exception will be ignored: ", e);
+                    LOG.error("Exception occurred during onCompletion. This exception will be ignored: ", e);
                 }
             }
         }

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/EventDrivenConsumerRoute.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/EventDrivenConsumerRoute.java?rev=807573&r1=807572&r2=807573&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/EventDrivenConsumerRoute.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/EventDrivenConsumerRoute.java Tue Aug 25 11:57:51 2009
@@ -23,6 +23,7 @@
 import org.apache.camel.Navigate;
 import org.apache.camel.Processor;
 import org.apache.camel.Service;
+import org.apache.camel.management.InstrumentationProcessor;
 
 /**
  * A {@link DefaultRoute} which starts with an
@@ -66,8 +67,14 @@
 
     @SuppressWarnings("unchecked")
     public Navigate<Processor> navigate() {
-        if (processor instanceof Navigate) {
-            return (Navigate) processor;
+        Processor answer = getProcessor();
+        // skip the instrumentation processor if this route was wrapped by one
+        if (answer instanceof InstrumentationProcessor) {
+            answer = ((InstrumentationProcessor) answer).getProcessor();
+        }
+
+        if (answer instanceof Navigate) {
+            return (Navigate) answer;
         }
         return null;
     }

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/RouteService.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/RouteService.java?rev=807573&r1=807572&r2=807573&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/RouteService.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/RouteService.java Tue Aug 25 11:57:51 2009
@@ -16,15 +16,19 @@
  */
 package org.apache.camel.impl;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 
 import org.apache.camel.CamelContext;
+import org.apache.camel.Navigate;
 import org.apache.camel.Route;
 import org.apache.camel.Service;
 import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.spi.LifecycleStrategy;
 import org.apache.camel.spi.RouteContext;
+import org.apache.camel.util.EventHelper;
+import org.apache.camel.util.ServiceHelper;
 
 /**
  * Represents the runtime objects for a given {@link RouteDefinition} so that it can be stopped independently
@@ -75,36 +79,64 @@
 
         for (Route route : routes) {
             List<Service> services = route.getServicesForRoute();
+
+            // gather list of services to start as we need to start child services as well
+            List<Service> list = new ArrayList<Service>();
             for (Service service : services) {
-                startChildService(service);
+                doGetServiesToStart(list, service);
             }
+            startChildService(list);
+
+            // fire event
+            EventHelper.notifyRouteStarted(camelContext, route);
         }
     }
 
-    protected void doStop() throws Exception {
-        camelContext.removeRouteCollection(routes);
+    /**
+     * Need to recursive start child services for routes
+     */
+    private void doGetServiesToStart(List<Service> services, Service service) throws Exception {
+        services.add(service);
+
+        if (service instanceof Navigate) {
+            Navigate<?> nav = (Navigate<?>) service;
+            if (nav.hasNext()) {
+                List<?> children = nav.next();
+                for (Object child : children) {
+                    if (child instanceof Service) {
+                        doGetServiesToStart(services, (Service) child);
+                    }
+                }
+            }
+        }
+    }
 
-        // there is no lifecycyle for routesRemove
+    protected void doStop() throws Exception {
+        getLifecycleStrategy().onRoutesRemove(routes);
 
         // do not stop child services as in doStart
         // as route.getServicesForRoute() will restart
         // already stopped services, so we end up starting
         // stuff when we stop.
+
+        // fire events
+        for (Route route : routes) {
+            EventHelper.notifyRouteStopped(camelContext, route);
+        }
+
+        camelContext.removeRouteCollection(routes);
     }
 
     protected LifecycleStrategy getLifecycleStrategy() {
         return camelContext.getLifecycleStrategy();
     }
 
-    protected void startChildService(Service service) throws Exception {
-        getLifecycleStrategy().onServiceAdd(camelContext, service);
-        service.start();
-        addChildService(service);
-    }
-
-    protected void stopChildService(Service service) throws Exception {
-        service.stop();
-        removeChildService(service);
+    protected void startChildService(List<Service> services) throws Exception {
+        for (Service service : services) {
+            getLifecycleStrategy().onServiceAdd(camelContext, service);
+            ServiceHelper.startService(service);
+            addChildService(service);
+        }
     }
 
 }

Added: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/SimpleLifecycleStrategy.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/SimpleLifecycleStrategy.java?rev=807573&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/SimpleLifecycleStrategy.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/SimpleLifecycleStrategy.java Tue Aug 25 11:57:51 2009
@@ -0,0 +1,78 @@
+/**
+ * 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.impl;
+
+import java.util.Collection;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Component;
+import org.apache.camel.Endpoint;
+import org.apache.camel.Route;
+import org.apache.camel.Service;
+import org.apache.camel.spi.LifecycleStrategy;
+import org.apache.camel.spi.RouteContext;
+
+/**
+ * Simple implementation of the {@link LifecycleStrategy} that does nothing.
+ */
+public class SimpleLifecycleStrategy implements LifecycleStrategy {
+
+    public void onContextStart(CamelContext context) {
+        // do nothing
+    }
+
+    public void onContextStop(CamelContext context) {
+        // do nothing
+    }
+
+    public void onComponentAdd(String name, Component component) {
+        // do nothing
+    }
+
+    public void onComponentRemove(String name, Component component) {
+        // do nothing
+    }
+
+    public void onEndpointAdd(Endpoint endpoint) {
+        // do nothing
+    }
+
+    public void onEndpointRemove(Endpoint endpoint) {
+        // do nothing
+    }
+
+    public void onServiceAdd(CamelContext context, Service service) {
+        // do nothing
+    }
+
+    public void onServiceRemove(CamelContext context, Service service) {
+        // do nothing
+    }
+
+    public void onRoutesAdd(Collection<Route> routes) {
+        // do nothing
+    }
+
+    public void onRoutesRemove(Collection<Route> routes) {
+        // do nothing
+    }
+
+    public void onRouteContextCreate(RouteContext routeContext) {
+        // do nothing
+    }
+
+}

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/SimpleLifecycleStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/SimpleLifecycleStrategy.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultEventFactory.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultEventFactory.java?rev=807573&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultEventFactory.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultEventFactory.java Tue Aug 25 11:57:51 2009
@@ -0,0 +1,76 @@
+/**
+ * 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 java.util.EventObject;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.Route;
+import org.apache.camel.management.event.CamelContextStartedEvent;
+import org.apache.camel.management.event.CamelContextStartingEvent;
+import org.apache.camel.management.event.CamelContextStoppedEvent;
+import org.apache.camel.management.event.CamelContextStoppingEvent;
+import org.apache.camel.management.event.ExchangeCompletedEvent;
+import org.apache.camel.management.event.ExchangeCreatedEvent;
+import org.apache.camel.management.event.ExchangeFailedEvent;
+import org.apache.camel.management.event.RouteStartEvent;
+import org.apache.camel.management.event.RouteStopEvent;
+import org.apache.camel.spi.EventFactory;
+
+/**
+ * @version $Revision$
+ */
+public class DefaultEventFactory implements EventFactory {
+
+    public EventObject createCamelContextStartingEvent(CamelContext context) {
+        return new CamelContextStartingEvent(context);
+    }
+
+    public EventObject createCamelContextStartedEvent(CamelContext context) {
+        return new CamelContextStartedEvent(context);
+    }
+
+    public EventObject createCamelContextStoppingEvent(CamelContext context) {
+        return new CamelContextStoppingEvent(context);
+    }
+
+    public EventObject createCamelContextStoppedEvent(CamelContext context) {
+        return new CamelContextStoppedEvent(context);
+    }
+
+    public EventObject createRouteStartEvent(Route route) {
+        return new RouteStartEvent(route);
+    }
+
+    public EventObject createRouteStopEvent(Route route) {
+        return new RouteStopEvent(route);
+    }
+
+    public EventObject createExchangeCreatedEvent(Exchange exchange) {
+        return new ExchangeCreatedEvent(exchange);
+    }
+
+    public EventObject createExchangeCompletedEvent(Exchange exchange) {
+        return new ExchangeCompletedEvent(exchange);
+    }
+
+    public EventObject createExchangeFailedEvent(Exchange exchange) {
+        return new ExchangeFailedEvent(exchange);
+    }
+
+}

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultEventFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultEventFactory.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultEventNotifier.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultEventNotifier.java?rev=807573&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultEventNotifier.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultEventNotifier.java Tue Aug 25 11:57:51 2009
@@ -0,0 +1,43 @@
+/**
+ * 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 java.util.EventObject;
+
+import org.apache.camel.spi.EventNotifier;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Default event notifier that only notifies if <tt>TRACE</tt> log level has
+ * been configured for its logger.
+ *
+ * @version $Revision$
+ */
+public class DefaultEventNotifier implements EventNotifier {
+
+    private static final Log LOG = LogFactory.getLog(DefaultEventNotifier.class);
+
+    public void notify(EventObject event) throws Exception {
+        LOG.trace("Event: " + event);
+    }
+
+    public boolean isEnabled(EventObject event) {
+        return LOG.isTraceEnabled();
+    }
+
+}

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultEventNotifier.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultEventNotifier.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultInstrumentationAgent.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultInstrumentationAgent.java?rev=807573&r1=807572&r2=807573&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultInstrumentationAgent.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultInstrumentationAgent.java Tue Aug 25 11:57:51 2009
@@ -61,7 +61,7 @@
 
     private ExecutorService executorService;
     private MBeanServer server;
-    private Set<ObjectName> mbeans = new HashSet<ObjectName>();
+    private final Set<ObjectName> mbeansRegistered = new HashSet<ObjectName>();
     private MetadataMBeanInfoAssembler assembler;
     private JMXConnectorServer cs;
 
@@ -213,6 +213,11 @@
 
     public void unregister(ObjectName name) throws JMException {
         server.unregisterMBean(name);
+        mbeansRegistered.remove(name);
+    }
+
+    public boolean isRegistered(ObjectName name) {
+        return server.isRegistered(name);
     }
 
     protected void doStart() throws Exception {
@@ -243,12 +248,12 @@
 
         // Using the array to hold the busMBeans to avoid the
         // CurrentModificationException
-        Object[] mBeans = mbeans.toArray();
+        ObjectName[] mBeans = mbeansRegistered.toArray(new ObjectName[mbeansRegistered.size()]);
         int caught = 0;
-        for (Object name : mBeans) {
-            mbeans.remove(name);
+        for (ObjectName name : mBeans) {
+            mbeansRegistered.remove(name);
             try {
-                unregister((ObjectName)name);
+                unregister(name);
             } catch (JMException jmex) {
                 LOG.info("Exception unregistering MBean", jmex);
                 caught++;
@@ -293,7 +298,7 @@
                 LOG.debug("Registered MBean with objectname: " + registeredName);
             }
 
-            mbeans.add(registeredName);
+            mbeansRegistered.add(registeredName);
         }
     }
 

Added: camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagedLifecycleStrategy.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagedLifecycleStrategy.java?rev=807573&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagedLifecycleStrategy.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagedLifecycleStrategy.java Tue Aug 25 11:57:51 2009
@@ -0,0 +1,470 @@
+/**
+ * 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 java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.management.JMException;
+import javax.management.ObjectName;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Component;
+import org.apache.camel.Consumer;
+import org.apache.camel.Endpoint;
+import org.apache.camel.Processor;
+import org.apache.camel.Producer;
+import org.apache.camel.Route;
+import org.apache.camel.Service;
+import org.apache.camel.impl.EventDrivenConsumerRoute;
+import org.apache.camel.management.mbean.ManagedBrowsableEndpoint;
+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.ManagedDelayer;
+import org.apache.camel.management.mbean.ManagedEndpoint;
+import org.apache.camel.management.mbean.ManagedPerformanceCounter;
+import org.apache.camel.management.mbean.ManagedProcessor;
+import org.apache.camel.management.mbean.ManagedProducer;
+import org.apache.camel.management.mbean.ManagedRoute;
+import org.apache.camel.management.mbean.ManagedThrottler;
+import org.apache.camel.model.AOPDefinition;
+import org.apache.camel.model.InterceptDefinition;
+import org.apache.camel.model.OnCompletionDefinition;
+import org.apache.camel.model.OnExceptionDefinition;
+import org.apache.camel.model.ProcessorDefinition;
+import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.processor.Delayer;
+import org.apache.camel.processor.Throttler;
+import org.apache.camel.spi.BrowsableEndpoint;
+import org.apache.camel.spi.ClassResolver;
+import org.apache.camel.spi.LifecycleStrategy;
+import org.apache.camel.spi.ManagementStrategy;
+import org.apache.camel.spi.RouteContext;
+import org.apache.camel.util.KeyValueHolder;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Default JMX managed lifecycle strategy that registered objects using the configured
+ * {@link org.apache.camel.spi.ManagementStrategy}.
+ *
+ * @see org.apache.camel.spi.ManagementStrategy
+ * @version $Revision$
+ */
+public class DefaultManagedLifecycleStrategy implements LifecycleStrategy, Service {
+
+    private static final Log LOG = LogFactory.getLog(DefaultManagedLifecycleStrategy.class);
+    private static final String MANAGED_RESOURCE_CLASSNAME = "org.springframework.jmx.export.annotation.ManagedResource";
+    private final Map<Processor, KeyValueHolder<ProcessorDefinition, InstrumentationProcessor>> wrappedProcessors =
+            new HashMap<Processor, KeyValueHolder<ProcessorDefinition, InstrumentationProcessor>>();
+    private final ManagementStrategy strategy;
+    private boolean initialized;
+
+    public DefaultManagedLifecycleStrategy() {
+        strategy = new ManagedManagementStrategy();
+    }
+
+    public DefaultManagedLifecycleStrategy(ManagementStrategy strategy) {
+        this.strategy = strategy;
+    }
+
+    public void onContextStart(CamelContext context) {
+        try {
+            initialized = true;
+
+            // call addService so that context will handle lifecycle on the strategy
+            context.addService(strategy);
+
+            ManagedCamelContext mc = new ManagedCamelContext(context);
+            strategy.manageObject(mc);
+
+        } catch (Exception e) {
+            // must rethrow to allow CamelContext fallback to non JMX agent to allow
+            // Camel to continue to run
+            throw ObjectHelper.wrapRuntimeCamelException(e);
+        }
+    }
+
+    public void onContextStop(CamelContext context) {
+        // the agent hasn't been started
+        if (!initialized) {
+            return;
+        }
+        try {
+            ManagedCamelContext mc = new ManagedCamelContext(context);
+            // the context could have been removed already
+            if (strategy.isManaged(null, mc)) {
+                strategy.unmanageObject(mc);
+            }
+        } catch (Exception e) {
+            LOG.warn("Could not unregister CamelContext MBean", e);
+        }
+    }
+
+    public void onComponentAdd(String name, Component component) {
+        // the agent hasn't been started
+        if (!initialized) {
+            return;
+        }
+        try {
+            ManagedComponent mc = new ManagedComponent(name, component);
+            strategy.manageObject(mc);
+        } catch (Exception e) {
+            LOG.warn("Could not register Component MBean", e);
+        }
+    }
+
+    public void onComponentRemove(String name, Component component) {
+        // the agent hasn't been started
+        if (!initialized) {
+            return;
+        }
+        try {
+            ManagedComponent mc = new ManagedComponent(name, component);
+            strategy.unmanageObject(mc);
+        } catch (Exception e) {
+            LOG.warn("Could not unregister Component MBean", e);
+        }
+    }
+
+    /**
+     * If the endpoint is an instance of ManagedResource then register it with the
+     * mbean server, if it is not then wrap the endpoint in a {@link ManagedEndpoint} and
+     * register that with the mbean server.
+     *
+     * @param endpoint the Endpoint attempted to be added
+     */
+    @SuppressWarnings("unchecked")
+    public void onEndpointAdd(Endpoint endpoint) {
+        // the agent hasn't been started
+        if (!initialized) {
+            return;
+        }
+
+        // see if the spring-jmx is on the classpath
+        Class annotationClass = resolveManagedAnnotation(endpoint);
+        if (annotationClass == null) {
+            // no its not so register the endpoint as a new managed endpoint
+            registerEndpointAsManagedEndpoint(endpoint);
+            return;
+        }
+
+        // see if the endpoint have been annotation with a spring JMX annotation
+        Object annotation = endpoint.getClass().getAnnotation(annotationClass);
+        if (annotation == null) {
+            // no its not so register the endpoint as a new managed endpoint
+            registerEndpointAsManagedEndpoint(endpoint);
+        } else {
+            // there is already a spring JMX annotation so attempt to register it
+            attemptToRegisterManagedResource(endpoint, annotation);
+        }
+    }
+
+    public void onEndpointRemove(Endpoint endpoint) {
+        // the agent hasn't been started
+        if (!initialized) {
+            return;
+        }
+
+        try {
+            ManagedEndpoint me;
+            if (endpoint instanceof BrowsableEndpoint) {
+                me = new ManagedBrowsableEndpoint((BrowsableEndpoint) endpoint);
+            } else {
+                me = new ManagedEndpoint(endpoint);
+            }
+            strategy.unmanageObject(me);
+        } catch (Exception e) {
+            LOG.warn("Could not unregister Endpoint MBean for uri: " + endpoint.getEndpointUri(), e);
+        }
+    }
+
+    private Class resolveManagedAnnotation(Endpoint endpoint) {
+        CamelContext context = endpoint.getCamelContext();
+
+        ClassResolver resolver = context.getClassResolver();
+        return resolver.resolveClass(MANAGED_RESOURCE_CLASSNAME);
+    }
+
+    private void attemptToRegisterManagedResource(Endpoint endpoint, Object annotation) {
+        try {
+            Method method = annotation.getClass().getMethod("objectName");
+            String name = (String) method.invoke(annotation);
+            ObjectName objectName = ObjectName.getInstance(name);
+            strategy.manageNamedObject(endpoint, objectName);
+        } catch (Exception e) {
+            if (LOG.isTraceEnabled()) {
+                LOG.trace("objectName method not present on endpoint, wrapping endpoint in ManagedEndpoint instead: " + endpoint);
+            }
+            registerEndpointAsManagedEndpoint(endpoint);
+        }
+    }
+
+    private void registerEndpointAsManagedEndpoint(Endpoint endpoint) {
+        try {
+            ManagedEndpoint me;
+            if (endpoint instanceof BrowsableEndpoint) {
+                me = new ManagedBrowsableEndpoint((BrowsableEndpoint) endpoint);
+            } else {
+                me = new ManagedEndpoint(endpoint);
+            }
+            strategy.manageObject(me);
+        } catch (Exception e) {
+            LOG.warn("Could not register Endpoint MBean for uri: " + endpoint.getEndpointUri(), e);
+        }
+
+    }
+
+    public void onServiceAdd(CamelContext context, Service service) {
+        // services can by any kind of misc type but also processors
+        // so we have special logic when its a processor
+
+        // the agent hasn't been started
+        if (!initialized) {
+            return;
+        }
+
+        Object managedObject;
+        if (service instanceof Processor) {
+            // special for processors
+            managedObject = getManagedObjectForProcessor(context, (Processor) service);
+        } else {
+            // regular for services
+            managedObject = getManagedObjectForService(context, service);
+        }
+        try {
+            strategy.manageObject(managedObject);
+        } catch (Exception e) {
+            LOG.warn("Could not register service: " + service + " as Service MBean.", e);
+        }
+    }
+
+    public void onServiceRemove(CamelContext context, Service service) {
+        // the agent hasn't been started
+        if (!initialized) {
+            return;
+        }
+
+        Object managedObject;
+        if (service instanceof Processor) {
+            managedObject = getManagedObjectForProcessor(context, (Processor) service);
+        } else {
+            // regular for services
+            managedObject = getManagedObjectForService(context, service);
+        }
+        if (managedObject != null) {
+            try {
+                strategy.unmanageObject(managedObject);
+            } catch (Exception e) {
+                LOG.warn("Could not unregister service: " + service + " as Service MBean.", e);
+            }
+        }
+    }
+
+    protected Object getManagedObjectForProcessor(CamelContext context, Processor processor) {
+        // a bit of magic here as the processors we want to manage have already been registered
+        // in the wrapped processors map when Camel have instrumented the route on route initialization
+        // so the idea is now to only manage the processors from the map
+        KeyValueHolder<ProcessorDefinition, InstrumentationProcessor> holder = wrappedProcessors.get(processor);
+        if (holder == null) {
+            // skip as its not an well known processor we want to manage anyway, such as Channel/UnitOfWork/Pipeline etc.
+            return null;
+        }
+
+        // get the managed object as it can be a specialized type such as a Delayer/Throttler etc.
+        Object managedObject = createManagedObjectForProcessor(context, processor, holder.getKey());
+        // only manage if we have a name for it as otherwise we do not want to manage it anyway
+        if (managedObject != null) {
+            // is it a performance counter then we need to set our counter
+            if (managedObject instanceof ManagedPerformanceCounter) {
+                InstrumentationProcessor counter = holder.getValue();
+                if (counter != null) {
+                    // change counter to us
+                    counter.setCounter((ManagedPerformanceCounter) managedObject);
+                }
+            }
+        }
+
+        return managedObject;
+    }
+
+    private Object createManagedObjectForProcessor(CamelContext context, Processor processor, ProcessorDefinition definition) {
+        if (processor instanceof Delayer) {
+            return new ManagedDelayer(context, (Delayer) processor, definition);
+        } else if (processor instanceof Throttler) {
+            return new ManagedThrottler(context, (Throttler) processor, definition);
+        }
+
+        // TODO Add more specialized support for processors such as SendTo, WireTap etc.
+
+        // fallback to a generic processor
+        return new ManagedProcessor(context, processor, definition);
+    }
+
+    private Object getManagedObjectForService(CamelContext context, Service service) {
+        if (service instanceof Consumer) {
+            return new ManagedConsumer(context, (Consumer) service);
+        } else if (service instanceof Producer) {
+            return new ManagedProducer(context, (Producer) service);
+        }
+
+        // not supported
+        return null;
+    }
+
+    public void onRoutesAdd(Collection<Route> routes) {
+        // the agent hasn't been started
+        if (!initialized) {
+            return;
+        }
+
+        for (Route route : routes) {
+            ManagedRoute mr = new ManagedRoute(strategy, route);
+
+            // get the wrapped instrumentation processor from this route
+            // and set me as the counter
+            if (route instanceof EventDrivenConsumerRoute) {
+                EventDrivenConsumerRoute edcr = (EventDrivenConsumerRoute) route;
+                Processor processor = edcr.getProcessor();
+                if (processor instanceof InstrumentationProcessor) {
+                    InstrumentationProcessor ip = (InstrumentationProcessor) processor;
+                    ip.setCounter(mr);
+                }
+            }
+
+            try {
+                strategy.manageObject(mr);
+            } catch (JMException e) {
+                LOG.warn("Could not register Route MBean", e);
+            } catch (Exception e) {
+                LOG.warn("Could not create Route MBean", e);
+            }
+        }
+    }
+
+    public void onRoutesRemove(Collection<Route> routes) {
+        // the agent hasn't been started
+        if (!initialized) {
+            return;
+        }
+
+        for (Route route : routes) {
+            ManagedRoute mr = new ManagedRoute(strategy, route);
+            try {
+                strategy.unmanageObject(mr);
+            } catch (Exception e) {
+                LOG.warn("Could not unregister Route MBean", e);
+            }
+        }
+    }
+
+    public void onRouteContextCreate(RouteContext routeContext) {
+        // the agent hasn't been started
+        if (!initialized) {
+            return;
+        }
+
+        // Create a map (ProcessorType -> PerformanceCounter)
+        // to be passed to InstrumentationInterceptStrategy.
+        Map<ProcessorDefinition, ManagedPerformanceCounter> registeredCounters =
+                new HashMap<ProcessorDefinition, ManagedPerformanceCounter>();
+
+        // Each processor in a route will have its own performance counter
+        // The performance counter are MBeans that we register with MBeanServer.
+        // These performance counter will be embedded
+        // to InstrumentationProcessor and wrap the appropriate processor
+        // by InstrumentationInterceptStrategy.
+        RouteDefinition route = routeContext.getRoute();
+
+        // register performance counters for all processors and its children
+        for (ProcessorDefinition processor : route.getOutputs()) {
+            registerPerformanceCounters(routeContext, processor, registeredCounters);
+        }
+
+        // add intercept strategy that executes the JMX instrumentation for performance metrics
+        // so our registered counters can be used for fine grained performance instrumentation
+        routeContext.addInterceptStrategy(new InstrumentationInterceptStrategy(registeredCounters, wrappedProcessors));
+    }
+
+    @SuppressWarnings("unchecked")
+    private void registerPerformanceCounters(RouteContext routeContext, ProcessorDefinition processor,
+                                             Map<ProcessorDefinition, ManagedPerformanceCounter> registeredCounters) {
+
+        // traverse children if any exists
+        List<ProcessorDefinition> children = processor.getOutputs();
+        for (ProcessorDefinition child : children) {
+            registerPerformanceCounters(routeContext, child, registeredCounters);
+        }
+
+        // skip processors that should not be registered
+        if (!registerProcessor(processor)) {
+            return;
+        }
+
+        // okay this is a processor we would like to manage so create the
+        // performance counter that is the base for processors
+        ManagedPerformanceCounter pc = new ManagedPerformanceCounter(strategy);
+
+        // and add it as a a registered counter that will be used lazy when Camel
+        // does the instrumentation of the route and adds the InstrumentationProcessor
+        // that does the actual performance metrics gatherings at runtime
+        registeredCounters.put(processor, pc);
+    }
+
+    /**
+     * Should the given processor be registered.
+     */
+    protected boolean registerProcessor(ProcessorDefinition processor) {
+        // skip on exception
+        if (processor instanceof OnExceptionDefinition) {
+            return false;
+        }
+        // skip on completion
+        if (processor instanceof OnCompletionDefinition) {
+            return false;
+        }
+        // skip intercept
+        if (processor instanceof InterceptDefinition) {
+            return false;
+        }
+        // skip aop
+        if (processor instanceof AOPDefinition) {
+            return false;
+        }
+
+        // only if custom id assigned
+        if (strategy.isOnlyManageProcessorWithCustomId()) {
+            return processor.hasCustomIdAssigned();
+        }
+
+        // use customer filter
+        return strategy.manageProcessor(processor);
+    }
+
+    public void start() throws Exception {
+        strategy.start();
+    }
+
+    public void stop() throws Exception {
+        strategy.stop();
+    }
+}
+

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagedLifecycleStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagedLifecycleStrategy.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

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=807573&r1=807572&r2=807573&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 Tue Aug 25 11:57:51 2009
@@ -18,34 +18,38 @@
 
 import java.net.InetAddress;
 import java.net.UnknownHostException;
-
 import javax.management.MalformedObjectNameException;
 import javax.management.ObjectName;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.Consumer;
 import org.apache.camel.Endpoint;
+import org.apache.camel.Processor;
 import org.apache.camel.Route;
-import org.apache.camel.Service;
+import org.apache.camel.management.mbean.ManagedComponent;
+import org.apache.camel.management.mbean.ManagedConsumer;
+import org.apache.camel.management.mbean.ManagedEndpoint;
+import org.apache.camel.management.mbean.ManagedProcessor;
+import org.apache.camel.management.mbean.ManagedRoute;
+import org.apache.camel.management.mbean.ManagedService;
 import org.apache.camel.model.ProcessorDefinition;
+import org.apache.camel.spi.ManagementNamingStrategy;
 import org.apache.camel.spi.RouteContext;
 
 /**
  * Naming strategy used when registering MBeans.
  */
-public class DefaultManagementNamingStrategy {
+public class DefaultManagementNamingStrategy implements ManagementNamingStrategy {
     public static final String VALUE_UNKNOWN = "unknown";
     public static final String KEY_NAME = "name";
     public static final String KEY_TYPE = "type";
     public static final String KEY_CONTEXT = "context";
-    public static final String KEY_GROUP = "group";
-    public static final String KEY_ROUTE = "route";
-    public static final String KEY_NODE_ID = "nodeid";
     public static final String TYPE_CONTEXT = "context";
     public static final String TYPE_ENDPOINT = "endpoints";
     public static final String TYPE_PROCESSOR = "processors";
     public static final String TYPE_CONSUMER = "consumers";
     public static final String TYPE_ROUTE = "routes";
+    public static final String TYPE_COMPONENT = "components";
 
     protected String domainName;
     protected String hostName = "localhost";
@@ -61,19 +65,10 @@
         try {
             hostName = InetAddress.getLocalHost().getHostName();
         } catch (UnknownHostException ex) {
-            // ignore, use the default "locahost"
+            // ignore, use the default "localhost"
         }
     }
 
-    /**
-     * Implements the naming strategy for a {@link CamelContext}.
-     * The convention used for a {@link CamelContext} ObjectName is:
-     * <tt>&lt;domain&gt;:context=&lt;context-name&gt;,type=context,name=&lt;context-name&gt;</tt>
-     *
-     * @param context the camel context
-     * @return generated ObjectName
-     * @throws MalformedObjectNameException can be thrown
-     */
     public ObjectName getObjectName(CamelContext context) throws MalformedObjectNameException {
         StringBuffer buffer = new StringBuffer();
         buffer.append(domainName).append(":");
@@ -83,11 +78,6 @@
         return createObjectName(buffer);
     }
 
-    /**
-     * Implements the naming strategy for a {@link ManagedEndpoint}.
-     * The convention used for a {@link ManagedEndpoint} ObjectName is:
-     * <tt>&lt;domain&gt;:context=&lt;context-name&gt;,type=endpoint,component=&lt;component-name&gt;name=&lt;endpoint-name&gt;</tt>
-     */
     public ObjectName getObjectName(ManagedEndpoint mbean) throws MalformedObjectNameException {
         Endpoint ep = mbean.getEndpoint();
 
@@ -99,36 +89,55 @@
         return createObjectName(buffer);
     }
 
-    /**
-     * Implements the naming strategy for a {@link org.apache.camel.impl.ServiceSupport Service}.
-     * The convention used for a {@link org.apache.camel.Service Service} ObjectName is
-     * <tt>&lt;domain&gt;:context=&lt;context-name&gt;,type=service,name=&lt;service-name&gt;</tt>
-     */
-    public ObjectName getObjectName(CamelContext context, ManagedService mbean) throws MalformedObjectNameException {
-        String serviceBranch;
-        Service service = mbean.getService();
-        if (service instanceof Consumer) {
-            serviceBranch = TYPE_CONSUMER;
+    public ObjectName getObjectName(ManagedComponent mbean) throws MalformedObjectNameException {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append(domainName).append(":");
+        buffer.append(KEY_CONTEXT + "=").append(getContextId(mbean.getComponent().getCamelContext())).append(",");
+        buffer.append(KEY_TYPE + "=" + TYPE_COMPONENT + ",");
+        buffer.append(KEY_NAME + "=").append(ObjectName.quote(mbean.getName()));
+        return createObjectName(buffer);
+    }
+
+    public ObjectName getObjectName(ManagedProcessor mbean) throws MalformedObjectNameException {
+        Processor processor = mbean.getProcessor();
+        ProcessorDefinition definition = mbean.getDefinition();
+
+        StringBuffer buffer = new StringBuffer();
+        buffer.append(domainName).append(":");
+        buffer.append(KEY_CONTEXT + "=").append(getContextId(mbean.getContext())).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 {
-            return null;
+            // create a name based on its instance
+            buffer.append(KEY_NAME + "=")
+                .append(processor.getClass().getSimpleName())
+                .append("(").append(getIdentityHashCode(processor)).append(")");
         }
+        return createObjectName(buffer);
+    }
+
+    public ObjectName getObjectName(ManagedConsumer mbean) throws MalformedObjectNameException {
+        Consumer consumer = mbean.getConsumer();
 
         StringBuffer buffer = new StringBuffer();
         buffer.append(domainName).append(":");
-        buffer.append(KEY_CONTEXT + "=").append(getContextId(context)).append(",");
-        buffer.append(KEY_TYPE + "=" + serviceBranch + ",");
+        buffer.append(KEY_CONTEXT + "=").append(getContextId(mbean.getContext())).append(",");
+        buffer.append(KEY_TYPE + "=").append(TYPE_CONSUMER).append(",");
         buffer.append(KEY_NAME + "=")
-            .append(service.getClass().getSimpleName())
-            .append("(0x").append(Integer.toHexString(mbean.getService().hashCode())).append(")");
+            .append(consumer.getClass().getSimpleName())
+            .append("(").append(getIdentityHashCode(consumer)).append(")");
         return createObjectName(buffer);
     }
 
+    public ObjectName getObjectName(ManagedService mbean) throws MalformedObjectNameException {
+        // not supported
+        return null;
+    }
 
-    /**
-     * Implements the naming strategy for a {@link ManagedRoute}.
-     * The convention used for a {@link ManagedRoute} ObjectName is:
-     * <tt>&lt;domain&gt;:context=&lt;context-name&gt;,route=&lt;route-name&gt;,type=route,name=&lt;route-name&gt;</tt>
-     */
     public ObjectName getObjectName(ManagedRoute mbean) throws MalformedObjectNameException {
         Route route = mbean.getRoute();
         Endpoint ep = route.getEndpoint();
@@ -138,37 +147,22 @@
         buffer.append(domainName).append(":");
         buffer.append(KEY_CONTEXT + "=").append(getContextId(ep.getCamelContext())).append(",");
         buffer.append(KEY_TYPE + "=" + TYPE_ROUTE + ",");
-        buffer.append(KEY_NAME + "=").append(ObjectName.quote(id == null ? ("0x" + Integer.toHexString(route.hashCode())) : id));
+        buffer.append(KEY_NAME + "=").append(ObjectName.quote(id));
         return createObjectName(buffer);
     }
 
-    /**
-     * Implements the naming strategy for a {@link ProcessorDefinition}.
-     * The convention used for a {@link ProcessorDefinition} ObjectName is:
-     * <tt>&lt;domain&gt;:context=&lt;context-name&gt;,route=&lt;route-name&gt;,type=processor,name=&lt;processor-name&gt;,nodeid=&lt;node-id&gt;</tt>
-     */
+    @Deprecated
     public ObjectName getObjectName(RouteContext routeContext, ProcessorDefinition processor)
         throws MalformedObjectNameException {
+
         Endpoint ep = routeContext.getEndpoint();
-        String ctxid;
-        String cid;
-        if (ep != null) {
-            ctxid = getContextId(ep.getCamelContext());            
-            cid = ObjectName.quote(ep.getEndpointUri());
-        } else {
-            ctxid = VALUE_UNKNOWN;
-            cid = null;
-        }
-        //String id = VALUE_UNKNOWN.equals(cid) ? ObjectName.quote(getEndpointId(ep) : "[" + cid + "]" + ObjectName.quote(getEndpointId(ep);
         String nodeId = processor.idOrCreate(routeContext.getCamelContext().getNodeIdFactory());
 
         StringBuffer buffer = new StringBuffer();
         buffer.append(domainName).append(":");
-        buffer.append(KEY_CONTEXT + "=").append(ctxid).append(",");
-        // buffer.append(KEY_ROUTE + "=").append(id).append(",");
+        buffer.append(KEY_CONTEXT + "=").append(getContextId(ep.getCamelContext())).append(",");
         buffer.append(KEY_TYPE + "=" + TYPE_PROCESSOR + ",");
-        buffer.append(KEY_NODE_ID + "=").append(nodeId).append(",");
-        buffer.append(KEY_NAME + "=").append(ObjectName.quote(processor.toString()));
+        buffer.append(KEY_NAME + "=").append(ObjectName.quote(nodeId));
         return createObjectName(buffer);
     }
 
@@ -200,11 +194,15 @@
             String uri = ep.getEndpointKey();
             int pos = uri.indexOf('?');
             String id = (pos == -1) ? uri : uri.substring(0, pos);
-            id += "?id=0x" + Integer.toHexString(ep.hashCode());
+            id += "?id=" + getIdentityHashCode(ep);
             return id;
         }
     }
 
+    private static String getIdentityHashCode(Object object) {
+        return "0x" + Integer.toHexString(System.identityHashCode(object));
+    }
+
     /**
      * Factory method to create an ObjectName escaping any required characters
      */

Added: camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementStrategy.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementStrategy.java?rev=807573&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementStrategy.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementStrategy.java Tue Aug 25 11:57:51 2009
@@ -0,0 +1,149 @@
+/**
+ * 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 java.util.EventObject;
+
+import org.apache.camel.model.ProcessorDefinition;
+import org.apache.camel.spi.EventFactory;
+import org.apache.camel.spi.EventNotifier;
+import org.apache.camel.spi.ManagementAgent;
+import org.apache.camel.spi.ManagementNamingStrategy;
+import org.apache.camel.spi.ManagementStrategy;
+import org.fusesource.commons.management.Statistic;
+
+/**
+ * A default management strategy that does <b>not</b> manage.
+ * <p/>
+ * This is default only used if Camel detects that it cannot use the JMX capable
+ * {@link org.apache.camel.management.ManagedManagementStrategy} strategy. Then Camel will
+ * fallback to use this instead that is basically a simple and <tt>noop</tt> strategy.
+ * <p/>
+ * This class can also be used to extend your custom management implement. In fact the JMX capable
+ * provided by Camel extends this class as well.
+ *
+ * @see ManagedManagementStrategy
+ * @version $Revision$
+ */
+public class DefaultManagementStrategy implements ManagementStrategy {
+
+    private EventNotifier eventNotifier = new DefaultEventNotifier();
+    private EventFactory eventFactory = new DefaultEventFactory();
+    private ManagementNamingStrategy managementNamingStrategy;
+    private boolean onlyManageProcessorWithCustomId;
+    private ManagementAgent managementAgent;
+
+    public EventNotifier getEventNotifier() {
+        return eventNotifier;
+    }
+
+    public void setEventNotifier(EventNotifier eventNotifier) {
+        this.eventNotifier = eventNotifier;
+    }
+
+    public EventFactory getEventFactory() {
+        return eventFactory;
+    }
+
+    public void setEventFactory(EventFactory eventFactory) {
+        this.eventFactory = eventFactory;
+    }
+
+    public ManagementNamingStrategy getManagementNamingStrategy() {
+        if (managementNamingStrategy == null) {
+            managementNamingStrategy = new DefaultManagementNamingStrategy();
+        }
+        return managementNamingStrategy;
+    }
+
+    public void setManagementNamingStrategy(ManagementNamingStrategy managementNamingStrategy) {
+        this.managementNamingStrategy = managementNamingStrategy;
+    }
+
+    public ManagementAgent getManagementAgent() {
+        return managementAgent;
+    }
+
+    public void setManagementAgent(ManagementAgent managementAgent) {
+        this.managementAgent = managementAgent;
+    }
+
+    public void onlyManageProcessorWithCustomId(boolean flag) {
+        onlyManageProcessorWithCustomId = flag;
+    }
+
+    public boolean isOnlyManageProcessorWithCustomId() {
+        return onlyManageProcessorWithCustomId;
+    }
+
+    public boolean manageProcessor(ProcessorDefinition definition) {
+        return false;
+    }
+
+    public void manageObject(Object o) throws Exception {
+        // noop
+    }
+
+    public void manageNamedObject(Object o, Object o1) throws Exception {
+        // noop
+    }
+
+    public <T> T getManagedObjectName(Object o, String s, Class<T> tClass) throws Exception {
+        // noop
+        return null;
+    }
+
+    public void unmanageObject(Object o) throws Exception {
+        // noop
+    }
+
+    public void unmanageNamedObject(Object o) throws Exception {
+        // noop
+    }
+
+    public boolean isManaged(Object o, Object o1) {
+        // noop
+        return false;
+    }
+
+    public void notify(EventObject event) throws Exception {
+        if (eventNotifier != null && eventNotifier.isEnabled(event)) {
+            eventNotifier.notify(event);
+        }
+    }
+
+    public Statistic createStatistic(String name, Object owner, Statistic.UpdateMode updateMode) {
+        // noop
+        return null;
+    }
+
+    public void start() throws Exception {
+        if (managementAgent != null) {
+            managementAgent.start();
+            // set the naming strategy using the domain name from the agent
+            if (managementNamingStrategy == null) {
+                setManagementNamingStrategy(new DefaultManagementNamingStrategy(managementAgent.getMBeanObjectDomainName()));
+            }
+        }
+    }
+
+    public void stop() throws Exception {
+        if (managementAgent != null) {
+            managementAgent.stop();
+        }
+    }
+}

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementStrategy.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date