Skip to content

CAMEL-21910: Add Salesforce example #155

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ readme's instructions.
=== Examples

// examples: START
Number of Examples: 61 (0 deprecated)
Number of Examples: 62 (0 deprecated)

[width="100%",cols="4,2,4",options="header"]
|===
Expand Down Expand Up @@ -98,7 +98,7 @@ Number of Examples: 61 (0 deprecated)
| link:fhir/readme.adoc[Fhir] (fhir) | Health Care | An example showing how to work with Camel, FHIR and Spring Boot

| link:fhir-auth-tx/readme.adoc[Fhir Auth Tx] (fhir-auth-tx) | Health Care | An example showing how to work with Camel, FHIR Authorization, FHIR Transaction and Spring Boot


| link:validator/readme.adoc[Validator Spring Boot] (validator) | Input/Output Type Contract | An example showing how to work with declarative validation and Spring Boot

Expand All @@ -114,7 +114,7 @@ Number of Examples: 61 (0 deprecated)
| link:metrics/README.adoc[Metrics] (metrics) | Management and Monitoring | An example showing how to work with Camel and Spring Boot and report metrics to Graphite

| link:observation/README.adoc[Micrometer Observation] (observation) | Management and Monitoring | An example showing how to trace incoming and outgoing messages from Camel with Micrometer Observation


| link:opentelemetry/README.adoc[OpenTelemetry] (opentelemetry) | Management and Monitoring | An example showing how to use Camel with OpenTelemetry

Expand All @@ -128,7 +128,7 @@ Number of Examples: 61 (0 deprecated)

| link:kafka-avro/README.adoc[Kafka Avro] (kafka-avro) | Messaging | An example for Kafka avro

| link:kafka-oauth/README.adoc[Kafka OAuth] (kafka-oauth) | Messaging | An example for Kafka authentication using OAuth
| link:kafka-oauth/README.adoc[Kafka Oauth] (kafka-oauth) | Messaging | An example of Kafka authentication using OAuth.

| link:kafka-offsetrepository/README.adoc[Kafka Offsetrepository] (kafka-offsetrepository) | Messaging | An example for Kafka offsetrepository

Expand All @@ -141,7 +141,7 @@ Number of Examples: 61 (0 deprecated)
| link:widget-gadget/README.adoc[Widget Gadget] (widget-gadget) | Messaging | The widget and gadget example from EIP book, running on Spring Boot

| link:reactive-streams/readme.adoc[Reactive Streams] (reactive-streams) | Reactive | An example that shows how Camel can exchange data using reactive streams with Spring Boot reactor


| link:http-ssl/README.adoc[Http Ssl] (http-ssl) | Rest | An example showing the Camel HTTP component with Spring Boot and SSL

Expand All @@ -160,6 +160,9 @@ Number of Examples: 61 (0 deprecated)
| link:jira/README.adoc[Jira] (jira) | SaaS | An example that uses Jira Camel API

| link:twitter-salesforce/README.adoc[Twitter Salesforce] (twitter-salesforce) | SaaS | Twitter mentions is created as contacts in Salesforce

| link:salesforce/README.adoc[Salesforce] (salesforce) | SaaS | How to work with Salesforce contacts using REST endpoints and Streaming API

|===
// examples: END

Expand Down
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
<module>routetemplate-xml</module>
<module>route-reload</module>
<module>routes-configuration</module>
<module>salesforce</module>
<module>saga</module>
<module>soap-cxf</module>
<module>supervising-route-controller</module>
Expand Down
1 change: 1 addition & 0 deletions salesforce/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
src/main/resources/application.properties
101 changes: 101 additions & 0 deletions salesforce/README.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
= Camel Salesforce Example

The example provides REST API endpoints for managing Salesforce contacts (list all, get by ID, update) and implements real-time monitoring of Contact changes through Change Data Capture (CDC) events.

== Features

* REST API endpoints to fetch all Salesforce contacts, get contact by ID and update a contact by ID
* Listens continuously for Change Data Capture events (CDC)
* Salesforce authentication using client credentials flow

== Prerequisites

* Java 17 or higher
* Maven 3.6+
* Salesforce developer account
* Salesforce Connected App credentials

== Configuration

1. Create a Connected App in your Salesforce org:
* Go to Setup > Apps > App Manager > New Connected App
* Enable OAuth Settings
* Set Callback URL (can be http://localhost:8080)
* Add 'Perform requests at any time' to Selected OAuth Scopes
* Save and wait for activation

2. Enable CDC events for Contact object:
* Go to Setup > Integrations > Change Data Capture
* Add `Contact (Contact)` to Selected Entities
* Save

3. Copy `src/main/resources/application.properties.example` to `src/main/resources/application.properties`

4. Update the properties with your Connected App credentials:
[source,properties]
----
camel.component.salesforce.client-id=<YOUR_CLIENT_ID> # Consumer Key from Connected App
camel.component.salesforce.client-secret=<YOUR_CLIENT_SECRET> # Consumer Secret from Connected App
camel.component.salesforce.instance-url=<YOUR_DOMAIN> # e.g. https://your-org.my.salesforce.com
camel.component.salesforce.login-url=<YOUR_DOMAIN> # Same as instance-url
----

== Building

[source,bash]
----
mvn clean install
----

== Running

[source,bash]
----
mvn spring-boot:run
----

The application will start on port 8080.

== Testing

=== REST Endpoints

1. Fetch all contacts:
[source,bash]
----
curl -X GET http://localhost:8080/camel/contacts | jq
----

2. Fetch a specific contact:
[source,bash]
----
curl -X GET http://localhost:8080/camel/contacts/003XXXXXXXXXXXXXXX | jq
----
Replace `003XXXXXXXXXXXXXXX` with an actual Salesforce Contact ID.

3. Update a specific contact:
[source,bash]
----
curl --location --request PUT 'http://localhost:8080/camel/contacts/003XXXXXXXXXXXXXXX' \
--header 'Content-Type: application/json' \
--data-raw '{
"LastName": "Smith",
"FirstName": "John",
"Salutation": "Mr.",
"Email": "[email protected]",
"Description": "Test description"
}'
----
Replace `003XXXXXXXXXXXXXXX` with an actual Salesforce Contact ID.

== Monitor CDC events
Listens continuously for Contact Change Events (CDC):

* Make changes to contacts in Salesforce or update a specific contact
* Watch the application logs for real-time change events

== Project Structure

* `SalesforceRouter.java`: Contains Camel route definitions
* `SalesforceApp.java`: Spring Boot application entry point
* `application.properties`: Configuration properties
115 changes: 115 additions & 0 deletions salesforce/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--

Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.apache.camel.springboot.example</groupId>
<artifactId>examples</artifactId>
<version>4.11.0-SNAPSHOT</version>
</parent>

<artifactId>camel-example-spring-boot-salesforce</artifactId>
<packaging>jar</packaging>
<name>Camel SB Examples :: Salesforce</name>
<description>How to work with Salesforce contacts using REST endpoints and Streaming API</description>

<properties>
<category>SaaS</category>

<camelSalesforce.clientId></camelSalesforce.clientId>
<camelSalesforce.clientSecret></camelSalesforce.clientSecret>
<camelSalesforce.sslContextParameters.secureSocketProtocol>TLSv1.3</camelSalesforce.sslContextParameters.secureSocketProtocol>
<camelSalesforce.loginUrl>https://login.salesforce.com</camelSalesforce.loginUrl>
</properties>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-bom</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>

<!-- Camel -->
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-salesforce-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-rest-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-servlet-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-jackson-starter</artifactId>
</dependency>

<!-- Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<!-- testing -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>


</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* 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.example.salesforce;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SalesforceApp {

public static void main(String[] args) {
SpringApplication.run(SalesforceApp.class, args);
}

}
Loading
Loading