== AMQP Salesforce - Spring Boot example

=== Abstract

This example listens for JSON messages sent to the AMQP server.

=== Introduction

Information about the user in the message is created as a contact in Salesforce.

=== Configuring AMQP

This example is already configured using a AMQ server. And therefore the example is ready to run
out of the box.

== Trying out the example on your local machine

Start the ActiveMQ broker in a docker container:

----
docker run --name artemis \
  -e AMQ_USER=admin \
  -e AMQ_PASSWORD=admin \
  -d -p 5672:5672 \
  quay.io/artemiscloud/activemq-artemis-broker
----

=== Configuring Salesforce

This example uses Camels own test Salesforce developer account, you
would most likely want to sign up with your own Developer account at
https://developer.salesforce.com/. After you have done that, you’ll need
to create a Connected Application for your integration.

To do this after logging in to your Salesforce Developer account,
navigate to _Apps_ located under _Build_ and then _Create_, there you
should see _Connected Apps_ table in the heading click on _New_ and fill
in the indicated required fields and enable the _OAuth Settings_, for
_Callback URL_ you can use
https://login.salesforce.com/services/oauth2/success.

In the _Available OAuth Scopes_ add _Access and manage your data (api)_
and _Perform requests on your behalf at any time (refresh_token,
offline_access)_.

After clicking _Save_ click on _Manage_ on the top of the page and then
click on _Edit Policies_. Change the _IP Relaxation_ to _Relax IP
restrictions_ and click on _Save_.

*NOTE:* This will get you started quicker, but production you should
re-evaluate to comply with your security needs.

Next gather your _Consumer Key_ (_clientId_ property), _Consumer Secret_
(clientSecret) and either use username and password of the developer
account; or get the refresh token from Salesforce (more on this below).

==== Adding the AMQP screen name custom field

The example adds a custom field to _Contact_ SObject, to add it to your
Salesforce environment go into _Customize_ under _Build_ and choose
_Fields_ under _Contact_.

In _Contact Custom Fields & Relationships_ click on _New_ and add a
field of type `+Text+` with field label `+AMQP Screen Name+`, length
of 15 and for uniqueness select _Do not allow duplicate values_ and set
the _Set this field as the unique record identifier from an external
system_.

==== Getting the OAuth refresh token

In your browser go to the URL change the `+__YOUR_CLIENT_ID_HERE__+`
with your connected application _Consumer Key_:

`+https://login.salesforce.com/services/oauth2/authorize?response_type=token&client_id=+`**YOUR_CLIENT_ID_HERE**`+&redirect_uri=https://login.salesforce.com/services/oauth2/success&display=touch+`

Allow access to the application, and you’ll end up on a page with
`+refresh_token+` after the `+#+`, something like:

`+https://login.salesforce.com/services/oauth2/success#access_token=..&refresh_token=+`**<refresh_token>**`+&instance_url=...&issued_at=...&signature=...&scope=...&token_type=Bearer+`

==== How to generate Salesforce Data Transfer Objects (DTOs)

The best way to generate Java representation of Salesforce SObjects is
to use the `+camel-salesforce-maven-plugin+` and specify the desired DTO in <configuration> section, for example:

....
        <configuration>
            <clientId>${camelSalesforce.clientId}</clientId>
            <clientSecret>${camelSalesforce.clientSecret}</clientSecret>
            <userName>${camelSalesforce.userName}</userName>
            <password>${camelSalesforce.password}</password>
            <includes>
                <include>Contact</include>
            </includes>
        </configuration>
....

To generate only DTOs needed for Contact, but the parameter value can be
specified using regular expressions.

=== Build

You will need to compile this example first:

....
mvn compile
....

=== Run

To run the example type using _generate.dto_ profile

....
mvn -DcamelSalesforce.clientId=<client id> \
    -DcamelSalesforce.clientSecret=<client secret> \
    -DcamelSalesforce.userName=<username> \
    -DcamelSalesforce.password=<password> \
    -DcamelSalesforce.secureSocketProtocol=TLSv1.3 \
    -Dgenerate.dto \
    -Dspring.profiles.active=local \
    spring-boot:run
....

To stop the example hit ctrl+c

The application exposes a REST endpoint that you can use to send a message to the ActiveMQ queue through the AMQP procotol. This message is then received in a second route and printed to the application log.

You can send the message with a following command:

----
curl -X POST -H "Content-Type: application/json" -d @src/main/resources/contact-message.json localhost:8080/amqp/
----

In the application log, you will see the following lines:

----
...
[  XNIO-1 task-2] route1                                   : Message {"lastName" : "JBoss Fuse QA", "screenName" : "Camel For Spring Boot"} sent to AMQP queue
...
[Consumer[example]] route2                                   : Received message from AMQP queue: {"lastName" : "JBoss Fuse QA", "screenName" : "Camel For Spring Boot"}
----

== Trying out the example on OpenShift

First, start with creating a new OpenShift project:

----
oc new-project csb-example-amqp-salesforce
----

Start a new deployment for Artemis:

----
oc new-app quay.io/artemiscloud/activemq-artemis-broker -e AMQ_USER=admin -e AMQ_PASSWORD=admin
----

Patch the default `activemq-artemis-broker` service to serve the `5672` port:

----
oc patch service/activemq-artemis-broker -p '{"spec":{"ports":[{"name":"5672-tcp", "port": 5672, "protocol": "TCP", "targetPort": 5672}]}}'
----

=== How to run

The application is deployed using the `openshift-maven-plugin` that takes care of creating all the necessary OpenShift resources.

Simply use the following command to deploy the application:

----
To run the example type using _generate.dto_ profile

....
mvn clean package -DcamelSalesforce.clientId=<client id> \
    -DcamelSalesforce.clientSecret=<client secret> \
    -DcamelSalesforce.userName=<username> \
    -DcamelSalesforce.password=<password> \
    -DcamelSalesforce.secureSocketProtocol=TLSv1.3 \
    -DcamelSalesforce.namespace=csb-example-amqp-salesforce \
    -Dgenerate.dto \
    -Dspring.profiles.active=openshift \
    spring-boot:repackage -Popenshift
....
----

After the application pod reaches the `Ready` state, you can try the same steps as in the local machine deployment.

To send the message to the application use:

----
curl -X POST -H "Content-Type: application/json" -d @src/main/resources/contact-message.json http://$(oc get route camel-example-spring-boot-amqp-salesforce -o jsonpath='{.spec.host}')/amqp/
----

To view the application logs, use `oc logs dc/camel-example-spring-boot-amqp-salesforce`


=== Help and contributions

If you hit any problem using Camel or have some feedback, then please
https://camel.apache.org/support.html[let us know].

We also love contributors, so
https://camel.apache.org/contributing.html[get involved] :-)

The Camel riders!
