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 2017/04/12 19:56:24 UTC

[05/11] camel git commit: initial commit of camel-pubnub component

initial commit of camel-pubnub component

Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/289a6728
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/289a6728
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/289a6728

Branch: refs/heads/master
Commit: 289a67285a21e6f48cfd8857953ba88b1a4993e9
Parents: 5148409
Author: Preben Asmussen <pr...@gmail.com>
Authored: Fri Mar 24 22:49:13 2017 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Wed Apr 12 21:56:07 2017 +0200

----------------------------------------------------------------------
 components/camel-pubnub/pom.xml                 |  80 +++++++
 .../camel/component/pubnub/JsonConverter.java   |  46 ++++
 .../camel/component/pubnub/PubNubComponent.java |  54 +++++
 .../component/pubnub/PubNubConfiguration.java   | 146 +++++++++++++
 .../camel/component/pubnub/PubNubConstants.java |  24 ++
 .../camel/component/pubnub/PubNubConsumer.java  | 120 ++++++++++
 .../camel/component/pubnub/PubNubEndpoint.java  | 218 +++++++++++++++++++
 .../component/pubnub/PubNubEndpointType.java    |  32 +++
 .../camel/component/pubnub/PubNubProducer.java  | 146 +++++++++++++
 .../src/main/resources/META-INF/LICENSE.txt     | 203 +++++++++++++++++
 .../src/main/resources/META-INF/NOTICE.txt      |  11 +
 .../services/org/apache/camel/TypeConverter     |  18 ++
 .../services/org/apache/camel/component/pubnub  |  17 ++
 .../component/pubnub/PubNubComponentTest.java   |  61 ++++++
 .../pubnub/PubNubConfigurationTest.java         |  55 +++++
 .../pubnub/PubNubEmptyPayloadTest.java          |  55 +++++
 .../camel/component/pubnub/PubNubMock.java      | 186 ++++++++++++++++
 .../component/pubnub/PubNubOperationsTest.java  |  91 ++++++++
 .../component/pubnub/PubNubPresensTest.java     |  72 ++++++
 .../pubnub/example/PubNubExampleConstants.java  |  24 ++
 .../pubnub/example/PubNubOperationsExample.java |  61 ++++++
 .../pubnub/example/PubNubPresenseExample.java   |  44 ++++
 .../pubnub/example/PubNubSensor2Example.html    |  87 ++++++++
 .../pubnub/example/PubNubSensor2Example.java    | 122 +++++++++++
 .../pubnub/example/PubNubSensorExample.java     |  40 ++++
 .../src/test/resources/log4j2.properties        |  28 +++
 components/pom.xml                              |   1 +
 parent/pom.xml                                  |   1 +
 28 files changed, 2043 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/289a6728/components/camel-pubnub/pom.xml
----------------------------------------------------------------------
diff --git a/components/camel-pubnub/pom.xml b/components/camel-pubnub/pom.xml
new file mode 100644
index 0000000..268cb2a
--- /dev/null
+++ b/components/camel-pubnub/pom.xml
@@ -0,0 +1,80 @@
+<?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>components</artifactId>
+    <version>2.19.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>camel-pubnub</artifactId>
+  <packaging>jar</packaging>
+
+  <name>Camel :: PubNub</name>
+  <description>Camel PubNub component</description>
+
+  <properties>
+    <camel.osgi.export.pkg>org.apache.camel.component.pubnub.*</camel.osgi.export.pkg>
+    <camel.osgi.export.service>org.apache.camel.spi.ComponentResolver;component=pubnub</camel.osgi.export.service>
+  </properties>
+
+  <dependencies>
+
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.pubnub</groupId>
+      <artifactId>pubnub</artifactId>
+      <version>${pubnub-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.code.gson</groupId>
+      <artifactId>gson</artifactId>
+      <version>${gson-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-lang3</artifactId>
+      <version>${commons-lang3-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.json</groupId>
+      <artifactId>json</artifactId>
+      <version>20160810</version>
+    </dependency>
+    <!-- testing -->
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-test</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-log4j12</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>log4j</groupId>
+      <artifactId>log4j</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-netty-http</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/camel/blob/289a6728/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/JsonConverter.java
----------------------------------------------------------------------
diff --git a/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/JsonConverter.java b/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/JsonConverter.java
new file mode 100644
index 0000000..e5f09a0
--- /dev/null
+++ b/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/JsonConverter.java
@@ -0,0 +1,46 @@
+/**
+ * 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.pubnub;
+
+import org.apache.camel.Converter;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+@Converter
+public final class JsonConverter {
+    private JsonConverter() {
+    }
+
+    @Converter
+    public static JSONObject toJsonObject(String json) {
+        try {
+            return new JSONObject(json);
+        } catch (JSONException e) {
+            return null;
+        }
+    }
+
+    @Converter
+    public static JSONArray toJsonArray(String json) {
+        try {
+            return new JSONArray(json);
+        } catch (JSONException e) {
+            return null;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/289a6728/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/PubNubComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/PubNubComponent.java b/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/PubNubComponent.java
new file mode 100644
index 0000000..9eb4e61
--- /dev/null
+++ b/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/PubNubComponent.java
@@ -0,0 +1,54 @@
+/**
+ * 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.pubnub;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Endpoint;
+import org.apache.camel.impl.DefaultComponent;
+
+/**
+ * Represents the component that manages {@link PubNubEndpoint}.
+ */
+public class PubNubComponent extends DefaultComponent {
+
+    public PubNubComponent(CamelContext context) {
+        super(context);
+    }
+
+    public PubNubComponent() {
+        super();
+    }
+
+    @Override
+    protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
+        String[] uriParts = remaining.split(":");
+        if (uriParts.length != 2) {
+            throw new IllegalArgumentException("Invalid Endpoint URI: " + uri + ". It should contains a valid endpointType and channel");
+        }
+        PubNubEndpointType endpointType = PubNubEndpointType.valueOf(uriParts[0]);
+        String channel = uriParts[1];
+
+        PubNubEndpoint endpoint = new PubNubEndpoint(uri, this);
+        setProperties(endpoint, parameters);
+        endpoint.setEndpointType(endpointType);
+        endpoint.setChannel(channel);
+        return endpoint;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/289a6728/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/PubNubConfiguration.java
----------------------------------------------------------------------
diff --git a/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/PubNubConfiguration.java b/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/PubNubConfiguration.java
new file mode 100644
index 0000000..b506508
--- /dev/null
+++ b/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/PubNubConfiguration.java
@@ -0,0 +1,146 @@
+/**
+ * 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.pubnub;
+
+import com.pubnub.api.Pubnub;
+
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriParams;
+import org.apache.camel.spi.UriPath;
+
+@UriParams
+public class PubNubConfiguration {
+    @UriParam
+    private Pubnub pubnub;
+
+    @UriPath(enums = "pubsub,presence")
+    @Metadata(required = "true", defaultValue = "pubsub")
+    private PubNubEndpointType endpointType = PubNubEndpointType.pubsub;
+
+    @UriPath()
+    @Metadata(required = "true")
+    private String channel;
+
+    @UriParam()
+    private String publisherKey;
+
+    @UriParam()
+    private String subscriberKey;
+
+    @UriParam()
+    private String secretKey;
+
+    @UriParam(defaultValue = "true")
+    private boolean ssl = true;
+
+    @UriParam()
+    private String uuid;
+
+    @UriParam(label = "producer", enums = "HERE_NOW, WHERE_NOW, GET_STATE, SET_STATE, GET_HISTORY, PUBLISH")
+    private String operation;
+
+    public PubNubEndpointType getEndpointType() {
+        return endpointType;
+    }
+
+    /**
+     * The publish key obtained from your PubNub account. Required when publishing messages.
+     */
+    public String getPublisherKey() {
+        return publisherKey;
+    }
+
+    public void setPublisherKey(String publisherKey) {
+        this.publisherKey = publisherKey;
+    }
+
+    /**
+     * The subscribe key obtained from your PubNub account. Required when subscribing to channels or listening for presence events
+     */
+    public String getSubscriberKey() {
+        return subscriberKey;
+    }
+
+    public void setSubscriberKey(String subscriberKey) {
+        this.subscriberKey = subscriberKey;
+    }
+
+    /**
+     * The secret key used for message signing.
+     */
+    public String getSecretKey() {
+        return secretKey;
+    }
+
+    public void setSecretKey(String secretKey) {
+        this.secretKey = secretKey;
+    }
+
+    /**
+     * Use ssl
+     */
+    public boolean isSsl() {
+        return ssl;
+    }
+
+    public void setSsl(boolean ssl) {
+        this.ssl = ssl;
+    }
+
+    /**
+     * The channel used for subscribing/publishing events
+     */
+    public String getChannel() {
+        return channel;
+    }
+
+    public void setChannel(String channel) {
+        this.channel = channel;
+    }
+
+    /**
+     * The uuid identifying the connection. Will be auto assigned if not set.
+     */
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    public String getUuid() {
+        return uuid;
+    }
+
+    /**
+     * The operation to perform.
+     */
+    public void setOperation(String operation) {
+        this.operation = operation;
+    }
+
+    public String getOperation() {
+        return operation;
+    }
+
+    public Pubnub getPubnub() {
+        return pubnub;
+    }
+
+    public void setPubnub(Pubnub pubnub) {
+        this.pubnub = pubnub;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/289a6728/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/PubNubConstants.java
----------------------------------------------------------------------
diff --git a/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/PubNubConstants.java b/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/PubNubConstants.java
new file mode 100644
index 0000000..30adae0
--- /dev/null
+++ b/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/PubNubConstants.java
@@ -0,0 +1,24 @@
+/**
+ * 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.pubnub;
+
+public interface PubNubConstants {
+    String OPERATION = "CamelPubNubOperation";
+    String TIMETOKEN = "CamelPubNubTimeToken";
+    String CHANNEL = "CamelPubNubChannel";
+    String UUID = "CamelPubNubUUID";
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/289a6728/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/PubNubConsumer.java
----------------------------------------------------------------------
diff --git a/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/PubNubConsumer.java b/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/PubNubConsumer.java
new file mode 100644
index 0000000..8b8002a
--- /dev/null
+++ b/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/PubNubConsumer.java
@@ -0,0 +1,120 @@
+/**
+ * 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.pubnub;
+
+import com.pubnub.api.Callback;
+import com.pubnub.api.PubnubError;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.Processor;
+import org.apache.camel.impl.DefaultConsumer;
+import org.apache.camel.impl.DefaultExchange;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The PubNub consumer.
+ */
+public class PubNubConsumer extends DefaultConsumer {
+    private static final Logger LOG = LoggerFactory.getLogger(PubNubConsumer.class);
+    private final PubNubEndpoint endpoint;
+
+    public PubNubConsumer(PubNubEndpoint endpoint, Processor processor) {
+        super(endpoint, processor);
+        this.endpoint = endpoint;
+    }
+
+    private void initCommunication() throws Exception {
+        if (endpoint.getEndpointType().equals(PubNubEndpointType.pubsub)) {
+            endpoint.getPubnub().subscribe(endpoint.getChannel(), new PubNubCallback());
+        } else {
+            endpoint.getPubnub().presence(endpoint.getChannel(), new PubNubCallback());
+        }
+    }
+
+    private void terminateCommunication() throws Exception {
+        if (endpoint.getEndpointType().equals(PubNubEndpointType.pubsub)) {
+            endpoint.getPubnub().unsubscribe(endpoint.getChannel());
+        } else {
+            endpoint.getPubnub().unsubscribePresence(endpoint.getChannel());
+        }
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+        initCommunication();
+    }
+
+    @Override
+    protected void doResume() throws Exception {
+        super.doResume();
+        initCommunication();
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        terminateCommunication();
+        super.doStop();
+    }
+
+    @Override
+    protected void doSuspend() throws Exception {
+        terminateCommunication();
+        super.doSuspend();
+    }
+
+    private class PubNubCallback extends Callback {
+
+        @Override
+        public void successCallback(String channel, Object objectMessage, String timetoken) {
+            Exchange exchange = new DefaultExchange(endpoint, endpoint.getExchangePattern());
+            Message message = exchange.getIn();
+            message.setBody(objectMessage);
+            message.setHeader(PubNubConstants.TIMETOKEN, timetoken);
+            message.setHeader(PubNubConstants.CHANNEL, channel);
+            try {
+                getProcessor().process(exchange);
+            } catch (Exception e) {
+                exchange.setException(e);
+                getExceptionHandler().handleException("Error processing exchange", exchange, e);
+            }
+        }
+
+        @Override
+        public void connectCallback(String channel, Object message) {
+            LOG.info("Subscriber : Successfully connected to PubNub channel {}", channel);
+        }
+
+        @Override
+        public void errorCallback(String channel, PubnubError error) {
+            LOG.error("Subscriber : Error [{}] received from PubNub on channel {}", error, channel);
+        }
+
+        @Override
+        public void reconnectCallback(String channel, Object message) {
+            LOG.info("Subscriber : Reconnected to PubNub channel {}", channel);
+        }
+
+        @Override
+        public void disconnectCallback(String channel, Object message) {
+            LOG.trace("Subscriber : Disconnected from PubNub channel {}", channel);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/289a6728/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/PubNubEndpoint.java
----------------------------------------------------------------------
diff --git a/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/PubNubEndpoint.java b/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/PubNubEndpoint.java
new file mode 100644
index 0000000..2f60d2a
--- /dev/null
+++ b/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/PubNubEndpoint.java
@@ -0,0 +1,218 @@
+/**
+ * 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.pubnub;
+
+import com.pubnub.api.Pubnub;
+
+import org.apache.camel.Consumer;
+import org.apache.camel.Processor;
+import org.apache.camel.Producer;
+import org.apache.camel.impl.DefaultEndpoint;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.UriEndpoint;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriPath;
+import org.apache.camel.util.ObjectHelper;
+
+@UriEndpoint(scheme = "pubnub", title = "PubNub", syntax = "pubnub:endpointType:channel", consumerClass = PubNubConsumer.class, label = "cloud,iot,messaging")
+public class PubNubEndpoint extends DefaultEndpoint {
+
+    @UriParam
+    private Pubnub pubnub;
+
+    @UriPath(enums = "pubsub,presence")
+    @Metadata(required = "true")
+    private PubNubEndpointType endpointType = PubNubEndpointType.pubsub;
+
+    @UriPath()
+    @Metadata(required = "true")
+    private String channel;
+
+    @UriParam()
+    private String publisherKey;
+
+    @UriParam()
+    private String subscriberKey;
+
+    @UriParam()
+    private String secretKey;
+
+    @UriParam(defaultValue = "true")
+    private boolean ssl = true;
+
+    @UriParam()
+    private String uuid;
+
+    @UriParam(label = "producer", enums = "HERE_NOW, WHERE_NOW, GET_STATE, SET_STATE, GET_HISTORY, PUBLISH")
+    private String operation;
+
+    public PubNubEndpoint(String uri, PubNubComponent component) {
+        super(uri, component);
+    }
+
+    
+
+    @Override
+    public Producer createProducer() throws Exception {
+        return new PubNubProducer(this);
+    }
+
+    @Override
+    public Consumer createConsumer(Processor processor) throws Exception {
+        return new PubNubConsumer(this, processor);
+    }
+
+    @Override
+    public boolean isSingleton() {
+        return true;
+    }
+
+    /**
+     * The type endpoint type. Either pubsub or presence
+     */
+
+    public PubNubEndpointType getEndpointType() {
+        return endpointType;
+    }
+
+    public void setEndpointType(PubNubEndpointType endpointType) {
+        this.endpointType = endpointType;
+    }
+
+    /**
+     * The pubnub publish key obtained from your pubnub account. Required when
+     * publishing messages.
+     */
+    public String getPublisherKey() {
+        return publisherKey;
+    }
+
+    public void setPublisherKey(String publisherKey) {
+        this.publisherKey = publisherKey;
+    }
+
+    /**
+     * The pubnub subscribe key obtained from your pubnub account. Required when
+     * subscribing to channels or listening for presence events
+     */
+    public String getSubscriberKey() {
+        return subscriberKey;
+    }
+
+    public void setSubscriberKey(String subscriberKey) {
+        this.subscriberKey = subscriberKey;
+    }
+
+    /**
+     * The pubnub secret key used for message signing.
+     */
+    public String getSecretKey() {
+        return secretKey;
+    }
+
+    public void setSecretKey(String secretKey) {
+        this.secretKey = secretKey;
+    }
+
+    /**
+     * Use ssl
+     */
+    public boolean isSsl() {
+        return ssl;
+    }
+
+    public void setSsl(boolean ssl) {
+        this.ssl = ssl;
+    }
+
+    /**
+     * The channel used for subscribing/publishing events
+     */
+    public String getChannel() {
+        return channel;
+    }
+
+    public void setChannel(String channel) {
+        this.channel = channel;
+    }
+
+    /**
+     * The uuid identifying the connection. Will be auto assigned if not set.
+     */
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    public String getUuid() {
+        return uuid;
+    }
+
+    /**
+     * The operation to perform.
+     */
+    public void setOperation(String operation) {
+        this.operation = operation;
+    }
+
+    public String getOperation() {
+        return operation;
+    }
+
+    /**
+     * Reference to a Pubnub client in the registry.
+     */
+
+    public Pubnub getPubnub() {
+        return pubnub;
+    }
+
+    public void setPubnub(Pubnub pubnub) {
+        this.pubnub = pubnub;
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        super.doStop();
+        if (pubnub != null) {
+            pubnub.shutdown();
+            pubnub = null;
+        }
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        this.pubnub = getPubnub() != null ? getPubnub() : getInstance();
+        super.doStart();
+    }
+
+    private Pubnub getInstance() {
+        Pubnub answer = null;
+        if (ObjectHelper.isNotEmpty(getSecretKey())) {
+            answer = new Pubnub(getPublisherKey(), getSubscriberKey(), getSecretKey(), isSsl());
+        } else {
+            answer = new Pubnub(getPublisherKey(), getSubscriberKey(), isSsl());
+        }
+        if (ObjectHelper.isNotEmpty(getUuid())) {
+            answer.setUUID(getUuid());
+        } else {
+            String autoUUID = answer.uuid();
+            setUuid(autoUUID);
+            answer.setUUID(autoUUID);
+        }
+        return answer;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/289a6728/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/PubNubEndpointType.java
----------------------------------------------------------------------
diff --git a/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/PubNubEndpointType.java b/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/PubNubEndpointType.java
new file mode 100644
index 0000000..1454b33
--- /dev/null
+++ b/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/PubNubEndpointType.java
@@ -0,0 +1,32 @@
+/**
+ * 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.pubnub;
+
+public enum PubNubEndpointType {
+    pubsub("pubsub"), presence("presence");
+
+    private final String text;
+
+    PubNubEndpointType(final String text) {
+        this.text = text;
+    }
+
+    @Override
+    public String toString() {
+        return text;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/289a6728/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/PubNubProducer.java
----------------------------------------------------------------------
diff --git a/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/PubNubProducer.java b/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/PubNubProducer.java
new file mode 100644
index 0000000..c2fb85c
--- /dev/null
+++ b/components/camel-pubnub/src/main/java/org/apache/camel/component/pubnub/PubNubProducer.java
@@ -0,0 +1,146 @@
+/**
+ * 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.pubnub;
+
+import com.pubnub.api.Callback;
+import com.pubnub.api.PubnubError;
+
+import org.apache.camel.AsyncCallback;
+import org.apache.camel.CamelException;
+import org.apache.camel.Exchange;
+import org.apache.camel.InvalidPayloadException;
+import org.apache.camel.impl.DefaultAsyncProducer;
+import org.apache.camel.util.ObjectHelper;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The PubNub producer.
+ */
+public class PubNubProducer extends DefaultAsyncProducer {
+    private static final Logger LOG = LoggerFactory.getLogger(PubNubProducer.class);
+    private final PubNubEndpoint endpoint;
+
+    public PubNubProducer(PubNubEndpoint endpoint) {
+        super(endpoint);
+        this.endpoint = endpoint;
+    }
+
+    @Override
+    public boolean process(final Exchange exchange, final AsyncCallback callback) {
+        Callback pubnubCallback = pubnubCallback(exchange, callback);
+
+        Operation operation = getOperation(exchange);
+        LOG.trace("Executing {} operation", operation);
+        switch (operation) {
+        case PUBLISH: {
+            String channel = exchange.getIn().getHeader(PubNubConstants.CHANNEL, String.class);
+            channel = channel != null ? channel : endpoint.getChannel();
+            Object body = exchange.getIn().getBody();
+            if (ObjectHelper.isEmpty(body)) {
+                exchange.setException(new CamelException("Can not publish empty message"));
+                callback.done(true);
+                return true;
+            }
+            LOG.trace("Sending message [{}] to channel [{}]", body, channel);
+            if (body.getClass().isAssignableFrom(JSONObject.class)) {
+                endpoint.getPubnub().publish(channel, (JSONObject)body, pubnubCallback);
+            } else if (body.getClass().isAssignableFrom(JSONArray.class)) {
+                endpoint.getPubnub().publish(channel, (JSONArray)body, pubnubCallback);
+            } else {
+                try {
+                    endpoint.getPubnub().publish(channel, exchange.getIn().getMandatoryBody(String.class), pubnubCallback);
+                } catch (InvalidPayloadException e) {
+                    exchange.setException(e);
+                    callback.done(true);
+                    return true;
+                }
+            }
+            break;
+        }
+        case GET_HISTORY: {
+            endpoint.getPubnub().history(endpoint.getChannel(), false, pubnubCallback);
+            break;
+        }
+        case GET_STATE: {
+            String uuid = exchange.getIn().getHeader(PubNubConstants.UUID, String.class);
+            endpoint.getPubnub().getState(endpoint.getChannel(), uuid != null ? uuid : endpoint.getUuid(), pubnubCallback);
+            break;
+        }
+        case HERE_NOW: {
+            endpoint.getPubnub().hereNow(endpoint.getChannel(), true, true, pubnubCallback);
+            break;
+        }
+        case SET_STATE: {
+            try {
+                JSONObject state = exchange.getIn().getMandatoryBody(JSONObject.class);
+                String uuid = exchange.getIn().getHeader(PubNubConstants.UUID, String.class);
+                endpoint.getPubnub().setState(endpoint.getChannel(), uuid != null ? uuid : endpoint.getUuid(), state, pubnubCallback);
+            } catch (InvalidPayloadException e) {
+                exchange.setException(e);
+                callback.done(true);
+                return true;
+            }
+            break;
+        }
+        case WHERE_NOW: {
+            String uuid = exchange.getIn().getHeader(PubNubConstants.UUID, String.class);
+            endpoint.getPubnub().whereNow(uuid != null ? uuid : endpoint.getUuid(), pubnubCallback);
+            break;
+        }
+        default:
+            throw new UnsupportedOperationException(operation.toString());
+        }
+        return false;
+    }
+
+    private Callback pubnubCallback(final Exchange exchange, final AsyncCallback callback) {
+        Callback pubnubCallback = new Callback() {
+            @Override
+            public void successCallback(String channel, Object message) {
+                LOG.trace("PubNub response {}", message);
+                exchange.getIn().setHeader(PubNubConstants.CHANNEL, channel);
+                if (exchange.getPattern().isOutCapable()) {
+                    exchange.getOut().copyFrom(exchange.getIn());
+                    exchange.getOut().setBody(message);
+                }
+                callback.done(false);
+            }
+
+            @Override
+            public void errorCallback(String channel, PubnubError error) {
+                exchange.setException(new CamelException(error.toString()));
+                callback.done(false);
+            }
+        };
+        return pubnubCallback;
+    }
+
+    private Operation getOperation(Exchange exchange) {
+        String operation = exchange.getIn().getHeader(PubNubConstants.OPERATION, String.class);
+        if (operation == null) {
+            operation = endpoint.getOperation();
+        }
+        return operation != null ? Operation.valueOf(operation) : Operation.PUBLISH;
+    }
+
+    private enum Operation {
+        HERE_NOW, WHERE_NOW, GET_STATE, SET_STATE, GET_HISTORY, PUBLISH;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/289a6728/components/camel-pubnub/src/main/resources/META-INF/LICENSE.txt
----------------------------------------------------------------------
diff --git a/components/camel-pubnub/src/main/resources/META-INF/LICENSE.txt b/components/camel-pubnub/src/main/resources/META-INF/LICENSE.txt
new file mode 100644
index 0000000..6b0b127
--- /dev/null
+++ b/components/camel-pubnub/src/main/resources/META-INF/LICENSE.txt
@@ -0,0 +1,203 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
+

http://git-wip-us.apache.org/repos/asf/camel/blob/289a6728/components/camel-pubnub/src/main/resources/META-INF/NOTICE.txt
----------------------------------------------------------------------
diff --git a/components/camel-pubnub/src/main/resources/META-INF/NOTICE.txt b/components/camel-pubnub/src/main/resources/META-INF/NOTICE.txt
new file mode 100644
index 0000000..2e215bf
--- /dev/null
+++ b/components/camel-pubnub/src/main/resources/META-INF/NOTICE.txt
@@ -0,0 +1,11 @@
+   =========================================================================
+   ==  NOTICE file corresponding to the section 4 d of                    ==
+   ==  the Apache License, Version 2.0,                                   ==
+   ==  in this case for the Apache Camel distribution.                    ==
+   =========================================================================
+
+   This product includes software developed by
+   The Apache Software Foundation (http://www.apache.org/).
+
+   Please read the different LICENSE files present in the licenses directory of
+   this distribution.

http://git-wip-us.apache.org/repos/asf/camel/blob/289a6728/components/camel-pubnub/src/main/resources/META-INF/services/org/apache/camel/TypeConverter
----------------------------------------------------------------------
diff --git a/components/camel-pubnub/src/main/resources/META-INF/services/org/apache/camel/TypeConverter b/components/camel-pubnub/src/main/resources/META-INF/services/org/apache/camel/TypeConverter
new file mode 100644
index 0000000..ebdd694
--- /dev/null
+++ b/components/camel-pubnub/src/main/resources/META-INF/services/org/apache/camel/TypeConverter
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+org.apache.camel.component.pubnub
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/289a6728/components/camel-pubnub/src/main/resources/META-INF/services/org/apache/camel/component/pubnub
----------------------------------------------------------------------
diff --git a/components/camel-pubnub/src/main/resources/META-INF/services/org/apache/camel/component/pubnub b/components/camel-pubnub/src/main/resources/META-INF/services/org/apache/camel/component/pubnub
new file mode 100644
index 0000000..1e8433c
--- /dev/null
+++ b/components/camel-pubnub/src/main/resources/META-INF/services/org/apache/camel/component/pubnub
@@ -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.pubnub.PubNubComponent

http://git-wip-us.apache.org/repos/asf/camel/blob/289a6728/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/PubNubComponentTest.java
----------------------------------------------------------------------
diff --git a/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/PubNubComponentTest.java b/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/PubNubComponentTest.java
new file mode 100644
index 0000000..664bafe
--- /dev/null
+++ b/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/PubNubComponentTest.java
@@ -0,0 +1,61 @@
+/**
+ * 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.pubnub;
+
+import org.apache.camel.EndpointInject;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.impl.JndiRegistry;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.json.JSONObject;
+import org.junit.Test;
+
+public class PubNubComponentTest extends CamelTestSupport {
+    private String endpoint = "pubnub:pubsub:someChannel?pubnub=#pubnub";
+
+    @EndpointInject(uri = "mock:result")
+    private MockEndpoint mockResult;
+
+    @Override
+    protected JndiRegistry createRegistry() throws Exception {
+        JndiRegistry registry = super.createRegistry();
+        registry.bind("pubnub", new PubNubMock("dummy", "dummy"));
+        return registry;
+    }
+
+    @Test
+    public void testPubNub() throws Exception {
+        mockResult.expectedMessageCount(1);
+        mockResult.expectedHeaderReceived("CamelPubNubChannel", "someChannel");
+        mockResult.expectedBodiesReceived("{\"hi\":\"there\"}");
+        JSONObject jo = new JSONObject();
+        jo.put("hi", "there");
+        template.sendBody("direct:publish", jo);
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() {
+                from(endpoint).to("mock:result");
+                from("direct:publish").to(endpoint);
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/289a6728/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/PubNubConfigurationTest.java
----------------------------------------------------------------------
diff --git a/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/PubNubConfigurationTest.java b/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/PubNubConfigurationTest.java
new file mode 100644
index 0000000..23e5c56
--- /dev/null
+++ b/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/PubNubConfigurationTest.java
@@ -0,0 +1,55 @@
+/**
+ * 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.pubnub;
+
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+
+public class PubNubConfigurationTest extends CamelTestSupport {
+
+    @Test(expected = IllegalArgumentException.class)
+    public void createEndpointWithIllegalArguments() throws Exception {
+        PubNubComponent component = new PubNubComponent(context);
+        component.createEndpoint("pubnub:XXX:xxx");
+    }
+
+    @Test
+    public void createEndpointWithMinimalConfiguration() throws Exception {
+        PubNubComponent component = new PubNubComponent(context);
+        PubNubEndpoint endpoint = (PubNubEndpoint) component.createEndpoint("pubnub://pubsub:xxx?subscriberKey=mysubkey");
+
+        assertEquals("xxx", endpoint.getChannel());
+        assertEquals("mysubkey", endpoint.getSubscriberKey());
+        assertTrue(endpoint.isSsl());
+    }
+
+    @Test
+    public void createEndpointWithMaximalConfiguration() throws Exception {
+        PubNubComponent component = new PubNubComponent(context);
+        PubNubEndpoint endpoint = (PubNubEndpoint)component
+            .createEndpoint("pubnub://pubsub:xxx?subscriberKey=mysubkey&publisherKey=mypubkey&secretKey=secrets&uuid=myuuid&operation=PUBLISH&ssl=false");
+
+        assertEquals("xxx", endpoint.getChannel());
+        assertEquals("mysubkey", endpoint.getSubscriberKey());
+        assertEquals("mypubkey", endpoint.getPublisherKey());
+        assertEquals("secrets", endpoint.getSecretKey());
+        assertEquals("myuuid", endpoint.getUuid());
+        assertEquals("PUBLISH", endpoint.getOperation());
+        assertFalse(endpoint.isSsl());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/289a6728/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/PubNubEmptyPayloadTest.java
----------------------------------------------------------------------
diff --git a/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/PubNubEmptyPayloadTest.java b/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/PubNubEmptyPayloadTest.java
new file mode 100644
index 0000000..d641259
--- /dev/null
+++ b/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/PubNubEmptyPayloadTest.java
@@ -0,0 +1,55 @@
+/**
+ * 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.pubnub;
+
+import org.apache.camel.CamelExecutionException;
+import org.apache.camel.EndpointInject;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.impl.JndiRegistry;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+
+public class PubNubEmptyPayloadTest extends CamelTestSupport {
+    private final String endpoint = "pubnub:pubsub:someChannel?pubnub=#pubnub";
+
+    @EndpointInject(uri = "mock:result")
+    private MockEndpoint mockResult;
+
+    @Override
+    protected JndiRegistry createRegistry() throws Exception {
+        JndiRegistry registry = super.createRegistry();
+        registry.bind("pubnub", new PubNubMock("dummy", "dummy"));
+        return registry;
+    }
+
+    @Test(expected = CamelExecutionException.class)
+    public void testPubNub() throws Exception {
+        template.sendBody("direct:publish", null);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                from("direct:publish").to(endpoint);
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/289a6728/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/PubNubMock.java
----------------------------------------------------------------------
diff --git a/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/PubNubMock.java b/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/PubNubMock.java
new file mode 100644
index 0000000..f7b6917
--- /dev/null
+++ b/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/PubNubMock.java
@@ -0,0 +1,186 @@
+/**
+ * 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.pubnub;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import com.pubnub.api.Callback;
+import com.pubnub.api.Pubnub;
+import com.pubnub.api.PubnubException;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+public class PubNubMock extends Pubnub {
+    private static Map<String, Callback> subscribers = new ConcurrentHashMap<String, Callback>();
+    private static Map<String, Callback> presenceSubscribers = new ConcurrentHashMap<String, Callback>();
+    private static Map<String, JSONObject> stateMap = new ConcurrentHashMap<String, JSONObject>();
+    private final ExecutorService executorService = Executors.newFixedThreadPool(3);
+
+    public PubNubMock(String publishKey, String subscribeKey) {
+        super(publishKey, subscribeKey);
+    }
+
+    @Override
+    public void subscribe(String channel, Callback callback) throws PubnubException {
+        subscribers.put(channel, callback);
+        executorService.execute(() -> {
+            try {
+                Thread.sleep(500);
+                callback.connectCallback(channel, "OK");
+            } catch (InterruptedException e) {
+            }
+        });
+        Callback presenceCallback = presenceSubscribers.get(channel);
+        if (presenceCallback != null) {
+            executorService.execute(() -> {
+                try {
+                    Thread.sleep(500);
+                    String presence = "{\"action\":\"join\",\"timestamp\":1431777382,\"uuid\":\"d08f121b-d146-45af-a814-058c1b7d283a\",\"occupancy\":1}";
+                    presenceCallback.successCallback(channel, new JSONObject(presence), "" + System.currentTimeMillis());
+                } catch (Exception e) {
+                }
+            });
+        }
+    }
+
+    @Override
+    public void publish(String channel, JSONObject message, Callback callback) {
+        callback.successCallback(channel, "OK");
+        Callback clientMockCallback = subscribers.get(channel);
+        if (clientMockCallback != null) {
+            executorService.execute(() -> {
+                try {
+                    Thread.sleep(1000);
+                    clientMockCallback.successCallback(channel, message, "" + System.currentTimeMillis());
+                } catch (InterruptedException e) {
+                }
+            });
+        }
+    }
+
+    @Override
+    public void publish(String channel, JSONArray message, Callback callback) {
+        callback.successCallback(channel, "OK");
+        Callback clientMockCallback = subscribers.get(channel);
+        if (clientMockCallback != null) {
+            executorService.execute(() -> {
+                try {
+                    Thread.sleep(1000);
+                    clientMockCallback.successCallback(channel, message, "" + System.currentTimeMillis());
+                } catch (InterruptedException e) {
+                }
+            });
+        }
+    }
+
+    @Override
+    public void publish(String channel, String message, Callback callback) {
+        callback.successCallback(channel, "OK");
+        Callback clientMockCallback = subscribers.get(channel);
+        if (clientMockCallback != null) {
+            executorService.execute(() -> {
+                try {
+                    Thread.sleep(1000);
+                    clientMockCallback.successCallback(channel, message, "" + System.currentTimeMillis());
+                } catch (InterruptedException e) {
+                }
+            });
+        }
+    }
+
+    @Override
+    public void presence(String channel, Callback callback) throws PubnubException {
+        presenceSubscribers.put(channel, callback);
+        executorService.execute(() -> {
+            try {
+                Thread.sleep(1000);
+                callback.connectCallback(channel, "OK");
+            } catch (InterruptedException e) {
+            }
+        });
+    }
+
+    @Override
+    public void history(String channel, boolean reverse, Callback callback) {
+        executorService.execute(() -> {
+            try {
+                Thread.sleep(1000);
+                callback.successCallback(channel, new JSONArray("[[\"message1\", \"message2\", \"message3\"],\"Start Time Token\",\"End Time Token\"]"));
+            } catch (Exception e) {
+            }
+        });
+    }
+
+    @Override
+    public void setState(String channel, String uuid, JSONObject state, Callback callback) {
+        stateMap.put(uuid, state);
+        executorService.execute(() -> {
+            try {
+                Thread.sleep(1000);
+                callback.successCallback(channel, "OK");
+            } catch (Exception e) {
+            }
+        });
+    }
+
+    @Override
+    public void getState(String channel, String uuid, Callback callback) {
+        JSONObject jsonObject = stateMap.get(uuid);
+        executorService.execute(() -> {
+            try {
+                Thread.sleep(1000);
+                callback.successCallback(channel, jsonObject);
+            } catch (Exception e) {
+            }
+        });
+    }
+
+    @Override
+    public void hereNow(String channel, boolean state, boolean uuids, Callback callback) {
+
+        executorService.execute(() -> {
+            try {
+                Thread.sleep(500);
+                //@formatter:off
+                JSONObject response = new JSONObject("{\"uuids\":[\"76c2c571-9a2b-d074-b4f8-e93e09f49bd\"," 
+                                                    + "\"175c2c67-b2a9-470d-8f4b-1db94f90e39e\", "
+                                                    + "\"2c67175c-2a9b-074d-4b8f-90e39e1db94f\"]," 
+                                                    + "\"occupancy\":3 }");
+                //@formatter:on
+                callback.successCallback(channel, response);
+            } catch (Exception e) {
+            }
+
+        });
+    }
+
+    @Override
+    public void whereNow(String uuid, Callback callback) {
+        executorService.execute(() -> {
+            try {
+                Thread.sleep(1000);
+                callback.successCallback("channel", new JSONObject("{\"channels\":[\"hello_world\"]}"));
+            } catch (Exception e) {
+            }
+        });
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/289a6728/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/PubNubOperationsTest.java
----------------------------------------------------------------------
diff --git a/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/PubNubOperationsTest.java b/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/PubNubOperationsTest.java
new file mode 100644
index 0000000..c918009
--- /dev/null
+++ b/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/PubNubOperationsTest.java
@@ -0,0 +1,91 @@
+/**
+ * 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.pubnub;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.impl.JndiRegistry;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.junit.Test;
+
+public class PubNubOperationsTest extends CamelTestSupport {
+
+    @Test
+    public void testWhereNow() throws Exception {
+        Map<String, Object> headers = new HashMap<String, Object>();
+        headers.put(PubNubConstants.OPERATION, "WHERE_NOW");
+        headers.put(PubNubConstants.UUID, "uuid");
+        JSONObject response = template.requestBodyAndHeaders("direct:publish", null, headers, JSONObject.class);
+        assertNotNull(response);
+        assertEquals("hello_world", response.getJSONArray("channels").getString(0));
+    }
+
+    @Test
+    public void testHereNow() throws Exception {
+        Map<String, Object> headers = new HashMap<String, Object>();
+        headers.put(PubNubConstants.OPERATION, "HERE_NOW");
+        JSONObject response = template.requestBodyAndHeaders("direct:publish", null, headers, JSONObject.class);
+        assertNotNull(response);
+        assertEquals(3, response.getInt("occupancy"));
+    }
+
+    @Test
+    public void testGetHistory() throws Exception {
+        Map<String, Object> headers = new HashMap<String, Object>();
+        headers.put(PubNubConstants.OPERATION, "GET_HISTORY");
+        JSONArray response = template.requestBodyAndHeaders("direct:publish", null, headers, JSONArray.class);
+        assertNotNull(response);
+        assertEquals("message1", response.getJSONArray(0).getString(0));
+    }
+
+    @Test
+    public void testSetAndGetState() throws Exception {
+        Map<String, Object> headers = new HashMap<String, Object>();
+        headers.put(PubNubConstants.OPERATION, "SET_STATE");
+        headers.put(PubNubConstants.UUID, "myuuid");
+        JSONObject state = new JSONObject("{\"state\":\"active\", \"lat\":\"55.645499\", \"lon\":\"12.370967\"}");
+        template.sendBodyAndHeaders("direct:publish", state, headers);
+        headers.replace(PubNubConstants.OPERATION, "GET_STATE");
+        JSONObject response = template.requestBodyAndHeaders("direct:publish", null, headers, JSONObject.class);
+        assertNotNull(response);
+        assertEquals(state, response);
+    }
+
+    @Override
+    protected JndiRegistry createRegistry() throws Exception {
+        JndiRegistry registry = super.createRegistry();
+        registry.bind("pubnub", new PubNubMock("dummy", "dummy"));
+        return registry;
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() {
+                //@formatter:off
+                from("direct:publish").to("pubnub://pubsub:mychannel?uuid=myuuid&pubnub=#pubnub")
+                .to("log:io.rhiot.component.pubnub?showAll=true&multiline=true")
+                .to("mock:result");
+                //@formatter:on
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/289a6728/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/PubNubPresensTest.java
----------------------------------------------------------------------
diff --git a/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/PubNubPresensTest.java b/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/PubNubPresensTest.java
new file mode 100644
index 0000000..b794537
--- /dev/null
+++ b/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/PubNubPresensTest.java
@@ -0,0 +1,72 @@
+/**
+ * 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.pubnub;
+
+import com.pubnub.api.Callback;
+
+import org.apache.camel.EndpointInject;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.impl.JndiRegistry;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.json.JSONObject;
+import org.junit.Test;
+
+public class PubNubPresensTest extends CamelTestSupport {
+    boolean connected;
+    private PubNubMock pubnubMock = new PubNubMock("foo", "bar");
+
+    @EndpointInject(uri = "mock:result")
+    private MockEndpoint mockResult;
+
+    @Test
+    public void testPresens() throws Exception {
+        mockResult.expectedMessageCount(1);
+        mockResult.expectedHeaderReceived(PubNubConstants.CHANNEL, "mychannel");
+        pubnubMock.subscribe("mychannel", new Callback() {
+            @Override
+            public void connectCallback(String channel, Object message) {
+                connected = true;
+            }
+        });
+        assertMockEndpointsSatisfied();
+        assertTrue(connected);
+        JSONObject presenceResponse = mockResult.getReceivedExchanges().get(0).getIn().getBody(JSONObject.class);
+        assertEquals("join", presenceResponse.getString("action"));
+    }
+
+    @Override
+    protected JndiRegistry createRegistry() throws Exception {
+        JndiRegistry registry = super.createRegistry();
+        registry.bind("pubnub", new PubNubMock("dummy", "dummy"));
+        return registry;
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() {
+                //@formatter:off
+                from("pubnub://presence:mychannel?pubnub=#pubnub")
+                    .to("log:org.apache.camel.component.pubnub?showAll=true&multiline=true")
+                    .to("mock:result");
+                //@formatter:on
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/289a6728/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/example/PubNubExampleConstants.java
----------------------------------------------------------------------
diff --git a/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/example/PubNubExampleConstants.java b/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/example/PubNubExampleConstants.java
new file mode 100644
index 0000000..f24c917
--- /dev/null
+++ b/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/example/PubNubExampleConstants.java
@@ -0,0 +1,24 @@
+/**
+ * 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.pubnub.example;
+
+public interface PubNubExampleConstants {
+    // replace subscriber+publisher key with one obtained from PubNub.
+    // http://www.pubnub.com
+    String PUBNUB_SUBSCRIBER_KEY = "mysubkey";
+    String PUBNUB_PUBLISHER_KEY = "mypubkey";
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/289a6728/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/example/PubNubOperationsExample.java
----------------------------------------------------------------------
diff --git a/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/example/PubNubOperationsExample.java b/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/example/PubNubOperationsExample.java
new file mode 100644
index 0000000..10db410
--- /dev/null
+++ b/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/example/PubNubOperationsExample.java
@@ -0,0 +1,61 @@
+/**
+ * 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.pubnub.example;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.main.Main;
+import org.json.JSONObject;
+
+//@formatter:off
+/**
+ * Just a small http server hack to try out pubnub method calls. 
+ * HERE_NOW, WHERE_NOW, GET_STATE, SET_STATE, GET_HISTORY, PUBLISH; 
+ * usage : 
+ * do a GET with http param CamelPubNubOperation=METHOD_TO_ACTIVATE eg. HERE_NOW 
+ * 
+ * SET_STATE requires a http param 'body' with some json that is used as pubnub state object. 
+ * Can be any valid json string.
+ *
+ */
+//@formatter:on
+public final class PubNubOperationsExample {
+
+    private PubNubOperationsExample() {
+    }
+
+    public static void main(String[] args) throws Exception {
+        Main main = new Main();
+        main.addRouteBuilder(new RestRoute());
+        main.run();
+    }
+
+    static class RestRoute extends RouteBuilder {
+        private String pubnub = "pubnub://pubsub:iot?publisherKey=" + PubNubExampleConstants.PUBNUB_PUBLISHER_KEY + "&subscriberKey="
+                                + PubNubExampleConstants.PUBNUB_SUBSCRIBER_KEY;
+
+        @Override
+        public void configure() throws Exception {
+            //@formatter:off
+            from("netty-http:http://0.0.0.0:8080?urlDecodeHeaders=true")
+                .setBody(simple("${header.body}"))
+                .convertBodyTo(JSONObject.class)
+                .to(pubnub);
+            //@formatter:on
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/289a6728/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/example/PubNubPresenseExample.java
----------------------------------------------------------------------
diff --git a/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/example/PubNubPresenseExample.java b/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/example/PubNubPresenseExample.java
new file mode 100644
index 0000000..2122bf0
--- /dev/null
+++ b/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/example/PubNubPresenseExample.java
@@ -0,0 +1,44 @@
+/**
+ * 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.pubnub.example;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.main.Main;
+
+public final class PubNubPresenseExample {
+
+    private PubNubPresenseExample() {
+    }
+
+    public static void main(String[] args) throws Exception {
+        Main main = new Main();
+        main.addRouteBuilder(new PresensRoute());
+        main.run();
+    }
+
+    static class PresensRoute extends RouteBuilder {
+        @Override
+        public void configure() throws Exception {
+            //@formatter:off
+            from("pubnub://presence:iot?subscriberKey=" + PubNubExampleConstants.PUBNUB_SUBSCRIBER_KEY)
+                .log("${body}")
+                .to("mock:result");
+            //@formatter:on
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/289a6728/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/example/PubNubSensor2Example.html
----------------------------------------------------------------------
diff --git a/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/example/PubNubSensor2Example.html b/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/example/PubNubSensor2Example.html
new file mode 100644
index 0000000..9794b0b
--- /dev/null
+++ b/components/camel-pubnub/src/test/java/org/apache/camel/component/pubnub/example/PubNubSensor2Example.html
@@ -0,0 +1,87 @@
+<!--
+ * 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.
+-->
+<html>
+  <head>
+
+    <link rel="stylesheet" type="text/css" href="http://pubnub.github.io/eon/lib/eon.css">
+    <script src="http://cdn.pubnub.com/pubnub-3.7.1.min.js"></script>
+    <script src="http://pubnub.github.io/eon/lib/eon-chart.js"></script>
+
+
+    <style>
+      .c3-region-1 {
+        fill: #dd3333;
+        fill-opacity: 0.8
+      }
+    </style>
+
+  </head>
+  <body>
+  	<div>
+  		<div align="center">
+  		<h1>Description</h1>
+  		</div>
+  		<br/>
+  		This is a example of PubNub EON charts displaying stream data using the camel-pubnub component.
+  		<br/>
+  		To see live data you have to:
+  		<ul>
+  			<li>Sign up for a PubNub acount</li>
+  			<li>Replace the 'subscribe_key' in this html.</li>
+  			<li>Update the constants PUBNUB_SUBSCRIBER_KEY and PUBNUB_PUBLISHER_KEY in the class PubNubExampleConstants</li>
+  			<li>Run the class PubNubSensor2Example</li>
+  			
+  		</ul>
+  	</div>
+    <div id="chart"></div>
+    <script>
+
+    var pubnub = PUBNUB.init({
+		subscribe_key: 'mysubscriberkey'
+	});
+    eon.chart({
+    	pubnub: pubnub,
+    	history: false,
+	    channel: 'iot',
+    	flow: true,
+    	generate: {
+    	    bindto: '#chart',
+    	    data: {
+				x: 'x',
+				labels: true
+    	    },
+    	    axis: {
+    	      	x: {
+	    	        type: 'timeseries',
+	    	        tick: {
+	    	            format: '%Y-%m-%d'
+	    	        }
+    	      	}
+    	    }
+    	},
+	    transform: function(m) {
+	    	var response = {columns: [
+	    		['x', new Date().getTime()],
+	    		['Humidity', m.humidity],
+	    		['Temperature', m.temperature]
+	    	]};
+	    	return response;
+	    }
+	});
+    </script>
+  </body>
+</html>
\ No newline at end of file