Integrating with Sales Cloud using SOAP web services and REST APIs (Part 2 of 2)

This is part 2 of a two-part blog post that covers SOAP and REST integration with Sales Cloud

In part 1, I covered the topic of invoking Sales Cloud SOAP web services from external applications. In this part, I will cover the topic of invoking external SOAP and REST services from Sales Cloud.

Before discussing the details, here is the outline of this post.

1.  Invoking Sales Cloud SOAP web services from external applications (covered in part 1)

2.  Invoking external SOAP Web Services from Sales Cloud

3.  Invoking external REST APIs from Sales Cloud

 

2. Invoking external SOAP Web Services from Sales Cloud

Sales Cloud Application Composer allows you to invoke external web services from within Sales Cloud. Application Composer is a feature only available in Sales Cloud.

In your Sales Cloud instance, use the Navigator to navigate to Tools > Customization >Application Composer. If you cannot see this navigation, you may be missing privileges. Contact your administrator.

Once in Application Composer, select your Application (say Sales). From Common Setup, select Web Services. You will see a screen similar to the one below where you can enter your WSDL and choose the operation and security.

 

image031

Once you create the web service you can use it to invoke the web services from your UI elements. For example this web service takes in two inputs, Card Type and Card Number and responds with whether the card number is valid for the given card type.

For this scenario we could create two new fields under a standard or custom object as shown in the Application Composer. These fields will be used for capturing card type and card number as inputs from the user. A Third field can be added to provide the response. Using Groovy construct, this third field can be made to invoke the web service for the given two input values.

More information is available at the Oracle official documentation here

The three security options in the figure above translates to invoking web services with one of the following OWSM security policies

o   wss_username_token_over_ssl_service_policy

o   wss_username_token_with_message_protection_service_policy

o   wss11_saml_token_with_message_protection_client_policy

o   wss_saml_token_bearer_over_ssl_client_policy

o   wss11_saml _token_ identity_switch_with_message_protection_service_policy

For external web Services that are not protected with OWSM policies refer the interoperability scenarios at http://docs.oracle.com/cd/E57014_01/owsm/interoperability/owsm-interop-intro.htm

 

In the above example we did not pass any Sales Cloud object attribute as a parameter. In a practical scenario you will be required to pass sales cloud attributes. For example assume that you are in the Accounts screen of Sales Cloud and would like to see the latest stock price of this account. You will want to pass the sales cloud account name or the stock ticker as a parameter to the web service. In this case, if you are writing a groovy script as part of a formula field, you can directly reference the values using the variable (ex. OrganizationName or StockSymbol can be directly referenced and used without having to declare or assign)

Sometimes, you may need to invoke a web service whenever you create or update an object entity. For example, you may want to invoke a webservice whenver a Sales Account is updated. This web service could be part of an integration strategy. For this, create a trigger that fires on create or update of an Account. When the trigger fires, invoke an object function or a global function, which in turn constructs the desired payload and invokes the outbound service that you have already configured. The account payload itself will be available directly using the object name in the trigger or the objection function. For example PartyId can be referenced/used directly in your groovy code. However, when using a global function,  you cannot directly reference the object. If you require the entire object in your global function (which you will use to invoke an external web service), then you can define a parameter (say, p_account) of type Object in your global function and pass “adf.source” for that parameter from the trigger code. Using adf.source will pass the entire object to the global function. It can be used as p_account.PartyId in the groovy code.
You can also refer to the groovy scripting guide at http://docs.oracle.com/cloud/latest/salescs_gs/CGSAC/toc.htm

 

3. Invoking external REST APIs from Sales Cloud

Presently there is no declarative way of registering external REST APIs in Sales Cloud similar to the support for SOAP web services. At this point the only option is to do this programmatically using Groovy.

To implement this, we will be using the Sales Cloud Application composer but this time we will be creating a Global Functions.

image032

Provide a name and description for the global function, define the Return Type etc.  In the Function Body, we will be using Groovy code to invoke REST APIs.

image034

Below is the sample groovy code for a simple invocation of a REST API that provides the details of a specific customer. In this case the response is returned in xml format and so a simple xml parser is employed to parse and return a string value.

At this point Sales Cloud supports at least two ways to invoke REST APIs using groovy, namely using HTTPClient or using HTTPUrlConnection. There are certain advantages of each approach, but in general HTTPClient is preferred for performance reasons. The code samples below will illustrate both options.

Using HTTPClient:

def authString = "User1:Welcome1".getBytes().encodeBase64().toString()
def url = new URL("http://test.oracle.com/xxx/api/v1/customers/1234")
org.apache.http.impl.client.DefaultHttpClient httpClient = new org.apache.http.impl.client.DefaultHttpClient()
org.apache.http.client.methods.HttpGet getRequest= new org.apache.http.client.methods.HttpGet(url);
getRequest.addHeader("Accept", "application/xml");
getRequest.addHeader("Authorization", "Basic " + authString);

//actual invocation of the REST API
org.apache.http.HttpResponse response = httpClient.execute(getRequest);
def status = response.getStatusLine().getStatusCode();

//Retrieving response
def returnMessage = ""
def customerName = ""
if (status>= 300) {
  throw new org.apache.http.client.ClientProtocolException("Unexpected response status: " + status)}
org.apache.http.HttpEntity responseEntity = response.getEntity();
if (responseEntity != null) {
            returnMessage= org.apache.http.util.EntityUtils.toString(responseEntity);
        }

def customers = new XmlParser().parseText(returnMessage)
customerName = "Customer Name: " + customers.details.name.text()
return customerName

The sample above illustrates a GET operation. Similar to org.apache.http.client.methods.HttpGet, POST and PUT can be achieved through HttpPost and HttpPut respectively.

Using HTTPUrlConnection:

def authString = "User1:Welcome1".getBytes().encodeBase64().toString()
def url = new URL("http://test.oracle.com/xxx/api/v1/customers/1234")
def connection = url.openConnection()
connection.setRequestMethod("GET")
connection.setRequestProperty("Authorization", "Basic " + authString);
connection.setRequestProperty("Accept", "application/xml");
connection.connect()

//Retrieving response
def returnMessage = ""
def customerName = ""
if (connection.responseCode == 200 || connection.responseCode == 201){
returnMessage = connection.content.text
  
//Parsing the response  
def customers = new XmlParser().parseText(returnMessage)
customerName = "Customer Name: " + customers.details.name.text()
} else { 
customerName = "Error Connecting to: " + url
}
return customerName

The above samples illustrate simple XML parsing. When using JSON, the results can be parsed as follows

def returnMessage = '[{"id":1234, "name":"John"}]'   
groovy.json.JsonSlurper js = new groovy.json.JsonSlurper()
// Parse the response as Map
def map = js.parseText( returnMessage )
   
def customerName=map[0].name
return customerName

Once the global function is created with the necessary groovy code, this global function can be used in any logic for existing or new fields of an Sales Cloud page.

The above examples hopefully helped you get a better understanding of Sales Cloud’ SOAP and REST capabilities. Oracle is continuously investing in this area. So stay tuned for more updates!

Add Your Comment