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 2013/06/05 17:12:45 UTC

[01/11] CAMEL-6428: Fixed CS

Updated Branches:
  refs/heads/master 469e0e37a -> aaa2710cb


http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/CamelSalesforceMojo.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/CamelSalesforceMojo.java b/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/CamelSalesforceMojo.java
index 70942a4..b191933 100644
--- a/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/CamelSalesforceMojo.java
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/CamelSalesforceMojo.java
@@ -14,9 +14,35 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.camel.maven;
 
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Pattern;
+
+import org.apache.camel.component.salesforce.SalesforceLoginConfig;
+import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.api.dto.AbstractSObjectBase;
+import org.apache.camel.component.salesforce.api.dto.GlobalObjects;
+import org.apache.camel.component.salesforce.api.dto.PickListValue;
+import org.apache.camel.component.salesforce.api.dto.SObject;
+import org.apache.camel.component.salesforce.api.dto.SObjectDescription;
+import org.apache.camel.component.salesforce.api.dto.SObjectField;
+import org.apache.camel.component.salesforce.internal.SalesforceSession;
+import org.apache.camel.component.salesforce.internal.client.DefaultRestClient;
+import org.apache.camel.component.salesforce.internal.client.RestClient;
+import org.apache.camel.component.salesforce.internal.client.SyncResponseCallback;
 import org.apache.log4j.Logger;
 import org.apache.maven.plugin.AbstractMojo;
 import org.apache.maven.plugin.MojoExecutionException;
@@ -29,33 +55,14 @@ import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.eclipse.jetty.client.HttpClient;
 import org.eclipse.jetty.client.RedirectListener;
-import org.apache.camel.component.salesforce.SalesforceLoginConfig;
-import org.apache.camel.component.salesforce.api.SalesforceException;
-import org.apache.camel.component.salesforce.api.dto.*;
-import org.apache.camel.component.salesforce.internal.SalesforceSession;
-import org.apache.camel.component.salesforce.internal.client.DefaultRestClient;
-import org.apache.camel.component.salesforce.internal.client.RestClient;
-import org.apache.camel.component.salesforce.internal.client.SyncResponseCallback;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.util.*;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Pattern;
 
 /**
  * Goal which generates POJOs for Salesforce SObjects
  *
  * @goal generate
- * 
  * @phase generate-sources
- *
  */
-public class CamelSalesforceMojo extends AbstractMojo
-{
+public class CamelSalesforceMojo extends AbstractMojo {
     private static final String JAVA_EXT = ".java";
     private static final String PACKAGE_NAME_PATTERN = "^[a-z]+(\\.[a-z][a-z0-9]*)*$";
     private static final String SOBJECT_POJO_VM = "/sobject-pojo.vm";
@@ -68,6 +75,7 @@ public class CamelSalesforceMojo extends AbstractMojo
 
     /**
      * Salesforce client id
+     *
      * @parameter property="${clientId}"
      * @required
      */
@@ -75,6 +83,7 @@ public class CamelSalesforceMojo extends AbstractMojo
 
     /**
      * Salesforce client secret
+     *
      * @parameter property="${clientSecret}"
      * @required
      */
@@ -82,6 +91,7 @@ public class CamelSalesforceMojo extends AbstractMojo
 
     /**
      * Salesforce user name
+     *
      * @parameter property="${userName}"
      * @required
      */
@@ -89,6 +99,7 @@ public class CamelSalesforceMojo extends AbstractMojo
 
     /**
      * Salesforce password
+     *
      * @parameter property="${password}"
      * @required
      */
@@ -96,12 +107,14 @@ public class CamelSalesforceMojo extends AbstractMojo
 
     /**
      * Salesforce version
+     *
      * @parameter property="${version}" default-value="25.0"
      */
     protected String version;
 
     /**
      * Location of the file.
+     *
      * @parameter property="${outputDirectory}" default-value="${project.build.directory}/generated-sources/camel-salesforce"
      * @required
      */
@@ -109,30 +122,35 @@ public class CamelSalesforceMojo extends AbstractMojo
 
     /**
      * Names of Salesforce SObject for which POJOs must be generated
+     *
      * @parameter
      */
     protected String[] includes;
 
     /**
      * Do NOT generate POJOs for these Salesforce SObjects
+     *
      * @parameter
      */
     protected String[] excludes;
 
     /**
      * Include Salesforce SObjects that match pattern
+     *
      * @parameter property="${includePattern}"
      */
     protected String includePattern;
 
     /**
      * Exclude Salesforce SObjects that match pattern
+     *
      * @parameter property="${excludePattern}"
      */
     protected String excludePattern;
 
     /**
      * Java package name for generated POJOs
+     *
      * @parameter property="${packageName}" default-value="org.apache.camel.salesforce.dto"
      */
     protected String packageName;
@@ -141,11 +159,11 @@ public class CamelSalesforceMojo extends AbstractMojo
 
     /**
      * Execute the mojo to generate SObject POJOs
+     *
      * @throws MojoExecutionException
      */
-    public void execute()
-        throws MojoExecutionException
-    {
+    // CHECKSTYLE:OFF
+    public void execute() throws MojoExecutionException {
         // initialize velocity to load resources from class loader and use Log4J
         Properties velocityProperties = new Properties();
         velocityProperties.setProperty(RuntimeConstants.RESOURCE_LOADER, "cloader");
@@ -156,8 +174,7 @@ public class CamelSalesforceMojo extends AbstractMojo
         engine.init();
 
         // make sure we can load both templates
-        if (!engine.resourceExists(SOBJECT_POJO_VM) ||
-            !engine.resourceExists(SOBJECT_QUERY_RECORDS_VM)) {
+        if (!engine.resourceExists(SOBJECT_POJO_VM) || !engine.resourceExists(SOBJECT_QUERY_RECORDS_VM)) {
             throw new MojoExecutionException("Velocity templates not found");
         }
 
@@ -173,8 +190,8 @@ public class CamelSalesforceMojo extends AbstractMojo
         }
 
         final SalesforceSession session = new SalesforceSession(httpClient,
-            new SalesforceLoginConfig(SalesforceLoginConfig.DEFAULT_LOGIN_URL,
-            clientId, clientSecret, userName, password, false));
+                new SalesforceLoginConfig(SalesforceLoginConfig.DEFAULT_LOGIN_URL,
+                        clientId, clientSecret, userName, password, false));
 
         getLog().info("Salesforce login...");
         try {
@@ -189,9 +206,9 @@ public class CamelSalesforceMojo extends AbstractMojo
         RestClient restClient = null;
         try {
             restClient = new DefaultRestClient(httpClient,
-                version, "json", session);
+                    version, "json", session);
             // remember to start the active client object
-            ((DefaultRestClient)restClient).start();
+            ((DefaultRestClient) restClient).start();
         } catch (Exception e) {
             final String msg = "Unexpected exception creating Rest client: " + e.getMessage();
             throw new MojoExecutionException(msg, e);
@@ -215,7 +232,7 @@ public class CamelSalesforceMojo extends AbstractMojo
                     throw ex;
                 }
                 final GlobalObjects globalObjects = mapper.readValue(callback.getResponse(),
-                    GlobalObjects.class);
+                        GlobalObjects.class);
 
                 // create a list of object names
                 for (SObject sObject : globalObjects.getSobjects()) {
@@ -227,10 +244,10 @@ public class CamelSalesforceMojo extends AbstractMojo
             }
 
             // check if we are generating POJOs for all objects or not
-            if ((includes != null && includes.length > 0) ||
-                (excludes != null && excludes.length > 0) ||
-                (includePattern != null && !includePattern.trim().isEmpty()) ||
-                (excludePattern != null && !excludePattern.trim().isEmpty())) {
+            if ((includes != null && includes.length > 0)
+                    || (excludes != null && excludes.length > 0)
+                    || (includePattern != null && !includePattern.trim().isEmpty())
+                    || (excludePattern != null && !excludePattern.trim().isEmpty())) {
 
                 getLog().info("Looking for matching Object names...");
                 // create a list of accepted names
@@ -281,9 +298,8 @@ public class CamelSalesforceMojo extends AbstractMojo
                 for (String name : objectNames) {
                     // name is included, or matches include pattern
                     // and is not excluded and does not match exclude pattern
-                    if ((includedNames.contains(name) || incPattern.matcher(name).matches()) &&
-                        !excludedNames.contains(name) &&
-                        !excPattern.matcher(name).matches()) {
+                    if ((includedNames.contains(name) || incPattern.matcher(name).matches())
+                            && !excludedNames.contains(name) && !excPattern.matcher(name).matches()) {
                         acceptedNames.add(name);
                     }
                 }
@@ -291,15 +307,12 @@ public class CamelSalesforceMojo extends AbstractMojo
                 objectNames.addAll(acceptedNames);
 
                 getLog().info(String.format("Found %s matching Objects", objectNames.size()));
-
             } else {
-                getLog().warn(String.format("Generating Java classes for all %s Objects, this may take a while...",
-                    objectNames.size()));
+                getLog().warn(String.format("Generating Java classes for all %s Objects, this may take a while...", objectNames.size()));
             }
 
             // for every accepted name, get SObject description
-            final Set<SObjectDescription> descriptions =
-                new HashSet<SObjectDescription>();
+            final Set<SObjectDescription> descriptions = new HashSet<SObjectDescription>();
 
             try {
                 getLog().info("Retrieving Object descriptions...");
@@ -307,15 +320,13 @@ public class CamelSalesforceMojo extends AbstractMojo
                     callback.reset();
                     restClient.getDescription(name, callback);
                     if (!callback.await(TIMEOUT, TimeUnit.MILLISECONDS)) {
-                        throw new MojoExecutionException(
-                            "Timeout waiting for getDescription for sObject " + name);
+                        throw new MojoExecutionException("Timeout waiting for getDescription for sObject " + name);
                     }
                     final SalesforceException ex = callback.getException();
                     if (ex != null) {
                         throw ex;
                     }
-                    descriptions.add(mapper.readValue(callback.getResponse(),
-                            SObjectDescription.class));
+                    descriptions.add(mapper.readValue(callback.getResponse(), SObjectDescription.class));
                 }
             } catch (Exception e) {
                 String msg = "Error getting SObject description " + e.getMessage();
@@ -342,26 +353,29 @@ public class CamelSalesforceMojo extends AbstractMojo
             for (SObjectDescription description : descriptions) {
                 processDescription(pkgDir, description, utility, generatedDate);
             }
-
-            getLog().info(String.format("Successfully generated %s Java Classes", (descriptions.size() * 2)));
+            getLog().info(String.format("Successfully generated %s Java Classes", descriptions.size() * 2));
 
         } finally {
             // remember to stop the client
             try {
-                ((DefaultRestClient)restClient).stop();
-            } catch (Exception ignore) {}
+                ((DefaultRestClient) restClient).stop();
+            } catch (Exception ignore) {
+            }
 
             // Salesforce session stop
             try {
                 session.stop();
-            } catch (Exception ignore) {}
+            } catch (Exception ignore) {
+            }
 
             // release HttpConnections
             try {
                 httpClient.stop();
-            } catch (Exception ignore) {}
+            } catch (Exception ignore) {
+            }
         }
     }
+    // CHECKSTYLE:ON
 
     private void processDescription(File pkgDir, SObjectDescription description, GeneratorUtility utility, String generatedDate) throws MojoExecutionException {
         // generate a source file for SObject
@@ -426,27 +440,28 @@ public class CamelSalesforceMojo extends AbstractMojo
             if (writer != null) {
                 try {
                     writer.close();
-                } catch (IOException ignore) {}
+                } catch (IOException ignore) {
+                }
             }
         }
     }
 
     public static class GeneratorUtility {
 
-        private static final Set<String> baseFields;
-        private static final Map<String, String> lookupMap;
+        private static final Set<String> BASE_FIELDS;
+        private static final Map<String, String> LOOKUP_MAP;
 
         static {
-            baseFields = new HashSet<String>();
+            BASE_FIELDS = new HashSet<String>();
             for (Field field : AbstractSObjectBase.class.getDeclaredFields()) {
-                baseFields.add(field.getName());
+                BASE_FIELDS.add(field.getName());
             }
 
             // create a type map
             // using JAXB mapping, for the most part
             // uses Joda time instead of XmlGregorianCalendar
             // TODO do we need support for commented types???
-            final String[][] typeMap = new String[][] {
+            final String[][] typeMap = new String[][]{
                 {"ID", "String"}, // mapping for tns:ID SOAP type
                 {"string", "String"},
                 {"integer", "java.math.BigInteger"},
@@ -463,7 +478,7 @@ public class CamelSalesforceMojo extends AbstractMojo
 //                {"dateTime", "javax.xml.datatype.XMLGregorianCalendar"},
                 {"dateTime", "org.joda.time.DateTime"},
 
-                // the blob base64Binary type is mapped to String URL for retrieving the blob
+                    // the blob base64Binary type is mapped to String URL for retrieving the blob
                 {"base64Binary", "String"},
 //                {"hexBinary", "byte[]"},
 
@@ -478,7 +493,7 @@ public class CamelSalesforceMojo extends AbstractMojo
 //                {"g", "javax.xml.datatype.XMLGregorianCalendar"},
                 {"g", "org.joda.time.DateTime"},
 
-                // Salesforce maps any types like string, picklist, reference, etc. to string
+                    // Salesforce maps any types like string, picklist, reference, etc. to string
                 {"anyType", "String"},
 /*
                 {"anySimpleType", "java.lang.Object"},
@@ -487,9 +502,9 @@ public class CamelSalesforceMojo extends AbstractMojo
                 {"NOTATION", "javax.xml.namespace.QName"}
 */
             };
-            lookupMap = new HashMap<String, String>();
+            LOOKUP_MAP = new HashMap<String, String>();
             for (String[] entry : typeMap) {
-                lookupMap.put(entry[0], entry[1]);
+                LOOKUP_MAP.put(entry[0], entry[1]);
             }
         }
 
@@ -497,11 +512,11 @@ public class CamelSalesforceMojo extends AbstractMojo
 
         public boolean isBlobField(SObjectField field) {
             final String soapType = field.getSoapType();
-            return BASE64BINARY.equals(soapType.substring(soapType.indexOf(':')+1));
+            return BASE64BINARY.equals(soapType.substring(soapType.indexOf(':') + 1));
         }
 
         public boolean notBaseField(String name) {
-            return !baseFields.contains(name);
+            return !BASE_FIELDS.contains(name);
         }
 
         public String getFieldType(SObjectField field) throws MojoExecutionException {
@@ -512,10 +527,10 @@ public class CamelSalesforceMojo extends AbstractMojo
             } else {
                 // map field to Java type
                 final String soapType = field.getSoapType();
-                final String type = lookupMap.get(soapType.substring(soapType.indexOf(':')+1));
+                final String type = LOOKUP_MAP.get(soapType.substring(soapType.indexOf(':') + 1));
                 if (type == null) {
                     throw new MojoExecutionException(
-                        String.format("Unsupported type %s for field %s", soapType, field.getName()));
+                            String.format("Unsupported type %s for field %s", soapType, field.getName()));
                 }
                 return type;
             }

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/java/org/apache/camel/maven/CamelSalesforceMojoIntegrationTest.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/java/org/apache/camel/maven/CamelSalesforceMojoIntegrationTest.java b/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/java/org/apache/camel/maven/CamelSalesforceMojoIntegrationTest.java
index 781c592..3a3d8b6 100644
--- a/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/java/org/apache/camel/maven/CamelSalesforceMojoIntegrationTest.java
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/java/org/apache/camel/maven/CamelSalesforceMojoIntegrationTest.java
@@ -16,16 +16,16 @@
  */
 package org.apache.camel.maven;
 
-import org.apache.maven.plugin.logging.SystemStreamLog;
-import org.junit.Assert;
-import org.junit.Test;
-
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.Properties;
 
+import org.apache.maven.plugin.logging.SystemStreamLog;
+import org.junit.Assert;
+import org.junit.Test;
+
 public class CamelSalesforceMojoIntegrationTest {
 
     private static final String TEST_LOGIN_PROPERTIES = "test-salesforce-login.properties";
@@ -71,15 +71,15 @@ public class CamelSalesforceMojoIntegrationTest {
         Properties properties = new Properties();
         InputStream stream = new FileInputStream(TEST_LOGIN_PROPERTIES);
         if (null == stream) {
-            throw new IllegalAccessException("Create a properties file named " +
-                TEST_LOGIN_PROPERTIES + " with clientId, clientSecret, userName, password and a testId" +
-                " for a Salesforce account with the Merchandise object from Salesforce Guides.");
+            throw new IllegalAccessException("Create a properties file named "
+                    + TEST_LOGIN_PROPERTIES + " with clientId, clientSecret, userName, password and a testId"
+                    + " for a Salesforce account with the Merchandise object from Salesforce Guides.");
         }
         properties.load(stream);
-        mojo.clientId= properties.getProperty("clientId");
-        mojo.clientSecret= properties.getProperty("clientSecret");
-        mojo.userName= properties.getProperty("userName");
-        mojo.password= properties.getProperty("password");
+        mojo.clientId = properties.getProperty("clientId");
+        mojo.clientSecret = properties.getProperty("clientSecret");
+        mojo.userName = properties.getProperty("userName");
+        mojo.password = properties.getProperty("password");
     }
 
 }


[04/11] git commit: CAMEL-6428: Fixed CS

Posted by da...@apache.org.
CAMEL-6428: Fixed CS


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

Branch: refs/heads/master
Commit: aaa2710cb8e7d23db4819599d87cb1a9af8c4549
Parents: 0c401b9
Author: Claus Ibsen <da...@apache.org>
Authored: Wed Jun 5 17:05:11 2013 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Wed Jun 5 17:12:31 2013 +0200

----------------------------------------------------------------------
 .../component/salesforce/SalesforceComponent.java  |   26 +-
 .../component/salesforce/SalesforceConsumer.java   |   38 +-
 .../component/salesforce/SalesforceEndpoint.java   |    6 +-
 .../salesforce/SalesforceEndpointConfig.java       |   12 +-
 .../component/salesforce/SalesforceProducer.java   |   37 +-
 .../salesforce/api/JodaTimeConverter.java          |   10 +-
 .../salesforce/api/PicklistEnumConverter.java      |   24 +-
 .../salesforce/api/SalesforceException.java        |    6 +-
 .../salesforce/api/dto/AbstractDTOBase.java        |    6 +-
 .../salesforce/api/dto/CreateSObjectResult.java    |    4 +-
 .../salesforce/api/dto/GlobalObjects.java          |    4 +-
 .../component/salesforce/api/dto/RestError.java    |    4 +-
 .../salesforce/api/dto/SObjectBasicInfo.java       |    4 +-
 .../salesforce/api/dto/SObjectDescription.java     |    4 +-
 .../component/salesforce/api/dto/SObjectField.java |    4 +-
 .../salesforce/api/dto/SearchResults.java          |    4 +-
 .../component/salesforce/api/dto/Versions.java     |    4 +-
 .../salesforce/api/dto/bulk/BatchInfo.java         |  180 +++----
 .../salesforce/api/dto/bulk/BatchInfoList.java     |   28 +-
 .../salesforce/api/dto/bulk/BatchResult.java       |   28 +-
 .../salesforce/api/dto/bulk/BatchStateEnum.java    |    7 +-
 .../api/dto/bulk/ConcurrencyModeEnum.java          |    7 +-
 .../salesforce/api/dto/bulk/ContentType.java       |    5 +-
 .../component/salesforce/api/dto/bulk/Error.java   |   42 +-
 .../component/salesforce/api/dto/bulk/JobInfo.java |  384 ++++++---------
 .../salesforce/api/dto/bulk/JobStateEnum.java      |    7 +-
 .../salesforce/api/dto/bulk/ObjectFactory.java     |   37 +-
 .../salesforce/api/dto/bulk/OperationEnum.java     |    7 +-
 .../salesforce/api/dto/bulk/QueryResult.java       |   28 +-
 .../salesforce/api/dto/bulk/QueryResultList.java   |   28 +-
 .../component/salesforce/api/dto/bulk/Result.java  |   54 +--
 .../salesforce/api/dto/bulk/ResultError.java       |   60 +--
 .../component/salesforce/api/dto/bulk/SObject.java |   66 ++--
 .../salesforce/api/dto/bulk/StatusCode.java        |    5 +-
 .../salesforce/api/dto/bulk/package-info.java      |    3 +-
 .../salesforce/internal/SalesforceSession.java     |   45 +-
 .../internal/client/AbstractClientBase.java        |   28 +-
 .../salesforce/internal/client/BulkApiClient.java  |   10 +-
 .../internal/client/DefaultBulkApiClient.java      |   68 ++--
 .../internal/client/DefaultRestClient.java         |   30 +-
 .../salesforce/internal/client/RestClient.java     |   75 ++--
 .../client/SalesforceSecurityListener.java         |   12 +-
 .../internal/client/SyncResponseCallback.java      |    4 +-
 .../salesforce/internal/dto/PushTopic.java         |    2 +-
 .../internal/dto/QueryRecordsPushTopic.java        |    4 +-
 .../salesforce/internal/dto/RestErrors.java        |    4 +-
 .../internal/processor/AbstractRestProcessor.java  |  183 ++++----
 .../processor/AbstractSalesforceProcessor.java     |   15 +-
 .../internal/processor/BulkApiProcessor.java       |   65 ++-
 .../internal/processor/JsonRestProcessor.java      |   33 +-
 .../internal/processor/XmlRestProcessor.java       |   62 ++-
 .../internal/streaming/PushTopicHelper.java        |   78 ++--
 .../internal/streaming/SubscriptionHelper.java     |   59 ++-
 .../salesforce/AbstractSalesforceTestBase.java     |    6 +-
 .../salesforce/BulkApiBatchIntegrationTest.java    |   14 +-
 .../salesforce/BulkApiJobIntegrationTest.java      |    6 +-
 .../salesforce/BulkApiQueryIntegrationTest.java    |   12 +-
 .../component/salesforce/LoginConfigHelper.java    |   10 +-
 .../salesforce/RestApiIntegrationTest.java         |   68 ++--
 .../salesforce/StreamingApiIntegrationTest.java    |   14 +-
 .../camel/component/salesforce/dto/Document.java   |    2 +-
 .../component/salesforce/dto/Line_Item__c.java     |    2 +-
 .../component/salesforce/dto/Merchandise__c.java   |    2 +-
 .../salesforce/dto/QueryRecordsLine_Item__c.java   |    4 +-
 .../internal/SessionIntegrationTest.java           |    2 +-
 .../apache/camel/maven/CamelSalesforceMojo.java    |  149 +++---
 .../maven/CamelSalesforceMojoIntegrationTest.java  |   22 +-
 67 files changed, 1063 insertions(+), 1200 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/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
index a48502a..57ee583 100644
--- 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
@@ -16,25 +16,25 @@
  */
 package org.apache.camel.component.salesforce;
 
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
 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.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.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}.
  */
@@ -84,7 +84,7 @@ public class SalesforceComponent extends DefaultComponent {
         setProperties(copy, parameters);
 
         final SalesforceEndpoint endpoint = new SalesforceEndpoint(uri, this, copy,
-            operationName, topicName);
+                operationName, topicName);
 
         // map remaining parameters to endpoint (specifically, synchronous)
         setProperties(endpoint, parameters);
@@ -115,8 +115,8 @@ public class SalesforceComponent extends DefaultComponent {
         // 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)) {
+        if (httpClient.getRegisteredListeners() == null
+                || !httpClient.getRegisteredListeners().contains(listenerClass)) {
             httpClient.registerListener(listenerClass);
         }
         // SalesforceSecurityListener can't be registered the same way

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/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
index 9fa1b91..c3f6a05 100644
--- 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
@@ -16,31 +16,32 @@
  */
 package org.apache.camel.component.salesforce;
 
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.HashMap;
+import java.util.Map;
+
 import org.apache.camel.AsyncCallback;
 import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
 import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.component.salesforce.internal.client.DefaultRestClient;
+import org.apache.camel.component.salesforce.internal.client.RestClient;
+import org.apache.camel.component.salesforce.internal.streaming.PushTopicHelper;
+import org.apache.camel.component.salesforce.internal.streaming.SubscriptionHelper;
 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 ObjectMapper OBJECT_MAPPER = new ObjectMapper();
     private static final String EVENT_PROPERTY = "event";
     private static final String TYPE_PROPERTY = "type";
     private static final String CREATED_DATE_PROPERTY = "createdDate";
@@ -48,12 +49,13 @@ public class SalesforceConsumer extends DefaultConsumer {
     private static final double MINIMUM_VERSION = 24.0;
 
     private final SalesforceEndpoint endpoint;
-    public final SubscriptionHelper subscriptionHelper;
+    private 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;
@@ -100,7 +102,7 @@ public class SalesforceConsumer extends DefaultConsumer {
             // create REST client for PushTopic operations
             SalesforceComponent component = endpoint.getComponent();
             RestClient restClient = new DefaultRestClient(component.getConfig().getHttpClient(),
-                endpoint.getConfiguration().getApiVersion(), "json", component.getSession());
+                    endpoint.getConfiguration().getApiVersion(), "json", component.getSession());
             // don't forget to start the client
             ServiceHelper.startService(restClient);
 
@@ -144,7 +146,7 @@ public class SalesforceConsumer extends DefaultConsumer {
         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));
+                    eventType, channel.getChannelId(), createdDate));
         }
 
         in.setHeader("CamelSalesforceEventType", eventType);
@@ -155,7 +157,7 @@ public class SalesforceConsumer extends DefaultConsumer {
         final Map<String, Object> sObject = (Map<String, Object>) data.get(SOBJECT_PROPERTY);
         try {
 
-            final String sObjectString = objectMapper.writeValueAsString(sObject);
+            final String sObjectString = OBJECT_MAPPER.writeValueAsString(sObject);
             log.debug("Received SObject: {}", sObjectString);
 
             if (sObjectClass == null) {
@@ -163,12 +165,12 @@ public class SalesforceConsumer extends DefaultConsumer {
                 in.setBody(sObject);
             } else {
                 // create the expected SObject
-                in.setBody(objectMapper.readValue(
-                    new StringReader(sObjectString), sObjectClass));
+                in.setBody(OBJECT_MAPPER.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());
+                    message, topicName, e.getMessage());
             handleException(msg, new RuntimeCamelException(msg, e));
         }
 
@@ -178,7 +180,7 @@ public class SalesforceConsumer extends DefaultConsumer {
                     // noop
                     if (log.isTraceEnabled()) {
                         log.trace("Done processing event: {} {}", eventType.toString(),
-                            doneSync ? "synchronously" : "asynchronously");
+                                doneSync ? "synchronously" : "asynchronously");
                     }
                 }
             });

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/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
index 24874bb..b7283eb 100644
--- 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
@@ -19,9 +19,9 @@ 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.component.salesforce.internal.OperationName;
 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;
 
@@ -63,11 +63,11 @@ public class SalesforceEndpoint extends DefaultEndpoint {
         // 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()));
+                    operationName.value()));
         }
 
         return new SalesforceConsumer(this, processor,
-            getComponent().getSubscriptionHelper());
+                getComponent().getSubscriptionHelper());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/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
index 817871b..78643c0 100644
--- 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
@@ -16,22 +16,22 @@
  */
 package org.apache.camel.component.salesforce;
 
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
 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;
+import org.eclipse.jetty.client.HttpClient;
 
 public class SalesforceEndpointConfig implements Cloneable {
 
     // default API version
-    static final String DEFAULT_VERSION = "27.0";
+    public static final String DEFAULT_VERSION = "27.0";
 
     // general parameter
     public static final String API_VERSION = "apiVersion";

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/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
index 5cc4547..a095f6f 100644
--- 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
@@ -18,8 +18,6 @@ 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;
@@ -27,6 +25,8 @@ 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;
+import org.apache.camel.impl.DefaultAsyncProducer;
+import org.apache.camel.util.ServiceHelper;
 
 /**
  * The Salesforce producer.
@@ -57,29 +57,28 @@ public class SalesforceProducer extends DefaultAsyncProducer {
 
     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;
+        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());
+                ((SalesforceEndpoint) getEndpoint()).getOperationName());
         return processor.process(exchange, callback);
     }
 

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/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
index 372e7a4..8a3296a 100644
--- 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
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.component.salesforce.api;
 
+import java.lang.reflect.Constructor;
+
 import com.thoughtworks.xstream.converters.Converter;
 import com.thoughtworks.xstream.converters.MarshallingContext;
 import com.thoughtworks.xstream.converters.UnmarshallingContext;
@@ -28,8 +30,6 @@ 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();
@@ -50,9 +50,9 @@ public class JodaTimeConverter implements Converter {
             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);
+                    String.format("Error reading Joda DateTime from value %s: %s",
+                            dateTimeStr, e.getMessage()),
+                    e);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/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
index 06d0ca5..6b5c95b 100644
--- 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
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.component.salesforce.api;
 
+import java.lang.reflect.Method;
+
 import com.thoughtworks.xstream.converters.Converter;
 import com.thoughtworks.xstream.converters.MarshallingContext;
 import com.thoughtworks.xstream.converters.UnmarshallingContext;
@@ -24,8 +26,6 @@ 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";
@@ -39,9 +39,9 @@ public class PicklistEnumConverter implements Converter {
             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);
+                    String.format("Exception writing pick list value %s of type %s: %s",
+                            o, o.getClass().getName(), e.getMessage()),
+                    e);
         }
     }
 
@@ -55,14 +55,14 @@ public class PicklistEnumConverter implements Converter {
             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);
+                    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);
+                    String.format("Security Exception reading pick list value %s of type %s: %s",
+                            value, context.getRequiredType().getName(), e.getMessage()),
+                    e);
         }
     }
 
@@ -71,7 +71,7 @@ public class PicklistEnumConverter implements Converter {
     public boolean canConvert(Class aClass) {
         try {
             return Enum.class.isAssignableFrom(aClass) &&
-                aClass.getMethod(FACTORY_METHOD, String.class) != null;
+                    aClass.getMethod(FACTORY_METHOD, String.class) != null;
         } catch (NoSuchMethodException e) {
             return false;
         }

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/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
index 760eebe..96d4622 100644
--- 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
@@ -16,13 +16,13 @@
  */
 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;
 
+import org.apache.camel.CamelException;
+import org.apache.camel.component.salesforce.api.dto.RestError;
+
 public class SalesforceException extends CamelException {
 
     private List<RestError> errors;

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/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
index e4723ae..5052921 100644
--- 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
@@ -16,12 +16,12 @@
  */
 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;
 
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
 // disable null values in json output
 @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
 public abstract class AbstractDTOBase {

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/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
index bc9fdaa..b7e7dd9 100644
--- 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
@@ -16,11 +16,11 @@
  */
 package org.apache.camel.component.salesforce.api.dto;
 
+import java.util.List;
+
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import com.thoughtworks.xstream.annotations.XStreamImplicit;
 
-import java.util.List;
-
 @XStreamAlias("Result")
 public class CreateSObjectResult extends AbstractDTOBase {
 

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/GlobalObjects.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/GlobalObjects.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/GlobalObjects.java
index 302e54e..f11bebe 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/GlobalObjects.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/GlobalObjects.java
@@ -16,11 +16,11 @@
  */
 package org.apache.camel.component.salesforce.api.dto;
 
+import java.util.List;
+
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import com.thoughtworks.xstream.annotations.XStreamImplicit;
 
-import java.util.List;
-
 @XStreamAlias("DescribeGlobal")
 public class GlobalObjects extends AbstractDTOBase {
 

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/RestError.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/RestError.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/RestError.java
index e155f05..6bda6c4 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/RestError.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/RestError.java
@@ -16,10 +16,10 @@
  */
 package org.apache.camel.component.salesforce.api.dto;
 
-import com.thoughtworks.xstream.annotations.XStreamImplicit;
-
 import java.util.List;
 
+import com.thoughtworks.xstream.annotations.XStreamImplicit;
+
 public class RestError extends AbstractDTOBase {
     private String errorCode;
     private String message;

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectBasicInfo.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectBasicInfo.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectBasicInfo.java
index b31708c..88b5e30 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectBasicInfo.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectBasicInfo.java
@@ -16,10 +16,10 @@
  */
 package org.apache.camel.component.salesforce.api.dto;
 
-import com.thoughtworks.xstream.annotations.XStreamImplicit;
-
 import java.util.List;
 
+import com.thoughtworks.xstream.annotations.XStreamImplicit;
+
 public class SObjectBasicInfo extends AbstractDTOBase {
 
     private SObject objectDescribe;

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectDescription.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectDescription.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectDescription.java
index 5177f4a..cd45847 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectDescription.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectDescription.java
@@ -16,10 +16,10 @@
  */
 package org.apache.camel.component.salesforce.api.dto;
 
-import com.thoughtworks.xstream.annotations.XStreamImplicit;
-
 import java.util.List;
 
+import com.thoughtworks.xstream.annotations.XStreamImplicit;
+
 public class SObjectDescription extends SObject {
 
     @XStreamImplicit

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectField.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectField.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectField.java
index 379365d..8664c19 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectField.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectField.java
@@ -16,10 +16,10 @@
  */
 package org.apache.camel.component.salesforce.api.dto;
 
-import com.thoughtworks.xstream.annotations.XStreamImplicit;
-
 import java.util.List;
 
+import com.thoughtworks.xstream.annotations.XStreamImplicit;
+
 public class SObjectField extends AbstractDTOBase {
 
     private Integer length;

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SearchResults.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SearchResults.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SearchResults.java
index 18fb680..6239756 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SearchResults.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SearchResults.java
@@ -16,11 +16,11 @@
  */
 package org.apache.camel.component.salesforce.api.dto;
 
+import java.util.List;
+
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import com.thoughtworks.xstream.annotations.XStreamImplicit;
 
-import java.util.List;
-
 /**
  * DTO for Salesforce SOSL Search results.
  */

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/Versions.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/Versions.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/Versions.java
index 1349eb8..e104c14 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/Versions.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/Versions.java
@@ -16,11 +16,11 @@
  */
 package org.apache.camel.component.salesforce.api.dto;
 
+import java.util.List;
+
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import com.thoughtworks.xstream.annotations.XStreamImplicit;
 
-import java.util.List;
-
 /**
  * DTO for Salesforce versions
  */

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchInfo.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchInfo.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchInfo.java
index 2a78b22..d33de87 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchInfo.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchInfo.java
@@ -16,15 +16,19 @@
  */
 package org.apache.camel.component.salesforce.api.dto.bulk;
 
-import javax.xml.bind.annotation.*;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlType;
 import javax.xml.datatype.XMLGregorianCalendar;
 
 
 /**
  * <p>Java class for BatchInfo complex type.
- * 
+ * <p/>
  * <p>The following schema fragment specifies the expected content contained within this class.
- * 
+ * <p/>
  * <pre>
  * &lt;complexType name="BatchInfo">
  *   &lt;complexContent>
@@ -46,22 +50,20 @@ import javax.xml.datatype.XMLGregorianCalendar;
  *   &lt;/complexContent>
  * &lt;/complexType>
  * </pre>
- * 
- * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "BatchInfo", propOrder = {
-    "id",
-    "jobId",
-    "state",
-    "stateMessage",
-    "createdDate",
-    "systemModstamp",
-    "numberRecordsProcessed",
-    "numberRecordsFailed",
-    "totalProcessingTime",
-    "apiActiveProcessingTime",
-    "apexProcessingTime"
+        "id",
+        "jobId",
+        "state",
+        "stateMessage",
+        "createdDate",
+        "systemModstamp",
+        "numberRecordsProcessed",
+        "numberRecordsFailed",
+        "totalProcessingTime",
+        "apiActiveProcessingTime",
+        "apexProcessingTime"
 })
 public class BatchInfo {
 
@@ -85,11 +87,9 @@ public class BatchInfo {
 
     /**
      * Gets the value of the id property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
+     *
+     * @return possible object is
+     *         {@link String }
      */
     public String getId() {
         return id;
@@ -97,11 +97,9 @@ public class BatchInfo {
 
     /**
      * Sets the value of the id property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
+     *
+     * @param value allowed object is
+     *              {@link String }
      */
     public void setId(String value) {
         this.id = value;
@@ -109,11 +107,9 @@ public class BatchInfo {
 
     /**
      * Gets the value of the jobId property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
+     *
+     * @return possible object is
+     *         {@link String }
      */
     public String getJobId() {
         return jobId;
@@ -121,11 +117,9 @@ public class BatchInfo {
 
     /**
      * Sets the value of the jobId property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
+     *
+     * @param value allowed object is
+     *              {@link String }
      */
     public void setJobId(String value) {
         this.jobId = value;
@@ -133,11 +127,9 @@ public class BatchInfo {
 
     /**
      * Gets the value of the state property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link BatchStateEnum }
      *
+     * @return possible object is
+     *         {@link BatchStateEnum }
      */
     public BatchStateEnum getState() {
         return state;
@@ -146,10 +138,8 @@ public class BatchInfo {
     /**
      * Sets the value of the state property.
      *
-     * @param value
-     *     allowed object is
-     *     {@link BatchStateEnum }
-     *
+     * @param value allowed object is
+     *              {@link BatchStateEnum }
      */
     public void setState(BatchStateEnum value) {
         this.state = value;
@@ -158,10 +148,8 @@ public class BatchInfo {
     /**
      * Gets the value of the stateMessage property.
      *
-     * @return
-     *     possible object is
-     *     {@link String }
-     *
+     * @return possible object is
+     *         {@link String }
      */
     public String getStateMessage() {
         return stateMessage;
@@ -170,10 +158,8 @@ public class BatchInfo {
     /**
      * Sets the value of the stateMessage property.
      *
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *
+     * @param value allowed object is
+     *              {@link String }
      */
     public void setStateMessage(String value) {
         this.stateMessage = value;
@@ -182,10 +168,8 @@ public class BatchInfo {
     /**
      * Gets the value of the createdDate property.
      *
-     * @return
-     *     possible object is
-     *     {@link javax.xml.datatype.XMLGregorianCalendar }
-     *
+     * @return possible object is
+     *         {@link javax.xml.datatype.XMLGregorianCalendar }
      */
     public XMLGregorianCalendar getCreatedDate() {
         return createdDate;
@@ -194,10 +178,8 @@ public class BatchInfo {
     /**
      * Sets the value of the createdDate property.
      *
-     * @param value
-     *     allowed object is
-     *     {@link javax.xml.datatype.XMLGregorianCalendar }
-     *
+     * @param value allowed object is
+     *              {@link javax.xml.datatype.XMLGregorianCalendar }
      */
     public void setCreatedDate(XMLGregorianCalendar value) {
         this.createdDate = value;
@@ -206,10 +188,8 @@ public class BatchInfo {
     /**
      * Gets the value of the systemModstamp property.
      *
-     * @return
-     *     possible object is
-     *     {@link javax.xml.datatype.XMLGregorianCalendar }
-     *
+     * @return possible object is
+     *         {@link javax.xml.datatype.XMLGregorianCalendar }
      */
     public XMLGregorianCalendar getSystemModstamp() {
         return systemModstamp;
@@ -218,10 +198,8 @@ public class BatchInfo {
     /**
      * Sets the value of the systemModstamp property.
      *
-     * @param value
-     *     allowed object is
-     *     {@link javax.xml.datatype.XMLGregorianCalendar }
-     *     
+     * @param value allowed object is
+     *              {@link javax.xml.datatype.XMLGregorianCalendar }
      */
     public void setSystemModstamp(XMLGregorianCalendar value) {
         this.systemModstamp = value;
@@ -229,7 +207,6 @@ public class BatchInfo {
 
     /**
      * Gets the value of the numberRecordsProcessed property.
-     * 
      */
     public int getNumberRecordsProcessed() {
         return numberRecordsProcessed;
@@ -237,7 +214,6 @@ public class BatchInfo {
 
     /**
      * Sets the value of the numberRecordsProcessed property.
-     * 
      */
     public void setNumberRecordsProcessed(int value) {
         this.numberRecordsProcessed = value;
@@ -245,11 +221,9 @@ public class BatchInfo {
 
     /**
      * Gets the value of the numberRecordsFailed property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Integer }
-     *     
+     *
+     * @return possible object is
+     *         {@link Integer }
      */
     public Integer getNumberRecordsFailed() {
         return numberRecordsFailed;
@@ -257,11 +231,9 @@ public class BatchInfo {
 
     /**
      * Sets the value of the numberRecordsFailed property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Integer }
-     *     
+     *
+     * @param value allowed object is
+     *              {@link Integer }
      */
     public void setNumberRecordsFailed(Integer value) {
         this.numberRecordsFailed = value;
@@ -269,11 +241,9 @@ public class BatchInfo {
 
     /**
      * Gets the value of the totalProcessingTime property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Long }
-     *     
+     *
+     * @return possible object is
+     *         {@link Long }
      */
     public Long getTotalProcessingTime() {
         return totalProcessingTime;
@@ -281,11 +251,9 @@ public class BatchInfo {
 
     /**
      * Sets the value of the totalProcessingTime property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Long }
-     *     
+     *
+     * @param value allowed object is
+     *              {@link Long }
      */
     public void setTotalProcessingTime(Long value) {
         this.totalProcessingTime = value;
@@ -293,11 +261,9 @@ public class BatchInfo {
 
     /**
      * Gets the value of the apiActiveProcessingTime property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Long }
-     *     
+     *
+     * @return possible object is
+     *         {@link Long }
      */
     public Long getApiActiveProcessingTime() {
         return apiActiveProcessingTime;
@@ -305,11 +271,9 @@ public class BatchInfo {
 
     /**
      * Sets the value of the apiActiveProcessingTime property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Long }
-     *     
+     *
+     * @param value allowed object is
+     *              {@link Long }
      */
     public void setApiActiveProcessingTime(Long value) {
         this.apiActiveProcessingTime = value;
@@ -317,11 +281,9 @@ public class BatchInfo {
 
     /**
      * Gets the value of the apexProcessingTime property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Long }
-     *     
+     *
+     * @return possible object is
+     *         {@link Long }
      */
     public Long getApexProcessingTime() {
         return apexProcessingTime;
@@ -329,11 +291,9 @@ public class BatchInfo {
 
     /**
      * Sets the value of the apexProcessingTime property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Long }
-     *     
+     *
+     * @param value allowed object is
+     *              {@link Long }
      */
     public void setApexProcessingTime(Long value) {
         this.apexProcessingTime = value;

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchInfoList.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchInfoList.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchInfoList.java
index de73632..9c15711 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchInfoList.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchInfoList.java
@@ -16,18 +16,18 @@
  */
 package org.apache.camel.component.salesforce.api.dto.bulk;
 
+import java.util.ArrayList;
+import java.util.List;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlType;
-import java.util.ArrayList;
-import java.util.List;
 
 
 /**
  * <p>Java class for BatchInfoList complex type.
- * 
+ * <p/>
  * <p>The following schema fragment specifies the expected content contained within this class.
- * 
+ * <p/>
  * <pre>
  * &lt;complexType name="BatchInfoList">
  *   &lt;complexContent>
@@ -39,12 +39,10 @@ import java.util.List;
  *   &lt;/complexContent>
  * &lt;/complexType>
  * </pre>
- * 
- * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "BatchInfoList", propOrder = {
-    "batchInfo"
+        "batchInfo"
 })
 public class BatchInfoList {
 
@@ -52,25 +50,23 @@ public class BatchInfoList {
 
     /**
      * Gets the value of the batchInfo property.
-     * 
-     * <p>
+     * <p/>
+     * <p/>
      * This accessor method returns a reference to the live list,
      * not a snapshot. Therefore any modification you make to the
      * returned list will be present inside the JAXB object.
      * This is why there is not a <CODE>set</CODE> method for the batchInfo property.
-     * 
-     * <p>
+     * <p/>
+     * <p/>
      * For example, to add a new item, do as follows:
      * <pre>
      *    getBatchInfo().add(newItem);
      * </pre>
-     * 
-     * 
-     * <p>
+     * <p/>
+     * <p/>
+     * <p/>
      * Objects of the following type(s) are allowed in the list
      * {@link BatchInfo }
-     * 
-     * 
      */
     public List<BatchInfo> getBatchInfo() {
         if (batchInfo == null) {

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchResult.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchResult.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchResult.java
index f7a7f72..b223965 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchResult.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchResult.java
@@ -16,18 +16,18 @@
  */
 package org.apache.camel.component.salesforce.api.dto.bulk;
 
+import java.util.ArrayList;
+import java.util.List;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlType;
-import java.util.ArrayList;
-import java.util.List;
 
 
 /**
  * <p>Java class for BatchResult complex type.
- * 
+ * <p/>
  * <p>The following schema fragment specifies the expected content contained within this class.
- * 
+ * <p/>
  * <pre>
  * &lt;complexType name="BatchResult">
  *   &lt;complexContent>
@@ -39,12 +39,10 @@ import java.util.List;
  *   &lt;/complexContent>
  * &lt;/complexType>
  * </pre>
- * 
- * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "BatchResult", propOrder = {
-    "result"
+        "result"
 })
 public class BatchResult {
 
@@ -52,25 +50,23 @@ public class BatchResult {
 
     /**
      * Gets the value of the result property.
-     * 
-     * <p>
+     * <p/>
+     * <p/>
      * This accessor method returns a reference to the live list,
      * not a snapshot. Therefore any modification you make to the
      * returned list will be present inside the JAXB object.
      * This is why there is not a <CODE>set</CODE> method for the result property.
-     * 
-     * <p>
+     * <p/>
+     * <p/>
      * For example, to add a new item, do as follows:
      * <pre>
      *    getResult().add(newItem);
      * </pre>
-     * 
-     * 
-     * <p>
+     * <p/>
+     * <p/>
+     * <p/>
      * Objects of the following type(s) are allowed in the list
      * {@link Result }
-     * 
-     * 
      */
     public List<Result> getResult() {
         if (result == null) {

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchStateEnum.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchStateEnum.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchStateEnum.java
index 1914ec0..b6be0d2 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchStateEnum.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchStateEnum.java
@@ -23,9 +23,9 @@ import javax.xml.bind.annotation.XmlType;
 
 /**
  * <p>Java class for BatchStateEnum.
- * 
+ * <p/>
  * <p>The following schema fragment specifies the expected content contained within this class.
- * <p>
+ * <p/>
  * <pre>
  * &lt;simpleType name="BatchStateEnum">
  *   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
@@ -37,7 +37,6 @@ import javax.xml.bind.annotation.XmlType;
  *   &lt;/restriction>
  * &lt;/simpleType>
  * </pre>
- * 
  */
 @XmlType(name = "BatchStateEnum")
 @XmlEnum
@@ -64,7 +63,7 @@ public enum BatchStateEnum {
     }
 
     public static BatchStateEnum fromValue(String v) {
-        for (BatchStateEnum c: BatchStateEnum.values()) {
+        for (BatchStateEnum c : BatchStateEnum.values()) {
             if (c.value.equals(v)) {
                 return c;
             }

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ConcurrencyModeEnum.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ConcurrencyModeEnum.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ConcurrencyModeEnum.java
index 879bb37..2a244ed 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ConcurrencyModeEnum.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ConcurrencyModeEnum.java
@@ -23,9 +23,9 @@ import javax.xml.bind.annotation.XmlType;
 
 /**
  * <p>Java class for ConcurrencyModeEnum.
- * 
+ * <p/>
  * <p>The following schema fragment specifies the expected content contained within this class.
- * <p>
+ * <p/>
  * <pre>
  * &lt;simpleType name="ConcurrencyModeEnum">
  *   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
@@ -34,7 +34,6 @@ import javax.xml.bind.annotation.XmlType;
  *   &lt;/restriction>
  * &lt;/simpleType>
  * </pre>
- * 
  */
 @XmlType(name = "ConcurrencyModeEnum")
 @XmlEnum
@@ -55,7 +54,7 @@ public enum ConcurrencyModeEnum {
     }
 
     public static ConcurrencyModeEnum fromValue(String v) {
-        for (ConcurrencyModeEnum c: ConcurrencyModeEnum.values()) {
+        for (ConcurrencyModeEnum c : ConcurrencyModeEnum.values()) {
             if (c.value.equals(v)) {
                 return c;
             }

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ContentType.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ContentType.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ContentType.java
index 1a3c75e..c5b4541 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ContentType.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ContentType.java
@@ -22,9 +22,9 @@ import javax.xml.bind.annotation.XmlType;
 
 /**
  * <p>Java class for ContentType.
- * 
+ * <p/>
  * <p>The following schema fragment specifies the expected content contained within this class.
- * <p>
+ * <p/>
  * <pre>
  * &lt;simpleType name="ContentType">
  *   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
@@ -35,7 +35,6 @@ import javax.xml.bind.annotation.XmlType;
  *   &lt;/restriction>
  * &lt;/simpleType>
  * </pre>
- * 
  */
 @XmlType(name = "ContentType")
 @XmlEnum

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/Error.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/Error.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/Error.java
index 4a06fbb..ee4cad1 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/Error.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/Error.java
@@ -24,9 +24,9 @@ import javax.xml.bind.annotation.XmlType;
 
 /**
  * <p>Java class for Error complex type.
- * 
+ * <p/>
  * <p>The following schema fragment specifies the expected content contained within this class.
- * 
+ * <p/>
  * <pre>
  * &lt;complexType name="Error">
  *   &lt;complexContent>
@@ -39,13 +39,11 @@ import javax.xml.bind.annotation.XmlType;
  *   &lt;/complexContent>
  * &lt;/complexType>
  * </pre>
- * 
- * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "Error", propOrder = {
-    "exceptionCode",
-    "exceptionMessage"
+        "exceptionCode",
+        "exceptionMessage"
 })
 public class Error {
 
@@ -56,11 +54,9 @@ public class Error {
 
     /**
      * Gets the value of the exceptionCode property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
+     *
+     * @return possible object is
+     *         {@link String }
      */
     public String getExceptionCode() {
         return exceptionCode;
@@ -68,11 +64,9 @@ public class Error {
 
     /**
      * Sets the value of the exceptionCode property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
+     *
+     * @param value allowed object is
+     *              {@link String }
      */
     public void setExceptionCode(String value) {
         this.exceptionCode = value;
@@ -80,11 +74,9 @@ public class Error {
 
     /**
      * Gets the value of the exceptionMessage property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
+     *
+     * @return possible object is
+     *         {@link String }
      */
     public String getExceptionMessage() {
         return exceptionMessage;
@@ -92,11 +84,9 @@ public class Error {
 
     /**
      * Sets the value of the exceptionMessage property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
+     *
+     * @param value allowed object is
+     *              {@link String }
      */
     public void setExceptionMessage(String value) {
         this.exceptionMessage = value;

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/JobInfo.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/JobInfo.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/JobInfo.java
index 568138c..f06ad3d 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/JobInfo.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/JobInfo.java
@@ -25,9 +25,9 @@ import javax.xml.datatype.XMLGregorianCalendar;
 
 /**
  * <p>Java class for JobInfo complex type.
- * 
+ * <p/>
  * <p>The following schema fragment specifies the expected content contained within this class.
- * 
+ * <p/>
  * <pre>
  * &lt;complexType name="JobInfo">
  *   &lt;complexContent>
@@ -61,34 +61,32 @@ import javax.xml.datatype.XMLGregorianCalendar;
  *   &lt;/complexContent>
  * &lt;/complexType>
  * </pre>
- * 
- * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "JobInfo", propOrder = {
-    "id",
-    "operation",
-    "object",
-    "createdById",
-    "createdDate",
-    "systemModstamp",
-    "state",
-    "externalIdFieldName",
-    "concurrencyMode",
-    "contentType",
-    "numberBatchesQueued",
-    "numberBatchesInProgress",
-    "numberBatchesCompleted",
-    "numberBatchesFailed",
-    "numberBatchesTotal",
-    "numberRecordsProcessed",
-    "numberRetries",
-    "apiVersion",
-    "assignmentRuleId",
-    "numberRecordsFailed",
-    "totalProcessingTime",
-    "apiActiveProcessingTime",
-    "apexProcessingTime"
+        "id",
+        "operation",
+        "object",
+        "createdById",
+        "createdDate",
+        "systemModstamp",
+        "state",
+        "externalIdFieldName",
+        "concurrencyMode",
+        "contentType",
+        "numberBatchesQueued",
+        "numberBatchesInProgress",
+        "numberBatchesCompleted",
+        "numberBatchesFailed",
+        "numberBatchesTotal",
+        "numberRecordsProcessed",
+        "numberRetries",
+        "apiVersion",
+        "assignmentRuleId",
+        "numberRecordsFailed",
+        "totalProcessingTime",
+        "apiActiveProcessingTime",
+        "apexProcessingTime"
 })
 public class JobInfo {
 
@@ -120,11 +118,9 @@ public class JobInfo {
 
     /**
      * Gets the value of the id property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
+     *
+     * @return possible object is
+     *         {@link String }
      */
     public String getId() {
         return id;
@@ -132,11 +128,9 @@ public class JobInfo {
 
     /**
      * Sets the value of the id property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
+     *
+     * @param value allowed object is
+     *              {@link String }
      */
     public void setId(String value) {
         this.id = value;
@@ -144,11 +138,9 @@ public class JobInfo {
 
     /**
      * Gets the value of the operation property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link OperationEnum }
      *
+     * @return possible object is
+     *         {@link OperationEnum }
      */
     public OperationEnum getOperation() {
         return operation;
@@ -157,10 +149,8 @@ public class JobInfo {
     /**
      * Sets the value of the operation property.
      *
-     * @param value
-     *     allowed object is
-     *     {@link OperationEnum }
-     *
+     * @param value allowed object is
+     *              {@link OperationEnum }
      */
     public void setOperation(OperationEnum value) {
         this.operation = value;
@@ -169,10 +159,8 @@ public class JobInfo {
     /**
      * Gets the value of the object property.
      *
-     * @return
-     *     possible object is
-     *     {@link String }
-     *
+     * @return possible object is
+     *         {@link String }
      */
     public String getObject() {
         return object;
@@ -181,10 +169,8 @@ public class JobInfo {
     /**
      * Sets the value of the object property.
      *
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *
+     * @param value allowed object is
+     *              {@link String }
      */
     public void setObject(String value) {
         this.object = value;
@@ -193,10 +179,8 @@ public class JobInfo {
     /**
      * Gets the value of the createdById property.
      *
-     * @return
-     *     possible object is
-     *     {@link String }
-     *
+     * @return possible object is
+     *         {@link String }
      */
     public String getCreatedById() {
         return createdById;
@@ -205,10 +189,8 @@ public class JobInfo {
     /**
      * Sets the value of the createdById property.
      *
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *
+     * @param value allowed object is
+     *              {@link String }
      */
     public void setCreatedById(String value) {
         this.createdById = value;
@@ -217,10 +199,8 @@ public class JobInfo {
     /**
      * Gets the value of the createdDate property.
      *
-     * @return
-     *     possible object is
-     *     {@link javax.xml.datatype.XMLGregorianCalendar }
-     *
+     * @return possible object is
+     *         {@link javax.xml.datatype.XMLGregorianCalendar }
      */
     public XMLGregorianCalendar getCreatedDate() {
         return createdDate;
@@ -229,10 +209,8 @@ public class JobInfo {
     /**
      * Sets the value of the createdDate property.
      *
-     * @param value
-     *     allowed object is
-     *     {@link javax.xml.datatype.XMLGregorianCalendar }
-     *
+     * @param value allowed object is
+     *              {@link javax.xml.datatype.XMLGregorianCalendar }
      */
     public void setCreatedDate(XMLGregorianCalendar value) {
         this.createdDate = value;
@@ -241,10 +219,8 @@ public class JobInfo {
     /**
      * Gets the value of the systemModstamp property.
      *
-     * @return
-     *     possible object is
-     *     {@link javax.xml.datatype.XMLGregorianCalendar }
-     *
+     * @return possible object is
+     *         {@link javax.xml.datatype.XMLGregorianCalendar }
      */
     public XMLGregorianCalendar getSystemModstamp() {
         return systemModstamp;
@@ -253,10 +229,8 @@ public class JobInfo {
     /**
      * Sets the value of the systemModstamp property.
      *
-     * @param value
-     *     allowed object is
-     *     {@link javax.xml.datatype.XMLGregorianCalendar }
-     *
+     * @param value allowed object is
+     *              {@link javax.xml.datatype.XMLGregorianCalendar }
      */
     public void setSystemModstamp(XMLGregorianCalendar value) {
         this.systemModstamp = value;
@@ -265,10 +239,8 @@ public class JobInfo {
     /**
      * Gets the value of the state property.
      *
-     * @return
-     *     possible object is
-     *     {@link JobStateEnum }
-     *
+     * @return possible object is
+     *         {@link JobStateEnum }
      */
     public JobStateEnum getState() {
         return state;
@@ -277,10 +249,8 @@ public class JobInfo {
     /**
      * Sets the value of the state property.
      *
-     * @param value
-     *     allowed object is
-     *     {@link JobStateEnum }
-     *
+     * @param value allowed object is
+     *              {@link JobStateEnum }
      */
     public void setState(JobStateEnum value) {
         this.state = value;
@@ -289,10 +259,8 @@ public class JobInfo {
     /**
      * Gets the value of the externalIdFieldName property.
      *
-     * @return
-     *     possible object is
-     *     {@link String }
-     *
+     * @return possible object is
+     *         {@link String }
      */
     public String getExternalIdFieldName() {
         return externalIdFieldName;
@@ -301,10 +269,8 @@ public class JobInfo {
     /**
      * Sets the value of the externalIdFieldName property.
      *
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *
+     * @param value allowed object is
+     *              {@link String }
      */
     public void setExternalIdFieldName(String value) {
         this.externalIdFieldName = value;
@@ -313,10 +279,8 @@ public class JobInfo {
     /**
      * Gets the value of the concurrencyMode property.
      *
-     * @return
-     *     possible object is
-     *     {@link ConcurrencyModeEnum }
-     *
+     * @return possible object is
+     *         {@link ConcurrencyModeEnum }
      */
     public ConcurrencyModeEnum getConcurrencyMode() {
         return concurrencyMode;
@@ -325,10 +289,8 @@ public class JobInfo {
     /**
      * Sets the value of the concurrencyMode property.
      *
-     * @param value
-     *     allowed object is
-     *     {@link ConcurrencyModeEnum }
-     *
+     * @param value allowed object is
+     *              {@link ConcurrencyModeEnum }
      */
     public void setConcurrencyMode(ConcurrencyModeEnum value) {
         this.concurrencyMode = value;
@@ -337,10 +299,8 @@ public class JobInfo {
     /**
      * Gets the value of the contentType property.
      *
-     * @return
-     *     possible object is
-     *     {@link ContentType }
-     *
+     * @return possible object is
+     *         {@link ContentType }
      */
     public ContentType getContentType() {
         return contentType;
@@ -349,10 +309,8 @@ public class JobInfo {
     /**
      * Sets the value of the contentType property.
      *
-     * @param value
-     *     allowed object is
-     *     {@link ContentType }
-     *     
+     * @param value allowed object is
+     *              {@link ContentType }
      */
     public void setContentType(ContentType value) {
         this.contentType = value;
@@ -360,11 +318,9 @@ public class JobInfo {
 
     /**
      * Gets the value of the numberBatchesQueued property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Integer }
-     *     
+     *
+     * @return possible object is
+     *         {@link Integer }
      */
     public Integer getNumberBatchesQueued() {
         return numberBatchesQueued;
@@ -372,11 +328,9 @@ public class JobInfo {
 
     /**
      * Sets the value of the numberBatchesQueued property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Integer }
-     *     
+     *
+     * @param value allowed object is
+     *              {@link Integer }
      */
     public void setNumberBatchesQueued(Integer value) {
         this.numberBatchesQueued = value;
@@ -384,11 +338,9 @@ public class JobInfo {
 
     /**
      * Gets the value of the numberBatchesInProgress property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Integer }
-     *     
+     *
+     * @return possible object is
+     *         {@link Integer }
      */
     public Integer getNumberBatchesInProgress() {
         return numberBatchesInProgress;
@@ -396,11 +348,9 @@ public class JobInfo {
 
     /**
      * Sets the value of the numberBatchesInProgress property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Integer }
-     *     
+     *
+     * @param value allowed object is
+     *              {@link Integer }
      */
     public void setNumberBatchesInProgress(Integer value) {
         this.numberBatchesInProgress = value;
@@ -408,11 +358,9 @@ public class JobInfo {
 
     /**
      * Gets the value of the numberBatchesCompleted property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Integer }
-     *     
+     *
+     * @return possible object is
+     *         {@link Integer }
      */
     public Integer getNumberBatchesCompleted() {
         return numberBatchesCompleted;
@@ -420,11 +368,9 @@ public class JobInfo {
 
     /**
      * Sets the value of the numberBatchesCompleted property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Integer }
-     *     
+     *
+     * @param value allowed object is
+     *              {@link Integer }
      */
     public void setNumberBatchesCompleted(Integer value) {
         this.numberBatchesCompleted = value;
@@ -432,11 +378,9 @@ public class JobInfo {
 
     /**
      * Gets the value of the numberBatchesFailed property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Integer }
-     *     
+     *
+     * @return possible object is
+     *         {@link Integer }
      */
     public Integer getNumberBatchesFailed() {
         return numberBatchesFailed;
@@ -444,11 +388,9 @@ public class JobInfo {
 
     /**
      * Sets the value of the numberBatchesFailed property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Integer }
-     *     
+     *
+     * @param value allowed object is
+     *              {@link Integer }
      */
     public void setNumberBatchesFailed(Integer value) {
         this.numberBatchesFailed = value;
@@ -456,11 +398,9 @@ public class JobInfo {
 
     /**
      * Gets the value of the numberBatchesTotal property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Integer }
-     *     
+     *
+     * @return possible object is
+     *         {@link Integer }
      */
     public Integer getNumberBatchesTotal() {
         return numberBatchesTotal;
@@ -468,11 +408,9 @@ public class JobInfo {
 
     /**
      * Sets the value of the numberBatchesTotal property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Integer }
-     *     
+     *
+     * @param value allowed object is
+     *              {@link Integer }
      */
     public void setNumberBatchesTotal(Integer value) {
         this.numberBatchesTotal = value;
@@ -480,11 +418,9 @@ public class JobInfo {
 
     /**
      * Gets the value of the numberRecordsProcessed property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Integer }
-     *     
+     *
+     * @return possible object is
+     *         {@link Integer }
      */
     public Integer getNumberRecordsProcessed() {
         return numberRecordsProcessed;
@@ -492,11 +428,9 @@ public class JobInfo {
 
     /**
      * Sets the value of the numberRecordsProcessed property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Integer }
-     *     
+     *
+     * @param value allowed object is
+     *              {@link Integer }
      */
     public void setNumberRecordsProcessed(Integer value) {
         this.numberRecordsProcessed = value;
@@ -504,11 +438,9 @@ public class JobInfo {
 
     /**
      * Gets the value of the numberRetries property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Integer }
-     *     
+     *
+     * @return possible object is
+     *         {@link Integer }
      */
     public Integer getNumberRetries() {
         return numberRetries;
@@ -516,11 +448,9 @@ public class JobInfo {
 
     /**
      * Sets the value of the numberRetries property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Integer }
-     *     
+     *
+     * @param value allowed object is
+     *              {@link Integer }
      */
     public void setNumberRetries(Integer value) {
         this.numberRetries = value;
@@ -528,11 +458,9 @@ public class JobInfo {
 
     /**
      * Gets the value of the apiVersion property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
+     *
+     * @return possible object is
+     *         {@link String }
      */
     public String getApiVersion() {
         return apiVersion;
@@ -540,11 +468,9 @@ public class JobInfo {
 
     /**
      * Sets the value of the apiVersion property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
+     *
+     * @param value allowed object is
+     *              {@link String }
      */
     public void setApiVersion(String value) {
         this.apiVersion = value;
@@ -552,11 +478,9 @@ public class JobInfo {
 
     /**
      * Gets the value of the assignmentRuleId property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
+     *
+     * @return possible object is
+     *         {@link String }
      */
     public String getAssignmentRuleId() {
         return assignmentRuleId;
@@ -564,11 +488,9 @@ public class JobInfo {
 
     /**
      * Sets the value of the assignmentRuleId property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
+     *
+     * @param value allowed object is
+     *              {@link String }
      */
     public void setAssignmentRuleId(String value) {
         this.assignmentRuleId = value;
@@ -576,11 +498,9 @@ public class JobInfo {
 
     /**
      * Gets the value of the numberRecordsFailed property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Integer }
-     *     
+     *
+     * @return possible object is
+     *         {@link Integer }
      */
     public Integer getNumberRecordsFailed() {
         return numberRecordsFailed;
@@ -588,11 +508,9 @@ public class JobInfo {
 
     /**
      * Sets the value of the numberRecordsFailed property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Integer }
-     *     
+     *
+     * @param value allowed object is
+     *              {@link Integer }
      */
     public void setNumberRecordsFailed(Integer value) {
         this.numberRecordsFailed = value;
@@ -600,11 +518,9 @@ public class JobInfo {
 
     /**
      * Gets the value of the totalProcessingTime property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Long }
-     *     
+     *
+     * @return possible object is
+     *         {@link Long }
      */
     public Long getTotalProcessingTime() {
         return totalProcessingTime;
@@ -612,11 +528,9 @@ public class JobInfo {
 
     /**
      * Sets the value of the totalProcessingTime property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Long }
-     *     
+     *
+     * @param value allowed object is
+     *              {@link Long }
      */
     public void setTotalProcessingTime(Long value) {
         this.totalProcessingTime = value;
@@ -624,11 +538,9 @@ public class JobInfo {
 
     /**
      * Gets the value of the apiActiveProcessingTime property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Long }
-     *     
+     *
+     * @return possible object is
+     *         {@link Long }
      */
     public Long getApiActiveProcessingTime() {
         return apiActiveProcessingTime;
@@ -636,11 +548,9 @@ public class JobInfo {
 
     /**
      * Sets the value of the apiActiveProcessingTime property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Long }
-     *     
+     *
+     * @param value allowed object is
+     *              {@link Long }
      */
     public void setApiActiveProcessingTime(Long value) {
         this.apiActiveProcessingTime = value;
@@ -648,11 +558,9 @@ public class JobInfo {
 
     /**
      * Gets the value of the apexProcessingTime property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link Long }
-     *     
+     *
+     * @return possible object is
+     *         {@link Long }
      */
     public Long getApexProcessingTime() {
         return apexProcessingTime;
@@ -660,11 +568,9 @@ public class JobInfo {
 
     /**
      * Sets the value of the apexProcessingTime property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link Long }
-     *     
+     *
+     * @param value allowed object is
+     *              {@link Long }
      */
     public void setApexProcessingTime(Long value) {
         this.apexProcessingTime = value;

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/JobStateEnum.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/JobStateEnum.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/JobStateEnum.java
index 474768c..06ca940 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/JobStateEnum.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/JobStateEnum.java
@@ -23,9 +23,9 @@ import javax.xml.bind.annotation.XmlType;
 
 /**
  * <p>Java class for JobStateEnum.
- * 
+ * <p/>
  * <p>The following schema fragment specifies the expected content contained within this class.
- * <p>
+ * <p/>
  * <pre>
  * &lt;simpleType name="JobStateEnum">
  *   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
@@ -36,7 +36,6 @@ import javax.xml.bind.annotation.XmlType;
  *   &lt;/restriction>
  * &lt;/simpleType>
  * </pre>
- * 
  */
 @XmlType(name = "JobStateEnum")
 @XmlEnum
@@ -61,7 +60,7 @@ public enum JobStateEnum {
     }
 
     public static JobStateEnum fromValue(String v) {
-        for (JobStateEnum c: JobStateEnum.values()) {
+        for (JobStateEnum c : JobStateEnum.values()) {
             if (c.value.equals(v)) {
                 return c;
             }


[09/11] CAMEL-6428: camel-salesforce component. Thanks to Dhiraj Bokde for the contribution.

Posted by da...@apache.org.
http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/JobInfo.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/JobInfo.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/JobInfo.java
new file mode 100644
index 0000000..568138c
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/JobInfo.java
@@ -0,0 +1,673 @@
+/**
+ * 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.bulk;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.datatype.XMLGregorianCalendar;
+
+
+/**
+ * <p>Java class for JobInfo complex type.
+ * 
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * 
+ * <pre>
+ * &lt;complexType name="JobInfo">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="id" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         &lt;element name="operation" type="{http://www.force.com/2009/06/asyncapi/dataload}OperationEnum" minOccurs="0"/>
+ *         &lt;element name="object" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         &lt;element name="createdById" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         &lt;element name="createdDate" type="{http://www.w3.org/2001/XMLSchema}dateTime" minOccurs="0"/>
+ *         &lt;element name="systemModstamp" type="{http://www.w3.org/2001/XMLSchema}dateTime" minOccurs="0"/>
+ *         &lt;element name="state" type="{http://www.force.com/2009/06/asyncapi/dataload}JobStateEnum" minOccurs="0"/>
+ *         &lt;element name="externalIdFieldName" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         &lt;element name="concurrencyMode" type="{http://www.force.com/2009/06/asyncapi/dataload}ConcurrencyModeEnum" minOccurs="0"/>
+ *         &lt;element name="contentType" type="{http://www.force.com/2009/06/asyncapi/dataload}ContentType" minOccurs="0"/>
+ *         &lt;element name="numberBatchesQueued" type="{http://www.w3.org/2001/XMLSchema}int" minOccurs="0"/>
+ *         &lt;element name="numberBatchesInProgress" type="{http://www.w3.org/2001/XMLSchema}int" minOccurs="0"/>
+ *         &lt;element name="numberBatchesCompleted" type="{http://www.w3.org/2001/XMLSchema}int" minOccurs="0"/>
+ *         &lt;element name="numberBatchesFailed" type="{http://www.w3.org/2001/XMLSchema}int" minOccurs="0"/>
+ *         &lt;element name="numberBatchesTotal" type="{http://www.w3.org/2001/XMLSchema}int" minOccurs="0"/>
+ *         &lt;element name="numberRecordsProcessed" type="{http://www.w3.org/2001/XMLSchema}int" minOccurs="0"/>
+ *         &lt;element name="numberRetries" type="{http://www.w3.org/2001/XMLSchema}int" minOccurs="0"/>
+ *         &lt;element name="apiVersion" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         &lt;element name="assignmentRuleId" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         &lt;element name="numberRecordsFailed" type="{http://www.w3.org/2001/XMLSchema}int" minOccurs="0"/>
+ *         &lt;element name="totalProcessingTime" type="{http://www.w3.org/2001/XMLSchema}long" minOccurs="0"/>
+ *         &lt;element name="apiActiveProcessingTime" type="{http://www.w3.org/2001/XMLSchema}long" minOccurs="0"/>
+ *         &lt;element name="apexProcessingTime" type="{http://www.w3.org/2001/XMLSchema}long" minOccurs="0"/>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ * 
+ * 
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "JobInfo", propOrder = {
+    "id",
+    "operation",
+    "object",
+    "createdById",
+    "createdDate",
+    "systemModstamp",
+    "state",
+    "externalIdFieldName",
+    "concurrencyMode",
+    "contentType",
+    "numberBatchesQueued",
+    "numberBatchesInProgress",
+    "numberBatchesCompleted",
+    "numberBatchesFailed",
+    "numberBatchesTotal",
+    "numberRecordsProcessed",
+    "numberRetries",
+    "apiVersion",
+    "assignmentRuleId",
+    "numberRecordsFailed",
+    "totalProcessingTime",
+    "apiActiveProcessingTime",
+    "apexProcessingTime"
+})
+public class JobInfo {
+
+    protected String id;
+    protected OperationEnum operation;
+    protected String object;
+    protected String createdById;
+    @XmlSchemaType(name = "dateTime")
+    protected XMLGregorianCalendar createdDate;
+    @XmlSchemaType(name = "dateTime")
+    protected XMLGregorianCalendar systemModstamp;
+    protected JobStateEnum state;
+    protected String externalIdFieldName;
+    protected ConcurrencyModeEnum concurrencyMode;
+    protected ContentType contentType;
+    protected Integer numberBatchesQueued;
+    protected Integer numberBatchesInProgress;
+    protected Integer numberBatchesCompleted;
+    protected Integer numberBatchesFailed;
+    protected Integer numberBatchesTotal;
+    protected Integer numberRecordsProcessed;
+    protected Integer numberRetries;
+    protected String apiVersion;
+    protected String assignmentRuleId;
+    protected Integer numberRecordsFailed;
+    protected Long totalProcessingTime;
+    protected Long apiActiveProcessingTime;
+    protected Long apexProcessingTime;
+
+    /**
+     * Gets the value of the id property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link String }
+     *     
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Sets the value of the id property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     *     
+     */
+    public void setId(String value) {
+        this.id = value;
+    }
+
+    /**
+     * Gets the value of the operation property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link OperationEnum }
+     *
+     */
+    public OperationEnum getOperation() {
+        return operation;
+    }
+
+    /**
+     * Sets the value of the operation property.
+     *
+     * @param value
+     *     allowed object is
+     *     {@link OperationEnum }
+     *
+     */
+    public void setOperation(OperationEnum value) {
+        this.operation = value;
+    }
+
+    /**
+     * Gets the value of the object property.
+     *
+     * @return
+     *     possible object is
+     *     {@link String }
+     *
+     */
+    public String getObject() {
+        return object;
+    }
+
+    /**
+     * Sets the value of the object property.
+     *
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     *
+     */
+    public void setObject(String value) {
+        this.object = value;
+    }
+
+    /**
+     * Gets the value of the createdById property.
+     *
+     * @return
+     *     possible object is
+     *     {@link String }
+     *
+     */
+    public String getCreatedById() {
+        return createdById;
+    }
+
+    /**
+     * Sets the value of the createdById property.
+     *
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     *
+     */
+    public void setCreatedById(String value) {
+        this.createdById = value;
+    }
+
+    /**
+     * Gets the value of the createdDate property.
+     *
+     * @return
+     *     possible object is
+     *     {@link javax.xml.datatype.XMLGregorianCalendar }
+     *
+     */
+    public XMLGregorianCalendar getCreatedDate() {
+        return createdDate;
+    }
+
+    /**
+     * Sets the value of the createdDate property.
+     *
+     * @param value
+     *     allowed object is
+     *     {@link javax.xml.datatype.XMLGregorianCalendar }
+     *
+     */
+    public void setCreatedDate(XMLGregorianCalendar value) {
+        this.createdDate = value;
+    }
+
+    /**
+     * Gets the value of the systemModstamp property.
+     *
+     * @return
+     *     possible object is
+     *     {@link javax.xml.datatype.XMLGregorianCalendar }
+     *
+     */
+    public XMLGregorianCalendar getSystemModstamp() {
+        return systemModstamp;
+    }
+
+    /**
+     * Sets the value of the systemModstamp property.
+     *
+     * @param value
+     *     allowed object is
+     *     {@link javax.xml.datatype.XMLGregorianCalendar }
+     *
+     */
+    public void setSystemModstamp(XMLGregorianCalendar value) {
+        this.systemModstamp = value;
+    }
+
+    /**
+     * Gets the value of the state property.
+     *
+     * @return
+     *     possible object is
+     *     {@link JobStateEnum }
+     *
+     */
+    public JobStateEnum getState() {
+        return state;
+    }
+
+    /**
+     * Sets the value of the state property.
+     *
+     * @param value
+     *     allowed object is
+     *     {@link JobStateEnum }
+     *
+     */
+    public void setState(JobStateEnum value) {
+        this.state = value;
+    }
+
+    /**
+     * Gets the value of the externalIdFieldName property.
+     *
+     * @return
+     *     possible object is
+     *     {@link String }
+     *
+     */
+    public String getExternalIdFieldName() {
+        return externalIdFieldName;
+    }
+
+    /**
+     * Sets the value of the externalIdFieldName property.
+     *
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     *
+     */
+    public void setExternalIdFieldName(String value) {
+        this.externalIdFieldName = value;
+    }
+
+    /**
+     * Gets the value of the concurrencyMode property.
+     *
+     * @return
+     *     possible object is
+     *     {@link ConcurrencyModeEnum }
+     *
+     */
+    public ConcurrencyModeEnum getConcurrencyMode() {
+        return concurrencyMode;
+    }
+
+    /**
+     * Sets the value of the concurrencyMode property.
+     *
+     * @param value
+     *     allowed object is
+     *     {@link ConcurrencyModeEnum }
+     *
+     */
+    public void setConcurrencyMode(ConcurrencyModeEnum value) {
+        this.concurrencyMode = value;
+    }
+
+    /**
+     * Gets the value of the contentType property.
+     *
+     * @return
+     *     possible object is
+     *     {@link ContentType }
+     *
+     */
+    public ContentType getContentType() {
+        return contentType;
+    }
+
+    /**
+     * Sets the value of the contentType property.
+     *
+     * @param value
+     *     allowed object is
+     *     {@link ContentType }
+     *     
+     */
+    public void setContentType(ContentType value) {
+        this.contentType = value;
+    }
+
+    /**
+     * Gets the value of the numberBatchesQueued property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link Integer }
+     *     
+     */
+    public Integer getNumberBatchesQueued() {
+        return numberBatchesQueued;
+    }
+
+    /**
+     * Sets the value of the numberBatchesQueued property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link Integer }
+     *     
+     */
+    public void setNumberBatchesQueued(Integer value) {
+        this.numberBatchesQueued = value;
+    }
+
+    /**
+     * Gets the value of the numberBatchesInProgress property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link Integer }
+     *     
+     */
+    public Integer getNumberBatchesInProgress() {
+        return numberBatchesInProgress;
+    }
+
+    /**
+     * Sets the value of the numberBatchesInProgress property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link Integer }
+     *     
+     */
+    public void setNumberBatchesInProgress(Integer value) {
+        this.numberBatchesInProgress = value;
+    }
+
+    /**
+     * Gets the value of the numberBatchesCompleted property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link Integer }
+     *     
+     */
+    public Integer getNumberBatchesCompleted() {
+        return numberBatchesCompleted;
+    }
+
+    /**
+     * Sets the value of the numberBatchesCompleted property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link Integer }
+     *     
+     */
+    public void setNumberBatchesCompleted(Integer value) {
+        this.numberBatchesCompleted = value;
+    }
+
+    /**
+     * Gets the value of the numberBatchesFailed property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link Integer }
+     *     
+     */
+    public Integer getNumberBatchesFailed() {
+        return numberBatchesFailed;
+    }
+
+    /**
+     * Sets the value of the numberBatchesFailed property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link Integer }
+     *     
+     */
+    public void setNumberBatchesFailed(Integer value) {
+        this.numberBatchesFailed = value;
+    }
+
+    /**
+     * Gets the value of the numberBatchesTotal property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link Integer }
+     *     
+     */
+    public Integer getNumberBatchesTotal() {
+        return numberBatchesTotal;
+    }
+
+    /**
+     * Sets the value of the numberBatchesTotal property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link Integer }
+     *     
+     */
+    public void setNumberBatchesTotal(Integer value) {
+        this.numberBatchesTotal = value;
+    }
+
+    /**
+     * Gets the value of the numberRecordsProcessed property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link Integer }
+     *     
+     */
+    public Integer getNumberRecordsProcessed() {
+        return numberRecordsProcessed;
+    }
+
+    /**
+     * Sets the value of the numberRecordsProcessed property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link Integer }
+     *     
+     */
+    public void setNumberRecordsProcessed(Integer value) {
+        this.numberRecordsProcessed = value;
+    }
+
+    /**
+     * Gets the value of the numberRetries property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link Integer }
+     *     
+     */
+    public Integer getNumberRetries() {
+        return numberRetries;
+    }
+
+    /**
+     * Sets the value of the numberRetries property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link Integer }
+     *     
+     */
+    public void setNumberRetries(Integer value) {
+        this.numberRetries = value;
+    }
+
+    /**
+     * Gets the value of the apiVersion property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link String }
+     *     
+     */
+    public String getApiVersion() {
+        return apiVersion;
+    }
+
+    /**
+     * Sets the value of the apiVersion property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     *     
+     */
+    public void setApiVersion(String value) {
+        this.apiVersion = value;
+    }
+
+    /**
+     * Gets the value of the assignmentRuleId property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link String }
+     *     
+     */
+    public String getAssignmentRuleId() {
+        return assignmentRuleId;
+    }
+
+    /**
+     * Sets the value of the assignmentRuleId property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     *     
+     */
+    public void setAssignmentRuleId(String value) {
+        this.assignmentRuleId = value;
+    }
+
+    /**
+     * Gets the value of the numberRecordsFailed property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link Integer }
+     *     
+     */
+    public Integer getNumberRecordsFailed() {
+        return numberRecordsFailed;
+    }
+
+    /**
+     * Sets the value of the numberRecordsFailed property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link Integer }
+     *     
+     */
+    public void setNumberRecordsFailed(Integer value) {
+        this.numberRecordsFailed = value;
+    }
+
+    /**
+     * Gets the value of the totalProcessingTime property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link Long }
+     *     
+     */
+    public Long getTotalProcessingTime() {
+        return totalProcessingTime;
+    }
+
+    /**
+     * Sets the value of the totalProcessingTime property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link Long }
+     *     
+     */
+    public void setTotalProcessingTime(Long value) {
+        this.totalProcessingTime = value;
+    }
+
+    /**
+     * Gets the value of the apiActiveProcessingTime property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link Long }
+     *     
+     */
+    public Long getApiActiveProcessingTime() {
+        return apiActiveProcessingTime;
+    }
+
+    /**
+     * Sets the value of the apiActiveProcessingTime property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link Long }
+     *     
+     */
+    public void setApiActiveProcessingTime(Long value) {
+        this.apiActiveProcessingTime = value;
+    }
+
+    /**
+     * Gets the value of the apexProcessingTime property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link Long }
+     *     
+     */
+    public Long getApexProcessingTime() {
+        return apexProcessingTime;
+    }
+
+    /**
+     * Sets the value of the apexProcessingTime property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link Long }
+     *     
+     */
+    public void setApexProcessingTime(Long value) {
+        this.apexProcessingTime = value;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/JobStateEnum.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/JobStateEnum.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/JobStateEnum.java
new file mode 100644
index 0000000..474768c
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/JobStateEnum.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.bulk;
+
+import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlEnumValue;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for JobStateEnum.
+ * 
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * <pre>
+ * &lt;simpleType name="JobStateEnum">
+ *   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
+ *     &lt;enumeration value="Open"/>
+ *     &lt;enumeration value="Closed"/>
+ *     &lt;enumeration value="Aborted"/>
+ *     &lt;enumeration value="Failed"/>
+ *   &lt;/restriction>
+ * &lt;/simpleType>
+ * </pre>
+ * 
+ */
+@XmlType(name = "JobStateEnum")
+@XmlEnum
+public enum JobStateEnum {
+
+    @XmlEnumValue("Open")
+    OPEN("Open"),
+    @XmlEnumValue("Closed")
+    CLOSED("Closed"),
+    @XmlEnumValue("Aborted")
+    ABORTED("Aborted"),
+    @XmlEnumValue("Failed")
+    FAILED("Failed");
+    private final String value;
+
+    JobStateEnum(String v) {
+        value = v;
+    }
+
+    public String value() {
+        return value;
+    }
+
+    public static JobStateEnum fromValue(String v) {
+        for (JobStateEnum c: JobStateEnum.values()) {
+            if (c.value.equals(v)) {
+                return c;
+            }
+        }
+        throw new IllegalArgumentException(v);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ObjectFactory.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ObjectFactory.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ObjectFactory.java
new file mode 100644
index 0000000..dc476ac
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ObjectFactory.java
@@ -0,0 +1,200 @@
+/**
+ * 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.bulk;
+
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.annotation.XmlElementDecl;
+import javax.xml.bind.annotation.XmlRegistry;
+import javax.xml.namespace.QName;
+
+
+/**
+ * This object contains factory methods for each 
+ * Java content interface and Java element interface 
+ * in the org.apache.camel.component.salesforce.api.dto.bulk package.
+ * <p>An ObjectFactory allows you to programatically 
+ * construct new instances of the Java representation 
+ * for XML content. The Java representation of XML 
+ * content can consist of schema derived interfaces 
+ * and classes representing the binding of schema 
+ * type definitions, element declarations and model 
+ * groups.  Factory methods for each of these are 
+ * provided in this class.
+ * 
+ */
+@XmlRegistry
+public class ObjectFactory {
+
+    private final static QName _JobInfo_QNAME = new QName("http://www.force.com/2009/06/asyncapi/dataload", "jobInfo");
+    private final static QName _BatchInfo_QNAME = new QName("http://www.force.com/2009/06/asyncapi/dataload", "batchInfo");
+    private final static QName _Error_QNAME = new QName("http://www.force.com/2009/06/asyncapi/dataload", "error");
+    private final static QName _Results_QNAME = new QName("http://www.force.com/2009/06/asyncapi/dataload", "results");
+    private final static QName _ResultList_QNAME = new QName("http://www.force.com/2009/06/asyncapi/dataload", "result-list");
+    private final static QName _BatchInfoList_QNAME = new QName("http://www.force.com/2009/06/asyncapi/dataload", "batchInfoList");
+    private final static QName _QueryResult_QNAME = new QName("http://www.force.com/2009/06/asyncapi/dataload", "queryResult");
+
+    /**
+     * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: org.apache.camel.component.salesforce.api.dto.bulk
+     * 
+     */
+    public ObjectFactory() {
+    }
+
+    /**
+     * Create an instance of {@link SObject }
+     *
+     */
+    public SObject createSObject() {
+        return new SObject();
+    }
+
+    /**
+     * Create an instance of {@link ResultError }
+     *
+     */
+    public ResultError createResultError() {
+        return new ResultError();
+    }
+
+    /**
+     * Create an instance of {@link BatchInfo }
+     *
+     */
+    public BatchInfo createBatchInfo() {
+        return new BatchInfo();
+    }
+
+    /**
+     * Create an instance of {@link BatchResult }
+     *
+     */
+    public BatchResult createBatchResult() {
+        return new BatchResult();
+    }
+
+    /**
+     * Create an instance of {@link QueryResultList }
+     *
+     */
+    public QueryResultList createQueryResultList() {
+        return new QueryResultList();
+    }
+
+    /**
+     * Create an instance of {@link Error }
+     *
+     */
+    public Error createError() {
+        return new Error();
+    }
+
+    /**
+     * Create an instance of {@link BatchInfoList }
+     *
+     */
+    public BatchInfoList createBatchInfoList() {
+        return new BatchInfoList();
+    }
+
+    /**
+     * Create an instance of {@link Result }
+     *
+     */
+    public Result createResult() {
+        return new Result();
+    }
+
+    /**
+     * Create an instance of {@link JobInfo }
+     *
+     */
+    public JobInfo createJobInfo() {
+        return new JobInfo();
+    }
+
+    /**
+     * Create an instance of {@link QueryResult }
+     *
+     */
+    public QueryResult createQueryResult() {
+        return new QueryResult();
+    }
+
+    /**
+     * Create an instance of {@link javax.xml.bind.JAXBElement }{@code <}{@link JobInfo }{@code >}}
+     *
+     */
+    @XmlElementDecl(namespace = "http://www.force.com/2009/06/asyncapi/dataload", name = "jobInfo")
+    public JAXBElement<JobInfo> createJobInfo(JobInfo value) {
+        return new JAXBElement<JobInfo>(_JobInfo_QNAME, JobInfo.class, null, value);
+    }
+
+    /**
+     * Create an instance of {@link javax.xml.bind.JAXBElement }{@code <}{@link BatchInfo }{@code >}}
+     *
+     */
+    @XmlElementDecl(namespace = "http://www.force.com/2009/06/asyncapi/dataload", name = "batchInfo")
+    public JAXBElement<BatchInfo> createBatchInfo(BatchInfo value) {
+        return new JAXBElement<BatchInfo>(_BatchInfo_QNAME, BatchInfo.class, null, value);
+    }
+
+    /**
+     * Create an instance of {@link javax.xml.bind.JAXBElement }{@code <}{@link Error }{@code >}}
+     *
+     */
+    @XmlElementDecl(namespace = "http://www.force.com/2009/06/asyncapi/dataload", name = "error")
+    public JAXBElement<Error> createError(Error value) {
+        return new JAXBElement<Error>(_Error_QNAME, Error.class, null, value);
+    }
+
+    /**
+     * Create an instance of {@link javax.xml.bind.JAXBElement }{@code <}{@link BatchResult }{@code >}}
+     *
+     */
+    @XmlElementDecl(namespace = "http://www.force.com/2009/06/asyncapi/dataload", name = "results")
+    public JAXBElement<BatchResult> createResults(BatchResult value) {
+        return new JAXBElement<BatchResult>(_Results_QNAME, BatchResult.class, null, value);
+    }
+
+    /**
+     * Create an instance of {@link javax.xml.bind.JAXBElement }{@code <}{@link QueryResultList }{@code >}}
+     *
+     */
+    @XmlElementDecl(namespace = "http://www.force.com/2009/06/asyncapi/dataload", name = "result-list")
+    public JAXBElement<QueryResultList> createResultList(QueryResultList value) {
+        return new JAXBElement<QueryResultList>(_ResultList_QNAME, QueryResultList.class, null, value);
+    }
+
+    /**
+     * Create an instance of {@link javax.xml.bind.JAXBElement }{@code <}{@link BatchInfoList }{@code >}}
+     *
+     */
+    @XmlElementDecl(namespace = "http://www.force.com/2009/06/asyncapi/dataload", name = "batchInfoList")
+    public JAXBElement<BatchInfoList> createBatchInfoList(BatchInfoList value) {
+        return new JAXBElement<BatchInfoList>(_BatchInfoList_QNAME, BatchInfoList.class, null, value);
+    }
+
+    /**
+     * Create an instance of {@link javax.xml.bind.JAXBElement }{@code <}{@link QueryResult }{@code >}}
+     * 
+     */
+    @XmlElementDecl(namespace = "http://www.force.com/2009/06/asyncapi/dataload", name = "queryResult")
+    public JAXBElement<QueryResult> createQueryResult(QueryResult value) {
+        return new JAXBElement<QueryResult>(_QueryResult_QNAME, QueryResult.class, null, value);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/OperationEnum.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/OperationEnum.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/OperationEnum.java
new file mode 100644
index 0000000..3f25e66
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/OperationEnum.java
@@ -0,0 +1,78 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.salesforce.api.dto.bulk;
+
+import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlEnumValue;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for OperationEnum.
+ * 
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * <pre>
+ * &lt;simpleType name="OperationEnum">
+ *   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
+ *     &lt;enumeration value="insert"/>
+ *     &lt;enumeration value="upsert"/>
+ *     &lt;enumeration value="update"/>
+ *     &lt;enumeration value="delete"/>
+ *     &lt;enumeration value="hardDelete"/>
+ *     &lt;enumeration value="query"/>
+ *   &lt;/restriction>
+ * &lt;/simpleType>
+ * </pre>
+ * 
+ */
+@XmlType(name = "OperationEnum")
+@XmlEnum
+public enum OperationEnum {
+
+    @XmlEnumValue("insert")
+    INSERT("insert"),
+    @XmlEnumValue("upsert")
+    UPSERT("upsert"),
+    @XmlEnumValue("update")
+    UPDATE("update"),
+    @XmlEnumValue("delete")
+    DELETE("delete"),
+    @XmlEnumValue("hardDelete")
+    HARD_DELETE("hardDelete"),
+    @XmlEnumValue("query")
+    QUERY("query");
+    private final String value;
+
+    OperationEnum(String v) {
+        value = v;
+    }
+
+    public String value() {
+        return value;
+    }
+
+    public static OperationEnum fromValue(String v) {
+        for (OperationEnum c: OperationEnum.values()) {
+            if (c.value.equals(v)) {
+                return c;
+            }
+        }
+        throw new IllegalArgumentException(v);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/QueryResult.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/QueryResult.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/QueryResult.java
new file mode 100644
index 0000000..702d993
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/QueryResult.java
@@ -0,0 +1,84 @@
+/**
+ * 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.bulk;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * <p>Java class for QueryResult complex type.
+ * 
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * 
+ * <pre>
+ * &lt;complexType name="QueryResult">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="records" type="{http://www.force.com/2009/06/asyncapi/dataload}sObject" maxOccurs="unbounded" minOccurs="0"/>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ * 
+ * 
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "QueryResult", propOrder = {
+    "records"
+})
+public class QueryResult {
+
+    @XmlElement(nillable = true)
+    protected List<SObject> records;
+
+    /**
+     * Gets the value of the records property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list,
+     * not a snapshot. Therefore any modification you make to the
+     * returned list will be present inside the JAXB object.
+     * This is why there is not a <CODE>set</CODE> method for the records property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
+     * <pre>
+     *    getRecords().add(newItem);
+     * </pre>
+     * 
+     * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link SObject }
+     * 
+     * 
+     */
+    public List<SObject> getRecords() {
+        if (records == null) {
+            records = new ArrayList<SObject>();
+        }
+        return this.records;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/QueryResultList.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/QueryResultList.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/QueryResultList.java
new file mode 100644
index 0000000..6dbda5a
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/QueryResultList.java
@@ -0,0 +1,82 @@
+/**
+ * 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.bulk;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlType;
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * <p>Java class for QueryResultList complex type.
+ * 
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * 
+ * <pre>
+ * &lt;complexType name="QueryResultList">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="result" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ * 
+ * 
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "QueryResultList", propOrder = {
+    "result"
+})
+public class QueryResultList {
+
+    protected List<String> result;
+
+    /**
+     * Gets the value of the result property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list,
+     * not a snapshot. Therefore any modification you make to the
+     * returned list will be present inside the JAXB object.
+     * This is why there is not a <CODE>set</CODE> method for the result property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
+     * <pre>
+     *    getResult().add(newItem);
+     * </pre>
+     * 
+     * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link String }
+     * 
+     * 
+     */
+    public List<String> getResult() {
+        if (result == null) {
+            result = new ArrayList<String>();
+        }
+        return this.result;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/Result.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/Result.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/Result.java
new file mode 100644
index 0000000..c36d9aa
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/Result.java
@@ -0,0 +1,147 @@
+/**
+ * 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.bulk;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlType;
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * <p>Java class for Result complex type.
+ * 
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * 
+ * <pre>
+ * &lt;complexType name="Result">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="errors" type="{http://www.force.com/2009/06/asyncapi/dataload}ResultError" maxOccurs="unbounded" minOccurs="0"/>
+ *         &lt;element name="id" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         &lt;element name="success" type="{http://www.w3.org/2001/XMLSchema}boolean"/>
+ *         &lt;element name="created" type="{http://www.w3.org/2001/XMLSchema}boolean"/>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ * 
+ * 
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "Result", propOrder = {
+    "errors",
+    "id",
+    "success",
+    "created"
+})
+public class Result {
+
+    protected List<ResultError> errors;
+    protected String id;
+    protected boolean success;
+    protected boolean created;
+
+    /**
+     * Gets the value of the errors property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list,
+     * not a snapshot. Therefore any modification you make to the
+     * returned list will be present inside the JAXB object.
+     * This is why there is not a <CODE>set</CODE> method for the errors property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
+     * <pre>
+     *    getErrors().add(newItem);
+     * </pre>
+     * 
+     * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link ResultError }
+     * 
+     * 
+     */
+    public List<ResultError> getErrors() {
+        if (errors == null) {
+            errors = new ArrayList<ResultError>();
+        }
+        return this.errors;
+    }
+
+    /**
+     * Gets the value of the id property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link String }
+     *     
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Sets the value of the id property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     *     
+     */
+    public void setId(String value) {
+        this.id = value;
+    }
+
+    /**
+     * Gets the value of the success property.
+     * 
+     */
+    public boolean isSuccess() {
+        return success;
+    }
+
+    /**
+     * Sets the value of the success property.
+     * 
+     */
+    public void setSuccess(boolean value) {
+        this.success = value;
+    }
+
+    /**
+     * Gets the value of the created property.
+     * 
+     */
+    public boolean isCreated() {
+        return created;
+    }
+
+    /**
+     * Sets the value of the created property.
+     * 
+     */
+    public void setCreated(boolean value) {
+        this.created = value;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ResultError.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ResultError.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ResultError.java
new file mode 100644
index 0000000..fabccab
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ResultError.java
@@ -0,0 +1,140 @@
+/**
+ * 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.bulk;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * <p>Java class for ResultError complex type.
+ * 
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * 
+ * <pre>
+ * &lt;complexType name="ResultError">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="fields" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
+ *         &lt;element name="message" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         &lt;element name="statusCode" type="{http://www.force.com/2009/06/asyncapi/dataload}StatusCode"/>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ * 
+ * 
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "ResultError", propOrder = {
+    "fields",
+    "message",
+    "statusCode"
+})
+public class ResultError {
+
+    @XmlElement(nillable = true)
+    protected List<String> fields;
+    @XmlElement(required = true)
+    protected String message;
+    @XmlElement(required = true)
+    protected StatusCode statusCode;
+
+    /**
+     * Gets the value of the fields property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list,
+     * not a snapshot. Therefore any modification you make to the
+     * returned list will be present inside the JAXB object.
+     * This is why there is not a <CODE>set</CODE> method for the fields property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
+     * <pre>
+     *    getFields().add(newItem);
+     * </pre>
+     * 
+     * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link String }
+     * 
+     * 
+     */
+    public List<String> getFields() {
+        if (fields == null) {
+            fields = new ArrayList<String>();
+        }
+        return this.fields;
+    }
+
+    /**
+     * Gets the value of the message property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link String }
+     *     
+     */
+    public String getMessage() {
+        return message;
+    }
+
+    /**
+     * Sets the value of the message property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     *     
+     */
+    public void setMessage(String value) {
+        this.message = value;
+    }
+
+    /**
+     * Gets the value of the statusCode property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link StatusCode }
+     *
+     */
+    public StatusCode getStatusCode() {
+        return statusCode;
+    }
+
+    /**
+     * Sets the value of the statusCode property.
+     *
+     * @param value
+     *     allowed object is
+     *     {@link StatusCode }
+     *     
+     */
+    public void setStatusCode(StatusCode value) {
+        this.statusCode = value;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/SObject.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/SObject.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/SObject.java
new file mode 100644
index 0000000..aa9c2c5
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/SObject.java
@@ -0,0 +1,138 @@
+/**
+ * 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.bulk;
+
+import javax.xml.bind.annotation.*;
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * <p>Java class for sObject complex type.
+ * 
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * 
+ * <pre>
+ * &lt;complexType name="sObject">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="type" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         &lt;element name="Id" type="{http://www.force.com/2009/06/asyncapi/dataload}ID"/>
+ *         &lt;any processContents='lax' namespace='http://www.force.com/2009/06/asyncapi/dataload' maxOccurs="unbounded" minOccurs="0"/>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ * 
+ * 
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "sObject", propOrder = {
+    "type",
+    "id",
+    "any"
+})
+public class SObject {
+
+    @XmlElement(required = true)
+    protected String type;
+    @XmlElement(name = "Id", required = true, nillable = true)
+    protected String id;
+    @XmlAnyElement(lax = true)
+    protected List<Object> any;
+
+    /**
+     * Gets the value of the type property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link String }
+     *     
+     */
+    public String getType() {
+        return type;
+    }
+
+    /**
+     * Sets the value of the type property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     *     
+     */
+    public void setType(String value) {
+        this.type = value;
+    }
+
+    /**
+     * Gets the value of the id property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link String }
+     *     
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Sets the value of the id property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     *     
+     */
+    public void setId(String value) {
+        this.id = value;
+    }
+
+    /**
+     * Gets the value of the any property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list,
+     * not a snapshot. Therefore any modification you make to the
+     * returned list will be present inside the JAXB object.
+     * This is why there is not a <CODE>set</CODE> method for the any property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
+     * <pre>
+     *    getAny().add(newItem);
+     * </pre>
+     * 
+     * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link Object }
+     * {@link org.w3c.dom.Element }
+     * 
+     * 
+     */
+    public List<Object> getAny() {
+        if (any == null) {
+            any = new ArrayList<Object>();
+        }
+        return this.any;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/StatusCode.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/StatusCode.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/StatusCode.java
new file mode 100644
index 0000000..d4e3493
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/StatusCode.java
@@ -0,0 +1,395 @@
+/**
+ * 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.bulk;
+
+import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for StatusCode.
+ * 
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * <pre>
+ * &lt;simpleType name="StatusCode">
+ *   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
+ *     &lt;enumeration value="ALL_OR_NONE_OPERATION_ROLLED_BACK"/>
+ *     &lt;enumeration value="ALREADY_IN_PROCESS"/>
+ *     &lt;enumeration value="ASSIGNEE_TYPE_REQUIRED"/>
+ *     &lt;enumeration value="BAD_CUSTOM_ENTITY_PARENT_DOMAIN"/>
+ *     &lt;enumeration value="BCC_NOT_ALLOWED_IF_BCC_COMPLIANCE_ENABLED"/>
+ *     &lt;enumeration value="CANNOT_CASCADE_PRODUCT_ACTIVE"/>
+ *     &lt;enumeration value="CANNOT_CHANGE_FIELD_TYPE_OF_APEX_REFERENCED_FIELD"/>
+ *     &lt;enumeration value="CANNOT_CREATE_ANOTHER_MANAGED_PACKAGE"/>
+ *     &lt;enumeration value="CANNOT_DEACTIVATE_DIVISION"/>
+ *     &lt;enumeration value="CANNOT_DELETE_LAST_DATED_CONVERSION_RATE"/>
+ *     &lt;enumeration value="CANNOT_DELETE_MANAGED_OBJECT"/>
+ *     &lt;enumeration value="CANNOT_DISABLE_LAST_ADMIN"/>
+ *     &lt;enumeration value="CANNOT_ENABLE_IP_RESTRICT_REQUESTS"/>
+ *     &lt;enumeration value="CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY"/>
+ *     &lt;enumeration value="CANNOT_MODIFY_MANAGED_OBJECT"/>
+ *     &lt;enumeration value="CANNOT_RENAME_APEX_REFERENCED_FIELD"/>
+ *     &lt;enumeration value="CANNOT_RENAME_APEX_REFERENCED_OBJECT"/>
+ *     &lt;enumeration value="CANNOT_REPARENT_RECORD"/>
+ *     &lt;enumeration value="CANNOT_UPDATE_CONVERTED_LEAD"/>
+ *     &lt;enumeration value="CANT_DISABLE_CORP_CURRENCY"/>
+ *     &lt;enumeration value="CANT_UNSET_CORP_CURRENCY"/>
+ *     &lt;enumeration value="CHILD_SHARE_FAILS_PARENT"/>
+ *     &lt;enumeration value="CIRCULAR_DEPENDENCY"/>
+ *     &lt;enumeration value="COMMUNITY_NOT_ACCESSIBLE"/>
+ *     &lt;enumeration value="CUSTOM_CLOB_FIELD_LIMIT_EXCEEDED"/>
+ *     &lt;enumeration value="CUSTOM_ENTITY_OR_FIELD_LIMIT"/>
+ *     &lt;enumeration value="CUSTOM_FIELD_INDEX_LIMIT_EXCEEDED"/>
+ *     &lt;enumeration value="CUSTOM_INDEX_EXISTS"/>
+ *     &lt;enumeration value="CUSTOM_LINK_LIMIT_EXCEEDED"/>
+ *     &lt;enumeration value="CUSTOM_TAB_LIMIT_EXCEEDED"/>
+ *     &lt;enumeration value="DELETE_FAILED"/>
+ *     &lt;enumeration value="DELETE_OPERATION_TOO_LARGE"/>
+ *     &lt;enumeration value="DELETE_REQUIRED_ON_CASCADE"/>
+ *     &lt;enumeration value="DEPENDENCY_EXISTS"/>
+ *     &lt;enumeration value="DUPLICATE_CASE_SOLUTION"/>
+ *     &lt;enumeration value="DUPLICATE_COMM_NICKNAME"/>
+ *     &lt;enumeration value="DUPLICATE_CUSTOM_ENTITY_DEFINITION"/>
+ *     &lt;enumeration value="DUPLICATE_CUSTOM_TAB_MOTIF"/>
+ *     &lt;enumeration value="DUPLICATE_DEVELOPER_NAME"/>
+ *     &lt;enumeration value="DUPLICATE_EXTERNAL_ID"/>
+ *     &lt;enumeration value="DUPLICATE_MASTER_LABEL"/>
+ *     &lt;enumeration value="DUPLICATE_SENDER_DISPLAY_NAME"/>
+ *     &lt;enumeration value="DUPLICATE_USERNAME"/>
+ *     &lt;enumeration value="DUPLICATE_VALUE"/>
+ *     &lt;enumeration value="EMAIL_NOT_PROCESSED_DUE_TO_PRIOR_ERROR"/>
+ *     &lt;enumeration value="EMPTY_SCONTROL_FILE_NAME"/>
+ *     &lt;enumeration value="ENTITY_FAILED_IFLASTMODIFIED_ON_UPDATE"/>
+ *     &lt;enumeration value="ENTITY_IS_ARCHIVED"/>
+ *     &lt;enumeration value="ENTITY_IS_DELETED"/>
+ *     &lt;enumeration value="ENTITY_IS_LOCKED"/>
+ *     &lt;enumeration value="ERROR_IN_MAILER"/>
+ *     &lt;enumeration value="EXTERNAL_OBJECT_AUTHENTICATION_EXCEPTION"/>
+ *     &lt;enumeration value="EXTERNAL_OBJECT_CONNECTION_EXCEPTION"/>
+ *     &lt;enumeration value="EXTERNAL_OBJECT_EXCEPTION"/>
+ *     &lt;enumeration value="EXTERNAL_OBJECT_UNSUPPORTED_EXCEPTION"/>
+ *     &lt;enumeration value="FAILED_ACTIVATION"/>
+ *     &lt;enumeration value="FIELD_CUSTOM_VALIDATION_EXCEPTION"/>
+ *     &lt;enumeration value="FIELD_FILTER_VALIDATION_EXCEPTION"/>
+ *     &lt;enumeration value="FIELD_INTEGRITY_EXCEPTION"/>
+ *     &lt;enumeration value="FILTERED_LOOKUP_LIMIT_EXCEEDED"/>
+ *     &lt;enumeration value="HTML_FILE_UPLOAD_NOT_ALLOWED"/>
+ *     &lt;enumeration value="IMAGE_TOO_LARGE"/>
+ *     &lt;enumeration value="INACTIVE_OWNER_OR_USER"/>
+ *     &lt;enumeration value="INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY"/>
+ *     &lt;enumeration value="INSUFFICIENT_ACCESS_OR_READONLY"/>
+ *     &lt;enumeration value="INVALID_ACCESS_LEVEL"/>
+ *     &lt;enumeration value="INVALID_ARGUMENT_TYPE"/>
+ *     &lt;enumeration value="INVALID_ASSIGNEE_TYPE"/>
+ *     &lt;enumeration value="INVALID_ASSIGNMENT_RULE"/>
+ *     &lt;enumeration value="INVALID_BATCH_OPERATION"/>
+ *     &lt;enumeration value="INVALID_CONTENT_TYPE"/>
+ *     &lt;enumeration value="INVALID_CREDIT_CARD_INFO"/>
+ *     &lt;enumeration value="INVALID_CROSS_REFERENCE_KEY"/>
+ *     &lt;enumeration value="INVALID_CROSS_REFERENCE_TYPE_FOR_FIELD"/>
+ *     &lt;enumeration value="INVALID_CURRENCY_CONV_RATE"/>
+ *     &lt;enumeration value="INVALID_CURRENCY_CORP_RATE"/>
+ *     &lt;enumeration value="INVALID_CURRENCY_ISO"/>
+ *     &lt;enumeration value="INVALID_DATA_CATEGORY_GROUP_REFERENCE"/>
+ *     &lt;enumeration value="INVALID_DATA_URI"/>
+ *     &lt;enumeration value="INVALID_EMAIL_ADDRESS"/>
+ *     &lt;enumeration value="INVALID_EMPTY_KEY_OWNER"/>
+ *     &lt;enumeration value="INVALID_FIELD"/>
+ *     &lt;enumeration value="INVALID_FIELD_FOR_INSERT_UPDATE"/>
+ *     &lt;enumeration value="INVALID_FIELD_WHEN_USING_TEMPLATE"/>
+ *     &lt;enumeration value="INVALID_FILTER_ACTION"/>
+ *     &lt;enumeration value="INVALID_GOOGLE_DOCS_URL"/>
+ *     &lt;enumeration value="INVALID_ID_FIELD"/>
+ *     &lt;enumeration value="INVALID_INET_ADDRESS"/>
+ *     &lt;enumeration value="INVALID_LINEITEM_CLONE_STATE"/>
+ *     &lt;enumeration value="INVALID_MASTER_OR_TRANSLATED_SOLUTION"/>
+ *     &lt;enumeration value="INVALID_MESSAGE_ID_REFERENCE"/>
+ *     &lt;enumeration value="INVALID_OPERATION"/>
+ *     &lt;enumeration value="INVALID_OPERATOR"/>
+ *     &lt;enumeration value="INVALID_OR_NULL_FOR_RESTRICTED_PICKLIST"/>
+ *     &lt;enumeration value="INVALID_PACKAGE_VERSION"/>
+ *     &lt;enumeration value="INVALID_PARTNER_NETWORK_STATUS"/>
+ *     &lt;enumeration value="INVALID_PERSON_ACCOUNT_OPERATION"/>
+ *     &lt;enumeration value="INVALID_QUERY_LOCATOR"/>
+ *     &lt;enumeration value="INVALID_READ_ONLY_USER_DML"/>
+ *     &lt;enumeration value="INVALID_SAVE_AS_ACTIVITY_FLAG"/>
+ *     &lt;enumeration value="INVALID_SESSION_ID"/>
+ *     &lt;enumeration value="INVALID_SETUP_OWNER"/>
+ *     &lt;enumeration value="INVALID_STATUS"/>
+ *     &lt;enumeration value="INVALID_TYPE"/>
+ *     &lt;enumeration value="INVALID_TYPE_FOR_OPERATION"/>
+ *     &lt;enumeration value="INVALID_TYPE_ON_FIELD_IN_RECORD"/>
+ *     &lt;enumeration value="IP_RANGE_LIMIT_EXCEEDED"/>
+ *     &lt;enumeration value="LICENSE_LIMIT_EXCEEDED"/>
+ *     &lt;enumeration value="LIGHT_PORTAL_USER_EXCEPTION"/>
+ *     &lt;enumeration value="LIMIT_EXCEEDED"/>
+ *     &lt;enumeration value="MALFORMED_ID"/>
+ *     &lt;enumeration value="MANAGER_NOT_DEFINED"/>
+ *     &lt;enumeration value="MASSMAIL_RETRY_LIMIT_EXCEEDED"/>
+ *     &lt;enumeration value="MASS_MAIL_LIMIT_EXCEEDED"/>
+ *     &lt;enumeration value="MAXIMUM_CCEMAILS_EXCEEDED"/>
+ *     &lt;enumeration value="MAXIMUM_DASHBOARD_COMPONENTS_EXCEEDED"/>
+ *     &lt;enumeration value="MAXIMUM_HIERARCHY_LEVELS_REACHED"/>
+ *     &lt;enumeration value="MAXIMUM_SIZE_OF_ATTACHMENT"/>
+ *     &lt;enumeration value="MAXIMUM_SIZE_OF_DOCUMENT"/>
+ *     &lt;enumeration value="MAX_ACTIONS_PER_RULE_EXCEEDED"/>
+ *     &lt;enumeration value="MAX_ACTIVE_RULES_EXCEEDED"/>
+ *     &lt;enumeration value="MAX_APPROVAL_STEPS_EXCEEDED"/>
+ *     &lt;enumeration value="MAX_FORMULAS_PER_RULE_EXCEEDED"/>
+ *     &lt;enumeration value="MAX_RULES_EXCEEDED"/>
+ *     &lt;enumeration value="MAX_RULE_ENTRIES_EXCEEDED"/>
+ *     &lt;enumeration value="MAX_TASK_DESCRIPTION_EXCEEEDED"/>
+ *     &lt;enumeration value="MAX_TM_RULES_EXCEEDED"/>
+ *     &lt;enumeration value="MAX_TM_RULE_ITEMS_EXCEEDED"/>
+ *     &lt;enumeration value="MERGE_FAILED"/>
+ *     &lt;enumeration value="MISSING_ARGUMENT"/>
+ *     &lt;enumeration value="MIXED_DML_OPERATION"/>
+ *     &lt;enumeration value="NONUNIQUE_SHIPPING_ADDRESS"/>
+ *     &lt;enumeration value="NO_APPLICABLE_PROCESS"/>
+ *     &lt;enumeration value="NO_ATTACHMENT_PERMISSION"/>
+ *     &lt;enumeration value="NO_INACTIVE_DIVISION_MEMBERS"/>
+ *     &lt;enumeration value="NO_MASS_MAIL_PERMISSION"/>
+ *     &lt;enumeration value="NUMBER_OUTSIDE_VALID_RANGE"/>
+ *     &lt;enumeration value="NUM_HISTORY_FIELDS_BY_SOBJECT_EXCEEDED"/>
+ *     &lt;enumeration value="OPTED_OUT_OF_MASS_MAIL"/>
+ *     &lt;enumeration value="OP_WITH_INVALID_USER_TYPE_EXCEPTION"/>
+ *     &lt;enumeration value="PACKAGE_LICENSE_REQUIRED"/>
+ *     &lt;enumeration value="PORTAL_NO_ACCESS"/>
+ *     &lt;enumeration value="PORTAL_USER_ALREADY_EXISTS_FOR_CONTACT"/>
+ *     &lt;enumeration value="PRIVATE_CONTACT_ON_ASSET"/>
+ *     &lt;enumeration value="QUERY_TIMEOUT"/>
+ *     &lt;enumeration value="RECORD_IN_USE_BY_WORKFLOW"/>
+ *     &lt;enumeration value="REQUEST_RUNNING_TOO_LONG"/>
+ *     &lt;enumeration value="REQUIRED_FEATURE_MISSING"/>
+ *     &lt;enumeration value="REQUIRED_FIELD_MISSING"/>
+ *     &lt;enumeration value="SELF_REFERENCE_FROM_TRIGGER"/>
+ *     &lt;enumeration value="SHARE_NEEDED_FOR_CHILD_OWNER"/>
+ *     &lt;enumeration value="SINGLE_EMAIL_LIMIT_EXCEEDED"/>
+ *     &lt;enumeration value="STANDARD_PRICE_NOT_DEFINED"/>
+ *     &lt;enumeration value="STORAGE_LIMIT_EXCEEDED"/>
+ *     &lt;enumeration value="STRING_TOO_LONG"/>
+ *     &lt;enumeration value="TABSET_LIMIT_EXCEEDED"/>
+ *     &lt;enumeration value="TEMPLATE_NOT_ACTIVE"/>
+ *     &lt;enumeration value="TERRITORY_REALIGN_IN_PROGRESS"/>
+ *     &lt;enumeration value="TEXT_DATA_OUTSIDE_SUPPORTED_CHARSET"/>
+ *     &lt;enumeration value="TOO_MANY_APEX_REQUESTS"/>
+ *     &lt;enumeration value="TOO_MANY_ENUM_VALUE"/>
+ *     &lt;enumeration value="TRANSFER_REQUIRES_READ"/>
+ *     &lt;enumeration value="UNABLE_TO_LOCK_ROW"/>
+ *     &lt;enumeration value="UNAVAILABLE_RECORDTYPE_EXCEPTION"/>
+ *     &lt;enumeration value="UNDELETE_FAILED"/>
+ *     &lt;enumeration value="UNKNOWN_EXCEPTION"/>
+ *     &lt;enumeration value="UNSPECIFIED_EMAIL_ADDRESS"/>
+ *     &lt;enumeration value="UNSUPPORTED_APEX_TRIGGER_OPERATON"/>
+ *     &lt;enumeration value="UNVERIFIED_SENDER_ADDRESS"/>
+ *     &lt;enumeration value="USER_OWNS_PORTAL_ACCOUNT_EXCEPTION"/>
+ *     &lt;enumeration value="USER_WITH_APEX_SHARES_EXCEPTION"/>
+ *     &lt;enumeration value="WEBLINK_SIZE_LIMIT_EXCEEDED"/>
+ *     &lt;enumeration value="WRONG_CONTROLLER_TYPE"/>
+ *   &lt;/restriction>
+ * &lt;/simpleType>
+ * </pre>
+ * 
+ */
+@XmlType(name = "StatusCode")
+@XmlEnum
+public enum StatusCode {
+
+    ALL_OR_NONE_OPERATION_ROLLED_BACK,
+    ALREADY_IN_PROCESS,
+    ASSIGNEE_TYPE_REQUIRED,
+    BAD_CUSTOM_ENTITY_PARENT_DOMAIN,
+    BCC_NOT_ALLOWED_IF_BCC_COMPLIANCE_ENABLED,
+    CANNOT_CASCADE_PRODUCT_ACTIVE,
+    CANNOT_CHANGE_FIELD_TYPE_OF_APEX_REFERENCED_FIELD,
+    CANNOT_CREATE_ANOTHER_MANAGED_PACKAGE,
+    CANNOT_DEACTIVATE_DIVISION,
+    CANNOT_DELETE_LAST_DATED_CONVERSION_RATE,
+    CANNOT_DELETE_MANAGED_OBJECT,
+    CANNOT_DISABLE_LAST_ADMIN,
+    CANNOT_ENABLE_IP_RESTRICT_REQUESTS,
+    CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY,
+    CANNOT_MODIFY_MANAGED_OBJECT,
+    CANNOT_RENAME_APEX_REFERENCED_FIELD,
+    CANNOT_RENAME_APEX_REFERENCED_OBJECT,
+    CANNOT_REPARENT_RECORD,
+    CANNOT_UPDATE_CONVERTED_LEAD,
+    CANT_DISABLE_CORP_CURRENCY,
+    CANT_UNSET_CORP_CURRENCY,
+    CHILD_SHARE_FAILS_PARENT,
+    CIRCULAR_DEPENDENCY,
+    COMMUNITY_NOT_ACCESSIBLE,
+    CUSTOM_CLOB_FIELD_LIMIT_EXCEEDED,
+    CUSTOM_ENTITY_OR_FIELD_LIMIT,
+    CUSTOM_FIELD_INDEX_LIMIT_EXCEEDED,
+    CUSTOM_INDEX_EXISTS,
+    CUSTOM_LINK_LIMIT_EXCEEDED,
+    CUSTOM_TAB_LIMIT_EXCEEDED,
+    DELETE_FAILED,
+    DELETE_OPERATION_TOO_LARGE,
+    DELETE_REQUIRED_ON_CASCADE,
+    DEPENDENCY_EXISTS,
+    DUPLICATE_CASE_SOLUTION,
+    DUPLICATE_COMM_NICKNAME,
+    DUPLICATE_CUSTOM_ENTITY_DEFINITION,
+    DUPLICATE_CUSTOM_TAB_MOTIF,
+    DUPLICATE_DEVELOPER_NAME,
+    DUPLICATE_EXTERNAL_ID,
+    DUPLICATE_MASTER_LABEL,
+    DUPLICATE_SENDER_DISPLAY_NAME,
+    DUPLICATE_USERNAME,
+    DUPLICATE_VALUE,
+    EMAIL_NOT_PROCESSED_DUE_TO_PRIOR_ERROR,
+    EMPTY_SCONTROL_FILE_NAME,
+    ENTITY_FAILED_IFLASTMODIFIED_ON_UPDATE,
+    ENTITY_IS_ARCHIVED,
+    ENTITY_IS_DELETED,
+    ENTITY_IS_LOCKED,
+    ERROR_IN_MAILER,
+    EXTERNAL_OBJECT_AUTHENTICATION_EXCEPTION,
+    EXTERNAL_OBJECT_CONNECTION_EXCEPTION,
+    EXTERNAL_OBJECT_EXCEPTION,
+    EXTERNAL_OBJECT_UNSUPPORTED_EXCEPTION,
+    FAILED_ACTIVATION,
+    FIELD_CUSTOM_VALIDATION_EXCEPTION,
+    FIELD_FILTER_VALIDATION_EXCEPTION,
+    FIELD_INTEGRITY_EXCEPTION,
+    FILTERED_LOOKUP_LIMIT_EXCEEDED,
+    HTML_FILE_UPLOAD_NOT_ALLOWED,
+    IMAGE_TOO_LARGE,
+    INACTIVE_OWNER_OR_USER,
+    INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY,
+    INSUFFICIENT_ACCESS_OR_READONLY,
+    INVALID_ACCESS_LEVEL,
+    INVALID_ARGUMENT_TYPE,
+    INVALID_ASSIGNEE_TYPE,
+    INVALID_ASSIGNMENT_RULE,
+    INVALID_BATCH_OPERATION,
+    INVALID_CONTENT_TYPE,
+    INVALID_CREDIT_CARD_INFO,
+    INVALID_CROSS_REFERENCE_KEY,
+    INVALID_CROSS_REFERENCE_TYPE_FOR_FIELD,
+    INVALID_CURRENCY_CONV_RATE,
+    INVALID_CURRENCY_CORP_RATE,
+    INVALID_CURRENCY_ISO,
+    INVALID_DATA_CATEGORY_GROUP_REFERENCE,
+    INVALID_DATA_URI,
+    INVALID_EMAIL_ADDRESS,
+    INVALID_EMPTY_KEY_OWNER,
+    INVALID_FIELD,
+    INVALID_FIELD_FOR_INSERT_UPDATE,
+    INVALID_FIELD_WHEN_USING_TEMPLATE,
+    INVALID_FILTER_ACTION,
+    INVALID_GOOGLE_DOCS_URL,
+    INVALID_ID_FIELD,
+    INVALID_INET_ADDRESS,
+    INVALID_LINEITEM_CLONE_STATE,
+    INVALID_MASTER_OR_TRANSLATED_SOLUTION,
+    INVALID_MESSAGE_ID_REFERENCE,
+    INVALID_OPERATION,
+    INVALID_OPERATOR,
+    INVALID_OR_NULL_FOR_RESTRICTED_PICKLIST,
+    INVALID_PACKAGE_VERSION,
+    INVALID_PARTNER_NETWORK_STATUS,
+    INVALID_PERSON_ACCOUNT_OPERATION,
+    INVALID_QUERY_LOCATOR,
+    INVALID_READ_ONLY_USER_DML,
+    INVALID_SAVE_AS_ACTIVITY_FLAG,
+    INVALID_SESSION_ID,
+    INVALID_SETUP_OWNER,
+    INVALID_STATUS,
+    INVALID_TYPE,
+    INVALID_TYPE_FOR_OPERATION,
+    INVALID_TYPE_ON_FIELD_IN_RECORD,
+    IP_RANGE_LIMIT_EXCEEDED,
+    LICENSE_LIMIT_EXCEEDED,
+    LIGHT_PORTAL_USER_EXCEPTION,
+    LIMIT_EXCEEDED,
+    MALFORMED_ID,
+    MANAGER_NOT_DEFINED,
+    MASSMAIL_RETRY_LIMIT_EXCEEDED,
+    MASS_MAIL_LIMIT_EXCEEDED,
+    MAXIMUM_CCEMAILS_EXCEEDED,
+    MAXIMUM_DASHBOARD_COMPONENTS_EXCEEDED,
+    MAXIMUM_HIERARCHY_LEVELS_REACHED,
+    MAXIMUM_SIZE_OF_ATTACHMENT,
+    MAXIMUM_SIZE_OF_DOCUMENT,
+    MAX_ACTIONS_PER_RULE_EXCEEDED,
+    MAX_ACTIVE_RULES_EXCEEDED,
+    MAX_APPROVAL_STEPS_EXCEEDED,
+    MAX_FORMULAS_PER_RULE_EXCEEDED,
+    MAX_RULES_EXCEEDED,
+    MAX_RULE_ENTRIES_EXCEEDED,
+    MAX_TASK_DESCRIPTION_EXCEEEDED,
+    MAX_TM_RULES_EXCEEDED,
+    MAX_TM_RULE_ITEMS_EXCEEDED,
+    MERGE_FAILED,
+    MISSING_ARGUMENT,
+    MIXED_DML_OPERATION,
+    NONUNIQUE_SHIPPING_ADDRESS,
+    NO_APPLICABLE_PROCESS,
+    NO_ATTACHMENT_PERMISSION,
+    NO_INACTIVE_DIVISION_MEMBERS,
+    NO_MASS_MAIL_PERMISSION,
+    NUMBER_OUTSIDE_VALID_RANGE,
+    NUM_HISTORY_FIELDS_BY_SOBJECT_EXCEEDED,
+    OPTED_OUT_OF_MASS_MAIL,
+    OP_WITH_INVALID_USER_TYPE_EXCEPTION,
+    PACKAGE_LICENSE_REQUIRED,
+    PORTAL_NO_ACCESS,
+    PORTAL_USER_ALREADY_EXISTS_FOR_CONTACT,
+    PRIVATE_CONTACT_ON_ASSET,
+    QUERY_TIMEOUT,
+    RECORD_IN_USE_BY_WORKFLOW,
+    REQUEST_RUNNING_TOO_LONG,
+    REQUIRED_FEATURE_MISSING,
+    REQUIRED_FIELD_MISSING,
+    SELF_REFERENCE_FROM_TRIGGER,
+    SHARE_NEEDED_FOR_CHILD_OWNER,
+    SINGLE_EMAIL_LIMIT_EXCEEDED,
+    STANDARD_PRICE_NOT_DEFINED,
+    STORAGE_LIMIT_EXCEEDED,
+    STRING_TOO_LONG,
+    TABSET_LIMIT_EXCEEDED,
+    TEMPLATE_NOT_ACTIVE,
+    TERRITORY_REALIGN_IN_PROGRESS,
+    TEXT_DATA_OUTSIDE_SUPPORTED_CHARSET,
+    TOO_MANY_APEX_REQUESTS,
+    TOO_MANY_ENUM_VALUE,
+    TRANSFER_REQUIRES_READ,
+    UNABLE_TO_LOCK_ROW,
+    UNAVAILABLE_RECORDTYPE_EXCEPTION,
+    UNDELETE_FAILED,
+    UNKNOWN_EXCEPTION,
+    UNSPECIFIED_EMAIL_ADDRESS,
+    UNSUPPORTED_APEX_TRIGGER_OPERATON,
+    UNVERIFIED_SENDER_ADDRESS,
+    USER_OWNS_PORTAL_ACCOUNT_EXCEPTION,
+    USER_WITH_APEX_SHARES_EXCEPTION,
+    WEBLINK_SIZE_LIMIT_EXCEEDED,
+    WRONG_CONTROLLER_TYPE;
+
+    public String value() {
+        return name();
+    }
+
+    public static StatusCode fromValue(String v) {
+        return valueOf(v);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/package-info.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/package-info.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/package-info.java
new file mode 100644
index 0000000..ae2b9ee
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/package-info.java
@@ -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.
+ */
+@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.force.com/2009/06/asyncapi/dataload", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
+package org.apache.camel.component.salesforce.api.dto.bulk;

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/OperationName.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/OperationName.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/OperationName.java
new file mode 100644
index 0000000..50141f1
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/OperationName.java
@@ -0,0 +1,71 @@
+/**
+ * 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.internal;
+
+public enum OperationName {
+
+    // rest API
+    GET_VERSIONS("getVersions"),
+    GET_RESOURCES("getResources"),
+    GET_GLOBAL_OBJECTS("getGlobalObjects"),
+    GET_BASIC_INFO("getBasicInfo"),
+    GET_DESCRIPTION("getDescription"),
+    GET_SOBJECT("getSObject"),
+    CREATE_SOBJECT("createSObject"),
+    UPDATE_SOBJECT("updateSObject"),
+    DELETE_SOBJECT("deleteSObject"),
+    GET_SOBJECT_WITH_ID("getSObjectWithId"),
+    UPSERT_SOBJECT("upsertSObject"),
+    DELETE_SOBJECT_WITH_ID("deleteSObjectWithId"),
+    GET_BLOB_FIELD("getBlobField"),
+    QUERY("query"),
+    QUERY_MORE("queryMore"),
+    SEARCH("search"),
+
+    // bulk API
+    CREATE_JOB("createJob"),
+    GET_JOB("getJob"),
+    CLOSE_JOB("closeJob"),
+    ABORT_JOB("abortJob"),
+    CREATE_BATCH("createBatch"),
+    GET_BATCH("getBatch"),
+    GET_ALL_BATCHES("getAllBatches"),
+    GET_REQUEST("getRequest"),
+    GET_RESULTS("getResults"),
+    CREATE_BATCH_QUERY("createBatchQuery"),
+    GET_QUERY_RESULT_IDS("getQueryResultIds"),
+    GET_QUERY_RESULT("getQueryResult");
+
+    private final String value;
+
+    private OperationName(String value) {
+        this.value = value;
+    }
+
+    public String value() {
+        return value;
+    }
+
+    public static OperationName fromValue(String value) {
+        for (OperationName operationName : OperationName.values()) {
+            if (operationName.value.equals(value)) {
+                return operationName;
+            }
+        }
+        throw new IllegalArgumentException(value);
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/PayloadFormat.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/PayloadFormat.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/PayloadFormat.java
new file mode 100644
index 0000000..8555910
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/PayloadFormat.java
@@ -0,0 +1,22 @@
+/**
+ * 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.internal;
+
+public enum PayloadFormat {
+    JSON,
+    XML
+}


[02/11] CAMEL-6428: Fixed CS

Posted by da...@apache.org.
http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/AbstractRestProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/AbstractRestProcessor.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/AbstractRestProcessor.java
index 1e40d18..82e2c14 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/AbstractRestProcessor.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/AbstractRestProcessor.java
@@ -16,22 +16,31 @@
  */
 package org.apache.camel.component.salesforce.internal.processor;
 
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Map;
+
 import org.apache.camel.AsyncCallback;
 import org.apache.camel.Exchange;
-import org.apache.camel.util.ServiceHelper;
 import org.apache.camel.component.salesforce.SalesforceEndpoint;
 import org.apache.camel.component.salesforce.api.SalesforceException;
 import org.apache.camel.component.salesforce.api.dto.AbstractSObjectBase;
 import org.apache.camel.component.salesforce.internal.PayloadFormat;
 import org.apache.camel.component.salesforce.internal.client.DefaultRestClient;
 import org.apache.camel.component.salesforce.internal.client.RestClient;
+import org.apache.camel.util.ServiceHelper;
 
-import java.io.InputStream;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Map;
-
-import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.*;
+import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.API_VERSION;
+import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.SOBJECT_BLOB_FIELD_NAME;
+import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.SOBJECT_CLASS;
+import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.SOBJECT_EXT_ID_NAME;
+import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.SOBJECT_EXT_ID_VALUE;
+import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.SOBJECT_FIELDS;
+import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.SOBJECT_ID;
+import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.SOBJECT_NAME;
+import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.SOBJECT_QUERY;
+import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.SOBJECT_SEARCH;
 
 public abstract class AbstractRestProcessor extends AbstractSalesforceProcessor {
 
@@ -46,7 +55,7 @@ public abstract class AbstractRestProcessor extends AbstractSalesforceProcessor
         final PayloadFormat payloadFormat = endpoint.getConfiguration().getPayloadFormat();
 
         this.restClient = new DefaultRestClient(httpClient, endpointConfigMap.get(API_VERSION),
-            payloadFormat.toString().toLowerCase() , session);
+                payloadFormat.toString().toLowerCase(), session);
 
         this.classMap = endpoint.getComponent().getClassMap();
     }
@@ -130,8 +139,7 @@ public abstract class AbstractRestProcessor extends AbstractSalesforceProcessor
                     });
                     break;
 
-                case GET_SOBJECT:
-                {
+                case GET_SOBJECT: {
                     String sObjectIdValue;
                     // determine parameters from input AbstractSObject
                     final AbstractSObjectBase sObjectBase = exchange.getIn().getBody(AbstractSObjectBase.class);
@@ -165,8 +173,7 @@ public abstract class AbstractRestProcessor extends AbstractSalesforceProcessor
                     break;
                 }
 
-                case CREATE_SOBJECT:
-                {
+                case CREATE_SOBJECT: {
                     // determine parameters from input AbstractSObject
                     AbstractSObjectBase sObjectBase = exchange.getIn().getBody(AbstractSObjectBase.class);
                     if (sObjectBase != null) {
@@ -176,18 +183,17 @@ public abstract class AbstractRestProcessor extends AbstractSalesforceProcessor
                     }
 
                     restClient.createSObject(sObjectName, getRequestStream(exchange),
-                        new RestClient.ResponseCallback() {
-                        @Override
-                        public void onResponse(InputStream response, SalesforceException exception) {
-                            processResponse(exchange, response, exception, callback);
-                        }
-                    });
+                            new RestClient.ResponseCallback() {
+                                @Override
+                                public void onResponse(InputStream response, SalesforceException exception) {
+                                    processResponse(exchange, response, exception, callback);
+                                }
+                            });
 
                     break;
                 }
 
-                case UPDATE_SOBJECT:
-                {
+                case UPDATE_SOBJECT: {
                     // determine parameters from input AbstractSObject
                     final AbstractSObjectBase sObjectBase = exchange.getIn().getBody(AbstractSObjectBase.class);
                     String sObjectId;
@@ -204,19 +210,18 @@ public abstract class AbstractRestProcessor extends AbstractSalesforceProcessor
 
                     final String finalsObjectId = sObjectId;
                     restClient.updateSObject(sObjectName, sObjectId, getRequestStream(exchange),
-                        new RestClient.ResponseCallback() {
-                            @Override
-                            public void onResponse(InputStream response, SalesforceException exception) {
-                                processResponse(exchange, response, exception, callback);
-                                restoreFields(exchange, sObjectBase, finalsObjectId, null, null);
-                            }
-                        });
+                            new RestClient.ResponseCallback() {
+                                @Override
+                                public void onResponse(InputStream response, SalesforceException exception) {
+                                    processResponse(exchange, response, exception, callback);
+                                    restoreFields(exchange, sObjectBase, finalsObjectId, null, null);
+                                }
+                            });
 
                     break;
                 }
 
-                case DELETE_SOBJECT:
-                {
+                case DELETE_SOBJECT: {
                     // determine parameters from input AbstractSObject
                     final AbstractSObjectBase sObjectBase = exchange.getIn().getBody(AbstractSObjectBase.class);
                     String sObjectIdValue;
@@ -239,12 +244,11 @@ public abstract class AbstractRestProcessor extends AbstractSalesforceProcessor
                     break;
                 }
 
-                case GET_SOBJECT_WITH_ID:
-                {
+                case GET_SOBJECT_WITH_ID: {
                     Object oldValue = null;
                     String sObjectExtIdValue;
                     final String sObjectExtIdName = getParameter(SOBJECT_EXT_ID_NAME,
-                        exchange, IGNORE_BODY, NOT_OPTIONAL);
+                            exchange, IGNORE_BODY, NOT_OPTIONAL);
 
                     // determine parameters from input AbstractSObject
                     final AbstractSObjectBase sObjectBase = exchange.getIn().getBody(AbstractSObjectBase.class);
@@ -262,22 +266,21 @@ public abstract class AbstractRestProcessor extends AbstractSalesforceProcessor
 
                     final Object finalOldValue = oldValue;
                     restClient.getSObjectWithId(sObjectName, sObjectExtIdName, sObjectExtIdValue,
-                        new RestClient.ResponseCallback() {
-                            @Override
-                            public void onResponse(InputStream response, SalesforceException exception) {
-                                processResponse(exchange, response, exception, callback);
-                                restoreFields(exchange, sObjectBase, null, sObjectExtIdName, finalOldValue);
-                            }
-                        });
+                            new RestClient.ResponseCallback() {
+                                @Override
+                                public void onResponse(InputStream response, SalesforceException exception) {
+                                    processResponse(exchange, response, exception, callback);
+                                    restoreFields(exchange, sObjectBase, null, sObjectExtIdName, finalOldValue);
+                                }
+                            });
 
                     break;
                 }
 
-                case UPSERT_SOBJECT:
-                {
+                case UPSERT_SOBJECT: {
                     String sObjectExtIdValue;
                     final String sObjectExtIdName = getParameter(SOBJECT_EXT_ID_NAME, exchange,
-                        IGNORE_BODY, NOT_OPTIONAL);
+                            IGNORE_BODY, NOT_OPTIONAL);
 
                     // determine parameters from input AbstractSObject
                     Object oldValue = null;
@@ -295,7 +298,7 @@ public abstract class AbstractRestProcessor extends AbstractSalesforceProcessor
 
                     final Object finalOldValue = oldValue;
                     restClient.upsertSObject(sObjectName, sObjectExtIdName, sObjectExtIdValue,
-                        getRequestStream(exchange), new RestClient.ResponseCallback() {
+                            getRequestStream(exchange), new RestClient.ResponseCallback() {
                         @Override
                         public void onResponse(InputStream response, SalesforceException exception) {
                             processResponse(exchange, response, exception, callback);
@@ -306,8 +309,7 @@ public abstract class AbstractRestProcessor extends AbstractSalesforceProcessor
                     break;
                 }
 
-                case DELETE_SOBJECT_WITH_ID:
-                {
+                case DELETE_SOBJECT_WITH_ID: {
                     final String sObjectExtIdName = getParameter(SOBJECT_EXT_ID_NAME, exchange, IGNORE_BODY, NOT_OPTIONAL);
 
                     // determine parameters from input AbstractSObject
@@ -325,22 +327,21 @@ public abstract class AbstractRestProcessor extends AbstractSalesforceProcessor
 
                     final Object finalOldValue = oldValue;
                     restClient.deleteSObjectWithId(sObjectName, sObjectExtIdName, sObjectExtIdValue,
-                        new RestClient.ResponseCallback() {
-                            @Override
-                            public void onResponse(InputStream response, SalesforceException exception) {
-                                processResponse(exchange, response, exception, callback);
-                                restoreFields(exchange, sObjectBase, null, sObjectExtIdName, finalOldValue);
-                            }
-                        });
+                            new RestClient.ResponseCallback() {
+                                @Override
+                                public void onResponse(InputStream response, SalesforceException exception) {
+                                    processResponse(exchange, response, exception, callback);
+                                    restoreFields(exchange, sObjectBase, null, sObjectExtIdName, finalOldValue);
+                                }
+                            });
 
                     break;
                 }
 
-                case GET_BLOB_FIELD:
-                {
+                case GET_BLOB_FIELD: {
                     // get blob field name
                     final String sObjectBlobFieldName = getParameter(SOBJECT_BLOB_FIELD_NAME,
-                        exchange, IGNORE_BODY, NOT_OPTIONAL);
+                            exchange, IGNORE_BODY, NOT_OPTIONAL);
 
                     // determine parameters from input AbstractSObject
                     final AbstractSObjectBase sObjectBase = exchange.getIn().getBody(AbstractSObjectBase.class);
@@ -355,13 +356,13 @@ public abstract class AbstractRestProcessor extends AbstractSalesforceProcessor
                     final String sObjectId = sObjectIdValue;
 
                     restClient.getBlobField(sObjectName, sObjectId, sObjectBlobFieldName,
-                        new RestClient.ResponseCallback() {
-                            @Override
-                            public void onResponse(InputStream response, SalesforceException exception) {
-                                processResponse(exchange, response, exception, callback);
-                                restoreFields(exchange, sObjectBase, sObjectId, null, null);
-                            }
-                        });
+                            new RestClient.ResponseCallback() {
+                                @Override
+                                public void onResponse(InputStream response, SalesforceException exception) {
+                                    processResponse(exchange, response, exception, callback);
+                                    restoreFields(exchange, sObjectBase, sObjectId, null, null);
+                                }
+                            });
                     break;
                 }
 
@@ -409,16 +410,16 @@ public abstract class AbstractRestProcessor extends AbstractSalesforceProcessor
 
         } catch (SalesforceException e) {
             exchange.setException(new SalesforceException(
-                String.format("Error processing %s: [%s] \"%s\"",
-                    operationName, e.getStatusCode(), e.getMessage()),
-                e));
+                    String.format("Error processing %s: [%s] \"%s\"",
+                            operationName, e.getStatusCode(), e.getMessage()),
+                    e));
             callback.done(true);
             return true;
         } catch (RuntimeException e) {
             exchange.setException(new SalesforceException(
-                String.format("Unexpected Error processing %s: \"%s\"",
-                    operationName, e.getMessage()),
-                e));
+                    String.format("Unexpected Error processing %s: \"%s\"",
+                            operationName, e.getMessage()),
+                    e));
             callback.done(true);
             return true;
         }
@@ -454,19 +455,19 @@ public abstract class AbstractRestProcessor extends AbstractSalesforceProcessor
             setMethod.invoke(sObjectBase, value);
         } catch (NoSuchMethodException e) {
             throw new SalesforceException(
-                String.format("SObject %s does not have a field %s",
-                    sObjectBase.getClass().getName(), name),
-                e);
+                    String.format("SObject %s does not have a field %s",
+                            sObjectBase.getClass().getName(), name),
+                    e);
         } catch (InvocationTargetException e) {
             throw new SalesforceException(
-                String.format("Error setting value %s.%s",
-                    sObjectBase.getClass().getSimpleName(), name),
-                e);
+                    String.format("Error setting value %s.%s",
+                            sObjectBase.getClass().getSimpleName(), name),
+                    e);
         } catch (IllegalAccessException e) {
             throw new SalesforceException(
-                String.format("Error accessing value %s.%s",
-                    sObjectBase.getClass().getSimpleName(), name),
-                e);
+                    String.format("Error accessing value %s.%s",
+                            sObjectBase.getClass().getSimpleName(), name),
+                    e);
         }
     }
 
@@ -478,24 +479,24 @@ public abstract class AbstractRestProcessor extends AbstractSalesforceProcessor
 
             // clear the value with the set method
             Method setMethod = sObjectBase.getClass().getMethod("set" + propertyName, getMethod.getReturnType());
-            setMethod.invoke(sObjectBase, new Object[] { null });
+            setMethod.invoke(sObjectBase, new Object[]{null});
 
             return value;
         } catch (NoSuchMethodException e) {
             throw new SalesforceException(
-                String.format("SObject %s does not have a field %s",
-                    sObjectBase.getClass().getSimpleName(), propertyName),
-                e);
+                    String.format("SObject %s does not have a field %s",
+                            sObjectBase.getClass().getSimpleName(), propertyName),
+                    e);
         } catch (InvocationTargetException e) {
             throw new SalesforceException(
-                String.format("Error getting/setting value %s.%s",
-                    sObjectBase.getClass().getSimpleName(), propertyName),
-                e);
+                    String.format("Error getting/setting value %s.%s",
+                            sObjectBase.getClass().getSimpleName(), propertyName),
+                    e);
         } catch (IllegalAccessException e) {
             throw new SalesforceException(
-                String.format("Error accessing value %s.%s",
-                    sObjectBase.getClass().getSimpleName(), propertyName),
-                e);
+                    String.format("Error accessing value %s.%s",
+                            sObjectBase.getClass().getSimpleName(), propertyName),
+                    e);
         }
     }
 
@@ -521,12 +522,12 @@ public abstract class AbstractRestProcessor extends AbstractSalesforceProcessor
             final String className = getParameter(SOBJECT_CLASS, exchange, IGNORE_BODY, NOT_OPTIONAL);
             try {
                 sObjectClass = endpoint.getComponent().getCamelContext()
-                    .getClassResolver().resolveMandatoryClass(className);
+                        .getClassResolver().resolveMandatoryClass(className);
             } catch (ClassNotFoundException e) {
                 throw new SalesforceException(
-                    String.format("SObject class not found %s, %s",
-                        className, e.getMessage()),
-                    e);
+                        String.format("SObject class not found %s, %s",
+                                className, e.getMessage()),
+                        e);
             }
         }
         exchange.setProperty(RESPONSE_CLASS, sObjectClass);

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/AbstractSalesforceProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/AbstractSalesforceProcessor.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/AbstractSalesforceProcessor.java
index e784458..c214c01 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/AbstractSalesforceProcessor.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/AbstractSalesforceProcessor.java
@@ -16,19 +16,19 @@
  */
 package org.apache.camel.component.salesforce.internal.processor;
 
+import java.util.Map;
+
 import org.apache.camel.AsyncCallback;
 import org.apache.camel.Exchange;
-import org.eclipse.jetty.client.HttpClient;
 import org.apache.camel.component.salesforce.SalesforceComponent;
 import org.apache.camel.component.salesforce.SalesforceEndpoint;
 import org.apache.camel.component.salesforce.api.SalesforceException;
 import org.apache.camel.component.salesforce.internal.OperationName;
 import org.apache.camel.component.salesforce.internal.SalesforceSession;
+import org.eclipse.jetty.client.HttpClient;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.Map;
-
 public abstract class AbstractSalesforceProcessor implements SalesforceProcessor {
 
     protected static final boolean NOT_OPTIONAL = false;
@@ -60,12 +60,13 @@ public abstract class AbstractSalesforceProcessor implements SalesforceProcessor
     /**
      * Gets value for a parameter from header, endpoint config, or exchange body (optional).
      *
-     * @param exchange exchange to inspect
+     * @param exchange      exchange to inspect
      * @param convertInBody converts In body to String value if true
-     * @param propName name of property
-     * @param optional if {@code true} returns null, otherwise throws RestException
+     * @param propName      name of property
+     * @param optional      if {@code true} returns null, otherwise throws RestException
      * @return value of property, or {@code null} for optional parameters if not found.
-     * @throws org.apache.camel.component.salesforce.api.SalesforceException if the property can't be found.
+     * @throws org.apache.camel.component.salesforce.api.SalesforceException
+     *          if the property can't be found.
      */
     protected final String getParameter(String propName, Exchange exchange, boolean convertInBody, boolean optional) throws SalesforceException {
         String propValue = exchange.getIn().getHeader(propName, String.class);

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/BulkApiProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/BulkApiProcessor.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/BulkApiProcessor.java
index 6e070f7..d461207 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/BulkApiProcessor.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/BulkApiProcessor.java
@@ -16,21 +16,32 @@
  */
 package org.apache.camel.component.salesforce.internal.processor;
 
-import org.apache.camel.*;
-import org.apache.camel.converter.stream.StreamCacheConverter;
-import org.apache.camel.util.ServiceHelper;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+import org.apache.camel.AsyncCallback;
+import org.apache.camel.CamelException;
+import org.apache.camel.Exchange;
+import org.apache.camel.InvalidPayloadException;
+import org.apache.camel.Message;
+import org.apache.camel.StreamCache;
 import org.apache.camel.component.salesforce.SalesforceEndpoint;
 import org.apache.camel.component.salesforce.SalesforceEndpointConfig;
 import org.apache.camel.component.salesforce.api.SalesforceException;
-import org.apache.camel.component.salesforce.api.dto.bulk.*;
+import org.apache.camel.component.salesforce.api.dto.bulk.BatchInfo;
+import org.apache.camel.component.salesforce.api.dto.bulk.ContentType;
+import org.apache.camel.component.salesforce.api.dto.bulk.JobInfo;
 import org.apache.camel.component.salesforce.internal.client.BulkApiClient;
 import org.apache.camel.component.salesforce.internal.client.DefaultBulkApiClient;
+import org.apache.camel.converter.stream.StreamCacheConverter;
+import org.apache.camel.util.ServiceHelper;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.List;
-
-import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.*;
+import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.BATCH_ID;
+import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.CONTENT_TYPE;
+import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.JOB_ID;
+import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.RESULT_ID;
+import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.SOBJECT_QUERY;
 
 public class BulkApiProcessor extends AbstractSalesforceProcessor {
 
@@ -40,7 +51,7 @@ public class BulkApiProcessor extends AbstractSalesforceProcessor {
         super(endpoint);
 
         this.bulkClient = new DefaultBulkApiClient(
-            endpointConfigMap.get(SalesforceEndpointConfig.API_VERSION), session, httpClient);
+                endpointConfigMap.get(SalesforceEndpointConfig.API_VERSION), session, httpClient);
     }
 
     @Override
@@ -112,7 +123,7 @@ public class BulkApiProcessor extends AbstractSalesforceProcessor {
                 case CREATE_BATCH:
                     // since request is in the body, use headers or endpoint params
                     ContentType contentType = ContentType.fromValue(
-                        getParameter(CONTENT_TYPE, exchange, IGNORE_BODY, NOT_OPTIONAL));
+                            getParameter(CONTENT_TYPE, exchange, IGNORE_BODY, NOT_OPTIONAL));
                     jobId = getParameter(JOB_ID, exchange, IGNORE_BODY, NOT_OPTIONAL);
 
                     InputStream request;
@@ -249,17 +260,17 @@ public class BulkApiProcessor extends AbstractSalesforceProcessor {
                     } else {
                         jobId = getParameter(JOB_ID, exchange, IGNORE_BODY, NOT_OPTIONAL);
                         contentType = ContentType.fromValue(
-                            getParameter(CONTENT_TYPE, exchange, IGNORE_BODY, NOT_OPTIONAL));
+                                getParameter(CONTENT_TYPE, exchange, IGNORE_BODY, NOT_OPTIONAL));
                         // reuse SOBJECT_QUERY property
                         soqlQuery = getParameter(SOBJECT_QUERY, exchange, USE_BODY, NOT_OPTIONAL);
                     }
                     bulkClient.createBatchQuery(jobId, soqlQuery, contentType,
-                        new BulkApiClient.BatchInfoResponseCallback() {
-                        @Override
-                        public void onResponse(BatchInfo batchInfo, SalesforceException ex) {
-                            processResponse(exchange, batchInfo, ex, callback);
-                        }
-                    });
+                            new BulkApiClient.BatchInfoResponseCallback() {
+                                @Override
+                                public void onResponse(BatchInfo batchInfo, SalesforceException ex) {
+                                    processResponse(exchange, batchInfo, ex, callback);
+                                }
+                            });
 
                     break;
 
@@ -323,23 +334,23 @@ public class BulkApiProcessor extends AbstractSalesforceProcessor {
 
         } catch (SalesforceException e) {
             exchange.setException(new SalesforceException(
-                String.format("Error processing %s: [%s] \"%s\"",
-                    operationName, e.getStatusCode(), e.getMessage()),
-                e));
+                    String.format("Error processing %s: [%s] \"%s\"",
+                            operationName, e.getStatusCode(), e.getMessage()),
+                    e));
             callback.done(true);
             done = true;
         } catch (InvalidPayloadException e) {
             exchange.setException(new SalesforceException(
-                String.format("Unexpected Error processing %s: \"%s\"",
-                    operationName, e.getMessage()),
-                e));
+                    String.format("Unexpected Error processing %s: \"%s\"",
+                            operationName, e.getMessage()),
+                    e));
             callback.done(true);
             done = true;
         } catch (RuntimeException e) {
             exchange.setException(new SalesforceException(
-                String.format("Unexpected Error processing %s: \"%s\"",
-                    operationName, e.getMessage()),
-                e));
+                    String.format("Unexpected Error processing %s: \"%s\"",
+                            operationName, e.getMessage()),
+                    e));
             callback.done(true);
             done = true;
         }

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/JsonRestProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/JsonRestProcessor.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/JsonRestProcessor.java
index 3ac32c6..528d8ca 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/JsonRestProcessor.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/JsonRestProcessor.java
@@ -16,22 +16,29 @@
  */
 package org.apache.camel.component.salesforce.internal.processor;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
 import org.apache.camel.AsyncCallback;
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
+import org.apache.camel.component.salesforce.SalesforceEndpoint;
+import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.api.dto.AbstractSObjectBase;
+import org.apache.camel.component.salesforce.api.dto.CreateSObjectResult;
+import org.apache.camel.component.salesforce.api.dto.GlobalObjects;
+import org.apache.camel.component.salesforce.api.dto.RestResources;
+import org.apache.camel.component.salesforce.api.dto.SObjectBasicInfo;
+import org.apache.camel.component.salesforce.api.dto.SObjectDescription;
+import org.apache.camel.component.salesforce.api.dto.SearchResult;
+import org.apache.camel.component.salesforce.api.dto.Version;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.codehaus.jackson.map.SerializationConfig;
 import org.codehaus.jackson.type.TypeReference;
 import org.eclipse.jetty.util.StringUtil;
-import org.apache.camel.component.salesforce.SalesforceEndpoint;
-import org.apache.camel.component.salesforce.api.SalesforceException;
-import org.apache.camel.component.salesforce.api.dto.*;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.List;
 
 public class JsonRestProcessor extends AbstractRestProcessor {
 
@@ -53,7 +60,8 @@ public class JsonRestProcessor extends AbstractRestProcessor {
         switch (operationName) {
             case GET_VERSIONS:
                 // handle in built response types
-                exchange.setProperty(RESPONSE_TYPE, new TypeReference<List<Version>>() {});
+                exchange.setProperty(RESPONSE_TYPE, new TypeReference<List<Version>>() {
+                });
                 break;
 
             case GET_RESOURCES:
@@ -88,7 +96,8 @@ public class JsonRestProcessor extends AbstractRestProcessor {
 
             case SEARCH:
                 // handle known response type
-                exchange.setProperty(RESPONSE_TYPE, new TypeReference<List<SearchResult>>() {});
+                exchange.setProperty(RESPONSE_TYPE, new TypeReference<List<SearchResult>>() {
+                });
                 break;
 
         }
@@ -112,7 +121,7 @@ public class JsonRestProcessor extends AbstractRestProcessor {
                     final String body = in.getBody(String.class);
                     if (null == body) {
                         String msg = "Unsupported request message body " +
-                            (in.getBody() == null ? null : in.getBody().getClass());
+                                (in.getBody() == null ? null : in.getBody().getClass());
                         throw new SalesforceException(msg, null);
                     } else {
                         request = new ByteArrayInputStream(body.getBytes(StringUtil.__UTF8_CHARSET));

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/XmlRestProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/XmlRestProcessor.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/XmlRestProcessor.java
index 75449b6..905127a 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/XmlRestProcessor.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/XmlRestProcessor.java
@@ -16,6 +16,13 @@
  */
 package org.apache.camel.component.salesforce.internal.processor;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+
 import com.thoughtworks.xstream.XStream;
 import com.thoughtworks.xstream.XStreamException;
 import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
@@ -27,13 +34,18 @@ import com.thoughtworks.xstream.mapper.CannotResolveClassException;
 import org.apache.camel.AsyncCallback;
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
-import org.eclipse.jetty.util.StringUtil;
 import org.apache.camel.component.salesforce.SalesforceEndpoint;
 import org.apache.camel.component.salesforce.api.JodaTimeConverter;
 import org.apache.camel.component.salesforce.api.SalesforceException;
-import org.apache.camel.component.salesforce.api.dto.*;
-
-import java.io.*;
+import org.apache.camel.component.salesforce.api.dto.AbstractSObjectBase;
+import org.apache.camel.component.salesforce.api.dto.CreateSObjectResult;
+import org.apache.camel.component.salesforce.api.dto.GlobalObjects;
+import org.apache.camel.component.salesforce.api.dto.RestResources;
+import org.apache.camel.component.salesforce.api.dto.SObjectBasicInfo;
+import org.apache.camel.component.salesforce.api.dto.SObjectDescription;
+import org.apache.camel.component.salesforce.api.dto.SearchResults;
+import org.apache.camel.component.salesforce.api.dto.Versions;
+import org.eclipse.jetty.util.StringUtil;
 
 import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.SOBJECT_NAME;
 
@@ -44,22 +56,22 @@ public class XmlRestProcessor extends AbstractRestProcessor {
     // not very efficient when both JSON and XML are used together with a single Thread pool
     // but this will do for now
     private static ThreadLocal<XStream> xStream =
-        new ThreadLocal<XStream>() {
-            @Override
-            protected XStream initialValue() {
-                // use NoNameCoder to avoid escaping __ in custom field names
-                // and CompactWriter to avoid pretty printing
-                XStream result = new XStream(new XppDriver(new NoNameCoder()) {
-                    @Override
-                    public HierarchicalStreamWriter createWriter(Writer out) {
-                        return new CompactWriter(out, getNameCoder());
-                    }
+            new ThreadLocal<XStream>() {
+                @Override
+                protected XStream initialValue() {
+                    // use NoNameCoder to avoid escaping __ in custom field names
+                    // and CompactWriter to avoid pretty printing
+                    XStream result = new XStream(new XppDriver(new NoNameCoder()) {
+                        @Override
+                        public HierarchicalStreamWriter createWriter(Writer out) {
+                            return new CompactWriter(out, getNameCoder());
+                        }
 
-                });
-                result.registerConverter(new JodaTimeConverter());
-                return result;
-            }
-        };
+                    });
+                    result.registerConverter(new JodaTimeConverter());
+                    return result;
+                }
+            };
 
     private static final String RESPONSE_ALIAS = XmlRestProcessor.class.getName() + ".responseAlias";
 
@@ -91,7 +103,7 @@ public class XmlRestProcessor extends AbstractRestProcessor {
 
                 // need to add alias for Salesforce XML that uses SObject name as root element
                 exchange.setProperty(RESPONSE_ALIAS,
-                    getParameter(SOBJECT_NAME, exchange, USE_BODY, NOT_OPTIONAL));
+                        getParameter(SOBJECT_NAME, exchange, USE_BODY, NOT_OPTIONAL));
                 break;
 
             case GET_DESCRIPTION:
@@ -100,13 +112,13 @@ public class XmlRestProcessor extends AbstractRestProcessor {
 
                 // need to add alias for Salesforce XML that uses SObject name as root element
                 exchange.setProperty(RESPONSE_ALIAS,
-                    getParameter(SOBJECT_NAME, exchange, USE_BODY, NOT_OPTIONAL));
+                        getParameter(SOBJECT_NAME, exchange, USE_BODY, NOT_OPTIONAL));
                 break;
 
             case GET_SOBJECT:
                 // need to add alias for Salesforce XML that uses SObject name as root element
                 exchange.setProperty(RESPONSE_ALIAS,
-                    getParameter(SOBJECT_NAME, exchange, IGNORE_BODY, NOT_OPTIONAL));
+                        getParameter(SOBJECT_NAME, exchange, IGNORE_BODY, NOT_OPTIONAL));
                 break;
 
             case CREATE_SOBJECT:
@@ -117,7 +129,7 @@ public class XmlRestProcessor extends AbstractRestProcessor {
             case GET_SOBJECT_WITH_ID:
                 // need to add alias for Salesforce XML that uses SObject name as root element
                 exchange.setProperty(RESPONSE_ALIAS,
-                    getParameter(SOBJECT_NAME, exchange, IGNORE_BODY, NOT_OPTIONAL));
+                        getParameter(SOBJECT_NAME, exchange, IGNORE_BODY, NOT_OPTIONAL));
                 break;
 
             case UPSERT_SOBJECT:
@@ -129,7 +141,7 @@ public class XmlRestProcessor extends AbstractRestProcessor {
             case QUERY_MORE:
                 // need to add alias for Salesforce XML that uses SObject name as root element
                 exchange.setProperty(RESPONSE_ALIAS,
-                    "QueryResult");
+                        "QueryResult");
                 break;
 
             case SEARCH:
@@ -162,7 +174,7 @@ public class XmlRestProcessor extends AbstractRestProcessor {
                     final String body = in.getBody(String.class);
                     if (null == body) {
                         String msg = "Unsupported request message body " +
-                            (in.getBody() == null ? null : in.getBody().getClass());
+                                (in.getBody() == null ? null : in.getBody().getClass());
                         throw new SalesforceException(msg, null);
                     } else {
                         request = new ByteArrayInputStream(body.getBytes(StringUtil.__UTF8_CHARSET));

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/streaming/PushTopicHelper.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/streaming/PushTopicHelper.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/streaming/PushTopicHelper.java
index 4e51281..70e8fa4 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/streaming/PushTopicHelper.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/streaming/PushTopicHelper.java
@@ -16,9 +16,11 @@
  */
 package org.apache.camel.component.salesforce.internal.streaming;
 
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
 import org.apache.camel.CamelException;
-import org.codehaus.jackson.map.ObjectMapper;
-import org.eclipse.jetty.http.HttpStatus;
 import org.apache.camel.component.salesforce.SalesforceEndpointConfig;
 import org.apache.camel.component.salesforce.api.SalesforceException;
 import org.apache.camel.component.salesforce.api.dto.CreateSObjectResult;
@@ -26,13 +28,11 @@ import org.apache.camel.component.salesforce.internal.client.RestClient;
 import org.apache.camel.component.salesforce.internal.client.SyncResponseCallback;
 import org.apache.camel.component.salesforce.internal.dto.PushTopic;
 import org.apache.camel.component.salesforce.internal.dto.QueryRecordsPushTopic;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.eclipse.jetty.http.HttpStatus;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.util.concurrent.TimeUnit;
-
 public class PushTopicHelper {
     private static final Logger LOG = LoggerFactory.getLogger(PushTopicHelper.class);
     private static final ObjectMapper objectMapper = new ObjectMapper();
@@ -56,9 +56,9 @@ public class PushTopicHelper {
         try {
             // use SOQL to lookup Topic, since Name is not an external ID!!!
             restClient.query("SELECT Id, Name, Query, ApiVersion, IsActive, " +
-                "NotifyForFields, NotifyForOperations, Description " +
-                "FROM PushTopic WHERE Name = '" + topicName + "'",
-                callback);
+                    "NotifyForFields, NotifyForOperations, Description " +
+                    "FROM PushTopic WHERE Name = '" + topicName + "'",
+                    callback);
 
             if (!callback.await(API_TIMEOUT, TimeUnit.SECONDS)) {
                 throw new SalesforceException("API call timeout!", null);
@@ -67,7 +67,7 @@ public class PushTopicHelper {
                 throw callback.getException();
             }
             QueryRecordsPushTopic records = objectMapper.readValue(callback.getResponse(),
-                QueryRecordsPushTopic.class);
+                    QueryRecordsPushTopic.class);
             if (records.getTotalSize() == 1) {
 
                 PushTopic topic = records.getRecords().get(0);
@@ -75,11 +75,11 @@ public class PushTopicHelper {
 
                 // check if we need to update topic query, notifyForFields or notifyForOperations
                 if (!query.equals(topic.getQuery()) ||
-                    (config.getNotifyForFields() != null &&
-                        !config.getNotifyForFields().equals(topic.getNotifyForFields())) ||
-                    (config.getNotifyForOperations() != null &&
-                        !config.getNotifyForOperations().equals(topic.getNotifyForOperations()))
-                    ) {
+                        (config.getNotifyForFields() != null &&
+                                !config.getNotifyForFields().equals(topic.getNotifyForFields())) ||
+                        (config.getNotifyForOperations() != null &&
+                                !config.getNotifyForOperations().equals(topic.getNotifyForOperations()))
+                        ) {
 
                     if (!config.isUpdateTopic()) {
                         String msg = "Query doesn't match existing Topic and updateTopic is set to false";
@@ -96,17 +96,17 @@ public class PushTopicHelper {
 
         } catch (SalesforceException e) {
             throw new CamelException(
-                String.format("Error retrieving Topic %s: %s", topicName, e.getMessage()),
-                e);
+                    String.format("Error retrieving Topic %s: %s", topicName, e.getMessage()),
+                    e);
         } catch (IOException e) {
             throw new CamelException(
-                String.format("Un-marshaling error retrieving Topic %s: %s", topicName, e.getMessage()),
-                e);
+                    String.format("Un-marshaling error retrieving Topic %s: %s", topicName, e.getMessage()),
+                    e);
         } catch (InterruptedException e) {
             Thread.currentThread().interrupt();
             throw new CamelException(
-                String.format("Un-marshaling error retrieving Topic %s: %s", topicName, e.getMessage()),
-                e);
+                    String.format("Un-marshaling error retrieving Topic %s: %s", topicName, e.getMessage()),
+                    e);
         } finally {
             // close stream to close HttpConnection
             if (callback.getResponse() != null) {
@@ -132,7 +132,7 @@ public class PushTopicHelper {
         final SyncResponseCallback callback = new SyncResponseCallback();
         try {
             restClient.createSObject(PUSH_TOPIC_OBJECT_NAME,
-                new ByteArrayInputStream(objectMapper.writeValueAsBytes(topic)), callback);
+                    new ByteArrayInputStream(objectMapper.writeValueAsBytes(topic)), callback);
 
             if (!callback.await(API_TIMEOUT, TimeUnit.SECONDS)) {
                 throw new SalesforceException("API call timeout!", null);
@@ -144,23 +144,23 @@ public class PushTopicHelper {
             CreateSObjectResult result = objectMapper.readValue(callback.getResponse(), CreateSObjectResult.class);
             if (!result.getSuccess()) {
                 final SalesforceException salesforceException = new SalesforceException(
-                    result.getErrors(), HttpStatus.BAD_REQUEST_400);
+                        result.getErrors(), HttpStatus.BAD_REQUEST_400);
                 throw new CamelException(
-                    String.format("Error creating Topic %s: %s", topicName, result.getErrors()),
-                    salesforceException);
+                        String.format("Error creating Topic %s: %s", topicName, result.getErrors()),
+                        salesforceException);
             }
         } catch (SalesforceException e) {
             throw new CamelException(
-                String.format("Error creating Topic %s: %s", topicName, e.getMessage()),
-                e);
+                    String.format("Error creating Topic %s: %s", topicName, e.getMessage()),
+                    e);
         } catch (IOException e) {
             throw new CamelException(
-                String.format("Un-marshaling error creating Topic %s: %s", topicName, e.getMessage()),
-                e);
+                    String.format("Un-marshaling error creating Topic %s: %s", topicName, e.getMessage()),
+                    e);
         } catch (InterruptedException e) {
             throw new CamelException(
-                String.format("Un-marshaling error creating Topic %s: %s", topicName, e.getMessage()),
-                e);
+                    String.format("Un-marshaling error creating Topic %s: %s", topicName, e.getMessage()),
+                    e);
         } finally {
             if (callback.getResponse() != null) {
                 try {
@@ -185,8 +185,8 @@ public class PushTopicHelper {
             topic.setNotifyForOperations(config.getNotifyForOperations());
 
             restClient.updateSObject("PushTopic", topicId,
-                new ByteArrayInputStream(objectMapper.writeValueAsBytes(topic)),
-                callback);
+                    new ByteArrayInputStream(objectMapper.writeValueAsBytes(topic)),
+                    callback);
 
             if (!callback.await(API_TIMEOUT, TimeUnit.SECONDS)) {
                 throw new SalesforceException("API call timeout!", null);
@@ -197,18 +197,18 @@ public class PushTopicHelper {
 
         } catch (SalesforceException e) {
             throw new CamelException(
-                String.format("Error updating topic %s with query [%s] : %s", topicName, query, e.getMessage()),
-                e);
+                    String.format("Error updating topic %s with query [%s] : %s", topicName, query, e.getMessage()),
+                    e);
         } catch (InterruptedException e) {
             // reset interrupt status
             Thread.currentThread().interrupt();
             throw new CamelException(
-                String.format("Error updating topic %s with query [%s] : %s", topicName, query, e.getMessage()),
-                e);
+                    String.format("Error updating topic %s with query [%s] : %s", topicName, query, e.getMessage()),
+                    e);
         } catch (IOException e) {
             throw new CamelException(
-                String.format("Error updating topic %s with query [%s] : %s", topicName, query, e.getMessage()),
-                e);
+                    String.format("Error updating topic %s with query [%s] : %s", topicName, query, e.getMessage()),
+                    e);
         } finally {
             if (callback.getResponse() != null) {
                 try {

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/streaming/SubscriptionHelper.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/streaming/SubscriptionHelper.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/streaming/SubscriptionHelper.java
index b3bd50f..f31fdda 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/streaming/SubscriptionHelper.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/streaming/SubscriptionHelper.java
@@ -16,8 +16,18 @@
  */
 package org.apache.camel.component.salesforce.internal.streaming;
 
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CountDownLatch;
+
 import org.apache.camel.CamelException;
 import org.apache.camel.Service;
+import org.apache.camel.component.salesforce.SalesforceComponent;
+import org.apache.camel.component.salesforce.SalesforceConsumer;
+import org.apache.camel.component.salesforce.internal.SalesforceSession;
+import org.apache.camel.component.salesforce.internal.client.SalesforceSecurityListener;
 import org.cometd.bayeux.Message;
 import org.cometd.bayeux.client.ClientSessionChannel;
 import org.cometd.client.BayeuxClient;
@@ -27,22 +37,15 @@ import org.eclipse.jetty.client.ContentExchange;
 import org.eclipse.jetty.client.HttpClient;
 import org.eclipse.jetty.http.HttpHeaders;
 import org.eclipse.jetty.http.HttpSchemes;
-import org.apache.camel.component.salesforce.SalesforceComponent;
-import org.apache.camel.component.salesforce.SalesforceConsumer;
-import org.apache.camel.component.salesforce.internal.SalesforceSession;
-import org.apache.camel.component.salesforce.internal.client.SalesforceSecurityListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CountDownLatch;
-
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.cometd.bayeux.Channel.*;
+import static org.cometd.bayeux.Channel.META_CONNECT;
+import static org.cometd.bayeux.Channel.META_HANDSHAKE;
+import static org.cometd.bayeux.Channel.META_SUBSCRIBE;
+import static org.cometd.bayeux.Channel.META_UNSUBSCRIBE;
 import static org.cometd.bayeux.Message.ERROR_FIELD;
 import static org.cometd.bayeux.Message.SUBSCRIPTION_FIELD;
 
@@ -128,11 +131,11 @@ public class SubscriptionHelper implements Service {
                         LOG.debug("Refreshing subscriptions to {} channels on reconnect", listenerMap.size());
                         // reconnected to Salesforce, subscribe to existing channels
                         final Map<SalesforceConsumer, ClientSessionChannel.MessageListener> map =
-                            new HashMap<SalesforceConsumer, ClientSessionChannel.MessageListener>();
+                                new HashMap<SalesforceConsumer, ClientSessionChannel.MessageListener>();
                         map.putAll(listenerMap);
                         listenerMap.clear();
                         for (Map.Entry<SalesforceConsumer, ClientSessionChannel.MessageListener> entry :
-                            map.entrySet()) {
+                                map.entrySet()) {
                             final SalesforceConsumer consumer = entry.getKey();
                             final String topicName = consumer.getTopicName();
                             try {
@@ -140,9 +143,9 @@ public class SubscriptionHelper implements Service {
                             } catch (CamelException e) {
                                 // let the consumer handle the exception
                                 consumer.handleException(
-                                    String.format("Error refreshing subscription to topic [%s]: %s",
-                                        topicName, e.getMessage()),
-                                    e);
+                                        String.format("Error refreshing subscription to topic [%s]: %s",
+                                                topicName, e.getMessage()),
+                                        e);
                             }
                         }
 
@@ -159,15 +162,15 @@ public class SubscriptionHelper implements Service {
         if (!client.waitFor(waitMs, BayeuxClient.State.CONNECTED)) {
             if (handshakeException != null) {
                 throw new CamelException(
-                    String.format("Exception during HANDSHAKE: %s", handshakeException.getMessage()),
-                    handshakeException);
+                        String.format("Exception during HANDSHAKE: %s", handshakeException.getMessage()),
+                        handshakeException);
             } else if (handshakeError != null) {
                 throw new CamelException(String.format("Error during HANDSHAKE: %s", handshakeError));
             } else if (connectError != null) {
                 throw new CamelException(String.format("Error during CONNECT: %s", connectError));
             } else {
                 throw new CamelException(
-                    String.format("Handshake request timeout after %s seconds", CONNECT_TIMEOUT));
+                        String.format("Handshake request timeout after %s seconds", CONNECT_TIMEOUT));
             }
         }
 
@@ -207,17 +210,17 @@ public class SubscriptionHelper implements Service {
                 try {
                     final boolean isHttps = HttpSchemes.HTTPS.equals(String.valueOf(exchange.getScheme()));
                     exchange.setEventListener(new SalesforceSecurityListener(
-                        httpClient.getDestination(exchange.getAddress(), isHttps),
-                        exchange, session, accessToken));
+                            httpClient.getDestination(exchange.getAddress(), isHttps),
+                            exchange, session, accessToken));
                 } catch (IOException e) {
                     throw new RuntimeException(
-                        String.format("Error adding SalesforceSecurityListener to exchange %s", e.getMessage()),
-                        e);
+                            String.format("Error adding SalesforceSecurityListener to exchange %s", e.getMessage()),
+                            e);
                 }
 
                 // add current security token obtained from session
                 exchange.addRequestHeader(HttpHeaders.AUTHORIZATION,
-                "OAuth " + accessToken);
+                        "OAuth " + accessToken);
             }
         };
 
@@ -280,10 +283,10 @@ public class SubscriptionHelper implements Service {
                     String message;
                     if (subscribeError[0] != null) {
                         message = String.format("Error subscribing to topic %s: %s",
-                            topicName, subscribeError[0]);
+                                topicName, subscribeError[0]);
                     } else {
                         message = String.format("Timeout error subscribing to topic %s after %s seconds",
-                            topicName, CHANNEL_TIMEOUT);
+                                topicName, CHANNEL_TIMEOUT);
                     }
                     throw new CamelException(message);
                 }
@@ -347,10 +350,10 @@ public class SubscriptionHelper implements Service {
                         String message;
                         if (unsubscribeError[0] != null) {
                             message = String.format("Error unsubscribing from topic %s: %s",
-                                topicName, unsubscribeError[0]);
+                                    topicName, unsubscribeError[0]);
                         } else {
                             message = String.format("Timeout error unsubscribing from topic %s after %s seconds",
-                                topicName, CHANNEL_TIMEOUT);
+                                    topicName, CHANNEL_TIMEOUT);
                         }
                         throw new CamelException(message);
                     }

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/AbstractSalesforceTestBase.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/AbstractSalesforceTestBase.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/AbstractSalesforceTestBase.java
index 3130a5b..7ce7311 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/AbstractSalesforceTestBase.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/AbstractSalesforceTestBase.java
@@ -16,11 +16,11 @@
  */
 package org.apache.camel.component.salesforce;
 
+import java.io.IOException;
+
 import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.test.junit4.CamelTestSupport;
 import org.apache.camel.component.salesforce.dto.Merchandise__c;
-
-import java.io.IOException;
+import org.apache.camel.test.junit4.CamelTestSupport;
 
 public abstract class AbstractSalesforceTestBase extends CamelTestSupport {
 

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/BulkApiBatchIntegrationTest.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/BulkApiBatchIntegrationTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/BulkApiBatchIntegrationTest.java
index bed6a0c..5406c16 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/BulkApiBatchIntegrationTest.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/BulkApiBatchIntegrationTest.java
@@ -16,17 +16,21 @@
  */
 package org.apache.camel.component.salesforce;
 
-import org.apache.camel.component.salesforce.api.dto.bulk.*;
-import org.apache.camel.component.salesforce.dto.Merchandise__c;
-import org.junit.experimental.theories.DataPoints;
-import org.junit.experimental.theories.Theory;
-
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.camel.component.salesforce.api.dto.bulk.BatchInfo;
+import org.apache.camel.component.salesforce.api.dto.bulk.BatchStateEnum;
+import org.apache.camel.component.salesforce.api.dto.bulk.ContentType;
+import org.apache.camel.component.salesforce.api.dto.bulk.JobInfo;
+import org.apache.camel.component.salesforce.api.dto.bulk.OperationEnum;
+import org.apache.camel.component.salesforce.dto.Merchandise__c;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theory;
+
 public class BulkApiBatchIntegrationTest extends AbstractBulkApiTestBase {
     private static final String TEST_REQUEST_XML = "/test-request.xml";
     private static final String TEST_REQUEST_CSV = "/test-request.csv";

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/BulkApiJobIntegrationTest.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/BulkApiJobIntegrationTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/BulkApiJobIntegrationTest.java
index 9010aa4..c3e52c3 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/BulkApiJobIntegrationTest.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/BulkApiJobIntegrationTest.java
@@ -16,6 +16,9 @@
  */
 package org.apache.camel.component.salesforce;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.apache.camel.component.salesforce.api.dto.bulk.ContentType;
 import org.apache.camel.component.salesforce.api.dto.bulk.JobInfo;
 import org.apache.camel.component.salesforce.api.dto.bulk.JobStateEnum;
@@ -24,9 +27,6 @@ import org.apache.camel.component.salesforce.dto.Merchandise__c;
 import org.junit.experimental.theories.DataPoints;
 import org.junit.experimental.theories.Theory;
 
-import java.util.ArrayList;
-import java.util.List;
-
 public class BulkApiJobIntegrationTest extends AbstractBulkApiTestBase {
 
     // test jobs for testJobLifecycle

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/BulkApiQueryIntegrationTest.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/BulkApiQueryIntegrationTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/BulkApiQueryIntegrationTest.java
index 0f22ee1..bcfd062 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/BulkApiQueryIntegrationTest.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/BulkApiQueryIntegrationTest.java
@@ -16,14 +16,18 @@
  */
 package org.apache.camel.component.salesforce;
 
-import org.apache.camel.component.salesforce.api.dto.bulk.*;
+import java.io.InputStream;
+import java.util.List;
+
+import org.apache.camel.component.salesforce.api.dto.bulk.BatchInfo;
+import org.apache.camel.component.salesforce.api.dto.bulk.BatchStateEnum;
+import org.apache.camel.component.salesforce.api.dto.bulk.ContentType;
+import org.apache.camel.component.salesforce.api.dto.bulk.JobInfo;
+import org.apache.camel.component.salesforce.api.dto.bulk.OperationEnum;
 import org.apache.camel.component.salesforce.dto.Merchandise__c;
 import org.junit.experimental.theories.DataPoints;
 import org.junit.experimental.theories.Theory;
 
-import java.io.InputStream;
-import java.util.List;
-
 public class BulkApiQueryIntegrationTest extends AbstractBulkApiTestBase {
 
     @DataPoints

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/LoginConfigHelper.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/LoginConfigHelper.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/LoginConfigHelper.java
index 1f8b480..365639d 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/LoginConfigHelper.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/LoginConfigHelper.java
@@ -16,13 +16,13 @@
  */
 package org.apache.camel.component.salesforce;
 
-import org.junit.Assert;
-
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.Properties;
 
+import org.junit.Assert;
+
 public class LoginConfigHelper extends Assert {
 
     private static final String TEST_LOGIN_PROPERTIES = "test-salesforce-login.properties";
@@ -33,9 +33,9 @@ public class LoginConfigHelper extends Assert {
         Properties properties = new Properties();
         InputStream stream = new FileInputStream(TEST_LOGIN_PROPERTIES);
         if (null == stream) {
-            throw new IllegalArgumentException("Create a properties file named " +
-                TEST_LOGIN_PROPERTIES + " with clientId, clientSecret, userName, and password" +
-                " for a Salesforce account with the Merchandise object from Salesforce Guides.");
+            throw new IllegalArgumentException("Create a properties file named "
+                + TEST_LOGIN_PROPERTIES + " with clientId, clientSecret, userName, and password"
+                + " for a Salesforce account with the Merchandise object from Salesforce Guides.");
         }
         properties.load(stream);
 

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/RestApiIntegrationTest.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/RestApiIntegrationTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/RestApiIntegrationTest.java
index a33d17d..a7510e3 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/RestApiIntegrationTest.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/RestApiIntegrationTest.java
@@ -16,8 +16,24 @@
  */
 package org.apache.camel.component.salesforce;
 
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.nio.channels.Channels;
+import java.nio.channels.FileChannel;
+import java.nio.channels.ReadableByteChannel;
+import java.util.HashMap;
+import java.util.List;
+
 import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.component.salesforce.api.dto.*;
+import org.apache.camel.component.salesforce.api.dto.CreateSObjectResult;
+import org.apache.camel.component.salesforce.api.dto.GlobalObjects;
+import org.apache.camel.component.salesforce.api.dto.RestResources;
+import org.apache.camel.component.salesforce.api.dto.SObjectBasicInfo;
+import org.apache.camel.component.salesforce.api.dto.SObjectDescription;
+import org.apache.camel.component.salesforce.api.dto.SearchResult;
+import org.apache.camel.component.salesforce.api.dto.SearchResults;
+import org.apache.camel.component.salesforce.api.dto.Version;
+import org.apache.camel.component.salesforce.api.dto.Versions;
 import org.apache.camel.component.salesforce.dto.Document;
 import org.apache.camel.component.salesforce.dto.Line_Item__c;
 import org.apache.camel.component.salesforce.dto.Merchandise__c;
@@ -26,14 +42,6 @@ import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.nio.channels.Channels;
-import java.nio.channels.FileChannel;
-import java.nio.channels.ReadableByteChannel;
-import java.util.HashMap;
-import java.util.List;
-
 public class RestApiIntegrationTest extends AbstractSalesforceTestBase {
 
     private static final Logger LOG = LoggerFactory.getLogger(RestApiIntegrationTest.class);
@@ -153,27 +161,27 @@ public class RestApiIntegrationTest extends AbstractSalesforceTestBase {
     }
 
     private void doTestCreateUpdateDelete(String suffix) throws InterruptedException {
-        Merchandise__c merchandise__c = new Merchandise__c();
-        merchandise__c.setName("Wee Wee Wee Plane");
-        merchandise__c.setDescription__c("Microlite plane");
-        merchandise__c.setPrice__c(2000.0);
-        merchandise__c.setTotal_Inventory__c(50.0);
+        Merchandise__c merchandise = new Merchandise__c();
+        merchandise.setName("Wee Wee Wee Plane");
+        merchandise.setDescription__c("Microlite plane");
+        merchandise.setPrice__c(2000.0);
+        merchandise.setTotal_Inventory__c(50.0);
         CreateSObjectResult result = template().requestBody("direct:CreateSObject" + suffix,
-            merchandise__c, CreateSObjectResult.class);
+            merchandise, CreateSObjectResult.class);
         assertNotNull(result);
         assertTrue("Create success", result.getSuccess());
         LOG.debug("Create: " + result);
 
         // test JSON update
         // make the plane cheaper
-        merchandise__c.setPrice__c(1500.0);
+        merchandise.setPrice__c(1500.0);
         // change inventory to half
-        merchandise__c.setTotal_Inventory__c(25.0);
+        merchandise.setTotal_Inventory__c(25.0);
         // also need to set the Id
-        merchandise__c.setId(result.getId());
+        merchandise.setId(result.getId());
 
         assertNull(template().requestBodyAndHeader("direct:UpdateSObject" + suffix,
-            merchandise__c, SalesforceEndpointConfig.SOBJECT_ID, result.getId()));
+            merchandise, SalesforceEndpointConfig.SOBJECT_ID, result.getId()));
         LOG.debug("Update successful");
 
         // delete the newly created SObject
@@ -189,34 +197,34 @@ public class RestApiIntegrationTest extends AbstractSalesforceTestBase {
 
     private void doTestCreateUpdateDeleteWithId(String suffix) throws InterruptedException {
         // get line item with Name 1
-        Line_Item__c line_item__c = template().requestBody("direct:getSObjectWithId" + suffix, TEST_LINE_ITEM_ID,
+        Line_Item__c lineItem = template().requestBody("direct:getSObjectWithId" + suffix, TEST_LINE_ITEM_ID,
             Line_Item__c.class);
-        assertNotNull(line_item__c);
-        LOG.debug("GetWithId: {}", line_item__c);
+        assertNotNull(lineItem);
+        LOG.debug("GetWithId: {}", lineItem);
 
         // test insert with id
         // set the unit price and sold
-        line_item__c.setUnit_Price__c(1000.0);
-        line_item__c.setUnits_Sold__c(50.0);
+        lineItem.setUnit_Price__c(1000.0);
+        lineItem.setUnits_Sold__c(50.0);
         // update line item with Name NEW_LINE_ITEM_ID
-        line_item__c.setName(NEW_LINE_ITEM_ID);
+        lineItem.setName(NEW_LINE_ITEM_ID);
 
         CreateSObjectResult result = template().requestBodyAndHeader("direct:upsertSObject" + suffix,
-            line_item__c, SalesforceEndpointConfig.SOBJECT_EXT_ID_VALUE, NEW_LINE_ITEM_ID,
+            lineItem, SalesforceEndpointConfig.SOBJECT_EXT_ID_VALUE, NEW_LINE_ITEM_ID,
             CreateSObjectResult.class);
         assertNotNull(result);
         assertTrue(result.getSuccess());
         LOG.debug("CreateWithId: {}", result);
 
         // clear read only parent type fields
-        line_item__c.setInvoice_Statement__c(null);
-        line_item__c.setMerchandise__c(null);
+        lineItem.setInvoice_Statement__c(null);
+        lineItem.setMerchandise__c(null);
         // change the units sold
-        line_item__c.setUnits_Sold__c(25.0);
+        lineItem.setUnits_Sold__c(25.0);
 
         // update line item with Name NEW_LINE_ITEM_ID
         result = template().requestBodyAndHeader("direct:upsertSObject" + suffix,
-            line_item__c, SalesforceEndpointConfig.SOBJECT_EXT_ID_VALUE, NEW_LINE_ITEM_ID,
+            lineItem, SalesforceEndpointConfig.SOBJECT_EXT_ID_VALUE, NEW_LINE_ITEM_ID,
             CreateSObjectResult.class);
         assertNull(result);
         LOG.debug("UpdateWithId: {}", result);

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/StreamingApiIntegrationTest.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/StreamingApiIntegrationTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/StreamingApiIntegrationTest.java
index d72ca2b..f80c2f6 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/StreamingApiIntegrationTest.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/StreamingApiIntegrationTest.java
@@ -37,8 +37,7 @@ public class StreamingApiIntegrationTest extends AbstractSalesforceTestBase {
 
         Merchandise__c merchandise = new Merchandise__c();
         merchandise.setName("TestNotification");
-        merchandise.setDescription__c("Merchandise for testing Streaming API updated on " +
-            new DateTime().toString());
+        merchandise.setDescription__c("Merchandise for testing Streaming API updated on " + new DateTime().toString());
         merchandise.setPrice__c(9.99);
         merchandise.setTotal_Inventory__c(1000.0);
         CreateSObjectResult result = template().requestBody(
@@ -80,10 +79,9 @@ public class StreamingApiIntegrationTest extends AbstractSalesforceTestBase {
             public void configure() throws Exception {
 
                 // test topic subscription
-                from("salesforce:CamelTestTopic?notifyForFields=ALL&notifyForOperations=ALL&" +
-//                    "sObjectClass=org.apache.camel.component.salesforce.dto.Merchandise__c&" +
-                    "sObjectName=Merchandise__c&" +
-                    "updateTopic=true&sObjectQuery=SELECT Id, Name FROM Merchandise__c").
+                from("salesforce:CamelTestTopic?notifyForFields=ALL&notifyForOperations=ALL&"
+                    + "sObjectName=Merchandise__c&"
+                    + "updateTopic=true&sObjectQuery=SELECT Id, Name FROM Merchandise__c").
                     to("mock:CamelTestTopic");
 
                 // route for creating test record
@@ -92,8 +90,8 @@ public class StreamingApiIntegrationTest extends AbstractSalesforceTestBase {
 
                 // route for finding test topic
                 from("direct:query").
-                    to("salesforce:query?sObjectQuery=SELECT Id FROM PushTopic WHERE Name = 'CamelTestTopic'&" +
-                        "sObjectClass=org.apache.camel.component.salesforce.internal.dto.QueryRecordsPushTopic");
+                    to("salesforce:query?sObjectQuery=SELECT Id FROM PushTopic WHERE Name = 'CamelTestTopic'&"
+                        + "sObjectClass=org.apache.camel.component.salesforce.internal.dto.QueryRecordsPushTopic");
 
                 // route for removing test record
                 from("direct:deleteSObjectWithId").

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/Document.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/Document.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/Document.java
index 090f2b1..a448bb3 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/Document.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/Document.java
@@ -5,8 +5,8 @@
 package org.apache.camel.component.salesforce.dto;
 
 import com.thoughtworks.xstream.annotations.XStreamAlias;
-import org.codehaus.jackson.annotate.JsonProperty;
 import org.apache.camel.component.salesforce.api.dto.AbstractSObjectBase;
+import org.codehaus.jackson.annotate.JsonProperty;
 
 /**
  * Salesforce DTO for SObject Document

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/Line_Item__c.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/Line_Item__c.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/Line_Item__c.java
index 1bf3668..31bc4ce 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/Line_Item__c.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/Line_Item__c.java
@@ -17,8 +17,8 @@
 package org.apache.camel.component.salesforce.dto;
 
 import com.thoughtworks.xstream.annotations.XStreamAlias;
-import org.codehaus.jackson.annotate.JsonProperty;
 import org.apache.camel.component.salesforce.api.dto.AbstractSObjectBase;
+import org.codehaus.jackson.annotate.JsonProperty;
 
 @XStreamAlias("Line_Item__c")
 public class Line_Item__c extends AbstractSObjectBase {

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/Merchandise__c.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/Merchandise__c.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/Merchandise__c.java
index 3e3d36a..f7a76db 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/Merchandise__c.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/Merchandise__c.java
@@ -17,8 +17,8 @@
 package org.apache.camel.component.salesforce.dto;
 
 import com.thoughtworks.xstream.annotations.XStreamAlias;
-import org.codehaus.jackson.annotate.JsonProperty;
 import org.apache.camel.component.salesforce.api.dto.AbstractSObjectBase;
+import org.codehaus.jackson.annotate.JsonProperty;
 
 @XStreamAlias("Merchandise__c")
 public class Merchandise__c extends AbstractSObjectBase {

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/QueryRecordsLine_Item__c.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/QueryRecordsLine_Item__c.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/QueryRecordsLine_Item__c.java
index a2d00cb..34dcad4 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/QueryRecordsLine_Item__c.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/QueryRecordsLine_Item__c.java
@@ -16,11 +16,11 @@
  */
 package org.apache.camel.component.salesforce.dto;
 
+import java.util.List;
+
 import com.thoughtworks.xstream.annotations.XStreamImplicit;
 import org.apache.camel.component.salesforce.api.dto.AbstractQueryRecordsBase;
 
-import java.util.List;
-
 public class QueryRecordsLine_Item__c extends AbstractQueryRecordsBase {
     @XStreamImplicit
     private List<Line_Item__c> records;

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/internal/SessionIntegrationTest.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/internal/SessionIntegrationTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/internal/SessionIntegrationTest.java
index 5e5ab5f..c8159b8 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/internal/SessionIntegrationTest.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/internal/SessionIntegrationTest.java
@@ -16,9 +16,9 @@
  */
 package org.apache.camel.component.salesforce.internal;
 
+import org.apache.camel.component.salesforce.LoginConfigHelper;
 import org.eclipse.jetty.client.HttpClient;
 import org.eclipse.jetty.client.RedirectListener;
-import org.apache.camel.component.salesforce.LoginConfigHelper;
 import org.junit.Assert;
 import org.junit.Test;
 import org.slf4j.Logger;


[07/11] CAMEL-6428: camel-salesforce component. Thanks to Dhiraj Bokde for the contribution.

Posted by da...@apache.org.
http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/NotifyForOperationsEnum.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/NotifyForOperationsEnum.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/NotifyForOperationsEnum.java
new file mode 100644
index 0000000..807fef5
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/NotifyForOperationsEnum.java
@@ -0,0 +1,52 @@
+/**
+ * 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.internal.dto;
+
+import org.codehaus.jackson.annotate.JsonCreator;
+import org.codehaus.jackson.annotate.JsonValue;
+
+/**
+ * Salesforce Enumeration DTO for picklist NotifyForOperations
+ */
+public enum NotifyForOperationsEnum {
+
+    CREATE("Create"),
+    UPDATE("Update"),
+    ALL("All");
+
+    final String value;
+
+    private NotifyForOperationsEnum(String value) {
+        this.value = value;
+    }
+
+    @JsonValue
+    public String value() {
+        return this.value;
+    }
+
+    @JsonCreator
+    public static NotifyForOperationsEnum forValue(String value) {
+        for (NotifyForOperationsEnum e : NotifyForOperationsEnum.values()) {
+            if (e.value.equals(value)) {
+                return e;
+            }
+        }
+        throw new IllegalArgumentException(value);
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/PushTopic.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/PushTopic.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/PushTopic.java
new file mode 100644
index 0000000..2135a16
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/PushTopic.java
@@ -0,0 +1,100 @@
+/**
+ * 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.internal.dto;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamConverter;
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.apache.camel.component.salesforce.api.PicklistEnumConverter;
+import org.apache.camel.component.salesforce.api.dto.AbstractSObjectBase;
+
+/**
+ * Salesforce DTO for SObject PushTopic
+ */
+@XStreamAlias("PushTopic")
+public class PushTopic extends AbstractSObjectBase {
+
+    private String Query;
+    private Double ApiVersion;
+    private Boolean IsActive;
+    @XStreamConverter(PicklistEnumConverter.class)
+    private NotifyForFieldsEnum NotifyForFields;
+    @XStreamConverter(PicklistEnumConverter.class)
+    private NotifyForOperationsEnum NotifyForOperations;
+    private String Description;
+
+    @JsonProperty("Query")
+    public String getQuery() {
+        return this.Query;
+    }
+
+    @JsonProperty("Query")
+    public void setQuery(String Query) {
+        this.Query = Query;
+    }
+
+    @JsonProperty("ApiVersion")
+    public Double getApiVersion() {
+        return this.ApiVersion;
+    }
+
+    @JsonProperty("ApiVersion")
+    public void setApiVersion(Double ApiVersion) {
+        this.ApiVersion = ApiVersion;
+    }
+
+    @JsonProperty("IsActive")
+    public Boolean getIsActive() {
+        return this.IsActive;
+    }
+
+    @JsonProperty("IsActive")
+    public void setIsActive(Boolean IsActive) {
+        this.IsActive = IsActive;
+    }
+
+    @JsonProperty("NotifyForFields")
+    public NotifyForFieldsEnum getNotifyForFields() {
+        return this.NotifyForFields;
+    }
+
+    @JsonProperty("NotifyForFields")
+    public void setNotifyForFields(NotifyForFieldsEnum NotifyForFields) {
+        this.NotifyForFields = NotifyForFields;
+    }
+
+    @JsonProperty("NotifyForOperations")
+    public NotifyForOperationsEnum getNotifyForOperations() {
+        return this.NotifyForOperations;
+    }
+
+    @JsonProperty("NotifyForOperations")
+    public void setNotifyForOperations(NotifyForOperationsEnum NotifyForOperations) {
+        this.NotifyForOperations = NotifyForOperations;
+    }
+
+    @JsonProperty("Description")
+    public String getDescription() {
+        return this.Description;
+    }
+
+    @JsonProperty("Description")
+    public void setDescription(String Description) {
+        this.Description = Description;
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/QueryRecordsPushTopic.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/QueryRecordsPushTopic.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/QueryRecordsPushTopic.java
new file mode 100644
index 0000000..4adc13c
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/QueryRecordsPushTopic.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.internal.dto;
+
+import com.thoughtworks.xstream.annotations.XStreamImplicit;
+import org.apache.camel.component.salesforce.api.dto.AbstractQueryRecordsBase;
+
+import java.util.List;
+
+/**
+ * Salesforce Query Records DTO for PushTopic
+ */
+public class QueryRecordsPushTopic extends AbstractQueryRecordsBase {
+    @XStreamImplicit
+    private List<PushTopic> records;
+
+    public List<PushTopic> getRecords() {
+        return records;
+    }
+
+    public void setRecords(List<PushTopic> records) {
+        this.records = records;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/RestErrors.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/RestErrors.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/RestErrors.java
new file mode 100644
index 0000000..caf59fe
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/RestErrors.java
@@ -0,0 +1,41 @@
+/**
+ * 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.internal.dto;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamImplicit;
+import org.apache.camel.component.salesforce.api.dto.RestError;
+
+import java.util.List;
+
+/**
+ * DTO for Salesforce REST errors
+ */
+@XStreamAlias("Errors")
+public class RestErrors {
+
+    @XStreamImplicit(itemFieldName = "Error")
+    private List<RestError> errors;
+
+    public List<RestError> getErrors() {
+        return errors;
+    }
+
+    public void setErrors(List<RestError> errors) {
+        this.errors = errors;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/AbstractRestProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/AbstractRestProcessor.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/AbstractRestProcessor.java
new file mode 100644
index 0000000..1e40d18
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/AbstractRestProcessor.java
@@ -0,0 +1,538 @@
+/**
+ * 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.internal.processor;
+
+import org.apache.camel.AsyncCallback;
+import org.apache.camel.Exchange;
+import org.apache.camel.util.ServiceHelper;
+import org.apache.camel.component.salesforce.SalesforceEndpoint;
+import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.api.dto.AbstractSObjectBase;
+import org.apache.camel.component.salesforce.internal.PayloadFormat;
+import org.apache.camel.component.salesforce.internal.client.DefaultRestClient;
+import org.apache.camel.component.salesforce.internal.client.RestClient;
+
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.*;
+
+public abstract class AbstractRestProcessor extends AbstractSalesforceProcessor {
+
+    protected static final String RESPONSE_CLASS = AbstractRestProcessor.class.getName() + ".responseClass";
+
+    private RestClient restClient;
+    private Map<String, Class<?>> classMap;
+
+    public AbstractRestProcessor(SalesforceEndpoint endpoint) throws SalesforceException {
+        super(endpoint);
+
+        final PayloadFormat payloadFormat = endpoint.getConfiguration().getPayloadFormat();
+
+        this.restClient = new DefaultRestClient(httpClient, endpointConfigMap.get(API_VERSION),
+            payloadFormat.toString().toLowerCase() , session);
+
+        this.classMap = endpoint.getComponent().getClassMap();
+    }
+
+    @Override
+    public void start() throws Exception {
+        ServiceHelper.startService(restClient);
+    }
+
+    @Override
+    public void stop() throws Exception {
+        ServiceHelper.stopService(restClient);
+    }
+
+    @Override
+    public final boolean process(final Exchange exchange, final AsyncCallback callback) {
+
+        // pre-process request message
+        try {
+            processRequest(exchange);
+        } catch (SalesforceException e) {
+            exchange.setException(e);
+            callback.done(true);
+            return true;
+        } catch (RuntimeException e) {
+            exchange.setException(new SalesforceException(e.getMessage(), e));
+            callback.done(true);
+            return true;
+        }
+
+        // call Salesforce asynchronously
+        try {
+
+            // call Operation using REST client
+            switch (operationName) {
+                case GET_VERSIONS:
+                    restClient.getVersions(new RestClient.ResponseCallback() {
+                        @Override
+                        public void onResponse(InputStream response, SalesforceException exception) {
+                            // process response entity and create out message
+                            processResponse(exchange, response, exception, callback);
+                        }
+                    });
+                    break;
+
+                case GET_RESOURCES:
+                    restClient.getResources(new RestClient.ResponseCallback() {
+                        @Override
+                        public void onResponse(InputStream response, SalesforceException exception) {
+                            processResponse(exchange, response, exception, callback);
+                        }
+                    });
+                    break;
+
+                case GET_GLOBAL_OBJECTS:
+                    restClient.getGlobalObjects(new RestClient.ResponseCallback() {
+                        @Override
+                        public void onResponse(InputStream response, SalesforceException exception) {
+                            processResponse(exchange, response, exception, callback);
+                        }
+                    });
+                    break;
+
+                case GET_BASIC_INFO:
+                    String sObjectName = getParameter(SOBJECT_NAME, exchange, USE_BODY, NOT_OPTIONAL);
+                    restClient.getBasicInfo(sObjectName, new RestClient.ResponseCallback() {
+                        @Override
+                        public void onResponse(InputStream response, SalesforceException exception) {
+                            processResponse(exchange, response, exception, callback);
+                        }
+                    });
+                    break;
+
+                case GET_DESCRIPTION:
+                    sObjectName = getParameter(SOBJECT_NAME, exchange, USE_BODY, NOT_OPTIONAL);
+                    restClient.getDescription(sObjectName, new RestClient.ResponseCallback() {
+                        @Override
+                        public void onResponse(InputStream response, SalesforceException exception) {
+                            processResponse(exchange, response, exception, callback);
+                        }
+                    });
+                    break;
+
+                case GET_SOBJECT:
+                {
+                    String sObjectIdValue;
+                    // determine parameters from input AbstractSObject
+                    final AbstractSObjectBase sObjectBase = exchange.getIn().getBody(AbstractSObjectBase.class);
+                    if (sObjectBase != null) {
+                        sObjectName = sObjectBase.getClass().getSimpleName();
+                        sObjectIdValue = sObjectBase.getId();
+                    } else {
+                        sObjectName = getParameter(SOBJECT_NAME, exchange, IGNORE_BODY, NOT_OPTIONAL);
+                        sObjectIdValue = getParameter(SOBJECT_ID, exchange, USE_BODY, NOT_OPTIONAL);
+                    }
+                    final String sObjectId = sObjectIdValue;
+
+                    // use sObject name to load class
+                    setResponseClass(exchange, sObjectName);
+
+                    // get optional field list
+                    String fieldsValue = getParameter(SOBJECT_FIELDS, exchange, IGNORE_BODY, IS_OPTIONAL);
+                    String[] fields = null;
+                    if (fieldsValue != null) {
+                        fields = fieldsValue.split(",");
+                    }
+
+                    restClient.getSObject(sObjectName, sObjectId, fields, new RestClient.ResponseCallback() {
+                        @Override
+                        public void onResponse(InputStream response, SalesforceException exception) {
+                            processResponse(exchange, response, exception, callback);
+                            restoreFields(exchange, sObjectBase, sObjectId, null, null);
+                        }
+                    });
+
+                    break;
+                }
+
+                case CREATE_SOBJECT:
+                {
+                    // determine parameters from input AbstractSObject
+                    AbstractSObjectBase sObjectBase = exchange.getIn().getBody(AbstractSObjectBase.class);
+                    if (sObjectBase != null) {
+                        sObjectName = sObjectBase.getClass().getSimpleName();
+                    } else {
+                        sObjectName = getParameter(SOBJECT_NAME, exchange, IGNORE_BODY, NOT_OPTIONAL);
+                    }
+
+                    restClient.createSObject(sObjectName, getRequestStream(exchange),
+                        new RestClient.ResponseCallback() {
+                        @Override
+                        public void onResponse(InputStream response, SalesforceException exception) {
+                            processResponse(exchange, response, exception, callback);
+                        }
+                    });
+
+                    break;
+                }
+
+                case UPDATE_SOBJECT:
+                {
+                    // determine parameters from input AbstractSObject
+                    final AbstractSObjectBase sObjectBase = exchange.getIn().getBody(AbstractSObjectBase.class);
+                    String sObjectId;
+                    if (sObjectBase != null) {
+                        sObjectName = sObjectBase.getClass().getSimpleName();
+                        // remember the sObject Id
+                        sObjectId = sObjectBase.getId();
+                        // clear base object fields, which cannot be updated
+                        sObjectBase.clearBaseFields();
+                    } else {
+                        sObjectName = getParameter(SOBJECT_NAME, exchange, IGNORE_BODY, NOT_OPTIONAL);
+                        sObjectId = getParameter(SOBJECT_ID, exchange, IGNORE_BODY, NOT_OPTIONAL);
+                    }
+
+                    final String finalsObjectId = sObjectId;
+                    restClient.updateSObject(sObjectName, sObjectId, getRequestStream(exchange),
+                        new RestClient.ResponseCallback() {
+                            @Override
+                            public void onResponse(InputStream response, SalesforceException exception) {
+                                processResponse(exchange, response, exception, callback);
+                                restoreFields(exchange, sObjectBase, finalsObjectId, null, null);
+                            }
+                        });
+
+                    break;
+                }
+
+                case DELETE_SOBJECT:
+                {
+                    // determine parameters from input AbstractSObject
+                    final AbstractSObjectBase sObjectBase = exchange.getIn().getBody(AbstractSObjectBase.class);
+                    String sObjectIdValue;
+                    if (sObjectBase != null) {
+                        sObjectName = sObjectBase.getClass().getSimpleName();
+                        sObjectIdValue = sObjectBase.getId();
+                    } else {
+                        sObjectName = getParameter(SOBJECT_NAME, exchange, IGNORE_BODY, NOT_OPTIONAL);
+                        sObjectIdValue = getParameter(SOBJECT_ID, exchange, USE_BODY, NOT_OPTIONAL);
+                    }
+                    final String sObjectId = sObjectIdValue;
+
+                    restClient.deleteSObject(sObjectName, sObjectId, new RestClient.ResponseCallback() {
+                        @Override
+                        public void onResponse(InputStream response, SalesforceException exception) {
+                            processResponse(exchange, response, exception, callback);
+                            restoreFields(exchange, sObjectBase, sObjectId, null, null);
+                        }
+                    });
+                    break;
+                }
+
+                case GET_SOBJECT_WITH_ID:
+                {
+                    Object oldValue = null;
+                    String sObjectExtIdValue;
+                    final String sObjectExtIdName = getParameter(SOBJECT_EXT_ID_NAME,
+                        exchange, IGNORE_BODY, NOT_OPTIONAL);
+
+                    // determine parameters from input AbstractSObject
+                    final AbstractSObjectBase sObjectBase = exchange.getIn().getBody(AbstractSObjectBase.class);
+                    if (sObjectBase != null) {
+                        sObjectName = sObjectBase.getClass().getSimpleName();
+                        oldValue = getAndClearPropertyValue(sObjectBase, sObjectExtIdName);
+                        sObjectExtIdValue = oldValue.toString();
+                    } else {
+                        sObjectName = getParameter(SOBJECT_NAME, exchange, IGNORE_BODY, NOT_OPTIONAL);
+                        sObjectExtIdValue = getParameter(SOBJECT_EXT_ID_VALUE, exchange, USE_BODY, NOT_OPTIONAL);
+                    }
+
+                    // use sObject name to load class
+                    setResponseClass(exchange, sObjectName);
+
+                    final Object finalOldValue = oldValue;
+                    restClient.getSObjectWithId(sObjectName, sObjectExtIdName, sObjectExtIdValue,
+                        new RestClient.ResponseCallback() {
+                            @Override
+                            public void onResponse(InputStream response, SalesforceException exception) {
+                                processResponse(exchange, response, exception, callback);
+                                restoreFields(exchange, sObjectBase, null, sObjectExtIdName, finalOldValue);
+                            }
+                        });
+
+                    break;
+                }
+
+                case UPSERT_SOBJECT:
+                {
+                    String sObjectExtIdValue;
+                    final String sObjectExtIdName = getParameter(SOBJECT_EXT_ID_NAME, exchange,
+                        IGNORE_BODY, NOT_OPTIONAL);
+
+                    // determine parameters from input AbstractSObject
+                    Object oldValue = null;
+                    final AbstractSObjectBase sObjectBase = exchange.getIn().getBody(AbstractSObjectBase.class);
+                    if (sObjectBase != null) {
+                        sObjectName = sObjectBase.getClass().getSimpleName();
+                        oldValue = getAndClearPropertyValue(sObjectBase, sObjectExtIdName);
+                        sObjectExtIdValue = oldValue.toString();
+                        // clear base object fields, which cannot be updated
+                        sObjectBase.clearBaseFields();
+                    } else {
+                        sObjectName = getParameter(SOBJECT_NAME, exchange, IGNORE_BODY, NOT_OPTIONAL);
+                        sObjectExtIdValue = getParameter(SOBJECT_EXT_ID_VALUE, exchange, IGNORE_BODY, NOT_OPTIONAL);
+                    }
+
+                    final Object finalOldValue = oldValue;
+                    restClient.upsertSObject(sObjectName, sObjectExtIdName, sObjectExtIdValue,
+                        getRequestStream(exchange), new RestClient.ResponseCallback() {
+                        @Override
+                        public void onResponse(InputStream response, SalesforceException exception) {
+                            processResponse(exchange, response, exception, callback);
+                            restoreFields(exchange, sObjectBase, null, sObjectExtIdName, finalOldValue);
+                        }
+                    });
+
+                    break;
+                }
+
+                case DELETE_SOBJECT_WITH_ID:
+                {
+                    final String sObjectExtIdName = getParameter(SOBJECT_EXT_ID_NAME, exchange, IGNORE_BODY, NOT_OPTIONAL);
+
+                    // determine parameters from input AbstractSObject
+                    Object oldValue = null;
+                    final AbstractSObjectBase sObjectBase = exchange.getIn().getBody(AbstractSObjectBase.class);
+                    String sObjectExtIdValue;
+                    if (sObjectBase != null) {
+                        sObjectName = sObjectBase.getClass().getSimpleName();
+                        oldValue = getAndClearPropertyValue(sObjectBase, sObjectExtIdName);
+                        sObjectExtIdValue = oldValue.toString();
+                    } else {
+                        sObjectName = getParameter(SOBJECT_NAME, exchange, IGNORE_BODY, NOT_OPTIONAL);
+                        sObjectExtIdValue = getParameter(SOBJECT_EXT_ID_VALUE, exchange, USE_BODY, NOT_OPTIONAL);
+                    }
+
+                    final Object finalOldValue = oldValue;
+                    restClient.deleteSObjectWithId(sObjectName, sObjectExtIdName, sObjectExtIdValue,
+                        new RestClient.ResponseCallback() {
+                            @Override
+                            public void onResponse(InputStream response, SalesforceException exception) {
+                                processResponse(exchange, response, exception, callback);
+                                restoreFields(exchange, sObjectBase, null, sObjectExtIdName, finalOldValue);
+                            }
+                        });
+
+                    break;
+                }
+
+                case GET_BLOB_FIELD:
+                {
+                    // get blob field name
+                    final String sObjectBlobFieldName = getParameter(SOBJECT_BLOB_FIELD_NAME,
+                        exchange, IGNORE_BODY, NOT_OPTIONAL);
+
+                    // determine parameters from input AbstractSObject
+                    final AbstractSObjectBase sObjectBase = exchange.getIn().getBody(AbstractSObjectBase.class);
+                    String sObjectIdValue;
+                    if (sObjectBase != null) {
+                        sObjectName = sObjectBase.getClass().getSimpleName();
+                        sObjectIdValue = sObjectBase.getId();
+                    } else {
+                        sObjectName = getParameter(SOBJECT_NAME, exchange, IGNORE_BODY, NOT_OPTIONAL);
+                        sObjectIdValue = getParameter(SOBJECT_ID, exchange, USE_BODY, NOT_OPTIONAL);
+                    }
+                    final String sObjectId = sObjectIdValue;
+
+                    restClient.getBlobField(sObjectName, sObjectId, sObjectBlobFieldName,
+                        new RestClient.ResponseCallback() {
+                            @Override
+                            public void onResponse(InputStream response, SalesforceException exception) {
+                                processResponse(exchange, response, exception, callback);
+                                restoreFields(exchange, sObjectBase, sObjectId, null, null);
+                            }
+                        });
+                    break;
+                }
+
+                case QUERY:
+                    final String sObjectQuery = getParameter(SOBJECT_QUERY, exchange, USE_BODY, NOT_OPTIONAL);
+
+                    // use sObject name to load class
+                    setResponseClass(exchange, null);
+
+                    restClient.query(sObjectQuery, new RestClient.ResponseCallback() {
+                        @Override
+                        public void onResponse(InputStream response, SalesforceException exception) {
+                            processResponse(exchange, response, exception, callback);
+                        }
+                    });
+                    break;
+
+                case QUERY_MORE:
+                    // reuse SOBJECT_QUERY parameter name for nextRecordsUrl
+                    final String nextRecordsUrl = getParameter(SOBJECT_QUERY, exchange, USE_BODY, NOT_OPTIONAL);
+
+                    // use custom response class property
+                    setResponseClass(exchange, null);
+
+                    restClient.queryMore(nextRecordsUrl, new RestClient.ResponseCallback() {
+                        @Override
+                        public void onResponse(InputStream response, SalesforceException exception) {
+                            processResponse(exchange, response, exception, callback);
+                        }
+                    });
+                    break;
+
+                case SEARCH:
+                    final String sObjectSearch = getParameter(SOBJECT_SEARCH, exchange, USE_BODY, NOT_OPTIONAL);
+
+                    restClient.search(sObjectSearch, new RestClient.ResponseCallback() {
+                        @Override
+                        public void onResponse(InputStream response, SalesforceException exception) {
+                            processResponse(exchange, response, exception, callback);
+                        }
+                    });
+                    break;
+
+            }
+
+        } catch (SalesforceException e) {
+            exchange.setException(new SalesforceException(
+                String.format("Error processing %s: [%s] \"%s\"",
+                    operationName, e.getStatusCode(), e.getMessage()),
+                e));
+            callback.done(true);
+            return true;
+        } catch (RuntimeException e) {
+            exchange.setException(new SalesforceException(
+                String.format("Unexpected Error processing %s: \"%s\"",
+                    operationName, e.getMessage()),
+                e));
+            callback.done(true);
+            return true;
+        }
+
+        // continue routing asynchronously
+        return false;
+    }
+
+    private void restoreFields(Exchange exchange, AbstractSObjectBase sObjectBase,
+                               String sObjectId, String sObjectExtIdName, Object oldValue) {
+        // restore fields
+        if (sObjectBase != null) {
+            // restore the Id if it was cleared
+            if (sObjectId != null) {
+                sObjectBase.setId(sObjectId);
+            }
+            // restore the external id if it was cleared
+            if (sObjectExtIdName != null && oldValue != null) {
+                try {
+                    setPropertyValue(sObjectBase, sObjectExtIdName, oldValue);
+                } catch (SalesforceException e) {
+                    // YES, the exchange may fail if the property cannot be reset!!!
+                    exchange.setException(e);
+                }
+            }
+        }
+    }
+
+    private void setPropertyValue(AbstractSObjectBase sObjectBase, String name, Object value) throws SalesforceException {
+        try {
+            // set the value with the set method
+            Method setMethod = sObjectBase.getClass().getMethod("set" + name, value.getClass());
+            setMethod.invoke(sObjectBase, value);
+        } catch (NoSuchMethodException e) {
+            throw new SalesforceException(
+                String.format("SObject %s does not have a field %s",
+                    sObjectBase.getClass().getName(), name),
+                e);
+        } catch (InvocationTargetException e) {
+            throw new SalesforceException(
+                String.format("Error setting value %s.%s",
+                    sObjectBase.getClass().getSimpleName(), name),
+                e);
+        } catch (IllegalAccessException e) {
+            throw new SalesforceException(
+                String.format("Error accessing value %s.%s",
+                    sObjectBase.getClass().getSimpleName(), name),
+                e);
+        }
+    }
+
+    private Object getAndClearPropertyValue(AbstractSObjectBase sObjectBase, String propertyName) throws SalesforceException {
+        try {
+            // obtain the value using the get method
+            Method getMethod = sObjectBase.getClass().getMethod("get" + propertyName);
+            Object value = getMethod.invoke(sObjectBase);
+
+            // clear the value with the set method
+            Method setMethod = sObjectBase.getClass().getMethod("set" + propertyName, getMethod.getReturnType());
+            setMethod.invoke(sObjectBase, new Object[] { null });
+
+            return value;
+        } catch (NoSuchMethodException e) {
+            throw new SalesforceException(
+                String.format("SObject %s does not have a field %s",
+                    sObjectBase.getClass().getSimpleName(), propertyName),
+                e);
+        } catch (InvocationTargetException e) {
+            throw new SalesforceException(
+                String.format("Error getting/setting value %s.%s",
+                    sObjectBase.getClass().getSimpleName(), propertyName),
+                e);
+        } catch (IllegalAccessException e) {
+            throw new SalesforceException(
+                String.format("Error accessing value %s.%s",
+                    sObjectBase.getClass().getSimpleName(), propertyName),
+                e);
+        }
+    }
+
+    // pre-process request message
+    protected abstract void processRequest(Exchange exchange) throws SalesforceException;
+
+    // get request stream from In message
+    protected abstract InputStream getRequestStream(Exchange exchange) throws SalesforceException;
+
+    private void setResponseClass(Exchange exchange, String sObjectName) throws SalesforceException {
+        Class<?> sObjectClass;
+
+        if (sObjectName != null) {
+            // lookup class from class map
+            sObjectClass = classMap.get(sObjectName);
+            if (null == sObjectClass) {
+                throw new SalesforceException(String.format("No class found for SObject %s", sObjectName), null);
+            }
+
+        } else {
+
+            // use custom response class property
+            final String className = getParameter(SOBJECT_CLASS, exchange, IGNORE_BODY, NOT_OPTIONAL);
+            try {
+                sObjectClass = endpoint.getComponent().getCamelContext()
+                    .getClassResolver().resolveMandatoryClass(className);
+            } catch (ClassNotFoundException e) {
+                throw new SalesforceException(
+                    String.format("SObject class not found %s, %s",
+                        className, e.getMessage()),
+                    e);
+            }
+        }
+        exchange.setProperty(RESPONSE_CLASS, sObjectClass);
+    }
+
+    // process response entity and set out message in exchange
+    protected abstract void processResponse(Exchange exchange, InputStream responseEntity, SalesforceException ex, AsyncCallback callback);
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/AbstractSalesforceProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/AbstractSalesforceProcessor.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/AbstractSalesforceProcessor.java
new file mode 100644
index 0000000..e784458
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/AbstractSalesforceProcessor.java
@@ -0,0 +1,84 @@
+/**
+ * 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.internal.processor;
+
+import org.apache.camel.AsyncCallback;
+import org.apache.camel.Exchange;
+import org.eclipse.jetty.client.HttpClient;
+import org.apache.camel.component.salesforce.SalesforceComponent;
+import org.apache.camel.component.salesforce.SalesforceEndpoint;
+import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.internal.OperationName;
+import org.apache.camel.component.salesforce.internal.SalesforceSession;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+
+public abstract class AbstractSalesforceProcessor implements SalesforceProcessor {
+
+    protected static final boolean NOT_OPTIONAL = false;
+    protected static final boolean IS_OPTIONAL = true;
+    protected static final boolean USE_BODY = true;
+    protected static final boolean IGNORE_BODY = false;
+    protected final Logger LOG = LoggerFactory.getLogger(this.getClass());
+
+    protected final SalesforceEndpoint endpoint;
+    protected final Map<String, String> endpointConfigMap;
+
+    protected final OperationName operationName;
+    protected final SalesforceSession session;
+    protected final HttpClient httpClient;
+
+    public AbstractSalesforceProcessor(SalesforceEndpoint endpoint) {
+        this.endpoint = endpoint;
+        this.operationName = endpoint.getOperationName();
+        this.endpointConfigMap = endpoint.getConfiguration().toValueMap();
+
+        final SalesforceComponent component = endpoint.getComponent();
+        this.session = component.getSession();
+        this.httpClient = endpoint.getConfiguration().getHttpClient();
+    }
+
+    @Override
+    public abstract boolean process(Exchange exchange, AsyncCallback callback);
+
+    /**
+     * Gets value for a parameter from header, endpoint config, or exchange body (optional).
+     *
+     * @param exchange exchange to inspect
+     * @param convertInBody converts In body to String value if true
+     * @param propName name of property
+     * @param optional if {@code true} returns null, otherwise throws RestException
+     * @return value of property, or {@code null} for optional parameters if not found.
+     * @throws org.apache.camel.component.salesforce.api.SalesforceException if the property can't be found.
+     */
+    protected final String getParameter(String propName, Exchange exchange, boolean convertInBody, boolean optional) throws SalesforceException {
+        String propValue = exchange.getIn().getHeader(propName, String.class);
+        propValue = propValue == null ? endpointConfigMap.get(propName) : propValue;
+        propValue = (propValue == null && convertInBody) ? exchange.getIn().getBody(String.class) : propValue;
+
+        // error if property was not set
+        if (propValue == null && !optional) {
+            String msg = "Missing property " + propName;
+            throw new SalesforceException(msg, null);
+        }
+
+        return propValue;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/BulkApiProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/BulkApiProcessor.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/BulkApiProcessor.java
new file mode 100644
index 0000000..6e070f7
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/BulkApiProcessor.java
@@ -0,0 +1,377 @@
+/**
+ * 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.internal.processor;
+
+import org.apache.camel.*;
+import org.apache.camel.converter.stream.StreamCacheConverter;
+import org.apache.camel.util.ServiceHelper;
+import org.apache.camel.component.salesforce.SalesforceEndpoint;
+import org.apache.camel.component.salesforce.SalesforceEndpointConfig;
+import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.api.dto.bulk.*;
+import org.apache.camel.component.salesforce.internal.client.BulkApiClient;
+import org.apache.camel.component.salesforce.internal.client.DefaultBulkApiClient;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.*;
+
+public class BulkApiProcessor extends AbstractSalesforceProcessor {
+
+    private BulkApiClient bulkClient;
+
+    public BulkApiProcessor(SalesforceEndpoint endpoint) throws SalesforceException {
+        super(endpoint);
+
+        this.bulkClient = new DefaultBulkApiClient(
+            endpointConfigMap.get(SalesforceEndpointConfig.API_VERSION), session, httpClient);
+    }
+
+    @Override
+    public boolean process(final Exchange exchange, final AsyncCallback callback) {
+
+        boolean done = false;
+        try {
+            switch (operationName) {
+                case CREATE_JOB:
+                    JobInfo jobBody = exchange.getIn().getMandatoryBody(JobInfo.class);
+                    bulkClient.createJob(jobBody, new BulkApiClient.JobInfoResponseCallback() {
+                        @Override
+                        public void onResponse(JobInfo jobInfo, SalesforceException ex) {
+                            processResponse(exchange, jobInfo, ex, callback);
+                        }
+                    });
+
+                    break;
+
+                case GET_JOB:
+                    jobBody = exchange.getIn().getBody(JobInfo.class);
+                    String jobId;
+                    if (jobBody != null) {
+                        jobId = jobBody.getId();
+                    } else {
+                        jobId = getParameter(JOB_ID, exchange, USE_BODY, NOT_OPTIONAL);
+                    }
+                    bulkClient.getJob(jobId, new BulkApiClient.JobInfoResponseCallback() {
+                        @Override
+                        public void onResponse(JobInfo jobInfo, SalesforceException ex) {
+                            processResponse(exchange, jobInfo, ex, callback);
+                        }
+                    });
+
+                    break;
+
+                case CLOSE_JOB:
+                    jobBody = exchange.getIn().getBody(JobInfo.class);
+                    if (jobBody != null) {
+                        jobId = jobBody.getId();
+                    } else {
+                        jobId = getParameter(JOB_ID, exchange, USE_BODY, NOT_OPTIONAL);
+                    }
+                    bulkClient.closeJob(jobId, new BulkApiClient.JobInfoResponseCallback() {
+                        @Override
+                        public void onResponse(JobInfo jobInfo, SalesforceException ex) {
+                            processResponse(exchange, jobInfo, ex, callback);
+                        }
+                    });
+
+                    break;
+
+                case ABORT_JOB:
+                    jobBody = exchange.getIn().getBody(JobInfo.class);
+                    if (jobBody != null) {
+                        jobId = jobBody.getId();
+                    } else {
+                        jobId = getParameter(JOB_ID, exchange, USE_BODY, NOT_OPTIONAL);
+                    }
+                    bulkClient.abortJob(jobId, new BulkApiClient.JobInfoResponseCallback() {
+                        @Override
+                        public void onResponse(JobInfo jobInfo, SalesforceException ex) {
+                            processResponse(exchange, jobInfo, ex, callback);
+                        }
+                    });
+
+                    break;
+
+                case CREATE_BATCH:
+                    // since request is in the body, use headers or endpoint params
+                    ContentType contentType = ContentType.fromValue(
+                        getParameter(CONTENT_TYPE, exchange, IGNORE_BODY, NOT_OPTIONAL));
+                    jobId = getParameter(JOB_ID, exchange, IGNORE_BODY, NOT_OPTIONAL);
+
+                    InputStream request;
+                    try {
+                        request = exchange.getIn().getMandatoryBody(InputStream.class);
+                    } catch (CamelException e) {
+                        String msg = "Error preparing batch request: " + e.getMessage();
+                        throw new SalesforceException(msg, e);
+                    }
+
+                    bulkClient.createBatch(request, jobId, contentType, new BulkApiClient.BatchInfoResponseCallback() {
+                        @Override
+                        public void onResponse(BatchInfo batchInfo, SalesforceException ex) {
+                            processResponse(exchange, batchInfo, ex, callback);
+                        }
+                    });
+
+                    break;
+
+                case GET_BATCH:
+                    BatchInfo batchBody = exchange.getIn().getBody(BatchInfo.class);
+                    String batchId;
+                    if (batchBody != null) {
+                        jobId = batchBody.getJobId();
+                        batchId = batchBody.getId();
+                    } else {
+                        jobId = getParameter(JOB_ID, exchange, IGNORE_BODY, NOT_OPTIONAL);
+                        batchId = getParameter(BATCH_ID, exchange, USE_BODY, NOT_OPTIONAL);
+                    }
+                    bulkClient.getBatch(jobId, batchId, new BulkApiClient.BatchInfoResponseCallback() {
+                        @Override
+                        public void onResponse(BatchInfo batchInfo, SalesforceException ex) {
+                            processResponse(exchange, batchInfo, ex, callback);
+                        }
+                    });
+
+                    break;
+
+                case GET_ALL_BATCHES:
+                    jobBody = exchange.getIn().getBody(JobInfo.class);
+                    if (jobBody != null) {
+                        jobId = jobBody.getId();
+                    } else {
+                        jobId = getParameter(JOB_ID, exchange, USE_BODY, NOT_OPTIONAL);
+                    }
+                    bulkClient.getAllBatches(jobId, new BulkApiClient.BatchInfoListResponseCallback() {
+                        @Override
+                        public void onResponse(List<BatchInfo> batchInfoList, SalesforceException ex) {
+                            processResponse(exchange, batchInfoList, ex, callback);
+                        }
+                    });
+
+                    break;
+
+                case GET_REQUEST:
+                    batchBody = exchange.getIn().getBody(BatchInfo.class);
+                    if (batchBody != null) {
+                        jobId = batchBody.getJobId();
+                        batchId = batchBody.getId();
+                    } else {
+                        jobId = getParameter(JOB_ID, exchange, IGNORE_BODY, NOT_OPTIONAL);
+                        batchId = getParameter(BATCH_ID, exchange, USE_BODY, NOT_OPTIONAL);
+                    }
+
+                    bulkClient.getRequest(jobId, batchId, new BulkApiClient.StreamResponseCallback() {
+                        @Override
+                        public void onResponse(InputStream inputStream, SalesforceException ex) {
+                            // read the request stream into a StreamCache temp file
+                            // ensures the connection is read
+                            StreamCache body = null;
+                            if (inputStream != null) {
+                                try {
+                                    body = StreamCacheConverter.convertToStreamCache(inputStream, exchange);
+                                } catch (IOException e) {
+                                    String msg = "Error retrieving batch request: " + e.getMessage();
+                                    ex = new SalesforceException(msg, e);
+                                } finally {
+                                    // close the input stream to release the Http connection
+                                    try {
+                                        inputStream.close();
+                                    } catch (IOException ignore) {
+                                    }
+                                }
+                            }
+                            processResponse(exchange, body, ex, callback);
+                        }
+                    });
+
+                    break;
+
+                case GET_RESULTS:
+                    batchBody = exchange.getIn().getBody(BatchInfo.class);
+                    if (batchBody != null) {
+                        jobId = batchBody.getJobId();
+                        batchId = batchBody.getId();
+                    } else {
+                        jobId = getParameter(JOB_ID, exchange, IGNORE_BODY, NOT_OPTIONAL);
+                        batchId = getParameter(BATCH_ID, exchange, USE_BODY, NOT_OPTIONAL);
+                    }
+                    bulkClient.getResults(jobId, batchId, new BulkApiClient.StreamResponseCallback() {
+                        @Override
+                        public void onResponse(InputStream inputStream, SalesforceException ex) {
+                            // read the result stream into a StreamCache temp file
+                            // ensures the connection is read
+                            StreamCache body = null;
+                            if (inputStream != null) {
+                                try {
+                                    body = StreamCacheConverter.convertToStreamCache(inputStream, exchange);
+                                } catch (IOException e) {
+                                    String msg = "Error retrieving batch results: " + e.getMessage();
+                                    ex = new SalesforceException(msg, e);
+                                } finally {
+                                    // close the input stream to release the Http connection
+                                    try {
+                                        inputStream.close();
+                                    } catch (IOException ignore) {
+                                    }
+                                }
+                            }
+                            processResponse(exchange, body, ex, callback);
+                        }
+                    });
+
+                    break;
+
+                case CREATE_BATCH_QUERY:
+                    jobBody = exchange.getIn().getBody(JobInfo.class);
+                    String soqlQuery;
+                    if (jobBody != null) {
+                        jobId = jobBody.getId();
+                        contentType = jobBody.getContentType();
+                        // use SOQL query from header or endpoint config
+                        soqlQuery = getParameter(SOBJECT_QUERY, exchange, IGNORE_BODY, NOT_OPTIONAL);
+                    } else {
+                        jobId = getParameter(JOB_ID, exchange, IGNORE_BODY, NOT_OPTIONAL);
+                        contentType = ContentType.fromValue(
+                            getParameter(CONTENT_TYPE, exchange, IGNORE_BODY, NOT_OPTIONAL));
+                        // reuse SOBJECT_QUERY property
+                        soqlQuery = getParameter(SOBJECT_QUERY, exchange, USE_BODY, NOT_OPTIONAL);
+                    }
+                    bulkClient.createBatchQuery(jobId, soqlQuery, contentType,
+                        new BulkApiClient.BatchInfoResponseCallback() {
+                        @Override
+                        public void onResponse(BatchInfo batchInfo, SalesforceException ex) {
+                            processResponse(exchange, batchInfo, ex, callback);
+                        }
+                    });
+
+                    break;
+
+                case GET_QUERY_RESULT_IDS:
+                    batchBody = exchange.getIn().getBody(BatchInfo.class);
+                    if (batchBody != null) {
+                        jobId = batchBody.getJobId();
+                        batchId = batchBody.getId();
+                    } else {
+                        jobId = getParameter(JOB_ID, exchange, IGNORE_BODY, NOT_OPTIONAL);
+                        batchId = getParameter(BATCH_ID, exchange, USE_BODY, NOT_OPTIONAL);
+                    }
+                    bulkClient.getQueryResultIds(jobId, batchId, new BulkApiClient.QueryResultIdsCallback() {
+                        @Override
+                        public void onResponse(List<String> ids, SalesforceException ex) {
+                            processResponse(exchange, ids, ex, callback);
+                        }
+                    });
+
+                    break;
+
+                case GET_QUERY_RESULT:
+                    batchBody = exchange.getIn().getBody(BatchInfo.class);
+                    String resultId;
+                    if (batchBody != null) {
+                        jobId = batchBody.getJobId();
+                        batchId = batchBody.getId();
+                        resultId = getParameter(RESULT_ID, exchange, IGNORE_BODY, NOT_OPTIONAL);
+                    } else {
+                        jobId = getParameter(JOB_ID, exchange, IGNORE_BODY, NOT_OPTIONAL);
+                        batchId = getParameter(BATCH_ID, exchange, IGNORE_BODY, NOT_OPTIONAL);
+                        resultId = getParameter(RESULT_ID, exchange, USE_BODY, NOT_OPTIONAL);
+                    }
+                    bulkClient.getQueryResult(jobId, batchId, resultId, new BulkApiClient.StreamResponseCallback() {
+                        @Override
+                        public void onResponse(InputStream inputStream, SalesforceException ex) {
+                            StreamCache body = null;
+                            if (inputStream != null) {
+                                // read the result stream into a StreamCache temp file
+                                // ensures the connection is read
+                                try {
+                                    body = StreamCacheConverter.convertToStreamCache(inputStream, exchange);
+                                } catch (IOException e) {
+                                    String msg = "Error retrieving query result: " + e.getMessage();
+                                    ex = new SalesforceException(msg, e);
+                                } finally {
+                                    // close the input stream to release the Http connection
+                                    try {
+                                        inputStream.close();
+                                    } catch (IOException e) {
+                                        // ignore
+                                    }
+                                }
+                            }
+                            processResponse(exchange, body, ex, callback);
+                        }
+                    });
+
+                    break;
+            }
+
+        } catch (SalesforceException e) {
+            exchange.setException(new SalesforceException(
+                String.format("Error processing %s: [%s] \"%s\"",
+                    operationName, e.getStatusCode(), e.getMessage()),
+                e));
+            callback.done(true);
+            done = true;
+        } catch (InvalidPayloadException e) {
+            exchange.setException(new SalesforceException(
+                String.format("Unexpected Error processing %s: \"%s\"",
+                    operationName, e.getMessage()),
+                e));
+            callback.done(true);
+            done = true;
+        } catch (RuntimeException e) {
+            exchange.setException(new SalesforceException(
+                String.format("Unexpected Error processing %s: \"%s\"",
+                    operationName, e.getMessage()),
+                e));
+            callback.done(true);
+            done = true;
+        }
+
+        // continue routing asynchronously if false
+        return done;
+    }
+
+    private void processResponse(Exchange exchange, Object body, SalesforceException ex, AsyncCallback callback) {
+        final Message out = exchange.getOut();
+        if (ex != null) {
+            exchange.setException(ex);
+        } else {
+            out.setBody(body);
+        }
+
+        // copy headers and attachments
+        out.getHeaders().putAll(exchange.getIn().getHeaders());
+        out.getAttachments().putAll(exchange.getIn().getAttachments());
+
+        // signal exchange completion
+        callback.done(false);
+    }
+
+    @Override
+    public void start() throws Exception {
+        ServiceHelper.startService(bulkClient);
+    }
+
+    @Override
+    public void stop() throws Exception {
+        // stop the client
+        ServiceHelper.stopService(bulkClient);
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/JsonRestProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/JsonRestProcessor.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/JsonRestProcessor.java
new file mode 100644
index 0000000..3ac32c6
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/JsonRestProcessor.java
@@ -0,0 +1,180 @@
+/**
+ * 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.internal.processor;
+
+import org.apache.camel.AsyncCallback;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.SerializationConfig;
+import org.codehaus.jackson.type.TypeReference;
+import org.eclipse.jetty.util.StringUtil;
+import org.apache.camel.component.salesforce.SalesforceEndpoint;
+import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.api.dto.*;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+public class JsonRestProcessor extends AbstractRestProcessor {
+
+    // it is ok to use a single thread safe ObjectMapper
+    private final ObjectMapper objectMapper;
+    private static final String RESPONSE_TYPE = JsonRestProcessor.class.getName() + ".responseType";
+
+    public JsonRestProcessor(SalesforceEndpoint endpoint) throws SalesforceException {
+        super(endpoint);
+
+        this.objectMapper = new ObjectMapper();
+        // enable date time support including Joda DateTime
+        this.objectMapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false);
+    }
+
+    @Override
+    protected void processRequest(Exchange exchange) {
+
+        switch (operationName) {
+            case GET_VERSIONS:
+                // handle in built response types
+                exchange.setProperty(RESPONSE_TYPE, new TypeReference<List<Version>>() {});
+                break;
+
+            case GET_RESOURCES:
+                // handle in built response types
+                exchange.setProperty(RESPONSE_CLASS, RestResources.class);
+                break;
+
+            case GET_GLOBAL_OBJECTS:
+                // handle in built response types
+                exchange.setProperty(RESPONSE_CLASS, GlobalObjects.class);
+                break;
+
+            case GET_BASIC_INFO:
+                // handle in built response types
+                exchange.setProperty(RESPONSE_CLASS, SObjectBasicInfo.class);
+                break;
+
+            case GET_DESCRIPTION:
+                // handle in built response types
+                exchange.setProperty(RESPONSE_CLASS, SObjectDescription.class);
+                break;
+
+            case CREATE_SOBJECT:
+                // handle known response type
+                exchange.setProperty(RESPONSE_CLASS, CreateSObjectResult.class);
+                break;
+
+            case UPSERT_SOBJECT:
+                // handle known response type
+                exchange.setProperty(RESPONSE_CLASS, CreateSObjectResult.class);
+                break;
+
+            case SEARCH:
+                // handle known response type
+                exchange.setProperty(RESPONSE_TYPE, new TypeReference<List<SearchResult>>() {});
+                break;
+
+        }
+    }
+
+    @Override
+    protected InputStream getRequestStream(Exchange exchange) throws SalesforceException {
+        try {
+            InputStream request;
+            Message in = exchange.getIn();
+            request = in.getBody(InputStream.class);
+            if (request == null) {
+                AbstractSObjectBase sObject = in.getBody(AbstractSObjectBase.class);
+                if (sObject != null) {
+                    // marshall the SObject
+                    ByteArrayOutputStream out = new ByteArrayOutputStream();
+                    objectMapper.writeValue(out, sObject);
+                    request = new ByteArrayInputStream(out.toByteArray());
+                } else {
+                    // if all else fails, get body as String
+                    final String body = in.getBody(String.class);
+                    if (null == body) {
+                        String msg = "Unsupported request message body " +
+                            (in.getBody() == null ? null : in.getBody().getClass());
+                        throw new SalesforceException(msg, null);
+                    } else {
+                        request = new ByteArrayInputStream(body.getBytes(StringUtil.__UTF8_CHARSET));
+                    }
+                }
+            }
+
+            return request;
+
+        } catch (IOException e) {
+            String msg = "Error marshaling request: " + e.getMessage();
+            throw new SalesforceException(msg, e);
+        }
+    }
+
+    @Override
+    protected void processResponse(Exchange exchange, InputStream responseEntity, SalesforceException ex, AsyncCallback callback) {
+
+        // process JSON response for TypeReference
+        try {
+            // do we need to un-marshal a response
+            if (responseEntity != null) {
+                Object response = null;
+                Class<?> responseClass = exchange.getProperty(RESPONSE_CLASS, Class.class);
+                if (responseClass != null) {
+                    response = objectMapper.readValue(responseEntity, responseClass);
+                } else {
+                    TypeReference<?> responseType = exchange.getProperty(RESPONSE_TYPE, TypeReference.class);
+                    if (responseType != null) {
+                        response = objectMapper.readValue(responseEntity, responseType);
+                    } else {
+                        // return the response as a stream, for getBlobField
+                        response = responseEntity;
+                    }
+                }
+                exchange.getOut().setBody(response);
+            } else {
+                exchange.setException(ex);
+            }
+            // copy headers and attachments
+            exchange.getOut().getHeaders().putAll(exchange.getIn().getHeaders());
+            exchange.getOut().getAttachments().putAll(exchange.getIn().getAttachments());
+        } catch (IOException e) {
+            String msg = "Error parsing JSON response: " + e.getMessage();
+            exchange.setException(new SalesforceException(msg, e));
+        } finally {
+            // cleanup temporary exchange headers
+            exchange.removeProperty(RESPONSE_CLASS);
+            exchange.removeProperty(RESPONSE_TYPE);
+
+            // consume response entity
+            try {
+                if (responseEntity != null) {
+                    responseEntity.close();
+                }
+            } catch (IOException ignored) {
+            }
+
+            // notify callback that exchange is done
+            callback.done(false);
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/SalesforceProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/SalesforceProcessor.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/SalesforceProcessor.java
new file mode 100644
index 0000000..36f77f6
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/SalesforceProcessor.java
@@ -0,0 +1,27 @@
+/**
+ * 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.internal.processor;
+
+import org.apache.camel.AsyncCallback;
+import org.apache.camel.Exchange;
+import org.apache.camel.Service;
+
+public interface SalesforceProcessor extends Service {
+
+    boolean process(Exchange exchange, AsyncCallback callback);
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/XmlRestProcessor.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/XmlRestProcessor.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/XmlRestProcessor.java
new file mode 100644
index 0000000..75449b6
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/XmlRestProcessor.java
@@ -0,0 +1,240 @@
+/**
+ * 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.internal.processor;
+
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.XStreamException;
+import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+import com.thoughtworks.xstream.io.naming.NoNameCoder;
+import com.thoughtworks.xstream.io.xml.CompactWriter;
+import com.thoughtworks.xstream.io.xml.XppDriver;
+import com.thoughtworks.xstream.mapper.CachingMapper;
+import com.thoughtworks.xstream.mapper.CannotResolveClassException;
+import org.apache.camel.AsyncCallback;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.eclipse.jetty.util.StringUtil;
+import org.apache.camel.component.salesforce.SalesforceEndpoint;
+import org.apache.camel.component.salesforce.api.JodaTimeConverter;
+import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.api.dto.*;
+
+import java.io.*;
+
+import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.SOBJECT_NAME;
+
+public class XmlRestProcessor extends AbstractRestProcessor {
+
+    // although XStream is generally thread safe, because of the way we use aliases
+    // for GET_BASIC_INFO and GET_DESCRIPTION, we need to use a ThreadLocal
+    // not very efficient when both JSON and XML are used together with a single Thread pool
+    // but this will do for now
+    private static ThreadLocal<XStream> xStream =
+        new ThreadLocal<XStream>() {
+            @Override
+            protected XStream initialValue() {
+                // use NoNameCoder to avoid escaping __ in custom field names
+                // and CompactWriter to avoid pretty printing
+                XStream result = new XStream(new XppDriver(new NoNameCoder()) {
+                    @Override
+                    public HierarchicalStreamWriter createWriter(Writer out) {
+                        return new CompactWriter(out, getNameCoder());
+                    }
+
+                });
+                result.registerConverter(new JodaTimeConverter());
+                return result;
+            }
+        };
+
+    private static final String RESPONSE_ALIAS = XmlRestProcessor.class.getName() + ".responseAlias";
+
+    public XmlRestProcessor(SalesforceEndpoint endpoint) throws SalesforceException {
+        super(endpoint);
+
+    }
+
+    @Override
+    protected void processRequest(Exchange exchange) throws SalesforceException {
+
+        switch (operationName) {
+            case GET_VERSIONS:
+                exchange.setProperty(RESPONSE_CLASS, Versions.class);
+                break;
+
+            case GET_RESOURCES:
+                exchange.setProperty(RESPONSE_CLASS, RestResources.class);
+                break;
+
+            case GET_GLOBAL_OBJECTS:
+                // handle in built response types
+                exchange.setProperty(RESPONSE_CLASS, GlobalObjects.class);
+                break;
+
+            case GET_BASIC_INFO:
+                // handle in built response types
+                exchange.setProperty(RESPONSE_CLASS, SObjectBasicInfo.class);
+
+                // need to add alias for Salesforce XML that uses SObject name as root element
+                exchange.setProperty(RESPONSE_ALIAS,
+                    getParameter(SOBJECT_NAME, exchange, USE_BODY, NOT_OPTIONAL));
+                break;
+
+            case GET_DESCRIPTION:
+                // handle in built response types
+                exchange.setProperty(RESPONSE_CLASS, SObjectDescription.class);
+
+                // need to add alias for Salesforce XML that uses SObject name as root element
+                exchange.setProperty(RESPONSE_ALIAS,
+                    getParameter(SOBJECT_NAME, exchange, USE_BODY, NOT_OPTIONAL));
+                break;
+
+            case GET_SOBJECT:
+                // need to add alias for Salesforce XML that uses SObject name as root element
+                exchange.setProperty(RESPONSE_ALIAS,
+                    getParameter(SOBJECT_NAME, exchange, IGNORE_BODY, NOT_OPTIONAL));
+                break;
+
+            case CREATE_SOBJECT:
+                // handle known response type
+                exchange.setProperty(RESPONSE_CLASS, CreateSObjectResult.class);
+                break;
+
+            case GET_SOBJECT_WITH_ID:
+                // need to add alias for Salesforce XML that uses SObject name as root element
+                exchange.setProperty(RESPONSE_ALIAS,
+                    getParameter(SOBJECT_NAME, exchange, IGNORE_BODY, NOT_OPTIONAL));
+                break;
+
+            case UPSERT_SOBJECT:
+                // handle known response type
+                exchange.setProperty(RESPONSE_CLASS, CreateSObjectResult.class);
+                break;
+
+            case QUERY:
+            case QUERY_MORE:
+                // need to add alias for Salesforce XML that uses SObject name as root element
+                exchange.setProperty(RESPONSE_ALIAS,
+                    "QueryResult");
+                break;
+
+            case SEARCH:
+                // handle known response type
+                exchange.setProperty(RESPONSE_CLASS, SearchResults.class);
+                break;
+
+        }
+
+    }
+
+    protected InputStream getRequestStream(Exchange exchange) throws SalesforceException {
+        final XStream localXStream = xStream.get();
+        try {
+            // get request stream from In message
+            Message in = exchange.getIn();
+            InputStream request = in.getBody(InputStream.class);
+            if (request == null) {
+                AbstractSObjectBase sObject = in.getBody(AbstractSObjectBase.class);
+                if (sObject != null) {
+                    // marshall the SObject
+                    // first process annotations on the class, for things like alias, etc.
+                    localXStream.processAnnotations(sObject.getClass());
+                    ByteArrayOutputStream out = new ByteArrayOutputStream();
+                    // make sure we write the XML with the right encoding
+                    localXStream.toXML(sObject, new OutputStreamWriter(out, StringUtil.__UTF8_CHARSET));
+                    request = new ByteArrayInputStream(out.toByteArray());
+                } else {
+                    // if all else fails, get body as String
+                    final String body = in.getBody(String.class);
+                    if (null == body) {
+                        String msg = "Unsupported request message body " +
+                            (in.getBody() == null ? null : in.getBody().getClass());
+                        throw new SalesforceException(msg, null);
+                    } else {
+                        request = new ByteArrayInputStream(body.getBytes(StringUtil.__UTF8_CHARSET));
+                    }
+                }
+            }
+            return request;
+        } catch (XStreamException e) {
+            String msg = "Error marshaling request: " + e.getMessage();
+            throw new SalesforceException(msg, e);
+        }
+    }
+
+    @Override
+    protected void processResponse(Exchange exchange, InputStream responseEntity,
+                                   SalesforceException exception, AsyncCallback callback) {
+        final XStream localXStream = xStream.get();
+        try {
+            // do we need to un-marshal a response
+            if (responseEntity != null) {
+                final Class<?> responseClass = exchange.getProperty(RESPONSE_CLASS, Class.class);
+                Object response;
+                if (responseClass != null) {
+                    // its ok to call this multiple times, as xstream ignores duplicate calls
+                    localXStream.processAnnotations(responseClass);
+                    final String responseAlias = exchange.getProperty(RESPONSE_ALIAS, String.class);
+                    if (responseAlias != null) {
+                        // extremely dirty, need to flush entire cache if its holding on to an old alias!!!
+                        final CachingMapper mapper = (CachingMapper) localXStream.getMapper();
+                        try {
+                            if (mapper.realClass(responseAlias) != responseClass) {
+                                mapper.flushCache();
+                            }
+                        } catch (CannotResolveClassException ignore) {
+                        }
+                        localXStream.alias(responseAlias, responseClass);
+                    }
+                    response = responseClass.newInstance();
+                    localXStream.fromXML(responseEntity, response);
+                } else {
+                    // return the response as a stream, for getBlobField
+                    response = responseEntity;
+                }
+                exchange.getOut().setBody(response);
+            } else {
+                exchange.setException(exception);
+            }
+            // copy headers and attachments
+            exchange.getOut().getHeaders().putAll(exchange.getIn().getHeaders());
+            exchange.getOut().getAttachments().putAll(exchange.getIn().getAttachments());
+        } catch (XStreamException e) {
+            String msg = "Error parsing XML response: " + e.getMessage();
+            exchange.setException(new SalesforceException(msg, e));
+        } catch (Exception e) {
+            String msg = "Error creating XML response: " + e.getMessage();
+            exchange.setException(new SalesforceException(msg, e));
+        } finally {
+            // cleanup temporary exchange headers
+            exchange.removeProperty(RESPONSE_CLASS);
+            exchange.removeProperty(RESPONSE_ALIAS);
+
+            // consume response entity
+            if (responseEntity != null) {
+                try {
+                    responseEntity.close();
+                } catch (IOException ignored) {
+                }
+            }
+
+            // notify callback that exchange is done
+            callback.done(false);
+        }
+    }
+
+}


[10/11] CAMEL-6428: camel-salesforce component. Thanks to Dhiraj Bokde for the contribution.

Posted by da...@apache.org.
http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/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;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/GlobalObjects.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/GlobalObjects.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/GlobalObjects.java
new file mode 100644
index 0000000..302e54e
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/GlobalObjects.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("DescribeGlobal")
+public class GlobalObjects extends AbstractDTOBase {
+
+    private String encoding;
+    private Integer maxBatchSize;
+
+    @XStreamImplicit
+    private List<SObject> sobjects;
+
+    public String getEncoding() {
+        return encoding;
+    }
+
+    public void setEncoding(String encoding) {
+        this.encoding = encoding;
+    }
+
+    public Integer getMaxBatchSize() {
+        return maxBatchSize;
+    }
+
+    public void setMaxBatchSize(Integer maxBatchSize) {
+        this.maxBatchSize = maxBatchSize;
+    }
+
+    public List<SObject> getSobjects() {
+        return sobjects;
+    }
+
+    public void setSobjects(List<SObject> sobjects) {
+        this.sobjects = sobjects;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/PickListValue.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/PickListValue.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/PickListValue.java
new file mode 100644
index 0000000..7816848
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/PickListValue.java
@@ -0,0 +1,70 @@
+/**
+ * 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;
+
+/**
+ * Salesforce DTO for picklist value.
+ */
+public class PickListValue {
+
+    private String value;
+    private String label;
+    private Boolean active;
+    private Boolean defaultValue;
+    private String validFor;
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public String getLabel() {
+        return label;
+    }
+
+    public void setLabel(String label) {
+        this.label = label;
+    }
+
+    public Boolean getActive() {
+        return active;
+    }
+
+    public void setActive(Boolean active) {
+        this.active = active;
+    }
+
+    public Boolean getDefaultValue() {
+        return defaultValue;
+    }
+
+    public void setDefaultValue(Boolean defaultValue) {
+        this.defaultValue = defaultValue;
+    }
+
+    public String getValidFor() {
+        return validFor;
+    }
+
+    public void setValidFor(String validFor) {
+        this.validFor = validFor;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/RecentItem.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/RecentItem.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/RecentItem.java
new file mode 100644
index 0000000..503c363
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/RecentItem.java
@@ -0,0 +1,56 @@
+/**
+ * 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;
+
+public class RecentItem extends AbstractDTOBase {
+
+    private Attributes attributes;
+
+    private String Id;
+
+    private String Name;
+
+    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("Name")
+    public String getName() {
+        return Name;
+    }
+
+    @JsonProperty("Name")
+    public void setName(String name) {
+        Name = name;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/RecordTypeInfo.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/RecordTypeInfo.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/RecordTypeInfo.java
new file mode 100644
index 0000000..7b8d997
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/RecordTypeInfo.java
@@ -0,0 +1,56 @@
+/**
+ * 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 RecordTypeInfo extends AbstractDTOBase {
+    private String name;
+    private Boolean available;
+    private String recordTypeId;
+    private Boolean defaultRecordTypeMapping;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Boolean isAvailable() {
+        return available;
+    }
+
+    public void setAvailable(Boolean available) {
+        this.available = available;
+    }
+
+    public String getRecordTypeId() {
+        return recordTypeId;
+    }
+
+    public void setRecordTypeId(String recordTypeId) {
+        this.recordTypeId = recordTypeId;
+    }
+
+    public Boolean isDefaultRecordTypeMapping() {
+        return defaultRecordTypeMapping;
+    }
+
+    public void setDefaultRecordTypeMapping(Boolean defaultRecordTypeMapping) {
+        this.defaultRecordTypeMapping = defaultRecordTypeMapping;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/RestError.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/RestError.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/RestError.java
new file mode 100644
index 0000000..e155f05
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/RestError.java
@@ -0,0 +1,68 @@
+/**
+ * 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.XStreamImplicit;
+
+import java.util.List;
+
+public class RestError extends AbstractDTOBase {
+    private String errorCode;
+    private String message;
+    @XStreamImplicit
+    private List<String> fields;
+
+    // default ctor for unmarshalling
+    public RestError() {
+        super();
+    }
+
+    public RestError(String errorCode, String message, List<String> fields) {
+        this(errorCode, message);
+        this.fields = fields;
+    }
+
+    public RestError(String errorCode, String message) {
+        this.errorCode = errorCode;
+        this.message = message;
+    }
+
+    public String getErrorCode() {
+        return errorCode;
+    }
+
+    public void setErrorCode(String errorCode) {
+        this.errorCode = errorCode;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public List<String> getFields() {
+        return fields;
+    }
+
+    public void setFields(List<String> fields) {
+        this.fields = fields;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/RestResources.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/RestResources.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/RestResources.java
new file mode 100644
index 0000000..9e7c644
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/RestResources.java
@@ -0,0 +1,100 @@
+/**
+ * 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;
+
+/**
+ * DTO for Salesforce Resources.
+ */
+@XStreamAlias("urls")
+public class RestResources extends AbstractDTOBase {
+
+    private String sobjects;
+    private String identity;
+    private String connect;
+    private String search;
+    private String query;
+    private String chatter;
+    private String recent;
+    private String tooling;
+
+    public String getSobjects() {
+        return sobjects;
+    }
+
+    public void setSobjects(String sobjects) {
+        this.sobjects = sobjects;
+    }
+
+    public String getIdentity() {
+        return identity;
+    }
+
+    public void setIdentity(String identity) {
+        this.identity = identity;
+    }
+
+    public String getConnect() {
+        return connect;
+    }
+
+    public void setConnect(String connect) {
+        this.connect = connect;
+    }
+
+    public String getSearch() {
+        return search;
+    }
+
+    public void setSearch(String search) {
+        this.search = search;
+    }
+
+    public String getQuery() {
+        return query;
+    }
+
+    public void setQuery(String query) {
+        this.query = query;
+    }
+
+    public String getChatter() {
+        return chatter;
+    }
+
+    public void setChatter(String chatter) {
+        this.chatter = chatter;
+    }
+
+    public String getRecent() {
+        return recent;
+    }
+
+    public void setRecent(String recent) {
+        this.recent = recent;
+    }
+
+    public String getTooling() {
+        return tooling;
+    }
+
+    public void setTooling(String tooling) {
+        this.tooling = tooling;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObject.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObject.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObject.java
new file mode 100644
index 0000000..0ad6962
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObject.java
@@ -0,0 +1,237 @@
+/**
+ * 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 SObject extends AbstractDTOBase {
+    private String name;
+    private String label;
+    private Boolean updateable;
+    private String keyPrefix;
+    private Boolean custom;
+    private SObjectUrls urls;
+    private Boolean searchable;
+    private String labelPlural;
+    private Boolean layoutable;
+    private Boolean activateable;
+    private Boolean createable;
+    private Boolean deprecatedAndHidden;
+    private Boolean deletable;
+    private Boolean customSetting;
+    private Boolean feedEnabled;
+    private String listviewable;
+    private String lookupLayoutable;
+    private Boolean mergeable;
+    private Boolean queryable;
+    private Boolean replicateable;
+    private Boolean retrieveable;
+    private String searchLayoutable;
+    private Boolean undeletable;
+    private Boolean triggerable;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getLabel() {
+        return label;
+    }
+
+    public void setLabel(String label) {
+        this.label = label;
+    }
+
+    public Boolean isUpdateable() {
+        return updateable;
+    }
+
+    public void setUpdateable(Boolean updateable) {
+        this.updateable = updateable;
+    }
+
+    public String getKeyPrefix() {
+        return keyPrefix;
+    }
+
+    public void setKeyPrefix(String keyPrefix) {
+        this.keyPrefix = keyPrefix;
+    }
+
+    public Boolean isCustom() {
+        return custom;
+    }
+
+    public void setCustom(Boolean custom) {
+        this.custom = custom;
+    }
+
+    public SObjectUrls getUrls() {
+        return urls;
+    }
+
+    public void setUrls(SObjectUrls urls) {
+        this.urls = urls;
+    }
+
+    public Boolean isSearchable() {
+        return searchable;
+    }
+
+    public void setSearchable(Boolean searchable) {
+        this.searchable = searchable;
+    }
+
+    public String getLabelPlural() {
+        return labelPlural;
+    }
+
+    public void setLabelPlural(String labelPlural) {
+        this.labelPlural = labelPlural;
+    }
+
+    public Boolean isLayoutable() {
+        return layoutable;
+    }
+
+    public void setLayoutable(Boolean layoutable) {
+        this.layoutable = layoutable;
+    }
+
+    public Boolean isActivateable() {
+        return activateable;
+    }
+
+    public void setActivateable(Boolean activateable) {
+        this.activateable = activateable;
+    }
+
+    public Boolean isCreateable() {
+        return createable;
+    }
+
+    public void setCreateable(Boolean createable) {
+        this.createable = createable;
+    }
+
+    public Boolean isDeprecatedAndHidden() {
+        return deprecatedAndHidden;
+    }
+
+    public void setDeprecatedAndHidden(Boolean deprecatedAndHidden) {
+        this.deprecatedAndHidden = deprecatedAndHidden;
+    }
+
+    public Boolean isDeletable() {
+        return deletable;
+    }
+
+    public void setDeletable(Boolean deletable) {
+        this.deletable = deletable;
+    }
+
+    public Boolean isCustomSetting() {
+        return customSetting;
+    }
+
+    public void setCustomSetting(Boolean customSetting) {
+        this.customSetting = customSetting;
+    }
+
+    public Boolean isFeedEnabled() {
+        return feedEnabled;
+    }
+
+    public void setFeedEnabled(Boolean feedEnabled) {
+        this.feedEnabled = feedEnabled;
+    }
+
+    public String getListviewable() {
+        return listviewable;
+    }
+
+    public void setListviewable(String listviewable) {
+        this.listviewable = listviewable;
+    }
+
+    public String getLookupLayoutable() {
+        return lookupLayoutable;
+    }
+
+    public void setLookupLayoutable(String lookupLayoutable) {
+        this.lookupLayoutable = lookupLayoutable;
+    }
+
+    public Boolean isMergeable() {
+        return mergeable;
+    }
+
+    public void setMergeable(Boolean mergeable) {
+        this.mergeable = mergeable;
+    }
+
+    public Boolean isQueryable() {
+        return queryable;
+    }
+
+    public void setQueryable(Boolean queryable) {
+        this.queryable = queryable;
+    }
+
+    public Boolean isReplicateable() {
+        return replicateable;
+    }
+
+    public void setReplicateable(Boolean replicateable) {
+        this.replicateable = replicateable;
+    }
+
+    public Boolean isRetrieveable() {
+        return retrieveable;
+    }
+
+    public void setRetrieveable(Boolean retrieveable) {
+        this.retrieveable = retrieveable;
+    }
+
+    public String getSearchLayoutable() {
+        return searchLayoutable;
+    }
+
+    public void setSearchLayoutable(String searchLayoutable) {
+        this.searchLayoutable = searchLayoutable;
+    }
+
+    public Boolean isUndeletable() {
+        return undeletable;
+    }
+
+    public void setUndeletable(Boolean undeletable) {
+        this.undeletable = undeletable;
+    }
+
+    public Boolean isTriggerable() {
+        return triggerable;
+    }
+
+    public void setTriggerable(Boolean triggerable) {
+        this.triggerable = triggerable;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectBasicInfo.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectBasicInfo.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectBasicInfo.java
new file mode 100644
index 0000000..b31708c
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectBasicInfo.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.salesforce.api.dto;
+
+import com.thoughtworks.xstream.annotations.XStreamImplicit;
+
+import java.util.List;
+
+public class SObjectBasicInfo extends AbstractDTOBase {
+
+    private SObject objectDescribe;
+
+    @XStreamImplicit
+    private List<RecentItem> recentItems;
+
+    public SObject getObjectDescribe() {
+        return objectDescribe;
+    }
+
+    public void setObjectDescribe(SObject objectDescribe) {
+        this.objectDescribe = objectDescribe;
+    }
+
+    public List<RecentItem> getRecentItems() {
+        return recentItems;
+    }
+
+    public void setRecentItems(List<RecentItem> recentItems) {
+        this.recentItems = recentItems;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectDescription.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectDescription.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectDescription.java
new file mode 100644
index 0000000..5177f4a
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectDescription.java
@@ -0,0 +1,67 @@
+/**
+ * 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.XStreamImplicit;
+
+import java.util.List;
+
+public class SObjectDescription extends SObject {
+
+    @XStreamImplicit
+    private List<SObjectField> fields;
+
+    private SObjectDescriptionUrls urls;
+
+    @XStreamImplicit
+    private List<ChildRelationShip> childRelationships;
+
+    @XStreamImplicit
+    private List<RecordTypeInfo> recordTypeInfos;
+
+    public List<SObjectField> getFields() {
+        return fields;
+    }
+
+    public void setFields(List<SObjectField> fields) {
+        this.fields = fields;
+    }
+
+    public SObjectDescriptionUrls getUrls() {
+        return urls;
+    }
+
+    public void setUrls(SObjectDescriptionUrls urls) {
+        this.urls = urls;
+    }
+
+    public List<ChildRelationShip> getChildRelationships() {
+        return childRelationships;
+    }
+
+    public void setChildRelationships(List<ChildRelationShip> childRelationships) {
+        this.childRelationships = childRelationships;
+    }
+
+    public List<RecordTypeInfo> getRecordTypeInfos() {
+        return recordTypeInfos;
+    }
+
+    public void setRecordTypeInfos(List<RecordTypeInfo> recordTypeInfos) {
+        this.recordTypeInfos = recordTypeInfos;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectDescriptionUrls.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectDescriptionUrls.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectDescriptionUrls.java
new file mode 100644
index 0000000..3fe7503
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectDescriptionUrls.java
@@ -0,0 +1,47 @@
+/**
+ * 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 SObjectDescriptionUrls extends SObjectUrls {
+    private String uiEditTemplate;
+    private String uiDetailTemplate;
+    private String uiNewRecord;
+
+    public String getUiEditTemplate() {
+        return uiEditTemplate;
+    }
+
+    public void setUiEditTemplate(String uiEditTemplate) {
+        this.uiEditTemplate = uiEditTemplate;
+    }
+
+    public String getUiDetailTemplate() {
+        return uiDetailTemplate;
+    }
+
+    public void setUiDetailTemplate(String uiDetailTemplate) {
+        this.uiDetailTemplate = uiDetailTemplate;
+    }
+
+    public String getUiNewRecord() {
+        return uiNewRecord;
+    }
+
+    public void setUiNewRecord(String uiNewRecord) {
+        this.uiNewRecord = uiNewRecord;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectField.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectField.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectField.java
new file mode 100644
index 0000000..379365d
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectField.java
@@ -0,0 +1,414 @@
+/**
+ * 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.XStreamImplicit;
+
+import java.util.List;
+
+public class SObjectField extends AbstractDTOBase {
+
+    private Integer length;
+    private String name;
+    private String type;
+    private String defaultValue;
+    private String label;
+    private Boolean updateable;
+    private Boolean calculated;
+    private Boolean caseSensitive;
+    private String controllerName;
+    private Boolean unique;
+    private Boolean nillable;
+    private Integer precision;
+    private Integer scale;
+    private Integer byteLength;
+    private Boolean nameField;
+    private Boolean sortable;
+    private Boolean filterable;
+    private Boolean writeRequiresMasterRead;
+    private Boolean externalId;
+    private Boolean idLookup;
+    private String inlineHelpText;
+    private Boolean createable;
+    private String soapType;
+    private Boolean autoNumber;
+    private Boolean restrictedPicklist;
+    private Boolean namePointing;
+    private Boolean custom;
+    private Boolean defaultedOnCreate;
+    private Boolean deprecatedAndHidden;
+    private Boolean htmlFormatted;
+    private String defaultValueFormula;
+    private String calculatedFormula;
+    @XStreamImplicit
+    private List<PickListValue> picklistValues;
+    private Boolean dependentPicklist;
+    @XStreamImplicit
+    private List<String> referenceTo;
+    private String relationshipName;
+    private String relationshipOrder;
+    private Boolean cascadeDelete;
+    private Boolean restrictedDelete;
+    private String digits;
+    private Boolean groupable;
+    private Boolean permissionable;
+    private Boolean displayLocationInDecimal;
+
+    public Integer getLength() {
+        return length;
+    }
+
+    public void setLength(Integer length) {
+        this.length = length;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getDefaultValue() {
+        return defaultValue;
+    }
+
+    public void setDefaultValue(String defaultValue) {
+        this.defaultValue = defaultValue;
+    }
+
+    public String getLabel() {
+        return label;
+    }
+
+    public void setLabel(String label) {
+        this.label = label;
+    }
+
+    public Boolean isUpdateable() {
+        return updateable;
+    }
+
+    public void setUpdateable(Boolean updateable) {
+        this.updateable = updateable;
+    }
+
+    public Boolean isCalculated() {
+        return calculated;
+    }
+
+    public void setCalculated(Boolean calculated) {
+        this.calculated = calculated;
+    }
+
+    public Boolean isCaseSensitive() {
+        return caseSensitive;
+    }
+
+    public void setCaseSensitive(Boolean caseSensitive) {
+        this.caseSensitive = caseSensitive;
+    }
+
+    public String getControllerName() {
+        return controllerName;
+    }
+
+    public void setControllerName(String controllerName) {
+        this.controllerName = controllerName;
+    }
+
+    public Boolean isUnique() {
+        return unique;
+    }
+
+    public void setUnique(Boolean unique) {
+        this.unique = unique;
+    }
+
+    public Boolean isNillable() {
+        return nillable;
+    }
+
+    public void setNillable(Boolean nillable) {
+        this.nillable = nillable;
+    }
+
+    public Integer getPrecision() {
+        return precision;
+    }
+
+    public void setPrecision(Integer precision) {
+        this.precision = precision;
+    }
+
+    public Integer getScale() {
+        return scale;
+    }
+
+    public void setScale(Integer scale) {
+        this.scale = scale;
+    }
+
+    public Integer getByteLength() {
+        return byteLength;
+    }
+
+    public void setByteLength(Integer byteLength) {
+        this.byteLength = byteLength;
+    }
+
+    public Boolean isNameField() {
+        return nameField;
+    }
+
+    public void setNameField(Boolean nameField) {
+        this.nameField = nameField;
+    }
+
+    public Boolean isSortable() {
+        return sortable;
+    }
+
+    public void setSortable(Boolean sortable) {
+        this.sortable = sortable;
+    }
+
+    public Boolean isFilterable() {
+        return filterable;
+    }
+
+    public void setFilterable(Boolean filterable) {
+        this.filterable = filterable;
+    }
+
+    public Boolean isWriteRequiresMasterRead() {
+        return writeRequiresMasterRead;
+    }
+
+    public void setWriteRequiresMasterRead(Boolean writeRequiresMasterRead) {
+        this.writeRequiresMasterRead = writeRequiresMasterRead;
+    }
+
+    public Boolean isExternalId() {
+        return externalId;
+    }
+
+    public void setExternalId(Boolean externalId) {
+        this.externalId = externalId;
+    }
+
+    public Boolean isIdLookup() {
+        return idLookup;
+    }
+
+    public void setIdLookup(Boolean idLookup) {
+        this.idLookup = idLookup;
+    }
+
+    public String getInlineHelpText() {
+        return inlineHelpText;
+    }
+
+    public void setInlineHelpText(String inlineHelpText) {
+        this.inlineHelpText = inlineHelpText;
+    }
+
+    public Boolean isCreateable() {
+        return createable;
+    }
+
+    public void setCreateable(Boolean createable) {
+        this.createable = createable;
+    }
+
+    public String getSoapType() {
+        return soapType;
+    }
+
+    public void setSoapType(String soapType) {
+        this.soapType = soapType;
+    }
+
+    public Boolean isAutoNumber() {
+        return autoNumber;
+    }
+
+    public void setAutoNumber(Boolean autoNumber) {
+        this.autoNumber = autoNumber;
+    }
+
+    public Boolean isRestrictedPicklist() {
+        return restrictedPicklist;
+    }
+
+    public void setRestrictedPicklist(Boolean restrictedPicklist) {
+        this.restrictedPicklist = restrictedPicklist;
+    }
+
+    public Boolean isNamePointing() {
+        return namePointing;
+    }
+
+    public void setNamePointing(Boolean namePointing) {
+        this.namePointing = namePointing;
+    }
+
+    public Boolean isCustom() {
+        return custom;
+    }
+
+    public void setCustom(Boolean custom) {
+        this.custom = custom;
+    }
+
+    public Boolean isDefaultedOnCreate() {
+        return defaultedOnCreate;
+    }
+
+    public void setDefaultedOnCreate(Boolean defaultedOnCreate) {
+        this.defaultedOnCreate = defaultedOnCreate;
+    }
+
+    public Boolean isDeprecatedAndHidden() {
+        return deprecatedAndHidden;
+    }
+
+    public void setDeprecatedAndHidden(Boolean deprecatedAndHidden) {
+        this.deprecatedAndHidden = deprecatedAndHidden;
+    }
+
+    public Boolean isHtmlFormatted() {
+        return htmlFormatted;
+    }
+
+    public void setHtmlFormatted(Boolean htmlFormatted) {
+        this.htmlFormatted = htmlFormatted;
+    }
+
+    public String getDefaultValueFormula() {
+        return defaultValueFormula;
+    }
+
+    public void setDefaultValueFormula(String defaultValueFormula) {
+        this.defaultValueFormula = defaultValueFormula;
+    }
+
+    public String getCalculatedFormula() {
+        return calculatedFormula;
+    }
+
+    public void setCalculatedFormula(String calculatedFormula) {
+        this.calculatedFormula = calculatedFormula;
+    }
+
+    public List<PickListValue> getPicklistValues() {
+        return picklistValues;
+    }
+
+    public void setPicklistValues(List<PickListValue> picklistValues) {
+        this.picklistValues = picklistValues;
+    }
+
+    public Boolean isDependentPicklist() {
+        return dependentPicklist;
+    }
+
+    public void setDependentPicklist(Boolean dependentPicklist) {
+        this.dependentPicklist = dependentPicklist;
+    }
+
+    public List<String> getReferenceTo() {
+        return referenceTo;
+    }
+
+    public void setReferenceTo(List<String> referenceTo) {
+        this.referenceTo = referenceTo;
+    }
+
+    public String getRelationshipName() {
+        return relationshipName;
+    }
+
+    public void setRelationshipName(String relationshipName) {
+        this.relationshipName = relationshipName;
+    }
+
+    public String getRelationshipOrder() {
+        return relationshipOrder;
+    }
+
+    public void setRelationshipOrder(String relationshipOrder) {
+        this.relationshipOrder = relationshipOrder;
+    }
+
+    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 getDigits() {
+        return digits;
+    }
+
+    public void setDigits(String digits) {
+        this.digits = digits;
+    }
+
+    public Boolean isGroupable() {
+        return groupable;
+    }
+
+    public void setGroupable(Boolean groupable) {
+        this.groupable = groupable;
+    }
+
+    public Boolean isPermissionable() {
+        return permissionable;
+    }
+
+    public void setPermissionable(Boolean permissionable) {
+        this.permissionable = permissionable;
+    }
+
+    public Boolean isDisplayLocationInDecimal() {
+        return displayLocationInDecimal;
+    }
+
+    public void setDisplayLocationInDecimal(Boolean displayLocationInDecimal) {
+        this.displayLocationInDecimal = displayLocationInDecimal;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectUrls.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectUrls.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectUrls.java
new file mode 100644
index 0000000..14b2f06
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SObjectUrls.java
@@ -0,0 +1,56 @@
+/**
+ * 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 SObjectUrls extends AbstractDTOBase {
+    private String sobject;
+    private String describe;
+    private String rowTemplate;
+    private String passwordUtilities;
+
+    public String getSobject() {
+        return sobject;
+    }
+
+    public void setSobject(String sobject) {
+        this.sobject = sobject;
+    }
+
+    public String getDescribe() {
+        return describe;
+    }
+
+    public void setDescribe(String describe) {
+        this.describe = describe;
+    }
+
+    public String getRowTemplate() {
+        return rowTemplate;
+    }
+
+    public void setRowTemplate(String rowTemplate) {
+        this.rowTemplate = rowTemplate;
+    }
+
+    public String getPasswordUtilities() {
+        return passwordUtilities;
+    }
+
+    public void setPasswordUtilities(String passwordUtilities) {
+        this.passwordUtilities = passwordUtilities;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SearchResult.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SearchResult.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SearchResult.java
new file mode 100644
index 0000000..d6fb673
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SearchResult.java
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.salesforce.api.dto;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import org.codehaus.jackson.annotate.JsonProperty;
+
+/**
+ * DTO for Salesforce SOSL Search result record.
+ */
+@XStreamAlias("SearchResult")
+public final class SearchResult extends AbstractDTOBase {
+
+    private Attributes attributes;
+    private String Id;
+
+    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;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SearchResults.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SearchResults.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SearchResults.java
new file mode 100644
index 0000000..18fb680
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/SearchResults.java
@@ -0,0 +1,41 @@
+/**
+ * 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;
+
+/**
+ * DTO for Salesforce SOSL Search results.
+ */
+@XStreamAlias("SearchResults")
+public final class SearchResults extends AbstractDTOBase {
+
+    @XStreamImplicit(itemFieldName = "SearchResult")
+    private List<SearchResult> results;
+
+    public List<SearchResult> getResults() {
+        return results;
+    }
+
+    public void setResults(List<SearchResult> results) {
+        this.results = results;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/Version.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/Version.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/Version.java
new file mode 100644
index 0000000..08e4031
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/Version.java
@@ -0,0 +1,52 @@
+/**
+ * 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;
+
+/**
+ * DTO for Salesforce version API
+ */
+public class Version extends AbstractDTOBase {
+
+    private String label;
+    private String url;
+    private String version;
+
+    public String getLabel() {
+        return label;
+    }
+
+    public void setLabel(String label) {
+        this.label = label;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/Versions.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/Versions.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/Versions.java
new file mode 100644
index 0000000..1349eb8
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/Versions.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 com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamImplicit;
+
+import java.util.List;
+
+/**
+ * DTO for Salesforce versions
+ */
+@XStreamAlias("Versions")
+public class Versions extends AbstractDTOBase {
+
+    @XStreamImplicit(itemFieldName = "Version")
+    private List<Version> versions;
+
+    public List<Version> getVersions() {
+        return versions;
+    }
+
+    public void setVersions(List<Version> versions) {
+        this.versions = versions;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchInfo.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchInfo.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchInfo.java
new file mode 100644
index 0000000..2a78b22
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchInfo.java
@@ -0,0 +1,342 @@
+/**
+ * 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.bulk;
+
+import javax.xml.bind.annotation.*;
+import javax.xml.datatype.XMLGregorianCalendar;
+
+
+/**
+ * <p>Java class for BatchInfo complex type.
+ * 
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * 
+ * <pre>
+ * &lt;complexType name="BatchInfo">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="id" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         &lt;element name="jobId" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         &lt;element name="state" type="{http://www.force.com/2009/06/asyncapi/dataload}BatchStateEnum"/>
+ *         &lt;element name="stateMessage" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         &lt;element name="createdDate" type="{http://www.w3.org/2001/XMLSchema}dateTime"/>
+ *         &lt;element name="systemModstamp" type="{http://www.w3.org/2001/XMLSchema}dateTime" minOccurs="0"/>
+ *         &lt;element name="numberRecordsProcessed" type="{http://www.w3.org/2001/XMLSchema}int"/>
+ *         &lt;element name="numberRecordsFailed" type="{http://www.w3.org/2001/XMLSchema}int" minOccurs="0"/>
+ *         &lt;element name="totalProcessingTime" type="{http://www.w3.org/2001/XMLSchema}long" minOccurs="0"/>
+ *         &lt;element name="apiActiveProcessingTime" type="{http://www.w3.org/2001/XMLSchema}long" minOccurs="0"/>
+ *         &lt;element name="apexProcessingTime" type="{http://www.w3.org/2001/XMLSchema}long" minOccurs="0"/>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ * 
+ * 
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "BatchInfo", propOrder = {
+    "id",
+    "jobId",
+    "state",
+    "stateMessage",
+    "createdDate",
+    "systemModstamp",
+    "numberRecordsProcessed",
+    "numberRecordsFailed",
+    "totalProcessingTime",
+    "apiActiveProcessingTime",
+    "apexProcessingTime"
+})
+public class BatchInfo {
+
+    @XmlElement(required = true)
+    protected String id;
+    @XmlElement(required = true)
+    protected String jobId;
+    @XmlElement(required = true)
+    protected BatchStateEnum state;
+    protected String stateMessage;
+    @XmlElement(required = true)
+    @XmlSchemaType(name = "dateTime")
+    protected XMLGregorianCalendar createdDate;
+    @XmlSchemaType(name = "dateTime")
+    protected XMLGregorianCalendar systemModstamp;
+    protected int numberRecordsProcessed;
+    protected Integer numberRecordsFailed;
+    protected Long totalProcessingTime;
+    protected Long apiActiveProcessingTime;
+    protected Long apexProcessingTime;
+
+    /**
+     * Gets the value of the id property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link String }
+     *     
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Sets the value of the id property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     *     
+     */
+    public void setId(String value) {
+        this.id = value;
+    }
+
+    /**
+     * Gets the value of the jobId property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link String }
+     *     
+     */
+    public String getJobId() {
+        return jobId;
+    }
+
+    /**
+     * Sets the value of the jobId property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     *     
+     */
+    public void setJobId(String value) {
+        this.jobId = value;
+    }
+
+    /**
+     * Gets the value of the state property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link BatchStateEnum }
+     *
+     */
+    public BatchStateEnum getState() {
+        return state;
+    }
+
+    /**
+     * Sets the value of the state property.
+     *
+     * @param value
+     *     allowed object is
+     *     {@link BatchStateEnum }
+     *
+     */
+    public void setState(BatchStateEnum value) {
+        this.state = value;
+    }
+
+    /**
+     * Gets the value of the stateMessage property.
+     *
+     * @return
+     *     possible object is
+     *     {@link String }
+     *
+     */
+    public String getStateMessage() {
+        return stateMessage;
+    }
+
+    /**
+     * Sets the value of the stateMessage property.
+     *
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     *
+     */
+    public void setStateMessage(String value) {
+        this.stateMessage = value;
+    }
+
+    /**
+     * Gets the value of the createdDate property.
+     *
+     * @return
+     *     possible object is
+     *     {@link javax.xml.datatype.XMLGregorianCalendar }
+     *
+     */
+    public XMLGregorianCalendar getCreatedDate() {
+        return createdDate;
+    }
+
+    /**
+     * Sets the value of the createdDate property.
+     *
+     * @param value
+     *     allowed object is
+     *     {@link javax.xml.datatype.XMLGregorianCalendar }
+     *
+     */
+    public void setCreatedDate(XMLGregorianCalendar value) {
+        this.createdDate = value;
+    }
+
+    /**
+     * Gets the value of the systemModstamp property.
+     *
+     * @return
+     *     possible object is
+     *     {@link javax.xml.datatype.XMLGregorianCalendar }
+     *
+     */
+    public XMLGregorianCalendar getSystemModstamp() {
+        return systemModstamp;
+    }
+
+    /**
+     * Sets the value of the systemModstamp property.
+     *
+     * @param value
+     *     allowed object is
+     *     {@link javax.xml.datatype.XMLGregorianCalendar }
+     *     
+     */
+    public void setSystemModstamp(XMLGregorianCalendar value) {
+        this.systemModstamp = value;
+    }
+
+    /**
+     * Gets the value of the numberRecordsProcessed property.
+     * 
+     */
+    public int getNumberRecordsProcessed() {
+        return numberRecordsProcessed;
+    }
+
+    /**
+     * Sets the value of the numberRecordsProcessed property.
+     * 
+     */
+    public void setNumberRecordsProcessed(int value) {
+        this.numberRecordsProcessed = value;
+    }
+
+    /**
+     * Gets the value of the numberRecordsFailed property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link Integer }
+     *     
+     */
+    public Integer getNumberRecordsFailed() {
+        return numberRecordsFailed;
+    }
+
+    /**
+     * Sets the value of the numberRecordsFailed property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link Integer }
+     *     
+     */
+    public void setNumberRecordsFailed(Integer value) {
+        this.numberRecordsFailed = value;
+    }
+
+    /**
+     * Gets the value of the totalProcessingTime property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link Long }
+     *     
+     */
+    public Long getTotalProcessingTime() {
+        return totalProcessingTime;
+    }
+
+    /**
+     * Sets the value of the totalProcessingTime property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link Long }
+     *     
+     */
+    public void setTotalProcessingTime(Long value) {
+        this.totalProcessingTime = value;
+    }
+
+    /**
+     * Gets the value of the apiActiveProcessingTime property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link Long }
+     *     
+     */
+    public Long getApiActiveProcessingTime() {
+        return apiActiveProcessingTime;
+    }
+
+    /**
+     * Sets the value of the apiActiveProcessingTime property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link Long }
+     *     
+     */
+    public void setApiActiveProcessingTime(Long value) {
+        this.apiActiveProcessingTime = value;
+    }
+
+    /**
+     * Gets the value of the apexProcessingTime property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link Long }
+     *     
+     */
+    public Long getApexProcessingTime() {
+        return apexProcessingTime;
+    }
+
+    /**
+     * Sets the value of the apexProcessingTime property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link Long }
+     *     
+     */
+    public void setApexProcessingTime(Long value) {
+        this.apexProcessingTime = value;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchInfoList.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchInfoList.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchInfoList.java
new file mode 100644
index 0000000..de73632
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchInfoList.java
@@ -0,0 +1,82 @@
+/**
+ * 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.bulk;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlType;
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * <p>Java class for BatchInfoList complex type.
+ * 
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * 
+ * <pre>
+ * &lt;complexType name="BatchInfoList">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="batchInfo" type="{http://www.force.com/2009/06/asyncapi/dataload}BatchInfo" maxOccurs="unbounded" minOccurs="0"/>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ * 
+ * 
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "BatchInfoList", propOrder = {
+    "batchInfo"
+})
+public class BatchInfoList {
+
+    protected List<BatchInfo> batchInfo;
+
+    /**
+     * Gets the value of the batchInfo property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list,
+     * not a snapshot. Therefore any modification you make to the
+     * returned list will be present inside the JAXB object.
+     * This is why there is not a <CODE>set</CODE> method for the batchInfo property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
+     * <pre>
+     *    getBatchInfo().add(newItem);
+     * </pre>
+     * 
+     * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link BatchInfo }
+     * 
+     * 
+     */
+    public List<BatchInfo> getBatchInfo() {
+        if (batchInfo == null) {
+            batchInfo = new ArrayList<BatchInfo>();
+        }
+        return this.batchInfo;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchResult.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchResult.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchResult.java
new file mode 100644
index 0000000..f7a7f72
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchResult.java
@@ -0,0 +1,82 @@
+/**
+ * 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.bulk;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlType;
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * <p>Java class for BatchResult complex type.
+ * 
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * 
+ * <pre>
+ * &lt;complexType name="BatchResult">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="result" type="{http://www.force.com/2009/06/asyncapi/dataload}Result" maxOccurs="unbounded" minOccurs="0"/>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ * 
+ * 
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "BatchResult", propOrder = {
+    "result"
+})
+public class BatchResult {
+
+    protected List<Result> result;
+
+    /**
+     * Gets the value of the result property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list,
+     * not a snapshot. Therefore any modification you make to the
+     * returned list will be present inside the JAXB object.
+     * This is why there is not a <CODE>set</CODE> method for the result property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
+     * <pre>
+     *    getResult().add(newItem);
+     * </pre>
+     * 
+     * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link Result }
+     * 
+     * 
+     */
+    public List<Result> getResult() {
+        if (result == null) {
+            result = new ArrayList<Result>();
+        }
+        return this.result;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchStateEnum.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchStateEnum.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchStateEnum.java
new file mode 100644
index 0000000..1914ec0
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/BatchStateEnum.java
@@ -0,0 +1,75 @@
+/**
+ * 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.bulk;
+
+import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlEnumValue;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for BatchStateEnum.
+ * 
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * <pre>
+ * &lt;simpleType name="BatchStateEnum">
+ *   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
+ *     &lt;enumeration value="Queued"/>
+ *     &lt;enumeration value="InProgress"/>
+ *     &lt;enumeration value="Completed"/>
+ *     &lt;enumeration value="Failed"/>
+ *     &lt;enumeration value="NotProcessed"/>
+ *   &lt;/restriction>
+ * &lt;/simpleType>
+ * </pre>
+ * 
+ */
+@XmlType(name = "BatchStateEnum")
+@XmlEnum
+public enum BatchStateEnum {
+
+    @XmlEnumValue("Queued")
+    QUEUED("Queued"),
+    @XmlEnumValue("InProgress")
+    IN_PROGRESS("InProgress"),
+    @XmlEnumValue("Completed")
+    COMPLETED("Completed"),
+    @XmlEnumValue("Failed")
+    FAILED("Failed"),
+    @XmlEnumValue("NotProcessed")
+    NOT_PROCESSED("NotProcessed");
+    private final String value;
+
+    BatchStateEnum(String v) {
+        value = v;
+    }
+
+    public String value() {
+        return value;
+    }
+
+    public static BatchStateEnum fromValue(String v) {
+        for (BatchStateEnum c: BatchStateEnum.values()) {
+            if (c.value.equals(v)) {
+                return c;
+            }
+        }
+        throw new IllegalArgumentException(v);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ConcurrencyModeEnum.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ConcurrencyModeEnum.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ConcurrencyModeEnum.java
new file mode 100644
index 0000000..879bb37
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ConcurrencyModeEnum.java
@@ -0,0 +1,66 @@
+/**
+ * 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.bulk;
+
+import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlEnumValue;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for ConcurrencyModeEnum.
+ * 
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * <pre>
+ * &lt;simpleType name="ConcurrencyModeEnum">
+ *   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
+ *     &lt;enumeration value="Parallel"/>
+ *     &lt;enumeration value="Serial"/>
+ *   &lt;/restriction>
+ * &lt;/simpleType>
+ * </pre>
+ * 
+ */
+@XmlType(name = "ConcurrencyModeEnum")
+@XmlEnum
+public enum ConcurrencyModeEnum {
+
+    @XmlEnumValue("Parallel")
+    PARALLEL("Parallel"),
+    @XmlEnumValue("Serial")
+    SERIAL("Serial");
+    private final String value;
+
+    ConcurrencyModeEnum(String v) {
+        value = v;
+    }
+
+    public String value() {
+        return value;
+    }
+
+    public static ConcurrencyModeEnum fromValue(String v) {
+        for (ConcurrencyModeEnum c: ConcurrencyModeEnum.values()) {
+            if (c.value.equals(v)) {
+                return c;
+            }
+        }
+        throw new IllegalArgumentException(v);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ContentType.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ContentType.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ContentType.java
new file mode 100644
index 0000000..1a3c75e
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ContentType.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.bulk;
+
+import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for ContentType.
+ * 
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * <pre>
+ * &lt;simpleType name="ContentType">
+ *   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
+ *     &lt;enumeration value="XML"/>
+ *     &lt;enumeration value="CSV"/>
+ *     &lt;enumeration value="ZIP_XML"/>
+ *     &lt;enumeration value="ZIP_CSV"/>
+ *   &lt;/restriction>
+ * &lt;/simpleType>
+ * </pre>
+ * 
+ */
+@XmlType(name = "ContentType")
+@XmlEnum
+public enum ContentType {
+
+    XML,
+    CSV,
+    ZIP_XML,
+    ZIP_CSV;
+
+    public String value() {
+        return name();
+    }
+
+    public static ContentType fromValue(String v) {
+        return valueOf(v);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/Error.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/Error.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/Error.java
new file mode 100644
index 0000000..4a06fbb
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/Error.java
@@ -0,0 +1,105 @@
+/**
+ * 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.bulk;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for Error complex type.
+ * 
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * 
+ * <pre>
+ * &lt;complexType name="Error">
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="exceptionCode" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         &lt;element name="exceptionMessage" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *       &lt;/sequence>
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ * 
+ * 
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "Error", propOrder = {
+    "exceptionCode",
+    "exceptionMessage"
+})
+public class Error {
+
+    @XmlElement(required = true)
+    protected String exceptionCode;
+    @XmlElement(required = true)
+    protected String exceptionMessage;
+
+    /**
+     * Gets the value of the exceptionCode property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link String }
+     *     
+     */
+    public String getExceptionCode() {
+        return exceptionCode;
+    }
+
+    /**
+     * Sets the value of the exceptionCode property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     *     
+     */
+    public void setExceptionCode(String value) {
+        this.exceptionCode = value;
+    }
+
+    /**
+     * Gets the value of the exceptionMessage property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link String }
+     *     
+     */
+    public String getExceptionMessage() {
+        return exceptionMessage;
+    }
+
+    /**
+     * Sets the value of the exceptionMessage property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     *     
+     */
+    public void setExceptionMessage(String value) {
+        this.exceptionMessage = value;
+    }
+
+}


[03/11] CAMEL-6428: Fixed CS

Posted by da...@apache.org.
http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ObjectFactory.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ObjectFactory.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ObjectFactory.java
index dc476ac..c0dbfc2 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ObjectFactory.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ObjectFactory.java
@@ -23,18 +23,17 @@ import javax.xml.namespace.QName;
 
 
 /**
- * This object contains factory methods for each 
- * Java content interface and Java element interface 
+ * This object contains factory methods for each
+ * Java content interface and Java element interface
  * in the org.apache.camel.component.salesforce.api.dto.bulk package.
- * <p>An ObjectFactory allows you to programatically 
- * construct new instances of the Java representation 
- * for XML content. The Java representation of XML 
- * content can consist of schema derived interfaces 
- * and classes representing the binding of schema 
- * type definitions, element declarations and model 
- * groups.  Factory methods for each of these are 
+ * <p>An ObjectFactory allows you to programatically
+ * construct new instances of the Java representation
+ * for XML content. The Java representation of XML
+ * content can consist of schema derived interfaces
+ * and classes representing the binding of schema
+ * type definitions, element declarations and model
+ * groups.  Factory methods for each of these are
  * provided in this class.
- * 
  */
 @XmlRegistry
 public class ObjectFactory {
@@ -49,14 +48,12 @@ public class ObjectFactory {
 
     /**
      * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: org.apache.camel.component.salesforce.api.dto.bulk
-     * 
      */
     public ObjectFactory() {
     }
 
     /**
      * Create an instance of {@link SObject }
-     *
      */
     public SObject createSObject() {
         return new SObject();
@@ -64,7 +61,6 @@ public class ObjectFactory {
 
     /**
      * Create an instance of {@link ResultError }
-     *
      */
     public ResultError createResultError() {
         return new ResultError();
@@ -72,7 +68,6 @@ public class ObjectFactory {
 
     /**
      * Create an instance of {@link BatchInfo }
-     *
      */
     public BatchInfo createBatchInfo() {
         return new BatchInfo();
@@ -80,7 +75,6 @@ public class ObjectFactory {
 
     /**
      * Create an instance of {@link BatchResult }
-     *
      */
     public BatchResult createBatchResult() {
         return new BatchResult();
@@ -88,7 +82,6 @@ public class ObjectFactory {
 
     /**
      * Create an instance of {@link QueryResultList }
-     *
      */
     public QueryResultList createQueryResultList() {
         return new QueryResultList();
@@ -96,7 +89,6 @@ public class ObjectFactory {
 
     /**
      * Create an instance of {@link Error }
-     *
      */
     public Error createError() {
         return new Error();
@@ -104,7 +96,6 @@ public class ObjectFactory {
 
     /**
      * Create an instance of {@link BatchInfoList }
-     *
      */
     public BatchInfoList createBatchInfoList() {
         return new BatchInfoList();
@@ -112,7 +103,6 @@ public class ObjectFactory {
 
     /**
      * Create an instance of {@link Result }
-     *
      */
     public Result createResult() {
         return new Result();
@@ -120,7 +110,6 @@ public class ObjectFactory {
 
     /**
      * Create an instance of {@link JobInfo }
-     *
      */
     public JobInfo createJobInfo() {
         return new JobInfo();
@@ -128,7 +117,6 @@ public class ObjectFactory {
 
     /**
      * Create an instance of {@link QueryResult }
-     *
      */
     public QueryResult createQueryResult() {
         return new QueryResult();
@@ -136,7 +124,6 @@ public class ObjectFactory {
 
     /**
      * Create an instance of {@link javax.xml.bind.JAXBElement }{@code <}{@link JobInfo }{@code >}}
-     *
      */
     @XmlElementDecl(namespace = "http://www.force.com/2009/06/asyncapi/dataload", name = "jobInfo")
     public JAXBElement<JobInfo> createJobInfo(JobInfo value) {
@@ -145,7 +132,6 @@ public class ObjectFactory {
 
     /**
      * Create an instance of {@link javax.xml.bind.JAXBElement }{@code <}{@link BatchInfo }{@code >}}
-     *
      */
     @XmlElementDecl(namespace = "http://www.force.com/2009/06/asyncapi/dataload", name = "batchInfo")
     public JAXBElement<BatchInfo> createBatchInfo(BatchInfo value) {
@@ -154,7 +140,6 @@ public class ObjectFactory {
 
     /**
      * Create an instance of {@link javax.xml.bind.JAXBElement }{@code <}{@link Error }{@code >}}
-     *
      */
     @XmlElementDecl(namespace = "http://www.force.com/2009/06/asyncapi/dataload", name = "error")
     public JAXBElement<Error> createError(Error value) {
@@ -163,7 +148,6 @@ public class ObjectFactory {
 
     /**
      * Create an instance of {@link javax.xml.bind.JAXBElement }{@code <}{@link BatchResult }{@code >}}
-     *
      */
     @XmlElementDecl(namespace = "http://www.force.com/2009/06/asyncapi/dataload", name = "results")
     public JAXBElement<BatchResult> createResults(BatchResult value) {
@@ -172,7 +156,6 @@ public class ObjectFactory {
 
     /**
      * Create an instance of {@link javax.xml.bind.JAXBElement }{@code <}{@link QueryResultList }{@code >}}
-     *
      */
     @XmlElementDecl(namespace = "http://www.force.com/2009/06/asyncapi/dataload", name = "result-list")
     public JAXBElement<QueryResultList> createResultList(QueryResultList value) {
@@ -181,7 +164,6 @@ public class ObjectFactory {
 
     /**
      * Create an instance of {@link javax.xml.bind.JAXBElement }{@code <}{@link BatchInfoList }{@code >}}
-     *
      */
     @XmlElementDecl(namespace = "http://www.force.com/2009/06/asyncapi/dataload", name = "batchInfoList")
     public JAXBElement<BatchInfoList> createBatchInfoList(BatchInfoList value) {
@@ -190,7 +172,6 @@ public class ObjectFactory {
 
     /**
      * Create an instance of {@link javax.xml.bind.JAXBElement }{@code <}{@link QueryResult }{@code >}}
-     * 
      */
     @XmlElementDecl(namespace = "http://www.force.com/2009/06/asyncapi/dataload", name = "queryResult")
     public JAXBElement<QueryResult> createQueryResult(QueryResult value) {

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/OperationEnum.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/OperationEnum.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/OperationEnum.java
index 3f25e66..a3f6f5b 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/OperationEnum.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/OperationEnum.java
@@ -23,9 +23,9 @@ import javax.xml.bind.annotation.XmlType;
 
 /**
  * <p>Java class for OperationEnum.
- * 
+ * <p/>
  * <p>The following schema fragment specifies the expected content contained within this class.
- * <p>
+ * <p/>
  * <pre>
  * &lt;simpleType name="OperationEnum">
  *   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
@@ -38,7 +38,6 @@ import javax.xml.bind.annotation.XmlType;
  *   &lt;/restriction>
  * &lt;/simpleType>
  * </pre>
- * 
  */
 @XmlType(name = "OperationEnum")
 @XmlEnum
@@ -67,7 +66,7 @@ public enum OperationEnum {
     }
 
     public static OperationEnum fromValue(String v) {
-        for (OperationEnum c: OperationEnum.values()) {
+        for (OperationEnum c : OperationEnum.values()) {
             if (c.value.equals(v)) {
                 return c;
             }

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/QueryResult.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/QueryResult.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/QueryResult.java
index 702d993..aaaf1b1 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/QueryResult.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/QueryResult.java
@@ -16,19 +16,19 @@
  */
 package org.apache.camel.component.salesforce.api.dto.bulk;
 
+import java.util.ArrayList;
+import java.util.List;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlType;
-import java.util.ArrayList;
-import java.util.List;
 
 
 /**
  * <p>Java class for QueryResult complex type.
- * 
+ * <p/>
  * <p>The following schema fragment specifies the expected content contained within this class.
- * 
+ * <p/>
  * <pre>
  * &lt;complexType name="QueryResult">
  *   &lt;complexContent>
@@ -40,12 +40,10 @@ import java.util.List;
  *   &lt;/complexContent>
  * &lt;/complexType>
  * </pre>
- * 
- * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "QueryResult", propOrder = {
-    "records"
+        "records"
 })
 public class QueryResult {
 
@@ -54,25 +52,23 @@ public class QueryResult {
 
     /**
      * Gets the value of the records property.
-     * 
-     * <p>
+     * <p/>
+     * <p/>
      * This accessor method returns a reference to the live list,
      * not a snapshot. Therefore any modification you make to the
      * returned list will be present inside the JAXB object.
      * This is why there is not a <CODE>set</CODE> method for the records property.
-     * 
-     * <p>
+     * <p/>
+     * <p/>
      * For example, to add a new item, do as follows:
      * <pre>
      *    getRecords().add(newItem);
      * </pre>
-     * 
-     * 
-     * <p>
+     * <p/>
+     * <p/>
+     * <p/>
      * Objects of the following type(s) are allowed in the list
      * {@link SObject }
-     * 
-     * 
      */
     public List<SObject> getRecords() {
         if (records == null) {

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/QueryResultList.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/QueryResultList.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/QueryResultList.java
index 6dbda5a..89339e3 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/QueryResultList.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/QueryResultList.java
@@ -16,18 +16,18 @@
  */
 package org.apache.camel.component.salesforce.api.dto.bulk;
 
+import java.util.ArrayList;
+import java.util.List;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlType;
-import java.util.ArrayList;
-import java.util.List;
 
 
 /**
  * <p>Java class for QueryResultList complex type.
- * 
+ * <p/>
  * <p>The following schema fragment specifies the expected content contained within this class.
- * 
+ * <p/>
  * <pre>
  * &lt;complexType name="QueryResultList">
  *   &lt;complexContent>
@@ -39,12 +39,10 @@ import java.util.List;
  *   &lt;/complexContent>
  * &lt;/complexType>
  * </pre>
- * 
- * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "QueryResultList", propOrder = {
-    "result"
+        "result"
 })
 public class QueryResultList {
 
@@ -52,25 +50,23 @@ public class QueryResultList {
 
     /**
      * Gets the value of the result property.
-     * 
-     * <p>
+     * <p/>
+     * <p/>
      * This accessor method returns a reference to the live list,
      * not a snapshot. Therefore any modification you make to the
      * returned list will be present inside the JAXB object.
      * This is why there is not a <CODE>set</CODE> method for the result property.
-     * 
-     * <p>
+     * <p/>
+     * <p/>
      * For example, to add a new item, do as follows:
      * <pre>
      *    getResult().add(newItem);
      * </pre>
-     * 
-     * 
-     * <p>
+     * <p/>
+     * <p/>
+     * <p/>
      * Objects of the following type(s) are allowed in the list
      * {@link String }
-     * 
-     * 
      */
     public List<String> getResult() {
         if (result == null) {

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/Result.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/Result.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/Result.java
index c36d9aa..b8406c3 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/Result.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/Result.java
@@ -16,18 +16,18 @@
  */
 package org.apache.camel.component.salesforce.api.dto.bulk;
 
+import java.util.ArrayList;
+import java.util.List;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlType;
-import java.util.ArrayList;
-import java.util.List;
 
 
 /**
  * <p>Java class for Result complex type.
- * 
+ * <p/>
  * <p>The following schema fragment specifies the expected content contained within this class.
- * 
+ * <p/>
  * <pre>
  * &lt;complexType name="Result">
  *   &lt;complexContent>
@@ -42,15 +42,13 @@ import java.util.List;
  *   &lt;/complexContent>
  * &lt;/complexType>
  * </pre>
- * 
- * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "Result", propOrder = {
-    "errors",
-    "id",
-    "success",
-    "created"
+        "errors",
+        "id",
+        "success",
+        "created"
 })
 public class Result {
 
@@ -61,25 +59,23 @@ public class Result {
 
     /**
      * Gets the value of the errors property.
-     * 
-     * <p>
+     * <p/>
+     * <p/>
      * This accessor method returns a reference to the live list,
      * not a snapshot. Therefore any modification you make to the
      * returned list will be present inside the JAXB object.
      * This is why there is not a <CODE>set</CODE> method for the errors property.
-     * 
-     * <p>
+     * <p/>
+     * <p/>
      * For example, to add a new item, do as follows:
      * <pre>
      *    getErrors().add(newItem);
      * </pre>
-     * 
-     * 
-     * <p>
+     * <p/>
+     * <p/>
+     * <p/>
      * Objects of the following type(s) are allowed in the list
      * {@link ResultError }
-     * 
-     * 
      */
     public List<ResultError> getErrors() {
         if (errors == null) {
@@ -90,11 +86,9 @@ public class Result {
 
     /**
      * Gets the value of the id property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
+     *
+     * @return possible object is
+     *         {@link String }
      */
     public String getId() {
         return id;
@@ -102,11 +96,9 @@ public class Result {
 
     /**
      * Sets the value of the id property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
+     *
+     * @param value allowed object is
+     *              {@link String }
      */
     public void setId(String value) {
         this.id = value;
@@ -114,7 +106,6 @@ public class Result {
 
     /**
      * Gets the value of the success property.
-     * 
      */
     public boolean isSuccess() {
         return success;
@@ -122,7 +113,6 @@ public class Result {
 
     /**
      * Sets the value of the success property.
-     * 
      */
     public void setSuccess(boolean value) {
         this.success = value;
@@ -130,7 +120,6 @@ public class Result {
 
     /**
      * Gets the value of the created property.
-     * 
      */
     public boolean isCreated() {
         return created;
@@ -138,7 +127,6 @@ public class Result {
 
     /**
      * Sets the value of the created property.
-     * 
      */
     public void setCreated(boolean value) {
         this.created = value;

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ResultError.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ResultError.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ResultError.java
index fabccab..c837888 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ResultError.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/ResultError.java
@@ -16,19 +16,19 @@
  */
 package org.apache.camel.component.salesforce.api.dto.bulk;
 
+import java.util.ArrayList;
+import java.util.List;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlType;
-import java.util.ArrayList;
-import java.util.List;
 
 
 /**
  * <p>Java class for ResultError complex type.
- * 
+ * <p/>
  * <p>The following schema fragment specifies the expected content contained within this class.
- * 
+ * <p/>
  * <pre>
  * &lt;complexType name="ResultError">
  *   &lt;complexContent>
@@ -42,14 +42,12 @@ import java.util.List;
  *   &lt;/complexContent>
  * &lt;/complexType>
  * </pre>
- * 
- * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "ResultError", propOrder = {
-    "fields",
-    "message",
-    "statusCode"
+        "fields",
+        "message",
+        "statusCode"
 })
 public class ResultError {
 
@@ -62,25 +60,23 @@ public class ResultError {
 
     /**
      * Gets the value of the fields property.
-     * 
-     * <p>
+     * <p/>
+     * <p/>
      * This accessor method returns a reference to the live list,
      * not a snapshot. Therefore any modification you make to the
      * returned list will be present inside the JAXB object.
      * This is why there is not a <CODE>set</CODE> method for the fields property.
-     * 
-     * <p>
+     * <p/>
+     * <p/>
      * For example, to add a new item, do as follows:
      * <pre>
      *    getFields().add(newItem);
      * </pre>
-     * 
-     * 
-     * <p>
+     * <p/>
+     * <p/>
+     * <p/>
      * Objects of the following type(s) are allowed in the list
      * {@link String }
-     * 
-     * 
      */
     public List<String> getFields() {
         if (fields == null) {
@@ -91,11 +87,9 @@ public class ResultError {
 
     /**
      * Gets the value of the message property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
+     *
+     * @return possible object is
+     *         {@link String }
      */
     public String getMessage() {
         return message;
@@ -103,11 +97,9 @@ public class ResultError {
 
     /**
      * Sets the value of the message property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
+     *
+     * @param value allowed object is
+     *              {@link String }
      */
     public void setMessage(String value) {
         this.message = value;
@@ -115,11 +107,9 @@ public class ResultError {
 
     /**
      * Gets the value of the statusCode property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link StatusCode }
      *
+     * @return possible object is
+     *         {@link StatusCode }
      */
     public StatusCode getStatusCode() {
         return statusCode;
@@ -128,10 +118,8 @@ public class ResultError {
     /**
      * Sets the value of the statusCode property.
      *
-     * @param value
-     *     allowed object is
-     *     {@link StatusCode }
-     *     
+     * @param value allowed object is
+     *              {@link StatusCode }
      */
     public void setStatusCode(StatusCode value) {
         this.statusCode = value;

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/SObject.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/SObject.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/SObject.java
index aa9c2c5..ff08913 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/SObject.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/SObject.java
@@ -16,16 +16,20 @@
  */
 package org.apache.camel.component.salesforce.api.dto.bulk;
 
-import javax.xml.bind.annotation.*;
 import java.util.ArrayList;
 import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAnyElement;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
 
 
 /**
  * <p>Java class for sObject complex type.
- * 
+ * <p/>
  * <p>The following schema fragment specifies the expected content contained within this class.
- * 
+ * <p/>
  * <pre>
  * &lt;complexType name="sObject">
  *   &lt;complexContent>
@@ -39,14 +43,12 @@ import java.util.List;
  *   &lt;/complexContent>
  * &lt;/complexType>
  * </pre>
- * 
- * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "sObject", propOrder = {
-    "type",
-    "id",
-    "any"
+        "type",
+        "id",
+        "any"
 })
 public class SObject {
 
@@ -59,11 +61,9 @@ public class SObject {
 
     /**
      * Gets the value of the type property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
+     *
+     * @return possible object is
+     *         {@link String }
      */
     public String getType() {
         return type;
@@ -71,11 +71,9 @@ public class SObject {
 
     /**
      * Sets the value of the type property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
+     *
+     * @param value allowed object is
+     *              {@link String }
      */
     public void setType(String value) {
         this.type = value;
@@ -83,11 +81,9 @@ public class SObject {
 
     /**
      * Gets the value of the id property.
-     * 
-     * @return
-     *     possible object is
-     *     {@link String }
-     *     
+     *
+     * @return possible object is
+     *         {@link String }
      */
     public String getId() {
         return id;
@@ -95,11 +91,9 @@ public class SObject {
 
     /**
      * Sets the value of the id property.
-     * 
-     * @param value
-     *     allowed object is
-     *     {@link String }
-     *     
+     *
+     * @param value allowed object is
+     *              {@link String }
      */
     public void setId(String value) {
         this.id = value;
@@ -107,26 +101,24 @@ public class SObject {
 
     /**
      * Gets the value of the any property.
-     * 
-     * <p>
+     * <p/>
+     * <p/>
      * This accessor method returns a reference to the live list,
      * not a snapshot. Therefore any modification you make to the
      * returned list will be present inside the JAXB object.
      * This is why there is not a <CODE>set</CODE> method for the any property.
-     * 
-     * <p>
+     * <p/>
+     * <p/>
      * For example, to add a new item, do as follows:
      * <pre>
      *    getAny().add(newItem);
      * </pre>
-     * 
-     * 
-     * <p>
+     * <p/>
+     * <p/>
+     * <p/>
      * Objects of the following type(s) are allowed in the list
      * {@link Object }
      * {@link org.w3c.dom.Element }
-     * 
-     * 
      */
     public List<Object> getAny() {
         if (any == null) {

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/StatusCode.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/StatusCode.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/StatusCode.java
index d4e3493..4106109 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/StatusCode.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/StatusCode.java
@@ -22,9 +22,9 @@ import javax.xml.bind.annotation.XmlType;
 
 /**
  * <p>Java class for StatusCode.
- * 
+ * <p/>
  * <p>The following schema fragment specifies the expected content contained within this class.
- * <p>
+ * <p/>
  * <pre>
  * &lt;simpleType name="StatusCode">
  *   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
@@ -204,7 +204,6 @@ import javax.xml.bind.annotation.XmlType;
  *   &lt;/restriction>
  * &lt;/simpleType>
  * </pre>
- * 
  */
 @XmlType(name = "StatusCode")
 @XmlEnum

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/package-info.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/package-info.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/package-info.java
index ae2b9ee..4eccf4d 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/package-info.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/bulk/package-info.java
@@ -14,5 +14,4 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.force.com/2009/06/asyncapi/dataload", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
-package org.apache.camel.component.salesforce.api.dto.bulk;
+@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.force.com/2009/06/asyncapi/dataload", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED) package org.apache.camel.component.salesforce.api.dto.bulk;

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/SalesforceSession.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/SalesforceSession.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/SalesforceSession.java
index a16a2a3..d60c1a0 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/SalesforceSession.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/SalesforceSession.java
@@ -16,7 +16,18 @@
  */
 package org.apache.camel.component.salesforce.internal;
 
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
+
 import org.apache.camel.Service;
+import org.apache.camel.component.salesforce.SalesforceLoginConfig;
+import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.api.dto.RestError;
+import org.apache.camel.component.salesforce.internal.dto.LoginError;
+import org.apache.camel.component.salesforce.internal.dto.LoginToken;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.eclipse.jetty.client.ContentExchange;
 import org.eclipse.jetty.client.HttpClient;
@@ -27,18 +38,9 @@ import org.eclipse.jetty.io.Buffer;
 import org.eclipse.jetty.io.ByteArrayBuffer;
 import org.eclipse.jetty.util.StringUtil;
 import org.eclipse.jetty.util.UrlEncoded;
-import org.apache.camel.component.salesforce.SalesforceLoginConfig;
-import org.apache.camel.component.salesforce.api.SalesforceException;
-import org.apache.camel.component.salesforce.api.dto.RestError;
-import org.apache.camel.component.salesforce.internal.dto.LoginError;
-import org.apache.camel.component.salesforce.internal.dto.LoginToken;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.IOException;
-import java.util.*;
-import java.util.concurrent.CopyOnWriteArraySet;
-
 public class SalesforceSession implements Service {
 
     private static final String OAUTH2_REVOKE_PATH = "/services/oauth2/revoke?token=";
@@ -120,7 +122,7 @@ public class SalesforceSession implements Service {
 
                 // set form content
                 loginPost.setRequestContent(new ByteArrayBuffer(
-                    nvps.encode(StringUtil.__UTF8, true).getBytes(StringUtil.__UTF8)));
+                        nvps.encode(StringUtil.__UTF8, true).getBytes(StringUtil.__UTF8)));
                 httpClient.send(loginPost);
 
                 // wait for the login to finish
@@ -135,7 +137,7 @@ public class SalesforceSession implements Service {
                             case HttpStatus.OK_200:
                                 // parse the response to get token
                                 LoginToken token = objectMapper.readValue(responseContent,
-                                    LoginToken.class);
+                                        LoginToken.class);
 
                                 // don't log token or instance URL for security reasons
                                 LOG.info("Login successful");
@@ -156,26 +158,26 @@ public class SalesforceSession implements Service {
                             case HttpStatus.BAD_REQUEST_400:
                                 // parse the response to get error
                                 final LoginError error = objectMapper.readValue(responseContent,
-                                    LoginError.class);
+                                        LoginError.class);
                                 final String msg = String.format("Login error code:[%s] description:[%s]",
-                                    error.getError(), error.getErrorDescription());
+                                        error.getError(), error.getErrorDescription());
                                 final List<RestError> errors = new ArrayList<RestError>();
                                 errors.add(new RestError(msg, error.getErrorDescription()));
                                 throw new SalesforceException(errors, HttpStatus.BAD_REQUEST_400);
 
                             default:
                                 throw new SalesforceException(
-                                    String.format("Login error status:[%s] reason:[%s]",
-                                        responseStatus, loginPost.getReason()),
-                                    responseStatus);
+                                        String.format("Login error status:[%s] reason:[%s]",
+                                                responseStatus, loginPost.getReason()),
+                                        responseStatus);
                         }
                         break;
 
                     case HttpExchange.STATUS_EXCEPTED:
                         final Throwable ex = loginPost.getException();
                         throw new SalesforceException(
-                            String.format("Unexpected login exception: %s", ex.getMessage()),
-                            ex);
+                                String.format("Unexpected login exception: %s", ex.getMessage()),
+                                ex);
 
                     case HttpExchange.STATUS_CANCELLED:
                         throw new SalesforceException("Login request CANCELLED!", null);
@@ -219,9 +221,9 @@ public class SalesforceSession implements Service {
                         LOG.info("Logout successful");
                     } else {
                         throw new SalesforceException(
-                            String.format("Logout error, code: [%s] reason: [%s]",
-                                statusCode, reason),
-                            statusCode);
+                                String.format("Logout error, code: [%s] reason: [%s]",
+                                        statusCode, reason),
+                                statusCode);
                     }
                     break;
 
@@ -330,6 +332,7 @@ public class SalesforceSession implements Service {
 
     public static interface SalesforceSessionListener {
         void onLogin(String accessToken, String instanceUrl);
+
         void onLogout();
     }
 

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/AbstractClientBase.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/AbstractClientBase.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/AbstractClientBase.java
index 6fe7028..1c058b9 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/AbstractClientBase.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/AbstractClientBase.java
@@ -16,7 +16,13 @@
  */
 package org.apache.camel.component.salesforce.internal.client;
 
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
 import org.apache.camel.Service;
+import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.internal.SalesforceSession;
 import org.eclipse.jetty.client.ContentExchange;
 import org.eclipse.jetty.client.HttpClient;
 import org.eclipse.jetty.client.HttpEventListenerWrapper;
@@ -25,15 +31,9 @@ import org.eclipse.jetty.http.HttpSchemes;
 import org.eclipse.jetty.http.HttpStatus;
 import org.eclipse.jetty.io.Buffer;
 import org.eclipse.jetty.util.StringUtil;
-import org.apache.camel.component.salesforce.api.SalesforceException;
-import org.apache.camel.component.salesforce.internal.SalesforceSession;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
 public abstract class AbstractClientBase implements SalesforceSession.SalesforceSessionListener, Service {
 
     protected final Logger LOG = LoggerFactory.getLogger(getClass());
@@ -107,13 +107,13 @@ public abstract class AbstractClientBase implements SalesforceSession.Salesforce
         try {
             final boolean isHttps = HttpSchemes.HTTPS.equals(String.valueOf(request.getScheme()));
             request.setEventListener(new SalesforceSecurityListener(
-                httpClient.getDestination(request.getAddress(), isHttps),
-                request, session, accessToken));
+                    httpClient.getDestination(request.getAddress(), isHttps),
+                    request, session, accessToken));
         } catch (IOException e) {
             // propagate exception
             callback.onResponse(null, new SalesforceException(
-                String.format("Error registering security listener: %s", e.getMessage()),
-                e));
+                    String.format("Error registering security listener: %s", e.getMessage()),
+                    e));
         }
 
         // use HttpEventListener for lifecycle events
@@ -125,21 +125,21 @@ public abstract class AbstractClientBase implements SalesforceSession.Salesforce
             public void onConnectionFailed(Throwable ex) {
                 super.onConnectionFailed(ex);
                 callback.onResponse(null,
-                    new SalesforceException("Connection error: " + ex.getMessage(), ex));
+                        new SalesforceException("Connection error: " + ex.getMessage(), ex));
             }
 
             @Override
             public void onException(Throwable ex) {
                 super.onException(ex);
                 callback.onResponse(null,
-                    new SalesforceException("Unexpected exception: " + ex.getMessage(), ex));
+                        new SalesforceException("Unexpected exception: " + ex.getMessage(), ex));
             }
 
             @Override
             public void onExpire() {
                 super.onExpire();
                 callback.onResponse(null,
-                    new SalesforceException("Request expired", null));
+                        new SalesforceException("Request expired", null));
             }
 
             @Override
@@ -149,7 +149,7 @@ public abstract class AbstractClientBase implements SalesforceSession.Salesforce
                 final int responseStatus = request.getResponseStatus();
                 if (responseStatus < HttpStatus.OK_200 || responseStatus >= HttpStatus.MULTIPLE_CHOICES_300) {
                     final String msg = String.format("Error {%s:%s} executing {%s:%s}",
-                        responseStatus, reason, request.getMethod(), request.getRequestURI());
+                            responseStatus, reason, request.getMethod(), request.getRequestURI());
                     final SalesforceException exception = new SalesforceException(msg, createRestException(request));
                     exception.setStatusCode(responseStatus);
                     callback.onResponse(null, exception);

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/BulkApiClient.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/BulkApiClient.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/BulkApiClient.java
index b00e3fd..f388bc7 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/BulkApiClient.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/BulkApiClient.java
@@ -16,12 +16,14 @@
  */
 package org.apache.camel.component.salesforce.internal.client;
 
-import org.apache.camel.component.salesforce.api.SalesforceException;
-import org.apache.camel.component.salesforce.api.dto.bulk.*;
-
 import java.io.InputStream;
 import java.util.List;
 
+import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.api.dto.bulk.BatchInfo;
+import org.apache.camel.component.salesforce.api.dto.bulk.ContentType;
+import org.apache.camel.component.salesforce.api.dto.bulk.JobInfo;
+
 /**
  * Client interface for Salesforce Bulk API
  */
@@ -50,7 +52,7 @@ public interface BulkApiClient {
     /**
      * Creates a Bulk Job
      *
-     * @param jobInfo {@link JobInfo} with required fields
+     * @param jobInfo  {@link JobInfo} with required fields
      * @param callback {@link JobInfoResponseCallback} to be invoked on response or error
      */
     void createJob(JobInfo jobInfo,

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultBulkApiClient.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultBulkApiClient.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultBulkApiClient.java
index b4899e5..81f467e 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultBulkApiClient.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultBulkApiClient.java
@@ -16,6 +16,29 @@
  */
 package org.apache.camel.component.salesforce.internal.client;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Collections;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.api.dto.RestError;
+import org.apache.camel.component.salesforce.api.dto.bulk.BatchInfo;
+import org.apache.camel.component.salesforce.api.dto.bulk.BatchInfoList;
+import org.apache.camel.component.salesforce.api.dto.bulk.ContentType;
+import org.apache.camel.component.salesforce.api.dto.bulk.Error;
+import org.apache.camel.component.salesforce.api.dto.bulk.JobInfo;
+import org.apache.camel.component.salesforce.api.dto.bulk.JobStateEnum;
+import org.apache.camel.component.salesforce.api.dto.bulk.ObjectFactory;
+import org.apache.camel.component.salesforce.api.dto.bulk.QueryResultList;
+import org.apache.camel.component.salesforce.internal.SalesforceSession;
 import org.eclipse.jetty.client.ContentExchange;
 import org.eclipse.jetty.client.HttpClient;
 import org.eclipse.jetty.client.HttpExchange;
@@ -23,19 +46,6 @@ import org.eclipse.jetty.http.HttpHeaders;
 import org.eclipse.jetty.http.HttpMethods;
 import org.eclipse.jetty.io.ByteArrayBuffer;
 import org.eclipse.jetty.util.StringUtil;
-import org.apache.camel.component.salesforce.api.SalesforceException;
-import org.apache.camel.component.salesforce.api.dto.RestError;
-import org.apache.camel.component.salesforce.api.dto.bulk.*;
-import org.apache.camel.component.salesforce.api.dto.bulk.Error;
-import org.apache.camel.component.salesforce.internal.SalesforceSession;
-
-import javax.xml.bind.*;
-import javax.xml.transform.stream.StreamSource;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-import java.util.Arrays;
-import java.util.Collections;
 
 public class DefaultBulkApiClient extends AbstractClientBase implements BulkApiClient {
 
@@ -330,7 +340,7 @@ public class DefaultBulkApiClient extends AbstractClientBase implements BulkApiC
                     ex = e;
                 }
                 callback.onResponse(value != null ? Collections.unmodifiableList(value.getResult()) : null,
-                    ex);
+                        ex);
             }
         });
 
@@ -401,7 +411,7 @@ public class DefaultBulkApiClient extends AbstractClientBase implements BulkApiC
         // this must be of type Error
         try {
             final Error error = unmarshalResponse(new ByteArrayInputStream(request.getResponseContentBytes()),
-                request, Error.class);
+                    request, Error.class);
 
             final RestError restError = new RestError();
             restError.setErrorCode(error.getExceptionCode());
@@ -415,26 +425,26 @@ public class DefaultBulkApiClient extends AbstractClientBase implements BulkApiC
     }
 
     private <T> T unmarshalResponse(InputStream response, ContentExchange request, Class<T> resultClass)
-        throws SalesforceException {
+            throws SalesforceException {
         try {
             Unmarshaller unmarshaller = context.createUnmarshaller();
             JAXBElement<T> result = unmarshaller.unmarshal(new StreamSource(response), resultClass);
             return result.getValue();
         } catch (JAXBException e) {
             throw new SalesforceException(
-                String.format("Error unmarshaling response {%s:%s} : %s",
-                    request.getMethod(), request.getRequestURI(), e.getMessage()),
-                e);
+                    String.format("Error unmarshaling response {%s:%s} : %s",
+                            request.getMethod(), request.getRequestURI(), e.getMessage()),
+                    e);
         } catch (IllegalArgumentException e) {
             throw new SalesforceException(
-                String.format("Error unmarshaling response for {%s:%s} : %s",
-                    request.getMethod(), request.getRequestURI(), e.getMessage()),
-                e);
+                    String.format("Error unmarshaling response for {%s:%s} : %s",
+                            request.getMethod(), request.getRequestURI(), e.getMessage()),
+                    e);
         }
     }
 
     private void marshalRequest(Object input, ContentExchange request, String contentType)
-        throws SalesforceException {
+            throws SalesforceException {
         try {
             Marshaller marshaller = context.createMarshaller();
             ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
@@ -443,14 +453,14 @@ public class DefaultBulkApiClient extends AbstractClientBase implements BulkApiC
             request.setRequestContentType(contentType);
         } catch (JAXBException e) {
             throw new SalesforceException(
-                String.format("Error marshaling request for {%s:%s} : %s",
-                    request.getMethod(), request.getRequestURI(), e.getMessage()),
-                e);
+                    String.format("Error marshaling request for {%s:%s} : %s",
+                            request.getMethod(), request.getRequestURI(), e.getMessage()),
+                    e);
         } catch (IllegalArgumentException e) {
             throw new SalesforceException(
-                String.format("Error marshaling request for {%s:%s} : %s",
-                    request.getMethod(), request.getRequestURI(), e.getMessage()),
-                e);
+                    String.format("Error marshaling request for {%s:%s} : %s",
+                            request.getMethod(), request.getRequestURI(), e.getMessage()),
+                    e);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultRestClient.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultRestClient.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultRestClient.java
index 07f5af2..70eec1c 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultRestClient.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultRestClient.java
@@ -16,7 +16,17 @@
  */
 package org.apache.camel.component.salesforce.internal.client;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.List;
+
 import com.thoughtworks.xstream.XStream;
+import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.api.dto.RestError;
+import org.apache.camel.component.salesforce.internal.SalesforceSession;
+import org.apache.camel.component.salesforce.internal.dto.RestErrors;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.codehaus.jackson.type.TypeReference;
 import org.eclipse.jetty.client.ContentExchange;
@@ -25,16 +35,6 @@ import org.eclipse.jetty.client.HttpExchange;
 import org.eclipse.jetty.http.HttpHeaders;
 import org.eclipse.jetty.http.HttpMethods;
 import org.eclipse.jetty.util.StringUtil;
-import org.apache.camel.component.salesforce.api.SalesforceException;
-import org.apache.camel.component.salesforce.api.dto.RestError;
-import org.apache.camel.component.salesforce.internal.SalesforceSession;
-import org.apache.camel.component.salesforce.internal.dto.RestErrors;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-import java.util.List;
 
 public class DefaultRestClient extends AbstractClientBase implements RestClient {
 
@@ -75,7 +75,7 @@ public class DefaultRestClient extends AbstractClientBase implements RestClient
         try {
             if ("json".equals(format)) {
                 List<RestError> restErrors = objectMapper.readValue(
-                    httpExchange.getResponseContent(), new TypeReference<List<RestError>>() {
+                        httpExchange.getResponseContent(), new TypeReference<List<RestError>>() {
                 });
                 return new SalesforceException(restErrors, httpExchange.getResponseStatus());
             } else {
@@ -211,7 +211,7 @@ public class DefaultRestClient extends AbstractClientBase implements RestClient
     public void getSObjectWithId(String sObjectName, String fieldName, String fieldValue,
                                  ResponseCallback callback) {
         final ContentExchange get = getContentExchange(HttpMethods.GET,
-            sobjectsExternalIdUrl(sObjectName, fieldName, fieldValue));
+                sobjectsExternalIdUrl(sObjectName, fieldName, fieldValue));
 
         // requires authorization token
         setAccessToken(get);
@@ -223,7 +223,7 @@ public class DefaultRestClient extends AbstractClientBase implements RestClient
     public void upsertSObject(String sObjectName, String fieldName, String fieldValue, InputStream sObject,
                               ResponseCallback callback) {
         final ContentExchange patch = getContentExchange("PATCH",
-            sobjectsExternalIdUrl(sObjectName, fieldName, fieldValue));
+                sobjectsExternalIdUrl(sObjectName, fieldName, fieldValue));
 
         // requires authorization token
         setAccessToken(patch);
@@ -240,7 +240,7 @@ public class DefaultRestClient extends AbstractClientBase implements RestClient
     public void deleteSObjectWithId(String sObjectName, String fieldName, String fieldValue,
                                     ResponseCallback callback) {
         final ContentExchange delete = getContentExchange(HttpMethods.DELETE,
-            sobjectsExternalIdUrl(sObjectName, fieldName, fieldValue));
+                sobjectsExternalIdUrl(sObjectName, fieldName, fieldValue));
 
         // requires authorization token
         setAccessToken(delete);
@@ -251,7 +251,7 @@ public class DefaultRestClient extends AbstractClientBase implements RestClient
     @Override
     public void getBlobField(String sObjectName, String id, String blobFieldName, ResponseCallback callback) {
         final ContentExchange get = getContentExchange(HttpMethods.GET,
-            sobjectsUrl(sObjectName + "/" + id +"/" + blobFieldName));
+                sobjectsUrl(sObjectName + "/" + id + "/" + blobFieldName));
         // TODO this doesn't seem to be required, the response is always the content binary stream
         //get.setRequestHeader(HttpHeaders.ACCEPT_ENCODING, "base64");
 

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/RestClient.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/RestClient.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/RestClient.java
index 30186d9..431a821 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/RestClient.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/RestClient.java
@@ -16,10 +16,10 @@
  */
 package org.apache.camel.component.salesforce.internal.client;
 
-import org.apache.camel.component.salesforce.api.SalesforceException;
-
 import java.io.InputStream;
 
+import org.apache.camel.component.salesforce.api.SalesforceException;
+
 public interface RestClient {
 
     public static interface ResponseCallback {
@@ -31,37 +31,37 @@ public interface RestClient {
      * including the version, label, and a link to each version's root.
      *
      * @param callback {@link ResponseCallback} to handle response or exception
-    */
+     */
     void getVersions(ResponseCallback callback);
 
     /**
      * Lists available resources for the specified API version, including resource name and URI.
      *
      * @param callback {@link ResponseCallback} to handle response or exception
-    */
+     */
     void getResources(ResponseCallback callback);
 
     /**
      * Lists the available objects and their metadata for your organization's data.
      *
      * @param callback {@link ResponseCallback} to handle response or exception
-    */
+     */
     void getGlobalObjects(ResponseCallback callback);
 
     /**
      * Describes the individual metadata for the specified object.
      *
      * @param sObjectName specified object name
-     * @param callback {@link ResponseCallback} to handle response or exception
-    */
+     * @param callback    {@link ResponseCallback} to handle response or exception
+     */
     void getBasicInfo(String sObjectName, ResponseCallback callback);
 
     /**
      * Completely describes the individual metadata at all levels for the specified object.
      *
      * @param sObjectName specified object name
-     * @param callback {@link ResponseCallback} to handle response or exception
-    */
+     * @param callback    {@link ResponseCallback} to handle response or exception
+     */
     void getDescription(String sObjectName, ResponseCallback callback);
 
     /**
@@ -69,8 +69,8 @@ public interface RestClient {
      *
      * @param sObjectName specified object name
      * @param id          object id
-     * @param callback {@link ResponseCallback} to handle response or exception
-    */
+     * @param callback    {@link ResponseCallback} to handle response or exception
+     */
     void getSObject(String sObjectName, String id, String[] fields, ResponseCallback callback);
 
     /**
@@ -78,8 +78,8 @@ public interface RestClient {
      *
      * @param sObjectName specified object name
      * @param sObject     request entity
-     * @param callback {@link ResponseCallback} to handle response or exception
-    */
+     * @param callback    {@link ResponseCallback} to handle response or exception
+     */
     void createSObject(String sObjectName, InputStream sObject, ResponseCallback callback);
 
     /**
@@ -88,8 +88,8 @@ public interface RestClient {
      * @param sObjectName specified object name
      * @param id          object id
      * @param sObject     request entity
-     * @param callback {@link ResponseCallback} to handle response or exception
-    */
+     * @param callback    {@link ResponseCallback} to handle response or exception
+     */
     void updateSObject(String sObjectName, String id, InputStream sObject, ResponseCallback callback);
 
     /**
@@ -97,47 +97,46 @@ public interface RestClient {
      *
      * @param sObjectName specified object name
      * @param id          object id
-     * @param callback {@link ResponseCallback} to handle response or exception
-    */
+     * @param callback    {@link ResponseCallback} to handle response or exception
+     */
     void deleteSObject(String sObjectName, String id, ResponseCallback callback);
 
     /**
      * Retrieves a record for the specified external ID.
      *
      * @param sObjectName specified object name
-     * @param fieldName external field name
-     * @param fieldValue external field value
-     * @param callback {@link ResponseCallback} to handle response or exception
-    */
+     * @param fieldName   external field name
+     * @param fieldValue  external field value
+     * @param callback    {@link ResponseCallback} to handle response or exception
+     */
     void getSObjectWithId(String sObjectName, String fieldName, String fieldValue, ResponseCallback callback);
 
     /**
      * Creates or updates a record based on the value of a specified external ID field.
      *
      * @param sObjectName specified object name
-     * @param fieldName external field name
-     * @param fieldValue external field value
-     * @param sObject input object to insert or update
-     * @param callback {@link ResponseCallback} to handle response or exception
-    */
+     * @param fieldName   external field name
+     * @param fieldValue  external field value
+     * @param sObject     input object to insert or update
+     * @param callback    {@link ResponseCallback} to handle response or exception
+     */
     void upsertSObject(String sObjectName,
-                              String fieldName, String fieldValue, InputStream sObject, ResponseCallback callback);
+                       String fieldName, String fieldValue, InputStream sObject, ResponseCallback callback);
 
     /**
      * Deletes a record based on the value of a specified external ID field.
      *
      * @param sObjectName specified object name
-     * @param fieldName external field name
-     * @param fieldValue external field value
-     * @param callback {@link ResponseCallback} to handle response or exception
-    */
+     * @param fieldName   external field name
+     * @param fieldValue  external field value
+     * @param callback    {@link ResponseCallback} to handle response or exception
+     */
     void deleteSObjectWithId(String sObjectName,
                              String fieldName, String fieldValue, ResponseCallback callback);
 
 
     /**
      * Retrieves the specified blob field from an individual record.
-     *
      */
     void getBlobField(String sObjectName, String id, String blobFieldName, ResponseCallback callback);
 
@@ -154,24 +153,24 @@ public interface RestClient {
      * Executes the specified SOQL query.
      *
      * @param soqlQuery SOQL query
-     * @param callback {@link ResponseCallback} to handle response or exception
-    */
+     * @param callback  {@link ResponseCallback} to handle response or exception
+     */
     void query(String soqlQuery, ResponseCallback callback);
 
     /**
      * Get SOQL query results using nextRecordsUrl.
      *
      * @param nextRecordsUrl URL for next records to fetch, returned by query()
-     * @param callback {@link ResponseCallback} to handle response or exception
-    */
+     * @param callback       {@link ResponseCallback} to handle response or exception
+     */
     void queryMore(String nextRecordsUrl, ResponseCallback callback);
 
     /**
      * Executes the specified SOSL search.
      *
      * @param soslQuery SOSL query
-     * @param callback {@link ResponseCallback} to handle response or exception
-    */
+     * @param callback  {@link ResponseCallback} to handle response or exception
+     */
     void search(String soslQuery, ResponseCallback callback);
 
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/SalesforceSecurityListener.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/SalesforceSecurityListener.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/SalesforceSecurityListener.java
index 5eec212..93ebc43 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/SalesforceSecurityListener.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/SalesforceSecurityListener.java
@@ -16,19 +16,19 @@
  */
 package org.apache.camel.component.salesforce.internal.client;
 
+import java.io.IOException;
+
+import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.internal.SalesforceSession;
 import org.eclipse.jetty.client.HttpDestination;
 import org.eclipse.jetty.client.HttpEventListenerWrapper;
 import org.eclipse.jetty.client.HttpExchange;
 import org.eclipse.jetty.http.HttpHeaders;
 import org.eclipse.jetty.http.HttpStatus;
 import org.eclipse.jetty.io.Buffer;
-import org.apache.camel.component.salesforce.api.SalesforceException;
-import org.apache.camel.component.salesforce.internal.SalesforceSession;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.IOException;
-
 public class SalesforceSecurityListener extends HttpEventListenerWrapper {
 
     private static final Logger LOG = LoggerFactory.getLogger(SalesforceSecurityListener.class);
@@ -55,7 +55,7 @@ public class SalesforceSecurityListener extends HttpEventListenerWrapper {
     @Override
     public void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException {
         if (status == HttpStatus.UNAUTHORIZED_401 &&
-            retries < destination.getHttpClient().maxRetries()) {
+                retries < destination.getHttpClient().maxRetries()) {
 
             LOG.warn("Retrying on Salesforce authentication error [{}]: [{}]", status, reason);
             setDelegatingRequests(false);
@@ -106,7 +106,7 @@ public class SalesforceSecurityListener extends HttpEventListenerWrapper {
                     client.setAccessToken(exchange);
                 } else {
                     exchange.addRequestHeader(HttpHeaders.AUTHORIZATION,
-                        "OAuth " + currentToken);
+                            "OAuth " + currentToken);
                 }
 
                 // TODO handle a change in Salesforce instanceUrl, right now we retry with the same destination

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/SyncResponseCallback.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/SyncResponseCallback.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/SyncResponseCallback.java
index 0f567e6..ca62e88 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/SyncResponseCallback.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/SyncResponseCallback.java
@@ -16,12 +16,12 @@
  */
 package org.apache.camel.component.salesforce.internal.client;
 
-import org.apache.camel.component.salesforce.api.SalesforceException;
-
 import java.io.InputStream;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.camel.component.salesforce.api.SalesforceException;
+
 /**
  * Thin wrapper to handle callbacks for {@link RestClient.ResponseCallback} and allow waiting for results
  */

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/PushTopic.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/PushTopic.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/PushTopic.java
index 2135a16..6dc8490 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/PushTopic.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/PushTopic.java
@@ -18,9 +18,9 @@ package org.apache.camel.component.salesforce.internal.dto;
 
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import com.thoughtworks.xstream.annotations.XStreamConverter;
-import org.codehaus.jackson.annotate.JsonProperty;
 import org.apache.camel.component.salesforce.api.PicklistEnumConverter;
 import org.apache.camel.component.salesforce.api.dto.AbstractSObjectBase;
+import org.codehaus.jackson.annotate.JsonProperty;
 
 /**
  * Salesforce DTO for SObject PushTopic

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/QueryRecordsPushTopic.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/QueryRecordsPushTopic.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/QueryRecordsPushTopic.java
index 4adc13c..b7ed5f9 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/QueryRecordsPushTopic.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/QueryRecordsPushTopic.java
@@ -16,11 +16,11 @@
  */
 package org.apache.camel.component.salesforce.internal.dto;
 
+import java.util.List;
+
 import com.thoughtworks.xstream.annotations.XStreamImplicit;
 import org.apache.camel.component.salesforce.api.dto.AbstractQueryRecordsBase;
 
-import java.util.List;
-
 /**
  * Salesforce Query Records DTO for PushTopic
  */

http://git-wip-us.apache.org/repos/asf/camel/blob/aaa2710c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/RestErrors.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/RestErrors.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/RestErrors.java
index caf59fe..2213067 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/RestErrors.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/RestErrors.java
@@ -16,12 +16,12 @@
  */
 package org.apache.camel.component.salesforce.internal.dto;
 
+import java.util.List;
+
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import com.thoughtworks.xstream.annotations.XStreamImplicit;
 import org.apache.camel.component.salesforce.api.dto.RestError;
 
-import java.util.List;
-
 /**
  * DTO for Salesforce REST errors
  */


[05/11] CAMEL-6428: camel-salesforce component. Thanks to Dhiraj Bokde for the contribution.

Posted by da...@apache.org.
http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/Merchandise__c.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/Merchandise__c.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/Merchandise__c.java
new file mode 100644
index 0000000..3e3d36a
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/Merchandise__c.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.salesforce.dto;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.apache.camel.component.salesforce.api.dto.AbstractSObjectBase;
+
+@XStreamAlias("Merchandise__c")
+public class Merchandise__c extends AbstractSObjectBase {
+
+    private String Description__c;
+
+    private Double Price__c;
+
+    private Double Total_Inventory__c;
+
+    @JsonProperty("Description__c")
+    public String getDescription__c() {
+        return Description__c;
+    }
+
+    @JsonProperty("Description__c")
+    public void setDescription__c(String description__c) {
+        Description__c = description__c;
+    }
+
+    @JsonProperty("Price__c")
+    public Double getPrice__c() {
+        return Price__c;
+    }
+
+    @JsonProperty("Price__c")
+    public void setPrice__c(Double price__c) {
+        Price__c = price__c;
+    }
+
+    @JsonProperty("Total_Inventory__c")
+    public Double getTotal_Inventory__c() {
+        return Total_Inventory__c;
+    }
+
+    @JsonProperty("Total_Inventory__c")
+    public void setTotal_Inventory__c(Double total_Inventory__c) {
+        Total_Inventory__c = total_Inventory__c;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/QueryRecordsLine_Item__c.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/QueryRecordsLine_Item__c.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/QueryRecordsLine_Item__c.java
new file mode 100644
index 0000000..a2d00cb
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/QueryRecordsLine_Item__c.java
@@ -0,0 +1,35 @@
+/**
+ * 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.dto;
+
+import com.thoughtworks.xstream.annotations.XStreamImplicit;
+import org.apache.camel.component.salesforce.api.dto.AbstractQueryRecordsBase;
+
+import java.util.List;
+
+public class QueryRecordsLine_Item__c extends AbstractQueryRecordsBase {
+    @XStreamImplicit
+    private List<Line_Item__c> records;
+
+    public List<Line_Item__c> getRecords() {
+        return records;
+    }
+
+    public void setRecords(List<Line_Item__c> records) {
+        this.records = records;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/internal/SessionIntegrationTest.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/internal/SessionIntegrationTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/internal/SessionIntegrationTest.java
new file mode 100644
index 0000000..5e5ab5f
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/internal/SessionIntegrationTest.java
@@ -0,0 +1,79 @@
+/**
+ * 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.internal;
+
+import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.client.RedirectListener;
+import org.apache.camel.component.salesforce.LoginConfigHelper;
+import org.junit.Assert;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author dbokde
+ */
+public class SessionIntegrationTest extends Assert implements SalesforceSession.SalesforceSessionListener {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SessionIntegrationTest.class);
+    private static final int TIMEOUT = 60000;
+    private boolean onLoginTriggered;
+    private boolean onLogoutTriggered;
+
+    @Test
+    public void testLogin() throws Exception {
+
+        final HttpClient httpClient = new HttpClient();
+        httpClient.setConnectTimeout(TIMEOUT);
+        httpClient.setTimeout(TIMEOUT);
+        httpClient.registerListener(RedirectListener.class.getName());
+        httpClient.start();
+
+        final SalesforceSession session = new SalesforceSession(
+            httpClient, LoginConfigHelper.getLoginConfig());
+        session.addListener(this);
+
+        try {
+            String loginToken = session.login(session.getAccessToken());
+            LOG.info("First token " + loginToken);
+
+            assertTrue("SalesforceSessionListener onLogin NOT called", onLoginTriggered);
+            onLoginTriggered = false;
+
+            // refresh token, also causes logout
+            loginToken = session.login(loginToken);
+            LOG.info("Refreshed token " + loginToken);
+
+            assertTrue("SalesforceSessionListener onLogout NOT called", onLogoutTriggered);
+            assertTrue("SalesforceSessionListener onLogin NOT called", onLoginTriggered);
+
+        } finally {
+            // logout finally
+            session.logout();
+        }
+    }
+
+    @Override
+    public void onLogin(String accessToken, String instanceUrl) {
+        onLoginTriggered = true;
+    }
+
+    @Override
+    public void onLogout() {
+        onLogoutTriggered = true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/resources/log4j.properties b/components/camel-salesforce/camel-salesforce-component/src/test/resources/log4j.properties
new file mode 100644
index 0000000..9bbf19e
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/resources/log4j.properties
@@ -0,0 +1,18 @@
+#
+# The logging properties used
+#
+log4j.rootLogger=INFO, out
+
+# uncomment the following line to turn on Camel debugging
+#log4j.logger.org.apache.camel=DEBUG
+
+# CONSOLE appender not used by default
+log4j.appender.out=org.apache.log4j.ConsoleAppender
+log4j.appender.out.layout=org.apache.log4j.PatternLayout
+log4j.appender.out.layout.ConversionPattern=[%30.30t] %-30.30c{1} %-5p %m%n
+#log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
+
+log4j.throwableRenderer=org.apache.log4j.EnhancedThrowableRenderer
+
+#log4j.logger.org.apache.http=DEBUG
+#log4j.logger.org.apache.camel.component.salesforce=TRACE

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/test/resources/test-request.csv
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/resources/test-request.csv b/components/camel-salesforce/camel-salesforce-component/src/test/resources/test-request.csv
new file mode 100644
index 0000000..880c4c4
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/resources/test-request.csv
@@ -0,0 +1,3 @@
+"Description__c","Name","Price__c","Total_Inventory__c"
+"Created from Bulk API","[Bulk API] Merchandise 0 (batch 0)","15.0","30.0"
+"Created from Bulk API","[Bulk API] Merchandise 1 (batch 0)","30.0","60.0"
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/test/resources/test-request.xml
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/resources/test-request.xml b/components/camel-salesforce/camel-salesforce-component/src/test/resources/test-request.xml
new file mode 100644
index 0000000..bdfa10e
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/resources/test-request.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<sObjects xmlns="http://www.force.com/2009/06/asyncapi/dataload">
+  <sObject>
+    <Description__c>Created from Bulk API</Description__c>
+    <Price__c>15.0</Price__c>
+    <Total_Inventory__c>30.0</Total_Inventory__c>
+    <Name>[Bulk API] Merchandise 0 (batch 0)</Name>
+  </sObject>
+  <sObject>
+    <Description__c>Created from Bulk API</Description__c>
+    <Price__c>30.0</Price__c>
+    <Total_Inventory__c>60.0</Total_Inventory__c>
+    <Name>[Bulk API] Merchandise 1 (batch 0)</Name>
+  </sObject>
+</sObjects>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-maven-plugin/README.md
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/README.md b/components/camel-salesforce/camel-salesforce-maven-plugin/README.md
new file mode 100644
index 0000000..5bfd808
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/README.md
@@ -0,0 +1,26 @@
+# Maven plugin for camel-salesforce component #
+
+This plugin generates DTOs for the [Camel Salesforce Component](https://github.com/dhirajsb/camel-salesforce). 
+
+## Usage ##
+
+The plugin configuration has the following properties.
+
+* clientId - Salesforce client Id for Remote API access
+* clientSecret - Salesforce client secret for Remote API access
+* userName - Salesforce account user name
+* password - Salesforce account password (including secret token)
+* version - Salesforce Rest API version, defaults to 25.0
+* outputDirectory - Directory where to place generated DTOs, defaults to ${project.build.directory}/generated-sources/camel-salesforce
+* includes - List of SObject types to include
+* excludes - List of SObject types to exclude
+* includePattern - Java RegEx for SObject types to include
+* excludePattern - Java RegEx for SObject types to exclude
+* packageName - Java package name for generated DTOs, defaults to org.apache.camel.salesforce.dto.
+
+Fro obvious security reasons it is recommended that the clientId, clientSecret, userName and password fields be not set in the pom.xml. 
+The plugin should be configured for the rest of the properties, and can be executed using the following command:
+
+	mvn camel-salesforce:generate -DclientId=<clientid> -DclientSecret=<clientsecret> -DuserName=<username> -Dpassword=<password>
+
+The generated DTOs use Jackson and XStream annotations. All Salesforce field types are supported. Date and time fields are mapped to Joda DateTime, and picklist fields are mapped to generated Java Enumerations. 

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-maven-plugin/pom.xml
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/pom.xml b/components/camel-salesforce/camel-salesforce-maven-plugin/pom.xml
new file mode 100644
index 0000000..a5bfdf7
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/pom.xml
@@ -0,0 +1,78 @@
+<?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-parent</artifactId>
+    <version>2.12-SNAPSHOT</version>
+  </parent>
+
+  <groupId>org.apache.camel.maven</groupId>
+  <artifactId>camel-salesforce-maven-plugin</artifactId>
+  <packaging>maven-plugin</packaging>
+  <name>Camel :: Salesforce :: Maven plugin</name>
+  <description>Camel Salesforce Maven plugin</description>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-plugin-api</artifactId>
+      <version>2.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-salesforce</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.velocity</groupId>
+      <artifactId>velocity</artifactId>
+      <version>${velocity-version}</version>
+    </dependency>
+
+    <!-- logging -->
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+      <version>${slf4j-api-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>log4j</groupId>
+      <artifactId>log4j</artifactId>
+      <version>${log4j-version}</version>
+    </dependency>
+
+    <!-- testing -->
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-log4j12</artifactId>
+      <version>${slf4j-api-version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>${junit-version}</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/CamelSalesforceMojo.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/CamelSalesforceMojo.java b/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/CamelSalesforceMojo.java
new file mode 100644
index 0000000..70942a4
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/java/org/apache/camel/maven/CamelSalesforceMojo.java
@@ -0,0 +1,570 @@
+/**
+ * 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.maven;
+
+import org.apache.log4j.Logger;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.runtime.RuntimeConstants;
+import org.apache.velocity.runtime.log.Log4JLogChute;
+import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.client.RedirectListener;
+import org.apache.camel.component.salesforce.SalesforceLoginConfig;
+import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.api.dto.*;
+import org.apache.camel.component.salesforce.internal.SalesforceSession;
+import org.apache.camel.component.salesforce.internal.client.DefaultRestClient;
+import org.apache.camel.component.salesforce.internal.client.RestClient;
+import org.apache.camel.component.salesforce.internal.client.SyncResponseCallback;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Pattern;
+
+/**
+ * Goal which generates POJOs for Salesforce SObjects
+ *
+ * @goal generate
+ * 
+ * @phase generate-sources
+ *
+ */
+public class CamelSalesforceMojo extends AbstractMojo
+{
+    private static final String JAVA_EXT = ".java";
+    private static final String PACKAGE_NAME_PATTERN = "^[a-z]+(\\.[a-z][a-z0-9]*)*$";
+    private static final String SOBJECT_POJO_VM = "/sobject-pojo.vm";
+    private static final String SOBJECT_QUERY_RECORDS_VM = "/sobject-query-records.vm";
+    private static final String SOBJECT_PICKLIST_VM = "/sobject-picklist.vm";
+
+    // used for velocity logging, to avoid creating velocity.log
+    private static final Logger LOG = Logger.getLogger(CamelSalesforceMojo.class.getName());
+    private static final int TIMEOUT = 60000;
+
+    /**
+     * Salesforce client id
+     * @parameter property="${clientId}"
+     * @required
+     */
+    protected String clientId;
+
+    /**
+     * Salesforce client secret
+     * @parameter property="${clientSecret}"
+     * @required
+     */
+    protected String clientSecret;
+
+    /**
+     * Salesforce user name
+     * @parameter property="${userName}"
+     * @required
+     */
+    protected String userName;
+
+    /**
+     * Salesforce password
+     * @parameter property="${password}"
+     * @required
+     */
+    protected String password;
+
+    /**
+     * Salesforce version
+     * @parameter property="${version}" default-value="25.0"
+     */
+    protected String version;
+
+    /**
+     * Location of the file.
+     * @parameter property="${outputDirectory}" default-value="${project.build.directory}/generated-sources/camel-salesforce"
+     * @required
+     */
+    protected File outputDirectory;
+
+    /**
+     * Names of Salesforce SObject for which POJOs must be generated
+     * @parameter
+     */
+    protected String[] includes;
+
+    /**
+     * Do NOT generate POJOs for these Salesforce SObjects
+     * @parameter
+     */
+    protected String[] excludes;
+
+    /**
+     * Include Salesforce SObjects that match pattern
+     * @parameter property="${includePattern}"
+     */
+    protected String includePattern;
+
+    /**
+     * Exclude Salesforce SObjects that match pattern
+     * @parameter property="${excludePattern}"
+     */
+    protected String excludePattern;
+
+    /**
+     * Java package name for generated POJOs
+     * @parameter property="${packageName}" default-value="org.apache.camel.salesforce.dto"
+     */
+    protected String packageName;
+
+    private VelocityEngine engine;
+
+    /**
+     * Execute the mojo to generate SObject POJOs
+     * @throws MojoExecutionException
+     */
+    public void execute()
+        throws MojoExecutionException
+    {
+        // initialize velocity to load resources from class loader and use Log4J
+        Properties velocityProperties = new Properties();
+        velocityProperties.setProperty(RuntimeConstants.RESOURCE_LOADER, "cloader");
+        velocityProperties.setProperty("cloader.resource.loader.class", ClasspathResourceLoader.class.getName());
+        velocityProperties.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, Log4JLogChute.class.getName());
+        velocityProperties.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM + ".log4j.logger", LOG.getName());
+        engine = new VelocityEngine(velocityProperties);
+        engine.init();
+
+        // make sure we can load both templates
+        if (!engine.resourceExists(SOBJECT_POJO_VM) ||
+            !engine.resourceExists(SOBJECT_QUERY_RECORDS_VM)) {
+            throw new MojoExecutionException("Velocity templates not found");
+        }
+
+        // connect to Salesforce
+        final HttpClient httpClient = new HttpClient();
+        httpClient.registerListener(RedirectListener.class.getName());
+        httpClient.setConnectTimeout(TIMEOUT);
+        httpClient.setTimeout(TIMEOUT);
+        try {
+            httpClient.start();
+        } catch (Exception e) {
+            throw new MojoExecutionException("Error creating HTTP client: " + e.getMessage(), e);
+        }
+
+        final SalesforceSession session = new SalesforceSession(httpClient,
+            new SalesforceLoginConfig(SalesforceLoginConfig.DEFAULT_LOGIN_URL,
+            clientId, clientSecret, userName, password, false));
+
+        getLog().info("Salesforce login...");
+        try {
+            session.login(null);
+        } catch (SalesforceException e) {
+            String msg = "Salesforce login error " + e.getMessage();
+            throw new MojoExecutionException(msg, e);
+        }
+        getLog().info("Salesforce login successful");
+
+        // create rest client
+        RestClient restClient = null;
+        try {
+            restClient = new DefaultRestClient(httpClient,
+                version, "json", session);
+            // remember to start the active client object
+            ((DefaultRestClient)restClient).start();
+        } catch (Exception e) {
+            final String msg = "Unexpected exception creating Rest client: " + e.getMessage();
+            throw new MojoExecutionException(msg, e);
+        }
+
+        try {
+            // use Jackson json
+            final ObjectMapper mapper = new ObjectMapper();
+
+            // call getGlobalObjects to get all SObjects
+            final Set<String> objectNames = new HashSet<String>();
+            final SyncResponseCallback callback = new SyncResponseCallback();
+            try {
+                getLog().info("Getting Salesforce Objects...");
+                restClient.getGlobalObjects(callback);
+                if (!callback.await(TIMEOUT, TimeUnit.MILLISECONDS)) {
+                    throw new MojoExecutionException("Timeout waiting for getGlobalObjects!");
+                }
+                final SalesforceException ex = callback.getException();
+                if (ex != null) {
+                    throw ex;
+                }
+                final GlobalObjects globalObjects = mapper.readValue(callback.getResponse(),
+                    GlobalObjects.class);
+
+                // create a list of object names
+                for (SObject sObject : globalObjects.getSobjects()) {
+                    objectNames.add(sObject.getName());
+                }
+            } catch (Exception e) {
+                String msg = "Error getting global Objects " + e.getMessage();
+                throw new MojoExecutionException(msg, e);
+            }
+
+            // check if we are generating POJOs for all objects or not
+            if ((includes != null && includes.length > 0) ||
+                (excludes != null && excludes.length > 0) ||
+                (includePattern != null && !includePattern.trim().isEmpty()) ||
+                (excludePattern != null && !excludePattern.trim().isEmpty())) {
+
+                getLog().info("Looking for matching Object names...");
+                // create a list of accepted names
+                final Set<String> includedNames = new HashSet<String>();
+                if (includes != null && includes.length > 0) {
+                    for (String name : includes) {
+                        name = name.trim();
+                        if (name.isEmpty()) {
+                            throw new MojoExecutionException("Invalid empty name in includes");
+                        }
+                        includedNames.add(name);
+                    }
+                }
+
+                final Set<String> excludedNames = new HashSet<String>();
+                if (excludes != null && excludes.length > 0) {
+                    for (String name : excludes) {
+                        name = name.trim();
+                        if (name.isEmpty()) {
+                            throw new MojoExecutionException("Invalid empty name in excludes");
+                        }
+                        excludedNames.add(name);
+                    }
+                }
+
+                // check whether a pattern is in effect
+                Pattern incPattern;
+                if (includePattern != null && !includePattern.trim().isEmpty()) {
+                    incPattern = Pattern.compile(includePattern.trim());
+                } else if (includedNames.isEmpty()) {
+                    // include everything by default if no include names are set
+                    incPattern = Pattern.compile(".*");
+                } else {
+                    // include nothing by default if include names are set
+                    incPattern = Pattern.compile("^$");
+                }
+
+                // check whether a pattern is in effect
+                Pattern excPattern;
+                if (excludePattern != null && !excludePattern.trim().isEmpty()) {
+                    excPattern = Pattern.compile(excludePattern.trim());
+                } else {
+                    // exclude nothing by default
+                    excPattern = Pattern.compile("^$");
+                }
+
+                final Set<String> acceptedNames = new HashSet<String>();
+                for (String name : objectNames) {
+                    // name is included, or matches include pattern
+                    // and is not excluded and does not match exclude pattern
+                    if ((includedNames.contains(name) || incPattern.matcher(name).matches()) &&
+                        !excludedNames.contains(name) &&
+                        !excPattern.matcher(name).matches()) {
+                        acceptedNames.add(name);
+                    }
+                }
+                objectNames.clear();
+                objectNames.addAll(acceptedNames);
+
+                getLog().info(String.format("Found %s matching Objects", objectNames.size()));
+
+            } else {
+                getLog().warn(String.format("Generating Java classes for all %s Objects, this may take a while...",
+                    objectNames.size()));
+            }
+
+            // for every accepted name, get SObject description
+            final Set<SObjectDescription> descriptions =
+                new HashSet<SObjectDescription>();
+
+            try {
+                getLog().info("Retrieving Object descriptions...");
+                for (String name : objectNames) {
+                    callback.reset();
+                    restClient.getDescription(name, callback);
+                    if (!callback.await(TIMEOUT, TimeUnit.MILLISECONDS)) {
+                        throw new MojoExecutionException(
+                            "Timeout waiting for getDescription for sObject " + name);
+                    }
+                    final SalesforceException ex = callback.getException();
+                    if (ex != null) {
+                        throw ex;
+                    }
+                    descriptions.add(mapper.readValue(callback.getResponse(),
+                            SObjectDescription.class));
+                }
+            } catch (Exception e) {
+                String msg = "Error getting SObject description " + e.getMessage();
+                throw new MojoExecutionException(msg, e);
+            }
+
+            // create package directory
+            // validate package name
+            if (!packageName.matches(PACKAGE_NAME_PATTERN)) {
+                throw new MojoExecutionException("Invalid package name " + packageName);
+            }
+            final File pkgDir = new File(outputDirectory, packageName.trim().replace('.', File.separatorChar));
+            if (!pkgDir.exists()) {
+                if (!pkgDir.mkdirs()) {
+                    throw new MojoExecutionException("Unable to create " + pkgDir);
+                }
+            }
+
+            getLog().info("Generating Java Classes...");
+            // generate POJOs for every object description
+            final GeneratorUtility utility = new GeneratorUtility();
+            // should we provide a flag to control timestamp generation?
+            final String generatedDate = new Date().toString();
+            for (SObjectDescription description : descriptions) {
+                processDescription(pkgDir, description, utility, generatedDate);
+            }
+
+            getLog().info(String.format("Successfully generated %s Java Classes", (descriptions.size() * 2)));
+
+        } finally {
+            // remember to stop the client
+            try {
+                ((DefaultRestClient)restClient).stop();
+            } catch (Exception ignore) {}
+
+            // Salesforce session stop
+            try {
+                session.stop();
+            } catch (Exception ignore) {}
+
+            // release HttpConnections
+            try {
+                httpClient.stop();
+            } catch (Exception ignore) {}
+        }
+    }
+
+    private void processDescription(File pkgDir, SObjectDescription description, GeneratorUtility utility, String generatedDate) throws MojoExecutionException {
+        // generate a source file for SObject
+        String fileName = description.getName() + JAVA_EXT;
+        BufferedWriter writer = null;
+        try {
+            final File pojoFile = new File(pkgDir, fileName);
+            writer = new BufferedWriter(new FileWriter(pojoFile));
+
+            VelocityContext context = new VelocityContext();
+            context.put("packageName", packageName);
+            context.put("utility", utility);
+            context.put("desc", description);
+            context.put("generatedDate", generatedDate);
+
+            Template pojoTemplate = engine.getTemplate(SOBJECT_POJO_VM);
+            pojoTemplate.merge(context, writer);
+            // close pojoFile
+            writer.close();
+
+            // write required Enumerations for any picklists
+            for (SObjectField field : description.getFields()) {
+                if (utility.isPicklist(field)) {
+                    fileName = utility.enumTypeName(field.getName()) + JAVA_EXT;
+                    File enumFile = new File(pkgDir, fileName);
+                    writer = new BufferedWriter(new FileWriter(enumFile));
+
+                    context = new VelocityContext();
+                    context.put("packageName", packageName);
+                    context.put("utility", utility);
+                    context.put("field", field);
+                    context.put("generatedDate", generatedDate);
+
+                    Template queryTemplate = engine.getTemplate(SOBJECT_PICKLIST_VM);
+                    queryTemplate.merge(context, writer);
+
+                    // close Enum file
+                    writer.close();
+                }
+            }
+
+            // write the QueryRecords class
+            fileName = "QueryRecords" + description.getName() + JAVA_EXT;
+            File queryFile = new File(pkgDir, fileName);
+            writer = new BufferedWriter(new FileWriter(queryFile));
+
+            context = new VelocityContext();
+            context.put("packageName", packageName);
+            context.put("desc", description);
+            context.put("generatedDate", generatedDate);
+
+            Template queryTemplate = engine.getTemplate(SOBJECT_QUERY_RECORDS_VM);
+            queryTemplate.merge(context, writer);
+
+            // close QueryRecords file
+            writer.close();
+
+        } catch (Exception e) {
+            String msg = "Error creating " + fileName + ": " + e.getMessage();
+            throw new MojoExecutionException(msg, e);
+        } finally {
+            if (writer != null) {
+                try {
+                    writer.close();
+                } catch (IOException ignore) {}
+            }
+        }
+    }
+
+    public static class GeneratorUtility {
+
+        private static final Set<String> baseFields;
+        private static final Map<String, String> lookupMap;
+
+        static {
+            baseFields = new HashSet<String>();
+            for (Field field : AbstractSObjectBase.class.getDeclaredFields()) {
+                baseFields.add(field.getName());
+            }
+
+            // create a type map
+            // using JAXB mapping, for the most part
+            // uses Joda time instead of XmlGregorianCalendar
+            // TODO do we need support for commented types???
+            final String[][] typeMap = new String[][] {
+                {"ID", "String"}, // mapping for tns:ID SOAP type
+                {"string", "String"},
+                {"integer", "java.math.BigInteger"},
+                {"int", "Integer"},
+                {"long", "Long"},
+                {"short", "Short"},
+                {"decimal", "java.math.BigDecimal"},
+                {"float", "Float"},
+                {"double", "Double"},
+                {"boolean", "Boolean"},
+                {"byte", "Byte"},
+//                {"QName", "javax.xml.namespace.QName"},
+
+//                {"dateTime", "javax.xml.datatype.XMLGregorianCalendar"},
+                {"dateTime", "org.joda.time.DateTime"},
+
+                // the blob base64Binary type is mapped to String URL for retrieving the blob
+                {"base64Binary", "String"},
+//                {"hexBinary", "byte[]"},
+
+                {"unsignedInt", "Long"},
+                {"unsignedShort", "Integer"},
+                {"unsignedByte", "Short"},
+
+//                {"time", "javax.xml.datatype.XMLGregorianCalendar"},
+                {"time", "org.joda.time.DateTime"},
+//                {"date", "javax.xml.datatype.XMLGregorianCalendar"},
+                {"date", "org.joda.time.DateTime"},
+//                {"g", "javax.xml.datatype.XMLGregorianCalendar"},
+                {"g", "org.joda.time.DateTime"},
+
+                // Salesforce maps any types like string, picklist, reference, etc. to string
+                {"anyType", "String"},
+/*
+                {"anySimpleType", "java.lang.Object"},
+                {"anySimpleType", "java.lang.String"},
+                {"duration", "javax.xml.datatype.Duration"},
+                {"NOTATION", "javax.xml.namespace.QName"}
+*/
+            };
+            lookupMap = new HashMap<String, String>();
+            for (String[] entry : typeMap) {
+                lookupMap.put(entry[0], entry[1]);
+            }
+        }
+
+        private static final String BASE64BINARY = "base64Binary";
+
+        public boolean isBlobField(SObjectField field) {
+            final String soapType = field.getSoapType();
+            return BASE64BINARY.equals(soapType.substring(soapType.indexOf(':')+1));
+        }
+
+        public boolean notBaseField(String name) {
+            return !baseFields.contains(name);
+        }
+
+        public String getFieldType(SObjectField field) throws MojoExecutionException {
+            // check if this is a picklist
+            if (isPicklist(field)) {
+                // use a pick list enum, which will be created after generating the SObject class
+                return enumTypeName(field.getName());
+            } else {
+                // map field to Java type
+                final String soapType = field.getSoapType();
+                final String type = lookupMap.get(soapType.substring(soapType.indexOf(':')+1));
+                if (type == null) {
+                    throw new MojoExecutionException(
+                        String.format("Unsupported type %s for field %s", soapType, field.getName()));
+                }
+                return type;
+            }
+        }
+
+        public boolean hasPicklists(SObjectDescription desc) {
+            for (SObjectField field : desc.getFields()) {
+                if (isPicklist(field)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public PickListValue getLastEntry(SObjectField field) {
+            final List<PickListValue> values = field.getPicklistValues();
+            return values.get(values.size() - 1);
+        }
+
+        public boolean isPicklist(SObjectField field) {
+            return field.getPicklistValues() != null && !field.getPicklistValues().isEmpty();
+        }
+
+        public String enumTypeName(String name) {
+            name = name.endsWith("__c") ? name.substring(0, name.length() - 3) : name;
+            return name + "Enum";
+        }
+
+        public String getEnumConstant(String value) {
+
+            // TODO add support for supplementary characters
+            final StringBuilder result = new StringBuilder();
+            boolean changed = false;
+            if (!Character.isJavaIdentifierStart(value.charAt(0))) {
+                result.append("_");
+                changed = true;
+            }
+            for (char c : value.toCharArray()) {
+                if (Character.isJavaIdentifierPart(c)) {
+                    result.append(c);
+                } else {
+                    // replace non Java identifier character with '_'
+                    result.append('_');
+                    changed = true;
+                }
+            }
+
+            return changed ? result.toString().toUpperCase() : value.toUpperCase();
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/resources/sobject-picklist.vm
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/resources/sobject-picklist.vm b/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/resources/sobject-picklist.vm
new file mode 100644
index 0000000..0aed2a7
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/resources/sobject-picklist.vm
@@ -0,0 +1,52 @@
+## sobject-picklist.vm
+/*
+ * Salesforce DTO generated by camel-salesforce-maven-plugin
+ * Generated on: $generatedDate
+ */
+package $packageName;
+
+import org.codehaus.jackson.annotate.JsonCreator;
+import org.codehaus.jackson.annotate.JsonValue;
+
+#set ( $enumName = $utility.enumTypeName($field.Name) )
+/**
+ * Salesforce Enumeration DTO for picklist $field.Name
+ */
+public enum $enumName {
+## find the last entry
+#set ( $lastEntry = $utility.getLastEntry($field) )
+
+#foreach ( $entry in $field.PicklistValues)
+#set ( $value = $entry.Value )
+#if ( $entry == $lastEntry )
+#set ( $delim = ";" )
+#else
+#set ( $delim = ",")
+#end
+    // $value
+    $utility.getEnumConstant($value)("$value")$delim
+#end
+
+    final String value;
+
+    private $enumName(String value) {
+        this.value = value;
+    }
+
+    @JsonValue
+    public String value() {
+        return this.value;
+    }
+
+    @JsonCreator
+    public static $enumName fromValue(String value) {
+#set ( $allValues = ".values()" )
+        for ($enumName e : $enumName$allValues) {
+            if (e.value.equals(value)) {
+                return e;
+            }
+        }
+        throw new IllegalArgumentException(value);
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/resources/sobject-pojo.vm
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/resources/sobject-pojo.vm b/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/resources/sobject-pojo.vm
new file mode 100644
index 0000000..b240d46
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/resources/sobject-pojo.vm
@@ -0,0 +1,60 @@
+## sobject-pojo.vm
+/*
+ * Salesforce DTO generated by camel-salesforce-maven-plugin
+ * Generated on: $generatedDate
+ */
+package $packageName;
+
+## add imports for XStreamConverter and PicklistEnumConverter if needed
+#set ( $hasPicklists = $utility.hasPicklists($desc) )
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+#if ( $hasPicklists )
+import com.thoughtworks.xstream.annotations.XStreamConverter;
+#end
+import org.codehaus.jackson.annotate.JsonProperty;
+#if ( $hasPicklists )
+import org.apache.camel.component.salesforce.api.PicklistEnumConverter;
+#end
+import org.apache.camel.component.salesforce.api.dto.AbstractSObjectBase;
+
+/**
+ * Salesforce DTO for SObject $desc.Name
+ */
+@XStreamAlias("$desc.Name")
+public class $desc.Name extends AbstractSObjectBase {
+
+#foreach ( $field in $desc.Fields )
+#if ( $utility.notBaseField($field.Name) )
+#set ( $fieldName = $field.Name )
+#set ( $fieldType = $utility.getFieldType($field) )
+    // $fieldName
+#if ( $utility.isBlobField($field) )
+#set ( $propertyName = $fieldName + "Url" )
+#else
+#set ( $propertyName = $fieldName )
+#end
+## add a converter annotation if needed
+#if ( $utility.isPicklist($field) )
+    @XStreamConverter(PicklistEnumConverter.class)
+#else
+## add an alias for blob field url if needed
+#if ( $propertyName != $fieldName )
+    // blob field url, use getBlobField to get the content
+    @XStreamAlias("$fieldName")
+#end
+#end
+    private $fieldType $propertyName;
+
+    @JsonProperty("$fieldName")
+    public $fieldType get$propertyName() {
+        return this.$propertyName;
+    }
+
+    @JsonProperty("$fieldName")
+    public void set$propertyName($fieldType $propertyName) {
+        this.$propertyName = $propertyName;
+    }
+
+#end
+#end
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/resources/sobject-query-records.vm
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/resources/sobject-query-records.vm b/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/resources/sobject-query-records.vm
new file mode 100644
index 0000000..40f1ac1
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/main/resources/sobject-query-records.vm
@@ -0,0 +1,29 @@
+## sobject-query-records.vm
+/*
+ * Salesforce Query DTO generated by camel-salesforce-maven-plugin
+ * Generated on: $generatedDate
+ */
+package $packageName;
+
+import com.thoughtworks.xstream.annotations.XStreamImplicit;
+import org.apache.camel.component.salesforce.api.dto.AbstractQueryRecordsBase;
+
+import java.util.List;
+
+/**
+ * Salesforce QueryRecords DTO for type $desc.Name
+ */
+#set( $descName = $desc.Name )
+public class QueryRecords$descName extends AbstractQueryRecordsBase {
+
+    @XStreamImplicit
+    private List<$descName> records;
+
+    public List<$descName> getRecords() {
+        return records;
+    }
+
+    public void setRecords(List<$descName> records) {
+        this.records = records;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/java/org/apache/camel/maven/CamelSalesforceMojoIntegrationTest.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/java/org/apache/camel/maven/CamelSalesforceMojoIntegrationTest.java b/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/java/org/apache/camel/maven/CamelSalesforceMojoIntegrationTest.java
new file mode 100644
index 0000000..781c592
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/java/org/apache/camel/maven/CamelSalesforceMojoIntegrationTest.java
@@ -0,0 +1,85 @@
+/**
+ * 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.maven;
+
+import org.apache.maven.plugin.logging.SystemStreamLog;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+public class CamelSalesforceMojoIntegrationTest {
+
+    private static final String TEST_LOGIN_PROPERTIES = "test-salesforce-login.properties";
+
+    @Test
+    public void testExecute() throws Exception {
+        CamelSalesforceMojo mojo = new CamelSalesforceMojo();
+
+        mojo.setLog(new SystemStreamLog());
+
+        // set login properties
+        setLoginProperties(mojo);
+
+        // set defaults
+        mojo.version = "27.0";
+        mojo.outputDirectory = new File("target/generated-sources/camel-salesforce");
+        mojo.packageName = "org.apache.camel.salesforce.dto";
+
+        // set code generation properties
+        mojo.includePattern = "(.*__c)|(PushTopic)";
+
+        // remove generated code directory
+        if (mojo.outputDirectory.exists()) {
+            // remove old files
+            for (File file : mojo.outputDirectory.listFiles()) {
+                file.delete();
+            }
+            mojo.outputDirectory.delete();
+        }
+
+        // generate code
+        mojo.execute();
+
+        // validate generated code
+        // check that it was generated
+        Assert.assertTrue("Output directory was not created", mojo.outputDirectory.exists());
+
+        // TODO check that the generated code compiles
+    }
+
+    private void setLoginProperties(CamelSalesforceMojo mojo) throws IllegalAccessException, IOException {
+        // load test-salesforce-login properties
+        Properties properties = new Properties();
+        InputStream stream = new FileInputStream(TEST_LOGIN_PROPERTIES);
+        if (null == stream) {
+            throw new IllegalAccessException("Create a properties file named " +
+                TEST_LOGIN_PROPERTIES + " with clientId, clientSecret, userName, password and a testId" +
+                " for a Salesforce account with the Merchandise object from Salesforce Guides.");
+        }
+        properties.load(stream);
+        mojo.clientId= properties.getProperty("clientId");
+        mojo.clientSecret= properties.getProperty("clientSecret");
+        mojo.userName= properties.getProperty("userName");
+        mojo.password= properties.getProperty("password");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/log4j.properties b/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/log4j.properties
new file mode 100644
index 0000000..6c5150e
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/test/resources/log4j.properties
@@ -0,0 +1,19 @@
+#
+# The logging properties used
+#
+log4j.rootLogger=INFO, out
+
+# uncomment the following line to turn on Camel debugging
+#log4j.logger.org.apache.camel=DEBUG
+
+# CONSOLE appender not used by default
+log4j.appender.out=org.apache.log4j.ConsoleAppender
+log4j.appender.out.layout=org.apache.log4j.PatternLayout
+log4j.appender.out.layout.ConversionPattern=[%30.30t] %-30.30c{1} %-5p %m%n
+#log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
+
+log4j.throwableRenderer=org.apache.log4j.EnhancedThrowableRenderer
+
+#log4j.logger.org.apache.camel.maven=DEBUG
+#log4j.logger.org.apache.http=DEBUG
+#log4j.logger.org.apache.camel.component.salesforce=TRACE

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/pom.xml
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/pom.xml b/components/camel-salesforce/pom.xml
new file mode 100644
index 0000000..1a79dcd
--- /dev/null
+++ b/components/camel-salesforce/pom.xml
@@ -0,0 +1,38 @@
+<?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.12-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>camel-salesforce-parent</artifactId>
+    <packaging>pom</packaging>
+    <name>Camel :: Salesforce :: Parent</name>
+    <description>Camel Salesforce parent</description>
+
+    <modules>
+        <module>camel-salesforce-component</module>
+        <module>camel-salesforce-maven-plugin</module>
+    </modules>
+
+</project>

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/pom.xml
----------------------------------------------------------------------
diff --git a/components/pom.xml b/components/pom.xml
index 8a4b7d4..e186ce3 100644
--- a/components/pom.xml
+++ b/components/pom.xml
@@ -143,6 +143,7 @@
     <module>camel-rx</module>
     <module>camel-sap-netweaver</module>
     <module>camel-saxon</module>
+    <module>camel-salesforce</module>
     <module>camel-script</module>
     <module>camel-servlet</module>
     <module>camel-servletlistener</module>

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index 66940d7..d558694 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -72,6 +72,7 @@
     <cglib-version>2.2</cglib-version>
     <cmis-version>0.8.0</cmis-version>
     <cometd-bayeux-version>6.1.11</cometd-bayeux-version>
+    <cometd-java-client-version>2.4.3</cometd-java-client-version>
     <cometd-java-server-bundle-version>2.3.1_2</cometd-java-server-bundle-version>
     <cometd-java-server>2.3.1</cometd-java-server>
     <commons-beanutils-bundle-version>1.8.3_1</commons-beanutils-bundle-version>
@@ -963,6 +964,11 @@
       </dependency>
       <dependency>
         <groupId>org.apache.camel</groupId>
+        <artifactId>camel-salesforce</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.camel</groupId>
         <artifactId>camel-saxon</artifactId>
         <version>${project.version}</version>
       </dependency>

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/platforms/karaf/features/src/main/resources/features.xml
----------------------------------------------------------------------
diff --git a/platforms/karaf/features/src/main/resources/features.xml b/platforms/karaf/features/src/main/resources/features.xml
index 165f9bb..7a378e2 100644
--- a/platforms/karaf/features/src/main/resources/features.xml
+++ b/platforms/karaf/features/src/main/resources/features.xml
@@ -738,6 +738,22 @@
     <bundle dependency='true'>mvn:org.codehaus.jackson/jackson-mapper-asl/${jackson-version}</bundle>
     <bundle>mvn:org.apache.camel/camel-sap-netweaver/${project.version}</bundle>
   </feature>
+  <feature name='camel-salesforce' version='${project.version}' resolver='(obr)' start-level='50'>
+    <feature version='${project.version}'>camel-core</feature>
+    <bundle dependency='true'>mvn:org.codehaus.jackson/jackson-mapper-asl/${jackson-version}</bundle>
+    <bundle dependency='true'>mvn:org.codehaus.jackson/jackson-core-asl/${jackson-version}</bundle>
+    <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.xstream/${xstream-bundle-version}</bundle>
+    <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.xpp3/${xpp3-bundle-version}</bundle>
+    <bundle dependency='true'>mvn:org.cometd.java/cometd-java-client/${cometd-java-client-version}</bundle>
+    <bundle dependency='true'>mvn:org.cometd.java/bayeux-api/${cometd-java-client-version}</bundle>
+    <bundle dependency='true'>mvn:org.cometd.java/cometd-java-common/${cometd-java-client-version}</bundle>
+    <bundle dependency='true'>mvn:org.eclipse.jetty/jetty-util/${jetty-version}</bundle>
+    <bundle dependency='true'>mvn:org.eclipse.jetty/jetty-io/${jetty--version}</bundle>
+    <bundle dependency='true'>mvn:org.eclipse.jetty/jetty-http/${jetty-version}</bundle>
+    <bundle dependency='true'>mvn:org.eclipse.jetty/jetty-client/${jetty-version}</bundle>
+    <bundle dependency='true'>mvn:joda-time/joda-time/${jodatime2-bundle-version}</bundle>
+    <bundle>mvn:org.apache.camel/camel-salesforce/${project.version}</bundle>
+  </feature>
   <feature name='camel-saxon' version='${project.version}' resolver='(obr)' start-level='50'>
     <feature version='${project.version}'>camel-core</feature>
     <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.xmlresolver/${xmlresolver-bundle-version}</bundle>


[11/11] git commit: CAMEL-6428: camel-salesforce component. Thanks to Dhiraj Bokde for the contribution.

Posted by da...@apache.org.
CAMEL-6428: camel-salesforce component. Thanks to Dhiraj Bokde for the contribution.


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

Branch: refs/heads/master
Commit: 0c401b9fba53837bdea3dc486880dd0e0c6e2d6f
Parents: 469e0e3
Author: Claus Ibsen <da...@apache.org>
Authored: Wed Jun 5 16:55:52 2013 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Wed Jun 5 17:12:31 2013 +0200

----------------------------------------------------------------------
 .gitignore                                         |    1 +
 apache-camel/pom.xml                               |    4 +
 apache-camel/src/main/descriptors/common-bin.xml   |    1 +
 .../camel-salesforce-component/README.md           |   68 ++
 .../camel-salesforce-component/pom.xml             |  121 +++
 .../component/salesforce/SalesforceComponent.java  |  233 +++++
 .../component/salesforce/SalesforceConsumer.java   |  215 +++++
 .../component/salesforce/SalesforceEndpoint.java   |   96 ++
 .../salesforce/SalesforceEndpointConfig.java       |  292 +++++++
 .../salesforce/SalesforceLoginConfig.java          |   99 +++
 .../component/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 ++++
 .../component/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 ++
 .../component/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 ++
 .../salesforce/api/dto/SObjectDescriptionUrls.java |   47 +
 .../component/salesforce/api/dto/SObjectField.java |  414 +++++++++
 .../component/salesforce/api/dto/SObjectUrls.java  |   56 ++
 .../component/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 ++
 .../component/salesforce/api/dto/bulk/Error.java   |  105 +++
 .../component/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 ++
 .../salesforce/api/dto/bulk/QueryResultList.java   |   82 ++
 .../component/salesforce/api/dto/bulk/Result.java  |  147 ++++
 .../salesforce/api/dto/bulk/ResultError.java       |  140 +++
 .../component/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 +++++
 .../salesforce/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 +
 .../internal/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        |  222 +++++
 .../internal/streaming/SubscriptionHelper.java     |  372 ++++++++
 .../services/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    |   59 ++
 .../salesforce/RestApiIntegrationTest.java         |  408 +++++++++
 .../salesforce/StreamingApiIntegrationTest.java    |  109 +++
 .../camel/component/salesforce/dto/Document.java   |  201 +++++
 .../component/salesforce/dto/Line_Item__c.java     |   74 ++
 .../component/salesforce/dto/Merchandise__c.java   |   61 ++
 .../salesforce/dto/QueryRecordsLine_Item__c.java   |   35 +
 .../internal/SessionIntegrationTest.java           |   79 ++
 .../src/test/resources/log4j.properties            |   18 +
 .../src/test/resources/test-request.csv            |    3 +
 .../src/test/resources/test-request.xml            |   15 +
 .../camel-salesforce-maven-plugin/README.md        |   26 +
 .../camel-salesforce-maven-plugin/pom.xml          |   78 ++
 .../apache/camel/maven/CamelSalesforceMojo.java    |  570 ++++++++++++
 .../src/main/resources/sobject-picklist.vm         |   52 ++
 .../src/main/resources/sobject-pojo.vm             |   60 ++
 .../src/main/resources/sobject-query-records.vm    |   29 +
 .../maven/CamelSalesforceMojoIntegrationTest.java  |   85 ++
 .../src/test/resources/log4j.properties            |   19 +
 components/camel-salesforce/pom.xml                |   38 +
 components/pom.xml                                 |    1 +
 parent/pom.xml                                     |    6 +
 .../karaf/features/src/main/resources/features.xml |   16 +
 109 files changed, 13184 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/.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/0c401b9f/apache-camel/pom.xml
----------------------------------------------------------------------
diff --git a/apache-camel/pom.xml b/apache-camel/pom.xml
index 0aeafe4..af957dd 100644
--- a/apache-camel/pom.xml
+++ b/apache-camel/pom.xml
@@ -436,6 +436,10 @@
     </dependency>
     <dependency>
       <groupId>org.apache.camel</groupId>
+      <artifactId>camel-salesforce</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.camel</groupId>
       <artifactId>camel-sap-netweaver</artifactId>
     </dependency>
     <dependency>

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/apache-camel/src/main/descriptors/common-bin.xml
----------------------------------------------------------------------
diff --git a/apache-camel/src/main/descriptors/common-bin.xml b/apache-camel/src/main/descriptors/common-bin.xml
index 3d08587..8e28551 100644
--- a/apache-camel/src/main/descriptors/common-bin.xml
+++ b/apache-camel/src/main/descriptors/common-bin.xml
@@ -120,6 +120,7 @@
         <include>org.apache.camel:camel-rss</include>
         <include>org.apache.camel:camel-ruby</include>
         <include>org.apache.camel:camel-rx</include>
+        <include>org.apache.camel:camel-salesforce</include>
         <include>org.apache.camel:camel-sap-netweaver</include>
         <include>org.apache.camel:camel-saxon</include>
         <include>org.apache.camel:camel-scala</include>

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/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/0c401b9f/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..03db485
--- /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-parent</artifactId>
+    <version>2.12-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>camel-salesforce</artifactId>
+  <packaging>bundle</packaging>
+  <name>Camel :: Salesforce</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/0c401b9f/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/0c401b9f/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/0c401b9f/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/0c401b9f/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..817871b
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceEndpointConfig.java
@@ -0,0 +1,292 @@
+/**
+ * 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.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/0c401b9f/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/0c401b9f/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/0c401b9f/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/0c401b9f/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/0c401b9f/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/0c401b9f/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/0c401b9f/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/0c401b9f/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/0c401b9f/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/0c401b9f/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;
+    }
+}


[08/11] CAMEL-6428: camel-salesforce component. Thanks to Dhiraj Bokde for the contribution.

Posted by da...@apache.org.
http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/SalesforceSession.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/SalesforceSession.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/SalesforceSession.java
new file mode 100644
index 0000000..a16a2a3
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/SalesforceSession.java
@@ -0,0 +1,336 @@
+/**
+ * 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.internal;
+
+import org.apache.camel.Service;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.eclipse.jetty.client.ContentExchange;
+import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.client.HttpExchange;
+import org.eclipse.jetty.http.HttpMethods;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.ByteArrayBuffer;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.UrlEncoded;
+import org.apache.camel.component.salesforce.SalesforceLoginConfig;
+import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.api.dto.RestError;
+import org.apache.camel.component.salesforce.internal.dto.LoginError;
+import org.apache.camel.component.salesforce.internal.dto.LoginToken;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+public class SalesforceSession implements Service {
+
+    private static final String OAUTH2_REVOKE_PATH = "/services/oauth2/revoke?token=";
+    private static final String OAUTH2_TOKEN_PATH = "/services/oauth2/token";
+
+    private static final Logger LOG = LoggerFactory.getLogger(SalesforceSession.class);
+    private static final String FORM_CONTENT_TYPE = "application/x-www-form-urlencoded;charset=utf-8";
+
+    private final HttpClient httpClient;
+
+    private final SalesforceLoginConfig config;
+
+    private final ObjectMapper objectMapper;
+    private final Set<SalesforceSessionListener> listeners;
+
+    private String accessToken;
+    private String instanceUrl;
+
+    public SalesforceSession(HttpClient httpClient, SalesforceLoginConfig config) {
+        // validate parameters
+        assertNotNull("Null httpClient", httpClient);
+        assertNotNull("Null SalesforceLoginConfig", config);
+        assertNotNull("Null loginUrl", config.getLoginUrl());
+        assertNotNull("Null clientId", config.getClientId());
+        assertNotNull("Null clientSecret", config.getClientSecret());
+        assertNotNull("Null userName", config.getUserName());
+        assertNotNull("Null password", config.getPassword());
+
+        this.httpClient = httpClient;
+        this.config = config;
+
+        // strip trailing '/'
+        String loginUrl = config.getLoginUrl();
+        config.setLoginUrl(loginUrl.endsWith("/") ? loginUrl.substring(0, loginUrl.length() - 1) : loginUrl);
+
+        this.objectMapper = new ObjectMapper();
+        this.listeners = new CopyOnWriteArraySet<SalesforceSessionListener>();
+    }
+
+    private void assertNotNull(String s, Object o) {
+        if (o == null) {
+            throw new IllegalArgumentException(s);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public synchronized String login(String oldToken) throws SalesforceException {
+
+        // check if we need a new session
+        // this way there's always a single valid session
+        if ((accessToken == null) || accessToken.equals(oldToken)) {
+
+            // try revoking the old access token before creating a new one
+            accessToken = oldToken;
+            if (accessToken != null) {
+                try {
+                    logout();
+                } catch (SalesforceException e) {
+                    LOG.warn("Error revoking old access token: " + e.getMessage(), e);
+                }
+                accessToken = null;
+            }
+
+            // login to Salesforce and get session id
+            final StatusExceptionExchange loginPost = new StatusExceptionExchange(true);
+            loginPost.setURL(config.getLoginUrl() + OAUTH2_TOKEN_PATH);
+            loginPost.setMethod(HttpMethods.POST);
+            loginPost.setRequestContentType(FORM_CONTENT_TYPE);
+
+            final UrlEncoded nvps = new UrlEncoded();
+            nvps.put("grant_type", "password");
+            nvps.put("client_id", config.getClientId());
+            nvps.put("client_secret", config.getClientSecret());
+            nvps.put("username", config.getUserName());
+            nvps.put("password", config.getPassword());
+            nvps.put("format", "json");
+
+            try {
+
+                // set form content
+                loginPost.setRequestContent(new ByteArrayBuffer(
+                    nvps.encode(StringUtil.__UTF8, true).getBytes(StringUtil.__UTF8)));
+                httpClient.send(loginPost);
+
+                // wait for the login to finish
+                final int exchangeState = loginPost.waitForDone();
+
+                switch (exchangeState) {
+                    case HttpExchange.STATUS_COMPLETED:
+                        final byte[] responseContent = loginPost.getResponseContentBytes();
+                        final int responseStatus = loginPost.getResponseStatus();
+                        switch (responseStatus) {
+
+                            case HttpStatus.OK_200:
+                                // parse the response to get token
+                                LoginToken token = objectMapper.readValue(responseContent,
+                                    LoginToken.class);
+
+                                // don't log token or instance URL for security reasons
+                                LOG.info("Login successful");
+                                accessToken = token.getAccessToken();
+                                instanceUrl = token.getInstanceUrl();
+
+                                // notify all listeners
+                                for (SalesforceSessionListener listener : listeners) {
+                                    try {
+                                        listener.onLogin(accessToken, instanceUrl);
+                                    } catch (Throwable t) {
+                                        LOG.warn("Unexpected error from listener {}: {}", listener, t.getMessage());
+                                    }
+                                }
+
+                                break;
+
+                            case HttpStatus.BAD_REQUEST_400:
+                                // parse the response to get error
+                                final LoginError error = objectMapper.readValue(responseContent,
+                                    LoginError.class);
+                                final String msg = String.format("Login error code:[%s] description:[%s]",
+                                    error.getError(), error.getErrorDescription());
+                                final List<RestError> errors = new ArrayList<RestError>();
+                                errors.add(new RestError(msg, error.getErrorDescription()));
+                                throw new SalesforceException(errors, HttpStatus.BAD_REQUEST_400);
+
+                            default:
+                                throw new SalesforceException(
+                                    String.format("Login error status:[%s] reason:[%s]",
+                                        responseStatus, loginPost.getReason()),
+                                    responseStatus);
+                        }
+                        break;
+
+                    case HttpExchange.STATUS_EXCEPTED:
+                        final Throwable ex = loginPost.getException();
+                        throw new SalesforceException(
+                            String.format("Unexpected login exception: %s", ex.getMessage()),
+                            ex);
+
+                    case HttpExchange.STATUS_CANCELLED:
+                        throw new SalesforceException("Login request CANCELLED!", null);
+
+                    case HttpExchange.STATUS_EXPIRED:
+                        throw new SalesforceException("Login request TIMEOUT!", null);
+
+                }
+
+            } catch (IOException e) {
+                String msg = "Login error: unexpected exception " + e.getMessage();
+                throw new SalesforceException(msg, e);
+            } catch (InterruptedException e) {
+                String msg = "Login error: unexpected exception " + e.getMessage();
+                throw new SalesforceException(msg, e);
+            }
+        }
+
+        return accessToken;
+    }
+
+    public void logout() throws SalesforceException {
+        if (accessToken == null) {
+            return;
+        }
+
+        StatusExceptionExchange logoutGet = new StatusExceptionExchange(true);
+        logoutGet.setURL(config.getLoginUrl() + OAUTH2_REVOKE_PATH + accessToken);
+        logoutGet.setMethod(HttpMethods.GET);
+
+        try {
+            httpClient.send(logoutGet);
+            final int done = logoutGet.waitForDone();
+            switch (done) {
+
+                case HttpExchange.STATUS_COMPLETED:
+                    final int statusCode = logoutGet.getResponseStatus();
+                    final String reason = logoutGet.getReason();
+
+                    if (statusCode == HttpStatus.OK_200) {
+                        LOG.info("Logout successful");
+                    } else {
+                        throw new SalesforceException(
+                            String.format("Logout error, code: [%s] reason: [%s]",
+                                statusCode, reason),
+                            statusCode);
+                    }
+                    break;
+
+                case HttpExchange.STATUS_EXCEPTED:
+                    final Throwable ex = logoutGet.getException();
+                    throw new SalesforceException("Unexpected logout exception: " + ex.getMessage(), ex);
+
+                case HttpExchange.STATUS_CANCELLED:
+                    throw new SalesforceException("Logout request CANCELLED!", null);
+
+                case HttpExchange.STATUS_EXPIRED:
+                    throw new SalesforceException("Logout request TIMEOUT!", null);
+
+            }
+
+        } catch (SalesforceException e) {
+            throw e;
+        } catch (Exception e) {
+            String msg = "Logout error: " + e.getMessage();
+            throw new SalesforceException(msg, e);
+        } finally {
+            // reset session
+            accessToken = null;
+            instanceUrl = null;
+            // notify all session listeners of the new access token and instance url
+            for (SalesforceSessionListener listener : listeners) {
+                try {
+                    listener.onLogout();
+                } catch (Throwable t) {
+                    LOG.warn("Unexpected error from listener {}: {}", listener, t.getMessage());
+                }
+            }
+        }
+    }
+
+    public String getAccessToken() {
+        return accessToken;
+    }
+
+    public String getInstanceUrl() {
+        return instanceUrl;
+    }
+
+    public boolean addListener(SalesforceSessionListener listener) {
+        return listeners.add(listener);
+    }
+
+    public boolean removeListener(SalesforceSessionListener listener) {
+        return listeners.remove(listener);
+    }
+
+    @Override
+    public void start() throws Exception {
+        // auto-login at start if needed
+        login(accessToken);
+    }
+
+    @Override
+    public void stop() throws Exception {
+        // logout
+        logout();
+    }
+
+    /**
+     * Records status line, and exception from exchange.
+     *
+     * @author dbokde
+     */
+    private static class StatusExceptionExchange extends ContentExchange {
+
+        private String reason;
+        private Throwable exception;
+
+        public StatusExceptionExchange(boolean cacheFields) {
+            super(cacheFields);
+        }
+
+        @Override
+        protected synchronized void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException {
+            // remember reason
+            this.reason = reason.toString(StringUtil.__ISO_8859_1);
+            super.onResponseStatus(version, status, reason);
+        }
+
+        @Override
+        protected void onConnectionFailed(Throwable x) {
+            this.exception = x;
+            super.onConnectionFailed(x);
+        }
+
+        @Override
+        protected void onException(Throwable x) {
+            this.exception = x;
+            super.onException(x);
+        }
+
+        public String getReason() {
+            return reason;
+        }
+
+        public Throwable getException() {
+            return exception;
+        }
+
+    }
+
+    public static interface SalesforceSessionListener {
+        void onLogin(String accessToken, String instanceUrl);
+        void onLogout();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/AbstractClientBase.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/AbstractClientBase.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/AbstractClientBase.java
new file mode 100644
index 0000000..6fe7028
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/AbstractClientBase.java
@@ -0,0 +1,196 @@
+/**
+ * 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.internal.client;
+
+import org.apache.camel.Service;
+import org.eclipse.jetty.client.ContentExchange;
+import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.client.HttpEventListenerWrapper;
+import org.eclipse.jetty.client.HttpExchange;
+import org.eclipse.jetty.http.HttpSchemes;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.util.StringUtil;
+import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.internal.SalesforceSession;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public abstract class AbstractClientBase implements SalesforceSession.SalesforceSessionListener, Service {
+
+    protected final Logger LOG = LoggerFactory.getLogger(getClass());
+
+    protected static final String APPLICATION_JSON_UTF8 = "application/json;charset=utf-8";
+    protected static final String APPLICATION_XML_UTF8 = "application/xml;charset=utf-8";
+
+    protected final HttpClient httpClient;
+    protected final SalesforceSession session;
+    protected final String version;
+
+    protected String accessToken;
+    protected String instanceUrl;
+
+    public AbstractClientBase(String version,
+                              SalesforceSession session, HttpClient httpClient) throws SalesforceException {
+
+        this.version = version;
+        this.session = session;
+        this.httpClient = httpClient;
+    }
+
+    public void start() throws Exception {
+        // local cache
+        accessToken = session.getAccessToken();
+        if (accessToken == null) {
+            // lazy login here!
+            accessToken = session.login(accessToken);
+        }
+        instanceUrl = session.getInstanceUrl();
+
+        // also register this client as a session listener
+        session.addListener(this);
+    }
+
+    @Override
+    public void stop() throws Exception {
+        // deregister listener
+        session.removeListener(this);
+    }
+
+    @Override
+    public void onLogin(String accessToken, String instanceUrl) {
+        if (!accessToken.equals(this.accessToken)) {
+            this.accessToken = accessToken;
+            this.instanceUrl = instanceUrl;
+        }
+    }
+
+    @Override
+    public void onLogout() {
+        // ignore, if this client makes another request with stale token,
+        // SalesforceSecurityListener will auto login!
+    }
+
+    protected SalesforceExchange getContentExchange(String method, String url) {
+        SalesforceExchange get = new SalesforceExchange();
+        get.setMethod(method);
+        get.setURL(url);
+        get.setClient(this);
+        return get;
+    }
+
+    protected interface ClientResponseCallback {
+        void onResponse(InputStream response, SalesforceException ex);
+    }
+
+    protected void doHttpRequest(final ContentExchange request, final ClientResponseCallback callback) {
+
+        // use SalesforceSecurityListener for security login retries
+        try {
+            final boolean isHttps = HttpSchemes.HTTPS.equals(String.valueOf(request.getScheme()));
+            request.setEventListener(new SalesforceSecurityListener(
+                httpClient.getDestination(request.getAddress(), isHttps),
+                request, session, accessToken));
+        } catch (IOException e) {
+            // propagate exception
+            callback.onResponse(null, new SalesforceException(
+                String.format("Error registering security listener: %s", e.getMessage()),
+                e));
+        }
+
+        // use HttpEventListener for lifecycle events
+        request.setEventListener(new HttpEventListenerWrapper(request.getEventListener(), true) {
+
+            public String reason;
+
+            @Override
+            public void onConnectionFailed(Throwable ex) {
+                super.onConnectionFailed(ex);
+                callback.onResponse(null,
+                    new SalesforceException("Connection error: " + ex.getMessage(), ex));
+            }
+
+            @Override
+            public void onException(Throwable ex) {
+                super.onException(ex);
+                callback.onResponse(null,
+                    new SalesforceException("Unexpected exception: " + ex.getMessage(), ex));
+            }
+
+            @Override
+            public void onExpire() {
+                super.onExpire();
+                callback.onResponse(null,
+                    new SalesforceException("Request expired", null));
+            }
+
+            @Override
+            public void onResponseComplete() throws IOException {
+                super.onResponseComplete();
+
+                final int responseStatus = request.getResponseStatus();
+                if (responseStatus < HttpStatus.OK_200 || responseStatus >= HttpStatus.MULTIPLE_CHOICES_300) {
+                    final String msg = String.format("Error {%s:%s} executing {%s:%s}",
+                        responseStatus, reason, request.getMethod(), request.getRequestURI());
+                    final SalesforceException exception = new SalesforceException(msg, createRestException(request));
+                    exception.setStatusCode(responseStatus);
+                    callback.onResponse(null, exception);
+                } else {
+                    // TODO not memory efficient for large response messages,
+                    // doesn't seem to be possible in Jetty 7 to directly stream to response parsers
+                    final byte[] bytes = request.getResponseContentBytes();
+                    callback.onResponse(bytes != null ? new ByteArrayInputStream(bytes) : null, null);
+                }
+
+            }
+
+            @Override
+            public void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException {
+                super.onResponseStatus(version, status, reason);
+                // remember status reason
+                this.reason = reason.toString(StringUtil.__ISO_8859_1);
+            }
+        });
+
+        // execute the request
+        try {
+            httpClient.send(request);
+        } catch (IOException e) {
+            String msg = "Unexpected Error: " + e.getMessage();
+            // send error through callback
+            callback.onResponse(null, new SalesforceException(msg, e));
+        }
+
+    }
+
+    public void setAccessToken(String accessToken) {
+        this.accessToken = accessToken;
+    }
+
+    public void setInstanceUrl(String instanceUrl) {
+        this.instanceUrl = instanceUrl;
+    }
+
+    protected abstract void setAccessToken(HttpExchange httpExchange);
+
+    protected abstract SalesforceException createRestException(ContentExchange httpExchange);
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/BulkApiClient.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/BulkApiClient.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/BulkApiClient.java
new file mode 100644
index 0000000..b00e3fd
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/BulkApiClient.java
@@ -0,0 +1,92 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.salesforce.internal.client;
+
+import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.api.dto.bulk.*;
+
+import java.io.InputStream;
+import java.util.List;
+
+/**
+ * Client interface for Salesforce Bulk API
+ */
+public interface BulkApiClient {
+
+    public static interface JobInfoResponseCallback {
+        void onResponse(JobInfo jobInfo, SalesforceException ex);
+    }
+
+    public static interface BatchInfoResponseCallback {
+        void onResponse(BatchInfo batchInfo, SalesforceException ex);
+    }
+
+    public static interface BatchInfoListResponseCallback {
+        void onResponse(List<BatchInfo> batchInfoList, SalesforceException ex);
+    }
+
+    public static interface StreamResponseCallback {
+        void onResponse(InputStream inputStream, SalesforceException ex);
+    }
+
+    public static interface QueryResultIdsCallback {
+        void onResponse(List<String> ids, SalesforceException ex);
+    }
+
+    /**
+     * Creates a Bulk Job
+     *
+     * @param jobInfo {@link JobInfo} with required fields
+     * @param callback {@link JobInfoResponseCallback} to be invoked on response or error
+     */
+    void createJob(JobInfo jobInfo,
+                   JobInfoResponseCallback callback);
+
+    void getJob(String jobId,
+                JobInfoResponseCallback callback);
+
+    void closeJob(String jobId,
+                  JobInfoResponseCallback callback);
+
+    void abortJob(String jobId,
+                  JobInfoResponseCallback callback);
+
+    void createBatch(InputStream batchStream, String jobId, ContentType contentTypeEnum,
+                     BatchInfoResponseCallback callback);
+
+    void getBatch(String jobId, String batchId,
+                  BatchInfoResponseCallback callback);
+
+    void getAllBatches(String jobId,
+                       BatchInfoListResponseCallback callback);
+
+    void getRequest(String jobId, String batchId,
+                    StreamResponseCallback callback);
+
+    void getResults(String jobId, String batchId,
+                    StreamResponseCallback callback);
+
+    void createBatchQuery(String jobId, String soqlQuery, ContentType jobContentType,
+                          BatchInfoResponseCallback callback);
+
+    void getQueryResultIds(String jobId, String batchId,
+                           QueryResultIdsCallback callback);
+
+    void getQueryResult(String jobId, String batchId, String resultId,
+                        StreamResponseCallback callback);
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultBulkApiClient.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultBulkApiClient.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultBulkApiClient.java
new file mode 100644
index 0000000..b4899e5
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultBulkApiClient.java
@@ -0,0 +1,481 @@
+/**
+ * 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.internal.client;
+
+import org.eclipse.jetty.client.ContentExchange;
+import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.client.HttpExchange;
+import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.http.HttpMethods;
+import org.eclipse.jetty.io.ByteArrayBuffer;
+import org.eclipse.jetty.util.StringUtil;
+import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.api.dto.RestError;
+import org.apache.camel.component.salesforce.api.dto.bulk.*;
+import org.apache.camel.component.salesforce.api.dto.bulk.Error;
+import org.apache.camel.component.salesforce.internal.SalesforceSession;
+
+import javax.xml.bind.*;
+import javax.xml.transform.stream.StreamSource;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Collections;
+
+public class DefaultBulkApiClient extends AbstractClientBase implements BulkApiClient {
+
+    private static final String TOKEN_HEADER = "X-SFDC-Session";
+
+    private JAXBContext context;
+    private static final ContentType DEFAULT_ACCEPT_TYPE = ContentType.XML;
+    private ObjectFactory objectFactory;
+
+    public DefaultBulkApiClient(String version,
+                                SalesforceSession session, HttpClient httpClient) throws SalesforceException {
+        super(version, session, httpClient);
+
+        try {
+            context = JAXBContext.newInstance(JobInfo.class.getPackage().getName(), getClass().getClassLoader());
+        } catch (JAXBException e) {
+            String msg = "Error loading Bulk API DTOs: " + e.getMessage();
+            throw new IllegalArgumentException(msg, e);
+        }
+
+        this.objectFactory = new ObjectFactory();
+    }
+
+    @Override
+    public void createJob(JobInfo request, final JobInfoResponseCallback callback) {
+
+        // clear system fields if set
+        sanitizeJobRequest(request);
+
+        final ContentExchange post = getContentExchange(HttpMethods.POST, jobUrl(null));
+        try {
+            marshalRequest(objectFactory.createJobInfo(request), post, APPLICATION_XML_UTF8);
+        } catch (SalesforceException e) {
+            callback.onResponse(null, e);
+            return;
+        }
+
+        // make the call and parse the result in callback
+        doHttpRequest(post, new ClientResponseCallback() {
+            @Override
+            public void onResponse(InputStream response, SalesforceException ex) {
+                JobInfo value = null;
+                if (response != null) {
+                    try {
+                        value = unmarshalResponse(response, post, JobInfo.class);
+                    } catch (SalesforceException e) {
+                        ex = e;
+                    }
+                }
+                callback.onResponse(value, ex);
+            }
+        });
+
+    }
+
+    // reset read only fields
+    private void sanitizeJobRequest(JobInfo request) {
+        request.setApexProcessingTime(null);
+        request.setApiActiveProcessingTime(null);
+        request.setApiVersion(null);
+        request.setCreatedById(null);
+        request.setCreatedDate(null);
+        request.setId(null);
+        request.setNumberBatchesCompleted(null);
+        request.setNumberBatchesFailed(null);
+        request.setNumberBatchesInProgress(null);
+        request.setNumberBatchesQueued(null);
+        request.setNumberBatchesTotal(null);
+        request.setNumberRecordsFailed(null);
+        request.setNumberRecordsProcessed(null);
+        request.setNumberRetries(null);
+        request.setState(null);
+        request.setSystemModstamp(null);
+        request.setSystemModstamp(null);
+    }
+
+    @Override
+    public void getJob(String jobId, final JobInfoResponseCallback callback) {
+
+        final ContentExchange get = getContentExchange(HttpMethods.GET, jobUrl(jobId));
+
+        // make the call and parse the result
+        doHttpRequest(get, new ClientResponseCallback() {
+            @Override
+            public void onResponse(InputStream response, SalesforceException ex) {
+                JobInfo value = null;
+                try {
+                    value = unmarshalResponse(response, get, JobInfo.class);
+                } catch (SalesforceException e) {
+                    ex = e;
+                }
+                callback.onResponse(value, ex);
+            }
+        });
+
+    }
+
+    @Override
+    public void closeJob(String jobId, final JobInfoResponseCallback callback) {
+        final JobInfo request = new JobInfo();
+        request.setState(JobStateEnum.CLOSED);
+
+        final ContentExchange post = getContentExchange(HttpMethods.POST, jobUrl(jobId));
+        try {
+            marshalRequest(objectFactory.createJobInfo(request), post, APPLICATION_XML_UTF8);
+        } catch (SalesforceException e) {
+            callback.onResponse(null, e);
+            return;
+        }
+
+        // make the call and parse the result
+        doHttpRequest(post, new ClientResponseCallback() {
+            @Override
+            public void onResponse(InputStream response, SalesforceException ex) {
+                JobInfo value = null;
+                try {
+                    value = unmarshalResponse(response, post, JobInfo.class);
+                } catch (SalesforceException e) {
+                    ex = e;
+                }
+                callback.onResponse(value, ex);
+            }
+        });
+
+    }
+
+    @Override
+    public void abortJob(String jobId, final JobInfoResponseCallback callback) {
+        final JobInfo request = new JobInfo();
+        request.setState(JobStateEnum.ABORTED);
+
+        final ContentExchange post = getContentExchange(HttpMethods.POST, jobUrl(jobId));
+        try {
+            marshalRequest(objectFactory.createJobInfo(request), post, APPLICATION_XML_UTF8);
+        } catch (SalesforceException e) {
+            callback.onResponse(null, e);
+            return;
+        }
+
+        // make the call and parse the result
+        doHttpRequest(post, new ClientResponseCallback() {
+            @Override
+            public void onResponse(InputStream response, SalesforceException ex) {
+                JobInfo value = null;
+                try {
+                    value = unmarshalResponse(response, post, JobInfo.class);
+                } catch (SalesforceException e) {
+                    ex = e;
+                }
+                callback.onResponse(value, ex);
+            }
+        });
+
+    }
+
+    @Override
+    public void createBatch(InputStream batchStream, String jobId, ContentType contentTypeEnum,
+                            final BatchInfoResponseCallback callback) {
+
+        final ContentExchange post = getContentExchange(HttpMethods.POST, batchUrl(jobId, null));
+        post.setRequestContentSource(batchStream);
+        post.setRequestContentType(getContentType(contentTypeEnum) + ";charset=" + StringUtil.__UTF8);
+
+        // make the call and parse the result
+        doHttpRequest(post, new ClientResponseCallback() {
+            @Override
+            public void onResponse(InputStream response, SalesforceException ex) {
+                BatchInfo value = null;
+                try {
+                    value = unmarshalResponse(response, post, BatchInfo.class);
+                } catch (SalesforceException e) {
+                    ex = e;
+                }
+                callback.onResponse(value, ex);
+            }
+        });
+
+    }
+
+    @Override
+    public void getBatch(String jobId, String batchId,
+                         final BatchInfoResponseCallback callback) {
+
+        final ContentExchange get = getContentExchange(HttpMethods.GET, batchUrl(jobId, batchId));
+
+        // make the call and parse the result
+        doHttpRequest(get, new ClientResponseCallback() {
+            @Override
+            public void onResponse(InputStream response, SalesforceException ex) {
+                BatchInfo value = null;
+                try {
+                    value = unmarshalResponse(response, get, BatchInfo.class);
+                } catch (SalesforceException e) {
+                    ex = e;
+                }
+                callback.onResponse(value, ex);
+            }
+        });
+
+    }
+
+    @Override
+    public void getAllBatches(String jobId,
+                              final BatchInfoListResponseCallback callback) {
+
+        final ContentExchange get = getContentExchange(HttpMethods.GET, batchUrl(jobId, null));
+
+        // make the call and parse the result
+        doHttpRequest(get, new ClientResponseCallback() {
+            @Override
+            public void onResponse(InputStream response, SalesforceException ex) {
+                BatchInfoList value = null;
+                try {
+                    value = unmarshalResponse(response, get, BatchInfoList.class);
+                } catch (SalesforceException e) {
+                    ex = e;
+                }
+                callback.onResponse(value != null ? value.getBatchInfo() : null, ex);
+            }
+        });
+
+    }
+
+    @Override
+    public void getRequest(String jobId, String batchId,
+                           final StreamResponseCallback callback) {
+
+        final ContentExchange get = getContentExchange(HttpMethods.GET, batchUrl(jobId, batchId));
+
+        // make the call and parse the result
+        doHttpRequest(get, new ClientResponseCallback() {
+            @Override
+            public void onResponse(InputStream response, SalesforceException ex) {
+                callback.onResponse(response, ex);
+            }
+        });
+
+    }
+
+    @Override
+    public void getResults(String jobId, String batchId,
+                           final StreamResponseCallback callback) {
+        final ContentExchange get = getContentExchange(HttpMethods.GET, batchResultUrl(jobId, batchId, null));
+
+        // make the call and return the result
+        doHttpRequest(get, new ClientResponseCallback() {
+            @Override
+            public void onResponse(InputStream response, SalesforceException ex) {
+                callback.onResponse(response, ex);
+            }
+        });
+    }
+
+    @Override
+    public void createBatchQuery(String jobId, String soqlQuery, ContentType jobContentType,
+                                 final BatchInfoResponseCallback callback) {
+
+        final ContentExchange post = getContentExchange(HttpMethods.POST, batchUrl(jobId, null));
+        byte[] queryBytes = soqlQuery.getBytes(StringUtil.__UTF8_CHARSET);
+        post.setRequestContent(new ByteArrayBuffer(queryBytes));
+        post.setRequestContentType(getContentType(jobContentType) + ";charset=" + StringUtil.__UTF8);
+
+        // make the call and parse the result
+        doHttpRequest(post, new ClientResponseCallback() {
+            @Override
+            public void onResponse(InputStream response, SalesforceException ex) {
+                BatchInfo value = null;
+                try {
+                    value = unmarshalResponse(response, post, BatchInfo.class);
+                } catch (SalesforceException e) {
+                    ex = e;
+                }
+                callback.onResponse(value, ex);
+            }
+        });
+
+    }
+
+    @Override
+    public void getQueryResultIds(String jobId, String batchId,
+                                  final QueryResultIdsCallback callback) {
+        final ContentExchange get = getContentExchange(HttpMethods.GET, batchResultUrl(jobId, batchId, null));
+
+        // make the call and parse the result
+        doHttpRequest(get, new ClientResponseCallback() {
+            @Override
+            public void onResponse(InputStream response, SalesforceException ex) {
+                QueryResultList value = null;
+                try {
+                    value = unmarshalResponse(response, get, QueryResultList.class);
+                } catch (SalesforceException e) {
+                    ex = e;
+                }
+                callback.onResponse(value != null ? Collections.unmodifiableList(value.getResult()) : null,
+                    ex);
+            }
+        });
+
+    }
+
+    @Override
+    public void getQueryResult(String jobId, String batchId, String resultId,
+                               final StreamResponseCallback callback) {
+        final ContentExchange get = getContentExchange(HttpMethods.GET, batchResultUrl(jobId, batchId, resultId));
+
+        // make the call and parse the result
+        doHttpRequest(get, new ClientResponseCallback() {
+            @Override
+            public void onResponse(InputStream response, SalesforceException ex) {
+                callback.onResponse(response, ex);
+            }
+        });
+
+    }
+
+    @Override
+    protected void setAccessToken(HttpExchange httpExchange) {
+        httpExchange.setRequestHeader(TOKEN_HEADER, accessToken);
+    }
+
+    @Override
+    protected void doHttpRequest(ContentExchange request, ClientResponseCallback callback) {
+        // set access token for all requests
+        setAccessToken(request);
+
+        // set default charset
+        request.setRequestHeader(HttpHeaders.ACCEPT_CHARSET, StringUtil.__UTF8);
+
+        // TODO check if this is really needed or not, since SF response content type seems fixed
+        // check if the default accept content type must be used
+        if (!request.getRequestFields().containsKey(HttpHeaders.ACCEPT)) {
+            final String contentType = getContentType(DEFAULT_ACCEPT_TYPE);
+            request.setRequestHeader(HttpHeaders.ACCEPT, contentType);
+            // request content type and charset is set by the request entity
+        }
+
+        super.doHttpRequest(request, callback);
+    }
+
+    private static String getContentType(ContentType type) {
+        String result = null;
+
+        switch (type) {
+            case CSV:
+                result = "text/csv";
+                break;
+
+            case XML:
+                result = "application/xml";
+                break;
+
+            case ZIP_CSV:
+            case ZIP_XML:
+                result = type.toString().toLowerCase().replace('_', '/');
+                break;
+        }
+
+        return result;
+    }
+
+    @Override
+    protected SalesforceException createRestException(ContentExchange request) {
+        // this must be of type Error
+        try {
+            final Error error = unmarshalResponse(new ByteArrayInputStream(request.getResponseContentBytes()),
+                request, Error.class);
+
+            final RestError restError = new RestError();
+            restError.setErrorCode(error.getExceptionCode());
+            restError.setMessage(error.getExceptionMessage());
+
+            return new SalesforceException(Arrays.asList(restError), request.getResponseStatus());
+        } catch (SalesforceException e) {
+            String msg = "Error un-marshaling Salesforce Error: " + e.getMessage();
+            return new SalesforceException(msg, e);
+        }
+    }
+
+    private <T> T unmarshalResponse(InputStream response, ContentExchange request, Class<T> resultClass)
+        throws SalesforceException {
+        try {
+            Unmarshaller unmarshaller = context.createUnmarshaller();
+            JAXBElement<T> result = unmarshaller.unmarshal(new StreamSource(response), resultClass);
+            return result.getValue();
+        } catch (JAXBException e) {
+            throw new SalesforceException(
+                String.format("Error unmarshaling response {%s:%s} : %s",
+                    request.getMethod(), request.getRequestURI(), e.getMessage()),
+                e);
+        } catch (IllegalArgumentException e) {
+            throw new SalesforceException(
+                String.format("Error unmarshaling response for {%s:%s} : %s",
+                    request.getMethod(), request.getRequestURI(), e.getMessage()),
+                e);
+        }
+    }
+
+    private void marshalRequest(Object input, ContentExchange request, String contentType)
+        throws SalesforceException {
+        try {
+            Marshaller marshaller = context.createMarshaller();
+            ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+            marshaller.marshal(input, byteStream);
+            request.setRequestContent(new ByteArrayBuffer(byteStream.toByteArray()));
+            request.setRequestContentType(contentType);
+        } catch (JAXBException e) {
+            throw new SalesforceException(
+                String.format("Error marshaling request for {%s:%s} : %s",
+                    request.getMethod(), request.getRequestURI(), e.getMessage()),
+                e);
+        } catch (IllegalArgumentException e) {
+            throw new SalesforceException(
+                String.format("Error marshaling request for {%s:%s} : %s",
+                    request.getMethod(), request.getRequestURI(), e.getMessage()),
+                e);
+        }
+    }
+
+    private String jobUrl(String jobId) {
+        if (jobId != null) {
+            return super.instanceUrl + "/services/async/" + version + "/job/" + jobId;
+        } else {
+            return super.instanceUrl + "/services/async/" + version + "/job";
+        }
+    }
+
+    private String batchUrl(String jobId, String batchId) {
+        if (batchId != null) {
+            return jobUrl(jobId) + "/batch/" + batchId;
+        } else {
+            return jobUrl(jobId) + "/batch";
+        }
+    }
+
+    private String batchResultUrl(String jobId, String batchId, String resultId) {
+        if (resultId != null) {
+            return batchUrl(jobId, batchId) + "/result/" + resultId;
+        } else {
+            return batchUrl(jobId, batchId) + "/result";
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultRestClient.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultRestClient.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultRestClient.java
new file mode 100644
index 0000000..07f5af2
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultRestClient.java
@@ -0,0 +1,364 @@
+/**
+ * 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.internal.client;
+
+import com.thoughtworks.xstream.XStream;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.type.TypeReference;
+import org.eclipse.jetty.client.ContentExchange;
+import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.client.HttpExchange;
+import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.http.HttpMethods;
+import org.eclipse.jetty.util.StringUtil;
+import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.api.dto.RestError;
+import org.apache.camel.component.salesforce.internal.SalesforceSession;
+import org.apache.camel.component.salesforce.internal.dto.RestErrors;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.List;
+
+public class DefaultRestClient extends AbstractClientBase implements RestClient {
+
+    private static final String SERVICES_DATA = "/services/data/";
+    private static final String TOKEN_HEADER = "Authorization";
+    private static final String TOKEN_PREFIX = "Bearer ";
+
+    private ObjectMapper objectMapper;
+    private XStream xStream;
+    protected String format;
+
+    public DefaultRestClient(HttpClient httpClient,
+                             String version, String format, SalesforceSession session) throws SalesforceException {
+        super(version, session, httpClient);
+
+        this.format = format;
+
+        // initialize error parsers for JSON and XML
+        this.objectMapper = new ObjectMapper();
+        this.xStream = new XStream();
+        xStream.processAnnotations(RestErrors.class);
+    }
+
+    @Override
+    protected void doHttpRequest(ContentExchange request, ClientResponseCallback callback) {
+        // set standard headers for all requests
+        final String contentType = "json".equals(format) ? APPLICATION_JSON_UTF8 : APPLICATION_XML_UTF8;
+        request.setRequestHeader(HttpHeaders.ACCEPT, contentType);
+        request.setRequestHeader(HttpHeaders.ACCEPT_CHARSET, StringUtil.__UTF8);
+        // request content type and charset is set by the request entity
+
+        super.doHttpRequest(request, callback);
+    }
+
+    @Override
+    protected SalesforceException createRestException(ContentExchange httpExchange) {
+        // try parsing response according to format
+        try {
+            if ("json".equals(format)) {
+                List<RestError> restErrors = objectMapper.readValue(
+                    httpExchange.getResponseContent(), new TypeReference<List<RestError>>() {
+                });
+                return new SalesforceException(restErrors, httpExchange.getResponseStatus());
+            } else {
+                RestErrors errors = new RestErrors();
+                xStream.fromXML(httpExchange.getResponseContent(), errors);
+                return new SalesforceException(errors.getErrors(), httpExchange.getResponseStatus());
+            }
+        } catch (IOException e) {
+            // log and ignore
+            String msg = "Unexpected Error parsing " + format + " error response: " + e.getMessage();
+            LOG.warn(msg, e);
+        } catch (RuntimeException e) {
+            // log and ignore
+            String msg = "Unexpected Error parsing " + format + " error response: " + e.getMessage();
+            LOG.warn(msg, e);
+        }
+
+        // just report HTTP status info
+        return new SalesforceException("Unexpected error", httpExchange.getResponseStatus());
+    }
+
+    @Override
+    public void getVersions(final ResponseCallback callback) {
+        ContentExchange get = getContentExchange(HttpMethods.GET, servicesDataUrl());
+        // does not require authorization token
+
+        doHttpRequest(get, new DelegatingClientCallback(callback));
+    }
+
+    @Override
+    public void getResources(ResponseCallback callback) {
+        ContentExchange get = getContentExchange(HttpMethods.GET, versionUrl());
+        // requires authorization token
+        setAccessToken(get);
+
+        doHttpRequest(get, new DelegatingClientCallback(callback));
+    }
+
+    @Override
+    public void getGlobalObjects(ResponseCallback callback) {
+        ContentExchange get = getContentExchange(HttpMethods.GET, sobjectsUrl(""));
+        // requires authorization token
+        setAccessToken(get);
+
+        doHttpRequest(get, new DelegatingClientCallback(callback));
+    }
+
+    @Override
+    public void getBasicInfo(String sObjectName,
+                             ResponseCallback callback) {
+        ContentExchange get = getContentExchange(HttpMethods.GET, sobjectsUrl(sObjectName + "/"));
+        // requires authorization token
+        setAccessToken(get);
+
+        doHttpRequest(get, new DelegatingClientCallback(callback));
+    }
+
+    @Override
+    public void getDescription(String sObjectName,
+                               ResponseCallback callback) {
+        ContentExchange get = getContentExchange(HttpMethods.GET, sobjectsUrl(sObjectName + "/describe/"));
+        // requires authorization token
+        setAccessToken(get);
+
+        doHttpRequest(get, new DelegatingClientCallback(callback));
+    }
+
+    @Override
+    public void getSObject(String sObjectName, String id, String[] fields,
+                           ResponseCallback callback) {
+
+        // parse fields if set
+        String params = "";
+        if (fields != null && fields.length > 0) {
+            StringBuilder fieldsValue = new StringBuilder("?fields=");
+            for (int i = 0; i < fields.length; i++) {
+                fieldsValue.append(fields[i]);
+                if (i < (fields.length - 1)) {
+                    fieldsValue.append(',');
+                }
+            }
+            params = fieldsValue.toString();
+        }
+        ContentExchange get = getContentExchange(HttpMethods.GET, sobjectsUrl(sObjectName + "/" + id + params));
+        // requires authorization token
+        setAccessToken(get);
+
+        doHttpRequest(get, new DelegatingClientCallback(callback));
+    }
+
+    @Override
+    public void createSObject(String sObjectName, InputStream sObject,
+                              ResponseCallback callback) {
+        // post the sObject
+        final ContentExchange post = getContentExchange(HttpMethods.POST, sobjectsUrl(sObjectName));
+
+        // authorization
+        setAccessToken(post);
+
+        // input stream as entity content
+        post.setRequestContentSource(sObject);
+        post.setRequestContentType("json".equals(format) ? APPLICATION_JSON_UTF8 : APPLICATION_XML_UTF8);
+
+        doHttpRequest(post, new DelegatingClientCallback(callback));
+    }
+
+    @Override
+    public void updateSObject(String sObjectName, String id, InputStream sObject,
+                              ResponseCallback callback) {
+        final ContentExchange patch = getContentExchange("PATCH", sobjectsUrl(sObjectName + "/" + id));
+        // requires authorization token
+        setAccessToken(patch);
+
+        // input stream as entity content
+        patch.setRequestContentSource(sObject);
+        patch.setRequestContentType("json".equals(format) ? APPLICATION_JSON_UTF8 : APPLICATION_XML_UTF8);
+
+        doHttpRequest(patch, new DelegatingClientCallback(callback));
+    }
+
+    @Override
+    public void deleteSObject(String sObjectName, String id,
+                              ResponseCallback callback) {
+        final ContentExchange delete = getContentExchange(HttpMethods.DELETE, sobjectsUrl(sObjectName + "/" + id));
+
+        // requires authorization token
+        setAccessToken(delete);
+
+        doHttpRequest(delete, new DelegatingClientCallback(callback));
+    }
+
+    @Override
+    public void getSObjectWithId(String sObjectName, String fieldName, String fieldValue,
+                                 ResponseCallback callback) {
+        final ContentExchange get = getContentExchange(HttpMethods.GET,
+            sobjectsExternalIdUrl(sObjectName, fieldName, fieldValue));
+
+        // requires authorization token
+        setAccessToken(get);
+
+        doHttpRequest(get, new DelegatingClientCallback(callback));
+    }
+
+    @Override
+    public void upsertSObject(String sObjectName, String fieldName, String fieldValue, InputStream sObject,
+                              ResponseCallback callback) {
+        final ContentExchange patch = getContentExchange("PATCH",
+            sobjectsExternalIdUrl(sObjectName, fieldName, fieldValue));
+
+        // requires authorization token
+        setAccessToken(patch);
+
+        // input stream as entity content
+        patch.setRequestContentSource(sObject);
+        // TODO will the encoding always be UTF-8??
+        patch.setRequestContentType("json".equals(format) ? APPLICATION_JSON_UTF8 : APPLICATION_XML_UTF8);
+
+        doHttpRequest(patch, new DelegatingClientCallback(callback));
+    }
+
+    @Override
+    public void deleteSObjectWithId(String sObjectName, String fieldName, String fieldValue,
+                                    ResponseCallback callback) {
+        final ContentExchange delete = getContentExchange(HttpMethods.DELETE,
+            sobjectsExternalIdUrl(sObjectName, fieldName, fieldValue));
+
+        // requires authorization token
+        setAccessToken(delete);
+
+        doHttpRequest(delete, new DelegatingClientCallback(callback));
+    }
+
+    @Override
+    public void getBlobField(String sObjectName, String id, String blobFieldName, ResponseCallback callback) {
+        final ContentExchange get = getContentExchange(HttpMethods.GET,
+            sobjectsUrl(sObjectName + "/" + id +"/" + blobFieldName));
+        // TODO this doesn't seem to be required, the response is always the content binary stream
+        //get.setRequestHeader(HttpHeaders.ACCEPT_ENCODING, "base64");
+
+        // requires authorization token
+        setAccessToken(get);
+
+        doHttpRequest(get, new DelegatingClientCallback(callback));
+    }
+
+    @Override
+    public void query(String soqlQuery, ResponseCallback callback) {
+        try {
+
+            String encodedQuery = URLEncoder.encode(soqlQuery, StringUtil.__UTF8_CHARSET.toString());
+            // URLEncoder likes to use '+' for spaces
+            encodedQuery = encodedQuery.replace("+", "%20");
+            final ContentExchange get = getContentExchange(HttpMethods.GET, versionUrl() + "query/?q=" + encodedQuery);
+
+            // requires authorization token
+            setAccessToken(get);
+
+            doHttpRequest(get, new DelegatingClientCallback(callback));
+
+        } catch (UnsupportedEncodingException e) {
+            String msg = "Unexpected error: " + e.getMessage();
+            callback.onResponse(null, new SalesforceException(msg, e));
+        }
+    }
+
+    @Override
+    public void queryMore(String nextRecordsUrl, ResponseCallback callback) {
+        final ContentExchange get = getContentExchange(HttpMethods.GET, instanceUrl + nextRecordsUrl);
+
+        // requires authorization token
+        setAccessToken(get);
+
+        doHttpRequest(get, new DelegatingClientCallback(callback));
+    }
+
+    @Override
+    public void search(String soslQuery, ResponseCallback callback) {
+        try {
+
+            String encodedQuery = URLEncoder.encode(soslQuery, StringUtil.__UTF8_CHARSET.toString());
+            // URLEncoder likes to use '+' for spaces
+            encodedQuery = encodedQuery.replace("+", "%20");
+            final ContentExchange get = getContentExchange(HttpMethods.GET, versionUrl() + "search/?q=" + encodedQuery);
+
+            // requires authorization token
+            setAccessToken(get);
+
+            doHttpRequest(get, new DelegatingClientCallback(callback));
+
+        } catch (UnsupportedEncodingException e) {
+            String msg = "Unexpected error: " + e.getMessage();
+            callback.onResponse(null, new SalesforceException(msg, e));
+        }
+    }
+
+    private String servicesDataUrl() {
+        return instanceUrl + SERVICES_DATA;
+    }
+
+    private String versionUrl() {
+        if (version == null) {
+            throw new IllegalArgumentException("NULL API version", new NullPointerException("version"));
+        }
+        return servicesDataUrl() + "v" + version + "/";
+    }
+
+    private String sobjectsUrl(String sObjectName) {
+        if (sObjectName == null) {
+            throw new IllegalArgumentException("Null SObject name", new NullPointerException("sObjectName"));
+        }
+        return versionUrl() + "sobjects/" + sObjectName;
+    }
+
+    private String sobjectsExternalIdUrl(String sObjectName, String fieldName, String fieldValue) {
+        if (fieldName == null || fieldValue == null) {
+            throw new IllegalArgumentException("External field name and value cannot be NULL");
+        }
+        try {
+            String encodedValue = URLEncoder.encode(fieldValue, StringUtil.__UTF8_CHARSET.toString());
+            // URLEncoder likes to use '+' for spaces
+            encodedValue = encodedValue.replace("+", "%20");
+            return sobjectsUrl(sObjectName + "/" + fieldName + "/" + encodedValue);
+        } catch (UnsupportedEncodingException e) {
+            String msg = "Unexpected error: " + e.getMessage();
+            throw new IllegalArgumentException(msg, e);
+        }
+    }
+
+    protected void setAccessToken(HttpExchange httpExchange) {
+        httpExchange.setRequestHeader(TOKEN_HEADER, TOKEN_PREFIX + accessToken);
+    }
+
+    private static class DelegatingClientCallback implements ClientResponseCallback {
+        private final ResponseCallback callback;
+
+        public DelegatingClientCallback(ResponseCallback callback) {
+            this.callback = callback;
+        }
+
+        @Override
+        public void onResponse(InputStream response, SalesforceException ex) {
+            callback.onResponse(response, ex);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/RestClient.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/RestClient.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/RestClient.java
new file mode 100644
index 0000000..30186d9
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/RestClient.java
@@ -0,0 +1,177 @@
+/**
+ * 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.internal.client;
+
+import org.apache.camel.component.salesforce.api.SalesforceException;
+
+import java.io.InputStream;
+
+public interface RestClient {
+
+    public static interface ResponseCallback {
+        void onResponse(InputStream response, SalesforceException exception);
+    }
+
+    /**
+     * Lists summary information about each API version currently available,
+     * including the version, label, and a link to each version's root.
+     *
+     * @param callback {@link ResponseCallback} to handle response or exception
+    */
+    void getVersions(ResponseCallback callback);
+
+    /**
+     * Lists available resources for the specified API version, including resource name and URI.
+     *
+     * @param callback {@link ResponseCallback} to handle response or exception
+    */
+    void getResources(ResponseCallback callback);
+
+    /**
+     * Lists the available objects and their metadata for your organization's data.
+     *
+     * @param callback {@link ResponseCallback} to handle response or exception
+    */
+    void getGlobalObjects(ResponseCallback callback);
+
+    /**
+     * Describes the individual metadata for the specified object.
+     *
+     * @param sObjectName specified object name
+     * @param callback {@link ResponseCallback} to handle response or exception
+    */
+    void getBasicInfo(String sObjectName, ResponseCallback callback);
+
+    /**
+     * Completely describes the individual metadata at all levels for the specified object.
+     *
+     * @param sObjectName specified object name
+     * @param callback {@link ResponseCallback} to handle response or exception
+    */
+    void getDescription(String sObjectName, ResponseCallback callback);
+
+    /**
+     * Retrieves a record for the specified object ID.
+     *
+     * @param sObjectName specified object name
+     * @param id          object id
+     * @param callback {@link ResponseCallback} to handle response or exception
+    */
+    void getSObject(String sObjectName, String id, String[] fields, ResponseCallback callback);
+
+    /**
+     * Creates a record for the specified object.
+     *
+     * @param sObjectName specified object name
+     * @param sObject     request entity
+     * @param callback {@link ResponseCallback} to handle response or exception
+    */
+    void createSObject(String sObjectName, InputStream sObject, ResponseCallback callback);
+
+    /**
+     * Updates a record for the specified object ID.
+     *
+     * @param sObjectName specified object name
+     * @param id          object id
+     * @param sObject     request entity
+     * @param callback {@link ResponseCallback} to handle response or exception
+    */
+    void updateSObject(String sObjectName, String id, InputStream sObject, ResponseCallback callback);
+
+    /**
+     * Deletes a record for the specified object ID.
+     *
+     * @param sObjectName specified object name
+     * @param id          object id
+     * @param callback {@link ResponseCallback} to handle response or exception
+    */
+    void deleteSObject(String sObjectName, String id, ResponseCallback callback);
+
+    /**
+     * Retrieves a record for the specified external ID.
+     *
+     * @param sObjectName specified object name
+     * @param fieldName external field name
+     * @param fieldValue external field value
+     * @param callback {@link ResponseCallback} to handle response or exception
+    */
+    void getSObjectWithId(String sObjectName, String fieldName, String fieldValue, ResponseCallback callback);
+
+    /**
+     * Creates or updates a record based on the value of a specified external ID field.
+     *
+     * @param sObjectName specified object name
+     * @param fieldName external field name
+     * @param fieldValue external field value
+     * @param sObject input object to insert or update
+     * @param callback {@link ResponseCallback} to handle response or exception
+    */
+    void upsertSObject(String sObjectName,
+                              String fieldName, String fieldValue, InputStream sObject, ResponseCallback callback);
+
+    /**
+     * Deletes a record based on the value of a specified external ID field.
+     *
+     * @param sObjectName specified object name
+     * @param fieldName external field name
+     * @param fieldValue external field value
+     * @param callback {@link ResponseCallback} to handle response or exception
+    */
+    void deleteSObjectWithId(String sObjectName,
+                             String fieldName, String fieldValue, ResponseCallback callback);
+
+
+    /**
+     * Retrieves the specified blob field from an individual record.
+     *
+     */
+    void getBlobField(String sObjectName, String id, String blobFieldName, ResponseCallback callback);
+
+/*
+    TODO
+    SObject User Password
+    /vXX.X/sobjects/User/user id/password
+    /vXX.X/sobjects/SelfServiceUser/self service user id/password
+
+    These methods set, reset, or get information about a user password.
+*/
+
+    /**
+     * Executes the specified SOQL query.
+     *
+     * @param soqlQuery SOQL query
+     * @param callback {@link ResponseCallback} to handle response or exception
+    */
+    void query(String soqlQuery, ResponseCallback callback);
+
+    /**
+     * Get SOQL query results using nextRecordsUrl.
+     *
+     * @param nextRecordsUrl URL for next records to fetch, returned by query()
+     * @param callback {@link ResponseCallback} to handle response or exception
+    */
+    void queryMore(String nextRecordsUrl, ResponseCallback callback);
+
+    /**
+     * Executes the specified SOSL search.
+     *
+     * @param soslQuery SOSL query
+     * @param callback {@link ResponseCallback} to handle response or exception
+    */
+    void search(String soslQuery, ResponseCallback callback);
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/SalesforceExchange.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/SalesforceExchange.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/SalesforceExchange.java
new file mode 100644
index 0000000..b17c5e1
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/SalesforceExchange.java
@@ -0,0 +1,36 @@
+/**
+ * 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.internal.client;
+
+import org.eclipse.jetty.client.ContentExchange;
+
+/**
+ * Wraps a Salesforce Http Exchange
+ */
+public class SalesforceExchange extends ContentExchange {
+
+    private AbstractClientBase client;
+
+    public AbstractClientBase getClient() {
+        return client;
+    }
+
+    public void setClient(AbstractClientBase client) {
+        this.client = client;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/SalesforceSecurityListener.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/SalesforceSecurityListener.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/SalesforceSecurityListener.java
new file mode 100644
index 0000000..5eec212
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/SalesforceSecurityListener.java
@@ -0,0 +1,162 @@
+/**
+ * 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.internal.client;
+
+import org.eclipse.jetty.client.HttpDestination;
+import org.eclipse.jetty.client.HttpEventListenerWrapper;
+import org.eclipse.jetty.client.HttpExchange;
+import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.io.Buffer;
+import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.internal.SalesforceSession;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+
+public class SalesforceSecurityListener extends HttpEventListenerWrapper {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SalesforceSecurityListener.class);
+
+    private final HttpDestination destination;
+    private final HttpExchange exchange;
+    private final SalesforceSession session;
+
+    private String currentToken;
+    private int retries;
+    private boolean retrying;
+    private boolean requestComplete;
+    private boolean responseComplete;
+
+    public SalesforceSecurityListener(HttpDestination destination, HttpExchange exchange,
+                                      SalesforceSession session, String accessToken) {
+        super(exchange.getEventListener(), true);
+        this.destination = destination;
+        this.exchange = exchange;
+        this.session = session;
+        this.currentToken = accessToken;
+    }
+
+    @Override
+    public void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException {
+        if (status == HttpStatus.UNAUTHORIZED_401 &&
+            retries < destination.getHttpClient().maxRetries()) {
+
+            LOG.warn("Retrying on Salesforce authentication error [{}]: [{}]", status, reason);
+            setDelegatingRequests(false);
+            setDelegatingResponses(false);
+
+            retrying = true;
+        }
+        super.onResponseStatus(version, status, reason);
+    }
+
+    @Override
+    public void onRequestComplete() throws IOException {
+        requestComplete = true;
+        if (checkExchangeComplete()) {
+            super.onRequestComplete();
+        }
+    }
+
+    @Override
+    public void onResponseComplete() throws IOException {
+        responseComplete = true;
+        if (checkExchangeComplete()) {
+            super.onResponseComplete();
+        }
+    }
+
+    private boolean checkExchangeComplete() throws IOException {
+        if (retrying && requestComplete && responseComplete) {
+            LOG.debug("Authentication Error, retrying: {}", exchange);
+
+            requestComplete = false;
+            responseComplete = false;
+
+            setDelegatingRequests(true);
+            setDelegatingResponses(true);
+
+            try {
+                // get a new token and retry
+                currentToken = session.login(currentToken);
+
+                if (exchange instanceof SalesforceExchange) {
+                    final SalesforceExchange salesforceExchange = (SalesforceExchange) exchange;
+                    final AbstractClientBase client = salesforceExchange.getClient();
+
+                    // update client cache for this and future requests
+                    client.setAccessToken(currentToken);
+                    client.setInstanceUrl(session.getInstanceUrl());
+                    client.setAccessToken(exchange);
+                } else {
+                    exchange.addRequestHeader(HttpHeaders.AUTHORIZATION,
+                        "OAuth " + currentToken);
+                }
+
+                // TODO handle a change in Salesforce instanceUrl, right now we retry with the same destination
+                destination.resend(exchange);
+
+                // resending, exchange is not done
+                return false;
+
+            } catch (SalesforceException e) {
+                // logging here, since login exception is not propagated!
+                LOG.error(e.getMessage(), e);
+
+                // the HTTP status and reason is pushed up
+                setDelegationResult(false);
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    public void onRetry() {
+        // ignore retries from other interceptors
+        if (retrying) {
+            retrying = false;
+            retries++;
+
+            setDelegatingRequests(true);
+            setDelegatingResponses(true);
+
+            requestComplete = false;
+            responseComplete = false;
+        }
+        super.onRetry();
+    }
+
+    @Override
+    public void onConnectionFailed(Throwable ex) {
+        setDelegatingRequests(true);
+        setDelegatingResponses(true);
+        // delegate connection failures
+        super.onConnectionFailed(ex);
+    }
+
+    @Override
+    public void onException(Throwable ex) {
+        setDelegatingRequests(true);
+        setDelegatingResponses(true);
+        // delegate exceptions
+        super.onException(ex);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/SyncResponseCallback.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/SyncResponseCallback.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/SyncResponseCallback.java
new file mode 100644
index 0000000..0f567e6
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/SyncResponseCallback.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.internal.client;
+
+import org.apache.camel.component.salesforce.api.SalesforceException;
+
+import java.io.InputStream;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Thin wrapper to handle callbacks for {@link RestClient.ResponseCallback} and allow waiting for results
+ */
+public class SyncResponseCallback implements RestClient.ResponseCallback {
+
+    private InputStream response;
+    private SalesforceException exception;
+    private CountDownLatch latch = new CountDownLatch(1);
+
+    @Override
+    public void onResponse(InputStream response, SalesforceException exception) {
+        this.response = response;
+        this.exception = exception;
+        latch.countDown();
+    }
+
+    public void reset() {
+        latch = new CountDownLatch(1);
+    }
+
+    public boolean await(long duration, TimeUnit unit) throws InterruptedException {
+        return latch.await(duration, unit);
+    }
+
+    public InputStream getResponse() {
+        return response;
+    }
+
+    public SalesforceException getException() {
+        return exception;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/LoginError.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/LoginError.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/LoginError.java
new file mode 100644
index 0000000..cec3ef8
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/LoginError.java
@@ -0,0 +1,47 @@
+/**
+ * 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.internal.dto;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+
+/**
+ * DTO for Salesforce login error
+ */
+public class LoginError {
+
+    private String error;
+
+    private String errorDescription;
+
+    public String getError() {
+        return error;
+    }
+
+    public void setError(String error) {
+        this.error = error;
+    }
+
+    @JsonProperty("error_description")
+    public String getErrorDescription() {
+        return errorDescription;
+    }
+
+    @JsonProperty("error_description")
+    public void setErrorDescription(String errorDescription) {
+        this.errorDescription = errorDescription;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/LoginToken.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/LoginToken.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/LoginToken.java
new file mode 100644
index 0000000..c23338e
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/LoginToken.java
@@ -0,0 +1,81 @@
+/**
+ * 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.internal.dto;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+
+/**
+ * DTO for Salesforce login
+ */
+public class LoginToken {
+
+    private String accessToken;
+
+    private String instanceUrl;
+
+    private String id;
+
+    private String signature;
+
+    private String issuedAt;
+
+    @JsonProperty("access_token")
+    public String getAccessToken() {
+        return accessToken;
+    }
+
+    @JsonProperty("access_token")
+    public void setAccessToken(String accessToken) {
+        this.accessToken = accessToken;
+    }
+
+    @JsonProperty("instance_url")
+    public String getInstanceUrl() {
+        return instanceUrl;
+    }
+
+    @JsonProperty("instance_url")
+    public void setInstanceUrl(String instanceUrl) {
+        this.instanceUrl = instanceUrl;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getSignature() {
+        return signature;
+    }
+
+    public void setSignature(String signature) {
+        this.signature = signature;
+    }
+
+    @JsonProperty("issued_at")
+    public String getIssuedAt() {
+        return issuedAt;
+    }
+
+    @JsonProperty("issued_at")
+    public void setIssuedAt(String issuedAt) {
+        this.issuedAt = issuedAt;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/NotifyForFieldsEnum.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/NotifyForFieldsEnum.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/NotifyForFieldsEnum.java
new file mode 100644
index 0000000..970b9aa
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/NotifyForFieldsEnum.java
@@ -0,0 +1,53 @@
+/**
+ * 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.internal.dto;
+
+import org.codehaus.jackson.annotate.JsonCreator;
+import org.codehaus.jackson.annotate.JsonValue;
+
+/**
+ * Salesforce Enumeration DTO for picklist NotifyForFields
+ */
+public enum NotifyForFieldsEnum {
+
+    SELECT("Select"),
+    WHERE("Where"),
+    REFERENCED("Referenced"),
+    ALL("All");
+
+    final String value;
+
+    private NotifyForFieldsEnum(String value) {
+        this.value = value;
+    }
+
+    @JsonValue
+    public String value() {
+        return this.value;
+    }
+
+    @JsonCreator
+    public static NotifyForFieldsEnum fromValue(String value) {
+        for (NotifyForFieldsEnum e : NotifyForFieldsEnum.values()) {
+            if (e.value.equals(value)) {
+                return e;
+            }
+        }
+        throw new IllegalArgumentException(value);
+    }
+
+}
\ No newline at end of file


[06/11] CAMEL-6428: camel-salesforce component. Thanks to Dhiraj Bokde for the contribution.

Posted by da...@apache.org.
http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/streaming/PushTopicHelper.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/streaming/PushTopicHelper.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/streaming/PushTopicHelper.java
new file mode 100644
index 0000000..4e51281
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/streaming/PushTopicHelper.java
@@ -0,0 +1,222 @@
+/**
+ * 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.internal.streaming;
+
+import org.apache.camel.CamelException;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.eclipse.jetty.http.HttpStatus;
+import org.apache.camel.component.salesforce.SalesforceEndpointConfig;
+import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.api.dto.CreateSObjectResult;
+import org.apache.camel.component.salesforce.internal.client.RestClient;
+import org.apache.camel.component.salesforce.internal.client.SyncResponseCallback;
+import org.apache.camel.component.salesforce.internal.dto.PushTopic;
+import org.apache.camel.component.salesforce.internal.dto.QueryRecordsPushTopic;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+public class PushTopicHelper {
+    private static final Logger LOG = LoggerFactory.getLogger(PushTopicHelper.class);
+    private static final ObjectMapper objectMapper = new ObjectMapper();
+    private static final String PUSH_TOPIC_OBJECT_NAME = "PushTopic";
+    private static final long API_TIMEOUT = 60; // Rest API call timeout
+    private final SalesforceEndpointConfig config;
+    private final String topicName;
+    private final RestClient restClient;
+
+    public PushTopicHelper(SalesforceEndpointConfig config, String topicName, RestClient restClient) {
+        this.config = config;
+        this.topicName = topicName;
+        this.restClient = restClient;
+    }
+
+    public void createOrUpdateTopic() throws CamelException {
+        final String query = config.getSObjectQuery();
+
+        final SyncResponseCallback callback = new SyncResponseCallback();
+        // lookup Topic first
+        try {
+            // use SOQL to lookup Topic, since Name is not an external ID!!!
+            restClient.query("SELECT Id, Name, Query, ApiVersion, IsActive, " +
+                "NotifyForFields, NotifyForOperations, Description " +
+                "FROM PushTopic WHERE Name = '" + topicName + "'",
+                callback);
+
+            if (!callback.await(API_TIMEOUT, TimeUnit.SECONDS)) {
+                throw new SalesforceException("API call timeout!", null);
+            }
+            if (callback.getException() != null) {
+                throw callback.getException();
+            }
+            QueryRecordsPushTopic records = objectMapper.readValue(callback.getResponse(),
+                QueryRecordsPushTopic.class);
+            if (records.getTotalSize() == 1) {
+
+                PushTopic topic = records.getRecords().get(0);
+                LOG.info("Found existing topic {}: {}", topicName, topic);
+
+                // check if we need to update topic query, notifyForFields or notifyForOperations
+                if (!query.equals(topic.getQuery()) ||
+                    (config.getNotifyForFields() != null &&
+                        !config.getNotifyForFields().equals(topic.getNotifyForFields())) ||
+                    (config.getNotifyForOperations() != null &&
+                        !config.getNotifyForOperations().equals(topic.getNotifyForOperations()))
+                    ) {
+
+                    if (!config.isUpdateTopic()) {
+                        String msg = "Query doesn't match existing Topic and updateTopic is set to false";
+                        throw new CamelException(msg);
+                    }
+
+                    // otherwise update the topic
+                    updateTopic(topic.getId());
+                }
+
+            } else {
+                createTopic();
+            }
+
+        } catch (SalesforceException e) {
+            throw new CamelException(
+                String.format("Error retrieving Topic %s: %s", topicName, e.getMessage()),
+                e);
+        } catch (IOException e) {
+            throw new CamelException(
+                String.format("Un-marshaling error retrieving Topic %s: %s", topicName, e.getMessage()),
+                e);
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            throw new CamelException(
+                String.format("Un-marshaling error retrieving Topic %s: %s", topicName, e.getMessage()),
+                e);
+        } finally {
+            // close stream to close HttpConnection
+            if (callback.getResponse() != null) {
+                try {
+                    callback.getResponse().close();
+                } catch (IOException e) {
+                    // ignore
+                }
+            }
+        }
+    }
+
+    private void createTopic() throws CamelException {
+        final PushTopic topic = new PushTopic();
+        topic.setName(topicName);
+        topic.setApiVersion(Double.valueOf(config.getApiVersion()));
+        topic.setQuery(config.getSObjectQuery());
+        topic.setDescription("Topic created by Camel Salesforce component");
+        topic.setNotifyForFields(config.getNotifyForFields());
+        topic.setNotifyForOperations(config.getNotifyForOperations());
+
+        LOG.info("Creating Topic {}: {}", topicName, topic);
+        final SyncResponseCallback callback = new SyncResponseCallback();
+        try {
+            restClient.createSObject(PUSH_TOPIC_OBJECT_NAME,
+                new ByteArrayInputStream(objectMapper.writeValueAsBytes(topic)), callback);
+
+            if (!callback.await(API_TIMEOUT, TimeUnit.SECONDS)) {
+                throw new SalesforceException("API call timeout!", null);
+            }
+            if (callback.getException() != null) {
+                throw callback.getException();
+            }
+
+            CreateSObjectResult result = objectMapper.readValue(callback.getResponse(), CreateSObjectResult.class);
+            if (!result.getSuccess()) {
+                final SalesforceException salesforceException = new SalesforceException(
+                    result.getErrors(), HttpStatus.BAD_REQUEST_400);
+                throw new CamelException(
+                    String.format("Error creating Topic %s: %s", topicName, result.getErrors()),
+                    salesforceException);
+            }
+        } catch (SalesforceException e) {
+            throw new CamelException(
+                String.format("Error creating Topic %s: %s", topicName, e.getMessage()),
+                e);
+        } catch (IOException e) {
+            throw new CamelException(
+                String.format("Un-marshaling error creating Topic %s: %s", topicName, e.getMessage()),
+                e);
+        } catch (InterruptedException e) {
+            throw new CamelException(
+                String.format("Un-marshaling error creating Topic %s: %s", topicName, e.getMessage()),
+                e);
+        } finally {
+            if (callback.getResponse() != null) {
+                try {
+                    callback.getResponse().close();
+                } catch (IOException e) {
+                    // ignore
+                }
+            }
+        }
+    }
+
+    private void updateTopic(String topicId) throws CamelException {
+        final String query = config.getSObjectQuery();
+        LOG.info("Updating Topic {} with Query [{}]", topicName, query);
+
+        final SyncResponseCallback callback = new SyncResponseCallback();
+        try {
+            // update the query, notifyForFields and notifyForOperations fields
+            final PushTopic topic = new PushTopic();
+            topic.setQuery(query);
+            topic.setNotifyForFields(config.getNotifyForFields());
+            topic.setNotifyForOperations(config.getNotifyForOperations());
+
+            restClient.updateSObject("PushTopic", topicId,
+                new ByteArrayInputStream(objectMapper.writeValueAsBytes(topic)),
+                callback);
+
+            if (!callback.await(API_TIMEOUT, TimeUnit.SECONDS)) {
+                throw new SalesforceException("API call timeout!", null);
+            }
+            if (callback.getException() != null) {
+                throw callback.getException();
+            }
+
+        } catch (SalesforceException e) {
+            throw new CamelException(
+                String.format("Error updating topic %s with query [%s] : %s", topicName, query, e.getMessage()),
+                e);
+        } catch (InterruptedException e) {
+            // reset interrupt status
+            Thread.currentThread().interrupt();
+            throw new CamelException(
+                String.format("Error updating topic %s with query [%s] : %s", topicName, query, e.getMessage()),
+                e);
+        } catch (IOException e) {
+            throw new CamelException(
+                String.format("Error updating topic %s with query [%s] : %s", topicName, query, e.getMessage()),
+                e);
+        } finally {
+            if (callback.getResponse() != null) {
+                try {
+                    callback.getResponse().close();
+                } catch (IOException ignore) {
+                }
+            }
+        }
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/streaming/SubscriptionHelper.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/streaming/SubscriptionHelper.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/streaming/SubscriptionHelper.java
new file mode 100644
index 0000000..b3bd50f
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/streaming/SubscriptionHelper.java
@@ -0,0 +1,372 @@
+/**
+ * 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.internal.streaming;
+
+import org.apache.camel.CamelException;
+import org.apache.camel.Service;
+import org.cometd.bayeux.Message;
+import org.cometd.bayeux.client.ClientSessionChannel;
+import org.cometd.client.BayeuxClient;
+import org.cometd.client.transport.ClientTransport;
+import org.cometd.client.transport.LongPollingTransport;
+import org.eclipse.jetty.client.ContentExchange;
+import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.http.HttpSchemes;
+import org.apache.camel.component.salesforce.SalesforceComponent;
+import org.apache.camel.component.salesforce.SalesforceConsumer;
+import org.apache.camel.component.salesforce.internal.SalesforceSession;
+import org.apache.camel.component.salesforce.internal.client.SalesforceSecurityListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CountDownLatch;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.cometd.bayeux.Channel.*;
+import static org.cometd.bayeux.Message.ERROR_FIELD;
+import static org.cometd.bayeux.Message.SUBSCRIPTION_FIELD;
+
+public class SubscriptionHelper implements Service {
+    private static final Logger LOG = LoggerFactory.getLogger(SubscriptionHelper.class);
+
+    private static final int CONNECT_TIMEOUT = 110;
+    private static final int CHANNEL_TIMEOUT = 40;
+
+    private static final String EXCEPTION_FIELD = "exception";
+
+    private final SalesforceComponent component;
+    private final SalesforceSession session;
+    private final BayeuxClient client;
+
+    private final Map<SalesforceConsumer, ClientSessionChannel.MessageListener> listenerMap;
+
+    private boolean started;
+    private ClientSessionChannel.MessageListener handshakeListener;
+    private ClientSessionChannel.MessageListener connectListener;
+
+    private String handshakeError;
+    private Exception handshakeException;
+    private String connectError;
+    private boolean reconnecting;
+
+    public SubscriptionHelper(SalesforceComponent component) throws Exception {
+        this.component = component;
+        this.session = component.getSession();
+
+        this.listenerMap = new ConcurrentHashMap<SalesforceConsumer, ClientSessionChannel.MessageListener>();
+
+        // create CometD client
+        this.client = createClient();
+    }
+
+    @Override
+    public void start() throws Exception {
+        if (started) {
+            // no need to start again
+            return;
+        }
+
+        // listener for handshake error or exception
+        if (handshakeListener == null) {
+            // first start
+            handshakeListener = new ClientSessionChannel.MessageListener() {
+                public void onMessage(ClientSessionChannel channel, Message message) {
+                    LOG.debug("[CHANNEL:META_HANDSHAKE]: {}", message);
+
+                    if (!message.isSuccessful()) {
+                        String error = (String) message.get(ERROR_FIELD);
+                        if (error != null) {
+                            handshakeError = error;
+                        }
+                        Exception exception = (Exception) message.get(EXCEPTION_FIELD);
+                        if (exception != null) {
+                            handshakeException = exception;
+                        }
+                    } else if (!listenerMap.isEmpty()) {
+                        reconnecting = true;
+                    }
+                }
+            };
+        }
+        client.getChannel(META_HANDSHAKE).addListener(handshakeListener);
+
+        // listener for connect error
+        if (connectListener == null) {
+            connectListener = new ClientSessionChannel.MessageListener() {
+                public void onMessage(ClientSessionChannel channel, Message message) {
+                    LOG.debug("[CHANNEL:META_CONNECT]: {}", message);
+
+                    if (!message.isSuccessful()) {
+                        String error = (String) message.get(ERROR_FIELD);
+                        if (error != null) {
+                            connectError = error;
+                        }
+                    } else if (reconnecting) {
+
+                        reconnecting = false;
+
+                        LOG.debug("Refreshing subscriptions to {} channels on reconnect", listenerMap.size());
+                        // reconnected to Salesforce, subscribe to existing channels
+                        final Map<SalesforceConsumer, ClientSessionChannel.MessageListener> map =
+                            new HashMap<SalesforceConsumer, ClientSessionChannel.MessageListener>();
+                        map.putAll(listenerMap);
+                        listenerMap.clear();
+                        for (Map.Entry<SalesforceConsumer, ClientSessionChannel.MessageListener> entry :
+                            map.entrySet()) {
+                            final SalesforceConsumer consumer = entry.getKey();
+                            final String topicName = consumer.getTopicName();
+                            try {
+                                subscribe(topicName, consumer);
+                            } catch (CamelException e) {
+                                // let the consumer handle the exception
+                                consumer.handleException(
+                                    String.format("Error refreshing subscription to topic [%s]: %s",
+                                        topicName, e.getMessage()),
+                                    e);
+                            }
+                        }
+
+                    }
+                }
+            };
+        }
+        client.getChannel(META_CONNECT).addListener(connectListener);
+
+        // connect to Salesforce cometd endpoint
+        client.handshake();
+
+        final long waitMs = MILLISECONDS.convert(CONNECT_TIMEOUT, SECONDS);
+        if (!client.waitFor(waitMs, BayeuxClient.State.CONNECTED)) {
+            if (handshakeException != null) {
+                throw new CamelException(
+                    String.format("Exception during HANDSHAKE: %s", handshakeException.getMessage()),
+                    handshakeException);
+            } else if (handshakeError != null) {
+                throw new CamelException(String.format("Error during HANDSHAKE: %s", handshakeError));
+            } else if (connectError != null) {
+                throw new CamelException(String.format("Error during CONNECT: %s", connectError));
+            } else {
+                throw new CamelException(
+                    String.format("Handshake request timeout after %s seconds", CONNECT_TIMEOUT));
+            }
+        }
+
+        started = true;
+    }
+
+    @Override
+    public void stop() {
+        if (started) {
+            started = false;
+            // TODO find and log any disconnect errors
+            client.disconnect();
+            client.getChannel(META_CONNECT).removeListener(connectListener);
+            client.getChannel(META_HANDSHAKE).removeListener(handshakeListener);
+        }
+    }
+
+    private BayeuxClient createClient() throws Exception {
+        // use default Jetty client from SalesforceComponent, its shared by all consumers
+        final HttpClient httpClient = component.getConfig().getHttpClient();
+
+        Map<String, Object> options = new HashMap<String, Object>();
+        options.put(ClientTransport.TIMEOUT_OPTION, httpClient.getTimeout());
+
+        // check login access token
+        if (session.getAccessToken() == null) {
+            // lazy login here!
+            session.login(null);
+        }
+
+        LongPollingTransport transport = new LongPollingTransport(options, httpClient) {
+            @Override
+            protected void customize(ContentExchange exchange) {
+                super.customize(exchange);
+                // add SalesforceSecurityListener to handle token expiry
+                final String accessToken = session.getAccessToken();
+                try {
+                    final boolean isHttps = HttpSchemes.HTTPS.equals(String.valueOf(exchange.getScheme()));
+                    exchange.setEventListener(new SalesforceSecurityListener(
+                        httpClient.getDestination(exchange.getAddress(), isHttps),
+                        exchange, session, accessToken));
+                } catch (IOException e) {
+                    throw new RuntimeException(
+                        String.format("Error adding SalesforceSecurityListener to exchange %s", e.getMessage()),
+                        e);
+                }
+
+                // add current security token obtained from session
+                exchange.addRequestHeader(HttpHeaders.AUTHORIZATION,
+                "OAuth " + accessToken);
+            }
+        };
+
+        BayeuxClient client = new BayeuxClient(getEndpointUrl(), transport);
+
+        client.setDebugEnabled(false);
+
+        return client;
+    }
+
+    public void subscribe(final String topicName, final SalesforceConsumer consumer) throws CamelException {
+        // create subscription for consumer
+        final String channelName = getChannelName(topicName);
+
+        // channel message listener
+        LOG.info("Subscribing to channel {}...", channelName);
+        final ClientSessionChannel.MessageListener listener = new ClientSessionChannel.MessageListener() {
+
+            @Override
+            public void onMessage(ClientSessionChannel channel, Message message) {
+                LOG.debug("Received Message: {}", message);
+                // convert CometD message to Camel Message
+                consumer.processMessage(channel, message);
+            }
+
+        };
+
+        final ClientSessionChannel clientChannel = client.getChannel(channelName);
+
+        // listener for subscribe error
+        final CountDownLatch latch = new CountDownLatch(1);
+        final String[] subscribeError = {null};
+        final ClientSessionChannel.MessageListener subscriptionListener = new ClientSessionChannel.MessageListener() {
+            public void onMessage(ClientSessionChannel channel, Message message) {
+                LOG.debug("[CHANNEL:META_SUBSCRIBE]: {}", message);
+                final String subscribedChannelName = message.get(SUBSCRIPTION_FIELD).toString();
+                if (channelName.equals(subscribedChannelName)) {
+
+                    if (!message.isSuccessful()) {
+                        String error = (String) message.get(ERROR_FIELD);
+                        if (error != null) {
+                            subscribeError[0] = error;
+                        }
+                    } else {
+                        // remember subscription
+                        LOG.info("Subscribed to channel {}", subscribedChannelName);
+                    }
+                    latch.countDown();
+                }
+            }
+        };
+        client.getChannel(META_SUBSCRIBE).addListener(subscriptionListener);
+
+        try {
+            clientChannel.subscribe(listener);
+
+            // confirm that a subscription was created
+            try {
+                if (!latch.await(CHANNEL_TIMEOUT, SECONDS)) {
+                    String message;
+                    if (subscribeError[0] != null) {
+                        message = String.format("Error subscribing to topic %s: %s",
+                            topicName, subscribeError[0]);
+                    } else {
+                        message = String.format("Timeout error subscribing to topic %s after %s seconds",
+                            topicName, CHANNEL_TIMEOUT);
+                    }
+                    throw new CamelException(message);
+                }
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                // probably shutting down, so forget subscription
+            }
+
+            listenerMap.put(consumer, listener);
+
+        } finally {
+            client.getChannel(META_SUBSCRIBE).removeListener(subscriptionListener);
+        }
+    }
+
+    private String getChannelName(String topicName) {
+        return "/topic/" + topicName;
+    }
+
+    public void unsubscribe(String topicName, SalesforceConsumer consumer) throws CamelException {
+
+        // channel name
+        final String channelName = getChannelName(topicName);
+
+        // listen for unsubscribe error
+        final CountDownLatch latch = new CountDownLatch(1);
+        final String[] unsubscribeError = {null};
+        final ClientSessionChannel.MessageListener unsubscribeListener = new ClientSessionChannel.MessageListener() {
+            public void onMessage(ClientSessionChannel channel, Message message) {
+                LOG.debug("[CHANNEL:META_UNSUBSCRIBE]: {}", message);
+                String unsubscribedChannelName = message.get(SUBSCRIPTION_FIELD).toString();
+                if (channelName.equals(unsubscribedChannelName)) {
+
+                    if (!message.isSuccessful()) {
+                        String error = (String) message.get(ERROR_FIELD);
+                        if (error != null) {
+                            unsubscribeError[0] = error;
+                        }
+                    } else {
+                        // forget subscription
+                        LOG.info("Unsubscribed from channel {}", unsubscribedChannelName);
+                    }
+                    latch.countDown();
+                }
+            }
+        };
+        client.getChannel(META_UNSUBSCRIBE).addListener(unsubscribeListener);
+
+        try {
+            // unsubscribe from channel
+            final ClientSessionChannel.MessageListener listener = listenerMap.remove(consumer);
+            if (listener != null) {
+
+                LOG.info("Unsubscribing from channel {}...", channelName);
+                final ClientSessionChannel clientChannel = client.getChannel(channelName);
+                clientChannel.unsubscribe(listener);
+
+                // confirm unsubscribe
+                try {
+                    if (!latch.await(CHANNEL_TIMEOUT, SECONDS)) {
+                        String message;
+                        if (unsubscribeError[0] != null) {
+                            message = String.format("Error unsubscribing from topic %s: %s",
+                                topicName, unsubscribeError[0]);
+                        } else {
+                            message = String.format("Timeout error unsubscribing from topic %s after %s seconds",
+                                topicName, CHANNEL_TIMEOUT);
+                        }
+                        throw new CamelException(message);
+                    }
+                } catch (InterruptedException e) {
+                    Thread.currentThread().interrupt();
+                    // probably shutting down, forget unsubscribe and return
+                }
+
+            }
+        } finally {
+            client.getChannel(META_UNSUBSCRIBE).removeListener(unsubscribeListener);
+        }
+    }
+
+    public String getEndpointUrl() {
+        return component.getSession().getInstanceUrl() + "/cometd/" + component.getConfig().getApiVersion();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/main/resources/META-INF/services/org/apache/camel/component/salesforce
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/resources/META-INF/services/org/apache/camel/component/salesforce b/components/camel-salesforce/camel-salesforce-component/src/main/resources/META-INF/services/org/apache/camel/component/salesforce
new file mode 100644
index 0000000..ad8d689
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/resources/META-INF/services/org/apache/camel/component/salesforce
@@ -0,0 +1 @@
+class=org.apache.camel.component.salesforce.SalesforceComponent

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/AbstractBulkApiTestBase.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/AbstractBulkApiTestBase.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/AbstractBulkApiTestBase.java
new file mode 100644
index 0000000..c48d143
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/AbstractBulkApiTestBase.java
@@ -0,0 +1,105 @@
+/**
+ * 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.builder.RouteBuilder;
+import org.apache.camel.component.salesforce.api.dto.bulk.BatchInfo;
+import org.apache.camel.component.salesforce.api.dto.bulk.BatchStateEnum;
+import org.apache.camel.component.salesforce.api.dto.bulk.JobInfo;
+import org.junit.experimental.theories.Theories;
+import org.junit.runner.RunWith;
+
+@RunWith(Theories.class)
+public abstract class AbstractBulkApiTestBase extends AbstractSalesforceTestBase {
+
+    protected JobInfo createJob(JobInfo jobInfo) throws InterruptedException {
+        jobInfo = template().requestBody("direct:createJob", jobInfo, JobInfo.class);
+        assertNotNull("Missing JobId", jobInfo.getId());
+        return jobInfo;
+    }
+
+    @Override
+    protected RouteBuilder doCreateRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                // test createJob
+                from("direct:createJob").
+                    to("salesforce://createJob");
+
+                // test getJob
+                from("direct:getJob").
+                    to("salesforce:getJob");
+
+                // test closeJob
+                from("direct:closeJob").
+                    to("salesforce:closeJob");
+
+                // test abortJob
+                from("direct:abortJob").
+                    to("salesforce:abortJob");
+
+                // test createBatch
+                from("direct:createBatch").
+                    to("salesforce:createBatch");
+
+                // test getBatch
+                from("direct:getBatch").
+                    to("salesforce:getBatch");
+
+                // test getAllBatches
+                from("direct:getAllBatches").
+                    to("salesforce:getAllBatches");
+
+                // test getRequest
+                from("direct:getRequest").
+                    to("salesforce:getRequest");
+
+                // test getResults
+                from("direct:getResults").
+                    to("salesforce:getResults");
+
+                // test createBatchQuery
+                from("direct:createBatchQuery").
+                    to("salesforce:createBatchQuery?sObjectQuery=SELECT Name, Description__c, Price__c, Total_Inventory__c FROM Merchandise__c WHERE Name LIKE '%25Bulk API%25'");
+
+                // test getQueryResultIds
+                from("direct:getQueryResultIds").
+                    to("salesforce:getQueryResultIds");
+
+                // test getQueryResult
+                from("direct:getQueryResult").
+                    to("salesforce:getQueryResult");
+
+            }
+        };
+    }
+
+    protected boolean batchProcessed(BatchInfo batchInfo) {
+        BatchStateEnum state = batchInfo.getState();
+        return !(state == BatchStateEnum.QUEUED || state == BatchStateEnum.IN_PROGRESS);
+    }
+
+    protected BatchInfo getBatchInfo(BatchInfo batchInfo) throws InterruptedException {
+        batchInfo = template().requestBody("direct:getBatch", batchInfo, BatchInfo.class);
+
+        assertNotNull("Null batch", batchInfo);
+        assertNotNull("Null batch id", batchInfo.getId());
+
+        return batchInfo;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/AbstractSalesforceTestBase.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/AbstractSalesforceTestBase.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/AbstractSalesforceTestBase.java
new file mode 100644
index 0000000..3130a5b
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/AbstractSalesforceTestBase.java
@@ -0,0 +1,60 @@
+/**
+ * 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.builder.RouteBuilder;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.apache.camel.component.salesforce.dto.Merchandise__c;
+
+import java.io.IOException;
+
+public abstract class AbstractSalesforceTestBase extends CamelTestSupport {
+
+    @Override
+    public boolean isCreateCamelContextPerClass() {
+        // only create the context once for this class
+        return true;
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        // create the test component
+        createComponent();
+
+        return doCreateRouteBuilder();
+    }
+
+    protected abstract RouteBuilder doCreateRouteBuilder() throws Exception;
+
+    protected void createComponent() throws IllegalAccessException, IOException {
+        // create the component
+        SalesforceComponent component = new SalesforceComponent();
+        final SalesforceEndpointConfig config = new SalesforceEndpointConfig();
+        config.setApiVersion(System.getProperty("apiVersion", SalesforceEndpointConfig.DEFAULT_VERSION));
+        component.setConfig(config);
+        component.setLoginConfig(LoginConfigHelper.getLoginConfig());
+
+        // set DTO package
+        component.setPackages(new String[] {
+            Merchandise__c.class.getPackage().getName()
+        });
+
+        // add it to context
+        context().addComponent("salesforce", component);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/BulkApiBatchIntegrationTest.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/BulkApiBatchIntegrationTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/BulkApiBatchIntegrationTest.java
new file mode 100644
index 0000000..bed6a0c
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/BulkApiBatchIntegrationTest.java
@@ -0,0 +1,109 @@
+/**
+ * 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.component.salesforce.api.dto.bulk.*;
+import org.apache.camel.component.salesforce.dto.Merchandise__c;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theory;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class BulkApiBatchIntegrationTest extends AbstractBulkApiTestBase {
+    private static final String TEST_REQUEST_XML = "/test-request.xml";
+    private static final String TEST_REQUEST_CSV = "/test-request.csv";
+
+    @DataPoints
+    public static BatchTest[] getBatches() {
+        List<BatchTest> result = new ArrayList<BatchTest>();
+        BatchTest test = new BatchTest();
+        test.contentType = ContentType.XML;
+        test.stream = AbstractBulkApiTestBase.class.getResourceAsStream(TEST_REQUEST_XML);
+        result.add(test);
+
+        test = new BatchTest();
+        test.contentType = ContentType.CSV;
+        test.stream = AbstractBulkApiTestBase.class.getResourceAsStream(TEST_REQUEST_CSV);
+        result.add(test);
+
+        // TODO test ZIP_XML and ZIP_CSV
+        return result.toArray(new BatchTest[result.size()]);
+    }
+
+    @Theory
+    public void testBatchLifecycle(BatchTest request) throws Exception {
+        log.info("Testing Batch lifecycle with {} content", request.contentType);
+
+        // create an UPSERT test Job for this batch request
+        JobInfo jobInfo = new JobInfo();
+        jobInfo.setOperation(OperationEnum.UPSERT);
+        jobInfo.setContentType(request.contentType);
+        jobInfo.setObject(Merchandise__c.class.getSimpleName());
+        jobInfo.setExternalIdFieldName("Name");
+        jobInfo = createJob(jobInfo);
+
+        // test createBatch
+        Map<String, Object> headers = new HashMap<String, Object>();
+        headers.put(SalesforceEndpointConfig.JOB_ID, jobInfo.getId());
+        headers.put(SalesforceEndpointConfig.CONTENT_TYPE, jobInfo.getContentType());
+        BatchInfo batchInfo  = template().requestBodyAndHeaders("direct:createBatch",
+            request.stream, headers, BatchInfo.class);
+        assertNotNull("Null batch", batchInfo);
+        assertNotNull("Null batch id", batchInfo.getId());
+
+        // test getAllBatches
+        @SuppressWarnings("unchecked")
+        List<BatchInfo> batches = template().requestBody("direct:getAllBatches", jobInfo, List.class);
+        assertNotNull("Null batches", batches);
+        assertFalse("Empty batch list", batches.isEmpty());
+
+        // test getBatch
+        batchInfo = batches.get(0);
+        batchInfo = getBatchInfo(batchInfo);
+
+        // test getRequest
+        InputStream requestStream  = template().requestBody("direct:getRequest", batchInfo, InputStream.class);
+        assertNotNull("Null batch request", requestStream);
+
+        // wait for batch to finish
+        log.info("Waiting for batch to finish...");
+        while (!batchProcessed(batchInfo)) {
+            // sleep 5 seconds
+            Thread.sleep(5000);
+            // check again
+            batchInfo = getBatchInfo(batchInfo);
+        }
+        log.info("Batch finished with state " + batchInfo.getState());
+        assertEquals("Batch did not succeed", BatchStateEnum.COMPLETED, batchInfo.getState());
+
+        // test getResults
+        InputStream results  = template().requestBody("direct:getResults", batchInfo, InputStream.class);
+        assertNotNull("Null batch results", results);
+
+        // close the test job
+        template().requestBody("direct:closeJob", jobInfo, JobInfo.class);
+    }
+
+    private static class BatchTest {
+        public InputStream stream;
+        public ContentType contentType;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/BulkApiJobIntegrationTest.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/BulkApiJobIntegrationTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/BulkApiJobIntegrationTest.java
new file mode 100644
index 0000000..9010aa4
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/BulkApiJobIntegrationTest.java
@@ -0,0 +1,111 @@
+/**
+ * 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.component.salesforce.api.dto.bulk.ContentType;
+import org.apache.camel.component.salesforce.api.dto.bulk.JobInfo;
+import org.apache.camel.component.salesforce.api.dto.bulk.JobStateEnum;
+import org.apache.camel.component.salesforce.api.dto.bulk.OperationEnum;
+import org.apache.camel.component.salesforce.dto.Merchandise__c;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BulkApiJobIntegrationTest extends AbstractBulkApiTestBase {
+
+    // test jobs for testJobLifecycle
+    @DataPoints
+    public static JobInfo[] getJobs() {
+        JobInfo jobInfo = new JobInfo();
+
+        // insert XML
+        jobInfo.setObject(Merchandise__c.class.getSimpleName());
+        jobInfo.setContentType(ContentType.XML);
+        jobInfo.setOperation(OperationEnum.INSERT);
+
+        List<JobInfo> result = new ArrayList<JobInfo>();
+        result.add(jobInfo);
+
+        // insert CSV
+        jobInfo = new JobInfo();
+        jobInfo.setObject(Merchandise__c.class.getSimpleName());
+        jobInfo.setContentType(ContentType.CSV);
+        jobInfo.setOperation(OperationEnum.INSERT);
+        result.add(jobInfo);
+
+        // update CSV
+        jobInfo = new JobInfo();
+        jobInfo.setObject(Merchandise__c.class.getSimpleName());
+        jobInfo.setContentType(ContentType.CSV);
+        jobInfo.setOperation(OperationEnum.UPDATE);
+        result.add(jobInfo);
+
+        // upsert CSV
+        jobInfo = new JobInfo();
+        jobInfo.setObject(Merchandise__c.class.getSimpleName());
+        jobInfo.setContentType(ContentType.CSV);
+        jobInfo.setOperation(OperationEnum.UPSERT);
+        jobInfo.setExternalIdFieldName("Name");
+        result.add(jobInfo);
+
+        // delete CSV
+        jobInfo = new JobInfo();
+        jobInfo.setObject(Merchandise__c.class.getSimpleName());
+        jobInfo.setContentType(ContentType.CSV);
+        jobInfo.setOperation(OperationEnum.DELETE);
+        result.add(jobInfo);
+
+        // hard delete CSV
+        jobInfo = new JobInfo();
+        jobInfo.setObject(Merchandise__c.class.getSimpleName());
+        jobInfo.setContentType(ContentType.CSV);
+        jobInfo.setOperation(OperationEnum.HARD_DELETE);
+        result.add(jobInfo);
+
+        // query CSV
+        jobInfo = new JobInfo();
+        jobInfo.setObject(Merchandise__c.class.getSimpleName());
+        jobInfo.setContentType(ContentType.CSV);
+        jobInfo.setOperation(OperationEnum.QUERY);
+        result.add(jobInfo);
+
+        return result.toArray(new JobInfo[result.size()]);
+    }
+
+    @Theory
+    public void testJobLifecycle(JobInfo jobInfo) throws Exception {
+        log.info("Testing Job lifecycle for {} of type {}", jobInfo.getOperation(), jobInfo.getContentType());
+
+        // test create
+        jobInfo = createJob(jobInfo);
+
+        // test get
+        jobInfo = template().requestBody("direct:getJob", jobInfo, JobInfo.class);
+        assertSame("Job should be OPEN", JobStateEnum.OPEN, jobInfo.getState());
+
+        // test close
+        jobInfo = template().requestBody("direct:closeJob", jobInfo, JobInfo.class);
+        assertSame("Job should be CLOSED", JobStateEnum.CLOSED, jobInfo.getState());
+
+        // test abort
+        jobInfo = template().requestBody("direct:abortJob", jobInfo, JobInfo.class);
+        assertSame("Job should be ABORTED", JobStateEnum.ABORTED, jobInfo.getState());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/BulkApiQueryIntegrationTest.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/BulkApiQueryIntegrationTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/BulkApiQueryIntegrationTest.java
new file mode 100644
index 0000000..0f22ee1
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/BulkApiQueryIntegrationTest.java
@@ -0,0 +1,85 @@
+/**
+ * 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.component.salesforce.api.dto.bulk.*;
+import org.apache.camel.component.salesforce.dto.Merchandise__c;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theory;
+
+import java.io.InputStream;
+import java.util.List;
+
+public class BulkApiQueryIntegrationTest extends AbstractBulkApiTestBase {
+
+    @DataPoints
+    public static ContentType[] getContentTypes() {
+        return new ContentType[] {
+            ContentType.XML,
+            ContentType.CSV
+        };
+    }
+
+    @Theory
+    public void testQueryLifecycle(ContentType contentType) throws Exception {
+        log.info("Testing Query lifecycle with {} content", contentType);
+
+        // create a QUERY test Job
+        JobInfo jobInfo = new JobInfo();
+        jobInfo.setOperation(OperationEnum.QUERY);
+        jobInfo.setContentType(contentType);
+        jobInfo.setObject(Merchandise__c.class.getSimpleName());
+        jobInfo = createJob(jobInfo);
+
+        // test createQuery
+        BatchInfo batchInfo = template().requestBody("direct:createBatchQuery", jobInfo, BatchInfo.class);
+        assertNotNull("Null batch query", batchInfo);
+        assertNotNull("Null batch query id", batchInfo.getId());
+
+        // test getRequest
+        InputStream requestStream = template().requestBody("direct:getRequest", batchInfo, InputStream.class);
+        assertNotNull("Null batch request", requestStream);
+
+        // wait for batch to finish
+        log.info("Waiting for query batch to finish...");
+        while (!batchProcessed(batchInfo)) {
+            // sleep 5 seconds
+            Thread.sleep(5000);
+            // check again
+            batchInfo = getBatchInfo(batchInfo);
+        }
+        log.info("Query finished with state " + batchInfo.getState());
+        assertEquals("Query did not succeed", BatchStateEnum.COMPLETED, batchInfo.getState());
+
+        // test getQueryResultList
+        @SuppressWarnings("unchecked")
+        List<String> resultIds = template().requestBody("direct:getQueryResultIds", batchInfo, List.class);
+        assertNotNull("Null query result ids", resultIds);
+        assertFalse("Empty result ids", resultIds.isEmpty());
+
+        // test getQueryResult
+        for (String resultId : resultIds) {
+            InputStream results = template().requestBodyAndHeader("direct:getQueryResult", batchInfo,
+                SalesforceEndpointConfig.RESULT_ID, resultId, InputStream.class);
+            assertNotNull("Null query result", results);
+        }
+
+        // close the test job
+        template().requestBody("direct:closeJob", jobInfo, JobInfo.class);
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/LoginConfigHelper.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/LoginConfigHelper.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/LoginConfigHelper.java
new file mode 100644
index 0000000..1f8b480
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/LoginConfigHelper.java
@@ -0,0 +1,59 @@
+/**
+ * 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.junit.Assert;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+public class LoginConfigHelper extends Assert {
+
+    private static final String TEST_LOGIN_PROPERTIES = "test-salesforce-login.properties";
+
+    public static SalesforceLoginConfig getLoginConfig() throws IllegalAccessException, IOException {
+
+        // load test-salesforce-login properties
+        Properties properties = new Properties();
+        InputStream stream = new FileInputStream(TEST_LOGIN_PROPERTIES);
+        if (null == stream) {
+            throw new IllegalArgumentException("Create a properties file named " +
+                TEST_LOGIN_PROPERTIES + " with clientId, clientSecret, userName, and password" +
+                " for a Salesforce account with the Merchandise object from Salesforce Guides.");
+        }
+        properties.load(stream);
+
+        final SalesforceLoginConfig config = new SalesforceLoginConfig(
+            properties.getProperty("loginUrl", SalesforceLoginConfig.DEFAULT_LOGIN_URL),
+            properties.getProperty("clientId"),
+            properties.getProperty("clientSecret"),
+            properties.getProperty("userName"),
+            properties.getProperty("password"),
+            Boolean.parseBoolean(properties.getProperty("lazyLogin", "false")));
+
+        assertNotNull("Null loginUrl", config.getLoginUrl());
+        assertNotNull("Null clientId", config.getClientId());
+        assertNotNull("Null clientSecret", config.getClientSecret());
+        assertNotNull("Null userName", config.getUserName());
+        assertNotNull("Null password", config.getPassword());
+
+        return config;
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/RestApiIntegrationTest.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/RestApiIntegrationTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/RestApiIntegrationTest.java
new file mode 100644
index 0000000..a33d17d
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/RestApiIntegrationTest.java
@@ -0,0 +1,408 @@
+/**
+ * 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.builder.RouteBuilder;
+import org.apache.camel.component.salesforce.api.dto.*;
+import org.apache.camel.component.salesforce.dto.Document;
+import org.apache.camel.component.salesforce.dto.Line_Item__c;
+import org.apache.camel.component.salesforce.dto.Merchandise__c;
+import org.apache.camel.component.salesforce.dto.QueryRecordsLine_Item__c;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.nio.channels.Channels;
+import java.nio.channels.FileChannel;
+import java.nio.channels.ReadableByteChannel;
+import java.util.HashMap;
+import java.util.List;
+
+public class RestApiIntegrationTest extends AbstractSalesforceTestBase {
+
+    private static final Logger LOG = LoggerFactory.getLogger(RestApiIntegrationTest.class);
+    private static final String TEST_LINE_ITEM_ID = "1";
+    private static final String NEW_LINE_ITEM_ID = "100";
+    private static final String TEST_DOCUMENT_ID = "Test Document";
+
+    private static String testId;
+
+    @Test
+    public void testGetVersions() throws Exception {
+        doTestGetVersions("");
+        doTestGetVersions("Xml");
+    }
+
+    @SuppressWarnings("unchecked")
+    private void doTestGetVersions(String suffix) throws Exception {
+        // test getVersions doesn't need a body
+        // assert expected result
+        Object o = template().requestBody("direct:getVersions" + suffix, (Object) null);
+        List<Version> versions = null;
+        if (o instanceof Versions) {
+            versions = ((Versions) o).getVersions();
+        } else {
+            versions = (List<Version>) o;
+        }
+        assertNotNull(versions);
+        LOG.debug("Versions: {}", versions);
+    }
+
+    @Test
+    public void testGetResources() throws Exception {
+        doTestGetResources("");
+        doTestGetResources("Xml");
+    }
+
+    private void doTestGetResources(String suffix) throws Exception {
+
+
+        RestResources resources = template().requestBody("direct:getResources" + suffix, null, RestResources.class);
+        assertNotNull(resources);
+        LOG.debug("Resources: {}", resources);
+    }
+
+    @Test
+    public void testGetGlobalObjects() throws Exception {
+        doTestGetGlobalObjects("");
+        doTestGetGlobalObjects("Xml");
+    }
+
+    private void doTestGetGlobalObjects(String suffix) throws Exception {
+
+
+        GlobalObjects globalObjects = template().requestBody("direct:getGlobalObjects" + suffix, null, GlobalObjects.class);
+        assertNotNull(globalObjects);
+        LOG.debug("GlobalObjects: {}", globalObjects);
+    }
+
+    @Test
+    public void testGetBasicInfo() throws Exception {
+        doTestGetBasicInfo("");
+        doTestGetBasicInfo("Xml");
+    }
+
+    private void doTestGetBasicInfo(String suffix) throws Exception {
+        SObjectBasicInfo objectBasicInfo = template().requestBody("direct:getBasicInfo" + suffix, null, SObjectBasicInfo.class);
+        assertNotNull(objectBasicInfo);
+        LOG.debug("SObjectBasicInfo: {}", objectBasicInfo);
+
+        // set test Id for testGetSObject
+        assertFalse("RecentItems is empty", objectBasicInfo.getRecentItems().isEmpty());
+        testId = objectBasicInfo.getRecentItems().get(0).getId();
+    }
+
+    @Test
+    public void testGetDescription() throws Exception {
+        doTestGetDescription("");
+        doTestGetDescription("Xml");
+    }
+
+    private void doTestGetDescription(String suffix) throws Exception {
+
+
+        SObjectDescription sObjectDescription = template().requestBody("direct:getDescription" + suffix, null, SObjectDescription.class);
+        assertNotNull(sObjectDescription);
+        LOG.debug("SObjectDescription: {}", sObjectDescription);
+    }
+
+    @Test
+    public void testGetSObject() throws Exception {
+        doTestGetSObject("");
+        doTestGetSObject("Xml");
+    }
+
+    private void doTestGetSObject(String suffix) throws Exception {
+        if (testId == null) {
+            // execute getBasicInfo to get test id from recent items
+            doTestGetBasicInfo("");
+        }
+
+        Merchandise__c merchandise = template().requestBody("direct:getSObject" + suffix, testId, Merchandise__c.class);
+        assertNotNull(merchandise);
+        if (suffix.isEmpty()) {
+            assertNull(merchandise.getTotal_Inventory__c());
+            assertNotNull(merchandise.getPrice__c());
+        } else {
+            assertNotNull(merchandise.getTotal_Inventory__c());
+            assertNull(merchandise.getPrice__c());
+        }
+        LOG.debug("SObjectById: {}", merchandise);
+    }
+
+    @Test
+    public void testCreateUpdateDelete() throws Exception {
+        doTestCreateUpdateDelete("");
+        doTestCreateUpdateDelete("Xml");
+    }
+
+    private void doTestCreateUpdateDelete(String suffix) throws InterruptedException {
+        Merchandise__c merchandise__c = new Merchandise__c();
+        merchandise__c.setName("Wee Wee Wee Plane");
+        merchandise__c.setDescription__c("Microlite plane");
+        merchandise__c.setPrice__c(2000.0);
+        merchandise__c.setTotal_Inventory__c(50.0);
+        CreateSObjectResult result = template().requestBody("direct:CreateSObject" + suffix,
+            merchandise__c, CreateSObjectResult.class);
+        assertNotNull(result);
+        assertTrue("Create success", result.getSuccess());
+        LOG.debug("Create: " + result);
+
+        // test JSON update
+        // make the plane cheaper
+        merchandise__c.setPrice__c(1500.0);
+        // change inventory to half
+        merchandise__c.setTotal_Inventory__c(25.0);
+        // also need to set the Id
+        merchandise__c.setId(result.getId());
+
+        assertNull(template().requestBodyAndHeader("direct:UpdateSObject" + suffix,
+            merchandise__c, SalesforceEndpointConfig.SOBJECT_ID, result.getId()));
+        LOG.debug("Update successful");
+
+        // delete the newly created SObject
+        assertNull(template().requestBody("direct:deleteSObject" + suffix, result.getId()));
+        LOG.debug("Delete successful");
+    }
+
+    @Test
+    public void testCreateUpdateDeleteWithId() throws Exception {
+        doTestCreateUpdateDeleteWithId("");
+        doTestCreateUpdateDeleteWithId("Xml");
+    }
+
+    private void doTestCreateUpdateDeleteWithId(String suffix) throws InterruptedException {
+        // get line item with Name 1
+        Line_Item__c line_item__c = template().requestBody("direct:getSObjectWithId" + suffix, TEST_LINE_ITEM_ID,
+            Line_Item__c.class);
+        assertNotNull(line_item__c);
+        LOG.debug("GetWithId: {}", line_item__c);
+
+        // test insert with id
+        // set the unit price and sold
+        line_item__c.setUnit_Price__c(1000.0);
+        line_item__c.setUnits_Sold__c(50.0);
+        // update line item with Name NEW_LINE_ITEM_ID
+        line_item__c.setName(NEW_LINE_ITEM_ID);
+
+        CreateSObjectResult result = template().requestBodyAndHeader("direct:upsertSObject" + suffix,
+            line_item__c, SalesforceEndpointConfig.SOBJECT_EXT_ID_VALUE, NEW_LINE_ITEM_ID,
+            CreateSObjectResult.class);
+        assertNotNull(result);
+        assertTrue(result.getSuccess());
+        LOG.debug("CreateWithId: {}", result);
+
+        // clear read only parent type fields
+        line_item__c.setInvoice_Statement__c(null);
+        line_item__c.setMerchandise__c(null);
+        // change the units sold
+        line_item__c.setUnits_Sold__c(25.0);
+
+        // update line item with Name NEW_LINE_ITEM_ID
+        result = template().requestBodyAndHeader("direct:upsertSObject" + suffix,
+            line_item__c, SalesforceEndpointConfig.SOBJECT_EXT_ID_VALUE, NEW_LINE_ITEM_ID,
+            CreateSObjectResult.class);
+        assertNull(result);
+        LOG.debug("UpdateWithId: {}", result);
+
+        // delete the SObject with Name NEW_LINE_ITEM_ID
+        assertNull(template().requestBody("direct:deleteSObjectWithId" + suffix, NEW_LINE_ITEM_ID));
+        LOG.debug("DeleteWithId successful");
+    }
+
+    @Test
+    public void testGetBlobField() throws Exception {
+        doTestGetBlobField("");
+        doTestGetBlobField("Xml");
+    }
+
+    public void doTestGetBlobField(String suffix) throws Exception {
+        // get document with Name "Test Document"
+        final HashMap<String, Object> headers = new HashMap<String, Object>();
+        headers.put(SalesforceEndpointConfig.SOBJECT_NAME, "Document");
+        headers.put(SalesforceEndpointConfig.SOBJECT_EXT_ID_NAME, "Name");
+        Document document = template().requestBodyAndHeaders("direct:getSObjectWithId" + suffix, TEST_DOCUMENT_ID,
+            headers, Document.class);
+        assertNotNull(document);
+        LOG.debug("GetWithId: {}", document);
+
+        // get Body field for this document
+        InputStream body = template().requestBody("direct:getBlobField" + suffix, document, InputStream.class);
+        assertNotNull(body);
+        LOG.debug("GetBlobField: {}", body);
+        // write body to test file
+        final FileChannel fileChannel = new FileOutputStream("target/getBlobField" + suffix + ".txt").getChannel();
+        final ReadableByteChannel src = Channels.newChannel(body);
+        fileChannel.transferFrom(src, 0, document.getBodyLength());
+        fileChannel.close();
+        src.close();
+    }
+
+    @Test
+    public void testQuery() throws Exception {
+        doTestQuery("");
+        doTestQuery("Xml");
+    }
+
+    private void doTestQuery(String suffix) throws InterruptedException {
+        QueryRecordsLine_Item__c queryRecords = template().requestBody("direct:query" + suffix, null,
+            QueryRecordsLine_Item__c.class);
+        assertNotNull(queryRecords);
+        LOG.debug("ExecuteQuery: {}", queryRecords);
+    }
+
+
+    @Test
+    public void testSearch() throws Exception {
+        doTestSearch("");
+        doTestSearch("Xml");
+    }
+
+    @SuppressWarnings("unchecked")
+    private void doTestSearch(String suffix) throws InterruptedException {
+
+        Object obj = template().requestBody("direct:search" + suffix, (Object) null);
+        List<SearchResult> searchResults = null;
+        if (obj instanceof SearchResults) {
+            SearchResults results = (SearchResults) obj;
+            searchResults = results.getResults();
+        } else {
+            searchResults = (List<SearchResult>) obj;
+        }
+        assertNotNull(searchResults);
+        LOG.debug("ExecuteSearch: {}", searchResults);
+    }
+
+    @Override
+    protected RouteBuilder doCreateRouteBuilder() throws Exception {
+
+        // create test route
+        return new RouteBuilder() {
+            public void configure() {
+
+                // testGetVersion
+                from("direct:getVersions")
+                    .to("salesforce:getVersions");
+
+                // allow overriding format per endpoint
+                from("direct:getVersionsXml")
+                    .to("salesforce:getVersions?format=xml");
+
+                // testGetResources
+                from("direct:getResources")
+                    .to("salesforce:getResources");
+
+                from("direct:getResourcesXml")
+                    .to("salesforce:getResources?format=xml");
+
+                // testGetGlobalObjects
+                from("direct:getGlobalObjects")
+                    .to("salesforce:getGlobalObjects");
+
+                from("direct:getGlobalObjectsXml")
+                    .to("salesforce:getGlobalObjects?format=xml");
+
+                // testGetBasicInfo
+                from("direct:getBasicInfo")
+                    .to("salesforce:getBasicInfo?sObjectName=Merchandise__c");
+
+                from("direct:getBasicInfoXml")
+                    .to("salesforce:getBasicInfo?format=xml&sObjectName=Merchandise__c");
+
+                // testGetDescription
+                from("direct:getDescription")
+                    .to("salesforce:getDescription?sObjectName=Merchandise__c");
+
+                from("direct:getDescriptionXml")
+                    .to("salesforce:getDescription?format=xml&sObjectName=Merchandise__c");
+
+                // testGetSObject
+                from("direct:getSObject")
+                    .to("salesforce:getSObject?sObjectName=Merchandise__c&sObjectFields=Description__c,Price__c");
+
+                from("direct:getSObjectXml")
+                    .to("salesforce:getSObject?format=xml&sObjectName=Merchandise__c&sObjectFields=Description__c,Total_Inventory__c");
+
+                // testCreateSObject
+                from("direct:CreateSObject")
+                    .to("salesforce:createSObject?sObjectName=Merchandise__c");
+
+                from("direct:CreateSObjectXml")
+                    .to("salesforce:createSObject?format=xml&sObjectName=Merchandise__c");
+
+                // testUpdateSObject
+                from("direct:UpdateSObject")
+                    .to("salesforce:updateSObject?sObjectName=Merchandise__c");
+
+                from("direct:UpdateSObjectXml")
+                    .to("salesforce:updateSObject?format=xml&sObjectName=Merchandise__c");
+
+                // testDeleteSObject
+                from("direct:deleteSObject")
+                    .to("salesforce:deleteSObject?sObjectName=Merchandise__c");
+
+                from("direct:deleteSObjectXml")
+                    .to("salesforce:deleteSObject?format=xml&sObjectName=Merchandise__c");
+
+                // testGetSObjectWithId
+                from("direct:getSObjectWithId")
+                    .to("salesforce:getSObjectWithId?sObjectName=Line_Item__c&sObjectIdName=Name");
+
+                from("direct:getSObjectWithIdXml")
+                    .to("salesforce:getSObjectWithId?format=xml&sObjectName=Line_Item__c&sObjectIdName=Name");
+
+                // testUpsertSObject
+                from("direct:upsertSObject")
+                    .to("salesforce:upsertSObject?sObjectName=Line_Item__c&sObjectIdName=Name");
+
+                from("direct:upsertSObjectXml")
+                    .to("salesforce:upsertSObject?format=xml&sObjectName=Line_Item__c&sObjectIdName=Name");
+
+                // testDeleteSObjectWithId
+                from("direct:deleteSObjectWithId")
+                    .to("salesforce:deleteSObjectWithId?sObjectName=Line_Item__c&sObjectIdName=Name");
+
+                from("direct:deleteSObjectWithIdXml")
+                    .to("salesforce:deleteSObjectWithId?format=xml&sObjectName=Line_Item__c&sObjectIdName=Name");
+
+                // testGetBlobField
+                from("direct:getBlobField")
+                    .to("salesforce:getBlobField?sObjectName=Document&sObjectBlobFieldName=Body");
+
+                from("direct:getBlobFieldXml")
+                    .to("salesforce:getBlobField?format=xml&sObjectName=Document&sObjectBlobFieldName=Body");
+
+                // testQuery
+                from("direct:query")
+                    .to("salesforce:query?sObjectQuery=SELECT name from Line_Item__c&sObjectClass=org.apache.camel.component.salesforce.dto.QueryRecordsLine_Item__c");
+
+                from("direct:queryXml")
+                    .to("salesforce:query?format=xml&sObjectQuery=SELECT name from Line_Item__c&sObjectClass=org.apache.camel.component.salesforce.dto.QueryRecordsLine_Item__c");
+
+                // testSearch
+                from("direct:search")
+                    .to("salesforce:search?sObjectSearch=FIND {Wee}");
+
+                from("direct:searchXml")
+                    .to("salesforce:search?format=xml&sObjectSearch=FIND {Wee}");
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/StreamingApiIntegrationTest.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/StreamingApiIntegrationTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/StreamingApiIntegrationTest.java
new file mode 100644
index 0000000..d72ca2b
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/StreamingApiIntegrationTest.java
@@ -0,0 +1,109 @@
+/**
+ * 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.Message;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.component.salesforce.api.dto.CreateSObjectResult;
+import org.apache.camel.component.salesforce.dto.Merchandise__c;
+import org.apache.camel.component.salesforce.internal.dto.QueryRecordsPushTopic;
+import org.joda.time.DateTime;
+import org.junit.Test;
+
+public class StreamingApiIntegrationTest extends AbstractSalesforceTestBase {
+
+    @Test
+    public void testSubscribeAndReceive() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:CamelTestTopic");
+        mock.expectedMessageCount(1);
+        // assert expected static headers
+        mock.expectedHeaderReceived("CamelSalesforceTopicName", "CamelTestTopic");
+        mock.expectedHeaderReceived("CamelSalesforceChannel", "/topic/CamelTestTopic");
+
+        Merchandise__c merchandise = new Merchandise__c();
+        merchandise.setName("TestNotification");
+        merchandise.setDescription__c("Merchandise for testing Streaming API updated on " +
+            new DateTime().toString());
+        merchandise.setPrice__c(9.99);
+        merchandise.setTotal_Inventory__c(1000.0);
+        CreateSObjectResult result = template().requestBody(
+            "direct:upsertSObject", merchandise, CreateSObjectResult.class);
+        assertTrue("Merchandise test record not created",  result == null || result.getSuccess());
+
+        try {
+            // wait for Salesforce notification
+            mock.assertIsSatisfied();
+            final Message in = mock.getExchanges().get(0).getIn();
+            merchandise = in.getMandatoryBody(Merchandise__c.class);
+            assertNotNull("Missing event body", merchandise);
+            log.info("Merchandise notification: {}", merchandise.toString());
+            assertNotNull("Missing field Id", merchandise.getId());
+            assertNotNull("Missing field Name", merchandise.getName());
+
+            // validate dynamic message headers
+            assertNotNull("Missing header CamelSalesforceClientId", in.getHeader("CamelSalesforceClientId"));
+
+        } finally {
+            // remove the test record
+            assertNull(template().requestBody("direct:deleteSObjectWithId", merchandise));
+
+            // remove the test topic
+            // find it using SOQL first
+            QueryRecordsPushTopic records = template().requestBody("direct:query", null,
+                QueryRecordsPushTopic.class);
+            assertEquals("Test topic not found", 1, records.getTotalSize());
+            assertNull(template().requestBody("direct:deleteSObject",
+                records.getRecords().get(0)));
+
+        }
+    }
+
+    @Override
+    protected RouteBuilder doCreateRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+
+                // test topic subscription
+                from("salesforce:CamelTestTopic?notifyForFields=ALL&notifyForOperations=ALL&" +
+//                    "sObjectClass=org.apache.camel.component.salesforce.dto.Merchandise__c&" +
+                    "sObjectName=Merchandise__c&" +
+                    "updateTopic=true&sObjectQuery=SELECT Id, Name FROM Merchandise__c").
+                    to("mock:CamelTestTopic");
+
+                // route for creating test record
+                from("direct:upsertSObject").
+                    to("salesforce:upsertSObject?SObjectIdName=Name");
+
+                // route for finding test topic
+                from("direct:query").
+                    to("salesforce:query?sObjectQuery=SELECT Id FROM PushTopic WHERE Name = 'CamelTestTopic'&" +
+                        "sObjectClass=org.apache.camel.component.salesforce.internal.dto.QueryRecordsPushTopic");
+
+                // route for removing test record
+                from("direct:deleteSObjectWithId").
+                    to("salesforce:deleteSObjectWithId?sObjectIdName=Name");
+
+                // route for removing topic
+                from("direct:deleteSObject").
+                    to("salesforce:deleteSObject");
+
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/Document.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/Document.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/Document.java
new file mode 100644
index 0000000..090f2b1
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/Document.java
@@ -0,0 +1,201 @@
+/*
+ * Salesforce DTO generated by camel-salesforce-maven-plugin
+ * Generated on: Tue May 14 21:15:54 PDT 2013
+ */
+package org.apache.camel.component.salesforce.dto;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.apache.camel.component.salesforce.api.dto.AbstractSObjectBase;
+
+/**
+ * Salesforce DTO for SObject Document
+ */
+@XStreamAlias("Document")
+public class Document extends AbstractSObjectBase {
+
+    // FolderId
+    private String FolderId;
+
+    @JsonProperty("FolderId")
+    public String getFolderId() {
+        return this.FolderId;
+    }
+
+    @JsonProperty("FolderId")
+    public void setFolderId(String FolderId) {
+        this.FolderId = FolderId;
+    }
+
+    // DeveloperName
+    private String DeveloperName;
+
+    @JsonProperty("DeveloperName")
+    public String getDeveloperName() {
+        return this.DeveloperName;
+    }
+
+    @JsonProperty("DeveloperName")
+    public void setDeveloperName(String DeveloperName) {
+        this.DeveloperName = DeveloperName;
+    }
+
+    // NamespacePrefix
+    private String NamespacePrefix;
+
+    @JsonProperty("NamespacePrefix")
+    public String getNamespacePrefix() {
+        return this.NamespacePrefix;
+    }
+
+    @JsonProperty("NamespacePrefix")
+    public void setNamespacePrefix(String NamespacePrefix) {
+        this.NamespacePrefix = NamespacePrefix;
+    }
+
+    // ContentType
+    private String ContentType;
+
+    @JsonProperty("ContentType")
+    public String getContentType() {
+        return this.ContentType;
+    }
+
+    @JsonProperty("ContentType")
+    public void setContentType(String ContentType) {
+        this.ContentType = ContentType;
+    }
+
+    // Type
+    private String Type;
+
+    @JsonProperty("Type")
+    public String getType() {
+        return this.Type;
+    }
+
+    @JsonProperty("Type")
+    public void setType(String Type) {
+        this.Type = Type;
+    }
+
+    // IsPublic
+    private Boolean IsPublic;
+
+    @JsonProperty("IsPublic")
+    public Boolean getIsPublic() {
+        return this.IsPublic;
+    }
+
+    @JsonProperty("IsPublic")
+    public void setIsPublic(Boolean IsPublic) {
+        this.IsPublic = IsPublic;
+    }
+
+    // BodyLength
+    private Integer BodyLength;
+
+    @JsonProperty("BodyLength")
+    public Integer getBodyLength() {
+        return this.BodyLength;
+    }
+
+    @JsonProperty("BodyLength")
+    public void setBodyLength(Integer BodyLength) {
+        this.BodyLength = BodyLength;
+    }
+
+    // Body
+    // blob field url, use getBlobField to get the content
+    @XStreamAlias("Body")
+    private String BodyUrl;
+
+    @JsonProperty("Body")
+    public String getBodyUrl() {
+        return this.BodyUrl;
+    }
+
+    @JsonProperty("Body")
+    public void setBodyUrl(String BodyUrl) {
+        this.BodyUrl = BodyUrl;
+    }
+
+    // Url
+    private String Url;
+
+    @JsonProperty("Url")
+    public String getUrl() {
+        return this.Url;
+    }
+
+    @JsonProperty("Url")
+    public void setUrl(String Url) {
+        this.Url = Url;
+    }
+
+    // Description
+    private String Description;
+
+    @JsonProperty("Description")
+    public String getDescription() {
+        return this.Description;
+    }
+
+    @JsonProperty("Description")
+    public void setDescription(String Description) {
+        this.Description = Description;
+    }
+
+    // Keywords
+    private String Keywords;
+
+    @JsonProperty("Keywords")
+    public String getKeywords() {
+        return this.Keywords;
+    }
+
+    @JsonProperty("Keywords")
+    public void setKeywords(String Keywords) {
+        this.Keywords = Keywords;
+    }
+
+    // IsInternalUseOnly
+    private Boolean IsInternalUseOnly;
+
+    @JsonProperty("IsInternalUseOnly")
+    public Boolean getIsInternalUseOnly() {
+        return this.IsInternalUseOnly;
+    }
+
+    @JsonProperty("IsInternalUseOnly")
+    public void setIsInternalUseOnly(Boolean IsInternalUseOnly) {
+        this.IsInternalUseOnly = IsInternalUseOnly;
+    }
+
+    // AuthorId
+    private String AuthorId;
+
+    @JsonProperty("AuthorId")
+    public String getAuthorId() {
+        return this.AuthorId;
+    }
+
+    @JsonProperty("AuthorId")
+    public void setAuthorId(String AuthorId) {
+        this.AuthorId = AuthorId;
+    }
+
+    // IsBodySearchable
+    private Boolean IsBodySearchable;
+
+    @JsonProperty("IsBodySearchable")
+    public Boolean getIsBodySearchable() {
+        return this.IsBodySearchable;
+    }
+
+    @JsonProperty("IsBodySearchable")
+    public void setIsBodySearchable(Boolean IsBodySearchable) {
+        this.IsBodySearchable = IsBodySearchable;
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/0c401b9f/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/Line_Item__c.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/Line_Item__c.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/Line_Item__c.java
new file mode 100644
index 0000000..1bf3668
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/Line_Item__c.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.dto;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.apache.camel.component.salesforce.api.dto.AbstractSObjectBase;
+
+@XStreamAlias("Line_Item__c")
+public class Line_Item__c extends AbstractSObjectBase {
+
+    private Double Unit_Price__c;
+
+    private Double Units_Sold__c;
+
+    private String Merchandise__c;
+
+    private String Invoice_Statement__c;
+
+    @JsonProperty("Unit_Price__c")
+    public Double getUnit_Price__c() {
+        return Unit_Price__c;
+    }
+
+    @JsonProperty("Unit_Price__c")
+    public void setUnit_Price__c(Double unit_Price__c) {
+        Unit_Price__c = unit_Price__c;
+    }
+
+    @JsonProperty("Units_Sold__c")
+    public Double getUnits_Sold__c() {
+        return Units_Sold__c;
+    }
+
+    @JsonProperty("Units_Sold__c")
+    public void setUnits_Sold__c(Double units_Sold__c) {
+        Units_Sold__c = units_Sold__c;
+    }
+
+    @JsonProperty("Merchandise__c")
+    public String getMerchandise__c() {
+        return Merchandise__c;
+    }
+
+    @JsonProperty("Merchandise__c")
+    public void setMerchandise__c(String merchandise__c) {
+        Merchandise__c = merchandise__c;
+    }
+
+    @JsonProperty("Invoice_Statement__c")
+    public String getInvoice_Statement__c() {
+        return Invoice_Statement__c;
+    }
+
+    @JsonProperty("Invoice_Statement__c")
+    public void setInvoice_Statement__c(String invoice_Statement__c) {
+        Invoice_Statement__c = invoice_Statement__c;
+    }
+
+}