You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by dh...@apache.org on 2015/03/20 22:30:32 UTC

[01/17] camel git commit: CAMEL-7398: camel-salesforce - Fixed missing token_type field in Salesforce login call

Repository: camel
Updated Branches:
  refs/heads/camel-2.12.x 10dd6c0a8 -> 32812e518


CAMEL-7398: camel-salesforce - Fixed missing token_type field in Salesforce login call


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

Branch: refs/heads/camel-2.12.x
Commit: 215a8af56e4c6b608201d879dd176c1a6f6d5407
Parents: 10dd6c0
Author: Dhiraj Bokde <db...@redhat.com>
Authored: Mon Apr 28 15:18:18 2014 -0700
Committer: Dhiraj Bokde <dh...@yahoo.com>
Committed: Fri Mar 20 14:24:40 2015 -0700

----------------------------------------------------------------------
 .../component/salesforce/internal/dto/LoginToken.java  | 13 +++++++++++++
 1 file changed, 13 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/215a8af5/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
index c23338e..136eda3 100644
--- 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
@@ -33,6 +33,8 @@ public class LoginToken {
 
     private String issuedAt;
 
+    private String tokenType;
+
     @JsonProperty("access_token")
     public String getAccessToken() {
         return accessToken;
@@ -78,4 +80,15 @@ public class LoginToken {
     public void setIssuedAt(String issuedAt) {
         this.issuedAt = issuedAt;
     }
+
+    @JsonProperty("token_type")
+    public String getTokenType() {
+        return tokenType;
+    }
+
+    @JsonProperty("token_type")
+    public void setTokenType(String tokenType) {
+        this.tokenType = tokenType;
+    }
+
 }


[06/17] camel git commit: CAMEL-8152: Added enum value EXTENDED

Posted by dh...@apache.org.
CAMEL-8152: Added enum value EXTENDED


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

Branch: refs/heads/camel-2.12.x
Commit: cbbc8f07e21b7eaffe936f9b3a8ae8882c8f7972
Parents: 36a1747
Author: Dhiraj Bokde <dh...@yahoo.com>
Authored: Sat Dec 13 10:18:31 2014 -0800
Committer: Dhiraj Bokde <dh...@yahoo.com>
Committed: Fri Mar 20 14:24:43 2015 -0700

----------------------------------------------------------------------
 .../salesforce/internal/dto/NotifyForOperationsEnum.java          | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/cbbc8f07/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
index 807fef5..f75839c 100644
--- 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
@@ -26,7 +26,8 @@ public enum NotifyForOperationsEnum {
 
     CREATE("Create"),
     UPDATE("Update"),
-    ALL("All");
+    ALL("All"),
+    EXTENDED("Extended");
 
     final String value;
 


[02/17] camel git commit: CAMEL-7399: camel-salesforce - Fixed alias caching for updated XStream

Posted by dh...@apache.org.
CAMEL-7399: camel-salesforce - Fixed alias caching for updated XStream


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

Branch: refs/heads/camel-2.12.x
Commit: 66652611c161ff2349c2198f6c7d12b1803e5a8f
Parents: 215a8af
Author: Dhiraj Bokde <db...@redhat.com>
Authored: Mon Apr 28 15:19:38 2014 -0700
Committer: Dhiraj Bokde <dh...@yahoo.com>
Committed: Fri Mar 20 14:24:41 2015 -0700

----------------------------------------------------------------------
 .../component/salesforce/internal/processor/XmlRestProcessor.java  | 2 ++
 1 file changed, 2 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/66652611/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 80bb488..a10de93 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
@@ -205,6 +205,8 @@ public class XmlRestProcessor extends AbstractRestProcessor {
                                 mapper.flushCache();
                             }
                         } catch (CannotResolveClassException ignore) {
+                            // recent XStream versions add a ClassNotFoundException to cache
+                            mapper.flushCache();
                         }
                         localXStream.alias(responseAlias, responseClass);
                     }


[03/17] camel git commit: Fixed the Rat check errors

Posted by dh...@apache.org.
Fixed the Rat check errors


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

Branch: refs/heads/camel-2.12.x
Commit: 583ee40b020cbba14b9ec864c87df4ee458bcf84
Parents: 6665261
Author: Ubuntu <wi...@gmail.com>
Authored: Wed May 7 03:26:04 2014 +0000
Committer: Dhiraj Bokde <dh...@yahoo.com>
Committed: Fri Mar 20 14:24:41 2015 -0700

----------------------------------------------------------------------
 .../src/it/simple-it/pom.xml                      | 16 ++++++++++++++++
 .../src/it/simple-it/verify.groovy                | 16 ++++++++++++++++
 .../src/main/resources/sobject-picklist.vm        | 18 +++++++++++++++++-
 .../src/main/resources/sobject-pojo.vm            | 18 +++++++++++++++++-
 .../src/main/resources/sobject-query-records.vm   | 16 ++++++++++++++++
 .../src/main/resources/create-derby.sql           | 18 +++++++++++++++++-
 .../archetype-resources/src/main/resources/ok.xml | 18 +++++++++++++++++-
 .../META-INF/m2e/lifecycle-mapping-metadata.xml   | 16 ++++++++++++++++
 8 files changed, 132 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/583ee40b/components/camel-salesforce/camel-salesforce-maven-plugin/src/it/simple-it/pom.xml
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/it/simple-it/pom.xml b/components/camel-salesforce/camel-salesforce-maven-plugin/src/it/simple-it/pom.xml
index 08142dd..0f24037 100644
--- a/components/camel-salesforce/camel-salesforce-maven-plugin/src/it/simple-it/pom.xml
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/it/simple-it/pom.xml
@@ -1,4 +1,20 @@
 <?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/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>

http://git-wip-us.apache.org/repos/asf/camel/blob/583ee40b/components/camel-salesforce/camel-salesforce-maven-plugin/src/it/simple-it/verify.groovy
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-maven-plugin/src/it/simple-it/verify.groovy b/components/camel-salesforce/camel-salesforce-maven-plugin/src/it/simple-it/verify.groovy
index 7153082..1436d6b 100644
--- a/components/camel-salesforce/camel-salesforce-maven-plugin/src/it/simple-it/verify.groovy
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/src/it/simple-it/verify.groovy
@@ -1,3 +1,19 @@
+/**
+ * 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.
+ */
 // assert that the generated files directory exists
 File sourceDir = new File( basedir, "target/generated-sources/camel-salesforce" );
 

http://git-wip-us.apache.org/repos/asf/camel/blob/583ee40b/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
index 0aed2a7..8e23fdb 100644
--- 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
@@ -1,3 +1,19 @@
+## ------------------------------------------------------------------------
+## 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.
+## ------------------------------------------------------------------------
 ## sobject-picklist.vm
 /*
  * Salesforce DTO generated by camel-salesforce-maven-plugin
@@ -49,4 +65,4 @@ public enum $enumName {
         throw new IllegalArgumentException(value);
     }
 
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/583ee40b/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
index b240d46..bbce083 100644
--- 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
@@ -1,3 +1,19 @@
+## ------------------------------------------------------------------------
+## 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.
+## ------------------------------------------------------------------------
 ## sobject-pojo.vm
 /*
  * Salesforce DTO generated by camel-salesforce-maven-plugin
@@ -57,4 +73,4 @@ public class $desc.Name extends AbstractSObjectBase {
 
 #end
 #end
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/583ee40b/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
index 40f1ac1..d17468a 100644
--- 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
@@ -1,3 +1,19 @@
+## ------------------------------------------------------------------------
+## 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.
+## ------------------------------------------------------------------------
 ## sobject-query-records.vm
 /*
  * Salesforce Query DTO generated by camel-salesforce-maven-plugin

http://git-wip-us.apache.org/repos/asf/camel/blob/583ee40b/examples/camel-example-jdbc/src/main/resources/create-derby.sql
----------------------------------------------------------------------
diff --git a/examples/camel-example-jdbc/src/main/resources/create-derby.sql b/examples/camel-example-jdbc/src/main/resources/create-derby.sql
index 2f75cb1..671d9e6 100644
--- a/examples/camel-example-jdbc/src/main/resources/create-derby.sql
+++ b/examples/camel-example-jdbc/src/main/resources/create-derby.sql
@@ -1,4 +1,20 @@
 /*
+  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.
+*/
+/*
 STATUS : 'NEW', 'DONE'
 */
 CREATE TABLE CAMEL_TEST ( 
@@ -6,4 +22,4 @@ CREATE TABLE CAMEL_TEST (
   MSG VARCHAR(10240),
   STATUS CHAR(4) DEFAULT 'NEW',
   CREATE_TS TIMESTAMP DEFAULT CURRENT_TIMESTAMP
-);
\ No newline at end of file
+);

http://git-wip-us.apache.org/repos/asf/camel/blob/583ee40b/tooling/archetypes/camel-archetype-cxf-contract-first-blueprint/src/main/resources/archetype-resources/src/main/resources/ok.xml
----------------------------------------------------------------------
diff --git a/tooling/archetypes/camel-archetype-cxf-contract-first-blueprint/src/main/resources/archetype-resources/src/main/resources/ok.xml b/tooling/archetypes/camel-archetype-cxf-contract-first-blueprint/src/main/resources/archetype-resources/src/main/resources/ok.xml
index 70800d1..ed3e194 100644
--- a/tooling/archetypes/camel-archetype-cxf-contract-first-blueprint/src/main/resources/archetype-resources/src/main/resources/ok.xml
+++ b/tooling/archetypes/camel-archetype-cxf-contract-first-blueprint/src/main/resources/archetype-resources/src/main/resources/ok.xml
@@ -1,3 +1,19 @@
+<!--
+  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.
+-->
 <ns2:outputReportIncident xmlns:ns2="http://reportincident.example.camel.apache.org">
   <code>Accepted</code>
-</ns2:outputReportIncident>
\ No newline at end of file
+</ns2:outputReportIncident>

http://git-wip-us.apache.org/repos/asf/camel/blob/583ee40b/tooling/maven/camel-package-maven-plugin/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-package-maven-plugin/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml b/tooling/maven/camel-package-maven-plugin/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml
index 565f8d4..56f2169 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml
+++ b/tooling/maven/camel-package-maven-plugin/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml
@@ -1,3 +1,19 @@
+<!--
+  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.
+-->
 <lifecycleMappingMetadata>
   <pluginExecutions>
     <pluginExecution>


[07/17] camel git commit: CAMEL-7927: Added support for Salesforce multiselect picklists

Posted by dh...@apache.org.
CAMEL-7927: Added support for Salesforce multiselect picklists


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

Branch: refs/heads/camel-2.12.x
Commit: 36a1747c6873acadc465d71acf3d23b6be2b91c5
Parents: 1cbd81b
Author: Dhiraj Bokde <dh...@yahoo.com>
Authored: Sat Dec 13 09:30:02 2014 -0800
Committer: Dhiraj Bokde <dh...@yahoo.com>
Committed: Fri Mar 20 14:24:43 2015 -0700

----------------------------------------------------------------------
 .../salesforce/api/JodaTimeConverter.java       |   6 +-
 .../api/MultiSelectPicklistConverter.java       | 101 +++++++++++++++++++
 .../api/MultiSelectPicklistDeserializer.java    |  94 +++++++++++++++++
 .../api/MultiSelectPicklistSerializer.java      |  64 ++++++++++++
 .../salesforce/api/PicklistEnumConverter.java   |  12 +--
 .../salesforce/internal/SalesforceSession.java  |   2 +-
 .../api/MultiSelectPicklistJsonTest.java        |  59 +++++++++++
 .../api/MultiSelectPicklistXmlTest.java         |  70 +++++++++++++
 .../salesforce/dto/generated/MSPTest.java       |  87 ++++++++++++++++
 .../camel-salesforce-maven-plugin/pom.xml       |   1 -
 .../apache/camel/maven/CamelSalesforceMojo.java |  23 ++++-
 .../src/main/resources/sobject-pojo.vm          |  25 ++++-
 components/camel-salesforce/pom.xml             |  27 +++++
 13 files changed, 557 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/36a1747c/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 009f697..c2609b8 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
@@ -18,6 +18,7 @@ package org.apache.camel.component.salesforce.api;
 
 import java.lang.reflect.Constructor;
 
+import com.thoughtworks.xstream.converters.ConversionException;
 import com.thoughtworks.xstream.converters.Converter;
 import com.thoughtworks.xstream.converters.MarshallingContext;
 import com.thoughtworks.xstream.converters.UnmarshallingContext;
@@ -29,6 +30,9 @@ import org.joda.time.DateTimeZone;
 import org.joda.time.format.DateTimeFormatter;
 import org.joda.time.format.ISODateTimeFormat;
 
+/**
+ * XStream converter for handling JodaTime fields.
+ */
 public class JodaTimeConverter implements Converter {
 
     private final DateTimeFormatter formatter = ISODateTimeFormat.dateTime();
@@ -48,7 +52,7 @@ public class JodaTimeConverter implements Converter {
             // normalize date time to UTC
             return constructor.newInstance(dateTimeStr, DateTimeZone.UTC);
         } catch (Exception e) {
-            throw new IllegalArgumentException(
+            throw new ConversionException(
                     String.format("Error reading Joda DateTime from value %s: %s",
                             dateTimeStr, e.getMessage()),
                     e);

http://git-wip-us.apache.org/repos/asf/camel/blob/36a1747c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/MultiSelectPicklistConverter.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/MultiSelectPicklistConverter.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/MultiSelectPicklistConverter.java
new file mode 100644
index 0000000..201a482
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/MultiSelectPicklistConverter.java
@@ -0,0 +1,101 @@
+/**
+ * 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 java.lang.reflect.Array;
+import java.lang.reflect.Method;
+
+import com.thoughtworks.xstream.converters.ConversionException;
+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;
+
+/**
+ * XStream converter for handling MSPs mapped to Picklist enum array fields.
+ */
+public class MultiSelectPicklistConverter implements Converter {
+
+    private static final String FACTORY_METHOD = "fromValue";
+
+    @Override
+    public void marshal(Object o, HierarchicalStreamWriter writer, MarshallingContext context) {
+        // get Picklist enum element class from array class
+        Class<?> arrayClass = o.getClass();
+        final Class<?> aClass = arrayClass.getComponentType();
+
+        try {
+            Method getterMethod = aClass.getMethod("value");
+            final int length = Array.getLength(o);
+
+            // construct a string of form value1;value2;...
+            final StringBuilder buffer = new StringBuilder();
+            for (int i = 0; i < length; i++) {
+                buffer.append((String) getterMethod.invoke(Array.get(o, i)));
+                if (i < (length - 1)) {
+                    buffer.append(';');
+                }
+            }
+            writer.setValue(buffer.toString());
+        } catch (Exception e) {
+            throw new ConversionException(
+                    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) {
+        final String listValue = reader.getValue();
+        // get Picklist enum element class from array class
+        final Class<?> requiredArrayType = context.getRequiredType();
+        final Class<?> requiredType = requiredArrayType.getComponentType();
+
+        try {
+            Method factoryMethod = requiredType.getMethod(FACTORY_METHOD, String.class);
+
+            // parse the string of the form value1;value2;...
+            final String[] value = listValue.split(";");
+            final int length = value.length;
+            final Object resultArray = Array.newInstance(requiredType, length);
+            for (int i = 0; i < length; i++) {
+                // use factory method to create object
+                Array.set(resultArray, i, factoryMethod.invoke(null, value[i].trim()));
+            }
+            return resultArray;
+        } catch (Exception e) {
+            throw new ConversionException(
+                    String.format("Exception reading pick list value %s of type %s: %s",
+                            listValue, requiredArrayType.getName(), e.getMessage()), e);
+        }
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public boolean canConvert(Class aClass) {
+        try {
+            // check whether the Class is an array, and whether the array elment is a Picklist enum class
+            final Class componentType = aClass.getComponentType();
+            return componentType != null && Enum.class.isAssignableFrom(componentType)
+                && componentType.getMethod(FACTORY_METHOD, String.class) != null;
+        } catch (NoSuchMethodException e) {
+            return false;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/36a1747c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/MultiSelectPicklistDeserializer.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/MultiSelectPicklistDeserializer.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/MultiSelectPicklistDeserializer.java
new file mode 100644
index 0000000..406f478
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/MultiSelectPicklistDeserializer.java
@@ -0,0 +1,94 @@
+/**
+ * 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 java.io.IOException;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+
+import org.codehaus.jackson.JsonParseException;
+import org.codehaus.jackson.JsonParser;
+import org.codehaus.jackson.map.BeanProperty;
+import org.codehaus.jackson.map.ContextualDeserializer;
+import org.codehaus.jackson.map.DeserializationConfig;
+import org.codehaus.jackson.map.DeserializationContext;
+import org.codehaus.jackson.map.JsonDeserializer;
+import org.codehaus.jackson.map.JsonMappingException;
+
+/**
+ * Jackson deserializer base class for reading ';' separated strings for MultiSelect pick-lists.
+ */
+public class MultiSelectPicklistDeserializer
+    extends JsonDeserializer<Object> implements ContextualDeserializer<Object> {
+
+    private static final String FACTORY_METHOD = "fromValue";
+
+    private final Class<? extends Enum> enumClass;
+    private final Method factoryMethod;
+
+    @SuppressWarnings("unused")
+    public MultiSelectPicklistDeserializer() {
+        enumClass = null;
+        factoryMethod = null;
+    }
+
+    public MultiSelectPicklistDeserializer(Class<? extends Enum> enumClass) throws JsonMappingException {
+        this.enumClass = enumClass;
+        try {
+            this.factoryMethod = enumClass.getMethod(FACTORY_METHOD, String.class);
+        } catch (NoSuchMethodException e) {
+            throw new JsonMappingException("Invalid pick-list enum class " + enumClass.getName(), e);
+        }
+    }
+
+    @Override
+    public Object deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
+
+        // validate enum class
+        if (enumClass == null) {
+            throw new JsonMappingException("Unable to parse unknown pick-list type");
+        }
+
+        final String listValue = jp.getText();
+
+        try {
+            // parse the string of the form value1;value2;...
+            final String[] value = listValue.split(";");
+            final int length = value.length;
+            final Object resultArray = Array.newInstance(enumClass, length);
+            for (int i = 0; i < length; i++) {
+                // use factory method to create object
+                Array.set(resultArray, i, factoryMethod.invoke(null, value[i].trim()));
+            }
+
+            return resultArray;
+        } catch (Exception e) {
+            throw new JsonParseException("Exception reading multi-select pick list value", jp.getCurrentLocation(), e);
+        }
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public JsonDeserializer<Object> createContextual(DeserializationConfig config, BeanProperty property) throws JsonMappingException {
+        final Class<?> rawClass = property.getType().getRawClass();
+        final Class<?> componentType = rawClass.getComponentType();
+        if (componentType == null || !componentType.isEnum()) {
+            throw new JsonMappingException("Pick list Enum array expected for " + rawClass);
+        }
+        return new MultiSelectPicklistDeserializer((Class<? extends Enum>) componentType);
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/36a1747c/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/MultiSelectPicklistSerializer.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/MultiSelectPicklistSerializer.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/MultiSelectPicklistSerializer.java
new file mode 100644
index 0000000..affbd1b
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/MultiSelectPicklistSerializer.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 java.io.IOException;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+
+import org.codehaus.jackson.JsonGenerationException;
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.map.JsonSerializer;
+import org.codehaus.jackson.map.SerializerProvider;
+
+/**
+ * Jackson Serializer for generating ';' separated strings for MultiSelect pick-lists.
+ */
+public class MultiSelectPicklistSerializer extends JsonSerializer<Object> {
+
+    private static final String FACTORY_METHOD = "fromValue";
+
+    @Override
+    public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
+
+        // get Picklist enum element class from array class
+        Class<?> arrayClass = value.getClass();
+        final Class<?> aClass = arrayClass.getComponentType();
+
+        try {
+
+            Method getterMethod = aClass.getMethod("value");
+            final int length = Array.getLength(value);
+
+            // construct a string of form value1;value2;...
+            final StringBuilder buffer = new StringBuilder();
+            for (int i = 0; i < length; i++) {
+                buffer.append((String) getterMethod.invoke(Array.get(value, i)));
+                if (i < (length - 1)) {
+                    buffer.append(';');
+                }
+            }
+
+            jgen.writeString(buffer.toString());
+
+        } catch (Exception e) {
+            throw new JsonGenerationException(
+                    String.format("Exception writing pick list value %s of type %s: %s",
+                            value, value.getClass().getName(), e.getMessage()), e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/36a1747c/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 775f5bd..4a430bf 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
@@ -18,12 +18,16 @@ package org.apache.camel.component.salesforce.api;
 
 import java.lang.reflect.Method;
 
+import com.thoughtworks.xstream.converters.ConversionException;
 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;
 
+/**
+ * XStream converter for handling pick-list enum fields.
+ */
 public class PicklistEnumConverter implements Converter {
 
     private static final String FACTORY_METHOD = "fromValue";
@@ -35,7 +39,7 @@ public class PicklistEnumConverter implements Converter {
             Method getterMethod = aClass.getMethod("value");
             writer.setValue((String) getterMethod.invoke(o));
         } catch (Exception e) {
-            throw new IllegalArgumentException(
+            throw new ConversionException(
                     String.format("Exception writing pick list value %s of type %s: %s",
                             o, o.getClass().getName(), e.getMessage()), e);
         }
@@ -49,12 +53,8 @@ public class PicklistEnumConverter implements Converter {
             Method factoryMethod = requiredType.getMethod(FACTORY_METHOD, String.class);
             // use factory method to create object
             return factoryMethod.invoke(null, value);
-        } 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);
         } catch (Exception e) {
-            throw new IllegalArgumentException(
+            throw new ConversionException(
                     String.format("Exception reading pick list value %s of type %s: %s",
                             value, context.getRequiredType().getName(), e.getMessage()), e);
         }

http://git-wip-us.apache.org/repos/asf/camel/blob/36a1747c/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 a1ce643..5dcb68b 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
@@ -121,7 +121,7 @@ public class SalesforceSession implements Service {
 
             try {
 
-                LOG.info("Logging clientId: {} into Salesforce url: {}", config.getClientId(), url);
+                LOG.info("Login user {} at Salesforce url: {}", config.getUserName(), url);
 
                 // set form content
                 loginPost.setRequestContent(new ByteArrayBuffer(

http://git-wip-us.apache.org/repos/asf/camel/blob/36a1747c/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/MultiSelectPicklistJsonTest.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/MultiSelectPicklistJsonTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/MultiSelectPicklistJsonTest.java
new file mode 100644
index 0000000..250c628
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/MultiSelectPicklistJsonTest.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.api;
+
+import org.apache.camel.component.salesforce.dto.generated.MSPTest;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.junit.Test;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+public class MultiSelectPicklistJsonTest {
+
+    private static final String TEST_JSON = "{\"MspField\":\"Value1;Value2;Value3\"}";
+    private static final String TEST_NULL_JSON = "{\"MspField\":null}";
+
+    private static ObjectMapper objectMapper = new ObjectMapper();
+
+    @Test
+    public void testMarshal() throws Exception {
+        final MSPTest mspTest = new MSPTest();
+        mspTest.setMspField(MSPTest.MSPEnum.values());
+
+        String json = objectMapper.writeValueAsString(mspTest);
+        assertEquals(TEST_JSON, json);
+
+        // test null
+        mspTest.setMspField(null);
+
+        json = objectMapper.writeValueAsString(mspTest);
+        assertEquals(TEST_NULL_JSON, json);
+    }
+
+    @Test
+    public void testUnmarshal() throws Exception {
+        MSPTest mspTest = objectMapper.readValue(TEST_JSON, MSPTest.class);
+        assertArrayEquals(MSPTest.MSPEnum.values(), mspTest.getMspField());
+
+        // test null
+        mspTest = objectMapper.readValue(TEST_NULL_JSON, MSPTest.class);
+        assertNull(mspTest.getMspField());
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/36a1747c/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/MultiSelectPicklistXmlTest.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/MultiSelectPicklistXmlTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/MultiSelectPicklistXmlTest.java
new file mode 100644
index 0000000..1dec3fd
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/api/MultiSelectPicklistXmlTest.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;
+
+import com.thoughtworks.xstream.XStream;
+
+import org.apache.camel.component.salesforce.dto.generated.MSPTest;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+public class MultiSelectPicklistXmlTest {
+
+    private static final String TEST_XML = "<MSPTest>\n"
+        + "  <MspField>Value1;Value2;Value3</MspField>\n"
+        + "</MSPTest>";
+    private static final String TEST_NULL_XML = "<MSPTest/>";
+
+    private static XStream xStream = new XStream();
+
+    @BeforeClass
+    public static void beforeClass() throws Exception {
+        xStream = new XStream();
+        xStream.processAnnotations(MSPTest.class);
+    }
+
+
+    @Test
+    public void testMarshal() throws Exception {
+        final MSPTest mspTest = new MSPTest();
+        mspTest.setMspField(MSPTest.MSPEnum.values());
+
+        String xml = xStream.toXML(mspTest);
+        assertEquals(TEST_XML, xml);
+
+        // test null value
+        mspTest.setMspField(null);
+
+        xml = xStream.toXML(mspTest);
+        assertEquals(TEST_NULL_XML, xml);
+    }
+
+    @Test
+    public void testUnmarshal() throws Exception {
+        MSPTest mspTest = (MSPTest) xStream.fromXML(TEST_XML);
+        assertArrayEquals(MSPTest.MSPEnum.values(), mspTest.getMspField());
+
+        // test null field value
+        mspTest = (MSPTest) xStream.fromXML(TEST_NULL_XML);
+        assertNull(mspTest.getMspField());
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/36a1747c/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/generated/MSPTest.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/generated/MSPTest.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/generated/MSPTest.java
new file mode 100644
index 0000000..a825391
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/generated/MSPTest.java
@@ -0,0 +1,87 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.salesforce.dto.generated;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamConverter;
+
+import org.apache.camel.component.salesforce.api.MultiSelectPicklistConverter;
+import org.apache.camel.component.salesforce.api.MultiSelectPicklistDeserializer;
+import org.apache.camel.component.salesforce.api.MultiSelectPicklistSerializer;
+import org.apache.camel.component.salesforce.api.dto.AbstractSObjectBase;
+import org.codehaus.jackson.annotate.JsonCreator;
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.annotate.JsonValue;
+import org.codehaus.jackson.map.annotate.JsonDeserialize;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+/**
+ * Sample POJO for MSP tests.
+ */
+//CHECKSTYLE:OFF
+@XStreamAlias("MSPTest")
+public class MSPTest extends AbstractSObjectBase {
+
+    @XStreamConverter(MultiSelectPicklistConverter.class)
+    private MSPEnum[] MspField;
+
+    @JsonProperty("MspField")
+    @JsonSerialize(using = MultiSelectPicklistSerializer.class)
+    public MSPEnum[] getMspField() {
+        return MspField;
+    }
+
+    @JsonProperty("MspField")
+    @JsonDeserialize(using = MultiSelectPicklistDeserializer.class)
+    public void setMspField(MSPEnum[] mspField) {
+        this.MspField = mspField;
+    }
+
+    @JsonDeserialize
+    public enum MSPEnum {
+
+        // Value1
+        VALUE1("Value1"),
+        // Value1
+        VALUE2("Value2"),
+        // Value1
+        VALUE3("Value3");
+
+        final String value;
+
+        private MSPEnum(String value) {
+            this.value = value;
+        }
+
+        @JsonValue
+        public String value() {
+            return this.value;
+        }
+
+        @JsonCreator
+        public static MSPEnum fromValue(String value) {
+            for (MSPEnum e : MSPEnum.values()) {
+                if (e.value.equals(value)) {
+                    return e;
+                }
+            }
+            throw new IllegalArgumentException(value);
+        }
+
+    }
+}
+//CHECKSTYLE:ON

http://git-wip-us.apache.org/repos/asf/camel/blob/36a1747c/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
index c354d61..011b440 100644
--- a/components/camel-salesforce/camel-salesforce-maven-plugin/pom.xml
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/pom.xml
@@ -157,7 +157,6 @@
             </executions>
           </plugin>
         </plugins>
-
       </build>
     </profile>
   </profiles>

http://git-wip-us.apache.org/repos/asf/camel/blob/36a1747c/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 4436d2e..fdb0f8e 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
@@ -386,7 +386,7 @@ public class CamelSalesforceMojo extends AbstractMojo {
 
             // write required Enumerations for any picklists
             for (SObjectField field : description.getFields()) {
-                if (utility.isPicklist(field)) {
+                if (utility.isPicklist(field) || utility.isMultiSelectPicklist(field)) {
                     fileName = utility.enumTypeName(field.getName()) + JAVA_EXT;
                     File enumFile = new File(pkgDir, fileName);
                     writer = new BufferedWriter(new FileWriter(enumFile));
@@ -497,6 +497,8 @@ public class CamelSalesforceMojo extends AbstractMojo {
         }
 
         private static final String BASE64BINARY = "base64Binary";
+        private static final String MULTIPICKLIST = "multipicklist";
+        private static final String PICKLIST = "picklist";
 
         public boolean isBlobField(SObjectField field) {
             final String soapType = field.getSoapType();
@@ -512,6 +514,9 @@ public class CamelSalesforceMojo extends AbstractMojo {
             if (isPicklist(field)) {
                 // use a pick list enum, which will be created after generating the SObject class
                 return enumTypeName(field.getName());
+            } else if (isMultiSelectPicklist(field)) {
+                // use a pick list enum array, enum will be created after generating the SObject class
+                return enumTypeName(field.getName()) + "[]";
             } else {
                 // map field to Java type
                 final String soapType = field.getSoapType();
@@ -524,6 +529,10 @@ public class CamelSalesforceMojo extends AbstractMojo {
             }
         }
 
+        public boolean isMultiSelectPicklist(SObjectField field) {
+            return MULTIPICKLIST.equals(field.getType());
+        }
+
         public boolean hasPicklists(SObjectDescription desc) {
             for (SObjectField field : desc.getFields()) {
                 if (isPicklist(field)) {
@@ -533,13 +542,23 @@ public class CamelSalesforceMojo extends AbstractMojo {
             return false;
         }
 
+        public boolean hasMultiSelectPicklists(SObjectDescription desc) {
+            for (SObjectField field : desc.getFields()) {
+                if (isMultiSelectPicklist(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();
+//            return field.getPicklistValues() != null && !field.getPicklistValues().isEmpty();
+            return PICKLIST.equals(field.getType());
         }
 
         public String enumTypeName(String name) {

http://git-wip-us.apache.org/repos/asf/camel/blob/36a1747c/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
index bbce083..b69a3d8 100644
--- 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
@@ -23,15 +23,25 @@ package $packageName;
 
 ## add imports for XStreamConverter and PicklistEnumConverter if needed
 #set ( $hasPicklists = $utility.hasPicklists($desc) )
+#set ( $hasMultiSelectPicklists = $utility.hasMultiSelectPicklists($desc) )
 import com.thoughtworks.xstream.annotations.XStreamAlias;
-#if ( $hasPicklists )
+#if ( $hasPicklists || $hasMultiSelectPicklists )
 import com.thoughtworks.xstream.annotations.XStreamConverter;
 #end
-import org.codehaus.jackson.annotate.JsonProperty;
 #if ( $hasPicklists )
 import org.apache.camel.component.salesforce.api.PicklistEnumConverter;
 #end
+#if ( $hasMultiSelectPicklists )
+import org.apache.camel.component.salesforce.api.MultiSelectPicklistConverter;
+import org.apache.camel.component.salesforce.api.MultiSelectPicklistDeserializer;
+import org.apache.camel.component.salesforce.api.MultiSelectPicklistSerializer;
+#end
 import org.apache.camel.component.salesforce.api.dto.AbstractSObjectBase;
+import org.codehaus.jackson.annotate.JsonProperty;
+#if ( $hasMultiSelectPicklists )
+import org.codehaus.jackson.map.annotate.JsonDeserialize;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+#end
 
 /**
  * Salesforce DTO for SObject $desc.Name
@@ -43,6 +53,7 @@ public class $desc.Name extends AbstractSObjectBase {
 #if ( $utility.notBaseField($field.Name) )
 #set ( $fieldName = $field.Name )
 #set ( $fieldType = $utility.getFieldType($field) )
+#set ( $isMultiSelectPicklist = $utility.isMultiSelectPicklist($field) )
     // $fieldName
 #if ( $utility.isBlobField($field) )
 #set ( $propertyName = $fieldName + "Url" )
@@ -50,8 +61,10 @@ public class $desc.Name extends AbstractSObjectBase {
 #set ( $propertyName = $fieldName )
 #end
 ## add a converter annotation if needed
-#if ( $utility.isPicklist($field) )
+#if ( !$isMultiSelectPicklist && $utility.isPicklist($field) )
     @XStreamConverter(PicklistEnumConverter.class)
+#elseif ( $isMultiSelectPicklist )
+    @XStreamConverter(MultiSelectPicklistConverter.class)
 #else
 ## add an alias for blob field url if needed
 #if ( $propertyName != $fieldName )
@@ -62,11 +75,17 @@ public class $desc.Name extends AbstractSObjectBase {
     private $fieldType $propertyName;
 
     @JsonProperty("$fieldName")
+#if ( $isMultiSelectPicklist )
+    @JsonSerialize(using = MultiSelectPicklistSerializer.class)
+#end
     public $fieldType get$propertyName() {
         return this.$propertyName;
     }
 
     @JsonProperty("$fieldName")
+#if ( $isMultiSelectPicklist )
+    @JsonDeserialize(using = MultiSelectPicklistDeserializer.class)
+#end
     public void set$propertyName($fieldType $propertyName) {
         this.$propertyName = $propertyName;
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/36a1747c/components/camel-salesforce/pom.xml
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/pom.xml b/components/camel-salesforce/pom.xml
index e5bcc4c..ff70069 100644
--- a/components/camel-salesforce/pom.xml
+++ b/components/camel-salesforce/pom.xml
@@ -35,4 +35,31 @@
         <module>camel-salesforce-maven-plugin</module>
     </modules>
 
+    <profiles>
+
+      <profile>
+        <id>salesforce-test</id>
+        <build>
+          <plugins>
+            <plugin>
+              <artifactId>maven-surefire-plugin</artifactId>
+              <configuration>
+                <childDelegation>false</childDelegation>
+                <useFile>true</useFile>
+                <forkCount>1</forkCount>
+                <reuseForks>true</reuseForks>
+                <forkedProcessTimeoutInSeconds>300</forkedProcessTimeoutInSeconds>
+                <excludes>
+                  <exclude>**/*XXXTest.java</exclude>
+                </excludes>
+                <includes>
+                  <include>**/*Test.java</include>
+                </includes>
+              </configuration>
+            </plugin>
+          </plugins>
+        </build>
+      </profile>
+    </profiles>
+
 </project>


[08/17] camel git commit: CAMEL-8267: fixed mojo integration test to use system property or default login url

Posted by dh...@apache.org.
CAMEL-8267: fixed mojo integration test to use system property or default login url


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

Branch: refs/heads/camel-2.12.x
Commit: 12916954f3af92c5cabac1746303470451760d29
Parents: 33b20d5
Author: Dhiraj Bokde <dh...@yahoo.com>
Authored: Mon Feb 23 12:34:41 2015 -0800
Committer: Dhiraj Bokde <dh...@yahoo.com>
Committed: Fri Mar 20 14:24:44 2015 -0700

----------------------------------------------------------------------
 .../camel/maven/CamelSalesforceMojoIntegrationTest.java      | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/12916954/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 406ce5f..cf9bcb9 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,10 +16,15 @@
  */
 package org.apache.camel.maven;
 
-import java.io.*;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.Properties;
 
 import org.apache.camel.component.salesforce.SalesforceEndpointConfig;
+import org.apache.camel.component.salesforce.SalesforceLoginConfig;
 import org.apache.maven.plugin.logging.SystemStreamLog;
 import org.junit.Assert;
 import org.junit.Test;
@@ -39,6 +44,7 @@ public class CamelSalesforceMojoIntegrationTest {
 
         // set defaults
         mojo.version = System.getProperty("apiVersion", SalesforceEndpointConfig.DEFAULT_VERSION);
+        mojo.loginUrl = System.getProperty("loginUrl", SalesforceLoginConfig.DEFAULT_LOGIN_URL);
         mojo.outputDirectory = new File("target/generated-sources/camel-salesforce");
         mojo.packageName = "org.apache.camel.salesforce.dto";
 


[13/17] camel git commit: CAMEL-8519: Fixed salesforce security listener to replace OAuth header

Posted by dh...@apache.org.
CAMEL-8519: Fixed salesforce security listener to replace OAuth header


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

Branch: refs/heads/camel-2.12.x
Commit: 93cd64512d9c0763653b4f4e5045b8d83f77daea
Parents: 9bb3a9e
Author: Dhiraj Bokde <dh...@yahoo.com>
Authored: Fri Mar 20 09:54:57 2015 -0700
Committer: Dhiraj Bokde <dh...@yahoo.com>
Committed: Fri Mar 20 14:24:46 2015 -0700

----------------------------------------------------------------------
 .../salesforce/internal/client/SalesforceSecurityListener.java   | 4 ++--
 .../salesforce/internal/streaming/SubscriptionHelper.java        | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/93cd6451/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 552401c..27d838a 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
@@ -103,8 +103,8 @@ public class SalesforceSecurityListener extends HttpEventListenerWrapper {
                     client.setInstanceUrl(session.getInstanceUrl());
                     client.setAccessToken(exchange);
                 } else {
-                    exchange.addRequestHeader(HttpHeaders.AUTHORIZATION,
-                            "OAuth " + currentToken);
+                    exchange.setRequestHeader(HttpHeaders.AUTHORIZATION,
+                        "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/93cd6451/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 7aaa086..b0ed0d6 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
@@ -213,7 +213,7 @@ public class SubscriptionHelper extends ServiceSupport {
                 }
 
                 // add current security token obtained from session
-                exchange.addRequestHeader(HttpHeaders.AUTHORIZATION,
+                exchange.setRequestHeader(HttpHeaders.AUTHORIZATION,
                         "OAuth " + accessToken);
             }
         };


[14/17] camel git commit: CAMEL-8269: replaced 2.15 URISupport.appendParametersToURI with 2.14.x URISupport.createRemainingURI

Posted by dh...@apache.org.
CAMEL-8269: replaced 2.15 URISupport.appendParametersToURI with 2.14.x URISupport.createRemainingURI


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

Branch: refs/heads/camel-2.12.x
Commit: 9bb3a9e982855bc01366fa149e0837839cb20aeb
Parents: 65cd95c
Author: Dhiraj Bokde <dh...@yahoo.com>
Authored: Mon Feb 23 13:56:52 2015 -0800
Committer: Dhiraj Bokde <dh...@yahoo.com>
Committed: Fri Mar 20 14:24:46 2015 -0700

----------------------------------------------------------------------
 .../component/salesforce/internal/client/DefaultRestClient.java  | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/9bb3a9e9/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 0b06289..9a9f91b 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
@@ -19,12 +19,14 @@ package org.apache.camel.component.salesforce.internal.client;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
+import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URLEncoder;
 import java.util.List;
 import java.util.Map;
 
 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.PayloadFormat;
@@ -344,7 +346,7 @@ public class DefaultRestClient extends AbstractClientBase implements RestClient
         throws UnsupportedEncodingException, URISyntaxException {
 
         if (queryParams != null && !queryParams.isEmpty()) {
-            apexUrl = URISupport.appendParametersToURI(apexUrl, queryParams);
+            apexUrl = URISupport.createRemainingURI(new URI(apexUrl), queryParams).toString();
         }
 
         return instanceUrl + SERVICES_APEXREST + apexUrl;


[15/17] camel git commit: CAMEL-8517: Updated SalesforceSession to use volatile shared fields

Posted by dh...@apache.org.
CAMEL-8517: Updated SalesforceSession to use volatile shared fields


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

Branch: refs/heads/camel-2.12.x
Commit: 40ff886df7f83ee46b71a9c46f1044badec03721
Parents: 93cd645
Author: Dhiraj Bokde <dh...@yahoo.com>
Authored: Fri Mar 20 09:57:03 2015 -0700
Committer: Dhiraj Bokde <dh...@yahoo.com>
Committed: Fri Mar 20 14:24:47 2015 -0700

----------------------------------------------------------------------
 .../component/salesforce/internal/SalesforceSession.java  | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/40ff886d/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 5dcb68b..2364697 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
@@ -56,8 +56,8 @@ public class SalesforceSession implements Service {
     private final ObjectMapper objectMapper;
     private final Set<SalesforceSessionListener> listeners;
 
-    private String accessToken;
-    private String instanceUrl;
+    private volatile String accessToken;
+    private volatile String instanceUrl;
 
     public SalesforceSession(HttpClient httpClient, SalesforceLoginConfig config) {
         // validate parameters
@@ -198,7 +198,7 @@ public class SalesforceSession implements Service {
         return accessToken;
     }
 
-    public void logout() throws SalesforceException {
+    public synchronized void logout() throws SalesforceException {
         if (accessToken == null) {
             return;
         }
@@ -236,7 +236,7 @@ public class SalesforceSession implements Service {
                 throw new SalesforceException("Logout request TIMEOUT!", null);
 
             default:
-                throw new SalesforceException("Unknow status: " + done, null);
+                throw new SalesforceException("Unknown status: " + done, null);
             }
         } catch (SalesforceException e) {
             throw e;
@@ -247,7 +247,7 @@ public class SalesforceSession implements Service {
             // reset session
             accessToken = null;
             instanceUrl = null;
-            // notify all session listeners of the new access token and instance url
+            // notify all session listeners about logout
             for (SalesforceSessionListener listener : listeners) {
                 try {
                     listener.onLogout();


[16/17] camel git commit: CAMEL-8516: Fixed 300 status code exception handling, minor polish

Posted by dh...@apache.org.
CAMEL-8516: Fixed 300 status code exception handling, minor polish


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

Branch: refs/heads/camel-2.12.x
Commit: 08f20d564a774fe2c49707df1b695b9eaaae084d
Parents: 40ff886
Author: Dhiraj Bokde <dh...@yahoo.com>
Authored: Fri Mar 20 13:36:48 2015 -0700
Committer: Dhiraj Bokde <dh...@yahoo.com>
Committed: Fri Mar 20 14:24:48 2015 -0700

----------------------------------------------------------------------
 .../salesforce/SalesforceConsumer.java          |   4 +-
 .../salesforce/api/SalesforceException.java     |  44 ++++---
 .../api/SalesforceMultipleChoicesException.java |  41 ++++++
 .../salesforce/internal/SalesforceSession.java  |  21 ++-
 .../internal/client/AbstractClientBase.java     |   4 +-
 .../internal/client/DefaultBulkApiClient.java   |   2 +-
 .../internal/client/DefaultRestClient.java      |  68 +++++++---
 .../salesforce/internal/dto/RestChoices.java    |  40 ++++++
 .../salesforce/RestApiIntegrationTest.java      | 131 ++++++++++++++++++-
 9 files changed, 296 insertions(+), 59 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/08f20d56/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 b47f658..ac44d5a 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
@@ -141,8 +141,8 @@ public class SalesforceConsumer extends DefaultConsumer {
         // 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);
+        @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()) {

http://git-wip-us.apache.org/repos/asf/camel/blob/08f20d56/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 4005ec4..dd25f0a 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
@@ -58,13 +58,13 @@ public class SalesforceException extends CamelException {
     }
 
     public SalesforceException(List<RestError> errors, int statusCode, String message, Throwable cause) {
-        super(toErrorMessage(errors, statusCode), cause);
+        super(message == null ? toErrorMessage(errors, statusCode) : message, cause);
         this.errors = errors;
         this.statusCode = statusCode;
     }
 
     public List<RestError> getErrors() {
-        return Collections.unmodifiableList(errors);
+        return errors != null ? Collections.unmodifiableList(errors) : null;
     }
 
     public int getStatusCode() {
@@ -73,30 +73,42 @@ public class SalesforceException extends CamelException {
 
     @Override
     public String toString() {
+        final StringBuilder builder = new StringBuilder("{");
+        appendFields(builder);
+        builder.append("}");
+        return builder.toString();
+    }
+
+    protected void appendFields(StringBuilder builder) {
+        // append message
+        builder.append("message:'");
+        builder.append(getMessage());
+        builder.append("',");
+
+        // check for error
         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();
+            builder.append("errors:[");
+            for (RestError error : errors) {
+                builder.append(error.toString());
+            }
+            builder.append("],");
+
         }
+        // append statusCode
+        builder.append("statusCode:");
+        builder.append(statusCode);
     }
 
     private static String toErrorMessage(List<RestError> errors, int statusCode) {
-        StringBuilder builder = new StringBuilder("{ ");
+        StringBuilder builder = new StringBuilder("{");
         if (errors != null) {
-            builder.append(" errors: [");
+            builder.append("errors:[");
             for (RestError error : errors) {
                 builder.append(error.toString());
             }
-            builder.append("], ");
+            builder.append("],");
         }
-        builder.append("statusCode: ");
+        builder.append("statusCode:");
         builder.append(statusCode);
         builder.append("}");
 

http://git-wip-us.apache.org/repos/asf/camel/blob/08f20d56/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/SalesforceMultipleChoicesException.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/SalesforceMultipleChoicesException.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/SalesforceMultipleChoicesException.java
new file mode 100644
index 0000000..8330e5e
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/SalesforceMultipleChoicesException.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;
+
+import java.util.List;
+
+public class SalesforceMultipleChoicesException extends SalesforceException {
+
+    private static final long serialVersionUID = 1L;
+    private final List<String> choices;
+
+    public SalesforceMultipleChoicesException(String message, int statusCode, List<String> choices) {
+        super(message, statusCode);
+        this.choices = choices;
+    }
+
+    public List<String> getChoices() {
+        return choices;
+    }
+
+    @Override
+    public void appendFields(StringBuilder builder) {
+        super.appendFields(builder);
+        builder.append(",choices=");
+        builder.append(choices.toString());
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/08f20d56/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 2364697..bf3a395 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
@@ -28,6 +28,7 @@ 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.apache.camel.util.ObjectHelper;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.eclipse.jetty.client.ContentExchange;
 import org.eclipse.jetty.client.HttpClient;
@@ -61,13 +62,13 @@ public class SalesforceSession implements Service {
 
     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());
+        ObjectHelper.notNull(httpClient, "httpClient");
+        ObjectHelper.notNull(config, "SalesforceLoginConfig");
+        ObjectHelper.notNull(config.getLoginUrl(), "loginUrl");
+        ObjectHelper.notNull(config.getClientId(), "clientId");
+        ObjectHelper.notNull(config.getClientSecret(), "clientSecret");
+        ObjectHelper.notNull(config.getUserName(), "userName");
+        ObjectHelper.notNull(config.getPassword(), "password");
 
         this.httpClient = httpClient;
         this.config = config;
@@ -80,12 +81,6 @@ public class SalesforceSession implements Service {
         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 {
 

http://git-wip-us.apache.org/repos/asf/camel/blob/08f20d56/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 a115a31..a00d289 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
@@ -150,7 +150,7 @@ public abstract class AbstractClientBase implements SalesforceSession.Salesforce
                 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, responseStatus, createRestException(request));
+                    final SalesforceException exception = new SalesforceException(msg, responseStatus, createRestException(request, reason));
                     callback.onResponse(null, exception);
                 } else {
                     // TODO not memory efficient for large response messages,
@@ -190,6 +190,6 @@ public abstract class AbstractClientBase implements SalesforceSession.Salesforce
 
     protected abstract void setAccessToken(HttpExchange httpExchange);
 
-    protected abstract SalesforceException createRestException(ContentExchange httpExchange);
+    protected abstract SalesforceException createRestException(ContentExchange httpExchange, String reason);
 
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/08f20d56/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 a72aee7..3ab4227 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
@@ -386,7 +386,7 @@ public class DefaultBulkApiClient extends AbstractClientBase implements BulkApiC
     }
 
     @Override
-    protected SalesforceException createRestException(ContentExchange request) {
+    protected SalesforceException createRestException(ContentExchange request, String reason) {
         // this must be of type Error
         try {
             final Error error = unmarshalResponse(new ByteArrayInputStream(request.getResponseContentBytes()),

http://git-wip-us.apache.org/repos/asf/camel/blob/08f20d56/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 9a9f91b..7269984 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
@@ -28,10 +28,13 @@ import java.util.Map;
 import com.thoughtworks.xstream.XStream;
 
 import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.api.SalesforceMultipleChoicesException;
 import org.apache.camel.component.salesforce.api.dto.RestError;
 import org.apache.camel.component.salesforce.internal.PayloadFormat;
 import org.apache.camel.component.salesforce.internal.SalesforceSession;
+import org.apache.camel.component.salesforce.internal.dto.RestChoices;
 import org.apache.camel.component.salesforce.internal.dto.RestErrors;
+import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.URISupport;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.codehaus.jackson.type.TypeReference;
@@ -40,6 +43,7 @@ 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.http.HttpStatus;
 import org.eclipse.jetty.util.StringUtil;
 
 public class DefaultRestClient extends AbstractClientBase implements RestClient {
@@ -63,6 +67,7 @@ public class DefaultRestClient extends AbstractClientBase implements RestClient
         this.objectMapper = new ObjectMapper();
         this.xStream = new XStream();
         xStream.processAnnotations(RestErrors.class);
+        xStream.processAnnotations(RestChoices.class);
     }
 
     @Override
@@ -77,32 +82,61 @@ public class DefaultRestClient extends AbstractClientBase implements RestClient
     }
 
     @Override
-    protected SalesforceException createRestException(ContentExchange httpExchange) {
+    protected SalesforceException createRestException(ContentExchange httpExchange, String reason) {
+        // get status code and reason phrase
+        final int statusCode = httpExchange.getResponseStatus();
+        if (reason == null || reason.isEmpty()) {
+            reason = HttpStatus.getMessage(statusCode);
+        }
         // try parsing response according to format
+        String responseContent = null;
         try {
-            if (PayloadFormat.JSON.equals(format)) {
-                List<RestError> restErrors = objectMapper.readValue(
-                    httpExchange.getResponseContent(), new TypeReference<List<RestError>>() {
+            responseContent = httpExchange.getResponseContent();
+            if (responseContent != null && !responseContent.isEmpty()) {
+                final List<String> choices;
+                // return list of choices as error message for 300
+                if (statusCode == HttpStatus.MULTIPLE_CHOICES_300) {
+                    if (PayloadFormat.JSON.equals(format)) {
+                        choices = objectMapper.readValue(
+                            responseContent, new TypeReference<List<String>>() {
+                            }
+                        );
+                    } else {
+                        RestChoices restChoices = new RestChoices();
+                        xStream.fromXML(responseContent, restChoices);
+                        choices = restChoices.getUrls();
+                    }
+                    return new SalesforceMultipleChoicesException(reason, statusCode, choices);
+                } else {
+                    final List<RestError> restErrors;
+                    if (PayloadFormat.JSON.equals(format)) {
+                        restErrors = objectMapper.readValue(
+                            responseContent, new TypeReference<List<RestError>>() {
+                            }
+                        );
+                    } else {
+                        RestErrors errors = new RestErrors();
+                        xStream.fromXML(responseContent, errors);
+                        restErrors = errors.getErrors();
                     }
-                );
-                return new SalesforceException(restErrors, httpExchange.getResponseStatus());
-            } else {
-                RestErrors errors = new RestErrors();
-                xStream.fromXML(httpExchange.getResponseContent(), errors);
-                return new SalesforceException(errors.getErrors(), httpExchange.getResponseStatus());
+                    return new SalesforceException(restErrors, statusCode);
+                }
             }
         } catch (IOException e) {
             // log and ignore
-            String msg = "Unexpected Error parsing " + format + " error response: " + e.getMessage();
+            String msg = "Unexpected Error parsing " + format
+                    + " error response body + [" + responseContent + "] : " + e.getMessage();
             log.warn(msg, e);
         } catch (RuntimeException e) {
             // log and ignore
-            String msg = "Unexpected Error parsing " + format + " error response: " + e.getMessage();
+            String msg = "Unexpected Error parsing " + format
+                    + " error response body + [" + responseContent + "] : " + e.getMessage();
             log.warn(msg, e);
         }
 
         // just report HTTP status info
-        return new SalesforceException("Unexpected error", httpExchange.getResponseStatus());
+        return new SalesforceException("Unexpected error: " + reason + ", with content: " + responseContent,
+                statusCode);
     }
 
     @Override
@@ -357,16 +391,12 @@ public class DefaultRestClient extends AbstractClientBase implements RestClient
     }
 
     private String versionUrl() {
-        if (version == null) {
-            throw new IllegalArgumentException("NULL API version", new NullPointerException("version"));
-        }
+        ObjectHelper.notNull(version, "version");
         return servicesDataUrl() + "v" + version + "/";
     }
 
     private String sobjectsUrl(String sObjectName) {
-        if (sObjectName == null) {
-            throw new IllegalArgumentException("Null SObject name", new NullPointerException("sObjectName"));
-        }
+        ObjectHelper.notNull(sObjectName, "sObjectName");
         return versionUrl() + "sobjects/" + sObjectName;
     }
 

http://git-wip-us.apache.org/repos/asf/camel/blob/08f20d56/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/RestChoices.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/RestChoices.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/RestChoices.java
new file mode 100644
index 0000000..cd639ff
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/dto/RestChoices.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.internal.dto;
+
+import java.util.List;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamImplicit;
+
+/**
+ * DTO for Salesforce REST choices XML response for status code 300
+ */
+@XStreamAlias("Choices")
+public class RestChoices {
+
+    @XStreamImplicit(itemFieldName = "Url")
+    private List<String> urls;
+
+    public List<String> getUrls() {
+        return urls;
+    }
+
+    public void setUrls(List<String> urls) {
+        this.urls = urls;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/08f20d56/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 52a95f6..9627cf3 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
@@ -29,6 +29,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
 import org.apache.camel.CamelExecutionException;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.api.SalesforceMultipleChoicesException;
 import org.apache.camel.component.salesforce.api.dto.AbstractDTOBase;
 import org.apache.camel.component.salesforce.api.dto.CreateSObjectResult;
 import org.apache.camel.component.salesforce.api.dto.GlobalObjects;
@@ -172,7 +173,7 @@ public class RestApiIntegrationTest extends AbstractSalesforceTestBase {
         merchandise.setDescription__c("Microlite plane");
         merchandise.setPrice__c(2000.0);
         merchandise.setTotal_Inventory__c(50.0);
-        CreateSObjectResult result = template().requestBody("direct:CreateSObject" + suffix,
+        CreateSObjectResult result = template().requestBody("direct:createSObject" + suffix,
             merchandise, CreateSObjectResult.class);
         assertNotNull(result);
         assertTrue("Create success", result.getSuccess());
@@ -186,7 +187,7 @@ public class RestApiIntegrationTest extends AbstractSalesforceTestBase {
         // also need to set the Id
         merchandise.setId(result.getId());
 
-        assertNull(template().requestBodyAndHeader("direct:UpdateSObject" + suffix,
+        assertNull(template().requestBodyAndHeader("direct:updateSObject" + suffix,
             merchandise, SalesforceEndpointConfig.SOBJECT_ID, result.getId()));
         LOG.debug("Update successful");
 
@@ -391,6 +392,124 @@ public class RestApiIntegrationTest extends AbstractSalesforceTestBase {
         }
     }
 
+    @Test
+    public void testStatus300() throws Exception {
+        doTestStatus300("");
+        doTestStatus300("Xml");
+    }
+
+    private void doTestStatus300(String suffix) throws Exception {
+        // clone test merchandise with same external Id
+        if (testId == null) {
+            // execute getBasicInfo to get test id from recent items
+            doTestGetBasicInfo("");
+        }
+
+        // get test merchandise
+        // note that the header value overrides sObjectFields in endpoint
+        Merchandise__c merchandise = template().requestBodyAndHeader("direct:getSObject" + suffix, testId,
+            "sObjectFields", "Name,Description__c,Price__c,Total_Inventory__c", Merchandise__c.class);
+        assertNotNull(merchandise);
+        assertNotNull(merchandise.getName());
+        assertNotNull(merchandise.getPrice__c());
+        assertNotNull(merchandise.getTotal_Inventory__c());
+
+        CreateSObjectResult result = null;
+        try {
+            merchandise.clearBaseFields();
+            result = template().requestBody("direct:createSObject" + suffix,
+                merchandise, CreateSObjectResult.class);
+            assertNotNull(result);
+            assertNotNull(result.getId());
+            LOG.debug("Clone SObject: {}", result);
+
+            // look by external Id to cause 300 error
+            // note that the request SObject overrides settings on the endpoint for LineItem__c
+            try {
+                template().requestBody("direct:getSObjectWithId" + suffix, merchandise, Merchandise__c.class);
+                fail("Expected SalesforceException with statusCode 300");
+            } catch (CamelExecutionException e) {
+                assertTrue(e.getCause() instanceof SalesforceException);
+                assertTrue(e.getCause().getCause() instanceof SalesforceMultipleChoicesException);
+                final SalesforceMultipleChoicesException cause = (SalesforceMultipleChoicesException) e.getCause().getCause();
+                assertEquals(300, cause.getStatusCode());
+                final List<String> choices = cause.getChoices();
+                assertNotNull(choices);
+                assertFalse(choices.isEmpty());
+                LOG.debug("Multiple choices: {}", choices);
+            }
+        } finally {
+            // delete the test clone
+            if (result != null) {
+                template().requestBody("direct:deleteSObject" + suffix, result.getId());
+            }
+        }
+    }
+
+    @Test
+    public void testStatus400() throws Exception {
+        doTestStatus400("");
+        doTestStatus400("Xml");
+    }
+
+    private void doTestStatus400(String suffix) throws Exception {
+        // clone test merchandise with same external Id
+        if (testId == null) {
+            // execute getBasicInfo to get test id from recent items
+            doTestGetBasicInfo("");
+        }
+
+        // get test merchandise
+        // note that the header value overrides sObjectFields in endpoint
+        Merchandise__c merchandise = template().requestBodyAndHeader("direct:getSObject" + suffix, testId,
+            "sObjectFields", "Description__c,Price__c", Merchandise__c.class);
+        assertNotNull(merchandise);
+        assertNotNull(merchandise.getPrice__c());
+        assertNull(merchandise.getTotal_Inventory__c());
+
+        merchandise.clearBaseFields();
+        // required field Total_Inventory__c is missing
+        CreateSObjectResult result = null;
+        try {
+            result = template().requestBody("direct:createSObject" + suffix,
+                merchandise, CreateSObjectResult.class);
+            fail("Expected SalesforceException with statusCode 400");
+        } catch (CamelExecutionException e) {
+            assertTrue(e.getCause() instanceof SalesforceException);
+            assertTrue(e.getCause().getCause() instanceof SalesforceException);
+            final SalesforceException cause = (SalesforceException) e.getCause().getCause();
+            assertEquals(400, cause.getStatusCode());
+            assertEquals(1, cause.getErrors().size());
+            assertEquals("[Total_Inventory__c]", cause.getErrors().get(0).getFields().toString());
+        } finally {
+            // delete the clone if created
+            if (result != null) {
+                template().requestBody("direct:deleteSObject" + suffix, result.getId());
+            }
+        }
+    }
+
+    @Test
+    public void testStatus404() {
+        doTestStatus404("");
+        doTestStatus404("Xml");
+    }
+
+    private void doTestStatus404(String suffix) {
+        // try to get a non existent SObject
+        try {
+            template().requestBody("direct:getSObject" + suffix, "ILLEGAL_ID", Merchandise__c.class);
+            fail("Expected SalesforceException");
+        } catch (CamelExecutionException e) {
+            assertTrue(e.getCause() instanceof SalesforceException);
+            assertTrue(e.getCause().getCause() instanceof SalesforceException);
+            final SalesforceException cause = (SalesforceException) e.getCause().getCause();
+            assertEquals(404, cause.getStatusCode());
+            assertEquals(1, cause.getErrors().size());
+            LOG.debug("Errors for 404: {}", cause.getErrors());
+        }
+    }
+
     @Override
     protected RouteBuilder doCreateRouteBuilder() throws Exception {
 
@@ -442,17 +561,17 @@ public class RestApiIntegrationTest extends AbstractSalesforceTestBase {
                     .to("salesforce:getSObject?format=XML&sObjectName=Merchandise__c&sObjectFields=Description__c,Total_Inventory__c");
 
                 // testCreateSObject
-                from("direct:CreateSObject")
+                from("direct:createSObject")
                     .to("salesforce:createSObject?sObjectName=Merchandise__c");
 
-                from("direct:CreateSObjectXml")
+                from("direct:createSObjectXml")
                     .to("salesforce:createSObject?format=XML&sObjectName=Merchandise__c");
 
                 // testUpdateSObject
-                from("direct:UpdateSObject")
+                from("direct:updateSObject")
                     .to("salesforce:updateSObject?sObjectName=Merchandise__c");
 
-                from("direct:UpdateSObjectXml")
+                from("direct:updateSObjectXml")
                     .to("salesforce:updateSObject?format=XML&sObjectName=Merchandise__c");
 
                 // testDeleteSObject


[05/17] camel git commit: Update README.md - Add Prefix "camelSalesforce"

Posted by dh...@apache.org.
Update README.md - Add Prefix "camelSalesforce"

The suffix "camelSalesforce" needs to be added as prefix to the properties.
The command should be corrected as:
mvn camel-salesforce:generate -DcamelSalesforce.clientId=<clientid> -DcamelSalesforce.clientSecret=<clientsecret> -DcamelSalesforce.userName=<username> -DcamelSalesforce.password=<password>


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

Branch: refs/heads/camel-2.12.x
Commit: 10c80635eb75f43646a44192727548391172dc03
Parents: 583ee40
Author: yelamanchili-murali <ye...@gmail.com>
Authored: Fri Oct 3 15:48:34 2014 +1000
Committer: Dhiraj Bokde <dh...@yahoo.com>
Committed: Fri Mar 20 14:24:42 2015 -0700

----------------------------------------------------------------------
 .../camel-salesforce/camel-salesforce-maven-plugin/README.md       | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/10c80635/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
index 5bfd808..0424771 100644
--- a/components/camel-salesforce/camel-salesforce-maven-plugin/README.md
+++ b/components/camel-salesforce/camel-salesforce-maven-plugin/README.md
@@ -21,6 +21,6 @@ The plugin configuration has the following properties.
 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>
+	mvn camel-salesforce:generate -DcamelSalesforce.clientId=<clientid> -DcamelSalesforce.clientSecret=<clientsecret> -DcamelSalesforce.userName=<username> -DcamelSalesforce.password=<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. 


[10/17] camel git commit: CAMEL-8395: handles empty Salesforce picklists, also maps urn:address to String

Posted by dh...@apache.org.
CAMEL-8395: handles empty Salesforce picklists, also maps urn:address to String


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

Branch: refs/heads/camel-2.12.x
Commit: 2dc15fa04c4f2ca84a8cdebd69f9f2a2403f62d5
Parents: 1291695
Author: Dhiraj Bokde <dh...@yahoo.com>
Authored: Mon Feb 23 12:42:21 2015 -0800
Committer: Dhiraj Bokde <dh...@yahoo.com>
Committed: Fri Mar 20 14:24:45 2015 -0700

----------------------------------------------------------------------
 .../apache/camel/maven/CamelSalesforceMojo.java | 63 +++++++++++++-------
 .../src/main/resources/sobject-picklist.vm      | 18 +++---
 2 files changed, 52 insertions(+), 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/2dc15fa0/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 dab9c70..d517f24 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
@@ -21,6 +21,9 @@ import java.io.File;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -28,6 +31,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
+import java.util.TreeSet;
 import java.util.concurrent.TimeUnit;
 import java.util.regex.Pattern;
 
@@ -212,7 +216,7 @@ public class CamelSalesforceMojo extends AbstractMojo {
             final ObjectMapper mapper = new ObjectMapper();
 
             // call getGlobalObjects to get all SObjects
-            final Set<String> objectNames = new HashSet<String>();
+            final Set<String> objectNames = new TreeSet<String>();
             final SyncResponseCallback callback = new SyncResponseCallback();
             try {
                 getLog().info("Getting Salesforce Objects...");
@@ -307,23 +311,23 @@ public class CamelSalesforceMojo extends AbstractMojo {
             // 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));
+            getLog().info("Retrieving Object descriptions...");
+            for (String name : objectNames) {
+                try {
+                        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 for '" + name + "': " + e.getMessage();
+                    throw new MojoExecutionException(msg, e);
                 }
-            } catch (Exception e) {
-                String msg = "Error getting SObject description " + e.getMessage();
-                throw new MojoExecutionException(msg, e);
             }
 
             // create package directory
@@ -494,6 +498,7 @@ public class CamelSalesforceMojo extends AbstractMojo {
                 {"duration", "javax.xml.datatype.Duration"},
                 {"NOTATION", "javax.xml.namespace.QName"}
 */
+                {"address", "String"}
             };
             LOOKUP_MAP = new HashMap<String, String>();
             for (String[] entry : typeMap) {
@@ -556,9 +561,27 @@ public class CamelSalesforceMojo extends AbstractMojo {
             return false;
         }
 
-        public PickListValue getLastEntry(SObjectField field) {
-            final List<PickListValue> values = field.getPicklistValues();
-            return values.get(values.size() - 1);
+        public List<PickListValue> getUniqueValues(SObjectField field) {
+            if (field.getPicklistValues().isEmpty()) {
+                return field.getPicklistValues();
+            }
+            final List<PickListValue> result = new ArrayList<PickListValue>();
+            final Set<String> literals = new HashSet<String>();
+            for (PickListValue listValue : field.getPicklistValues()) {
+                final String value = listValue.getValue();
+                if (!literals.contains(value)) {
+                    literals.add(value);
+                    result.add(listValue);
+                }
+            }
+            literals.clear();
+            Collections.sort(result, new Comparator<PickListValue>() {
+                @Override
+                public int compare(PickListValue o1, PickListValue o2) {
+                    return o1.getValue().compareTo(o2.getValue());
+                }
+            });
+            return result;
         }
 
         public boolean isPicklist(SObjectField field) {

http://git-wip-us.apache.org/repos/asf/camel/blob/2dc15fa0/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
index 8e23fdb..bb3a22f 100644
--- 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
@@ -29,18 +29,18 @@ import org.codehaus.jackson.annotate.JsonValue;
  * Salesforce Enumeration DTO for picklist $field.Name
  */
 public enum $enumName {
-## find the last entry
-#set ( $lastEntry = $utility.getLastEntry($field) )
+#set ( $values = $utility.getUniqueValues($field) )
 
-#foreach ( $entry in $field.PicklistValues)
-#set ( $value = $entry.Value )
-#if ( $entry == $lastEntry )
-#set ( $delim = ";" )
+## handle empty picklists
+#if ( $values.isEmpty() )
+    ; // empty picklist!
 #else
-#set ( $delim = ",")
-#end
+#foreach ( $entry in $values)
+#set ( $value = $entry.Value )
     // $value
-    $utility.getEnumConstant($value)("$value")$delim
+    $utility.getEnumConstant($value)("$value")#if ( $foreach.hasNext ),#else;#end
+
+#end
 #end
 
     final String value;


[12/17] camel git commit: CAMEL-8269: added support for APEX REST calls, also updated Salesforce API version to 33.0

Posted by dh...@apache.org.
CAMEL-8269: added support for APEX REST calls, also updated Salesforce API version to 33.0


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

Branch: refs/heads/camel-2.12.x
Commit: 65cd95c5ec6c531a58621dd206d69a35532045c9
Parents: 2dc15fa
Author: Dhiraj Bokde <dh...@yahoo.com>
Authored: Mon Feb 23 13:38:37 2015 -0800
Committer: Dhiraj Bokde <dh...@yahoo.com>
Committed: Fri Mar 20 14:24:45 2015 -0700

----------------------------------------------------------------------
 .../MerchandiseRestResource.apxc                |  44 +++++
 .../salesforce/SalesforceComponent.java         |  21 ++
 .../salesforce/SalesforceEndpointConfig.java    |  80 +++++++-
 .../salesforce/api/dto/AbstractSObjectBase.java |  22 +++
 .../salesforce/api/dto/ActionOverride.java      |  75 ++++++++
 .../api/dto/ActionOverrideTypeEnum.java         |  57 ++++++
 .../salesforce/api/dto/ChildRelationShip.java   |  20 ++
 .../salesforce/api/dto/FilteredLookupInfo.java  |  48 +++++
 .../component/salesforce/api/dto/InfoUrls.java  |  30 +++
 .../salesforce/api/dto/NamedLayoutInfo.java     |  39 ++++
 .../salesforce/api/dto/RecordTypeInfo.java      |   9 +
 .../salesforce/api/dto/RestResources.java       |  99 ++++++++++
 .../component/salesforce/api/dto/SObject.java   |   8 +
 .../salesforce/api/dto/SObjectDescription.java  |  20 ++
 .../salesforce/api/dto/SObjectField.java        |  63 ++++++
 .../salesforce/api/dto/SObjectUrls.java         |  81 ++++++++
 .../salesforce/internal/OperationName.java      |   1 +
 .../internal/client/DefaultRestClient.java      |  60 +++++-
 .../salesforce/internal/client/RestClient.java  |  13 ++
 .../internal/dto/NotifyForFieldsEnum.java       |  10 +-
 .../internal/dto/NotifyForOperationsEnum.java   |  10 +-
 .../salesforce/internal/dto/PushTopic.java      |  49 ++++-
 .../processor/AbstractRestProcessor.java        | 190 +++++++++++++++----
 .../internal/processor/JsonRestProcessor.java   |  10 +-
 .../internal/processor/XmlRestProcessor.java    |  17 +-
 .../internal/streaming/PushTopicHelper.java     |  74 ++++++--
 .../salesforce/RestApiIntegrationTest.java      | 113 +++++++++++
 .../salesforce/StreamingApiIntegrationTest.java |   4 +-
 .../salesforce/dto/generated/Document.java      |  26 ++-
 .../src/test/resources/log4j.properties         |   1 +
 30 files changed, 1194 insertions(+), 100 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/components/camel-salesforce/camel-salesforce-component/MerchandiseRestResource.apxc
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/MerchandiseRestResource.apxc b/components/camel-salesforce/camel-salesforce-component/MerchandiseRestResource.apxc
new file mode 100644
index 0000000..91ce5ce
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/MerchandiseRestResource.apxc
@@ -0,0 +1,44 @@
+@RestResource(urlMapping='/Merchandise/*')
+global with sharing class MerchandiseRestResource {
+
+    @HttpGet
+    global static Merchandise__c doGet() {
+        RestRequest req = RestContext.request;
+        String merchandiseId = null;
+        if (!req.requestURI.endsWith('/')) {
+            merchandiseId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);
+        } else if (req.params.get('id') != null) {
+            merchandiseId = req.params.get('id');
+        }
+        if (merchandiseId != null) {
+	        Merchandise__c merchandise = [SELECT Id, Name, Description__c, Price__c, Total_Inventory__c FROM Merchandise__c WHERE Id = :merchandiseId];
+            return merchandise;
+        } else {
+            throw new InvalidParamException('Missing merchandise id in URL and query params');
+        }
+    }
+  
+	@HttpPatch
+	global static Merchandise__c doPatch(Merchandise__c merchandise) {
+        // lookup merchandise
+        Merchandise__c current = [SELECT Id, Name, Description__c, Price__c, Total_Inventory__c FROM Merchandise__c WHERE Id = :merchandise.Id];
+        if (current == null) {
+            throw new InvalidParamException('Missing merchandise for id ' + merchandise.Id);
+        }
+        if (merchandise.Description__c != null) {
+            current.Description__c = merchandise.Description__c;
+        }
+        if (merchandise.Price__c != null) {
+            current.Price__c = merchandise.Price__c;
+        }
+        if (merchandise.Total_Inventory__c != null) {
+            current.Total_Inventory__c = merchandise.Total_Inventory__c;
+        }
+
+        update current;
+        return current;
+    }
+
+	// Invalid Merchandise Id exception
+    public class InvalidParamException extends Exception {}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/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 8a38bec..c12edc2 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
@@ -59,6 +59,7 @@ public class SalesforceComponent extends UriEndpointComponent implements Endpoin
     private static final int CONNECTION_TIMEOUT = 60000;
     private static final int RESPONSE_TIMEOUT = 60000;
     private static final Pattern SOBJECT_NAME_PATTERN = Pattern.compile("^.*[\\?&]sObjectName=([^&,]+).*$");
+    private static final String APEX_CALL_PREFIX = OperationName.APEX_CALL.value() + "/";
 
     private SalesforceLoginConfig loginConfig;
     private SalesforceEndpointConfig config;
@@ -86,8 +87,14 @@ public class SalesforceComponent extends UriEndpointComponent implements Endpoin
         // get Operation from remaining URI
         OperationName operationName = null;
         String topicName = null;
+        String apexUrl = null;
         try {
             LOG.debug("Creating endpoint for: {}", remaining);
+            if (remaining.startsWith(APEX_CALL_PREFIX)) {
+                // extract APEX URL
+                apexUrl = remaining.substring(APEX_CALL_PREFIX.length());
+                remaining = OperationName.APEX_CALL.value();
+            }
             operationName = OperationName.fromValue(remaining);
         } catch (IllegalArgumentException ex) {
             // if its not an operation name, treat is as topic name for consumer endpoints
@@ -107,12 +114,26 @@ public class SalesforceComponent extends UriEndpointComponent implements Endpoin
         final SalesforceEndpointConfig copy = config.copy();
         setProperties(copy, parameters);
 
+        // set apexUrl in endpoint config
+        if (apexUrl != null) {
+            copy.setApexUrl(apexUrl);
+        }
+
         final SalesforceEndpoint endpoint = new SalesforceEndpoint(uri, this, copy,
                 operationName, topicName);
 
         // map remaining parameters to endpoint (specifically, synchronous)
         setProperties(endpoint, parameters);
 
+        // if operation is APEX call, map remaining parameters to query params
+        if (operationName == OperationName.APEX_CALL && !parameters.isEmpty()) {
+            Map<String, Object> queryParams = new HashMap<String, Object>(parameters);
+            parameters.clear();
+
+            queryParams.putAll(copy.getApexQueryParams());
+            copy.setApexQueryParams(queryParams);
+        }
+
         return endpoint;
     }
 

http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/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 353ed30..9af05b9 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
@@ -36,7 +36,7 @@ import org.eclipse.jetty.client.HttpClient;
 public class SalesforceEndpointConfig implements Cloneable {
 
     // default API version
-    public static final String DEFAULT_VERSION = "27.0";
+    public static final String DEFAULT_VERSION = "33.0";
 
     // general parameter
     public static final String API_VERSION = "apiVersion";
@@ -52,6 +52,11 @@ public class SalesforceEndpointConfig implements Cloneable {
     public static final String SOBJECT_CLASS = "sObjectClass";
     public static final String SOBJECT_QUERY = "sObjectQuery";
     public static final String SOBJECT_SEARCH = "sObjectSearch";
+    public static final String APEX_METHOD = "apexMethod";
+    public static final String APEX_URL = "apexUrl";
+
+    // prefix for parameters in headers
+    public static final String APEX_QUERY_PARAM_PREFIX = "apexQueryParam.";
 
     // parameters for Bulk API
     public static final String CONTENT_TYPE = "contentType";
@@ -84,6 +89,12 @@ public class SalesforceEndpointConfig implements Cloneable {
     private String sObjectQuery;
     @UriParam
     private String sObjectSearch;
+    @UriParam
+    private String apexMethod;
+    @UriParam
+    private String apexUrl;
+    @UriParam
+    private Map<String, Object> apexQueryParams;
 
     // Bulk API properties
     @UriParam
@@ -102,6 +113,14 @@ public class SalesforceEndpointConfig implements Cloneable {
     private NotifyForFieldsEnum notifyForFields;
     @UriParam
     private NotifyForOperationsEnum notifyForOperations;
+    @UriParam
+    private Boolean notifyForOperationCreate;
+    @UriParam
+    private Boolean notifyForOperationUpdate;
+    @UriParam
+    private Boolean notifyForOperationDelete;
+    @UriParam
+    private Boolean notifyForOperationUndelete;
 
     // Jetty HttpClient, set using reference
     @UriParam
@@ -205,6 +224,30 @@ public class SalesforceEndpointConfig implements Cloneable {
         this.sObjectSearch = sObjectSearch;
     }
 
+    public String getApexMethod() {
+        return apexMethod;
+    }
+
+    public void setApexMethod(String apexMethod) {
+        this.apexMethod = apexMethod;
+    }
+
+    public String getApexUrl() {
+        return apexUrl;
+    }
+
+    public void setApexUrl(String apexUrl) {
+        this.apexUrl = apexUrl;
+    }
+
+    public Map<String, Object> getApexQueryParams() {
+        return apexQueryParams == null ? Collections.EMPTY_MAP : Collections.unmodifiableMap(apexQueryParams);
+    }
+
+    public void setApexQueryParams(Map<String, Object> apexQueryParams) {
+        this.apexQueryParams = apexQueryParams;
+    }
+
     public ContentType getContentType() {
         return contentType;
     }
@@ -261,6 +304,38 @@ public class SalesforceEndpointConfig implements Cloneable {
         this.notifyForOperations = notifyForOperations;
     }
 
+    public Boolean getNotifyForOperationCreate() {
+        return notifyForOperationCreate;
+    }
+
+    public void setNotifyForOperationCreate(Boolean notifyForOperationCreate) {
+        this.notifyForOperationCreate = notifyForOperationCreate;
+    }
+
+    public Boolean getNotifyForOperationUpdate() {
+        return notifyForOperationUpdate;
+    }
+
+    public void setNotifyForOperationUpdate(Boolean notifyForOperationUpdate) {
+        this.notifyForOperationUpdate = notifyForOperationUpdate;
+    }
+
+    public Boolean getNotifyForOperationDelete() {
+        return notifyForOperationDelete;
+    }
+
+    public void setNotifyForOperationDelete(Boolean notifyForOperationDelete) {
+        this.notifyForOperationDelete = notifyForOperationDelete;
+    }
+
+    public Boolean getNotifyForOperationUndelete() {
+        return notifyForOperationUndelete;
+    }
+
+    public void setNotifyForOperationUndelete(Boolean notifyForOperationUndelete) {
+        this.notifyForOperationUndelete = notifyForOperationUndelete;
+    }
+
     public void setHttpClient(HttpClient httpClient) {
         this.httpClient = httpClient;
     }
@@ -284,6 +359,9 @@ public class SalesforceEndpointConfig implements Cloneable {
         valueMap.put(SOBJECT_CLASS, sObjectClass);
         valueMap.put(SOBJECT_QUERY, sObjectQuery);
         valueMap.put(SOBJECT_SEARCH, sObjectSearch);
+        valueMap.put(APEX_METHOD, apexMethod);
+        valueMap.put(APEX_URL, apexUrl);
+        // apexQueryParams are handled explicitly in AbstractRestProcessor
 
         // add bulk API properties
         if (contentType != null) {

http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/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
index fa20827..7337a52 100644
--- 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
@@ -35,6 +35,8 @@ public class AbstractSObjectBase extends AbstractDTOBase {
     private String LastModifiedById;
     private DateTime SystemModstamp;
     private String LastActivityDate;
+    private DateTime LastViewedDate;
+    private DateTime LastReferencedDate;
 
     /**
      * Utility method to clear all system {@link AbstractSObjectBase} fields.
@@ -161,5 +163,25 @@ public class AbstractSObjectBase extends AbstractDTOBase {
     public void setLastActivityDate(String lastActivityDate) {
         this.LastActivityDate = lastActivityDate;
     }
+
+    @JsonProperty("LastViewedDate")
+    public DateTime getLastViewedDate() {
+        return LastViewedDate;
+    }
+
+    @JsonProperty("LastViewedDate")
+    public void setLastViewedDate(DateTime lastViewedDate) {
+        LastViewedDate = lastViewedDate;
+    }
+
+    @JsonProperty("LastReferencedDate")
+    public DateTime getLastReferencedDate() {
+        return LastReferencedDate;
+    }
+
+    @JsonProperty("LastReferencedDate")
+    public void setLastReferencedDate(DateTime lastReferencedDate) {
+        LastReferencedDate = lastReferencedDate;
+    }
 }
 //CHECKSTYLE:ON

http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/ActionOverride.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/ActionOverride.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/ActionOverride.java
new file mode 100644
index 0000000..eff26df
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/ActionOverride.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;
+
+import com.thoughtworks.xstream.annotations.XStreamConverter;
+
+import org.apache.camel.component.salesforce.api.PicklistEnumConverter;
+
+public class ActionOverride extends AbstractDTOBase {
+
+    private String actionName;
+
+    private String comment;
+
+    private String content;
+
+    private Boolean skipRecordTypeSelect;
+
+    @XStreamConverter(PicklistEnumConverter.class)
+    private ActionOverrideTypeEnum type;
+
+    public String getActionName() {
+        return actionName;
+    }
+
+    public void setActionName(String actionName) {
+        this.actionName = actionName;
+    }
+
+    public String getComment() {
+        return comment;
+    }
+
+    public void setComment(String comment) {
+        this.comment = comment;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public Boolean getSkipRecordTypeSelect() {
+        return skipRecordTypeSelect;
+    }
+
+    public void setSkipRecordTypeSelect(Boolean skipRecordTypeSelect) {
+        this.skipRecordTypeSelect = skipRecordTypeSelect;
+    }
+
+    public ActionOverrideTypeEnum getType() {
+        return type;
+    }
+
+    public void setType(ActionOverrideTypeEnum type) {
+        this.type = type;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/ActionOverrideTypeEnum.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/ActionOverrideTypeEnum.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/ActionOverrideTypeEnum.java
new file mode 100644
index 0000000..967b0a8
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/ActionOverrideTypeEnum.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 org.codehaus.jackson.annotate.JsonCreator;
+import org.codehaus.jackson.annotate.JsonValue;
+import org.codehaus.jackson.map.annotate.JsonDeserialize;
+
+@JsonDeserialize
+public enum ActionOverrideTypeEnum {
+
+    // The override uses a custom override provided by an installed package.
+    // If there isn’t one available, the standard Salesforce behavior is used.
+    DEFAULT("default"),
+    // The override uses behavior from an s-control.
+    SCONTROL("scontrol"),
+    // The override uses regular Salesforce behavior.
+    STANDARD("standard"),
+    // The override uses behavior from a Visualforce page.
+    VISUALFORCE("visualforce");
+
+    final String value;
+
+    private ActionOverrideTypeEnum(String value) {
+        this.value = value;
+    }
+
+    @JsonValue
+    public String value() {
+        return this.value;
+    }
+
+    @JsonCreator
+    public static ActionOverrideTypeEnum fromValue(String value) {
+        for (ActionOverrideTypeEnum e : ActionOverrideTypeEnum.values()) {
+            if (e.value.equals(value)) {
+                return e;
+            }
+        }
+        throw new IllegalArgumentException(value);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/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
index 9b89923..7a674e7 100644
--- 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
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.component.salesforce.api.dto;
 
+import java.util.List;
+
 public class ChildRelationShip extends AbstractDTOBase {
 
     private String field;
@@ -24,6 +26,8 @@ public class ChildRelationShip extends AbstractDTOBase {
     private Boolean cascadeDelete;
     private Boolean restrictedDelete;
     private String childSObject;
+    private String junctionIdListName;
+    private List<String> junctionReferenceTo;
 
     public String getField() {
         return field;
@@ -72,4 +76,20 @@ public class ChildRelationShip extends AbstractDTOBase {
     public void setChildSObject(String childSObject) {
         this.childSObject = childSObject;
     }
+
+    public String getJunctionIdListName() {
+        return junctionIdListName;
+    }
+
+    public void setJunctionIdListName(String junctionIdListName) {
+        this.junctionIdListName = junctionIdListName;
+    }
+
+    public List<String> getJunctionReferenceTo() {
+        return junctionReferenceTo;
+    }
+
+    public void setJunctionReferenceTo(List<String> junctionReferenceTo) {
+        this.junctionReferenceTo = junctionReferenceTo;
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/FilteredLookupInfo.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/FilteredLookupInfo.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/FilteredLookupInfo.java
new file mode 100644
index 0000000..182efd6
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/FilteredLookupInfo.java
@@ -0,0 +1,48 @@
+/**
+ * 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 FilteredLookupInfo extends AbstractDTOBase {
+
+    private String controllingFields;
+    private Boolean dependent;
+    private Boolean optionalFilter;
+
+    public String getControllingFields() {
+        return controllingFields;
+    }
+
+    public void setControllingFields(String controllingFields) {
+        this.controllingFields = controllingFields;
+    }
+
+    public Boolean getDependent() {
+        return dependent;
+    }
+
+    public void setDependent(Boolean dependent) {
+        this.dependent = dependent;
+    }
+
+    public Boolean getOptionalFilter() {
+        return optionalFilter;
+    }
+
+    public void setOptionalFilter(Boolean optionalFilter) {
+        this.optionalFilter = optionalFilter;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/InfoUrls.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/InfoUrls.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/InfoUrls.java
new file mode 100644
index 0000000..51da519
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/InfoUrls.java
@@ -0,0 +1,30 @@
+/**
+ * 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 InfoUrls extends AbstractDTOBase {
+
+    private String layout;
+
+    public String getLayout() {
+        return layout;
+    }
+
+    public void setLayout(String layout) {
+        this.layout = layout;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/NamedLayoutInfo.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/NamedLayoutInfo.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/NamedLayoutInfo.java
new file mode 100644
index 0000000..7dc1d00
--- /dev/null
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/api/dto/NamedLayoutInfo.java
@@ -0,0 +1,39 @@
+/**
+ * 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 NamedLayoutInfo extends AbstractDTOBase {
+
+    private String name;
+    private InfoUrls urls;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public InfoUrls getUrls() {
+        return urls;
+    }
+
+    public void setUrls(InfoUrls urls) {
+        this.urls = urls;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/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
index 392ddb4..92eda59 100644
--- 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
@@ -22,6 +22,7 @@ public class RecordTypeInfo extends AbstractDTOBase {
     private Boolean available;
     private String recordTypeId;
     private Boolean defaultRecordTypeMapping;
+    private InfoUrls urls;
 
     public String getName() {
         return name;
@@ -54,4 +55,12 @@ public class RecordTypeInfo extends AbstractDTOBase {
     public void setDefaultRecordTypeMapping(Boolean defaultRecordTypeMapping) {
         this.defaultRecordTypeMapping = defaultRecordTypeMapping;
     }
+
+    public InfoUrls getUrls() {
+        return urls;
+    }
+
+    public void setUrls(InfoUrls urls) {
+        this.urls = urls;
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/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
index ce108b1..b37aa13 100644
--- 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
@@ -34,6 +34,17 @@ public class RestResources extends AbstractDTOBase {
     private String tooling;
     private String licensing;
     private String analytics;
+    private String limits;
+    private String theme;
+    private String queryAll;
+    private String knowledgeManagement;
+    private String process;
+    private String flexiPage;
+    private String quickActions;
+    private String appMenu;
+    private String compactLayouts;
+    private String actions;
+    private String tabs;
 
     public String getSobjects() {
         return sobjects;
@@ -114,4 +125,92 @@ public class RestResources extends AbstractDTOBase {
     public void setAnalytics(String analytics) {
         this.analytics = analytics;
     }
+
+    public String getLimits() {
+        return limits;
+    }
+
+    public void setLimits(String limits) {
+        this.limits = limits;
+    }
+
+    public String getTheme() {
+        return theme;
+    }
+
+    public void setTheme(String theme) {
+        this.theme = theme;
+    }
+
+    public String getQueryAll() {
+        return queryAll;
+    }
+
+    public void setQueryAll(String queryAll) {
+        this.queryAll = queryAll;
+    }
+
+    public String getKnowledgeManagement() {
+        return knowledgeManagement;
+    }
+
+    public void setKnowledgeManagement(String knowledgeManagement) {
+        this.knowledgeManagement = knowledgeManagement;
+    }
+
+    public String getProcess() {
+        return process;
+    }
+
+    public void setProcess(String process) {
+        this.process = process;
+    }
+
+    public String getFlexiPage() {
+        return flexiPage;
+    }
+
+    public void setFlexiPage(String flexiPage) {
+        this.flexiPage = flexiPage;
+    }
+
+    public String getQuickActions() {
+        return quickActions;
+    }
+
+    public void setQuickActions(String quickActions) {
+        this.quickActions = quickActions;
+    }
+
+    public String getAppMenu() {
+        return appMenu;
+    }
+
+    public void setAppMenu(String appMenu) {
+        this.appMenu = appMenu;
+    }
+
+    public String getCompactLayouts() {
+        return compactLayouts;
+    }
+
+    public void setCompactLayouts(String compactLayouts) {
+        this.compactLayouts = compactLayouts;
+    }
+
+    public String getActions() {
+        return actions;
+    }
+
+    public void setActions(String actions) {
+        this.actions = actions;
+    }
+
+    public String getTabs() {
+        return tabs;
+    }
+
+    public void setTabs(String tabs) {
+        this.tabs = tabs;
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/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
index 97fa39d..d390595 100644
--- 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
@@ -42,6 +42,7 @@ public class SObject extends AbstractDTOBase {
     private String searchLayoutable;
     private Boolean undeletable;
     private Boolean triggerable;
+    private Boolean compactLayoutable;
 
     public String getName() {
         return name;
@@ -235,4 +236,11 @@ public class SObject extends AbstractDTOBase {
         this.triggerable = triggerable;
     }
 
+    public Boolean getCompactLayoutable() {
+        return compactLayoutable;
+    }
+
+    public void setCompactLayoutable(Boolean compactLayoutable) {
+        this.compactLayoutable = compactLayoutable;
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/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 9096c1e..4fb5a29 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
@@ -23,12 +23,24 @@ import com.thoughtworks.xstream.annotations.XStreamImplicit;
 public class SObjectDescription extends SObject {
 
     @XStreamImplicit
+    private List<ActionOverride> actionOverrides;
+    @XStreamImplicit
     private List<SObjectField> fields;
     private SObjectDescriptionUrls urls;
     @XStreamImplicit
     private List<ChildRelationShip> childRelationships;
     @XStreamImplicit
     private List<RecordTypeInfo> recordTypeInfos;
+    @XStreamImplicit
+    private List<NamedLayoutInfo> namedLayoutInfos;
+
+    public List<ActionOverride> getActionOverrides() {
+        return actionOverrides;
+    }
+
+    public void setActionOverrides(List<ActionOverride> actionOverrides) {
+        this.actionOverrides = actionOverrides;
+    }
 
     public List<SObjectField> getFields() {
         return fields;
@@ -61,4 +73,12 @@ public class SObjectDescription extends SObject {
     public void setRecordTypeInfos(List<RecordTypeInfo> recordTypeInfos) {
         this.recordTypeInfos = recordTypeInfos;
     }
+
+    public List<NamedLayoutInfo> getNamedLayoutInfos() {
+        return namedLayoutInfos;
+    }
+
+    public void setNamedLayoutInfos(List<NamedLayoutInfo> namedLayoutInfos) {
+        this.namedLayoutInfos = namedLayoutInfos;
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/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 8664c19..312e6c3 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
@@ -67,6 +67,13 @@ public class SObjectField extends AbstractDTOBase {
     private Boolean groupable;
     private Boolean permissionable;
     private Boolean displayLocationInDecimal;
+    private String extraTypeInfo;
+    private FilteredLookupInfo filteredLookupInfo;
+    private Boolean highScaleNumber;
+    private String mask;
+    private String maskType;
+    private Boolean queryByDistance;
+    private String referenceTargetField;
 
     public Integer getLength() {
         return length;
@@ -411,4 +418,60 @@ public class SObjectField extends AbstractDTOBase {
     public void setDisplayLocationInDecimal(Boolean displayLocationInDecimal) {
         this.displayLocationInDecimal = displayLocationInDecimal;
     }
+
+    public String getExtraTypeInfo() {
+        return extraTypeInfo;
+    }
+
+    public void setExtraTypeInfo(String extraTypeInfo) {
+        this.extraTypeInfo = extraTypeInfo;
+    }
+
+    public FilteredLookupInfo getFilteredLookupInfo() {
+        return filteredLookupInfo;
+    }
+
+    public void setFilteredLookupInfo(FilteredLookupInfo filteredLookupInfo) {
+        this.filteredLookupInfo = filteredLookupInfo;
+    }
+
+    public Boolean getHighScaleNumber() {
+        return highScaleNumber;
+    }
+
+    public void setHighScaleNumber(Boolean highScaleNumber) {
+        this.highScaleNumber = highScaleNumber;
+    }
+
+    public String getMask() {
+        return mask;
+    }
+
+    public void setMask(String mask) {
+        this.mask = mask;
+    }
+
+    public String getMaskType() {
+        return maskType;
+    }
+
+    public void setMaskType(String maskType) {
+        this.maskType = maskType;
+    }
+
+    public Boolean getQueryByDistance() {
+        return queryByDistance;
+    }
+
+    public void setQueryByDistance(Boolean queryByDistance) {
+        this.queryByDistance = queryByDistance;
+    }
+
+    public String getReferenceTargetField() {
+        return referenceTargetField;
+    }
+
+    public void setReferenceTargetField(String referenceTargetField) {
+        this.referenceTargetField = referenceTargetField;
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/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
index b1abd74..85115d1 100644
--- 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
@@ -22,6 +22,15 @@ public class SObjectUrls extends AbstractDTOBase {
     private String describe;
     private String rowTemplate;
     private String passwordUtilities;
+    private String approvalLayouts;
+    private String quickActions;
+    private String caseArticleSuggestions;
+    private String listviews;
+    private String layouts;
+    private String namedLayouts;
+    private String compactLayouts;
+    private String caseRowArticleSuggestions;
+    private String push;
 
     public String getSobject() {
         return sobject;
@@ -54,4 +63,76 @@ public class SObjectUrls extends AbstractDTOBase {
     public void setPasswordUtilities(String passwordUtilities) {
         this.passwordUtilities = passwordUtilities;
     }
+
+    public String getApprovalLayouts() {
+        return approvalLayouts;
+    }
+
+    public void setApprovalLayouts(String approvalLayouts) {
+        this.approvalLayouts = approvalLayouts;
+    }
+
+    public String getQuickActions() {
+        return quickActions;
+    }
+
+    public void setQuickActions(String quickActions) {
+        this.quickActions = quickActions;
+    }
+
+    public String getCaseArticleSuggestions() {
+        return caseArticleSuggestions;
+    }
+
+    public void setCaseArticleSuggestions(String caseArticleSuggestions) {
+        this.caseArticleSuggestions = caseArticleSuggestions;
+    }
+
+    public String getListviews() {
+        return listviews;
+    }
+
+    public void setListviews(String listviews) {
+        this.listviews = listviews;
+    }
+
+    public String getLayouts() {
+        return layouts;
+    }
+
+    public void setLayouts(String layouts) {
+        this.layouts = layouts;
+    }
+
+    public String getNamedLayouts() {
+        return namedLayouts;
+    }
+
+    public void setNamedLayouts(String namedLayouts) {
+        this.namedLayouts = namedLayouts;
+    }
+
+    public String getCompactLayouts() {
+        return compactLayouts;
+    }
+
+    public void setCompactLayouts(String compactLayouts) {
+        this.compactLayouts = compactLayouts;
+    }
+
+    public String getCaseRowArticleSuggestions() {
+        return caseRowArticleSuggestions;
+    }
+
+    public void setCaseRowArticleSuggestions(String caseRowArticleSuggestions) {
+        this.caseRowArticleSuggestions = caseRowArticleSuggestions;
+    }
+
+    public String getPush() {
+        return push;
+    }
+
+    public void setPush(String push) {
+        this.push = push;
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/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
index 50141f1..a5b7893 100644
--- 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
@@ -35,6 +35,7 @@ public enum OperationName {
     QUERY("query"),
     QUERY_MORE("queryMore"),
     SEARCH("search"),
+    APEX_CALL("apexCall"),
 
     // bulk API
     CREATE_JOB("createJob"),

http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/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 1edfed7..0b06289 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
@@ -19,8 +19,10 @@ package org.apache.camel.component.salesforce.internal.client;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
+import java.net.URISyntaxException;
 import java.net.URLEncoder;
 import java.util.List;
+import java.util.Map;
 
 import com.thoughtworks.xstream.XStream;
 import org.apache.camel.component.salesforce.api.SalesforceException;
@@ -28,6 +30,7 @@ import org.apache.camel.component.salesforce.api.dto.RestError;
 import org.apache.camel.component.salesforce.internal.PayloadFormat;
 import org.apache.camel.component.salesforce.internal.SalesforceSession;
 import org.apache.camel.component.salesforce.internal.dto.RestErrors;
+import org.apache.camel.util.URISupport;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.codehaus.jackson.type.TypeReference;
 import org.eclipse.jetty.client.ContentExchange;
@@ -42,6 +45,7 @@ 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 static final String SERVICES_APEXREST = "/services/apexrest/";
 
     protected PayloadFormat format;
     private ObjectMapper objectMapper;
@@ -267,9 +271,7 @@ public class DefaultRestClient extends AbstractClientBase implements RestClient
     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");
+            String encodedQuery = urlEncode(soqlQuery);
             final ContentExchange get = getContentExchange(HttpMethods.GET, versionUrl() + "query/?q=" + encodedQuery);
 
             // requires authorization token
@@ -297,9 +299,7 @@ public class DefaultRestClient extends AbstractClientBase implements RestClient
     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");
+            String encodedQuery = urlEncode(soslQuery);
             final ContentExchange get = getContentExchange(HttpMethods.GET, versionUrl() + "search/?q=" + encodedQuery);
 
             // requires authorization token
@@ -313,6 +313,43 @@ public class DefaultRestClient extends AbstractClientBase implements RestClient
         }
     }
 
+    @Override
+    public void apexCall(String httpMethod, String apexUrl,
+                         Map<String, Object> queryParams, InputStream requestDto, ResponseCallback callback) {
+        // create APEX call exchange
+        final ContentExchange exchange;
+        try {
+            exchange = getContentExchange(httpMethod, apexCallUrl(apexUrl, queryParams));
+            // set request SObject and content type
+            if (requestDto != null) {
+                exchange.setRequestContentSource(requestDto);
+                exchange.setRequestContentType(
+                    PayloadFormat.JSON.equals(format) ? APPLICATION_JSON_UTF8 : APPLICATION_XML_UTF8);
+            }
+
+            // requires authorization token
+            setAccessToken(exchange);
+
+            doHttpRequest(exchange, new DelegatingClientCallback(callback));
+        } catch (UnsupportedEncodingException e) {
+            String msg = "Unexpected error: " + e.getMessage();
+            callback.onResponse(null, new SalesforceException(msg, e));
+        } catch (URISyntaxException e) {
+            String msg = "Unexpected error: " + e.getMessage();
+            callback.onResponse(null, new SalesforceException(msg, e));
+        }
+    }
+
+    private String apexCallUrl(String apexUrl, Map<String, Object> queryParams)
+        throws UnsupportedEncodingException, URISyntaxException {
+
+        if (queryParams != null && !queryParams.isEmpty()) {
+            apexUrl = URISupport.appendParametersToURI(apexUrl, queryParams);
+        }
+
+        return instanceUrl + SERVICES_APEXREST + apexUrl;
+    }
+
     private String servicesDataUrl() {
         return instanceUrl + SERVICES_DATA;
     }
@@ -336,9 +373,7 @@ public class DefaultRestClient extends AbstractClientBase implements RestClient
             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");
+            String encodedValue = urlEncode(fieldValue);
             return sobjectsUrl(sObjectName + "/" + fieldName + "/" + encodedValue);
         } catch (UnsupportedEncodingException e) {
             String msg = "Unexpected error: " + e.getMessage();
@@ -350,6 +385,13 @@ public class DefaultRestClient extends AbstractClientBase implements RestClient
         httpExchange.setRequestHeader(TOKEN_HEADER, TOKEN_PREFIX + accessToken);
     }
 
+    private String urlEncode(String query) throws UnsupportedEncodingException {
+        String encodedQuery = URLEncoder.encode(query, StringUtil.__UTF8_CHARSET.toString());
+        // URLEncoder likes to use '+' for spaces
+        encodedQuery = encodedQuery.replace("+", "%20");
+        return encodedQuery;
+    }
+
     private static class DelegatingClientCallback implements ClientResponseCallback {
         private final ResponseCallback callback;
 

http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/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 a28f8b8..5747976 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
@@ -17,6 +17,7 @@
 package org.apache.camel.component.salesforce.internal.client;
 
 import java.io.InputStream;
+import java.util.Map;
 
 import org.apache.camel.component.salesforce.api.SalesforceException;
 
@@ -173,4 +174,16 @@ public interface RestClient {
      */
     void search(String soslQuery, ResponseCallback callback);
 
+    /**
+     * Executes a user defined APEX REST API call.
+     *
+     * @param httpMethod    HTTP method to execute.
+     * @param apexUrl       APEX api url.
+     * @param queryParams   optional query parameters for GET methods, may be empty.
+     * @param requestDto    optional input DTO for POST, etc. may be null.
+     * @param callback      {@link ResponseCallback} to handle response or exception
+     */
+    void apexCall(String httpMethod, String apexUrl, Map<String, Object> queryParams, InputStream requestDto,
+                  ResponseCallback callback);
+
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/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
index 970b9aa..0385be3 100644
--- 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
@@ -24,10 +24,14 @@ import org.codehaus.jackson.annotate.JsonValue;
  */
 public enum NotifyForFieldsEnum {
 
-    SELECT("Select"),
-    WHERE("Where"),
+    // All
+    ALL("All"),
+    // Referenced
     REFERENCED("Referenced"),
-    ALL("All");
+    // Select
+    SELECT("Select"),
+    // Where
+    WHERE("Where");
 
     final String value;
 

http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/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
index f75839c..6ac2b87 100644
--- 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
@@ -24,10 +24,14 @@ import org.codehaus.jackson.annotate.JsonValue;
  */
 public enum NotifyForOperationsEnum {
 
-    CREATE("Create"),
-    UPDATE("Update"),
+    // All
     ALL("All"),
-    EXTENDED("Extended");
+    // Create
+    CREATE("Create"),
+    // Extended
+    EXTENDED("Extended"),
+    // Update
+    UPDATE("Update");
 
     final String value;
 

http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/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 17dbd98..4274dc1 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
@@ -47,6 +47,14 @@ public class PushTopic extends AbstractSObjectBase {
 
     private String Description;
 
+    private Boolean NotifyForOperationCreate;
+
+    private Boolean NotifyForOperationUpdate;
+
+    private Boolean NotifyForOperationDelete;
+
+    private Boolean NotifyForOperationUndelete;
+
     @JsonProperty("Query")
     public String getQuery() {
         return this.Query;
@@ -106,6 +114,45 @@ public class PushTopic extends AbstractSObjectBase {
     public void setDescription(String description) {
         this.Description = description;
     }
+
+    @JsonProperty("NotifyForOperationCreate")
+    public Boolean getNotifyForOperationCreate() {
+        return this.NotifyForOperationCreate;
+    }
+
+    @JsonProperty("NotifyForOperationCreate")
+    public void setNotifyForOperationCreate(Boolean notifyForOperationCreate) {
+        this.NotifyForOperationCreate = notifyForOperationCreate;
+    }
+
+    @JsonProperty("NotifyForOperationUpdate")
+    public Boolean getNotifyForOperationUpdate() {
+        return this.NotifyForOperationUpdate;
+    }
+
+    @JsonProperty("NotifyForOperationUpdate")
+    public void setNotifyForOperationUpdate(Boolean notifyForOperationUpdate) {
+        this.NotifyForOperationUpdate = notifyForOperationUpdate;
+    }
+
+    @JsonProperty("NotifyForOperationDelete")
+    public Boolean getNotifyForOperationDelete() {
+        return this.NotifyForOperationDelete;
+    }
+
+    @JsonProperty("NotifyForOperationDelete")
+    public void setNotifyForOperationDelete(Boolean notifyForOperationDelete) {
+        this.NotifyForOperationDelete = notifyForOperationDelete;
+    }
+
+    @JsonProperty("NotifyForOperationUndelete")
+    public Boolean getNotifyForOperationUndelete() {
+        return this.NotifyForOperationUndelete;
+    }
+
+    @JsonProperty("NotifyForOperationUndelete")
+    public void setNotifyForOperationUndelete(Boolean notifyForOperationUndelete) {
+        this.NotifyForOperationUndelete = notifyForOperationUndelete;
+    }
 }
 //CHECKSTYLE:ON
-

http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/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 661a896..834ea51 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
@@ -17,9 +17,14 @@
 package org.apache.camel.component.salesforce.internal.processor;
 
 import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.net.URLEncoder;
+import java.util.HashMap;
 import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.apache.camel.AsyncCallback;
 import org.apache.camel.Exchange;
@@ -30,12 +35,26 @@ 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 static org.apache.camel.component.salesforce.SalesforceEndpointConfig.*;
+import org.eclipse.jetty.http.HttpMethods;
+
+import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.APEX_METHOD;
+import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.APEX_QUERY_PARAM_PREFIX;
+import static org.apache.camel.component.salesforce.SalesforceEndpointConfig.APEX_URL;
+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 {
 
     protected static final String RESPONSE_CLASS = AbstractRestProcessor.class.getName() + ".responseClass";
+    private static final Pattern URL_TEMPLATE = Pattern.compile("\\{([^\\{\\}]+)\\}");
 
     private RestClient restClient;
     private Map<String, Class<?>> classMap;
@@ -128,6 +147,9 @@ public abstract class AbstractRestProcessor extends AbstractSalesforceProcessor
             case SEARCH:
                 processSearch(exchange, callback);
                 break;
+            case APEX_CALL:
+                processApexCall(exchange, callback);
+                break;
             default:
                 throw new SalesforceException("Unknow operation name: " + operationName, null);
             }
@@ -244,12 +266,12 @@ 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);
+                }
+            });
     }
 
     private void processUpdateSobject(final Exchange exchange, final AsyncCallback callback) throws SalesforceException {
@@ -270,13 +292,13 @@ 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);
+                }
+            });
     }
 
     private void processDeleteSobject(final Exchange exchange, final AsyncCallback callback) throws SalesforceException {
@@ -325,13 +347,13 @@ 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);
+                }
+            });
     }
 
     private void processUpsertSobject(final Exchange exchange, final AsyncCallback callback) throws SalesforceException {
@@ -357,12 +379,12 @@ public abstract class AbstractRestProcessor extends AbstractSalesforceProcessor
         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);
-                    }
-                });
+                @Override
+                public void onResponse(InputStream response, SalesforceException exception) {
+                    processResponse(exchange, response, exception, callback);
+                    restoreFields(exchange, sObjectBase, null, sObjectExtIdName, finalOldValue);
+                }
+            });
     }
 
     private void processDeleteSobjectWithId(final Exchange exchange, final AsyncCallback callback) throws SalesforceException {
@@ -384,13 +406,13 @@ 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);
+                }
+            });
     }
 
     private void processGetBlobField(final Exchange exchange, final AsyncCallback callback) throws SalesforceException {
@@ -412,13 +434,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);
+                }
+            });
     }
 
     private void processQuery(final Exchange exchange, final AsyncCallback callback) throws SalesforceException {
@@ -461,6 +483,90 @@ public abstract class AbstractRestProcessor extends AbstractSalesforceProcessor
         });
     }
 
+    private void processApexCall(final Exchange exchange, final AsyncCallback callback) throws SalesforceException {
+
+        // HTTP method, URL and query params for APEX call
+        final String apexUrl = getApexUrl(exchange);
+        String apexMethod = getParameter(APEX_METHOD, exchange, IGNORE_BODY, IS_OPTIONAL);
+        // default to GET
+        if (apexMethod == null) {
+            apexMethod = HttpMethods.GET;
+            log.debug("Using HTTP GET method by default for APEX REST call for {}", apexUrl);
+        }
+        final Map<String, Object> queryParams = getQueryParams(exchange);
+
+        // set response class
+        setResponseClass(exchange, getParameter(SOBJECT_NAME, exchange, IGNORE_BODY, IS_OPTIONAL));
+
+        // set request stream
+        final Object requestBody = exchange.getIn().getBody();
+        final InputStream requestDto =
+            (requestBody != null && !(requestBody instanceof Map)) ? getRequestStream(exchange) : null;
+
+        restClient.apexCall(apexMethod, apexUrl, queryParams, requestDto,
+            new RestClient.ResponseCallback() {
+                @Override
+                public void onResponse(InputStream response, SalesforceException exception) {
+                    processResponse(exchange, response, exception, callback);
+                }
+            });
+    }
+
+    private String getApexUrl(Exchange exchange) throws SalesforceException {
+        final String apexUrl = getParameter(APEX_URL, exchange, IGNORE_BODY, NOT_OPTIONAL);
+
+        final Matcher matcher = URL_TEMPLATE.matcher(apexUrl);
+        StringBuilder result = new StringBuilder();
+        int start = 0;
+        while (matcher.find()) {
+            // append part before parameter template
+            result.append(apexUrl.substring(start, matcher.start()));
+            start = matcher.end();
+
+            // append template value from exchange header
+            final String parameterName = matcher.group(1);
+            final Object value = exchange.getIn().getHeader(parameterName);
+            if (value == null) {
+                throw new IllegalArgumentException("Missing APEX URL template header " + parameterName);
+            }
+            try {
+                result.append(URLEncoder.encode(String.valueOf(value), "UTF-8").replaceAll("\\+", "%20"));
+            } catch (UnsupportedEncodingException e) {
+                throw new SalesforceException("Unexpected error: " + e.getMessage(), e);
+            }
+        }
+        if (start != 0) {
+            // append remaining URL
+            result.append(apexUrl.substring(start));
+            final String resolvedUrl = result.toString();
+            log.debug("Resolved APEX URL {} to {}", apexUrl, resolvedUrl);
+            return resolvedUrl;
+        }
+        return apexUrl;
+    }
+
+    @SuppressWarnings("unchecked")
+    private Map<String, Object> getQueryParams(Exchange exchange) {
+
+        // use endpoint map
+        Map<String, Object> queryParams = new HashMap<String, Object>(endpoint.getConfiguration().getApexQueryParams());
+
+        // look for individual properties, allowing endpoint properties to be overridden
+        for (Map.Entry<String, Object> entry : exchange.getIn().getHeaders().entrySet()) {
+            if (entry.getKey().startsWith(APEX_QUERY_PARAM_PREFIX)) {
+                queryParams.put(entry.getKey().substring(APEX_QUERY_PARAM_PREFIX.length()), entry.getValue());
+            }
+        }
+        // add params from body if it's a map
+        final Object body = exchange.getIn().getBody();
+        if (body instanceof Map) {
+            queryParams.putAll((Map<String, Object>) body);
+        }
+
+        log.debug("Using APEX query params {}", queryParams);
+        return queryParams;
+    }
+
     private void restoreFields(Exchange exchange, AbstractSObjectBase sObjectBase,
                                String sObjectId, String sObjectExtIdName, Object oldValue) {
         // restore fields

http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/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 b29f36b..f3c8b4d 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
@@ -27,7 +27,7 @@ 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.AbstractDTOBase;
 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;
@@ -113,11 +113,11 @@ public class JsonRestProcessor extends AbstractRestProcessor {
             Message in = exchange.getIn();
             request = in.getBody(InputStream.class);
             if (request == null) {
-                AbstractSObjectBase sObject = in.getBody(AbstractSObjectBase.class);
-                if (sObject != null) {
-                    // marshall the SObject
+                AbstractDTOBase dto = in.getBody(AbstractDTOBase.class);
+                if (dto != null) {
+                    // marshall the DTO
                     ByteArrayOutputStream out = new ByteArrayOutputStream();
-                    objectMapper.writeValue(out, sObject);
+                    objectMapper.writeValue(out, dto);
                     request = new ByteArrayInputStream(out.toByteArray());
                 } else {
                     // if all else fails, get body as String

http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/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 a10de93..f11bc2f 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
@@ -37,7 +37,7 @@ import org.apache.camel.Message;
 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.AbstractSObjectBase;
+import org.apache.camel.component.salesforce.api.dto.AbstractDTOBase;
 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;
@@ -144,6 +144,11 @@ public class XmlRestProcessor extends AbstractRestProcessor {
             exchange.setProperty(RESPONSE_CLASS, SearchResults.class);
             break;
 
+        case APEX_CALL:
+            // need to add alias for Salesforce XML that uses SObject name as root element
+            exchange.setProperty(RESPONSE_ALIAS, "response");
+            break;
+
         default:
             // ignore, some operations do not require alias or class exchange properties
         }
@@ -156,14 +161,14 @@ public class XmlRestProcessor extends AbstractRestProcessor {
             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
+                AbstractDTOBase dto = in.getBody(AbstractDTOBase.class);
+                if (dto != null) {
+                    // marshall the DTO
                     // first process annotations on the class, for things like alias, etc.
-                    localXStream.processAnnotations(sObject.getClass());
+                    localXStream.processAnnotations(dto.getClass());
                     ByteArrayOutputStream out = new ByteArrayOutputStream();
                     // make sure we write the XML with the right encoding
-                    localXStream.toXML(sObject, new OutputStreamWriter(out, StringUtil.__UTF8_CHARSET));
+                    localXStream.toXML(dto, new OutputStreamWriter(out, StringUtil.__UTF8_CHARSET));
                     request = new ByteArrayInputStream(out.toByteArray());
                 } else {
                     // if all else fails, get body as String

http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/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 4924aad..7423064 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
@@ -41,11 +41,28 @@ public class PushTopicHelper {
     private final SalesforceEndpointConfig config;
     private final String topicName;
     private final RestClient restClient;
+    private final boolean preApi29;
 
     public PushTopicHelper(SalesforceEndpointConfig config, String topicName, RestClient restClient) {
         this.config = config;
         this.topicName = topicName;
         this.restClient = restClient;
+        this.preApi29 = Double.valueOf(config.getApiVersion()) < 29.0;
+
+        // validate notify fields right away
+        if (preApi29 && (config.getNotifyForOperationCreate() != null
+                || config.getNotifyForOperationDelete() != null
+                || config.getNotifyForOperationUndelete() != null
+                || config.getNotifyForOperationUpdate() != null)) {
+            throw new IllegalArgumentException("NotifyForOperationCreate, NotifyForOperationDelete"
+                + ", NotifyForOperationUndelete, and NotifyForOperationUpdate"
+                + " are only supported since API version 29.0"
+                + ", instead use NotifyForOperations");
+        } else if (!preApi29 && config.getNotifyForOperations() != null) {
+            throw new IllegalArgumentException("NotifyForOperations is readonly since API version 29.0"
+                + ", instead use NotifyForOperationCreate, NotifyForOperationDelete"
+                + ", NotifyForOperationUndelete, and NotifyForOperationUpdate");
+        }
     }
 
     public void createOrUpdateTopic() throws CamelException {
@@ -63,8 +80,9 @@ public class PushTopicHelper {
             if (!callback.await(API_TIMEOUT, TimeUnit.SECONDS)) {
                 throw new SalesforceException("API call timeout!", null);
             }
-            if (callback.getException() != null) {
-                throw callback.getException();
+            final SalesforceException callbackException = callback.getException();
+            if (callbackException != null) {
+                throw callbackException;
             }
             QueryRecordsPushTopic records = OBJECT_MAPPER.readValue(callback.getResponse(),
                     QueryRecordsPushTopic.class);
@@ -73,13 +91,21 @@ public class PushTopicHelper {
                 PushTopic topic = records.getRecords().get(0);
                 LOG.info("Found existing topic {}: {}", topicName, topic);
 
-                // check if we need to update topic query, notifyForFields or notifyForOperations
+                // check if we need to update topic
+                final boolean notifyOperationsChanged;
+                if (preApi29) {
+                    notifyOperationsChanged =
+                        notEquals(config.getNotifyForOperations(), topic.getNotifyForOperations());
+                } else {
+                    notifyOperationsChanged =
+                        notEquals(config.getNotifyForOperationCreate(), topic.getNotifyForOperationCreate())
+                        || notEquals(config.getNotifyForOperationDelete(), topic.getNotifyForOperationDelete())
+                        || notEquals(config.getNotifyForOperationUndelete(), topic.getNotifyForOperationUndelete())
+                        || notEquals(config.getNotifyForOperationUpdate(), topic.getNotifyForOperationUpdate());
+                }
                 if (!query.equals(topic.getQuery())
-                        || (config.getNotifyForFields() != null
-                                && !config.getNotifyForFields().equals(topic.getNotifyForFields()))
-                        || (config.getNotifyForOperations() != null
-                                && !config.getNotifyForOperations().equals(topic.getNotifyForOperations()))
-                ) {
+                    || notEquals(config.getNotifyForFields(), topic.getNotifyForFields())
+                    || notifyOperationsChanged) {
 
                     if (!config.isUpdateTopic()) {
                         String msg = "Query doesn't match existing Topic and updateTopic is set to false";
@@ -126,7 +152,14 @@ public class PushTopicHelper {
         topic.setQuery(config.getSObjectQuery());
         topic.setDescription("Topic created by Camel Salesforce component");
         topic.setNotifyForFields(config.getNotifyForFields());
-        topic.setNotifyForOperations(config.getNotifyForOperations());
+        if (preApi29) {
+            topic.setNotifyForOperations(config.getNotifyForOperations());
+        } else {
+            topic.setNotifyForOperationCreate(config.getNotifyForOperationCreate());
+            topic.setNotifyForOperationDelete(config.getNotifyForOperationDelete());
+            topic.setNotifyForOperationUndelete(config.getNotifyForOperationUndelete());
+            topic.setNotifyForOperationUpdate(config.getNotifyForOperationUpdate());
+        }
 
         LOG.info("Creating Topic {}: {}", topicName, topic);
         final SyncResponseCallback callback = new SyncResponseCallback();
@@ -137,8 +170,9 @@ public class PushTopicHelper {
             if (!callback.await(API_TIMEOUT, TimeUnit.SECONDS)) {
                 throw new SalesforceException("API call timeout!", null);
             }
-            if (callback.getException() != null) {
-                throw callback.getException();
+            final SalesforceException callbackException = callback.getException();
+            if (callbackException != null) {
+                throw callbackException;
             }
 
             CreateSObjectResult result = OBJECT_MAPPER.readValue(callback.getResponse(), CreateSObjectResult.class);
@@ -182,7 +216,14 @@ public class PushTopicHelper {
             final PushTopic topic = new PushTopic();
             topic.setQuery(query);
             topic.setNotifyForFields(config.getNotifyForFields());
-            topic.setNotifyForOperations(config.getNotifyForOperations());
+            if (preApi29) {
+                topic.setNotifyForOperations(config.getNotifyForOperations());
+            } else {
+                topic.setNotifyForOperationCreate(config.getNotifyForOperationCreate());
+                topic.setNotifyForOperationDelete(config.getNotifyForOperationDelete());
+                topic.setNotifyForOperationUndelete(config.getNotifyForOperationUndelete());
+                topic.setNotifyForOperationUpdate(config.getNotifyForOperationUpdate());
+            }
 
             restClient.updateSObject("PushTopic", topicId,
                     new ByteArrayInputStream(OBJECT_MAPPER.writeValueAsBytes(topic)),
@@ -191,8 +232,9 @@ public class PushTopicHelper {
             if (!callback.await(API_TIMEOUT, TimeUnit.SECONDS)) {
                 throw new SalesforceException("API call timeout!", null);
             }
-            if (callback.getException() != null) {
-                throw callback.getException();
+            final SalesforceException callbackException = callback.getException();
+            if (callbackException != null) {
+                throw callbackException;
             }
 
         } catch (SalesforceException e) {
@@ -219,4 +261,8 @@ public class PushTopicHelper {
         }
     }
 
+    private static <T> boolean notEquals(T o1, T o2) {
+        return o1 != null && !o1.equals(o2);
+    }
+
 }
\ No newline at end of file


[04/17] camel git commit: CAMEL-7956: Updated Camel-salesforce to support SSLContextParameters to configure HttpClient

Posted by dh...@apache.org.
CAMEL-7956: Updated Camel-salesforce to support SSLContextParameters to configure HttpClient


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

Branch: refs/heads/camel-2.12.x
Commit: 1cbd81b22c7950a8206a90517be8ec16e429ccd7
Parents: 10c8063
Author: Dhiraj Bokde <dh...@yahoo.com>
Authored: Fri Oct 24 13:21:07 2014 -0700
Committer: Dhiraj Bokde <dh...@yahoo.com>
Committed: Fri Mar 20 14:24:42 2015 -0700

----------------------------------------------------------------------
 .../component/salesforce/SalesforceComponent.java | 18 +++++++++++++++++-
 .../internal/SessionIntegrationTest.java          |  6 +++++-
 2 files changed, 22 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/1cbd81b2/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 52dafa5..8a38bec 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
@@ -41,8 +41,10 @@ import org.apache.camel.spi.EndpointCompleter;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.ReflectionHelper;
 import org.apache.camel.util.ServiceHelper;
+import org.apache.camel.util.jsse.SSLContextParameters;
 import org.eclipse.jetty.client.HttpClient;
 import org.eclipse.jetty.client.RedirectListener;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -60,6 +62,8 @@ public class SalesforceComponent extends UriEndpointComponent implements Endpoin
 
     private SalesforceLoginConfig loginConfig;
     private SalesforceEndpointConfig config;
+
+    private SSLContextParameters sslContextParameters;
     private String[] packages;
 
     // component state
@@ -136,7 +140,11 @@ public class SalesforceComponent extends UriEndpointComponent implements Endpoin
             if (config != null && config.getHttpClient() != null) {
                 httpClient = config.getHttpClient();
             } else {
-                httpClient = new HttpClient();
+                final SslContextFactory sslContextFactory = new SslContextFactory();
+                final SSLContextParameters contextParameters =
+                    sslContextParameters != null ? sslContextParameters : new SSLContextParameters();
+                sslContextFactory.setSslContext(contextParameters.createSSLContext());
+                httpClient = new HttpClient(sslContextFactory);
                 httpClient.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
                 httpClient.setMaxConnectionsPerAddress(MAX_CONNECTIONS_PER_ADDRESS);
                 httpClient.setConnectTimeout(CONNECTION_TIMEOUT);
@@ -303,6 +311,14 @@ public class SalesforceComponent extends UriEndpointComponent implements Endpoin
         this.config = config;
     }
 
+    public SSLContextParameters getSslContextParameters() {
+        return sslContextParameters;
+    }
+
+    public void setSslContextParameters(SSLContextParameters sslContextParameters) {
+        this.sslContextParameters = sslContextParameters;
+    }
+
     public String[] getPackages() {
         return packages;
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/1cbd81b2/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 ce55033..a25ad52 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
@@ -17,8 +17,10 @@
 package org.apache.camel.component.salesforce.internal;
 
 import org.apache.camel.component.salesforce.LoginConfigHelper;
+import org.apache.camel.util.jsse.SSLContextParameters;
 import org.eclipse.jetty.client.HttpClient;
 import org.eclipse.jetty.client.RedirectListener;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
 import org.junit.Assert;
 import org.junit.Test;
 import org.slf4j.Logger;
@@ -37,7 +39,9 @@ public class SessionIntegrationTest extends Assert implements SalesforceSession.
     @Test
     public void testLogin() throws Exception {
 
-        final HttpClient httpClient = new HttpClient();
+        final SslContextFactory sslContextFactory = new SslContextFactory();
+        sslContextFactory.setSslContext(new SSLContextParameters().createSSLContext());
+        final HttpClient httpClient = new HttpClient(sslContextFactory);
         httpClient.setConnectTimeout(TIMEOUT);
         httpClient.setTimeout(TIMEOUT);
         httpClient.registerListener(RedirectListener.class.getName());


[09/17] camel git commit: CAMEL-8267: Allow to configure Salesforce URL

Posted by dh...@apache.org.
CAMEL-8267: Allow to configure Salesforce URL


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

Branch: refs/heads/camel-2.12.x
Commit: 33b20d59c504ab1ead9c7e69678abb3870037288
Parents: cbbc8f0
Author: Cristiano Nicolai <cr...@gmail.com>
Authored: Fri Jan 23 12:43:45 2015 +1000
Committer: Dhiraj Bokde <dh...@yahoo.com>
Committed: Fri Mar 20 14:24:44 2015 -0700

----------------------------------------------------------------------
 .../java/org/apache/camel/maven/CamelSalesforceMojo.java    | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/33b20d59/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 fdb0f8e..dab9c70 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
@@ -114,6 +114,12 @@ public class CamelSalesforceMojo extends AbstractMojo {
     protected File outputDirectory;
 
     /**
+     * Salesforce URL.
+     */
+    @Parameter(property = "camelSalesforce.loginUrl", defaultValue = SalesforceLoginConfig.DEFAULT_LOGIN_URL)
+    protected String loginUrl;
+
+    /**
      * Names of Salesforce SObject for which POJOs must be generated
      */
     @Parameter
@@ -178,8 +184,7 @@ public class CamelSalesforceMojo extends AbstractMojo {
         }
 
         final SalesforceSession session = new SalesforceSession(httpClient,
-                new SalesforceLoginConfig(SalesforceLoginConfig.DEFAULT_LOGIN_URL,
-                        clientId, clientSecret, userName, password, false));
+                new SalesforceLoginConfig(loginUrl, clientId, clientSecret, userName, password, false));
 
         getLog().info("Salesforce login...");
         try {


[17/17] camel git commit: Minor polish

Posted by dh...@apache.org.
Minor polish


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

Branch: refs/heads/camel-2.12.x
Commit: 32812e518883086fe159aeee4c35d2ae7434a289
Parents: 08f20d5
Author: Dhiraj Bokde <dh...@yahoo.com>
Authored: Fri Mar 20 14:08:05 2015 -0700
Committer: Dhiraj Bokde <dh...@yahoo.com>
Committed: Fri Mar 20 14:24:48 2015 -0700

----------------------------------------------------------------------
 .../org/apache/camel/component/salesforce/api/dto/RestError.java    | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/32812e51/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 980108e..c67cf07 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
@@ -29,7 +29,6 @@ public class RestError extends AbstractDTOBase {
 
     // default ctor for unmarshalling
     public RestError() {
-        super();
     }
 
     public RestError(String errorCode, String message, List<String> fields) {


[11/17] camel git commit: CAMEL-8269: added support for APEX REST calls, also updated Salesforce API version to 33.0

Posted by dh...@apache.org.
http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/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 9f51bbd..52a95f6 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
@@ -24,7 +24,12 @@ import java.nio.channels.ReadableByteChannel;
 import java.util.HashMap;
 import java.util.List;
 
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+
+import org.apache.camel.CamelExecutionException;
 import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.api.dto.AbstractDTOBase;
 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;
@@ -38,6 +43,7 @@ import org.apache.camel.component.salesforce.dto.generated.Document;
 import org.apache.camel.component.salesforce.dto.generated.Line_Item__c;
 import org.apache.camel.component.salesforce.dto.generated.Merchandise__c;
 import org.apache.camel.component.salesforce.dto.generated.QueryRecordsLine_Item__c;
+import org.eclipse.jetty.http.HttpStatus;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -297,6 +303,94 @@ public class RestApiIntegrationTest extends AbstractSalesforceTestBase {
         LOG.debug("ExecuteSearch: {}", searchResults);
     }
 
+    @Test
+    public void testApexCall() throws Exception {
+        try {
+            doTestApexCall("");
+            doTestApexCall("Xml");
+        } catch (CamelExecutionException e) {
+            if (e.getCause() instanceof SalesforceException) {
+                SalesforceException cause = (SalesforceException) e.getCause();
+                if (cause.getStatusCode() == HttpStatus.NOT_FOUND_404) {
+                    LOG.error("Make sure test REST resource MerchandiseRestResource.apxc has been loaded: "
+                        + e.getMessage());
+                }
+            }
+            throw e;
+        }
+    }
+
+    private void doTestApexCall(String suffix) throws Exception {
+
+        if (testId == null) {
+            // execute getBasicInfo to get test id from recent items
+            doTestGetBasicInfo("");
+        }
+
+        // request merchandise with id in URI template
+        Merchandise__c merchandise = template().requestBodyAndHeader("direct:apexCallGet" + suffix, null,
+            "id", testId, Merchandise__c.class);
+        assertNotNull(merchandise);
+        LOG.debug("ApexCallGet: {}", merchandise);
+
+        // request merchandise with id as query param
+        merchandise = template().requestBodyAndHeader("direct:apexCallGetWithId" + suffix, null,
+            SalesforceEndpointConfig.APEX_QUERY_PARAM_PREFIX + "id", testId, Merchandise__c.class);
+        assertNotNull(merchandise);
+        LOG.debug("ApexCallGetWithId: {}", merchandise);
+
+        // patch merchandise
+        // clear fields that won't be modified
+        merchandise.clearBaseFields();
+        merchandise.setId(testId);
+        merchandise.setPrice__c(null);
+        merchandise.setTotal_Inventory__c(null);
+
+        merchandise = template().requestBody("direct:apexCallPatch" + suffix,
+            new MerchandiseRequest(merchandise), Merchandise__c.class);
+        assertNotNull(merchandise);
+        LOG.debug("ApexCallPatch: {}", merchandise);
+    }
+
+    /**
+     * Request DTO for Salesforce APEX REST calls.
+     * See https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_rest_methods.htm.
+     */
+    @XStreamAlias("request")
+    public static class MerchandiseRequest extends AbstractDTOBase {
+        private Merchandise__c merchandise;
+
+        public MerchandiseRequest(Merchandise__c merchandise) {
+            this.merchandise = merchandise;
+        }
+
+        public Merchandise__c getMerchandise() {
+            return merchandise;
+        }
+
+        public void setMerchandise(Merchandise__c merchandise) {
+            this.merchandise = merchandise;
+        }
+    }
+
+    /**
+     * Response DTO for Salesforce APEX REST calls.
+     * See https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_rest_methods.htm.
+     */
+    @XStreamAlias("response")
+    public static class MerchandiseXmlResponse extends Merchandise__c {
+        // XML response contains a type string with the SObject type name
+        private String type;
+
+        public String getType() {
+            return type;
+        }
+
+        public void setType(String type) {
+            this.type = type;
+        }
+    }
+
     @Override
     protected RouteBuilder doCreateRouteBuilder() throws Exception {
 
@@ -409,6 +503,25 @@ public class RestApiIntegrationTest extends AbstractSalesforceTestBase {
 
                 from("direct:searchXml")
                     .to("salesforce:search?format=XML&sObjectSearch=FIND {Wee}");
+
+                // testApexCall
+                from("direct:apexCallGet")
+                    .to("salesforce:apexCall?apexMethod=GET&apexUrl=Merchandise/{id}&sObjectName=Merchandise__c");
+
+                from("direct:apexCallGetXml")
+                    .to("salesforce:apexCall/Merchandise/{id}?format=XML&apexMethod=GET&sObjectClass=" + MerchandiseXmlResponse.class.getName());
+
+                from("direct:apexCallGetWithId")
+                    .to("salesforce:apexCall/Merchandise/?apexMethod=GET&id=dummyId&sObjectClass=" + Merchandise__c.class.getName());
+
+                from("direct:apexCallGetWithIdXml")
+                    .to("salesforce:apexCall?format=XML&apexMethod=GET&apexUrl=Merchandise/&id=dummyId&sObjectClass=" + MerchandiseXmlResponse.class.getName());
+
+                from("direct:apexCallPatch")
+                    .to("salesforce:apexCall?apexMethod=PATCH&apexUrl=Merchandise/&sObjectName=Merchandise__c");
+
+                from("direct:apexCallPatchXml")
+                    .to("salesforce:apexCall/Merchandise/?format=XML&apexMethod=PATCH&sObjectClass=" + MerchandiseXmlResponse.class.getName());
             }
         };
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/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 66628eb..0123b05 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
@@ -81,7 +81,9 @@ public class StreamingApiIntegrationTest extends AbstractSalesforceTestBase {
             public void configure() throws Exception {
 
                 // test topic subscription
-                from("salesforce:CamelTestTopic?notifyForFields=ALL&notifyForOperations=ALL&"
+                //from("salesforce:CamelTestTopic?notifyForFields=ALL&notifyForOperations=ALL&"
+                from("salesforce:CamelTestTopic?notifyForFields=ALL&"
+                    + "notifyForOperationCreate=true&notifyForOperationDelete=true&notifyForOperationUpdate=true&"
                     + "sObjectName=Merchandise__c&"
                     + "updateTopic=true&sObjectQuery=SELECT Id, Name FROM Merchandise__c").
                     to("mock:CamelTestTopic");

http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/generated/Document.java
----------------------------------------------------------------------
diff --git a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/generated/Document.java b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/generated/Document.java
index 794b752..67e4b30 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/generated/Document.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/dto/generated/Document.java
@@ -1,18 +1,3 @@
-//CHECKSTYLE:OFF
-/*
- * 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.generated;
-
-import com.thoughtworks.xstream.annotations.XStreamAlias;
-import org.apache.camel.component.salesforce.api.dto.AbstractSObjectBase;
-import org.codehaus.jackson.annotate.JsonProperty;
-
-/**
- * Salesforce DTO for SObject Document
- */
-@XStreamAlias("Document")
 /**
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -29,6 +14,17 @@ import org.codehaus.jackson.annotate.JsonProperty;
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.camel.component.salesforce.dto.generated;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import org.apache.camel.component.salesforce.api.dto.AbstractSObjectBase;
+import org.codehaus.jackson.annotate.JsonProperty;
+
+//CHECKSTYLE:OFF
+/**
+ * Salesforce DTO for SObject Document
+ */
+@XStreamAlias("Document")
 public class Document extends AbstractSObjectBase {
 
     // FolderId

http://git-wip-us.apache.org/repos/asf/camel/blob/65cd95c5/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
index 7ddaf0f..d0a193a 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/test/resources/log4j.properties
+++ b/components/camel-salesforce/camel-salesforce-component/src/test/resources/log4j.properties
@@ -22,6 +22,7 @@ log4j.rootLogger=INFO, file
 
 # uncomment the following to enable camel debugging
 #log4j.logger.org.apache.camel.component.salesforce=DEBUG
+#log4j.logger.org.eclipse.jetty=DEBUG
 
 # CONSOLE appender not used by default
 log4j.appender.out=org.apache.log4j.ConsoleAppender