Added Salesforce component

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

Branch: refs/heads/trunk
Commit: 72a1767eb44fbb03fc29691e80509f21e6e65233
Parents: b0ccd94
Author: Dhiraj Bokde <dbo...@fusesource.com>
Authored: Wed Jun 5 00:51:21 2013 -0700
Committer: Dhiraj Bokde <dbo...@fusesource.com>
Committed: Wed Jun 5 02:04:16 2013 -0700

----------------------------------------------------------------------
 .gitignore                                      |   1 +
 .../camel-salesforce-component/.gitignore       |   6 +
 .../camel-salesforce-component/README.md        |  68 ++
 .../camel-salesforce-component/pom.xml          | 121 ++++
 .../salesforce/SalesforceComponent.java         | 233 +++++++
 .../salesforce/SalesforceConsumer.java          | 215 ++++++
 .../salesforce/SalesforceEndpoint.java          |  96 +++
 .../salesforce/SalesforceEndpointConfig.java    | 276 ++++++++
 .../salesforce/SalesforceLoginConfig.java       |  99 +++
 .../salesforce/SalesforceProducer.java          | 102 +++
 .../salesforce/api/JodaTimeConverter.java       |  64 ++
 .../salesforce/api/PicklistEnumConverter.java   |  80 +++
 .../salesforce/api/SalesforceException.java     | 104 +++
 .../salesforce/api/dto/AbstractDTOBase.java     |  40 ++
 .../api/dto/AbstractQueryRecordsBase.java       |  72 ++
 .../salesforce/api/dto/AbstractSObjectBase.java | 172 +++++
 .../salesforce/api/dto/Attributes.java          |  38 ++
 .../salesforce/api/dto/ChildRelationShip.java   |  74 ++
 .../salesforce/api/dto/CreateSObjectResult.java |  57 ++
 .../salesforce/api/dto/GlobalObjects.java       |  57 ++
 .../salesforce/api/dto/PickListValue.java       |  70 ++
 .../salesforce/api/dto/RecentItem.java          |  56 ++
 .../salesforce/api/dto/RecordTypeInfo.java      |  56 ++
 .../component/salesforce/api/dto/RestError.java |  68 ++
 .../salesforce/api/dto/RestResources.java       | 100 +++
 .../component/salesforce/api/dto/SObject.java   | 237 +++++++
 .../salesforce/api/dto/SObjectBasicInfo.java    |  46 ++
 .../salesforce/api/dto/SObjectDescription.java  |  67 ++
 .../api/dto/SObjectDescriptionUrls.java         |  47 ++
 .../salesforce/api/dto/SObjectField.java        | 414 ++++++++++++
 .../salesforce/api/dto/SObjectUrls.java         |  56 ++
 .../salesforce/api/dto/SearchResult.java        |  49 ++
 .../salesforce/api/dto/SearchResults.java       |  41 ++
 .../component/salesforce/api/dto/Version.java   |  52 ++
 .../component/salesforce/api/dto/Versions.java  |  40 ++
 .../salesforce/api/dto/bulk/BatchInfo.java      | 342 ++++++++++
 .../salesforce/api/dto/bulk/BatchInfoList.java  |  82 +++
 .../salesforce/api/dto/bulk/BatchResult.java    |  82 +++
 .../salesforce/api/dto/bulk/BatchStateEnum.java |  75 +++
 .../api/dto/bulk/ConcurrencyModeEnum.java       |  66 ++
 .../salesforce/api/dto/bulk/ContentType.java    |  57 ++
 .../salesforce/api/dto/bulk/Error.java          | 105 +++
 .../salesforce/api/dto/bulk/JobInfo.java        | 673 +++++++++++++++++++
 .../salesforce/api/dto/bulk/JobStateEnum.java   |  72 ++
 .../salesforce/api/dto/bulk/ObjectFactory.java  | 200 ++++++
 .../salesforce/api/dto/bulk/OperationEnum.java  |  78 +++
 .../salesforce/api/dto/bulk/QueryResult.java    |  84 +++
 .../api/dto/bulk/QueryResultList.java           |  82 +++
 .../salesforce/api/dto/bulk/Result.java         | 147 ++++
 .../salesforce/api/dto/bulk/ResultError.java    | 140 ++++
 .../salesforce/api/dto/bulk/SObject.java        | 138 ++++
 .../salesforce/api/dto/bulk/StatusCode.java     | 395 +++++++++++
 .../salesforce/api/dto/bulk/package-info.java   |  18 +
 .../salesforce/internal/OperationName.java      |  71 ++
 .../salesforce/internal/PayloadFormat.java      |  22 +
 .../salesforce/internal/SalesforceSession.java  | 336 +++++++++
 .../internal/client/AbstractClientBase.java     | 196 ++++++
 .../internal/client/BulkApiClient.java          |  92 +++
 .../internal/client/DefaultBulkApiClient.java   | 481 +++++++++++++
 .../internal/client/DefaultRestClient.java      | 364 ++++++++++
 .../salesforce/internal/client/RestClient.java  | 177 +++++
 .../internal/client/SalesforceExchange.java     |  36 +
 .../client/SalesforceSecurityListener.java      | 162 +++++
 .../internal/client/SyncResponseCallback.java   |  57 ++
 .../salesforce/internal/dto/LoginError.java     |  47 ++
 .../salesforce/internal/dto/LoginToken.java     |  81 +++
 .../internal/dto/NotifyForFieldsEnum.java       |  53 ++
 .../internal/dto/NotifyForOperationsEnum.java   |  52 ++
 .../salesforce/internal/dto/PushTopic.java      | 100 +++
 .../internal/dto/QueryRecordsPushTopic.java     |  38 ++
 .../salesforce/internal/dto/RestErrors.java     |  41 ++
 .../processor/AbstractRestProcessor.java        | 538 +++++++++++++++
 .../processor/AbstractSalesforceProcessor.java  |  84 +++
 .../internal/processor/BulkApiProcessor.java    | 377 +++++++++++
 .../internal/processor/JsonRestProcessor.java   | 180 +++++
 .../internal/processor/SalesforceProcessor.java |  27 +
 .../internal/processor/XmlRestProcessor.java    | 240 +++++++
 .../internal/streaming/PushTopicHelper.java     | 206 ++++++
 .../internal/streaming/SubscriptionHelper.java  | 372 ++++++++++
 .../org/apache/camel/component/salesforce       |   1 +
 .../salesforce/AbstractBulkApiTestBase.java     | 105 +++
 .../salesforce/AbstractSalesforceTestBase.java  |  60 ++
 .../salesforce/BulkApiBatchIntegrationTest.java | 109 +++
 .../salesforce/BulkApiJobIntegrationTest.java   | 111 +++
 .../salesforce/BulkApiQueryIntegrationTest.java |  85 +++
 .../component/salesforce/LoginConfigHelper.java |  43 ++
 .../salesforce/RestApiIntegrationTest.java      | 408 +++++++++++
 .../salesforce/StreamingApiIntegrationTest.java | 109 +++
 .../component/salesforce/dto/Document.java      | 201 ++++++
 .../component/salesforce/dto/Line_Item__c.java  |  74 ++
 .../salesforce/dto/Merchandise__c.java          |  61 ++
 .../dto/QueryRecordsLine_Item__c.java           |  35 +
 .../internal/SessionIntegrationTest.java        |  63 ++
 .../src/test/resources/log4j.properties         |  18 +
 .../src/test/resources/test-request.csv         |   3 +
 .../src/test/resources/test-request.xml         |  15 +
 .../camel-salesforce-maven-plugin/.gitignore    |   5 +
 .../camel-salesforce-maven-plugin/README.md     |  26 +
 .../camel-salesforce-maven-plugin/pom.xml       |  78 +++
 .../apache/camel/maven/CamelSalesforceMojo.java | 569 ++++++++++++++++
 .../src/main/resources/sobject-picklist.vm      |  52 ++
 .../src/main/resources/sobject-pojo.vm          |  60 ++
 .../src/main/resources/sobject-query-records.vm |  29 +
 .../CamelSalesforceMojoIntegrationTest.java     |  85 +++
 .../src/test/resources/log4j.properties         |  19 +
 components/camel-salesforce/pom.xml             |  38 ++
 components/pom.xml                              |   1 +
 parent/pom.xml                                  |   6 +
 .../features/src/main/resources/features.xml    |  16 +
 109 files changed, 13125 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 394c174..b74e107 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,4 +9,5 @@ target
 .settings
 .checkstyle
 *.log
+test-salesforce-login.properties
 dependency-reduced-pom.xml

http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/.gitignore
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/.gitignore 
b/components/camel-salesforce/camel-salesforce-component/.gitignore
new file mode 100644
index 0000000..acf55cc
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/.gitignore
@@ -0,0 +1,6 @@
+target
+*.ipr
+*.iml
+*.iws
+# Salesforce login properties
+*test-login.properties*

http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/README.md
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/README.md 
b/components/camel-salesforce/camel-salesforce-component/README.md
new file mode 100644
index 0000000..9bf9845
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/README.md
@@ -0,0 +1,68 @@
+# Camel Salesforce component #
+
+This component supports producer and consumer endpoints to communicate with 
Salesforce using Java DTOs. 
+There is a companion maven plugin 
[camel-salesforce-plugin](https://github.com/dhirajsb/camel-salesforce-maven-plugin)
 that generates these DTOs. 
+
+The component supports the following Salesforce APIs
+
+## REST API ##
+
+Producer endpoints can use the following APIs. Most of the APIs process one 
record at a time, the Query API can retrieve multiple Records. 
+
+* getVersions - Gets supported Salesforce REST API versions
+* getResources - Gets available Salesforce REST Resource endpoints
+* getGlobalObjects - Gets metadata for all available SObject types
+* getBasicInfo - Gets basic metadata for a specific SObject type
+* getDescription - Gets comprehensive metadata for a specific SObject type
+* getSObject - Gets an SObject using its Salesforce Id
+* createSObject - Creates an SObject
+* updateSObject - Updates an SObject using Id
+* deleteSObject - Deletes an SObject using Id
+* getSObjectWithId - Gets an SObject using an external (user defined) id field
+* upsertSObject - Updates or inserts an SObject using an external id
+* deleteSObjectWithId - Deletes an SObject using an external id
+* query - Runs a Salesforce SOQL query
+* queryMore - Retrieves more results (in case of large number of results) 
using result link returned from the 'query' API
+* search - Runs a Salesforce SOSL query
+
+For example, the following producer endpoint uses the upsertSObject API, with 
the sObjectIdName parameter specifying 'Name' as the external id field. 
+The request message body should be an SObject DTO generated using the maven 
plugin. 
+The response message will either be NULL if an existing record was updated, or 
[CreateSObjectResult] with an id of the new record, or a list of errors while 
creating the new object.
+
+       ...to("force:upsertSObject?sObjectIdName=Name")...
+
+## Bulk API ##
+
+Producer endpoints can use the following APIs. All Job data formats, i.e. xml, 
csv, zip/xml, and zip/csv are supported. 
+The request and response have to be marshalled/unmarshalled by the route. 
Usually the request will be some stream source like a CSV file, 
+and the response may also be saved to a file to be correlated with the 
request. 
+
+* createJob - Creates a Salesforce Bulk Job
+* getJob - Gets a Job using its Salesforce Id
+* closeJob - Closes a Job
+* abortJob - Aborts a Job
+* createBatch - Submits a Batch within a Bulk Job
+* getBatch - Gets a Batch using Id
+* getAllBatches - Gets all Batches for a Bulk Job Id
+* getRequest - Gets Request data (XML/CSV) for a Batch
+* getResults - Gets the results of the Batch when its complete
+* createBatchQuery - Creates a Batch from an SOQL query
+* getQueryResultIds - Gets a list of Result Ids for a Batch Query
+* getQueryResult - Gets results for a Result Id
+
+For example, the following producer endpoint uses the createBatch API to 
create a Job Batch. 
+The in message must contain a body that can be converted into an InputStream 
(usually UTF-8 CSV or XML content from a file, etc.) and header fields 'jobId' 
for the Job and 'contentType' for the Job content type, which can be XML, CSV, 
ZIP\_XML or ZIP\_CSV. The put message body will contain [BatchInfo] on success, 
or throw a [SalesforceException] on error.
+
+       ...to("force:createBatchJob")..
+
+## Streaming API ##
+
+Consumer endpoints can use the following sytax for streaming endpoints to 
receive Salesforce notifications on create/update. 
+
+To create and subscribe to a topic
+
+       
from("force:CamelTestTopic?notifyForFields=ALL&notifyForOperations=ALL&sObjectName=Merchandise__c&updateTopic=true&sObjectQuery=SELECT
 Id, Name FROM Merchandise__c")...
+
+To subscribe to an existing topic
+
+       from("force:CamelTestTopic&sObjectName=Merchandise__c")...

http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/pom.xml
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/pom.xml 
b/components/camel-salesforce/camel-salesforce-component/pom.xml
new file mode 100644
index 0000000..3a811f5
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/pom.xml
@@ -0,0 +1,121 @@
+<?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-salesforce</artifactId>
+    <version>2.12-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>camel-salesforce-component</artifactId>
+  <packaging>bundle</packaging>
+  <name>Camel :: Salesforce component</name>
+  <description>Camel Salesforce support</description>
+
+  <properties>
+    <camel.osgi.export.pkg/>
+    <camel.osgi.export>
+      org.apache.camel.component.salesforce;version=${project.version},
+      org.apache.camel.component.salesforce.api.*;version=${project.version}
+    </camel.osgi.export>
+    
<camel.osgi.private.pkg>org.apache.camel.component.salesforce.internal.*</camel.osgi.private.pkg>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-client</artifactId>
+      <version>${jetty-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-util</artifactId>
+      <version>${jetty-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-io</artifactId>
+      <version>${jetty-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.jackson</groupId>
+      <artifactId>jackson-mapper-asl</artifactId>
+      <version>${jackson-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.thoughtworks.xstream</groupId>
+      <artifactId>xstream</artifactId>
+      <version>${xstream-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.cometd.java</groupId>
+      <artifactId>cometd-java-client</artifactId>
+      <version>${cometd-java-client-version}</version>
+      <exclusions>
+        <exclusion>
+          <groupId>org.eclipse.jetty</groupId>
+          <artifactId>jetty-util</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.eclipse.jetty</groupId>
+          <artifactId>jetty-io</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>joda-time</groupId>
+      <artifactId>joda-time</artifactId>
+      <version>${jodatime2-bundle-version}</version>
+    </dependency>
+    <!-- logging -->
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+      <version>${slf4j-api-version}</version>
+    </dependency>
+
+    <!-- testing -->
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-log4j12</artifactId>
+      <version>${slf4j-api-version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>log4j</groupId>
+      <artifactId>log4j</artifactId>
+      <version>${log4j-version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-test</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceComponent.java
----------------------------------------------------------------------
diff --git 
a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceComponent.java
 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceComponent.java
new file mode 100644
index 0000000..a48502a
--- /dev/null
+++ 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceComponent.java
@@ -0,0 +1,233 @@
+/**
+ * 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.salesforce;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.impl.DefaultComponent;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.ServiceHelper;
+import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.client.RedirectListener;
+import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.api.dto.AbstractSObjectBase;
+import org.apache.camel.component.salesforce.internal.OperationName;
+import org.apache.camel.component.salesforce.internal.SalesforceSession;
+import 
org.apache.camel.component.salesforce.internal.streaming.SubscriptionHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Represents the component that manages {@link SalesforceEndpoint}.
+ */
+public class SalesforceComponent extends DefaultComponent {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(SalesforceComponent.class);
+
+    private static final int MAX_CONNECTIONS_PER_ADDRESS = 20;
+    private static final int CONNECTION_TIMEOUT = 60000;
+    private static final int RESPONSE_TIMEOUT = 60000;
+
+    private SalesforceLoginConfig loginConfig;
+    private SalesforceEndpointConfig config;
+    private String[] packages;
+
+    // component state
+    private HttpClient httpClient;
+    private SalesforceSession session;
+    private Map<String, Class<?>> classMap;
+
+    // Lazily created helper for consumer endpoints
+    private SubscriptionHelper subscriptionHelper;
+
+    protected Endpoint createEndpoint(String uri, String remaining, 
Map<String, Object> parameters) throws Exception {
+        // get Operation from remaining URI
+        OperationName operationName = null;
+        String topicName = null;
+        try {
+            LOG.debug("Creating endpoint for ", remaining);
+            operationName = OperationName.fromValue(remaining);
+        } catch (IllegalArgumentException ex) {
+            // if its not an operation name, treat is as topic name for 
consumer endpoints
+            topicName = remaining;
+        }
+
+        // create endpoint config
+        if (config == null) {
+            config = new SalesforceEndpointConfig();
+        }
+        if (config.getHttpClient() == null) {
+            // set the component's httpClient as default
+            config.setHttpClient(httpClient);
+        }
+
+        // create a deep copy and map parameters
+        final SalesforceEndpointConfig copy = config.copy();
+        setProperties(copy, parameters);
+
+        final SalesforceEndpoint endpoint = new SalesforceEndpoint(uri, this, 
copy,
+            operationName, topicName);
+
+        // map remaining parameters to endpoint (specifically, synchronous)
+        setProperties(endpoint, parameters);
+
+        return endpoint;
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+
+        // validate properties
+        ObjectHelper.notNull(loginConfig, "loginConfig");
+
+        // create a Jetty HttpClient if not already set
+        if (null == httpClient) {
+            if (config != null && config.getHttpClient() != null) {
+                httpClient = config.getHttpClient();
+            } else {
+                httpClient = new HttpClient();
+                
httpClient.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
+                
httpClient.setMaxConnectionsPerAddress(MAX_CONNECTIONS_PER_ADDRESS);
+                httpClient.setConnectTimeout(CONNECTION_TIMEOUT);
+                httpClient.setTimeout(RESPONSE_TIMEOUT);
+            }
+        }
+
+        // add redirect listener to handle Salesforce redirects
+        // this is ok to do since the RedirectListener is in the same 
classloader as Jetty client
+        String listenerClass = RedirectListener.class.getName();
+        if (httpClient.getRegisteredListeners() == null ||
+            !httpClient.getRegisteredListeners().contains(listenerClass)) {
+            httpClient.registerListener(listenerClass);
+        }
+        // SalesforceSecurityListener can't be registered the same way
+        // since Jetty HttpClient's Class.forName() can't see it
+
+        // start the Jetty client to initialize thread pool, etc.
+        httpClient.start();
+
+        // support restarts
+        if (null == this.session) {
+            this.session = new SalesforceSession(httpClient, loginConfig);
+        }
+
+        // login at startup if lazyLogin is disabled
+        if (!loginConfig.isLazyLogin()) {
+            ServiceHelper.startService(session);
+        }
+
+        if (packages != null && packages.length > 0) {
+            // parse the packages to create SObject name to class map
+            classMap = parsePackages();
+        } else {
+            // use an empty map to avoid NPEs later
+            LOG.warn("Missing property packages, getSObject* operations will 
NOT work");
+            classMap = Collections.unmodifiableMap(new HashMap<String, 
Class<?>>());
+        }
+
+        if (subscriptionHelper != null) {
+            ServiceHelper.startService(subscriptionHelper);
+        }
+    }
+
+    private Map<String, Class<?>> parsePackages() {
+        Map<String, Class<?>> result = new HashMap<String, Class<?>>();
+        Set<Class<?>> classes = 
getCamelContext().getPackageScanClassResolver().findImplementations(AbstractSObjectBase.class,
 packages);
+        for (Class<?> aClass : classes) {
+            // findImplementations also returns AbstractSObjectBase for some 
reason!!!
+            if (AbstractSObjectBase.class != aClass) {
+                result.put(aClass.getSimpleName(), aClass);
+            }
+        }
+
+        return Collections.unmodifiableMap(result);
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        super.doStop();
+
+        try {
+            if (subscriptionHelper != null) {
+                // shutdown all streaming connections
+                // note that this is done in the component, and not in consumer
+                ServiceHelper.stopService(subscriptionHelper);
+            }
+            if (session != null && session.getAccessToken() != null) {
+                try {
+                    // logout of Salesforce
+                    ServiceHelper.stopService(session);
+                } catch (SalesforceException ignored) {
+                }
+            }
+        } finally {
+            if (httpClient != null) {
+                // shutdown http client connections
+                httpClient.stop();
+            }
+        }
+    }
+
+    public SubscriptionHelper getSubscriptionHelper() throws Exception {
+        if (subscriptionHelper == null) {
+            // lazily create subscription helper
+            subscriptionHelper = new SubscriptionHelper(this);
+
+            // also start the helper to connect to Salesforce
+            ServiceHelper.startService(subscriptionHelper);
+        }
+        return subscriptionHelper;
+    }
+
+    public SalesforceLoginConfig getLoginConfig() {
+        return loginConfig;
+    }
+
+    public void setLoginConfig(SalesforceLoginConfig loginConfig) {
+        this.loginConfig = loginConfig;
+    }
+
+    public SalesforceEndpointConfig getConfig() {
+        return config;
+    }
+
+    public void setConfig(SalesforceEndpointConfig config) {
+        this.config = config;
+    }
+
+    public String[] getPackages() {
+        return packages;
+    }
+
+    public void setPackages(String[] packages) {
+        this.packages = packages;
+    }
+
+    public SalesforceSession getSession() {
+        return session;
+    }
+
+    public Map<String, Class<?>> getClassMap() {
+        return classMap;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceConsumer.java
----------------------------------------------------------------------
diff --git 
a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceConsumer.java
 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceConsumer.java
new file mode 100644
index 0000000..9fa1b91
--- /dev/null
+++ 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceConsumer.java
@@ -0,0 +1,215 @@
+/**
+ * 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.salesforce;
+
+import org.apache.camel.AsyncCallback;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.impl.DefaultConsumer;
+import org.apache.camel.util.ServiceHelper;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.cometd.bayeux.Message;
+import org.cometd.bayeux.client.ClientSessionChannel;
+import org.apache.camel.component.salesforce.internal.client.DefaultRestClient;
+import 
org.apache.camel.component.salesforce.internal.streaming.PushTopicHelper;
+import org.apache.camel.component.salesforce.internal.client.RestClient;
+import 
org.apache.camel.component.salesforce.internal.streaming.SubscriptionHelper;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * The Salesforce consumer.
+ */
+public class SalesforceConsumer extends DefaultConsumer {
+
+    private static final ObjectMapper objectMapper = new ObjectMapper();
+    private static final String EVENT_PROPERTY = "event";
+    private static final String TYPE_PROPERTY = "type";
+    private static final String CREATED_DATE_PROPERTY = "createdDate";
+    private static final String SOBJECT_PROPERTY = "sobject";
+    private static final double MINIMUM_VERSION = 24.0;
+
+    private final SalesforceEndpoint endpoint;
+    public final SubscriptionHelper subscriptionHelper;
+
+    private final String topicName;
+    private final Class<?> sObjectClass;
+    private boolean subscribed;
+
+    public SalesforceConsumer(SalesforceEndpoint endpoint, Processor 
processor, SubscriptionHelper helper) {
+        super(endpoint, processor);
+        this.endpoint = endpoint;
+
+        // check minimum supported API version
+        if (Double.valueOf(endpoint.getConfiguration().getApiVersion()) < 
MINIMUM_VERSION) {
+            throw new IllegalArgumentException("Minimum supported API version 
for consumer endpoints is " + 24.0);
+        }
+
+        this.topicName = endpoint.getTopicName();
+        this.subscriptionHelper = helper;
+
+        // get sObjectClass to convert to
+        final String sObjectName = 
endpoint.getConfiguration().getSObjectName();
+        if (sObjectName != null) {
+            sObjectClass = 
endpoint.getComponent().getClassMap().get(sObjectName);
+            if (sObjectClass == null) {
+                throw new IllegalArgumentException(String.format("SObject 
Class not found for %s", sObjectName));
+            }
+        } else {
+            final String className = 
endpoint.getConfiguration().getSObjectClass();
+            if (className != null) {
+                sObjectClass = 
endpoint.getComponent().getCamelContext().getClassResolver().resolveClass(className);
+                if (sObjectClass == null) {
+                    throw new IllegalArgumentException(String.format("SObject 
Class not found %s", className));
+                }
+            } else {
+                log.warn("Property sObjectName or sObjectClass NOT set, 
messages will be of type java.lang.Map");
+                sObjectClass = null;
+            }
+        }
+
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+
+        final SalesforceEndpointConfig config = endpoint.getConfiguration();
+
+        // is a query configured in the endpoint?
+        if (config.getSObjectQuery() != null) {
+            // Note that we don't lookup topic if the query is not specified
+            // create REST client for PushTopic operations
+            SalesforceComponent component = endpoint.getComponent();
+            RestClient restClient = new 
DefaultRestClient(component.getConfig().getHttpClient(),
+                endpoint.getConfiguration().getApiVersion(), "json", 
component.getSession());
+            // don't forget to start the client
+            ServiceHelper.startService(restClient);
+
+            try {
+                PushTopicHelper helper = new PushTopicHelper(config, 
topicName, restClient);
+                helper.createOrUpdateTopic();
+            } finally {
+                // don't forget to stop the client
+                ServiceHelper.stopService(restClient);
+            }
+        }
+
+        // subscribe to topic
+        subscriptionHelper.subscribe(topicName, this);
+        subscribed = true;
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        super.doStop();
+
+        if (subscribed) {
+            subscribed = false;
+            // unsubscribe from topic
+            subscriptionHelper.unsubscribe(topicName, this);
+        }
+    }
+
+    public void processMessage(ClientSessionChannel channel, Message message) {
+        final Exchange exchange = endpoint.createExchange();
+        org.apache.camel.Message in = exchange.getIn();
+        setHeaders(in, message);
+
+        // get event data
+        // TODO do we need to add NPE checks for message/data.get***???
+        Map<String, Object> data = message.getDataAsMap();
+
+        @SuppressWarnings("unchecked") final
+        Map<String, Object> event = (Map<String, Object>) 
data.get(EVENT_PROPERTY);
+        final Object eventType = event.get(TYPE_PROPERTY);
+        Object createdDate = event.get(CREATED_DATE_PROPERTY);
+        if (log.isDebugEnabled()) {
+            log.debug(String.format("Received event %s on channel %s created 
on %s",
+                eventType, channel.getChannelId(), createdDate));
+        }
+
+        in.setHeader("CamelSalesforceEventType", eventType);
+        in.setHeader("CamelSalesforceCreatedDate", createdDate);
+
+        // get SObject
+        @SuppressWarnings("unchecked")
+        final Map<String, Object> sObject = (Map<String, Object>) 
data.get(SOBJECT_PROPERTY);
+        try {
+
+            final String sObjectString = 
objectMapper.writeValueAsString(sObject);
+            log.debug("Received SObject: {}", sObjectString);
+
+            if (sObjectClass == null) {
+                // return sobject map as exchange body
+                in.setBody(sObject);
+            } else {
+                // create the expected SObject
+                in.setBody(objectMapper.readValue(
+                    new StringReader(sObjectString), sObjectClass));
+            }
+        } catch (IOException e) {
+            final String msg = String.format("Error parsing message [%s] from 
Topic %s: %s",
+                message, topicName, e.getMessage());
+            handleException(msg, new RuntimeCamelException(msg, e));
+        }
+
+        try {
+            getAsyncProcessor().process(exchange, new AsyncCallback() {
+                public void done(boolean doneSync) {
+                    // noop
+                    if (log.isTraceEnabled()) {
+                        log.trace("Done processing event: {} {}", 
eventType.toString(),
+                            doneSync ? "synchronously" : "asynchronously");
+                    }
+                }
+            });
+        } catch (Exception e) {
+            handleException(String.format("Error processing %s: %s", exchange, 
e.getMessage()), e);
+        } finally {
+            Exception ex = exchange.getException();
+            if (ex != null) {
+                handleException(String.format("Unhandled exception: %s", 
ex.getMessage()), ex);
+            }
+        }
+    }
+
+    private void setHeaders(org.apache.camel.Message in, Message message) {
+        Map<String, Object> headers = new HashMap<String, Object>();
+        // set topic name
+        headers.put("CamelSalesforceTopicName", topicName);
+        // set message properties as headers
+        headers.put("CamelSalesforceChannel", message.getChannel());
+        headers.put("CamelSalesforceClientId", message.getClientId());
+
+        in.setHeaders(headers);
+    }
+
+    @Override
+    public void handleException(String message, Throwable t) {
+        super.handleException(message, t);
+    }
+
+    public String getTopicName() {
+        return topicName;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceEndpoint.java
----------------------------------------------------------------------
diff --git 
a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceEndpoint.java
 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceEndpoint.java
new file mode 100644
index 0000000..24874bb
--- /dev/null
+++ 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceEndpoint.java
@@ -0,0 +1,96 @@
+/**
+ * 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.salesforce;
+
+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.impl.SynchronousDelegateProducer;
+import org.apache.camel.component.salesforce.internal.OperationName;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Represents a Salesforce endpoint.
+ */
+public class SalesforceEndpoint extends DefaultEndpoint {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(SalesforceEndpoint.class);
+
+    private final SalesforceEndpointConfig config;
+    private final OperationName operationName;
+    private final String topicName;
+
+    public SalesforceEndpoint(String uri, SalesforceComponent 
salesforceComponent,
+                              SalesforceEndpointConfig config, OperationName 
operationName, String topicName) {
+        super(uri, salesforceComponent);
+
+        this.config = config;
+        this.operationName = operationName;
+        this.topicName = topicName;
+    }
+
+    public Producer createProducer() throws Exception {
+        // producer requires an operation, topicName must be the invalid 
operation name
+        if (operationName == null) {
+            throw new IllegalArgumentException(String.format("Invalid 
Operation %s", topicName));
+        }
+
+        SalesforceProducer producer = new SalesforceProducer(this);
+        if (isSynchronous()) {
+            return new SynchronousDelegateProducer(producer);
+        } else {
+            return producer;
+        }
+    }
+
+    public Consumer createConsumer(Processor processor) throws Exception {
+        // consumer requires a topicName, operation name must be the invalid 
topic name
+        if (topicName == null) {
+            throw new IllegalArgumentException(String.format("Invalid topic 
name %s, matches a producer operation name",
+                operationName.value()));
+        }
+
+        return new SalesforceConsumer(this, processor,
+            getComponent().getSubscriptionHelper());
+    }
+
+    @Override
+    public SalesforceComponent getComponent() {
+        return (SalesforceComponent) super.getComponent();
+    }
+
+    public boolean isSingleton() {
+        // re-use endpoint instance across multiple threads
+        // the description of this method is a little confusing
+        return true;
+    }
+
+    public SalesforceEndpointConfig getConfiguration() {
+        return config;
+    }
+
+    public OperationName getOperationName() {
+        return operationName;
+    }
+
+    public String getTopicName() {
+        return topicName;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceEndpointConfig.java
----------------------------------------------------------------------
diff --git 
a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceEndpointConfig.java
 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceEndpointConfig.java
new file mode 100644
index 0000000..065f2f1
--- /dev/null
+++ 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceEndpointConfig.java
@@ -0,0 +1,276 @@
+package org.apache.camel.component.salesforce;
+
+import org.apache.camel.RuntimeCamelException;
+import org.eclipse.jetty.client.HttpClient;
+import org.apache.camel.component.salesforce.api.dto.bulk.ContentType;
+import org.apache.camel.component.salesforce.api.dto.bulk.OperationEnum;
+import org.apache.camel.component.salesforce.internal.PayloadFormat;
+import org.apache.camel.component.salesforce.internal.dto.NotifyForFieldsEnum;
+import 
org.apache.camel.component.salesforce.internal.dto.NotifyForOperationsEnum;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+public class SalesforceEndpointConfig implements Cloneable {
+
+    // default API version
+    static final String DEFAULT_VERSION = "27.0";
+
+    // general parameter
+    public static final String API_VERSION = "apiVersion";
+
+    // parameters for Rest API
+    public static final String FORMAT = "format";
+    public static final String SOBJECT_NAME = "sObjectName";
+    public static final String SOBJECT_ID = "sObjectId";
+    public static final String SOBJECT_FIELDS = "sObjectFields";
+    public static final String SOBJECT_EXT_ID_NAME = "sObjectIdName";
+    public static final String SOBJECT_EXT_ID_VALUE = "sObjectIdValue";
+    public static final String SOBJECT_BLOB_FIELD_NAME = 
"sObjectBlobFieldName";
+    public static final String SOBJECT_CLASS = "sObjectClass";
+    public static final String SOBJECT_QUERY = "sObjectQuery";
+    public static final String SOBJECT_SEARCH = "sObjectSearch";
+
+    // parameters for Bulk API
+    public static final String BULK_OPERATION = "bulkOperation";
+    public static final String CONTENT_TYPE = "contentType";
+    public static final String JOB_ID = "jobId";
+    public static final String BATCH_ID = "batchId";
+    public static final String RESULT_ID = "resultId";
+
+    // parameters for Streaming API
+    public static final String UPDATE_TOPIC = "updateTopic";
+
+    // general properties
+    private String apiVersion = DEFAULT_VERSION;
+
+    // Rest API properties
+    private PayloadFormat format = PayloadFormat.JSON;
+    private String sObjectName;
+    private String sObjectId;
+    private String sObjectFields;
+    private String sObjectIdName;
+    private String sObjectIdValue;
+    private String sObjectBlobFieldName;
+    private String sObjectClass;
+    private String sObjectQuery;
+    private String sObjectSearch;
+
+    // Bulk API properties
+    private OperationEnum bulkOperation;
+    private ContentType contentType;
+    private String jobId;
+    private String batchId;
+    private String resultId;
+
+    // Streaming API properties
+    private boolean updateTopic;
+    private NotifyForFieldsEnum notifyForFields;
+    private NotifyForOperationsEnum notifyForOperations;
+
+    // Jetty HttpClient, set using reference
+    private HttpClient httpClient;
+
+    public SalesforceEndpointConfig copy() {
+        try {
+            final SalesforceEndpointConfig copy = (SalesforceEndpointConfig) 
super.clone();
+            // nothing to deep copy
+            return copy;
+        } catch (CloneNotSupportedException ex) {
+            throw new RuntimeCamelException(ex);
+        }
+    }
+
+    public PayloadFormat getPayloadFormat() {
+        return format;
+    }
+
+    public void setFormat(String format) {
+        this.format = PayloadFormat.valueOf(format.toUpperCase());
+    }
+
+    public String getApiVersion() {
+        return apiVersion;
+    }
+
+    public void setApiVersion(String apiVersion) {
+        this.apiVersion = apiVersion;
+    }
+
+    public String getSObjectName() {
+        return sObjectName;
+    }
+
+    public void setSObjectName(String sObjectName) {
+        this.sObjectName = sObjectName;
+    }
+
+    public String getSObjectId() {
+        return sObjectId;
+    }
+
+    public void setSObjectId(String sObjectId) {
+        this.sObjectId = sObjectId;
+    }
+
+    public String getSObjectFields() {
+        return sObjectFields;
+    }
+
+    public void setSObjectFields(String sObjectFields) {
+        this.sObjectFields = sObjectFields;
+    }
+
+    public String getSObjectIdName() {
+        return sObjectIdName;
+    }
+
+    public void setSObjectIdName(String sObjectIdName) {
+        this.sObjectIdName = sObjectIdName;
+    }
+
+    public String getSObjectIdValue() {
+        return sObjectIdValue;
+    }
+
+    public void setSObjectIdValue(String sObjectIdValue) {
+        this.sObjectIdValue = sObjectIdValue;
+    }
+
+    public String getSObjectBlobFieldName() {
+        return sObjectBlobFieldName;
+    }
+
+    public void setSObjectBlobFieldName(String sObjectBlobFieldName) {
+        this.sObjectBlobFieldName = sObjectBlobFieldName;
+    }
+
+    public String getSObjectClass() {
+        return sObjectClass;
+    }
+
+    public void setSObjectClass(String sObjectClass) {
+        this.sObjectClass = sObjectClass;
+    }
+
+    public String getSObjectQuery() {
+        return sObjectQuery;
+    }
+
+    public void setSObjectQuery(String sObjectQuery) {
+        this.sObjectQuery = sObjectQuery;
+    }
+
+    public String getSObjectSearch() {
+        return sObjectSearch;
+    }
+
+    public void setSObjectSearch(String sObjectSearch) {
+        this.sObjectSearch = sObjectSearch;
+    }
+
+    public OperationEnum getBulkOperation() {
+        return bulkOperation;
+    }
+
+    public void setBulkOperation(OperationEnum bulkOperation) {
+        this.bulkOperation = bulkOperation;
+    }
+
+    public ContentType getContentType() {
+        return contentType;
+    }
+
+    public void setContentType(ContentType contentType) {
+        this.contentType = contentType;
+    }
+
+    public String getJobId() {
+        return jobId;
+    }
+
+    public void setJobId(String jobId) {
+        this.jobId = jobId;
+    }
+
+    public String getBatchId() {
+        return batchId;
+    }
+
+    public void setBatchId(String batchId) {
+        this.batchId = batchId;
+    }
+
+    public String getResultId() {
+        return resultId;
+    }
+
+    public void setResultId(String resultId) {
+        this.resultId = resultId;
+    }
+
+    public boolean isUpdateTopic() {
+        return updateTopic;
+    }
+
+    public void setUpdateTopic(boolean updateTopic) {
+        this.updateTopic = updateTopic;
+    }
+
+    public NotifyForFieldsEnum getNotifyForFields() {
+        return notifyForFields;
+    }
+
+    public void setNotifyForFields(NotifyForFieldsEnum notifyForFields) {
+        this.notifyForFields = notifyForFields;
+    }
+
+    public NotifyForOperationsEnum getNotifyForOperations() {
+        return notifyForOperations;
+    }
+
+    public void setNotifyForOperations(NotifyForOperationsEnum 
notifyForOperations) {
+        this.notifyForOperations = notifyForOperations;
+    }
+
+    public void setHttpClient(HttpClient httpClient) {
+        this.httpClient = httpClient;
+    }
+
+    public HttpClient getHttpClient() {
+        return httpClient;
+    }
+
+    public Map<String, String> toValueMap() {
+
+        final Map<String, String> valueMap = new HashMap<String, String>();
+        valueMap.put(FORMAT, format.toString().toLowerCase());
+        valueMap.put(API_VERSION, apiVersion);
+
+        valueMap.put(SOBJECT_NAME, sObjectName);
+        valueMap.put(SOBJECT_ID, sObjectId);
+        valueMap.put(SOBJECT_FIELDS, sObjectFields);
+        valueMap.put(SOBJECT_EXT_ID_NAME, sObjectIdName);
+        valueMap.put(SOBJECT_BLOB_FIELD_NAME, sObjectBlobFieldName);
+        valueMap.put(SOBJECT_EXT_ID_VALUE, sObjectIdValue);
+        valueMap.put(SOBJECT_CLASS, sObjectClass);
+        valueMap.put(SOBJECT_QUERY, sObjectQuery);
+        valueMap.put(SOBJECT_SEARCH, sObjectSearch);
+
+        // add bulk API properties
+        if (bulkOperation != null) {
+            valueMap.put(BULK_OPERATION, bulkOperation.value());
+        }
+        if (contentType != null) {
+            valueMap.put(CONTENT_TYPE, contentType.value());
+        }
+        valueMap.put(JOB_ID, jobId);
+        valueMap.put(BATCH_ID, batchId);
+        valueMap.put(RESULT_ID, resultId);
+
+        valueMap.put(UPDATE_TOPIC, String.valueOf(updateTopic));
+
+        return Collections.unmodifiableMap(valueMap);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceLoginConfig.java
----------------------------------------------------------------------
diff --git 
a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceLoginConfig.java
 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceLoginConfig.java
new file mode 100644
index 0000000..a6a097f
--- /dev/null
+++ 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceLoginConfig.java
@@ -0,0 +1,99 @@
+/**
+ * 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.salesforce;
+
+/**
+ * Configuration object for Salesforce login properties
+ */
+public class SalesforceLoginConfig {
+
+    public static final String DEFAULT_LOGIN_URL = 
"https://login.salesforce.com";;
+
+    private String loginUrl;
+    private String clientId;
+    private String clientSecret;
+    private String userName;
+    private String password;
+    // allow lazy login into Salesforce
+    // note that login issues may not surface until a message needs to be 
processed
+    private boolean lazyLogin;
+
+    public SalesforceLoginConfig() {
+        loginUrl = DEFAULT_LOGIN_URL;
+        lazyLogin = false;
+    }
+
+    public SalesforceLoginConfig(String loginUrl,
+                                 String clientId, String clientSecret,
+                                 String userName, String password, boolean 
lazyLogin) {
+        this.loginUrl = loginUrl;
+        this.clientId = clientId;
+        this.clientSecret = clientSecret;
+        this.userName = userName;
+        this.password = password;
+        this.lazyLogin = lazyLogin;
+    }
+
+    public String getLoginUrl() {
+        return loginUrl;
+    }
+
+    public void setLoginUrl(String loginUrl) {
+        this.loginUrl = loginUrl;
+    }
+
+    public String getClientId() {
+        return clientId;
+    }
+
+    public void setClientId(String clientId) {
+        this.clientId = clientId;
+    }
+
+    public String getClientSecret() {
+        return clientSecret;
+    }
+
+    public void setClientSecret(String clientSecret) {
+        this.clientSecret = clientSecret;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public boolean isLazyLogin() {
+        return lazyLogin;
+    }
+
+    public void setLazyLogin(boolean lazyLogin) {
+        this.lazyLogin = lazyLogin;
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceProducer.java
----------------------------------------------------------------------
diff --git 
a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceProducer.java
 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceProducer.java
new file mode 100644
index 0000000..5cc4547
--- /dev/null
+++ 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceProducer.java
@@ -0,0 +1,102 @@
+/**
+ * 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.salesforce;
+
+import org.apache.camel.AsyncCallback;
+import org.apache.camel.Exchange;
+import org.apache.camel.impl.DefaultAsyncProducer;
+import org.apache.camel.util.ServiceHelper;
+import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.internal.OperationName;
+import org.apache.camel.component.salesforce.internal.PayloadFormat;
+import 
org.apache.camel.component.salesforce.internal.processor.BulkApiProcessor;
+import 
org.apache.camel.component.salesforce.internal.processor.JsonRestProcessor;
+import 
org.apache.camel.component.salesforce.internal.processor.SalesforceProcessor;
+import 
org.apache.camel.component.salesforce.internal.processor.XmlRestProcessor;
+
+/**
+ * The Salesforce producer.
+ */
+public class SalesforceProducer extends DefaultAsyncProducer {
+
+    private final SalesforceProcessor processor;
+
+    public SalesforceProducer(SalesforceEndpoint endpoint) throws 
SalesforceException {
+        super(endpoint);
+
+        final SalesforceEndpointConfig endpointConfig = 
endpoint.getConfiguration();
+        final PayloadFormat payloadFormat = endpointConfig.getPayloadFormat();
+
+        // check if its a Bulk Operation
+        if (isBulkOperation(endpoint.getOperationName())) {
+            processor = new BulkApiProcessor(endpoint);
+        } else {
+            // create an appropriate processor
+            if (payloadFormat == PayloadFormat.JSON) {
+                // create a JSON exchange processor
+                processor = new JsonRestProcessor(endpoint);
+            } else {
+                processor = new XmlRestProcessor(endpoint);
+            }
+        }
+    }
+
+    private boolean isBulkOperation(OperationName operationName) {
+        switch (operationName) {
+            case CREATE_JOB:
+            case GET_JOB:
+            case CLOSE_JOB:
+            case ABORT_JOB:
+            case CREATE_BATCH:
+            case GET_BATCH:
+            case GET_ALL_BATCHES:
+            case GET_REQUEST:
+            case GET_RESULTS:
+            case CREATE_BATCH_QUERY:
+            case GET_QUERY_RESULT_IDS:
+            case GET_QUERY_RESULT:
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
+    @Override
+    public boolean process(Exchange exchange, AsyncCallback callback) {
+        log.debug("Processing {}",
+            ((SalesforceEndpoint) getEndpoint()).getOperationName());
+        return processor.process(exchange, callback);
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+
+        // start Salesforce processor
+        ServiceHelper.startService(processor);
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        // stop Salesforce processor
+        ServiceHelper.stopService(processor);
+
+        super.doStop();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/JodaTimeConverter.java
----------------------------------------------------------------------
diff --git 
a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/JodaTimeConverter.java
 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/JodaTimeConverter.java
new file mode 100644
index 0000000..372e7a4
--- /dev/null
+++ 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/JodaTimeConverter.java
@@ -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.salesforce.api;
+
+import com.thoughtworks.xstream.converters.Converter;
+import com.thoughtworks.xstream.converters.MarshallingContext;
+import com.thoughtworks.xstream.converters.UnmarshallingContext;
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.joda.time.format.DateTimeFormatter;
+import org.joda.time.format.ISODateTimeFormat;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Constructor;
+
+public class JodaTimeConverter implements Converter {
+    private static final Logger LOG = 
LoggerFactory.getLogger(JodaTimeConverter.class);
+    private final DateTimeFormatter formatter = ISODateTimeFormat.dateTime();
+
+    @Override
+    public void marshal(Object o, HierarchicalStreamWriter writer, 
MarshallingContext context) {
+        DateTime dateTime = (DateTime) o;
+        writer.setValue(formatter.print(dateTime));
+    }
+
+    @Override
+    public Object unmarshal(HierarchicalStreamReader reader, 
UnmarshallingContext context) {
+        String dateTimeStr = reader.getValue();
+        Class<?> requiredType = context.getRequiredType();
+        try {
+            Constructor<?> constructor = 
requiredType.getConstructor(Object.class, DateTimeZone.class);
+            // normalize date time to UTC
+            return constructor.newInstance(dateTimeStr, DateTimeZone.UTC);
+        } catch (Exception e) {
+            throw new IllegalArgumentException(
+                String.format("Error reading Joda DateTime from value %s: %s",
+                    dateTimeStr, e.getMessage()),
+                e);
+        }
+    }
+
+    @Override
+    public boolean canConvert(Class aClass) {
+        return DateTime.class.isAssignableFrom(aClass);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/PicklistEnumConverter.java
----------------------------------------------------------------------
diff --git 
a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/PicklistEnumConverter.java
 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/PicklistEnumConverter.java
new file mode 100644
index 0000000..06d0ca5
--- /dev/null
+++ 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/PicklistEnumConverter.java
@@ -0,0 +1,80 @@
+/**
+ * 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.salesforce.api;
+
+import com.thoughtworks.xstream.converters.Converter;
+import com.thoughtworks.xstream.converters.MarshallingContext;
+import com.thoughtworks.xstream.converters.UnmarshallingContext;
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Method;
+
+public class PicklistEnumConverter implements Converter {
+    private static final Logger LOG = 
LoggerFactory.getLogger(PicklistEnumConverter.class);
+    private static final String FACTORY_METHOD = "fromValue";
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void marshal(Object o, HierarchicalStreamWriter writer, 
MarshallingContext context) {
+        Class<?> aClass = o.getClass();
+        try {
+            Method getterMethod = aClass.getMethod("value");
+            writer.setValue((String) getterMethod.invoke(o));
+        } catch (ReflectiveOperationException e) {
+            throw new IllegalArgumentException(
+                String.format("Exception writing pick list value %s of type 
%s: %s",
+                    o, o.getClass().getName(), e.getMessage()),
+                e);
+        }
+    }
+
+    @Override
+    public Object unmarshal(HierarchicalStreamReader reader, 
UnmarshallingContext context) {
+        String value = reader.getValue();
+        Class<?> requiredType = context.getRequiredType();
+        try {
+            Method factoryMethod = requiredType.getMethod(FACTORY_METHOD, 
String.class);
+            // use factory method to create object
+            return factoryMethod.invoke(null, value);
+        } catch (ReflectiveOperationException e) {
+            throw new IllegalArgumentException(
+                String.format("Exception reading pick list value %s of type 
%s: %s",
+                    value, context.getRequiredType().getName(), 
e.getMessage()),
+                e);
+        } catch (SecurityException e) {
+            throw new IllegalArgumentException(
+                String.format("Security Exception reading pick list value %s 
of type %s: %s",
+                    value, context.getRequiredType().getName(), 
e.getMessage()),
+                e);
+        }
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public boolean canConvert(Class aClass) {
+        try {
+            return Enum.class.isAssignableFrom(aClass) &&
+                aClass.getMethod(FACTORY_METHOD, String.class) != null;
+        } catch (NoSuchMethodException e) {
+            return false;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/SalesforceException.java
----------------------------------------------------------------------
diff --git 
a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/SalesforceException.java
 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/SalesforceException.java
new file mode 100644
index 0000000..760eebe
--- /dev/null
+++ 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/SalesforceException.java
@@ -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.salesforce.api;
+
+import org.apache.camel.CamelException;
+import org.apache.camel.component.salesforce.api.dto.RestError;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class SalesforceException extends CamelException {
+
+    private List<RestError> errors;
+    private int statusCode;
+
+    public SalesforceException(List<RestError> errors, int statusCode) {
+        this(toErrorMessage(errors, statusCode), statusCode);
+
+        this.errors = errors;
+    }
+
+    public SalesforceException(String message, int statusCode) {
+        super(message);
+
+        this.statusCode = statusCode;
+    }
+
+    public SalesforceException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public SalesforceException(Throwable cause) {
+        super(cause);
+    }
+
+    public List<RestError> getErrors() {
+        return Collections.unmodifiableList(errors);
+    }
+
+    public void setErrors(List<RestError> errors) {
+        if (this.errors != null) {
+            this.errors.clear();
+        } else {
+            this.errors = new ArrayList<RestError>();
+        }
+        this.errors.addAll(errors);
+    }
+
+    public int getStatusCode() {
+        return statusCode;
+    }
+
+    public void setStatusCode(int statusCode) {
+        this.statusCode = statusCode;
+    }
+
+    @Override
+    public String toString() {
+        if (errors != null) {
+            return toErrorMessage(errors, statusCode);
+        } else {
+            // make sure we include the custom message
+            final StringBuilder builder = new StringBuilder("{ ");
+            builder.append(getMessage());
+            builder.append(", statusCode: ");
+            builder.append(statusCode);
+            builder.append("}");
+
+            return builder.toString();
+        }
+    }
+
+    private static String toErrorMessage(List<RestError> errors, int 
statusCode) {
+        StringBuilder builder = new StringBuilder("{ ");
+        if (errors != null) {
+            builder.append(" errors: [");
+            for (RestError error : errors) {
+                builder.append(error.toString());
+            }
+            builder.append("], ");
+        }
+        builder.append("statusCode: ");
+        builder.append(statusCode);
+        builder.append("}");
+
+        return builder.toString();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/AbstractDTOBase.java
----------------------------------------------------------------------
diff --git 
a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/AbstractDTOBase.java
 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/AbstractDTOBase.java
new file mode 100644
index 0000000..e4723ae
--- /dev/null
+++ 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/AbstractDTOBase.java
@@ -0,0 +1,40 @@
+/**
+ * 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.salesforce.api.dto;
+
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+// disable null values in json output
+@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+public abstract class AbstractDTOBase {
+    private final static ObjectMapper mapper = new ObjectMapper();
+
+    @Override
+    public String toString() {
+        try {
+            StringWriter writer = new StringWriter();
+            mapper.writeValue(writer, this);
+            return writer.toString();
+        } catch (IOException e) {
+            return "Error in toString " + e.getMessage();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/AbstractQueryRecordsBase.java
----------------------------------------------------------------------
diff --git 
a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/AbstractQueryRecordsBase.java
 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/AbstractQueryRecordsBase.java
new file mode 100644
index 0000000..ddfa6bf
--- /dev/null
+++ 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/AbstractQueryRecordsBase.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.salesforce.api.dto;
+
+/**
+ * Abstract base DTO for Salesforce SOQL Query records.
+ * <p>
+ * Derived classes must follow the template below:
+ * </p>
+ * <pre>
+ * {@code
+ * public class QueryResultMySObject extends AbstractQueryRecordsBase {
+ *     @XStreamImplicit
+ *     private List<MySObject> records;
+ *
+ *     public List<MySObject> getRecords() {
+ *         return records;
+ *     }
+ *
+ *     public void setRecords(List<MySObject> records) {
+ *         this.records = records;
+ *     }
+ *
+ * }
+ * }
+ * </pre>
+ */
+public abstract class AbstractQueryRecordsBase extends AbstractDTOBase {
+
+    private Boolean done;
+    private int totalSize;
+    private String nextRecordsUrl;
+
+    public Boolean getDone() {
+        return done;
+    }
+
+    public void setDone(Boolean done) {
+        this.done = done;
+    }
+
+    public int getTotalSize() {
+        return totalSize;
+    }
+
+    public void setTotalSize(int totalSize) {
+        this.totalSize = totalSize;
+    }
+
+    public String getNextRecordsUrl() {
+        return nextRecordsUrl;
+    }
+
+    public void setNextRecordsUrl(String nextRecordsUrl) {
+        this.nextRecordsUrl = nextRecordsUrl;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/AbstractSObjectBase.java
----------------------------------------------------------------------
diff --git 
a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/AbstractSObjectBase.java
 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/AbstractSObjectBase.java
new file mode 100644
index 0000000..c236872
--- /dev/null
+++ 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/AbstractSObjectBase.java
@@ -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.salesforce.api.dto;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.joda.time.DateTime;
+
+public class AbstractSObjectBase extends AbstractDTOBase {
+
+    private Attributes attributes;
+
+    private String Id;
+
+    private String OwnerId;
+
+    private Boolean IsDeleted;
+
+    private String Name;
+
+    private DateTime CreatedDate;
+
+    private String CreatedById;
+
+    private DateTime LastModifiedDate;
+
+    private String LastModifiedById;
+
+    private DateTime SystemModstamp;
+
+    private String LastActivityDate;
+
+    /**
+     * Utility method to clear all {@link AbstractSObjectBase} fields.
+     * <p>Used when reusing a DTO for a new record.</p>
+     */
+    public final void clearBaseFields() {
+        attributes = null;
+        Id = null;
+        OwnerId = null;
+        IsDeleted = null;
+        Name = null;
+        CreatedDate = null;
+        CreatedById = null;
+        LastModifiedDate = null;
+        LastModifiedById = null;
+        SystemModstamp = null;
+        LastActivityDate = null;
+    }
+
+    public Attributes getAttributes() {
+        return attributes;
+    }
+
+    public void setAttributes(Attributes attributes) {
+        this.attributes = attributes;
+    }
+
+    @JsonProperty("Id")
+    public String getId() {
+        return Id;
+    }
+
+    @JsonProperty("Id")
+    public void setId(String id) {
+        Id = id;
+    }
+
+    @JsonProperty("OwnerId")
+    public String getOwnerId() {
+        return OwnerId;
+    }
+
+    @JsonProperty("OwnerId")
+    public void setOwnerId(String ownerId) {
+        OwnerId = ownerId;
+    }
+
+    @JsonProperty("IsDeleted")
+    public Boolean isIsDeleted() {
+        return IsDeleted;
+    }
+
+    @JsonProperty("IsDeleted")
+    public void setIsDeleted(Boolean isDeleted) {
+        IsDeleted = isDeleted;
+    }
+
+    @JsonProperty("Name")
+    public String getName() {
+        return Name;
+    }
+
+    @JsonProperty("Name")
+    public void setName(String name) {
+        Name = name;
+    }
+
+    @JsonProperty("CreatedDate")
+    public DateTime getCreatedDate() {
+        return CreatedDate;
+    }
+
+    @JsonProperty("CreatedDate")
+    public void setCreatedDate(DateTime createdDate) {
+        CreatedDate = createdDate;
+    }
+
+    @JsonProperty("CreatedById")
+    public String getCreatedById() {
+        return CreatedById;
+    }
+
+    @JsonProperty("CreatedById")
+    public void setCreatedById(String createdById) {
+        CreatedById = createdById;
+    }
+
+    @JsonProperty("LastModifiedDate")
+    public DateTime getLastModifiedDate() {
+        return LastModifiedDate;
+    }
+
+    @JsonProperty("LastModifiedDate")
+    public void setLastModifiedDate(DateTime lastModifiedDate) {
+        LastModifiedDate = lastModifiedDate;
+    }
+
+    @JsonProperty("LastModifiedById")
+    public String getLastModifiedById() {
+        return LastModifiedById;
+    }
+
+    @JsonProperty("LastModifiedById")
+    public void setLastModifiedById(String lastModifiedById) {
+        LastModifiedById = lastModifiedById;
+    }
+
+    @JsonProperty("SystemModstamp")
+    public DateTime getSystemModstamp() {
+        return SystemModstamp;
+    }
+
+    @JsonProperty("SystemModstamp")
+    public void setSystemModstamp(DateTime systemModstamp) {
+        SystemModstamp = systemModstamp;
+    }
+
+    @JsonProperty("LastActivityDate")
+    public String getLastActivityDate() {
+        return LastActivityDate;
+    }
+
+    @JsonProperty("LastActivityDate")
+    public void setLastActivityDate(String lastActivityDate) {
+        LastActivityDate = lastActivityDate;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/Attributes.java
----------------------------------------------------------------------
diff --git 
a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/Attributes.java
 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/Attributes.java
new file mode 100644
index 0000000..439f4c3
--- /dev/null
+++ 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/Attributes.java
@@ -0,0 +1,38 @@
+/**
+ * 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.salesforce.api.dto;
+
+public class Attributes extends AbstractDTOBase {
+    private String type;
+    private String url;
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/ChildRelationShip.java
----------------------------------------------------------------------
diff --git 
a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/ChildRelationShip.java
 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/ChildRelationShip.java
new file mode 100644
index 0000000..4c2d58e
--- /dev/null
+++ 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/ChildRelationShip.java
@@ -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.salesforce.api.dto;
+
+public class ChildRelationShip extends AbstractDTOBase {
+    private String field;
+    private Boolean deprecatedAndHidden;
+    private String relationshipName;
+    private Boolean cascadeDelete;
+    private Boolean restrictedDelete;
+    private String childSObject;
+
+    public String getField() {
+        return field;
+    }
+
+    public void setField(String field) {
+        this.field = field;
+    }
+
+    public Boolean isDeprecatedAndHidden() {
+        return deprecatedAndHidden;
+    }
+
+    public void setDeprecatedAndHidden(Boolean deprecatedAndHidden) {
+        this.deprecatedAndHidden = deprecatedAndHidden;
+    }
+
+    public String getRelationshipName() {
+        return relationshipName;
+    }
+
+    public void setRelationshipName(String relationshipName) {
+        this.relationshipName = relationshipName;
+    }
+
+    public Boolean isCascadeDelete() {
+        return cascadeDelete;
+    }
+
+    public void setCascadeDelete(Boolean cascadeDelete) {
+        this.cascadeDelete = cascadeDelete;
+    }
+
+    public Boolean isRestrictedDelete() {
+        return restrictedDelete;
+    }
+
+    public void setRestrictedDelete(Boolean restrictedDelete) {
+        this.restrictedDelete = restrictedDelete;
+    }
+
+    public String getChildSObject() {
+        return childSObject;
+    }
+
+    public void setChildSObject(String childSObject) {
+        this.childSObject = childSObject;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/72a1767e/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/CreateSObjectResult.java
----------------------------------------------------------------------
diff --git 
a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/CreateSObjectResult.java
 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/CreateSObjectResult.java
new file mode 100644
index 0000000..bc9fdaa
--- /dev/null
+++ 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/CreateSObjectResult.java
@@ -0,0 +1,57 @@
+/**
+ * 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.salesforce.api.dto;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamImplicit;
+
+import java.util.List;
+
+@XStreamAlias("Result")
+public class CreateSObjectResult extends AbstractDTOBase {
+
+    private String id;
+
+    @XStreamImplicit
+    private List<RestError> errors;
+
+    private Boolean success;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public List<RestError> getErrors() {
+        return errors;
+    }
+
+    public void setErrors(List<RestError> errors) {
+        this.errors = errors;
+    }
+
+    public Boolean getSuccess() {
+        return success;
+    }
+
+    public void setSuccess(Boolean success) {
+        this.success = success;
+    }
+}

Reply via email to