This is an automated email from the ASF dual-hosted git repository.

jeremyross pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 89524c6  CAMEL-16390: Add salesforce 'raw' operation. (#5582)
89524c6 is described below

commit 89524c67a569db7cb2a6cb706aa3aec1f80ae488
Author: Jeremy Ross <[email protected]>
AuthorDate: Tue May 18 11:07:52 2021 -0500

    CAMEL-16390: Add salesforce 'raw' operation. (#5582)
    
    CAMEL-16390: Add salesforce 'raw' operation.
---
 .../camel/catalog/docs/salesforce-component.adoc   |  60 +++++++++-
 .../camel-salesforce-component/pom.xml             |   9 +-
 .../salesforce/SalesforceComponentConfigurer.java  |  24 ++++
 .../salesforce/SalesforceEndpointConfigurer.java   |  24 ++++
 .../salesforce/SalesforceEndpointUriFactory.java   |   6 +-
 .../camel/component/salesforce/salesforce.json     |  12 +-
 .../src/main/docs/salesforce-component.adoc        |  60 +++++++++-
 .../component/salesforce/SalesforceComponent.java  |   7 ++
 .../component/salesforce/SalesforceEndpoint.java   |   3 +-
 .../salesforce/SalesforceEndpointConfig.java       |  74 ++++++++++++
 .../component/salesforce/SalesforceProducer.java   |   8 +-
 .../salesforce/internal/OperationName.java         |   5 +-
 .../internal/client/DefaultRawClient.java          | 109 ++++++++++++++++++
 .../salesforce/internal/client/RawClient.java      |  44 +++++++
 .../internal/processor/RawProcessor.java           | 126 +++++++++++++++++++++
 .../salesforce/RawOperationIntegrationTest.java    |  79 +++++++++++++
 .../dsl/SalesforceComponentBuilderFactory.java     |  66 +++++++++++
 .../builder/endpoint/StaticEndpointBuilders.java   |   8 +-
 .../dsl/SalesforceEndpointBuilderFactory.java      |  70 +++++++++++-
 .../modules/ROOT/pages/salesforce-component.adoc   |  60 +++++++++-
 20 files changed, 826 insertions(+), 28 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/salesforce-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/salesforce-component.adoc
index 3bd5a27..8d2677f 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/salesforce-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/salesforce-component.adoc
@@ -168,6 +168,7 @@ Returns a list of UpsertSObjectResult objects.
 the  information about archived Task and Event records.
 * getBlobField - Retrieves the specified blob field from an individual record.
 * apexCall - Executes a user defined APEX REST API call.
+* raw - Send requests to salesforce and have full, raw control over endpoint, 
parameters, body, etc.
 
 For example, the following producer endpoint uses the upsertSObject API,
 with the sObjectIdName parameter specifying 'Name' as the external id
@@ -674,6 +675,51 @@ With this approach, you have the complete control on the 
Salesforce request.
 `compositeMethod` option to override to the other supported value, `GET`, 
which returns a list of
 other available composite resources.
 
+== Using Raw Operation
+
+Send HTTP requests to salesforce with full, raw control of all aspects of the 
call. Any serialization or deserialization of request and response bodies must 
be performed in the route. The `Content-Type` HTTP
+header will be automatically set based on the `format` option, but this can be 
overridden with the `rawHttpHeaders` option.
+
+|===
+| Parameter | Type | Description| Default| Required
+
+| request body | `String` or `InputStream` | Body of the HTTP request | |
+| rawPath | `String` | The portion of the endpoint URL after the domain name, 
e.g., '/services/data/v51.0/sobjects/Account/' | | x
+| rawMethod | `String` | The HTTP method | | x
+| rawQueryParameters | `String` | Comma separated list of message headers to 
include as query parameters. Do not url-encode values as this will be done 
automatically. | |
+| rawHttpHeaders | `String` | Comma separated list of message headers to 
include as HTTP headers | |
+|===
+
+=== Query example
+
+In this example we'll send a query to the REST API. The query must be passed 
in a URL parameter called "q", so we'll create a message header called q and 
tell the
+raw operation to include that message header as a URL parameter:
+----
+from("direct:queryExample")
+  .setHeader("q", "SELECT Id, LastName FROM Contact")
+  
.to("salesforce:raw?format=JSON&rawMethod=GET&rawQueryParameters=q&rawPath=/services/data/v51.0/query")
+  // deserialize JSON results or handle in some other way
+----
+
+=== SObject example
+
+In this example, we'll pass a Contact the REST API in a `create` operation. 
Since the `raw` operation does not perform any serialization,
+we make sure to pass XML in the message body
+
+----
+from("direct:createAContact")
+  .setBody(constant("<Contact><LastName>TestLast</LastName></Contact>"))
+  
.to("salesforce:raw?format=XML&rawMethod=POST&rawPath=/services/data/v51.0/sobjects/Contact")
+----
+The response is:
+----
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<Result>
+    <id>0034x00000RnV6zAAF</id>
+    <success>true</success>
+</Result>
+----
+
 == Using Composite SObject Collections
 
 The SObject Collections API executes actions on multiple records in one 
request. Use sObject Collections to reduce the number of round-trips between 
the client and server. The entire request counts as a single call toward your 
API limits. This resource is available in API version 42.0 and later. `SObject` 
records (aka DTOs) supplied to these operations must be instances of subclasses 
of `AbstractDescribedSObjectBase`. See the Maven Plugin section for information 
on generating these DTO c [...]
@@ -777,7 +823,7 @@ for details on how to generate the DTO.
 == Options
 
 // component options: START
-The Salesforce component supports 80 options, which are listed below.
+The Salesforce component supports 84 options, which are listed below.
 
 
 
@@ -839,6 +885,10 @@ The Salesforce component supports 80 options, which are 
listed below.
 | *apexUrl* (producer) | APEX method URL |  | String
 | *compositeMethod* (producer) | Composite (raw) method. |  | String
 | *lazyStartProducer* (producer) | Whether the producer should be started lazy 
(on the first message). By starting lazy you can use this to allow CamelContext 
and routes to startup in situations where a producer may otherwise fail during 
starting and cause the route to fail being started. By deferring this startup 
to be lazy then the startup failure can be handled during routing messages via 
Camel's routing error handlers. Beware that when the first message is processed 
then creating and [...]
+| *rawHttpHeaders* (producer) | Comma separated list of message headers to 
include as HTTP parameters for Raw operation. |  | String
+| *rawMethod* (producer) | HTTP method to use for the Raw operation |  | String
+| *rawPath* (producer) | The portion of the endpoint URL after the domain 
name. E.g., '/services/data/v52.0/sobjects/Account/' |  | String
+| *rawQueryParameters* (producer) | Comma separated list of message headers to 
include as query parameters for Raw operation. Do not url-encode values as this 
will be done automatically. |  | String
 | *autowiredEnabled* (advanced) | Whether autowiring is enabled. This is used 
for automatic autowiring options (the option must be marked as autowired) by 
looking up in the registry to find if there is a single instance of matching 
type, which then gets configured on the component. This can be used for 
automatic configuring JDBC data sources, JMS connection factories, AWS Clients, 
etc. | true | boolean
 | *httpProxyExcludedAddresses* (proxy) | A list of addresses for which HTTP 
proxy server should not be used. |  | Set
 | *httpProxyHost* (proxy) | Hostname of the HTTP proxy server to use. |  | 
String
@@ -891,12 +941,12 @@ with the following path and query parameters:
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
 | Name | Description | Default | Type
-| *operationName* | The operation to use. There are 64 enums and the value can 
be one of: getVersions, getResources, getGlobalObjects, getBasicInfo, 
getDescription, getSObject, createSObject, updateSObject, deleteSObject, 
getSObjectWithId, upsertSObject, deleteSObjectWithId, getBlobField, query, 
queryMore, queryAll, search, apexCall, recent, createJob, getJob, closeJob, 
abortJob, createBatch, getBatch, getAllBatches, getRequest, getResults, 
createBatchQuery, getQueryResultIds, getQueryRe [...]
+| *operationName* | The operation to use. There are 65 enums and the value can 
be one of: getVersions, getResources, getGlobalObjects, getBasicInfo, 
getDescription, getSObject, createSObject, updateSObject, deleteSObject, 
getSObjectWithId, upsertSObject, deleteSObjectWithId, getBlobField, query, 
queryMore, queryAll, search, apexCall, recent, createJob, getJob, closeJob, 
abortJob, createBatch, getBatch, getAllBatches, getRequest, getResults, 
createBatchQuery, getQueryResultIds, getQueryRe [...]
 | *topicName* | The name of the topic/channel to use |  | String
 |===
 
 
-=== Query Parameters (50 parameters):
+=== Query Parameters (54 parameters):
 
 
 [width="100%",cols="2,5,^1,2",options="header"]
@@ -952,6 +1002,10 @@ with the following path and query parameters:
 | *apexUrl* (producer) | APEX method URL |  | String
 | *compositeMethod* (producer) | Composite (raw) method. |  | String
 | *lazyStartProducer* (producer) | Whether the producer should be started lazy 
(on the first message). By starting lazy you can use this to allow CamelContext 
and routes to startup in situations where a producer may otherwise fail during 
starting and cause the route to fail being started. By deferring this startup 
to be lazy then the startup failure can be handled during routing messages via 
Camel's routing error handlers. Beware that when the first message is processed 
then creating and [...]
+| *rawHttpHeaders* (producer) | Comma separated list of message headers to 
include as HTTP parameters for Raw operation. |  | String
+| *rawMethod* (producer) | HTTP method to use for the Raw operation |  | String
+| *rawPath* (producer) | The portion of the endpoint URL after the domain 
name. E.g., '/services/data/v52.0/sobjects/Account/' |  | String
+| *rawQueryParameters* (producer) | Comma separated list of message headers to 
include as query parameters for Raw operation. Do not url-encode values as this 
will be done automatically. |  | String
 |===
 // endpoint options: END
 
diff --git a/components/camel-salesforce/camel-salesforce-component/pom.xml 
b/components/camel-salesforce/camel-salesforce-component/pom.xml
index c301235..cc009ac 100644
--- a/components/camel-salesforce/camel-salesforce-component/pom.xml
+++ b/components/camel-salesforce/camel-salesforce-component/pom.xml
@@ -114,6 +114,10 @@
             <artifactId>xstream</artifactId>
         </dependency>
         <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.cometd.java</groupId>
             <artifactId>cometd-java-client</artifactId>
             <version>${cometd-java-client-version}</version>
@@ -148,11 +152,6 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>commons-io</groupId>
-            <artifactId>commons-io</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
             <groupId>org.apache.logging.log4j</groupId>
             <artifactId>log4j-slf4j-impl</artifactId>
             <scope>test</scope>
diff --git 
a/components/camel-salesforce/camel-salesforce-component/src/generated/java/org/apache/camel/component/salesforce/SalesforceComponentConfigurer.java
 
b/components/camel-salesforce/camel-salesforce-component/src/generated/java/org/apache/camel/component/salesforce/SalesforceComponentConfigurer.java
index f6197e8..281478f 100644
--- 
a/components/camel-salesforce/camel-salesforce-component/src/generated/java/org/apache/camel/component/salesforce/SalesforceComponentConfigurer.java
+++ 
b/components/camel-salesforce/camel-salesforce-component/src/generated/java/org/apache/camel/component/salesforce/SalesforceComponentConfigurer.java
@@ -146,8 +146,16 @@ public class SalesforceComponentConfigurer extends 
PropertyConfigurerSupport imp
         case "pkChunkingStartRow": 
getOrCreateConfig(target).setPkChunkingStartRow(property(camelContext, 
java.lang.String.class, value)); return true;
         case "querylocator":
         case "queryLocator": 
getOrCreateConfig(target).setQueryLocator(property(camelContext, 
java.lang.String.class, value)); return true;
+        case "rawhttpheaders":
+        case "rawHttpHeaders": 
getOrCreateConfig(target).setRawHttpHeaders(property(camelContext, 
java.lang.String.class, value)); return true;
+        case "rawmethod":
+        case "rawMethod": 
getOrCreateConfig(target).setRawMethod(property(camelContext, 
java.lang.String.class, value)); return true;
+        case "rawpath":
+        case "rawPath": 
getOrCreateConfig(target).setRawPath(property(camelContext, 
java.lang.String.class, value)); return true;
         case "rawpayload":
         case "rawPayload": 
getOrCreateConfig(target).setRawPayload(property(camelContext, boolean.class, 
value)); return true;
+        case "rawqueryparameters":
+        case "rawQueryParameters": 
getOrCreateConfig(target).setRawQueryParameters(property(camelContext, 
java.lang.String.class, value)); return true;
         case "refreshtoken":
         case "refreshToken": target.setRefreshToken(property(camelContext, 
java.lang.String.class, value)); return true;
         case "reportid":
@@ -307,8 +315,16 @@ public class SalesforceComponentConfigurer extends 
PropertyConfigurerSupport imp
         case "pkChunkingStartRow": return java.lang.String.class;
         case "querylocator":
         case "queryLocator": return java.lang.String.class;
+        case "rawhttpheaders":
+        case "rawHttpHeaders": return java.lang.String.class;
+        case "rawmethod":
+        case "rawMethod": return java.lang.String.class;
+        case "rawpath":
+        case "rawPath": return java.lang.String.class;
         case "rawpayload":
         case "rawPayload": return boolean.class;
+        case "rawqueryparameters":
+        case "rawQueryParameters": return java.lang.String.class;
         case "refreshtoken":
         case "refreshToken": return java.lang.String.class;
         case "reportid":
@@ -469,8 +485,16 @@ public class SalesforceComponentConfigurer extends 
PropertyConfigurerSupport imp
         case "pkChunkingStartRow": return 
getOrCreateConfig(target).getPkChunkingStartRow();
         case "querylocator":
         case "queryLocator": return 
getOrCreateConfig(target).getQueryLocator();
+        case "rawhttpheaders":
+        case "rawHttpHeaders": return 
getOrCreateConfig(target).getRawHttpHeaders();
+        case "rawmethod":
+        case "rawMethod": return getOrCreateConfig(target).getRawMethod();
+        case "rawpath":
+        case "rawPath": return getOrCreateConfig(target).getRawPath();
         case "rawpayload":
         case "rawPayload": return getOrCreateConfig(target).isRawPayload();
+        case "rawqueryparameters":
+        case "rawQueryParameters": return 
getOrCreateConfig(target).getRawQueryParameters();
         case "refreshtoken":
         case "refreshToken": return target.getRefreshToken();
         case "reportid":
diff --git 
a/components/camel-salesforce/camel-salesforce-component/src/generated/java/org/apache/camel/component/salesforce/SalesforceEndpointConfigurer.java
 
b/components/camel-salesforce/camel-salesforce-component/src/generated/java/org/apache/camel/component/salesforce/SalesforceEndpointConfigurer.java
index 23abe0a..031c963 100644
--- 
a/components/camel-salesforce/camel-salesforce-component/src/generated/java/org/apache/camel/component/salesforce/SalesforceEndpointConfigurer.java
+++ 
b/components/camel-salesforce/camel-salesforce-component/src/generated/java/org/apache/camel/component/salesforce/SalesforceEndpointConfigurer.java
@@ -89,8 +89,16 @@ public class SalesforceEndpointConfigurer extends 
PropertyConfigurerSupport impl
         case "pkChunkingStartRow": 
target.getConfiguration().setPkChunkingStartRow(property(camelContext, 
java.lang.String.class, value)); return true;
         case "querylocator":
         case "queryLocator": 
target.getConfiguration().setQueryLocator(property(camelContext, 
java.lang.String.class, value)); return true;
+        case "rawhttpheaders":
+        case "rawHttpHeaders": 
target.getConfiguration().setRawHttpHeaders(property(camelContext, 
java.lang.String.class, value)); return true;
+        case "rawmethod":
+        case "rawMethod": 
target.getConfiguration().setRawMethod(property(camelContext, 
java.lang.String.class, value)); return true;
+        case "rawpath":
+        case "rawPath": 
target.getConfiguration().setRawPath(property(camelContext, 
java.lang.String.class, value)); return true;
         case "rawpayload":
         case "rawPayload": 
target.getConfiguration().setRawPayload(property(camelContext, boolean.class, 
value)); return true;
+        case "rawqueryparameters":
+        case "rawQueryParameters": 
target.getConfiguration().setRawQueryParameters(property(camelContext, 
java.lang.String.class, value)); return true;
         case "replayid":
         case "replayId": target.setReplayId(property(camelContext, 
java.lang.Long.class, value)); return true;
         case "reportid":
@@ -194,8 +202,16 @@ public class SalesforceEndpointConfigurer extends 
PropertyConfigurerSupport impl
         case "pkChunkingStartRow": return java.lang.String.class;
         case "querylocator":
         case "queryLocator": return java.lang.String.class;
+        case "rawhttpheaders":
+        case "rawHttpHeaders": return java.lang.String.class;
+        case "rawmethod":
+        case "rawMethod": return java.lang.String.class;
+        case "rawpath":
+        case "rawPath": return java.lang.String.class;
         case "rawpayload":
         case "rawPayload": return boolean.class;
+        case "rawqueryparameters":
+        case "rawQueryParameters": return java.lang.String.class;
         case "replayid":
         case "replayId": return java.lang.Long.class;
         case "reportid":
@@ -300,8 +316,16 @@ public class SalesforceEndpointConfigurer extends 
PropertyConfigurerSupport impl
         case "pkChunkingStartRow": return 
target.getConfiguration().getPkChunkingStartRow();
         case "querylocator":
         case "queryLocator": return 
target.getConfiguration().getQueryLocator();
+        case "rawhttpheaders":
+        case "rawHttpHeaders": return 
target.getConfiguration().getRawHttpHeaders();
+        case "rawmethod":
+        case "rawMethod": return target.getConfiguration().getRawMethod();
+        case "rawpath":
+        case "rawPath": return target.getConfiguration().getRawPath();
         case "rawpayload":
         case "rawPayload": return target.getConfiguration().isRawPayload();
+        case "rawqueryparameters":
+        case "rawQueryParameters": return 
target.getConfiguration().getRawQueryParameters();
         case "replayid":
         case "replayId": return target.getReplayId();
         case "reportid":
diff --git 
a/components/camel-salesforce/camel-salesforce-component/src/generated/java/org/apache/camel/component/salesforce/SalesforceEndpointUriFactory.java
 
b/components/camel-salesforce/camel-salesforce-component/src/generated/java/org/apache/camel/component/salesforce/SalesforceEndpointUriFactory.java
index c92251d..40da452 100644
--- 
a/components/camel-salesforce/camel-salesforce-component/src/generated/java/org/apache/camel/component/salesforce/SalesforceEndpointUriFactory.java
+++ 
b/components/camel-salesforce/camel-salesforce-component/src/generated/java/org/apache/camel/component/salesforce/SalesforceEndpointUriFactory.java
@@ -20,7 +20,7 @@ public class SalesforceEndpointUriFactory extends 
org.apache.camel.support.compo
     private static final Set<String> PROPERTY_NAMES;
     private static final Set<String> SECRET_PROPERTY_NAMES;
     static {
-        Set<String> props = new HashSet<>(52);
+        Set<String> props = new HashSet<>(56);
         props.add("initialReplayIdMap");
         props.add("notifyForOperations");
         props.add("sObjectQuery");
@@ -39,6 +39,7 @@ public class SalesforceEndpointUriFactory extends 
org.apache.camel.support.compo
         props.add("sObjectBlobFieldName");
         props.add("backoffIncrement");
         props.add("format");
+        props.add("rawHttpHeaders");
         props.add("sObjectId");
         props.add("defaultReplayId");
         props.add("jobId");
@@ -54,6 +55,8 @@ public class SalesforceEndpointUriFactory extends 
org.apache.camel.support.compo
         props.add("notifyForOperationUndelete");
         props.add("apexUrl");
         props.add("updateTopic");
+        props.add("rawMethod");
+        props.add("rawPath");
         props.add("instanceId");
         props.add("notifyForFields");
         props.add("sObjectIdValue");
@@ -69,6 +72,7 @@ public class SalesforceEndpointUriFactory extends 
org.apache.camel.support.compo
         props.add("exchangePattern");
         props.add("operationName");
         props.add("pkChunking");
+        props.add("rawQueryParameters");
         props.add("notFoundBehaviour");
         props.add("allOrNone");
         props.add("topicName");
diff --git 
a/components/camel-salesforce/camel-salesforce-component/src/generated/resources/org/apache/camel/component/salesforce/salesforce.json
 
b/components/camel-salesforce/camel-salesforce-component/src/generated/resources/org/apache/camel/component/salesforce/salesforce.json
index 28ee224..f23c070 100644
--- 
a/components/camel-salesforce/camel-salesforce-component/src/generated/resources/org/apache/camel/component/salesforce/salesforce.json
+++ 
b/components/camel-salesforce/camel-salesforce-component/src/generated/resources/org/apache/camel/component/salesforce/salesforce.json
@@ -78,6 +78,10 @@
     "apexUrl": { "kind": "property", "displayName": "Apex Url", "group": 
"producer", "label": "producer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.salesforce.SalesforceEndpointConfig", 
"configurationField": "config", "description": "APEX method URL" },
     "compositeMethod": { "kind": "property", "displayName": "Composite 
Method", "group": "producer", "label": "producer", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.salesforce.SalesforceEndpointConfig", 
"configurationField": "config", "description": "Composite (raw) method." },
     "lazyStartProducer": { "kind": "property", "displayName": "Lazy Start 
Producer", "group": "producer", "label": "producer", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": false, "description": "Whether the producer 
should be started lazy (on the first message). By starting lazy you can use 
this to allow CamelContext and routes to startup in situations where a producer 
may otherwise fail during star [...]
+    "rawHttpHeaders": { "kind": "property", "displayName": "Raw Http Headers", 
"group": "producer", "label": "producer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.salesforce.SalesforceEndpointConfig", 
"configurationField": "config", "description": "Comma separated list of message 
headers to include as HTTP parameters for Raw operation." },
+    "rawMethod": { "kind": "property", "displayName": "Raw Method", "group": 
"producer", "label": "producer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.salesforce.SalesforceEndpointConfig", 
"configurationField": "config", "description": "HTTP method to use for the Raw 
operation" },
+    "rawPath": { "kind": "property", "displayName": "Raw Path", "group": 
"producer", "label": "producer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.salesforce.SalesforceEndpointConfig", 
"configurationField": "config", "description": "The portion of the endpoint URL 
after the domain name. E.g., '\/services\/data\/v52.0\/sobjects\/Account\/'" },
+    "rawQueryParameters": { "kind": "property", "displayName": "Raw Query 
Parameters", "group": "producer", "label": "producer", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.salesforce.SalesforceEndpointConfig", 
"configurationField": "config", "description": "Comma separated list of message 
headers to include as query parameters for Raw operation. Do not url [...]
     "autowiredEnabled": { "kind": "property", "displayName": "Autowired 
Enabled", "group": "advanced", "label": "advanced", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether autowiring is 
enabled. This is used for automatic autowiring options (the option must be 
marked as autowired) by looking up in the registry to find if there is a single 
instance of matching type, which t [...]
     "httpProxyExcludedAddresses": { "kind": "property", "displayName": "Http 
Proxy Excluded Addresses", "group": "proxy", "label": "common,proxy", 
"required": false, "type": "object", "javaType": 
"java.util.Set<java.lang.String>", "deprecated": false, "autowired": false, 
"secret": false, "description": "A list of addresses for which HTTP proxy 
server should not be used." },
     "httpProxyHost": { "kind": "property", "displayName": "Http Proxy Host", 
"group": "proxy", "label": "common,proxy", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "Hostname of the HTTP proxy server to use." },
@@ -105,7 +109,7 @@
     "userName": { "kind": "property", "displayName": "User Name", "group": 
"security", "label": "common,security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "Username used in OAuth flow to gain access to 
access token. It's easy to get started with password OAuth flow, but in general 
one should avoid it as it is deemed less secure than other flows." }
   },
   "properties": {
-    "operationName": { "kind": "path", "displayName": "Operation Name", 
"group": "producer", "label": "producer", "required": false, "type": "object", 
"javaType": "org.apache.camel.component.salesforce.internal.OperationName", 
"enum": [ "getVersions", "getResources", "getGlobalObjects", "getBasicInfo", 
"getDescription", "getSObject", "createSObject", "updateSObject", 
"deleteSObject", "getSObjectWithId", "upsertSObject", "deleteSObjectWithId", 
"getBlobField", "query", "queryMore", "queryA [...]
+    "operationName": { "kind": "path", "displayName": "Operation Name", 
"group": "producer", "label": "producer", "required": false, "type": "object", 
"javaType": "org.apache.camel.component.salesforce.internal.OperationName", 
"enum": [ "getVersions", "getResources", "getGlobalObjects", "getBasicInfo", 
"getDescription", "getSObject", "createSObject", "updateSObject", 
"deleteSObject", "getSObjectWithId", "upsertSObject", "deleteSObjectWithId", 
"getBlobField", "query", "queryMore", "queryA [...]
     "topicName": { "kind": "path", "displayName": "Topic Name", "group": 
"consumer", "label": "consumer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "The name of the topic\/channel to use" },
     "apexMethod": { "kind": "parameter", "displayName": "Apex Method", 
"group": "common", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.salesforce.SalesforceEndpointConfig", 
"configurationField": "configuration", "description": "APEX method name" },
     "apexQueryParams": { "kind": "parameter", "displayName": "Apex Query 
Params", "group": "common", "label": "", "required": false, "type": "object", 
"javaType": "java.util.Map<java.lang.String, java.lang.Object>", "deprecated": 
false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.salesforce.SalesforceEndpointConfig", 
"configurationField": "configuration", "description": "Query params for APEX 
method" },
@@ -156,6 +160,10 @@
     "allOrNone": { "kind": "parameter", "displayName": "All Or None", "group": 
"producer", "label": "producer", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "defaultValue": false, "configurationClass": 
"org.apache.camel.component.salesforce.SalesforceEndpointConfig", 
"configurationField": "configuration", "description": "Composite API option to 
indicate to rollback all records if any are not successful." },
     "apexUrl": { "kind": "parameter", "displayName": "Apex Url", "group": 
"producer", "label": "producer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.salesforce.SalesforceEndpointConfig", 
"configurationField": "configuration", "description": "APEX method URL" },
     "compositeMethod": { "kind": "parameter", "displayName": "Composite 
Method", "group": "producer", "label": "producer", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.salesforce.SalesforceEndpointConfig", 
"configurationField": "configuration", "description": "Composite (raw) method." 
},
-    "lazyStartProducer": { "kind": "parameter", "displayName": "Lazy Start 
Producer", "group": "producer", "label": "producer", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": false, "description": "Whether the producer 
should be started lazy (on the first message). By starting lazy you can use 
this to allow CamelContext and routes to startup in situations where a producer 
may otherwise fail during sta [...]
+    "lazyStartProducer": { "kind": "parameter", "displayName": "Lazy Start 
Producer", "group": "producer", "label": "producer", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": false, "description": "Whether the producer 
should be started lazy (on the first message). By starting lazy you can use 
this to allow CamelContext and routes to startup in situations where a producer 
may otherwise fail during sta [...]
+    "rawHttpHeaders": { "kind": "parameter", "displayName": "Raw Http 
Headers", "group": "producer", "label": "producer", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.salesforce.SalesforceEndpointConfig", 
"configurationField": "configuration", "description": "Comma separated list of 
message headers to include as HTTP parameters for Raw operation." },
+    "rawMethod": { "kind": "parameter", "displayName": "Raw Method", "group": 
"producer", "label": "producer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.salesforce.SalesforceEndpointConfig", 
"configurationField": "configuration", "description": "HTTP method to use for 
the Raw operation" },
+    "rawPath": { "kind": "parameter", "displayName": "Raw Path", "group": 
"producer", "label": "producer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.salesforce.SalesforceEndpointConfig", 
"configurationField": "configuration", "description": "The portion of the 
endpoint URL after the domain name. E.g., 
'\/services\/data\/v52.0\/sobjects\/Account\/'" },
+    "rawQueryParameters": { "kind": "parameter", "displayName": "Raw Query 
Parameters", "group": "producer", "label": "producer", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.salesforce.SalesforceEndpointConfig", 
"configurationField": "configuration", "description": "Comma separated list of 
message headers to include as query parameters for Raw operation. Do [...]
   }
 }
diff --git 
a/components/camel-salesforce/camel-salesforce-component/src/main/docs/salesforce-component.adoc
 
b/components/camel-salesforce/camel-salesforce-component/src/main/docs/salesforce-component.adoc
index 3bd5a27..8d2677f 100644
--- 
a/components/camel-salesforce/camel-salesforce-component/src/main/docs/salesforce-component.adoc
+++ 
b/components/camel-salesforce/camel-salesforce-component/src/main/docs/salesforce-component.adoc
@@ -168,6 +168,7 @@ Returns a list of UpsertSObjectResult objects.
 the  information about archived Task and Event records.
 * getBlobField - Retrieves the specified blob field from an individual record.
 * apexCall - Executes a user defined APEX REST API call.
+* raw - Send requests to salesforce and have full, raw control over endpoint, 
parameters, body, etc.
 
 For example, the following producer endpoint uses the upsertSObject API,
 with the sObjectIdName parameter specifying 'Name' as the external id
@@ -674,6 +675,51 @@ With this approach, you have the complete control on the 
Salesforce request.
 `compositeMethod` option to override to the other supported value, `GET`, 
which returns a list of
 other available composite resources.
 
+== Using Raw Operation
+
+Send HTTP requests to salesforce with full, raw control of all aspects of the 
call. Any serialization or deserialization of request and response bodies must 
be performed in the route. The `Content-Type` HTTP
+header will be automatically set based on the `format` option, but this can be 
overridden with the `rawHttpHeaders` option.
+
+|===
+| Parameter | Type | Description| Default| Required
+
+| request body | `String` or `InputStream` | Body of the HTTP request | |
+| rawPath | `String` | The portion of the endpoint URL after the domain name, 
e.g., '/services/data/v51.0/sobjects/Account/' | | x
+| rawMethod | `String` | The HTTP method | | x
+| rawQueryParameters | `String` | Comma separated list of message headers to 
include as query parameters. Do not url-encode values as this will be done 
automatically. | |
+| rawHttpHeaders | `String` | Comma separated list of message headers to 
include as HTTP headers | |
+|===
+
+=== Query example
+
+In this example we'll send a query to the REST API. The query must be passed 
in a URL parameter called "q", so we'll create a message header called q and 
tell the
+raw operation to include that message header as a URL parameter:
+----
+from("direct:queryExample")
+  .setHeader("q", "SELECT Id, LastName FROM Contact")
+  
.to("salesforce:raw?format=JSON&rawMethod=GET&rawQueryParameters=q&rawPath=/services/data/v51.0/query")
+  // deserialize JSON results or handle in some other way
+----
+
+=== SObject example
+
+In this example, we'll pass a Contact the REST API in a `create` operation. 
Since the `raw` operation does not perform any serialization,
+we make sure to pass XML in the message body
+
+----
+from("direct:createAContact")
+  .setBody(constant("<Contact><LastName>TestLast</LastName></Contact>"))
+  
.to("salesforce:raw?format=XML&rawMethod=POST&rawPath=/services/data/v51.0/sobjects/Contact")
+----
+The response is:
+----
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<Result>
+    <id>0034x00000RnV6zAAF</id>
+    <success>true</success>
+</Result>
+----
+
 == Using Composite SObject Collections
 
 The SObject Collections API executes actions on multiple records in one 
request. Use sObject Collections to reduce the number of round-trips between 
the client and server. The entire request counts as a single call toward your 
API limits. This resource is available in API version 42.0 and later. `SObject` 
records (aka DTOs) supplied to these operations must be instances of subclasses 
of `AbstractDescribedSObjectBase`. See the Maven Plugin section for information 
on generating these DTO c [...]
@@ -777,7 +823,7 @@ for details on how to generate the DTO.
 == Options
 
 // component options: START
-The Salesforce component supports 80 options, which are listed below.
+The Salesforce component supports 84 options, which are listed below.
 
 
 
@@ -839,6 +885,10 @@ The Salesforce component supports 80 options, which are 
listed below.
 | *apexUrl* (producer) | APEX method URL |  | String
 | *compositeMethod* (producer) | Composite (raw) method. |  | String
 | *lazyStartProducer* (producer) | Whether the producer should be started lazy 
(on the first message). By starting lazy you can use this to allow CamelContext 
and routes to startup in situations where a producer may otherwise fail during 
starting and cause the route to fail being started. By deferring this startup 
to be lazy then the startup failure can be handled during routing messages via 
Camel's routing error handlers. Beware that when the first message is processed 
then creating and [...]
+| *rawHttpHeaders* (producer) | Comma separated list of message headers to 
include as HTTP parameters for Raw operation. |  | String
+| *rawMethod* (producer) | HTTP method to use for the Raw operation |  | String
+| *rawPath* (producer) | The portion of the endpoint URL after the domain 
name. E.g., '/services/data/v52.0/sobjects/Account/' |  | String
+| *rawQueryParameters* (producer) | Comma separated list of message headers to 
include as query parameters for Raw operation. Do not url-encode values as this 
will be done automatically. |  | String
 | *autowiredEnabled* (advanced) | Whether autowiring is enabled. This is used 
for automatic autowiring options (the option must be marked as autowired) by 
looking up in the registry to find if there is a single instance of matching 
type, which then gets configured on the component. This can be used for 
automatic configuring JDBC data sources, JMS connection factories, AWS Clients, 
etc. | true | boolean
 | *httpProxyExcludedAddresses* (proxy) | A list of addresses for which HTTP 
proxy server should not be used. |  | Set
 | *httpProxyHost* (proxy) | Hostname of the HTTP proxy server to use. |  | 
String
@@ -891,12 +941,12 @@ with the following path and query parameters:
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
 | Name | Description | Default | Type
-| *operationName* | The operation to use. There are 64 enums and the value can 
be one of: getVersions, getResources, getGlobalObjects, getBasicInfo, 
getDescription, getSObject, createSObject, updateSObject, deleteSObject, 
getSObjectWithId, upsertSObject, deleteSObjectWithId, getBlobField, query, 
queryMore, queryAll, search, apexCall, recent, createJob, getJob, closeJob, 
abortJob, createBatch, getBatch, getAllBatches, getRequest, getResults, 
createBatchQuery, getQueryResultIds, getQueryRe [...]
+| *operationName* | The operation to use. There are 65 enums and the value can 
be one of: getVersions, getResources, getGlobalObjects, getBasicInfo, 
getDescription, getSObject, createSObject, updateSObject, deleteSObject, 
getSObjectWithId, upsertSObject, deleteSObjectWithId, getBlobField, query, 
queryMore, queryAll, search, apexCall, recent, createJob, getJob, closeJob, 
abortJob, createBatch, getBatch, getAllBatches, getRequest, getResults, 
createBatchQuery, getQueryResultIds, getQueryRe [...]
 | *topicName* | The name of the topic/channel to use |  | String
 |===
 
 
-=== Query Parameters (50 parameters):
+=== Query Parameters (54 parameters):
 
 
 [width="100%",cols="2,5,^1,2",options="header"]
@@ -952,6 +1002,10 @@ with the following path and query parameters:
 | *apexUrl* (producer) | APEX method URL |  | String
 | *compositeMethod* (producer) | Composite (raw) method. |  | String
 | *lazyStartProducer* (producer) | Whether the producer should be started lazy 
(on the first message). By starting lazy you can use this to allow CamelContext 
and routes to startup in situations where a producer may otherwise fail during 
starting and cause the route to fail being started. By deferring this startup 
to be lazy then the startup failure can be handled during routing messages via 
Camel's routing error handlers. Beware that when the first message is processed 
then creating and [...]
+| *rawHttpHeaders* (producer) | Comma separated list of message headers to 
include as HTTP parameters for Raw operation. |  | String
+| *rawMethod* (producer) | HTTP method to use for the Raw operation |  | String
+| *rawPath* (producer) | The portion of the endpoint URL after the domain 
name. E.g., '/services/data/v52.0/sobjects/Account/' |  | String
+| *rawQueryParameters* (producer) | Comma separated list of message headers to 
include as query parameters for Raw operation. Do not url-encode values as this 
will be done automatically. |  | String
 |===
 // endpoint options: END
 
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 d5b7ce2..33f4753 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
@@ -36,7 +36,9 @@ import 
org.apache.camel.component.salesforce.api.utils.XStreamUtils;
 import org.apache.camel.component.salesforce.internal.OperationName;
 import org.apache.camel.component.salesforce.internal.PayloadFormat;
 import org.apache.camel.component.salesforce.internal.SalesforceSession;
+import org.apache.camel.component.salesforce.internal.client.DefaultRawClient;
 import org.apache.camel.component.salesforce.internal.client.DefaultRestClient;
+import org.apache.camel.component.salesforce.internal.client.RawClient;
 import org.apache.camel.component.salesforce.internal.client.RestClient;
 import 
org.apache.camel.component.salesforce.internal.streaming.SubscriptionHelper;
 import org.apache.camel.spi.Metadata;
@@ -788,6 +790,11 @@ public class SalesforceComponent extends DefaultComponent 
implements SSLContextP
         return new DefaultRestClient(httpClient, config.getApiVersion(), 
config.getFormat(), session, loginConfig);
     }
 
+    public RawClient createRawClientFor(SalesforceEndpoint endpoint) throws 
SalesforceException {
+        SalesforceEndpointConfig endpointConfig = endpoint.getConfiguration();
+        return new DefaultRawClient(httpClient, "", session, loginConfig);
+    }
+
     static SalesforceHttpClient createHttpClient(final SslContextFactory 
sslContextFactory) throws Exception {
         SecurityUtils.adaptToIBMCipherNames(sslContextFactory);
 
diff --git 
a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceEndpoint.java
 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceEndpoint.java
index 7070af0..3084597 100644
--- 
a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceEndpoint.java
+++ 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceEndpoint.java
@@ -54,7 +54,8 @@ public class SalesforceEndpoint extends DefaultEndpoint {
             + 
"bulk2GetAllJobs,bulk2CreateJob,bulk2GetJob,bulk2CreateBatch,bulk2CloseJob,"
             + 
"bulk2AbortJob,bulk2DeleteJob,bulk2GetSuccessfulResults,bulk2GetFailedResults,"
             + 
"bulk2GetUnprocessedRecords,bulk2CreateQueryJob,bulk2GetQueryJob,"
-            + 
"bulk2GetAllQueryJobs,bulk2GetQueryJobResults,bulk2AbortQueryJob,bulk2DeleteQueryJob")
+            + 
"bulk2GetAllQueryJobs,bulk2GetQueryJobResults,bulk2AbortQueryJob,bulk2DeleteQueryJob,"
+            + "raw")
     private final OperationName operationName;
     //CHECKSTYLE:ON
     @UriPath(label = "consumer", description = "The name of the topic/channel 
to use")
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 0557b49..f0c6c81 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
@@ -94,6 +94,12 @@ public class SalesforceEndpointConfig implements Cloneable {
     // parameters for Approval API
     public static final String APPROVAL = "approval";
 
+    // parameters for the RAW operation
+    public static final String RAW_PATH = "rawPath";
+    public static final String RAW_METHOD = "rawMethod";
+    public static final String RAW_QUERY_PARAMETERS = "rawQueryParameters";
+    public static final String RAW_HTTP_HEADERS = "rawHttpHeaders";
+
     // default maximum authentication retries on failed authentication or
     // expired session
     public static final int DEFAULT_MAX_AUTHENTICATION_RETRIES = 4;
@@ -199,6 +205,16 @@ public class SalesforceEndpointConfig implements Cloneable 
{
     // Approval API properties
     private ApprovalRequest approval;
 
+    // RAW operation properties
+    @UriParam(label = "producer")
+    private String rawPath;
+    @UriParam(label = "producer")
+    private String rawMethod;
+    @UriParam(label = "producer")
+    private String rawQueryParameters;
+    @UriParam(label = "producer")
+    private String rawHttpHeaders;
+
     // Salesforce Jetty9 HttpClient, set using reference
     @UriParam
     private SalesforceHttpClient httpClient;
@@ -744,6 +760,11 @@ public class SalesforceEndpointConfig implements Cloneable 
{
 
         valueMap.put(NOT_FOUND_BEHAVIOUR, notFoundBehaviour);
 
+        valueMap.put(RAW_PATH, rawPath);
+        valueMap.put(RAW_METHOD, rawMethod);
+        valueMap.put(RAW_HTTP_HEADERS, rawHttpHeaders);
+        valueMap.put(RAW_QUERY_PARAMETERS, rawQueryParameters);
+
         return Collections.unmodifiableMap(valueMap);
     }
 
@@ -959,4 +980,57 @@ public class SalesforceEndpointConfig implements Cloneable 
{
     public void setNotFoundBehaviour(final NotFoundBehaviour 
notFoundBehaviour) {
         this.notFoundBehaviour = notFoundBehaviour;
     }
+
+    public String getRawPath() {
+        return rawPath;
+    }
+
+    /**
+     * The portion of the endpoint URL after the domain name. E.g., " + 
"'/services/data/v52.0/sobjects/Account/'
+     * 
+     * @param rawPath the path
+     */
+    public void setRawPath(String rawPath) {
+        this.rawPath = rawPath;
+    }
+
+    public String getRawMethod() {
+        return rawMethod;
+    }
+
+    /**
+     * HTTP method to use for the Raw operation
+     * 
+     * @param rawMethod http method
+     */
+    public void setRawMethod(String rawMethod) {
+        this.rawMethod = rawMethod;
+    }
+
+    public String getRawQueryParameters() {
+        return rawQueryParameters;
+    }
+
+    /**
+     * Comma separated list of message headers to include as query parameters 
for Raw operation. Do not url-encode
+     * values as this will be done automatically.
+     * 
+     * @param rawQueryParameters
+     */
+    public void setRawQueryParameters(String rawQueryParameters) {
+        this.rawQueryParameters = rawQueryParameters;
+    }
+
+    public String getRawHttpHeaders() {
+        return rawHttpHeaders;
+    }
+
+    /**
+     * Comma separated list of message headers to include as HTTP parameters 
for Raw operation.
+     * 
+     * @param
+     */
+    public void setRawHttpHeaders(String rawHttpHeaders) {
+        this.rawHttpHeaders = rawHttpHeaders;
+    }
 }
diff --git 
a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceProducer.java
 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceProducer.java
index 4569bfd..700cb31 100644
--- 
a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceProducer.java
+++ 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/SalesforceProducer.java
@@ -29,6 +29,7 @@ import 
org.apache.camel.component.salesforce.internal.processor.BulkApiV2Process
 import 
org.apache.camel.component.salesforce.internal.processor.CompositeApiProcessor;
 import 
org.apache.camel.component.salesforce.internal.processor.CompositeSObjectCollectionsProcessor;
 import 
org.apache.camel.component.salesforce.internal.processor.JsonRestProcessor;
+import org.apache.camel.component.salesforce.internal.processor.RawProcessor;
 import 
org.apache.camel.component.salesforce.internal.processor.SalesforceProcessor;
 import 
org.apache.camel.component.salesforce.internal.processor.XmlRestProcessor;
 import org.apache.camel.support.DefaultAsyncProducer;
@@ -63,6 +64,8 @@ public class SalesforceProducer extends DefaultAsyncProducer {
             processor = new CompositeApiProcessor(endpoint);
         } else if (isCompositeSObjectCollectionsOperation(operationName)) {
             processor = new CompositeSObjectCollectionsProcessor(endpoint);
+        } else if (isRawOperation(operationName)) {
+            processor = new RawProcessor(endpoint);
         } else {
             // create an appropriate processor
             if (payloadFormat == PayloadFormat.JSON) {
@@ -156,6 +159,10 @@ public class SalesforceProducer extends 
DefaultAsyncProducer {
         }
     }
 
+    private static boolean isRawOperation(OperationName operationName) {
+        return operationName == OperationName.RAW;
+    }
+
     @Override
     public boolean process(Exchange exchange, AsyncCallback callback) {
         SalesforceEndpoint endpoint = (SalesforceEndpoint) getEndpoint();
@@ -187,5 +194,4 @@ public class SalesforceProducer extends 
DefaultAsyncProducer {
 
         super.doStop();
     }
-
 }
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 086cef8..53811af 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
@@ -102,7 +102,10 @@ public enum OperationName {
     COMPOSITE_UPDATE_SOBJECT_COLLECTIONS("compositeUpdateSObjectCollections"),
     COMPOSITE_UPSERT_SOBJECT_COLLECTIONS("compositeUpsertSObjectCollections"),
     
COMPOSITE_RETRIEVE_SOBJECT_COLLECTIONS("compositeRetrieveSObjectCollections"),
-    COMPOSITE_DELETE_SOBJECT_COLLECTIONS("compositeDeleteSObjectCollections");
+    COMPOSITE_DELETE_SOBJECT_COLLECTIONS("compositeDeleteSObjectCollections"),
+
+    // Raw operation
+    RAW("raw");
 
     private final String value;
 
diff --git 
a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultRawClient.java
 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultRawClient.java
new file mode 100644
index 0000000..c4483d4
--- /dev/null
+++ 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultRawClient.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.salesforce.internal.client;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.camel.component.salesforce.SalesforceHttpClient;
+import org.apache.camel.component.salesforce.SalesforceLoginConfig;
+import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.internal.PayloadFormat;
+import org.apache.camel.component.salesforce.internal.SalesforceSession;
+import org.apache.commons.io.IOUtils;
+import org.eclipse.jetty.client.api.Request;
+import org.eclipse.jetty.client.api.Response;
+import org.eclipse.jetty.client.util.InputStreamContentProvider;
+import org.eclipse.jetty.http.HttpHeader;
+import org.eclipse.jetty.util.StringUtil;
+
+public class DefaultRawClient extends AbstractClientBase implements RawClient {
+
+    private static final String BULK_TOKEN_HEADER = "X-SFDC-Session";
+    private static final String REST_TOKEN_HEADER = "Authorization";
+    private static final String TOKEN_PREFIX = "Bearer ";
+
+    public DefaultRawClient(final SalesforceHttpClient httpClient, final 
String version,
+                            final SalesforceSession session,
+                            final SalesforceLoginConfig loginConfig) throws 
SalesforceException {
+        super(version, session, httpClient, loginConfig);
+    }
+
+    @Override
+    protected void setAccessToken(Request request) {
+        // replace old token
+        request.getHeaders().put(BULK_TOKEN_HEADER, accessToken);
+        request.getHeaders().put(REST_TOKEN_HEADER, TOKEN_PREFIX + 
accessToken);
+    }
+
+    @Override
+    protected SalesforceException createRestException(Response response, 
InputStream responseContent) {
+        String message = null;
+        try {
+            message = IOUtils.toString(responseContent, 
StandardCharsets.UTF_8);
+        } catch (IOException e) {
+            message = "Unable to read exception message: " + e.getMessage();
+        }
+        return new SalesforceException(message, response.getStatus());
+    }
+
+    /**
+     * Make a raw HTTP request to salesforce
+     * 
+     * @param method   HTTP method. "GET", "POST", etc.
+     * @param path     The path of the URL. Must begin with a "/"
+     * @param format   Encoding format
+     * @param body     Optional HTTP body
+     * @param headers  HTTP headers
+     * @param callback Callback instance that will be invoked when the HTTP 
call returns
+     */
+    @Override
+    public void makeRequest(
+            String method, String path, PayloadFormat format, InputStream 
body, Map<String, List<String>> headers,
+            ResponseCallback callback) {
+        final Request request = getRequest(method, instanceUrl + path, 
headers);
+        final String contentType = PayloadFormat.JSON.equals(format) ? 
APPLICATION_JSON_UTF8 : APPLICATION_XML_UTF8;
+        if (!request.getHeaders().contains(HttpHeader.ACCEPT)) {
+            request.header(HttpHeader.ACCEPT, contentType);
+        }
+        request.header(HttpHeader.ACCEPT_CHARSET, StringUtil.__UTF8);
+        if (!request.getHeaders().contains(HttpHeader.CONTENT_TYPE)) {
+            request.header(HttpHeader.CONTENT_TYPE, contentType);
+        }
+        if (body != null) {
+            request.content(new InputStreamContentProvider(body));
+        }
+        setAccessToken(request);
+        doHttpRequest(request, new DelegatingClientCallback(callback));
+    }
+
+    private static class DelegatingClientCallback implements 
ClientResponseCallback {
+        private final ResponseCallback callback;
+
+        DelegatingClientCallback(ResponseCallback callback) {
+            this.callback = callback;
+        }
+
+        @Override
+        public void onResponse(InputStream response, Map<String, String> 
headers, SalesforceException ex) {
+            callback.onResponse(response, headers, ex);
+        }
+    }
+}
diff --git 
a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/RawClient.java
 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/RawClient.java
new file mode 100644
index 0000000..7b9c20b
--- /dev/null
+++ 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/RawClient.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.salesforce.internal.client;
+
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.internal.PayloadFormat;
+
+public interface RawClient {
+
+    /**
+     * Make a raw HTTP request to salesforce
+     * 
+     * @param method   HTTP method. "GET", "POST", etc.
+     * @param path     the path of the URL. Must begin with a "/"
+     * @param body     Optional HTTP body
+     * @param headers  HTTP headers
+     * @param callback callback instance that will be invoked when the HTTP 
call returns
+     */
+    void makeRequest(
+            String method, String path, PayloadFormat format, InputStream 
body, Map<String, List<String>> headers,
+            ResponseCallback callback);
+
+    interface ResponseCallback {
+        void onResponse(InputStream response, Map<String, String> headers, 
SalesforceException exception);
+    }
+}
diff --git 
a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/RawProcessor.java
 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/RawProcessor.java
new file mode 100644
index 0000000..edf306b
--- /dev/null
+++ 
b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/RawProcessor.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.salesforce.internal.processor;
+
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.camel.AsyncCallback;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.salesforce.SalesforceComponent;
+import org.apache.camel.component.salesforce.SalesforceEndpoint;
+import org.apache.camel.component.salesforce.SalesforceEndpointConfig;
+import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.internal.PayloadFormat;
+import org.apache.camel.component.salesforce.internal.client.RawClient;
+import org.apache.camel.support.service.ServiceHelper;
+import org.eclipse.jetty.util.StringUtil;
+
+public class RawProcessor extends AbstractSalesforceProcessor {
+
+    private RawClient rawClient;
+    private final PayloadFormat format;
+
+    public RawProcessor(SalesforceEndpoint endpoint) throws 
SalesforceException {
+        super(endpoint);
+        format = endpoint.getConfiguration().getFormat();
+        if (format == null) {
+            throw new IllegalArgumentException("format option must be 
specified when using the raw operation.");
+        }
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+        SalesforceComponent component = endpoint.getComponent();
+        rawClient = component.createRawClientFor(endpoint);
+        ServiceHelper.startService(rawClient);
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        ServiceHelper.stopService(rawClient);
+        super.doStop();
+    }
+
+    @Override
+    public boolean process(Exchange exchange, AsyncCallback callback) {
+        try {
+            StringBuilder path
+                    = new 
StringBuilder(getParameter(SalesforceEndpointConfig.RAW_PATH, exchange, 
IGNORE_BODY, NOT_OPTIONAL));
+            String method = getParameter(SalesforceEndpointConfig.RAW_METHOD, 
exchange, IGNORE_BODY, NOT_OPTIONAL);
+            String params = getParameter(
+                    SalesforceEndpointConfig.RAW_QUERY_PARAMETERS, exchange, 
IGNORE_BODY, IS_OPTIONAL);
+            if (params != null) {
+                path.append("?");
+                for (String p : params.split(",")) {
+                    if (!path.toString().endsWith("?")) {
+                        path.append("&");
+                    }
+                    path.append(p).append("=");
+                    
path.append(urlEncode(exchange.getIn().getHeader(p).toString()));
+                }
+            }
+
+            InputStream body = exchange.getIn().getBody(InputStream.class);
+            rawClient.makeRequest(method, path.toString(), format, body, 
determineHeaders(exchange),
+                    (response, headers, exception) -> {
+                        Message in = exchange.getIn();
+                        in.getHeaders().putAll(headers);
+                        if (exception != null) {
+                            exchange.setException(exception);
+                        }
+                        in.setBody(response);
+                        callback.done(false);
+                    });
+        } catch (Exception e) {
+            exchange.setException(e);
+            callback.done(true);
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public Map<String, List<String>> determineHeaders(Exchange exchange) {
+        try {
+            final Map<String, List<String>> headers = 
super.determineHeaders(exchange);
+            String params = getParameter(
+                    SalesforceEndpointConfig.RAW_HTTP_HEADERS, exchange, 
IGNORE_BODY, IS_OPTIONAL);
+            if (params != null) {
+                for (String p : params.split(",")) {
+                    headers.put(p, 
Collections.singletonList(exchange.getIn().getHeader(p).toString()));
+                }
+            }
+            return headers;
+        } catch (SalesforceException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private String urlEncode(String query) throws UnsupportedEncodingException 
{
+        String encodedQuery = URLEncoder.encode(query, StringUtil.__UTF8);
+        // URLEncoder likes to use '+' for spaces
+        encodedQuery = encodedQuery.replace("+", "%20");
+        return encodedQuery;
+    }
+}
diff --git 
a/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/RawOperationIntegrationTest.java
 
b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/RawOperationIntegrationTest.java
new file mode 100644
index 0000000..cd78f5f
--- /dev/null
+++ 
b/components/camel-salesforce/camel-salesforce-component/src/test/java/org/apache/camel/component/salesforce/RawOperationIntegrationTest.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.salesforce;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class RawOperationIntegrationTest extends AbstractSalesforceTestBase {
+
+    @Test
+    public void testCreate() {
+        String body = "{\n" +
+                      "    \"LastName\" : \"TestLast\"\n" +
+                      "}";
+
+        Exchange exchange = fluentTemplate.withBody(body)
+                
.to("salesforce:raw?rawMethod=POST&rawPath=/services/data/v51.0/sobjects/Contact")
+                .send();
+
+        String response = exchange.getIn().getBody(String.class);
+        assertNull(exchange.getException());
+        assertTrue(response.contains("success"));
+    }
+
+    @Test
+    public void testCreateXml() {
+        String body = "<Contact>\n" +
+                      "    <LastName>TestLast</LastName>\n" +
+                      "</Contact>";
+
+        Exchange exchange = fluentTemplate.withBody(body)
+                
.to("salesforce:raw?format=XML&rawMethod=POST&rawPath=/services/data/v51.0/sobjects/Contact")
+                .send();
+
+        String response = exchange.getIn().getBody(String.class);
+        assertNull(exchange.getException());
+        assertTrue(response.contains("success"));
+    }
+
+    @Test
+    public void testQuery() {
+
+        Exchange exchange = fluentTemplate
+                .withHeader("q", "SELECT Id FROM Contact LIMIT 10")
+                
.to("salesforce:raw?format=JSON&rawMethod=GET&rawQueryParameters=q&rawPath=/services/data/v51.0/query")
+                .send();
+
+        String response = exchange.getIn().getBody(String.class);
+        assertTrue(response.contains("done"));
+        assertTrue(response.contains("totalSize"));
+    }
+
+    @Override
+    protected RouteBuilder doCreateRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+            }
+        };
+    }
+}
diff --git 
a/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SalesforceComponentBuilderFactory.java
 
b/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SalesforceComponentBuilderFactory.java
index 56bdcfd..7a4a8c6 100644
--- 
a/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SalesforceComponentBuilderFactory.java
+++ 
b/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SalesforceComponentBuilderFactory.java
@@ -942,6 +942,68 @@ public interface SalesforceComponentBuilderFactory {
             return this;
         }
         /**
+         * Comma separated list of message headers to include as HTTP 
parameters
+         * for Raw operation.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: producer
+         * 
+         * @param rawHttpHeaders the value to set
+         * @return the dsl builder
+         */
+        default SalesforceComponentBuilder rawHttpHeaders(
+                java.lang.String rawHttpHeaders) {
+            doSetProperty("rawHttpHeaders", rawHttpHeaders);
+            return this;
+        }
+        /**
+         * HTTP method to use for the Raw operation.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: producer
+         * 
+         * @param rawMethod the value to set
+         * @return the dsl builder
+         */
+        default SalesforceComponentBuilder rawMethod(java.lang.String 
rawMethod) {
+            doSetProperty("rawMethod", rawMethod);
+            return this;
+        }
+        /**
+         * The portion of the endpoint URL after the domain name. E.g.,
+         * '/services/data/v52.0/sobjects/Account/'.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: producer
+         * 
+         * @param rawPath the value to set
+         * @return the dsl builder
+         */
+        default SalesforceComponentBuilder rawPath(java.lang.String rawPath) {
+            doSetProperty("rawPath", rawPath);
+            return this;
+        }
+        /**
+         * Comma separated list of message headers to include as query
+         * parameters for Raw operation. Do not url-encode values as this will
+         * be done automatically.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: producer
+         * 
+         * @param rawQueryParameters the value to set
+         * @return the dsl builder
+         */
+        default SalesforceComponentBuilder rawQueryParameters(
+                java.lang.String rawQueryParameters) {
+            doSetProperty("rawQueryParameters", rawQueryParameters);
+            return this;
+        }
+        /**
          * Whether autowiring is enabled. This is used for automatic autowiring
          * options (the option must be marked as autowired) by looking up in 
the
          * registry to find if there is a single instance of matching type,
@@ -1443,6 +1505,10 @@ public interface SalesforceComponentBuilderFactory {
             case "apexUrl": getOrCreateConfiguration((SalesforceComponent) 
component).setApexUrl((java.lang.String) value); return true;
             case "compositeMethod": 
getOrCreateConfiguration((SalesforceComponent) 
component).setCompositeMethod((java.lang.String) value); return true;
             case "lazyStartProducer": ((SalesforceComponent) 
component).setLazyStartProducer((boolean) value); return true;
+            case "rawHttpHeaders": 
getOrCreateConfiguration((SalesforceComponent) 
component).setRawHttpHeaders((java.lang.String) value); return true;
+            case "rawMethod": getOrCreateConfiguration((SalesforceComponent) 
component).setRawMethod((java.lang.String) value); return true;
+            case "rawPath": getOrCreateConfiguration((SalesforceComponent) 
component).setRawPath((java.lang.String) value); return true;
+            case "rawQueryParameters": 
getOrCreateConfiguration((SalesforceComponent) 
component).setRawQueryParameters((java.lang.String) value); return true;
             case "autowiredEnabled": ((SalesforceComponent) 
component).setAutowiredEnabled((boolean) value); return true;
             case "httpProxyExcludedAddresses": ((SalesforceComponent) 
component).setHttpProxyExcludedAddresses((java.util.Set) value); return true;
             case "httpProxyHost": ((SalesforceComponent) 
component).setHttpProxyHost((java.lang.String) value); return true;
diff --git 
a/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/StaticEndpointBuilders.java
 
b/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/StaticEndpointBuilders.java
index 0404053..0d69c80 100644
--- 
a/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/StaticEndpointBuilders.java
+++ 
b/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/StaticEndpointBuilders.java
@@ -12596,7 +12596,7 @@ public class StaticEndpointBuilders {
      * 
      * Path parameter: operationName
      * The operation to use
-     * There are 64 enums and the value can be one of: getVersions,
+     * There are 65 enums and the value can be one of: getVersions,
      * getResources, getGlobalObjects, getBasicInfo, getDescription, 
getSObject,
      * createSObject, updateSObject, deleteSObject, getSObjectWithId,
      * upsertSObject, deleteSObjectWithId, getBlobField, query, queryMore,
@@ -12613,7 +12613,7 @@ public class StaticEndpointBuilders {
      * bulk2DeleteJob, bulk2GetSuccessfulResults, bulk2GetFailedResults,
      * bulk2GetUnprocessedRecords, bulk2CreateQueryJob, bulk2GetQueryJob,
      * bulk2GetAllQueryJobs, bulk2GetQueryJobResults, bulk2AbortQueryJob,
-     * bulk2DeleteQueryJob
+     * bulk2DeleteQueryJob, raw
      * 
      * Path parameter: topicName
      * The name of the topic/channel to use
@@ -12637,7 +12637,7 @@ public class StaticEndpointBuilders {
      * 
      * Path parameter: operationName
      * The operation to use
-     * There are 64 enums and the value can be one of: getVersions,
+     * There are 65 enums and the value can be one of: getVersions,
      * getResources, getGlobalObjects, getBasicInfo, getDescription, 
getSObject,
      * createSObject, updateSObject, deleteSObject, getSObjectWithId,
      * upsertSObject, deleteSObjectWithId, getBlobField, query, queryMore,
@@ -12654,7 +12654,7 @@ public class StaticEndpointBuilders {
      * bulk2DeleteJob, bulk2GetSuccessfulResults, bulk2GetFailedResults,
      * bulk2GetUnprocessedRecords, bulk2CreateQueryJob, bulk2GetQueryJob,
      * bulk2GetAllQueryJobs, bulk2GetQueryJobResults, bulk2AbortQueryJob,
-     * bulk2DeleteQueryJob
+     * bulk2DeleteQueryJob, raw
      * 
      * Path parameter: topicName
      * The name of the topic/channel to use
diff --git 
a/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SalesforceEndpointBuilderFactory.java
 
b/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SalesforceEndpointBuilderFactory.java
index ed5654c..1ea7580 100644
--- 
a/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SalesforceEndpointBuilderFactory.java
+++ 
b/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SalesforceEndpointBuilderFactory.java
@@ -2395,6 +2395,68 @@ public interface SalesforceEndpointBuilderFactory {
             doSetProperty("lazyStartProducer", lazyStartProducer);
             return this;
         }
+        /**
+         * Comma separated list of message headers to include as HTTP 
parameters
+         * for Raw operation.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: producer
+         * 
+         * @param rawHttpHeaders the value to set
+         * @return the dsl builder
+         */
+        default SalesforceEndpointProducerBuilder rawHttpHeaders(
+                String rawHttpHeaders) {
+            doSetProperty("rawHttpHeaders", rawHttpHeaders);
+            return this;
+        }
+        /**
+         * HTTP method to use for the Raw operation.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: producer
+         * 
+         * @param rawMethod the value to set
+         * @return the dsl builder
+         */
+        default SalesforceEndpointProducerBuilder rawMethod(String rawMethod) {
+            doSetProperty("rawMethod", rawMethod);
+            return this;
+        }
+        /**
+         * The portion of the endpoint URL after the domain name. E.g.,
+         * '/services/data/v52.0/sobjects/Account/'.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: producer
+         * 
+         * @param rawPath the value to set
+         * @return the dsl builder
+         */
+        default SalesforceEndpointProducerBuilder rawPath(String rawPath) {
+            doSetProperty("rawPath", rawPath);
+            return this;
+        }
+        /**
+         * Comma separated list of message headers to include as query
+         * parameters for Raw operation. Do not url-encode values as this will
+         * be done automatically.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: producer
+         * 
+         * @param rawQueryParameters the value to set
+         * @return the dsl builder
+         */
+        default SalesforceEndpointProducerBuilder rawQueryParameters(
+                String rawQueryParameters) {
+            doSetProperty("rawQueryParameters", rawQueryParameters);
+            return this;
+        }
     }
 
     /**
@@ -3518,7 +3580,7 @@ public interface SalesforceEndpointBuilderFactory {
          * 
          * Path parameter: operationName
          * The operation to use
-         * There are 64 enums and the value can be one of: getVersions,
+         * There are 65 enums and the value can be one of: getVersions,
          * getResources, getGlobalObjects, getBasicInfo, getDescription,
          * getSObject, createSObject, updateSObject, deleteSObject,
          * getSObjectWithId, upsertSObject, deleteSObjectWithId, getBlobField,
@@ -3536,7 +3598,7 @@ public interface SalesforceEndpointBuilderFactory {
          * bulk2GetSuccessfulResults, bulk2GetFailedResults,
          * bulk2GetUnprocessedRecords, bulk2CreateQueryJob, bulk2GetQueryJob,
          * bulk2GetAllQueryJobs, bulk2GetQueryJobResults, bulk2AbortQueryJob,
-         * bulk2DeleteQueryJob
+         * bulk2DeleteQueryJob, raw
          * 
          * Path parameter: topicName
          * The name of the topic/channel to use
@@ -3559,7 +3621,7 @@ public interface SalesforceEndpointBuilderFactory {
          * 
          * Path parameter: operationName
          * The operation to use
-         * There are 64 enums and the value can be one of: getVersions,
+         * There are 65 enums and the value can be one of: getVersions,
          * getResources, getGlobalObjects, getBasicInfo, getDescription,
          * getSObject, createSObject, updateSObject, deleteSObject,
          * getSObjectWithId, upsertSObject, deleteSObjectWithId, getBlobField,
@@ -3577,7 +3639,7 @@ public interface SalesforceEndpointBuilderFactory {
          * bulk2GetSuccessfulResults, bulk2GetFailedResults,
          * bulk2GetUnprocessedRecords, bulk2CreateQueryJob, bulk2GetQueryJob,
          * bulk2GetAllQueryJobs, bulk2GetQueryJobResults, bulk2AbortQueryJob,
-         * bulk2DeleteQueryJob
+         * bulk2DeleteQueryJob, raw
          * 
          * Path parameter: topicName
          * The name of the topic/channel to use
diff --git a/docs/components/modules/ROOT/pages/salesforce-component.adoc 
b/docs/components/modules/ROOT/pages/salesforce-component.adoc
index 7819e8d..e486848 100644
--- a/docs/components/modules/ROOT/pages/salesforce-component.adoc
+++ b/docs/components/modules/ROOT/pages/salesforce-component.adoc
@@ -170,6 +170,7 @@ Returns a list of UpsertSObjectResult objects.
 the  information about archived Task and Event records.
 * getBlobField - Retrieves the specified blob field from an individual record.
 * apexCall - Executes a user defined APEX REST API call.
+* raw - Send requests to salesforce and have full, raw control over endpoint, 
parameters, body, etc.
 
 For example, the following producer endpoint uses the upsertSObject API,
 with the sObjectIdName parameter specifying 'Name' as the external id
@@ -676,6 +677,51 @@ With this approach, you have the complete control on the 
Salesforce request.
 `compositeMethod` option to override to the other supported value, `GET`, 
which returns a list of
 other available composite resources.
 
+== Using Raw Operation
+
+Send HTTP requests to salesforce with full, raw control of all aspects of the 
call. Any serialization or deserialization of request and response bodies must 
be performed in the route. The `Content-Type` HTTP
+header will be automatically set based on the `format` option, but this can be 
overridden with the `rawHttpHeaders` option.
+
+|===
+| Parameter | Type | Description| Default| Required
+
+| request body | `String` or `InputStream` | Body of the HTTP request | |
+| rawPath | `String` | The portion of the endpoint URL after the domain name, 
e.g., '/services/data/v51.0/sobjects/Account/' | | x
+| rawMethod | `String` | The HTTP method | | x
+| rawQueryParameters | `String` | Comma separated list of message headers to 
include as query parameters. Do not url-encode values as this will be done 
automatically. | |
+| rawHttpHeaders | `String` | Comma separated list of message headers to 
include as HTTP headers | |
+|===
+
+=== Query example
+
+In this example we'll send a query to the REST API. The query must be passed 
in a URL parameter called "q", so we'll create a message header called q and 
tell the
+raw operation to include that message header as a URL parameter:
+----
+from("direct:queryExample")
+  .setHeader("q", "SELECT Id, LastName FROM Contact")
+  
.to("salesforce:raw?format=JSON&rawMethod=GET&rawQueryParameters=q&rawPath=/services/data/v51.0/query")
+  // deserialize JSON results or handle in some other way
+----
+
+=== SObject example
+
+In this example, we'll pass a Contact the REST API in a `create` operation. 
Since the `raw` operation does not perform any serialization,
+we make sure to pass XML in the message body
+
+----
+from("direct:createAContact")
+  .setBody(constant("<Contact><LastName>TestLast</LastName></Contact>"))
+  
.to("salesforce:raw?format=XML&rawMethod=POST&rawPath=/services/data/v51.0/sobjects/Contact")
+----
+The response is:
+----
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<Result>
+    <id>0034x00000RnV6zAAF</id>
+    <success>true</success>
+</Result>
+----
+
 == Using Composite SObject Collections
 
 The SObject Collections API executes actions on multiple records in one 
request. Use sObject Collections to reduce the number of round-trips between 
the client and server. The entire request counts as a single call toward your 
API limits. This resource is available in API version 42.0 and later. `SObject` 
records (aka DTOs) supplied to these operations must be instances of subclasses 
of `AbstractDescribedSObjectBase`. See the Maven Plugin section for information 
on generating these DTO c [...]
@@ -779,7 +825,7 @@ for details on how to generate the DTO.
 == Options
 
 // component options: START
-The Salesforce component supports 80 options, which are listed below.
+The Salesforce component supports 84 options, which are listed below.
 
 
 
@@ -841,6 +887,10 @@ The Salesforce component supports 80 options, which are 
listed below.
 | *apexUrl* (producer) | APEX method URL |  | String
 | *compositeMethod* (producer) | Composite (raw) method. |  | String
 | *lazyStartProducer* (producer) | Whether the producer should be started lazy 
(on the first message). By starting lazy you can use this to allow CamelContext 
and routes to startup in situations where a producer may otherwise fail during 
starting and cause the route to fail being started. By deferring this startup 
to be lazy then the startup failure can be handled during routing messages via 
Camel's routing error handlers. Beware that when the first message is processed 
then creating and [...]
+| *rawHttpHeaders* (producer) | Comma separated list of message headers to 
include as HTTP parameters for Raw operation. |  | String
+| *rawMethod* (producer) | HTTP method to use for the Raw operation |  | String
+| *rawPath* (producer) | The portion of the endpoint URL after the domain 
name. E.g., '/services/data/v52.0/sobjects/Account/' |  | String
+| *rawQueryParameters* (producer) | Comma separated list of message headers to 
include as query parameters for Raw operation. Do not url-encode values as this 
will be done automatically. |  | String
 | *autowiredEnabled* (advanced) | Whether autowiring is enabled. This is used 
for automatic autowiring options (the option must be marked as autowired) by 
looking up in the registry to find if there is a single instance of matching 
type, which then gets configured on the component. This can be used for 
automatic configuring JDBC data sources, JMS connection factories, AWS Clients, 
etc. | true | boolean
 | *httpProxyExcludedAddresses* (proxy) | A list of addresses for which HTTP 
proxy server should not be used. |  | Set
 | *httpProxyHost* (proxy) | Hostname of the HTTP proxy server to use. |  | 
String
@@ -893,12 +943,12 @@ with the following path and query parameters:
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
 | Name | Description | Default | Type
-| *operationName* | The operation to use. There are 64 enums and the value can 
be one of: getVersions, getResources, getGlobalObjects, getBasicInfo, 
getDescription, getSObject, createSObject, updateSObject, deleteSObject, 
getSObjectWithId, upsertSObject, deleteSObjectWithId, getBlobField, query, 
queryMore, queryAll, search, apexCall, recent, createJob, getJob, closeJob, 
abortJob, createBatch, getBatch, getAllBatches, getRequest, getResults, 
createBatchQuery, getQueryResultIds, getQueryRe [...]
+| *operationName* | The operation to use. There are 65 enums and the value can 
be one of: getVersions, getResources, getGlobalObjects, getBasicInfo, 
getDescription, getSObject, createSObject, updateSObject, deleteSObject, 
getSObjectWithId, upsertSObject, deleteSObjectWithId, getBlobField, query, 
queryMore, queryAll, search, apexCall, recent, createJob, getJob, closeJob, 
abortJob, createBatch, getBatch, getAllBatches, getRequest, getResults, 
createBatchQuery, getQueryResultIds, getQueryRe [...]
 | *topicName* | The name of the topic/channel to use |  | String
 |===
 
 
-=== Query Parameters (50 parameters):
+=== Query Parameters (54 parameters):
 
 
 [width="100%",cols="2,5,^1,2",options="header"]
@@ -954,6 +1004,10 @@ with the following path and query parameters:
 | *apexUrl* (producer) | APEX method URL |  | String
 | *compositeMethod* (producer) | Composite (raw) method. |  | String
 | *lazyStartProducer* (producer) | Whether the producer should be started lazy 
(on the first message). By starting lazy you can use this to allow CamelContext 
and routes to startup in situations where a producer may otherwise fail during 
starting and cause the route to fail being started. By deferring this startup 
to be lazy then the startup failure can be handled during routing messages via 
Camel's routing error handlers. Beware that when the first message is processed 
then creating and [...]
+| *rawHttpHeaders* (producer) | Comma separated list of message headers to 
include as HTTP parameters for Raw operation. |  | String
+| *rawMethod* (producer) | HTTP method to use for the Raw operation |  | String
+| *rawPath* (producer) | The portion of the endpoint URL after the domain 
name. E.g., '/services/data/v52.0/sobjects/Account/' |  | String
+| *rawQueryParameters* (producer) | Comma separated list of message headers to 
include as query parameters for Raw operation. Do not url-encode values as this 
will be done automatically. |  | String
 |===
 // endpoint options: END
 

Reply via email to