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 2010/11/05 08:40:03 UTC

svn commit: r1031461 [1/2] - in /camel/trunk: apache-camel/ apache-camel/src/main/descriptors/ components/ components/camel-jmx/ components/camel-jmx/src/ components/camel-jmx/src/main/ components/camel-jmx/src/main/java/ components/camel-jmx/src/main/...

Author: davsclaus
Date: Fri Nov  5 07:40:01 2010
New Revision: 1031461

URL: http://svn.apache.org/viewvc?rev=1031461&view=rev
Log:
CAMEL-3236: New camel-jmx component. Thanks to Mark Ford for donating to Apache.

Added:
    camel/trunk/components/camel-jmx/   (with props)
    camel/trunk/components/camel-jmx/pom.xml   (with props)
    camel/trunk/components/camel-jmx/src/
    camel/trunk/components/camel-jmx/src/main/
    camel/trunk/components/camel-jmx/src/main/java/
    camel/trunk/components/camel-jmx/src/main/java/org/
    camel/trunk/components/camel-jmx/src/main/java/org/apache/
    camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/
    camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/
    camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/
    camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/JMXComponent.java   (with props)
    camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/JMXConsumer.java   (with props)
    camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/JMXEndpoint.java   (with props)
    camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/JMXUriBuilder.java   (with props)
    camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/NotificationFormatException.java   (with props)
    camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/NotificationXmlFormatter.java   (with props)
    camel/trunk/components/camel-jmx/src/main/resources/
    camel/trunk/components/camel-jmx/src/main/resources/META-INF/
    camel/trunk/components/camel-jmx/src/main/resources/META-INF/services/
    camel/trunk/components/camel-jmx/src/main/resources/META-INF/services/org/
    camel/trunk/components/camel-jmx/src/main/resources/META-INF/services/org/apache/
    camel/trunk/components/camel-jmx/src/main/resources/META-INF/services/org/apache/camel/
    camel/trunk/components/camel-jmx/src/main/resources/META-INF/services/org/apache/camel/component/
    camel/trunk/components/camel-jmx/src/main/resources/META-INF/services/org/apache/camel/component/jmx
    camel/trunk/components/camel-jmx/src/main/resources/notifications.xsd   (with props)
    camel/trunk/components/camel-jmx/src/test/
    camel/trunk/components/camel-jmx/src/test/java/
    camel/trunk/components/camel-jmx/src/test/java/org/
    camel/trunk/components/camel-jmx/src/test/java/org/apache/
    camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/
    camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/
    camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/
    camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXComponentTest.java   (with props)
    camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXConsumerTest.java   (with props)
    camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXEndpointTest.java   (with props)
    camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXHandbackTest.java   (with props)
    camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXMonitorTest.java   (with props)
    camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXNotificationFilterTest.java   (with props)
    camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXObjectPropertiesTest.java   (with props)
    camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXRemoteTest.java   (with props)
    camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXUriBuilderTest.java   (with props)
    camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/SimpleBeanFixture.java   (with props)
    camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/XmlFixture.java   (with props)
    camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/beans/
    camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/beans/ISimpleMXBean.java   (with props)
    camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/beans/SimpleBean.java   (with props)
    camel/trunk/components/camel-jmx/src/test/resources/
    camel/trunk/components/camel-jmx/src/test/resources/consumer-test/
    camel/trunk/components/camel-jmx/src/test/resources/consumer-test/attributeChange-0.xml   (with props)
    camel/trunk/components/camel-jmx/src/test/resources/consumer-test/attributeChange-1.xml   (with props)
    camel/trunk/components/camel-jmx/src/test/resources/consumer-test/attributeChange-2.xml   (with props)
    camel/trunk/components/camel-jmx/src/test/resources/consumer-test/jmxConnectionNotification.xml   (with props)
    camel/trunk/components/camel-jmx/src/test/resources/consumer-test/mbeanServerNotification.xml   (with props)
    camel/trunk/components/camel-jmx/src/test/resources/consumer-test/monitorNotification.xml   (with props)
    camel/trunk/components/camel-jmx/src/test/resources/consumer-test/relationNotification.xml   (with props)
    camel/trunk/components/camel-jmx/src/test/resources/consumer-test/timerNotification.xml   (with props)
    camel/trunk/components/camel-jmx/src/test/resources/consumer-test/touched.xml   (with props)
    camel/trunk/components/camel-jmx/src/test/resources/consumer-test/userdata.xml   (with props)
    camel/trunk/components/camel-jmx/src/test/resources/log4j.properties   (with props)
    camel/trunk/components/camel-jmx/src/test/resources/stripTimestamp.xsl   (with props)
Modified:
    camel/trunk/apache-camel/pom.xml
    camel/trunk/apache-camel/src/main/descriptors/common-bin.xml
    camel/trunk/components/pom.xml
    camel/trunk/parent/pom.xml

Modified: camel/trunk/apache-camel/pom.xml
URL: http://svn.apache.org/viewvc/camel/trunk/apache-camel/pom.xml?rev=1031461&r1=1031460&r2=1031461&view=diff
==============================================================================
--- camel/trunk/apache-camel/pom.xml (original)
+++ camel/trunk/apache-camel/pom.xml Fri Nov  5 07:40:01 2010
@@ -192,6 +192,10 @@
     </dependency>
     <dependency>
       <groupId>org.apache.camel</groupId>
+      <artifactId>camel-jmx</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.camel</groupId>
       <artifactId>camel-josql</artifactId>
     </dependency>
     <dependency>

Modified: camel/trunk/apache-camel/src/main/descriptors/common-bin.xml
URL: http://svn.apache.org/viewvc/camel/trunk/apache-camel/src/main/descriptors/common-bin.xml?rev=1031461&r1=1031460&r2=1031461&view=diff
==============================================================================
--- camel/trunk/apache-camel/src/main/descriptors/common-bin.xml (original)
+++ camel/trunk/apache-camel/src/main/descriptors/common-bin.xml Fri Nov  5 07:40:01 2010
@@ -71,6 +71,7 @@
         <include>org.apache.camel:camel-jetty</include>
         <include>org.apache.camel:camel-jing</include>
         <include>org.apache.camel:camel-jms</include>
+        <include>org.apache.camel:camel-jmx</include>
         <include>org.apache.camel:camel-josql</include>
         <include>org.apache.camel:camel-jpa</include>
         <include>org.apache.camel:camel-jt400</include>

Propchange: camel/trunk/components/camel-jmx/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Fri Nov  5 07:40:01 2010
@@ -0,0 +1,9 @@
+.checkstyle
+.pmd
+target
+eclipse-classes
+.classpath
+.project
+.settings
+res
+*.i??

Added: camel/trunk/components/camel-jmx/pom.xml
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jmx/pom.xml?rev=1031461&view=auto
==============================================================================
--- camel/trunk/components/camel-jmx/pom.xml (added)
+++ camel/trunk/components/camel-jmx/pom.xml Fri Nov  5 07:40:01 2010
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>camel-parent</artifactId>
+        <version>2.6-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>camel-jmx</artifactId>
+    <packaging>bundle</packaging>
+    <name>Camel :: JMX</name>
+    <description>Camel JMX support</description>
+
+    <properties>
+        <camel.osgi.export.pkg>org.apache.camel.component.jmx.*</camel.osgi.export.pkg>
+    </properties>
+
+    <!-- TODO: move net.java.dev.jaxb2-commons to fusesource repo --> 
+    <repositories>
+        <repository>
+            <id>camel-jmx</id>
+            <url>http://camel-jmx.googlecode.com/svn/trunk/repository/</url>
+        </repository>
+    </repositories>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>xmlunit</groupId>
+            <artifactId>xmlunit</artifactId>
+            <version>1.3</version>
+            <scope>test</scope>
+        </dependency>
+        <!-- to allow Spring annotations (jmx) to be tested -->
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context</artifactId>
+            <optional>true</optional>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-aop</artifactId>
+            <optional>true</optional>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.jvnet.jaxb2.maven2</groupId>
+                <artifactId>maven-jaxb2-plugin</artifactId>
+                <version>0.7.4</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>generate</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <strict>false</strict>
+                    <extension>true</extension>
+                    <args>
+                        <arg>-Xfluent-api</arg>
+                    </args>
+                    <plugins>
+                        <plugin>
+                            <groupId>net.java.dev.jaxb2-commons</groupId>
+                            <artifactId>jaxb-fluent-api</artifactId>
+                            <version>2.1.8</version>
+                        </plugin>
+                    </plugins>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

Propchange: camel/trunk/components/camel-jmx/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/components/camel-jmx/pom.xml
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Propchange: camel/trunk/components/camel-jmx/pom.xml
------------------------------------------------------------------------------
    svn:mime-type = text/xml

Added: camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/JMXComponent.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/JMXComponent.java?rev=1031461&view=auto
==============================================================================
--- camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/JMXComponent.java (added)
+++ camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/JMXComponent.java Fri Nov  5 07:40:01 2010
@@ -0,0 +1,74 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.jmx;
+
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.impl.DefaultComponent;
+import org.apache.camel.util.EndpointHelper;
+
+/**
+ * Component for connecting JMX Notification events to a camel route.
+ * The endpoint created from this component allows users to specify
+ * an ObjectName to listen to and any JMX Notifications received from
+ * that object will flow into the route.
+ */
+public class JMXComponent extends DefaultComponent {
+
+    @Override
+    protected Endpoint createEndpoint(String aUri, String aRemaining,
+                                      Map<String, Object> aParameters) throws Exception {
+        JMXEndpoint endpoint = new JMXEndpoint(aUri, this);
+        // use the helper class to set all of the properties
+        EndpointHelper.setReferenceProperties(getCamelContext(), endpoint, aParameters);
+        EndpointHelper.setProperties(getCamelContext(), endpoint, aParameters);
+
+        endpoint.setServerURL(aRemaining);
+
+        // we may have some extra params left over for the object properties hashtable
+        // these properties need to be consumed or the framework will throw an exception
+        // for unused params
+        if (!aParameters.isEmpty()) {
+            Hashtable<String, String> objectProperties = new Hashtable<String, String>();
+
+            for (Iterator<Entry<String, Object>> it = aParameters.entrySet().iterator(); it.hasNext();) {
+                Entry<String, Object> entry = it.next();
+                if (entry.getKey().startsWith("key.")) {
+                    objectProperties.put(entry.getKey().substring("key.".length()), entry.getValue().toString());
+                    it.remove();
+                }
+            }
+
+            endpoint.setObjectProperties(objectProperties);
+        }
+
+        if (endpoint.getObjectDomain() == null) {
+            throw new IllegalArgumentException("Must specify domain");
+        }
+
+        if (endpoint.getObjectName() == null && endpoint.getObjectProperties() == null) {
+            throw new IllegalArgumentException("Must specify object name or object properties");
+        }
+
+        return endpoint;
+    }
+
+}

Propchange: camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/JMXComponent.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/JMXComponent.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/JMXConsumer.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/JMXConsumer.java?rev=1031461&view=auto
==============================================================================
--- camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/JMXConsumer.java (added)
+++ camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/JMXConsumer.java Fri Nov  5 07:40:01 2010
@@ -0,0 +1,136 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.jmx;
+
+import java.lang.management.ManagementFactory;
+import java.util.Collections;
+import java.util.Map;
+import javax.management.MBeanServerConnection;
+import javax.management.Notification;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXServiceURL;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.ExchangePattern;
+import org.apache.camel.Message;
+import org.apache.camel.Processor;
+import org.apache.camel.impl.DefaultConsumer;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Consumer will add itself as a NotificationListener on the object
+ * specified by the objectName param.
+ */
+public class JMXConsumer extends DefaultConsumer implements NotificationListener {
+    private static final Log LOG = LogFactory.getLog(JMXConsumer.class);
+
+    /**
+     * connection to the mbean server (local or remote)
+     */
+    private MBeanServerConnection mServerConnection;
+
+    /**
+     * used to format Notification objects as xml
+     */
+    private NotificationXmlFormatter mFormatter;
+
+    public JMXConsumer(JMXEndpoint aEndpoint, Processor aProcessor) {
+        super(aEndpoint, aProcessor);
+        mFormatter = new NotificationXmlFormatter();
+    }
+
+    /**
+     * Initializes the mbean server connection and starts listening for
+     * Notification events from the object.
+     */
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+
+        JMXEndpoint ep = (JMXEndpoint) getEndpoint();
+
+        // connect to the mbean server
+        if (ep.isPlatformServer()) {
+            setServerConnection(ManagementFactory.getPlatformMBeanServer());
+        } else {
+            JMXServiceURL url = new JMXServiceURL(ep.getServerURL());
+            String[] creds = {ep.getUser(), ep.getPassword()};
+            Map map = Collections.singletonMap(JMXConnector.CREDENTIALS, creds);
+            JMXConnector connector = JMXConnectorFactory.connect(url, map);
+            setServerConnection(connector.getMBeanServerConnection());
+        }
+        // subscribe
+        NotificationFilter nf = ep.getNotificationFilter();
+
+        ObjectName objectName = ep.getJMXObjectName();
+
+        getServerConnection().addNotificationListener(objectName, this, nf, ep.getHandback());
+    }
+
+    /**
+     * Removes the notification listener
+     */
+    @Override
+    protected void doStop() throws Exception {
+        super.doStop();
+        JMXEndpoint ep = (JMXEndpoint) getEndpoint();
+        getServerConnection().removeNotificationListener(ep.getJMXObjectName(), this);
+    }
+
+    protected MBeanServerConnection getServerConnection() {
+        return mServerConnection;
+    }
+
+    protected void setServerConnection(MBeanServerConnection aServerConnection) {
+        mServerConnection = aServerConnection;
+    }
+
+    /**
+     * Processes the Notification received. The handback will be set as
+     * the header "jmx.handback" while the Notification will be set as
+     * the body.
+     * <p/>
+     * If the format is set to "xml" then the Notification will be converted
+     * to XML first using {@link NotificationXmlFormatter}
+     *
+     * @see javax.management.NotificationListener#handleNotification(javax.management.Notification, java.lang.Object)
+     */
+    public void handleNotification(Notification aNotification, Object aHandback) {
+        JMXEndpoint ep = (JMXEndpoint) getEndpoint();
+        Exchange exchange = getEndpoint().createExchange(ExchangePattern.InOnly);
+        Message message = exchange.getIn();
+        message.setHeader("jmx.handback", aHandback);
+        try {
+            if (ep.isXML()) {
+                message.setBody(mFormatter.format(aNotification));
+            } else {
+                message.setBody(aNotification);
+            }
+            getProcessor().process(exchange);
+        } catch (NotificationFormatException e) {
+            getExceptionHandler().handleException("Failed to marshal notification", e);
+        } catch (Exception e) {
+            getExceptionHandler().handleException("Failed to process notification", e);
+        }
+    }
+
+}

Propchange: camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/JMXConsumer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/JMXConsumer.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/JMXEndpoint.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/JMXEndpoint.java?rev=1031461&view=auto
==============================================================================
--- camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/JMXEndpoint.java (added)
+++ camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/JMXEndpoint.java Fri Nov  5 07:40:01 2010
@@ -0,0 +1,229 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.jmx;
+
+import java.util.Hashtable;
+import javax.management.MalformedObjectNameException;
+import javax.management.NotificationFilter;
+import javax.management.ObjectName;
+
+import org.apache.camel.Consumer;
+import org.apache.camel.Processor;
+import org.apache.camel.Producer;
+import org.apache.camel.impl.DefaultEndpoint;
+
+/**
+ * Endpoint that describes a connection to an mbean.
+ * <p/>
+ * The component can connect to the local platform mbean server with the following URI:
+ * <p/>
+ * <code>jmx://platform?options</code>
+ * <p/>
+ * A remote mbean server url can be provided following the initial JMX scheme like so:
+ * <p/>
+ * <code>jmx:service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi?options</code>
+ * <p/>
+ * You can append query options to the URI in the following format, ?options=value&option2=value&...
+ *
+ * @author markford
+ */
+public class JMXEndpoint extends DefaultEndpoint {
+
+    /**
+     * URI Property: Format for the message body. Either "xml" or "raw". If xml, the notification is serialized to xml. If raw, then the raw java object is set as the body.
+     */
+    private String mFormat = "xml";
+
+    /**
+     * URI Property: credentials for making a remote connection
+     */
+    private String mUser;
+
+    /**
+     * URI Property: credentials for making a remote connection
+     */
+    private String mPassword;
+
+    /**
+     * URI Property: The domain for the mbean you're connecting to
+     */
+    private String mObjectDomain;
+
+    /**
+     * URI Property: The name key for the mbean you're connecting to. This value is mutually exclusive with the object properties that get passed.
+     */
+    private String mObjectName;
+
+    /**
+     * URI Property: Reference to a bean that implements the NotificationFilter.
+     */
+    private NotificationFilter mNotificationFilter;
+
+    /**
+     * URI Property: Value to handback to the listener when a notification is received. This value will be put in the message header with the key "jmx.handback"
+     */
+    private Object mHandback;
+
+    /**
+     * URI Property: properties for the object name. These values will be used if the objectName param is not set
+     */
+    private Hashtable<String, String> mObjectProperties;
+
+    /**
+     * cached object name that was built from the objectName param or the hashtable
+     */
+    private ObjectName mJMXObjectName;
+    /**
+     * server url comes from the remaining endpoint
+     */
+    private String mServerURL;
+
+    public JMXEndpoint(String aEndpointUri, JMXComponent aComponent) {
+        super(aEndpointUri, aComponent);
+    }
+
+    public Consumer createConsumer(Processor aProcessor) throws Exception {
+        return new JMXConsumer(this, aProcessor);
+    }
+
+    public Producer createProducer() throws Exception {
+        throw new UnsupportedOperationException("producing JMX notifications is not supported");
+    }
+
+    public boolean isSingleton() {
+        return false;
+    }
+
+    public String getFormat() {
+        return mFormat;
+    }
+
+    public void setFormat(String aFormat) {
+        mFormat = aFormat;
+    }
+
+    public boolean isXML() {
+        return "xml".equals(getFormat());
+    }
+
+    public boolean isPlatformServer() {
+        return "platform".equals(getServerURL());
+    }
+
+    public String getUser() {
+        return mUser;
+    }
+
+    public void setUser(String aUser) {
+        mUser = aUser;
+    }
+
+    public String getPassword() {
+        return mPassword;
+    }
+
+    public void setPassword(String aPassword) {
+        mPassword = aPassword;
+    }
+
+    public String getObjectDomain() {
+        return mObjectDomain;
+    }
+
+    public void setObjectDomain(String aObjectDomain) {
+        mObjectDomain = aObjectDomain;
+    }
+
+    public String getObjectName() {
+        return mObjectName;
+    }
+
+    public void setObjectName(String aObjectName) {
+        if (getObjectProperties() != null) {
+            throw new IllegalArgumentException("Cannot set both objectName and objectProperties");
+        }
+        mObjectName = aObjectName;
+    }
+
+    protected String getServerURL() {
+        return mServerURL;
+    }
+
+    protected void setServerURL(String aServerURL) {
+        mServerURL = aServerURL;
+    }
+
+    public NotificationFilter getNotificationFilter() {
+        return mNotificationFilter;
+    }
+
+    public void setNotificationFilter(NotificationFilter aFilterRef) {
+        mNotificationFilter = aFilterRef;
+    }
+
+    public Object getHandback() {
+        return mHandback;
+    }
+
+    public void setHandback(Object aHandback) {
+        mHandback = aHandback;
+    }
+
+    public Hashtable<String, String> getObjectProperties() {
+        return mObjectProperties;
+    }
+
+    /**
+     * Setter for the ObjectProperties is either called by reflection when
+     * processing the URI or manually by the component.
+     * <p/>
+     * If the URI contained a value with a reference like "objectProperties=#myHashtable"
+     * then the Hashtable will be set in place.
+     * <p/>
+     * If there are extra properties that begin with "key." then the component will
+     * create a Hashtable with these values after removing the "key." prefix.
+     */
+    public void setObjectProperties(Hashtable<String, String> aObjectProperties) {
+        if (getObjectName() != null) {
+            throw new IllegalArgumentException("Cannot set both objectName and objectProperties");
+        }
+        mObjectProperties = aObjectProperties;
+    }
+
+    protected ObjectName getJMXObjectName() throws MalformedObjectNameException {
+        if (mJMXObjectName == null) {
+            ObjectName on = buildObjectName();
+            setJMXObjectName(on);
+        }
+        return mJMXObjectName;
+    }
+
+    protected void setJMXObjectName(ObjectName aCachedObjectName) {
+        mJMXObjectName = aCachedObjectName;
+    }
+
+    private ObjectName buildObjectName() throws MalformedObjectNameException {
+        ObjectName objectName;
+        if (getObjectProperties() == null) {
+            StringBuilder sb = new StringBuilder(getObjectDomain()).append(':').append("name=").append(getObjectName());
+            objectName = new ObjectName(sb.toString());
+        } else {
+            objectName = new ObjectName(getObjectDomain(), getObjectProperties());
+        }
+        return objectName;
+    }
+}

Propchange: camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/JMXEndpoint.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/JMXEndpoint.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/JMXUriBuilder.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/JMXUriBuilder.java?rev=1031461&view=auto
==============================================================================
--- camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/JMXUriBuilder.java (added)
+++ camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/JMXUriBuilder.java Fri Nov  5 07:40:01 2010
@@ -0,0 +1,131 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.jmx;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * Builder for JMX endpoint URI's. Saves you from having to do the string concat'ing
+ * and messing up the param names
+ */
+public class JMXUriBuilder {
+    private Map<String, String> mQueryProps = new LinkedHashMap<String, String>();
+    private String mServerName = "platform";
+
+    public JMXUriBuilder() {
+    }
+
+    public JMXUriBuilder(String aServerName) {
+        setServerName(aServerName);
+    }
+
+    public JMXUriBuilder withFormat(String aFormat) {
+        addProperty("format", aFormat);
+        return this;
+    }
+
+    public JMXUriBuilder withUser(String aFormat) {
+        addProperty("user", aFormat);
+        return this;
+    }
+
+    public JMXUriBuilder withPassword(String aFormat) {
+        addProperty("password", aFormat);
+        return this;
+    }
+
+    public JMXUriBuilder withObjectDomain(String aFormat) {
+        addProperty("objectDomain", aFormat);
+        return this;
+    }
+
+    public JMXUriBuilder withObjectName(String aFormat) {
+        addProperty("objectName", aFormat);
+        return this;
+    }
+
+    public JMXUriBuilder withNotificationFilter(String aFilter) {
+        addProperty("notificationFilter", aFilter);
+        return this;
+    }
+
+    public JMXUriBuilder withHandback(String aHandback) {
+        addProperty("handback", aHandback);
+        return this;
+    }
+
+    /**
+     * Converts all of the values to params with the "key." prefix so the
+     * component will pick up on them and set them on the endpoint. Alternatively,
+     * you can pass in a reference to a Hashtable using the version of this
+     * method that takes a single string.
+     */
+    public JMXUriBuilder withObjectProperties(Map<String, String> aPropertiesSansKeyPrefix) {
+        for (Entry<String, String> entry : aPropertiesSansKeyPrefix.entrySet()) {
+            addProperty("key." + entry.getKey(), entry.getValue());
+        }
+        return this;
+    }
+
+    /**
+     * Your value should start with a hash mark since it's a reference to a value.
+     * This method will add the hash mark if it's not present.
+     */
+    public JMXUriBuilder withObjectPropertiesReference(String aReferenceToHashtable) {
+        if (aReferenceToHashtable.startsWith("#")) {
+            addProperty("objectProperties", aReferenceToHashtable);
+        } else {
+            addProperty("objectProperties", "#" + aReferenceToHashtable);
+        }
+        return this;
+    }
+
+    protected void addProperty(String aName, String aValue) {
+        mQueryProps.put(aName, aValue);
+    }
+
+    public String getServerName() {
+        return mServerName;
+    }
+
+    public void setServerName(String aServerName) {
+        mServerName = aServerName;
+    }
+
+    public JMXUriBuilder withServerName(String aServerName) {
+        setServerName(aServerName);
+        return this;
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder("jmx:").append(getServerName());
+        if (!mQueryProps.isEmpty()) {
+            sb.append('?');
+
+            String delim = "";
+            for (Entry<String, String> entry : mQueryProps.entrySet()) {
+                sb.append(delim);
+                sb.append(entry.getKey()).append('=').append(entry.getValue());
+                delim = "&";
+            }
+        }
+        return sb.toString();
+    }
+
+}

Propchange: camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/JMXUriBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/JMXUriBuilder.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/NotificationFormatException.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/NotificationFormatException.java?rev=1031461&view=auto
==============================================================================
--- camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/NotificationFormatException.java (added)
+++ camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/NotificationFormatException.java Fri Nov  5 07:40:01 2010
@@ -0,0 +1,28 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.jmx;
+
+/**
+ * Reports a problem formatting the Notification. This will be a JAXB related issue.
+ */
+public class NotificationFormatException extends Exception {
+
+    public NotificationFormatException(Exception aCausedBy) {
+        super(aCausedBy);
+    }
+
+}

Propchange: camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/NotificationFormatException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/NotificationFormatException.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/NotificationXmlFormatter.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/NotificationXmlFormatter.java?rev=1031461&view=auto
==============================================================================
--- camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/NotificationXmlFormatter.java (added)
+++ camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/NotificationXmlFormatter.java Fri Nov  5 07:40:01 2010
@@ -0,0 +1,172 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.jmx;
+
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.List;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import javax.management.AttributeChangeNotification;
+import javax.management.MBeanServerNotification;
+import javax.management.Notification;
+import javax.management.ObjectName;
+import javax.management.monitor.MonitorNotification;
+import javax.management.relation.RelationNotification;
+import javax.management.remote.JMXConnectionNotification;
+import javax.management.timer.TimerNotification;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.datatype.DatatypeConfigurationException;
+import javax.xml.datatype.DatatypeFactory;
+
+import org.apache.camel.component.jmx.jaxb.NotificationEventType;
+import org.apache.camel.component.jmx.jaxb.ObjectFactory;
+import org.apache.camel.component.jmx.jaxb.ObjectNamesType;
+
+/**
+ * Converts the Notification into an XML stream.
+ *
+ * @author markford
+ */
+public class NotificationXmlFormatter {
+
+    private DatatypeFactory mDatatypeFactory;
+    private Marshaller mMarshaller;
+    private Lock mMarshallerLock = new ReentrantLock(false);
+    private ObjectFactory mObjectFactory = new ObjectFactory();
+
+    public String format(Notification aNotification) throws NotificationFormatException {
+
+        NotificationEventType jaxb = null;
+
+        boolean wrap = false;
+
+        if (aNotification instanceof AttributeChangeNotification) {
+            AttributeChangeNotification ac = (AttributeChangeNotification) aNotification;
+
+            jaxb = mObjectFactory.createAttributeChangeNotification()
+                    .withAttributeName(ac.getAttributeName())
+                    .withAttributeType(ac.getAttributeType())
+                    .withNewValue(ac.getNewValue() == null ? null : String.valueOf(ac.getNewValue()))
+                    .withOldValue(ac.getOldValue() == null ? null : String.valueOf(ac.getOldValue()));
+        } else if (aNotification instanceof JMXConnectionNotification) {
+            jaxb = mObjectFactory.createJMXConnectionNotification()
+                    .withConnectionId(((JMXConnectionNotification) aNotification).getConnectionId());
+        } else if (aNotification instanceof MBeanServerNotification) {
+            jaxb = mObjectFactory.createMBeanServerNotification()
+                    .withMBeanName(String.valueOf(((MBeanServerNotification) aNotification).getMBeanName()));
+        } else if (aNotification instanceof MonitorNotification) {
+            MonitorNotification mn = (MonitorNotification) aNotification;
+            jaxb = mObjectFactory.createMonitorNotification()
+                    .withDerivedGauge(String.valueOf(mn.getDerivedGauge()))
+                    .withObservedAttribute(mn.getObservedAttribute())
+                    .withObservedObject(String.valueOf(mn.getObservedObject()))
+                    .withTrigger(String.valueOf(mn.getTrigger()));
+        } else if (aNotification instanceof RelationNotification) {
+            RelationNotification rn = (RelationNotification) aNotification;
+            jaxb = mObjectFactory.createRelationNotification()
+                    .withObjectName(String.valueOf(rn.getObjectName()))
+                    .withRelationId(rn.getRelationId())
+                    .withRelationTypeName(rn.getRelationTypeName())
+                    .withRoleName(rn.getRoleName());
+            if (rn.getNewRoleValue() != null) {
+                ObjectNamesType ont = toObjectNamesType(rn.getNewRoleValue());
+                ((org.apache.camel.component.jmx.jaxb.RelationNotification) jaxb).withNewRoleValue(ont);
+            }
+            if (rn.getOldRoleValue() != null) {
+                ObjectNamesType ont = toObjectNamesType(rn.getOldRoleValue());
+                ((org.apache.camel.component.jmx.jaxb.RelationNotification) jaxb).withOldRoleValue(ont);
+            }
+            if (rn.getMBeansToUnregister() != null) {
+                ObjectNamesType ont = toObjectNamesType(rn.getMBeansToUnregister());
+                ((org.apache.camel.component.jmx.jaxb.RelationNotification) jaxb).withMBeansToUnregister(ont);
+            }
+        } else if (aNotification instanceof TimerNotification) {
+            jaxb = mObjectFactory.createTimerNotification().withNotificationId(((TimerNotification) aNotification).getNotificationID());
+        } else {
+            jaxb = mObjectFactory.createNotificationEventType();
+            wrap = true;
+        }
+
+        // add all of the common properties
+        jaxb.withMessage(aNotification.getMessage())
+                .withSequence(aNotification.getSequenceNumber())
+                .withSource(String.valueOf(aNotification.getSource()))
+                .withTimestamp(aNotification.getTimeStamp())
+                .withType(aNotification.getType());
+        if (aNotification.getUserData() != null) {
+            jaxb.withUserData(String.valueOf(aNotification.getUserData()));
+        }
+
+        try {
+            DatatypeFactory df = getDatatypeFactory();
+            Date date = new Date(aNotification.getTimeStamp());
+            GregorianCalendar gc = new GregorianCalendar();
+            gc.setTime(date);
+            jaxb.withDateTime(df.newXMLGregorianCalendar(gc));
+
+            Object bean = wrap ? mObjectFactory.createNotificationEvent(jaxb) : jaxb;
+
+            StringWriter sw = new StringWriter();
+
+            try {
+                mMarshallerLock.lock();
+                getMarshaller(mObjectFactory.getClass().getPackage().getName()).marshal(bean, sw);
+            } finally {
+                mMarshallerLock.unlock();
+            }
+            return sw.toString();
+        } catch (JAXBException e) {
+            throw new NotificationFormatException(e);
+        } catch (DatatypeConfigurationException e) {
+            throw new NotificationFormatException(e);
+        }
+    }
+
+    private ObjectNamesType toObjectNamesType(List<ObjectName> objectNameList) {
+        List<String> roles = toStringList(objectNameList);
+        ObjectNamesType ont = mObjectFactory.createObjectNamesType();
+        ont.withObjectName(roles);
+        return ont;
+    }
+
+    private DatatypeFactory getDatatypeFactory() throws DatatypeConfigurationException {
+        if (mDatatypeFactory == null) {
+            mDatatypeFactory = DatatypeFactory.newInstance();
+        }
+        return mDatatypeFactory;
+    }
+
+    private Marshaller getMarshaller(String aPackageName) throws JAXBException {
+        if (mMarshaller == null) {
+            mMarshaller = JAXBContext.newInstance(aPackageName).createMarshaller();
+        }
+        return mMarshaller;
+    }
+
+    private List<String> toStringList(List<ObjectName> objectNames) {
+        List<String> roles = new ArrayList(objectNames.size());
+        for (ObjectName on : objectNames) {
+            roles.add(on.toString());
+        }
+        return roles;
+    }
+}

Propchange: camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/NotificationXmlFormatter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/components/camel-jmx/src/main/java/org/apache/camel/component/jmx/NotificationXmlFormatter.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/components/camel-jmx/src/main/resources/META-INF/services/org/apache/camel/component/jmx
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jmx/src/main/resources/META-INF/services/org/apache/camel/component/jmx?rev=1031461&view=auto
==============================================================================
--- camel/trunk/components/camel-jmx/src/main/resources/META-INF/services/org/apache/camel/component/jmx (added)
+++ camel/trunk/components/camel-jmx/src/main/resources/META-INF/services/org/apache/camel/component/jmx Fri Nov  5 07:40:01 2010
@@ -0,0 +1,17 @@
+#
+# 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.
+#
+class=org.apache.camel.component.jmx.JMXComponent
\ No newline at end of file

Added: camel/trunk/components/camel-jmx/src/main/resources/notifications.xsd
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jmx/src/main/resources/notifications.xsd?rev=1031461&view=auto
==============================================================================
--- camel/trunk/components/camel-jmx/src/main/resources/notifications.xsd (added)
+++ camel/trunk/components/camel-jmx/src/main/resources/notifications.xsd Fri Nov  5 07:40:01 2010
@@ -0,0 +1,197 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+    targetNamespace="urn:org.apache.camel.component:jmx"
+    xmlns:tns="urn:org.apache.camel.component:jmx" elementFormDefault="qualified"
+    xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
+    jxb:version="1.0">
+    <xs:annotation>
+        <xs:appinfo>
+            <jxb:schemaBindings>
+                <jxb:package name="org.apache.camel.component.jmx.jaxb"/>
+            </jxb:schemaBindings>
+        </xs:appinfo>
+    </xs:annotation>
+
+    <xs:complexType name="notificationEventType">
+        <xs:annotation>
+            <xs:documentation>
+                Base type that includes all of the elements for a 
+                javax.management.Notification
+            </xs:documentation>
+        </xs:annotation>
+        <xs:sequence>
+            <xs:element name="source" type="xs:string"/>
+            <xs:element name="message" type="xs:string"/>
+            <xs:element name="sequence" type="xs:long"/>
+            <xs:element name="timestamp" type="xs:long"/>
+            <xs:element name="dateTime" type="xs:dateTime"/>
+            <xs:element name="type" type="xs:string"/>
+            <xs:element name="userData" type="xs:string" minOccurs="0"/>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:element name="NotificationEvent" type="tns:notificationEventType">
+        <xs:annotation>
+            <xs:documentation>
+                Models a javax.management.Notification
+            </xs:documentation>
+        </xs:annotation>
+    </xs:element>
+
+    <xs:element name="AttributeChangeNotification">
+        <xs:annotation>
+            <xs:documentation>
+                Models a javax.management.AttributeChangeNotification
+            </xs:documentation>
+        </xs:annotation>
+        <xs:complexType>
+            <xs:complexContent>
+                <xs:extension base="tns:notificationEventType">
+                    <xs:sequence>
+                        <xs:element name="attributeName" type="xs:string"/>
+                        <xs:element name="attributeType" type="xs:string"/>
+                        <xs:element name="newValue" type="xs:string" nillable="true">
+                            <xs:annotation>
+                                <xs:documentation>
+                                    Value will be converted to a string. xsi:nil is used
+                                    to convey a null value
+                                </xs:documentation>
+                            </xs:annotation>
+                        </xs:element>
+                        <xs:element name="oldValue" type="xs:string" nillable="true">
+                            <xs:annotation>
+                                <xs:documentation>
+                                    Value will be converted to a string. xsi:nil is used
+                                    to convey a null value
+                                </xs:documentation>
+                            </xs:annotation>
+                        </xs:element>
+                    </xs:sequence>
+                </xs:extension>
+            </xs:complexContent>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="JMXConnectionNotification">
+        <xs:annotation>
+            <xs:documentation>
+                Models a javax.management.JMXConnectionNotification
+            </xs:documentation>
+        </xs:annotation>
+        <xs:complexType>
+            <xs:complexContent>
+                <xs:extension base="tns:notificationEventType">
+                    <xs:sequence>
+                        <xs:element name="connectionId" type="xs:string"/>
+                    </xs:sequence>
+                </xs:extension>
+            </xs:complexContent>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="MBeanServerNotification">
+        <xs:annotation>
+            <xs:documentation>
+                Models a javax.management.MBeanServerNotification
+            </xs:documentation>
+        </xs:annotation>
+        <xs:complexType>
+            <xs:complexContent>
+                <xs:extension base="tns:notificationEventType">
+                    <xs:sequence>
+                        <xs:element name="MBeanName" type="xs:string"/>
+                    </xs:sequence>
+                </xs:extension>
+            </xs:complexContent>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="MonitorNotification">
+        <xs:annotation>
+            <xs:documentation>
+                Models a javax.management.MonitorNotification
+            </xs:documentation>
+        </xs:annotation>
+        <xs:complexType>
+            <xs:complexContent>
+                <xs:extension base="tns:notificationEventType">
+                    <xs:sequence>
+                        <xs:element name="derivedGauge" type="xs:string"/>
+                        <xs:element name="observedAttribute" type="xs:string"/>
+                        <xs:element name="observedObject" type="xs:string"/>
+                        <xs:element name="trigger" type="xs:string"/>
+                    </xs:sequence>
+                </xs:extension>
+            </xs:complexContent>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="RelationNotification">
+        <xs:annotation>
+            <xs:documentation>
+                Models a javax.management.RelationNotification
+            </xs:documentation>
+        </xs:annotation>
+        <xs:complexType>
+            <xs:complexContent>
+                <xs:extension base="tns:notificationEventType">
+                    <xs:sequence>
+                        <xs:element name="objectName" type="xs:string"/>
+                        <xs:element name="relationId" type="xs:string"/>
+                        <xs:element name="relationTypeName" type="xs:string"/>
+                        <xs:element name="roleName" type="xs:string" minOccurs="0"/>
+                        <xs:element name="MBeansToUnregister" minOccurs="0" type="tns:objectNamesType"/>
+                        <xs:element name="newRoleValue" minOccurs="0" type="tns:objectNamesType"/>
+                        <xs:element name="oldRoleValue" minOccurs="0" type="tns:objectNamesType"/>
+                    </xs:sequence>
+                </xs:extension>
+            </xs:complexContent>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:complexType name="objectNamesType">
+        <xs:annotation>
+            <xs:documentation>
+                List of object names used in RelationNotification
+            </xs:documentation>
+        </xs:annotation>
+        <xs:sequence>
+            <xs:element name="objectName" type="xs:string"
+                maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+    
+    <xs:element name="TimerNotification">
+        <xs:annotation>
+            <xs:documentation>
+                Models a javax.management.TimerNotification
+            </xs:documentation>
+        </xs:annotation>
+        <xs:complexType>
+            <xs:complexContent>
+                <xs:extension base="tns:notificationEventType">
+                    <xs:sequence>
+                        <xs:element name="notificationId" type="xs:int"/>
+                    </xs:sequence>
+                </xs:extension>
+            </xs:complexContent>
+        </xs:complexType>
+    </xs:element>
+
+</xs:schema>

Propchange: camel/trunk/components/camel-jmx/src/main/resources/notifications.xsd
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/components/camel-jmx/src/main/resources/notifications.xsd
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Propchange: camel/trunk/components/camel-jmx/src/main/resources/notifications.xsd
------------------------------------------------------------------------------
    svn:mime-type = text/xml

Added: camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXComponentTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXComponentTest.java?rev=1031461&view=auto
==============================================================================
--- camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXComponentTest.java (added)
+++ camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXComponentTest.java Fri Nov  5 07:40:01 2010
@@ -0,0 +1,92 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.jmx;
+
+import java.util.Hashtable;
+
+import org.apache.camel.ResolveEndpointFailedException;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * Test behavior in the component for initializing an endpoint. Not much here beyond
+ * checking that the code for the required and mutually exclusive params is working.
+ */
+public class JMXComponentTest {
+
+    DefaultCamelContext context = new DefaultCamelContext();
+
+    @Test
+    public void withObjectProperties() throws Exception {
+        JMXEndpoint ep = (JMXEndpoint) context.getEndpoint("jmx:platform?objectDomain=FooDomain&key.propOne=prop1&key.propTwo=prop2");
+        assertNotNull(ep);
+
+        Hashtable<String, String> props = ep.getObjectProperties();
+        assertEquals(2, props.size());
+        assertEquals("prop1", props.get("propOne"));
+        assertEquals("prop2", props.get("propTwo"));
+
+        assertNull(ep.getObjectName());
+    }
+
+    @Test
+    public void withObjectName() throws Exception {
+        JMXEndpoint ep = (JMXEndpoint) context.getEndpoint("jmx:platform?objectDomain=FooDomain&objectName=theObjectName");
+        assertNotNull(ep);
+
+        assertEquals("theObjectName", ep.getObjectName());
+
+        Hashtable<String, String> props = ep.getObjectProperties();
+        assertNull(props);
+    }
+
+    @Test
+    public void withObjectNameAndObjectProperties() throws Exception {
+        try {
+            context.getEndpoint("jmx:platform?objectDomain=FooDomain&objectName=theObjectName&key.propOne=prop1");
+            fail("expected exception");
+        } catch (ResolveEndpointFailedException e) {
+            assertTrue(e.getCause() instanceof IllegalArgumentException);
+        }
+    }
+
+    @Test
+    public void withoutDomain() throws Exception {
+        try {
+            context.getEndpoint("jmx:platform?objectName=theObjectName");
+            fail("missing domain should have caused failure");
+        } catch (ResolveEndpointFailedException e) {
+            assertTrue(e.getCause() instanceof IllegalArgumentException);
+        }
+    }
+
+    @Test
+    public void withoutObjectNameAndObjectProperties() throws Exception {
+        try {
+            context.getEndpoint("jmx:platform?objectDomain=theObjectDomain");
+            fail("missing name should have caused failure");
+        } catch (ResolveEndpointFailedException e) {
+            assertTrue(e.getCause() instanceof IllegalArgumentException);
+        }
+    }
+}

Propchange: camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXComponentTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXComponentTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXConsumerTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXConsumerTest.java?rev=1031461&view=auto
==============================================================================
--- camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXConsumerTest.java (added)
+++ camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXConsumerTest.java Fri Nov  5 07:40:01 2010
@@ -0,0 +1,98 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.jmx;
+
+import java.io.File;
+
+import org.apache.camel.component.jmx.beans.ISimpleMXBean;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * Tests that trigger notification events on our simple bean without
+ * requiring any special setup.
+ */
+@Ignore("TODO: Fails with timestamp diff error")
+public class JMXConsumerTest extends SimpleBeanFixture {
+
+    ISimpleMXBean simpleBean;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        simpleBean = getSimpleMXBean();
+    }
+
+    @Test
+    public void attributeChange() throws Exception {
+        getMockEndpoint().setExpectedMessageCount(1);
+        simpleBean.setStringValue("foo");
+        waitAndAssertMessageReceived("src/test/resources/consumer-test/attributeChange-0.xml");
+
+        getMockEndpoint().setExpectedMessageCount(1);
+        simpleBean.setStringValue("bar");
+        waitAndAssertMessageReceived("src/test/resources/consumer-test/attributeChange-1.xml");
+
+        // set the string to null
+        getMockEndpoint().setExpectedMessageCount(1);
+        simpleBean.setStringValue(null);
+        waitAndAssertMessageReceived("src/test/resources/consumer-test/attributeChange-2.xml");
+    }
+
+    @Test
+    public void notification() throws Exception {
+        simpleBean.touch();
+        waitAndAssertMessageReceived("src/test/resources/consumer-test/touched.xml");
+    }
+
+    @Test
+    public void userData() throws Exception {
+        simpleBean.userData("myUserData");
+        waitAndAssertMessageReceived("src/test/resources/consumer-test/userdata.xml");
+    }
+
+    @Test
+    public void jmxConnection() throws Exception {
+        simpleBean.triggerConnectionNotification();
+        waitAndAssertMessageReceived("src/test/resources/consumer-test/jmxConnectionNotification.xml");
+    }
+
+    @Test
+    public void mbeanServerNotification() throws Exception {
+        simpleBean.triggerMBeanServerNotification();
+        waitAndAssertMessageReceived("src/test/resources/consumer-test/mbeanServerNotification.xml");
+    }
+
+    @Test
+    public void relationNotification() throws Exception {
+        simpleBean.triggerRelationNotification();
+        waitAndAssertMessageReceived("src/test/resources/consumer-test/relationNotification.xml");
+    }
+
+    @Test
+    public void timerNotification() throws Exception {
+        simpleBean.triggerTimerNotification();
+        waitAndAssertMessageReceived("src/test/resources/consumer-test/timerNotification.xml");
+    }
+
+    private void waitAndAssertMessageReceived(String aExpectedFilePath) throws InterruptedException, Exception {
+        waitForMessages();
+        assertMessageReceived(new File(aExpectedFilePath));
+    }
+
+}

Propchange: camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXConsumerTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXConsumerTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXEndpointTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXEndpointTest.java?rev=1031461&view=auto
==============================================================================
--- camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXEndpointTest.java (added)
+++ camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXEndpointTest.java Fri Nov  5 07:40:01 2010
@@ -0,0 +1,125 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.jmx;
+
+import java.util.Hashtable;
+import javax.management.ObjectName;
+
+import org.apache.camel.impl.DefaultCamelContext;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests for the endpoint. Most of the params in the endpoint are
+ * set via the endpoint helper so there's no much beyond some sanity
+ * checks here.
+ */
+public class JMXEndpointTest {
+
+    DefaultCamelContext context = new DefaultCamelContext();
+
+    @Test
+    public void setObjectNameThrowsWhenObjectPropertiesIsSet() throws Exception {
+        JMXEndpoint ep = new JMXEndpoint("urn:ignored", new JMXComponent());
+        ep.setObjectProperties(new Hashtable());
+        try {
+            // should fault since objectName is mutex with objectProperties
+            ep.setObjectName("foo");
+            fail("expected exception");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void defaultsToXml() throws Exception {
+        JMXEndpoint ep = (JMXEndpoint) context.getEndpoint("jmx:platform?objectDomain=FooDomain&objectName=theObjectName");
+        assertTrue(ep.isXML());
+    }
+
+    @Test
+    public void formatRaw() throws Exception {
+        JMXEndpoint ep = (JMXEndpoint) context.getEndpoint("jmx:platform?objectDomain=FooDomain&objectName=theObjectName&format=raw");
+        assertFalse(ep.isXML());
+        assertEquals("raw", ep.getFormat());
+    }
+
+    @Test
+    public void getJMXObjectName() throws Exception {
+        JMXEndpoint ep = (JMXEndpoint) context.getEndpoint("jmx:platform?objectDomain=FooDomain&objectName=theObjectName");
+        ObjectName on = ep.getJMXObjectName();
+        assertNotNull(on);
+        assertEquals("FooDomain:name=theObjectName", on.toString());
+    }
+
+    @Test
+    public void getJMXObjectNameWithProps() throws Exception {
+        JMXEndpoint ep = (JMXEndpoint) context.getEndpoint("jmx:platform?objectDomain=FooDomain&key.name=theObjectName");
+        ObjectName on = ep.getJMXObjectName();
+        assertNotNull(on);
+        assertEquals("FooDomain:name=theObjectName", on.toString());
+    }
+
+    @Test
+    public void getJMXObjectNameCached() throws Exception {
+        JMXEndpoint ep = (JMXEndpoint) context.getEndpoint("jmx:platform?objectDomain=FooDomain&key.name=theObjectName");
+        ObjectName on = ep.getJMXObjectName();
+        assertNotNull(on);
+        assertSame(on, ep.getJMXObjectName());
+    }
+
+    @Test
+    public void platformServer() throws Exception {
+        JMXEndpoint ep = (JMXEndpoint) context.getEndpoint("jmx:platform?objectDomain=FooDomain&key.name=theObjectName");
+        assertTrue(ep.isPlatformServer());
+        assertEquals("platform", ep.getServerURL());
+    }
+
+    @Test
+    public void remoteServer() throws Exception {
+        JMXEndpoint ep = (JMXEndpoint) context.getEndpoint("jmx:service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi?objectDomain=FooDomain&key.name=theObjectName");
+        assertFalse(ep.isPlatformServer());
+        assertEquals("service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi", ep.getServerURL());
+
+        ep = (JMXEndpoint) context.getEndpoint("jmx://service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi?objectDomain=FooDomain&key.name=theObjectName");
+        assertFalse(ep.isPlatformServer());
+        assertEquals("service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi", ep.getServerURL());
+    }
+
+    @Test
+    public void noProducer() throws Exception {
+        JMXEndpoint ep = (JMXEndpoint) context.getEndpoint("jmx:platform?objectDomain=FooDomain&key.name=theObjectName");
+        try {
+            ep.createProducer();
+            fail("producer pattern is not supported");
+        } catch (UnsupportedOperationException e) {
+        }
+    }
+
+    @Test
+    public void credentials() throws Exception {
+        JMXEndpoint ep = (JMXEndpoint) context.getEndpoint("jmx:platform?objectDomain=FooDomain&key.name=theObjectName&user=user1&password=1234");
+        assertEquals("user1", ep.getUser());
+        assertEquals("1234", ep.getPassword());
+    }
+}

Propchange: camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXEndpointTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXEndpointTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXHandbackTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXHandbackTest.java?rev=1031461&view=auto
==============================================================================
--- camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXHandbackTest.java (added)
+++ camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXHandbackTest.java Fri Nov  5 07:40:01 2010
@@ -0,0 +1,64 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.jmx;
+
+import java.net.URI;
+
+import org.apache.camel.Message;
+import org.apache.camel.component.jmx.beans.ISimpleMXBean;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertSame;
+
+
+/**
+ * Tests that we get the handback object in the message header
+ */
+public class JMXHandbackTest extends SimpleBeanFixture {
+
+    URI hb;
+
+    @Before
+    public void setUp() throws Exception {
+        hb = new URI("urn:some:handback:object");
+        super.setUp();
+    }
+
+    @Test
+    public void test() throws Exception {
+        ISimpleMXBean simpleBean = getSimpleMXBean();
+        simpleBean.userData("myUserData");
+
+        waitForMessages();
+
+        Message m = getMessage(0);
+        URI uri = (URI) m.getHeader("jmx.handback");
+        assertSame(hb, uri);
+    }
+
+    @Override
+    protected JMXUriBuilder buildFromURI() {
+        return super.buildFromURI().withHandback("#hb").withFormat("raw");
+    }
+
+    @Override
+    protected void initRegistry() {
+        super.initRegistry();
+        getRegistry().put("hb", hb);
+    }
+}

Propchange: camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXHandbackTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXHandbackTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXMonitorTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXMonitorTest.java?rev=1031461&view=auto
==============================================================================
--- camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXMonitorTest.java (added)
+++ camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXMonitorTest.java Fri Nov  5 07:40:01 2010
@@ -0,0 +1,104 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.jmx;
+
+import java.io.File;
+import java.util.concurrent.TimeUnit;
+import javax.management.monitor.CounterMonitor;
+
+import org.w3c.dom.Document;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.jmx.beans.ISimpleMXBean;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Registers another bean that monitors an attribute on the simple bean.
+ * When the attribute changes, an event is fired that we'll assert on.
+ */
+public class JMXMonitorTest extends SimpleBeanFixture {
+
+    /**
+     * endpoint for the monitor bean
+     */
+    MockEndpoint mMonitorSink;
+
+    @Test
+    public void counter() throws Exception {
+
+        assertEquals(0, mMonitorSink.getReceivedCounter());
+
+        mMonitorSink.setExpectedMessageCount(1);
+        getMockEndpoint().setExpectedMessageCount(2);
+
+        ISimpleMXBean simpleBean = getSimpleMXBean();
+
+        // we should get an event after the sequence reaches 2
+
+        // changing the attrib increments the sequence
+        simpleBean.setStringValue("foo");
+        // changing the attrib increments the sequence again
+        simpleBean.setStringValue("bar");
+
+        // we should have gotten 2 attribute change messages
+        waitForMessages();
+
+        // and 1 monitor message
+        assertTrue("messages didn't arrive within timeout", mMonitorSink.await(10, TimeUnit.SECONDS));
+
+        Document monitorBody = XmlFixture.toDoc(mMonitorSink.getReceivedExchanges().get(0).getIn().getBody(String.class));
+        // strip the timestamp and dateTime fields so we can assert w/o having them trip us up
+        monitorBody = XmlFixture.stripTimestamp(monitorBody);
+        XmlFixture.assertXMLIgnorePrefix("failed to match",
+                XmlFixture.toDoc(new File("src/test/resources/consumer-test/monitorNotification.xml")),
+                monitorBody);
+    }
+
+    @Override
+    protected void initBean() throws Exception {
+        // add the simple bean
+        super.initBean();
+        // add our monitor bean
+        CounterMonitor monitor = new CounterMonitor();
+        monitor.addObservedObject(makeObjectName("simpleBean"));
+        monitor.setObservedAttribute("MonitorNumber");
+        monitor.setNotify(true);
+        monitor.setInitThreshold(1);
+        monitor.setGranularityPeriod(500);
+        registerBean(monitor, makeObjectName("counter"));
+        monitor.start();
+    }
+
+
+    @Override
+    protected void initContext() throws Exception {
+        // add the route for the simple bean
+        super.initContext();
+        // add the route for the monitor bean
+        mMonitorSink = (MockEndpoint) getContext().getEndpoint("mock:monitor");
+        getContext().addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from(buildFromURI().withObjectName("counter").toString()).to(mMonitorSink);
+            }
+        });
+    }
+}

Propchange: camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXMonitorTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXMonitorTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXNotificationFilterTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXNotificationFilterTest.java?rev=1031461&view=auto
==============================================================================
--- camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXNotificationFilterTest.java (added)
+++ camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXNotificationFilterTest.java Fri Nov  5 07:40:01 2010
@@ -0,0 +1,90 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.jmx;
+
+import java.util.LinkedHashSet;
+import javax.management.Notification;
+import javax.management.NotificationFilter;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.jmx.beans.ISimpleMXBean;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Tests that the NotificationFilter is applied if configured
+ */
+public class JMXNotificationFilterTest extends SimpleBeanFixture {
+
+    /**
+     * we'll track the rejected messages so we know what got filtered
+     */
+    private LinkedHashSet<Notification> mRejected = new LinkedHashSet<Notification>();
+
+    @Test
+    public void testNotificationFilter() throws Exception {
+        ISimpleMXBean bean = getSimpleMXBean();
+
+        assertEquals("no notifications should have been filtered at this point", 0, mRejected.size());
+
+        // we should only get 5 messages, which is 1/2 the number of times we touched the object.
+        // The 1/2 is due to the behavior of the test NotificationFilter implemented below 
+        getMockEndpoint().setExpectedMessageCount(5);
+        for (int i = 0; i < 10; i++) {
+            bean.touch();
+        }
+
+        waitForMessages();
+        assertEquals("5 notifications should have been filtered", 5, mRejected.size());
+
+        // assert that all of the rejected ones are odd and accepted ones even
+        for (Notification rejected : mRejected) {
+            assertEquals(1, rejected.getSequenceNumber() % 2);
+        }
+
+        for (Exchange received : getMockEndpoint().getReceivedExchanges()) {
+            Notification n = (Notification) received.getIn().getBody();
+            assertEquals(0, n.getSequenceNumber() % 2);
+        }
+    }
+
+    @Override
+    protected JMXUriBuilder buildFromURI() {
+        // use the raw format so we can we can get the Notification and assert on the sequence
+        return super.buildFromURI().withNotificationFilter("#myFilter").withFormat("raw");
+    }
+
+    @SuppressWarnings("serial")
+    @Override
+    protected void initRegistry() {
+        super.initRegistry();
+
+        // initialize the registry with our filter
+        getRegistry().put("myFilter", new NotificationFilter() {
+            public boolean isNotificationEnabled(Notification aNotification) {
+                // only accept even notifications
+                boolean enabled = aNotification.getSequenceNumber() % 2 == 0;
+                if (!enabled) {
+                    mRejected.add(aNotification);
+                }
+                return enabled;
+            }
+        });
+    }
+
+}

Propchange: camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXNotificationFilterTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXNotificationFilterTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXObjectPropertiesTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXObjectPropertiesTest.java?rev=1031461&view=auto
==============================================================================
--- camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXObjectPropertiesTest.java (added)
+++ camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXObjectPropertiesTest.java Fri Nov  5 07:40:01 2010
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.jmx;
+
+import java.util.Hashtable;
+
+import org.apache.camel.component.jmx.beans.ISimpleMXBean;
+import org.junit.Test;
+
+/**
+ * Tests that the objectName is created with the hashtable of objectProperties
+ */
+public class JMXObjectPropertiesTest extends SimpleBeanFixture {
+
+    @Test
+    public void testObjectProperties() throws Exception {
+        ISimpleMXBean bean = getSimpleMXBean();
+        bean.touch();
+        waitForMessages();
+    }
+
+    @Override
+    protected JMXUriBuilder buildFromURI() {
+        return new JMXUriBuilder().withObjectDomain(DOMAIN).withObjectPropertiesReference("#myTable");
+    }
+
+    @SuppressWarnings("serial")
+    @Override
+    protected void initRegistry() {
+        Hashtable<String, String> ht = new Hashtable<String, String>();
+        ht.put("name", "simpleBean");
+        getRegistry().put("myTable", ht);
+    }
+
+}

Propchange: camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXObjectPropertiesTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/components/camel-jmx/src/test/java/org/apache/camel/component/jmx/JMXObjectPropertiesTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date