Making authenticated web service callouts from Salesforce to IBM Cast Iron using SSL/certificates–Part II

Introduction

The first part of this article series explained the scenario and some of the basics in making authenticated web service callouts from salesforce to IBM WebSphere Cast Iron. This article will continue to build the solution for the use case that was explained in the previous article. The solution to the problem is decomposed into several tutorials and this article will lay out the first tutorial.

Tutorial 1: Developing the Cast Iron Web Service and the Salesforce Trigger

The first tutorial will accomplish the following steps:

  • Develop the orchestration to update the users table and expose it as a web service over HTTP.
  • Consume the WSDL in salesforce using apex2wsdl.
  • Create the wrapper class in Apex that encapsulates the system generated stub to make the callout.
  • Create the Apex trigger and make the web service callout using the class generated in the previous step.
  • Configure the salesforce security settings to allow the outbound web service callout.

Design

The web service is built as an orchestration in IBM WebSphere Cast Iron runtime appliance which updates a row in a table in your database. This web service is called whenever a user’s status is updated. The following diagram shows a simplified architecture for this problem.

A1-P2-AD-01-ArchitectureFigure 2a. Architecture

Step # 1: Develop the orchestration.

This cast iron orchestration is a simple orchestration that will receive the input and update the ‘Users’ table and return the status. The following screenshot shows the orchestration and the configurations.

A1-P2-CI-01-Orchestration

Figure 2b. Orchestration

A1-P2-CI-02-UserManager-WSEndpoint-HTTP

Figure 2c. Web Service endpoint

Note that we are not configuring any security in the first tutorial. Hence the ‘None’ option is selected when defining the ‘Provide Service’ endpoint.

It’s a good practice to generate the WSDL of this web service and store it as part of the project. This can be accomplished very easily by right clicking the ‘Provide Service’ activity and clicking the ‘Add generated WSDL to Studio Project’ from the context menu as shown in the following screenshot.

A1-P2-CI-03-GenerateWSDLFigure 2d. Generate WSDL

There are many ways to test the web service. The options include the Salesforce Developer Console, SOAP UI, custom test application etc. Use your favorite tool to test the web service. Once the unit test is complete then it can be deployed to the runtime appliance. To do this, click File->Deploy Project which will prompt the following dialog box.

A1-P2-004-CI-PublishProject

Figure 2e. Publishing the project to the WMC.

Enter the IP address/DNS name of the runtime appliance and the user name and the password and click OK. Browse through the WMC and verify the configuration parameters and start the orchestration.

Step # 2: Consume the WSDL

Once the web service is ready and deployed, the next step is to consume the WSDL on the Salesforce side, so that the web service can be called to update the status update. Sign in to your force.com org, and click ‘Generate from WSDL’ under Setup->Develop->Apex Classes. Choose the WSDL file (from the <cast iron project folder>->WSDL folder) and click ‘Parse WSDL’ button. This tool will generate three classes; one for the request, one for the response and another is the actual stub. This tool names the file based on the namespaces defined in the WSDL file as shown below.

A1-P2-01-GenerateFromWSDL

Figure 2f. Before renaming the files

We will change these names as shown in the screenshot below.

A1-P2-02-RenameWSDLFiles

Figure 2g. After renaming the files

Click ‘Generate Apex code’ button and this creates the necessary stub, the request and the response files. The ‘UserStatusWsdl’ class needs to be updated with the actual endpoint address, as the Cast Iron embeds the proprietary syntax when a configuration parameter is used for the endpoint definitions. Click the ‘Edit’ button under Develop->Apex Classes and update the ‘endpoint_x’ variable with the endpoint URL where the Cast Iron web service is hosted.

Step # 3: Create the wrapper class

The wrapper class wraps the system generated stub class as shown in the previous step. This class basically constructs the endpoint and the web service operation parameters and makes the call to the remote web service. As indicated previously, this tutorial will make a call to the HTTP based web service that is not secured with SSL/certificates. Click ‘New’ button under Setup->Develop->Apex Classes and copy the following code snippet to the editor.

public class UserStatusClient {

    @future (callout=true)
    public static void updateUser(string userName, Boolean isActive) {
        Boolean isSuccess = true;
        try {
            UserStatusWsdl.Update_StatusPort binding = buildService();

            UserStatusRequest.statusChange_element element = new UserStatusRequest.statusChange_element();
            element.userName = userName;
            element.isActive = isActive;

            Boolean output = binding.Update_Status(element);
            System.debug('\nOutput is :' + output);
            isSuccess = true;

        } catch (Exception e) {
            isSuccess = false;
        }

        //return;
    }

    private static UserStatusWsdl.Update_StatusPort buildService() {
        UserStatusWsdl.Update_StatusPort updateStatusInstance = new UserStatusWsdl.Update_StatusPort();

        updateStatusInstance.endpoint_x         = 'http://<YourServerName>/UserManager/UpdateStatus';
        updateStatusInstance.inputHttpHeaders_x = new Map<String, String>();
        updateStatusInstance.inputHttpHeaders_x.put('OrganizationId', UserInfo.getOrganizationId());
        updateStatusInstance.timeout_x          = 60000;

        return updateStatusInstance;
    }
}

Make sure to update the <yourservername> with your actual server name (which is your Cast Iron runtime appliance).

Click ‘Save’.

Step # 4: Create the Apex trigger

An Apex trigger needs to be created that is attached to the ‘User’ object and will be invoked every time the user’s status gets updated. Click ‘New’ button under Setup->Customize->Users->Triggers and copy the code to the editor as in the following code snippet.

trigger UserAfter on User (after insert, after update) {
    if (Trigger.isUpdate) {
        for (User u: Trigger.New) {
            if (u.IsActive != Trigger.OldMap.get(u.Id).isActive) {
                UserStatusClient.updateUser(u.Username, u.isActive);
            }
        }
    }
}

Click ‘Save’. The trigger simply calls the web service using the wrapper class that was defined in the previous step.

Step # 5: Configure the salesforce security settings

Salesforce needs to be configured to allow any outbound HTTP/SOAP requests and this can be accomplished as follows:

  • Click ‘New Remote Site’ under Setup->Security Controls->Remote site settings (under Administration Setup).
  • Enter a unique name for the ‘Remote Site Name’ label.
  • Enter the URL of the site for ‘Remote Site URL’.
  • Leave the ‘Disable Protocol Security’ unchecked.
  • Leave the ‘Active’ checked.
  • Click Save.

The following screenshot shows the Remote site settings screen.

A1-P2-SF-001-RemoteSiteSettings

Figure 2h.Remote site settings

We have completed setting up the tutorial and this is now ready for testing. Create one or more test users and update their status by clicking ‘Edit’ button under Setup->Manage Users->Users section. Uncheck the ‘Active’ column and you will be prompted with the following dialog box.

A1-P2-SF-02-UpdateUserStatus-Warning

Figure 2i. Warning dialog when trying to update the ‘Active’ column.

Click ‘Ok’ and then ‘Save’.  This should fire the trigger which will invoke the web service that updates the user’s status in your database. To check whether the call was successful, you can either run the Developer Console or by going to the WMC.

With this, the first tutorial of setting up the use case with no security is complete. The Part-3 article of this series will add one-way SSL/certificate authentication.

Note: The source for the Cast Iron Studio project, the Salesforce trigger and the custom wrapper class  can be downloaded from here.

Advertisements

Tagged: , , , , ,

8 thoughts on “Making authenticated web service callouts from Salesforce to IBM Cast Iron using SSL/certificates–Part II

  1. Shivani November 22, 2012 at 9:01 am Reply

    HI Hari,
    I do not have enough words to thank you.You provide a very good description.Why not others do the same.Seriously thanks for this beautiful post.

    I am doing same work for my server.So tell me one thing if i use a one way certificate(I only want Salesforce to accesss my server) Then should i use request for certificate in Apex code ike n java we do req.setClientCertificateName(‘Cert_For_MyWebSite’);
    I am confused here.Since there is certificate on my server and i am making call from Salesforce then it will ask for a certificate since i have(HTTPS) ssl certificate enable on server.

    • Hari Krishnan November 29, 2012 at 2:30 am Reply

      Thanks Shivani. In one way SSL certificate, the server is going to have provide the certificate to the clients to prove it’s identity, which in this case, it is the Cast Iron Server. If you want to make sure that you Cast Iron should accept requests only from your Salesforce org, then there are multiple ways to do it. I thought of writing this as a separate blog post in detail, but I just got busy. Anyways, I’ll just specify the options briefly.
      1. Firewall: All requests from Salesforce to your Cast Iron server originate from a set of IP ranges. You can get this IP range from your salesforce contact and configure it in your firewall such that inbound access is allowed only from these IP range.
      2. Two-way SSL: You configure your Salesforce org to provide SSL certificate to Cast Iron prove it’s identity. This is the most bullet proof security. I blogged this about here.
      3. Orchestration: You can build functionality into your orchestration to validate that the request comes from your org. You can do this by passing the organization id (org ids are unique and can be found under ‘Company Information’ under ‘Administration Setup’) in the HTTP header when you call your Cast Iron web service and have that checked in your Cast Iron web service.

      All these methods have pros and cons. You have to weigh in and choose the right one based on your needs. Hope this helps.

      • Shivani November 29, 2012 at 4:37 am Reply

        Hi Hari,

        Thanks for reply!
        I was already late for this project so i used Salesforce organization id in the same way you have described in third step.So this authenticate Salesforce to Server and i also used one-way SSL to authenticate Server to Salesforce since Salesforce organization id is unique.
        Thanks again.

  2. salesforceGirl March 26, 2013 at 6:57 pm Reply

    This is the most incredible article i have ever seen on WS integration. I was very worried on my project as i don’t have any integration knowledge and background. This is so helping … Please keep the good work coming so that people like me can learn something. I am so thankful for your knowledge share . Whenever i will be working on any kind of integration , i will pray for you.

    • Hari Krishnan March 26, 2013 at 7:20 pm Reply

      Thanks for your compliments. Best of luck in your integration project.

  3. vinodtiwari10 March 7, 2016 at 1:03 pm Reply

    Hi Hari,

    How to add WS-Security headers in a SOAP request. How does Cast Iron support this?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: