Saturday 17 December 2011

How to get the data from java app to Salesforce using webservices


Integrate your Cloud Computing Apps with Salesforce.com, Java

New integration patterns have emerged to enable many applications to migrate to the cloud while leveraging existing infrastructure.
by Andrew Lawlor

Current economic conditions have created pressure to reduce the costs associated with developing and maintaining enterprise applications. As such, many organizations are turning to cloud computing technologies such as the Force.com platform from Salesforce.com, to lower costs and increase value.

If you haven't heard of it, Force.com, launched in 2007, lets you build and deliver apps in the cloud, and includes database, user interface, logic, workflow, mobile and security functionality -– all backed by a multi-tenant kernel currently powering 150K applications for more than 1.5 million users.

As more organizations begin the process of moving their critical apps to the cloud they may decide to maintain a subset of their infrastructure on-premise due to the large investments made in this infrastructure and for security reasons, whether due to institutional paranoia or legitimate regulatory requirements. New integration patterns have emerged to enable many applications to migrate to the cloud while leveraging existing infrastructure.

This article demonstrates how to build a mashup that seamlessly and securely integrates data and services sourced from on-premise infrastructure into a cloud application. By leveraging this pattern an organization can realize the manifold benefits of cloud sourcing an application whilst leveraging sensitive data and existing functionality available in on-premise infrastructure. As an illustrative example, an on-premise service built in Java and web-service enabled with Apache Axis is seamlessly invoked from within a Force.com application.

An Integration Architecture
A cloud-based application built on the Force.com platform may need to access sensitive data and invoke critical business logic available only in the company's on-premise infrastructure. Considering the traditional three-tier architecture, the entire presentation layer can reside in the cloud. The business logic layer too resides in the cloud with the exception of those critical services developed previously by the organization. Likewise, the data layer resides in the cloud and handles the bulk of the data used by the application. When sensitive data is needed the application accesses additional data services that reside on-premise utilizing integration technologies. The architecture is shown in the diagram below.


As you can see, most of the app and functionality sits on Force.com, with some data and functions residing on an intranet. The end-user accesses the Force.com application, which in turn makes secure callouts to the on-premise solution. This isn't the only way to integrate Force.com with Java, but it's illustrative of the general technique. See the Additional Integration Scenarios for other possibilities.

The Integration Mashup
To illustrate the integration capabilities of the Force.com platform, an example from the Wealth Management industry is shown. A large Wall Street bank wishes to migrate its Wealth Management CRM application to the cloud using the Force.com platform. Due to the sensitive nature of the customer's account balance information, the organization decides this information must remain under their control at all times within their self-managed on-premise infrastructure. The chosen architecture cloud-sources the bulk of the application on the Force.com platform and uses a mashup to seamlessly and securely integrate account balance information as needed from the organization's on-premise infrastructure.

The bank has an enterprise class account balance service built in Java that (in simplified form) returns the current balance given an account number. The bank's robust Service Oriented Architecture (SOA) surfaces this service so that it may be consumed from the Web using the standard SOAP protocol and securely authenticates the consumer to ensures the user has the rights to access this sensitive information. Apache Axis is used to Web Service enable this Java service. This can be done quite securely, for example by leveraging two-way SSL and restricting incoming IP ranges to those of Force.com.

The Wealth Management application displays the account balance by invoking the Account Balance Web Service in real-time with each render of the account page.
The Force.com platform uses the common Model-View-Controller (MVC) pattern to display content to the user. The View uses Visualforce markup to format the page. The Controller contains the business logic used to interact with the user. For this application, an Apex Code controller extension is used to invoke the external Web Service to retrieve the current account balance. The Model in this case is a combination of Force.com standard and custom objects (Force.com terminology for a rich database-like structure).

Java and Web Service Hosting
We're going to assume the Java web service is hosted on the intranet, on the Apache Axis web services stack. Lets look at this in a little more detail.
The Java Account Balance service, sitting on the intranet, has the following signature:
                                   
<pre><code>public java.lang.String getAccountBalance
(java.lang.String accountNumber)
This service returns the accountBalance for the given accountNumber, returning "Invalid Account Number" if the accountNumber is invalid. This is obviously a simplication, but illustrates the point. This service accesses an on-premise relational database to retrieve the current balance, but the details of this service aren't shown here as they are not central to this integration use-case.
In order for our cloud based Wealth Management application to consume this on-premise service it must be made available as a web service. The Apache Axis project is a very popular and mature package used to surface a Java method as a Web Service that can be invoked by any consumer with access to this on-premise server. Axis provides a Java2WSDL function that produces a standards compliant WSDL file from any given Java class file. To produce a WSDL file for our account balance service, execute the following at the command-line:

          Java2WSDL AccountService.java

Here AccountService is the name of the class that contains the getAccountBalance() method. Axis will produce a number of files that are used to Web Service enable our getAccountService method. Of most interest to our integration use case is the Web Service Description Language (WSDL) file produced called AccountService.wsdl. The WSDL file will look something like this (I've cut bits out):

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:tns2="http://AccountService" targetNamespace="http://AccountService">
    <!-- WSDL scheme type removed -->
  <wsdl:message name="getAccountBalanceRequest">
    <wsdl:part name="getAccountBalanceRequest" element="tns2:getAccountBalance"/>
  </wsdl:message>
  <wsdl:message name="getAccountBalanceResponse">
    <wsdl:part name="return" element="tns2:getAccountBalanceResponse"/>
  </wsdl:message>
  <wsdl:portType name="AccountServicePortType">
    <wsdl:operation name="getAccountBalance">
      <wsdl:input message="tns2:getAccountBalanceRequest"/>
      <wsdl:output message="tns2:getAccountBalanceResponse"/>
    </wsdl:operation>
  </wsdl:portType>
<!--wsdl binding removed -->
<wsdl:service name="AccountService">
    <wsdl:port name="AccountServicePort" binding="tns2:AccountServiceBinding">
      <soap:address location="https://aptaria.com:9081/AccountService/services/AccountServicePort"/>
    </wsdl:port>
  </wsdl:service>
Note that this WSDL identifies that the AccountService has one Web Service: getAccountBalance that takes an accountNumber String and returns an accountBalance String. Note also that the location of the AccountService is at an external domain: aptaria.com. This external on-premise server hosts our getBalanceService.

Now that our AccountService has been established in our on-premise infrastructure and the getAccountBalance method has been Web Service enabled (surfaced), we can now concentrate on integrating this critical functionality into our Force.com Wealth Management application.

Force.com and Web Service Invocation
In order to display to the user the current balance for an account we must configure our Wealth Management application to perform a callout to an external Web Service whenever the account page is rendered on Force.com. This section looks at how to configure Force.com to invoke external web services, and how to use the tooling to automatically generate the code to invoke the web service.

First we must enable the Force.com network security settings to allow our application to invoke outbound Web Service calls. As this is sensitive information we want to ensure that only our trusted on-premise infrastructure interfaces with our cloud based application. The Force.com platform can be configured to restrict all outbound Web Service calls to a particular IP range. This greatly reduces the risk of interfacing with a counterfeit or malicious AccountService.
Once you have identified the range of IP addresses at which the AccountService will be available, go to the Force.com Setup menu in your org (Force.com terminology for their cloud based application environment) and navigate to Administrative Setup : Security Controls : Network Access. From this page you can enter the Starting and Ending IP address of the secure AccountService.

Next we must identify the external Web Service to our application. We do this by uploading the generated WSDL into the Force.com platform. Once loaded, the external Web Service can be invoked by any Apex class (Apex is name of the Force.com platform programming language). To load the generated WSDL go to the Force.com Setup menu in your org and navigate to App Setup: Apex Classes. From this page select the Generate from WSDL button and then provide the location of the WSDL file generated above, and then press the Parse WSDL button.
Once the WSDL file has been loaded you will notice a new Apex class appears in the Org: AccountService. The generated class will look something like this:
//Generated by wsdl2apex

public class AccountService{
  public class getAccountBalance_element {
   /* snip */
  }
  public class getAccountBalanceResponse_element {
   /* snip */
  }    
  public class AccountServicePort {
      public String endpoint_x = 'https://aptaria.com:9081/AccountService/services/AccountServicePort';
        public String getAccountBalance(String accountNumber) {
         /* snip */
        }
  }
}
This class was completely auto generated by the Force.com platform when our AccountService WSDL was loaded. Notice that the endpoint_x variable identifies the URL address of our AccountService. The beauty of WSDL2Apex is that we don't need to concern ourselves with the details of this code. The platform handles the dirty work of invoking our getAccountBalance Web Service for us. All we need to do is call the public method getAccountBalance and pass in an accountNumber String.

The Force.com Application User Interface

Now that our AccountService is available and the platform is aware of how to invoke it as a Web Service we can update our Force.com Financial Account screen to invoke the service with each render of the page. This section looks at how to use the markup language to display the data.



To do this we use the Force.com platform's Visualforce markup language. Visualforce uses HTML-like tags (actually, more similar to Java Server Faces) to produce different visual constructs. In our case we need to display the return value from our getAccountBalance service in such a way that the user is unaware that the balance is being provided from an external web service.
The following is the Visualforce used on our Financial Account page to show the Account Balance:
<apex:page standardController="Financial_Account__c" extensions="AccountServiceController">
    <apex:pageBlock >
        <apex:pageBlockSection columns="2" >
            <apex:pageBlockSectionItem >
                <apex:outputLabel value="Account Balance"></apex:outputLabel>
            </apex:pageBlockSectionItem>
            <apex:pageBlockSectionItem >
                <div id="AccountBalance">{!AccountBalance}</div>                
            </apex:pageBlockSectionItem>            
        </apex:pageBlockSection>
        <apex:pageBlockSection columns="2" >
        </apex:pageBlockSection>

    </apex:pageBlock>
</apex:page>
The Visualforce tags define a two column table for the label 'Account Balance' and the variable {!AccountBalance}.

Visualforce automatically calls the get method defined in current controller: getAccountBalance. This method invokes the external web service and returns the AccountBalance value for display to the user in real-time. This is the secret sauce of the mashup. While standard controllers pull data directly from Force.com standard and custom objects, we need an account balance that isn't available in the cloud. Instead we integrate with an on-premise Web Service to provide the needed sensitive information. For this we need to utilize an Apex controller extension.

The Force.com Application Controller Layer
The user interface layer has a nice separation of "View" from "Control". This section looks at how to flesh out the controller layer to invoke our web service so that the appropriate data can be displayed.

Notice that the <apex:page> includes the extensions property. This property identifies a 
controller (the C an MVC) extension called AccountServiceController. This is where we extend the behavior of the standard Visualforce controller for the Financial_Account__c object by adding the capability to retrieve an account balance through integration with an external web service. The following is a complete listing of the Apex class:
global class AccountServiceController {
    Financial_Account__c account;
    String balance ='';    
    // controller
    public AccountServiceController(ApexPages.StandardController stdController) {
        this.account = (Financial_Account__c)stdController.getRecord();        
    }
    //get and set accountbalance
    public String getAccountBalance() {
        String accountNumber = [Select Account_Number__c from Financial_Account__c where Id=:account.Id].Name;
        //Invoke service
        balance = showBalance(accountNumber);
        return balance;
    }
    public void setAccountBalance(String balance) {
        this.balance = balance;
    }
    //Invoke the web service callout  
    static String showBalance(String accountNumber) {
        String accountBalance = '';
        //call Authentication Call out          
        String isValid = AuthenticationCallout();
        System.debug('Auth Result '+ isValid);
        if(isValid == 'true'){
            AccountService.AccountServicePort stub = new AccountService.AccountServicePort();
            stub.setApexTest(testFlag);                    
            accountBalance = stub.getAccountBalance(accountNumber);         
        }
        return accountBalance;
    }
    //Authentication callout (cheap - use two-way SSL for real)
    public static string AuthenticationCallout (){
        HttpRequest req = new HttpRequest();               
  req.setEndpoint('https://aptaria.com:9081/HttpAuthentication/Authenticate');
        req.setMethod('POST');
        req.setBody('username=admin&password=admin123');
        Http http = new Http();
        String result = '';
          // Make a real callout since we are not running a test
        HttpResponse res = http.send(req);
        System.debug('Authenticateresult'+res.getHeader('authValid'));
        result = res.getHeader('authValid');
          return result;
    }
}
Visualforce automatically call the getAccountBalance method when it attempts to perform variable substitution for the {!AccountBalance} element. This method identifies the AccountNumber from page context using SOQL and calls the showBalance method. The showBalance method first authenticates to the external web service using simple authentication. In a real implementation, you'll want to use a stronger form of integration -- something like two-way SSL for example.

Once authenticated, the method then invokes the AccountService methods auto generated when we imported the WSDL file to invoke the external web service and retrieve the given account's balance. Visualforce then displays the returned account balance to the user transparently, as if the data resided in the cloud.

Pulling It All Together

Our on-premise account balance service is available and Web Service enabled with Apache Axis. Force.com platform network security settings have been configured to allow outbound Web Service callouts to this critical service. The WSDL has been loaded into our application enabling our app to easily invoke our external web service. The Visualforce on our Account page has been modified to pull the account balance using a controller extension. This controller extension has been coded to invoke the code auto generated from our WSDL to call our external AccountBalance Web Service.

When the user logs into our Wealth Management App and navigates to the Financial Account page for a given account number (10001002, for example), the following screen appears:



The key point here is that the account balance for account 10001002 ($12,345.68) appears no differently from the other data about this account page (although there is a slight delay before this field appears because of network latency). The user is unaware that this data is being served from an outside resource. The integration pattern mashup provides seamless and transparent access to this sensitive data.
Additional Integration Scenarios
The demo above focuses on the outbound Web Service invocation use-case, but other scenarios are equally critical to a successful cloud-source strategy. This application can be used to execute an account transfer use-case by invoking a service that updates data in an on-premise application. You can use the built-in Force.com trigger and workflow functionality to perform this whenever data changes, or use the code scheduler to time such transfers at particular periods of the day or week etc.

Conversely, an on-premise application can access business logic and data in an application built on the Force.com platform through inbound integration. To enable this capability one simply adds the webservice keyword to any Apex method - the Force.com stack handles the rest of what it takes to get the web service up. For example, on-premise infrastructure may invoke a Force.com web service to return the total number of accounts available in a Force.com org. Once this Apex method has been web service enabled, one can use the Force.com platform to easily generate its corresponding WSDL file, which can be loaded into external infrastructure for easy integration with your cloud app.

A common use for integration with Force.com is to synchronize data between two complimentary enterprise systems. Many organizations use Salesforce.com for CRM and another application such as SAP or Oracle Applications for ERP. It is critical that these two enterprise systems properly synchronize their Account data. Integration is commonly used for this purpose. As new customers are closed through the Salesforce.com CRM system a web service callout can be used to notify downstream ERP systems for fulfillment and support. Conversely, customers are frequently added directly into ERP systems. In this case the ERP system can notify your app on Force.com of the new Accounts via inbound web service calls.
Other integration scenarios include using email services (sending or consuming emails from trusted sources), and of course invoking HTTP-based service instead of the SOAP ones used in this article.

Summary
This article explores how to integrate the Force.com platform with on-premise Java infrastructure. We have shown how a mashup can be used to seamlessly and securely leverage data and logic from on-premise Java services by integrating them directly into a Force.com application, and sketched other integration techniques.

The Force.com platform offers tremendous capabilities to seamlessly integrate your cloud sourced applications into your enterprise. Applications built on the Force.com platform can easily produce or consume data and services for your existing applications. More developer resources can be found on Developer Force athttp://developer.force.com.
Andrew is a respected thought leader in the Cloud Computing space generally and Force.com development specifically. He is a published author and respected authority on the proper application of cutting-edge information technologies to advance business goals. Andrew founded Aptaria, a registered Salesforce.com consulting partner that helps organizations of all sizes build mission critical business applications on the Force.com cloud platform. Andrew holds a Force.com Developer certification.



18 comments:

  1. Wonderful blog & good post.Its really helpful for me, awaiting for more new post. Keep Blogging!

    Salesforce Training

    ReplyDelete
  2. Thanks for your informative article on Java. It is most popular and reliable software development platform for creating mobile application. J2EE Training in Chennai

    ReplyDelete

  3. I am following your blog from the beginning, it was so distinct & I had a chance to collect conglomeration of information that helps me a lot to improvise myself. I hope this will help many readers who are in need of this vital piece of information. Thanks for sharing & keep your blog updated.
    JAVA Training in Chennai | JAVA Training Institutes in Chennai

    ReplyDelete
  4. Hi friends,This is Christy from Chennai.Thanks for sharing this informative blog. I did Unix certification course in Chennai at Fita academy. This is really useful for me to make a bright career. Suppose if anyone interested to learn Unix Training Chennai please visit Fita academy located at Chennai.
    Regards..
    Unix Training

    ReplyDelete
  5. Hi friends, This is Murali from Chennai. I am a technology freak. Your technical information is really useful for me. Keep update your blog.
    Regards..
    Oracle Training Center in Chennai

    ReplyDelete
  6. SAS is a comprehensive statistical software system which integrates utilities for storing, modifying, analyzing, and graphing data. SAS runs on both Windows and UNIX platforms. And now this is the most widely used statistical software. To know more about this please visit this site. SAS Training in Chennai

    ReplyDelete
  7. It was really a wonderful article and I was really impressed by reading this blog. Your technical information is very useful for me. Thanks for sharing your ideas.

    Regards...
    Hacking Course in Chennai

    ReplyDelete
  8. The information which you have provided is very good. It is very useful who is looking for salesforce Online Training

    ReplyDelete
  9. Thanks for sharing this information, it helps me to learn new things. Continue sharing more like this.
    R Training in Chennai

    ReplyDelete
  10. Excellent Blog! I would like to thank for the efforts you have made in writing this post. oracle training in chennai

    ReplyDelete
  11. Wow! Such an amazing and helpful post this is. I really really love it. It's so good and so awesome. I am just amazed. I hope that you continue to do your work like this in the future also for more info

    ReplyDelete

How to include a screen flow in a Lightning Web Component

 Hi, Assume  you have a flow called "Quick Contact Creation" and API Name for the same is "Quick_Contact_Creation". To i...