Thursday, March 14, 2013

Invoking IBM BPM Service using REST API from an external system (java system)


In this post, I would like demonstrate how to invoke a Lombardi service using via rest API, and how to pass the inputs and get back outputs. Let’s just pass two numbers (‘a’ and ‘b’) as input parametersand get back sum of these two numbers as the output parameter ‘sum’.

First of all let us know the restrictions on the services which can be invoked using REST API, you can very well find this on IBM BPM rest API documentation. Just for reference, only a human service or AJX service can be invoked using REST API URL.

In order to overcome the restriction on length of the URL which can become large because of the query parameters, the rest URL which will be used for invoking a Lombardi service is provided with POST method call.

Below shown is the format of the URL: 


In the above URL, the service name to be invoked is specified as "POC@GetSumOfNumbers" as "POC" is name of the processAPP and "GetSumOfNumbers" is the name of the service to be invoked.

Below are Steps at high level:

In BPM
1. First we need to create a service in IBM BPM, with a set of input parameters and output parameter. In the demo,
Input parameters:  ‘a’ and ‘b’
Output parameters: ‘sum’
2. Once this is done, make sure the service is created as or wrapped with a Human Service or an Ajax Service.

In Java
3. Create a class which can authenticate and invoke the REST URL in the specified format.
4.  capture the output in desired format (XML or Json) and process the output. 


Java Code 
------------------------------------------------------------------------------------------------------------
package com.ibpmcoding.resttest

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Authenticator;
import java.net.MalformedURLException;
import java.net.PasswordAuthentication;
import java.net.URL;
import java.net.URLConnection;


/**
 * Main.java
 *
 * @author ibpmcoing.blogspot.com
 */
public class TestRest {
    
    /**
     * Extends the size of an array.
     */
static final String username = "pradee"; // your account name
    static final String password = "pradeep"; // your password for the account

    static class MyAuthenticator extends Authenticator {
        public PasswordAuthentication getPasswordAuthentication() {
           System.err.println("Feeding username and password for " + getRequestingScheme()+ " authentication");
            return (new PasswordAuthentication(username, password.toCharArray()));
        }
    }

    public void sendPostRequest() {
     
        //Build parameter string
        String data = "action=start&params={'a':'1','b':'2'}&createTask=false&parts=all";
        try {
            
            // Send the request
            URL url = new URL("http://bpmserver:9081/rest/bpm/wle/v1/service/POC@GetSumOfNumbers");
            URLConnection conn = url.openConnection();
            conn.setDoOutput(true);

            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            conn.setRequestProperty("Accept","application/json");

            OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
            
            //write parameters
            writer.write(data);
            writer.flush();
            
            // Get the response
            StringBuffer answer = new StringBuffer();
            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                answer.append(line);
            }
            writer.close();
            reader.close();
            
            //Output the response
            System.out.println(answer.toString());
            
        } catch (MalformedURLException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
    /**
     * Starts the program
     *
     * @param args the command line arguments
     */
    public static void main(String[] args) {
    Authenticator.setDefault(new MyAuthenticator());  // provides basic authentication
    new TestRest().sendPostRequest();
    }
}
-----------------------------------------------------------------------------------------------------------
Output:
On executing the above java class on can see the below output.

In the above figure output is in Json format. Highlighted is the output parameter from the service.
If the output is need in the XML format, the parameter "Accept" (highlighted in above code)should be given a value "
application/xml
".



16 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. Sorry didn't get the question. Can you please elaborate.

    ReplyDelete
    Replies
    1. OOps, Typo error ..
      Here is the correct one....
      In the above code you have used the MyAuthenticator where it requires the credentials, But is there any function where the credentials are fetched from the BPM by means of session or the function MyAuthenticator is used without the credentials?

      Delete
  3. To my Knowledge there is no function which can fetch credential from BPM when you are calling the REST API method from an external system. Logically that is a security violation to expose a function which fetch credentials from BPM.
    So I dont think it will be there.
    You should be aware of credentials which invoking a BPM REST API method.

    ReplyDelete
    Replies
    1. Pradeep,

      Thanks for your immediate replies.

      I got what I needed with different approach,like when I logged in to the process portal with the login credentials, credentials will be there in the session untill I logout of the portal. So with this idea when we used the rest api url call without the credentials it will automatically take the credential from the session. Thus my job becomes very easy.... :).

      Delete
  4. If you are in using it from portal why are you using the REST API. You can directly use the webapi methods since you are in IBM BPM itself.

    ReplyDelete
  5. I have used the external UI in process portal, Where I have used the Rest api in the external UI.

    ReplyDelete
  6. This comment has been removed by the author.

    ReplyDelete
  7. This comment has been removed by the author.

    ReplyDelete
  8. This comment has been removed by the author.

    ReplyDelete
  9. By testing this approach on /bpmrest-ui. I have an ajax service with input is an EPV variable name that I will pass to the service. Expected output would be the data from EPV . But I got 'null' data when I test on the Process Server but I got the expected data on the Process Center. I get access to ProcessAdmin on Process Server the data was there but why I could see it when my ajax service was invoked on Process Server.

    ReplyDelete
  10. Can I use this java code inside a jsp page; I have .jsp page while loading the page I need to do REST API call and base don result I need to construct the page view.

    ReplyDelete
    Replies
    1. The best way to make a REST from .jsp is to use the ajax call feature of dojo/jquery etc while loading the page and use that data to construct the page view.

      Delete
  11. I found it difficult when i see the rest example. Can you post a sample example showing integrating rest API through external implementation.

    ReplyDelete
    Replies
    1. Hi Murali,
      If you are asking about integrating BPM rest API with external system (for example : Java application), where external java application calls BPM rest URL. You can find lot of java code samples which does this on web. I just gave on of the methods here.

      Delete
    2. I am doing a GET using your code,I am getting below exception:
      "pkix path building failed sun.security.provider.certpath.suncertpathbuilderexception:unable to find valid certification path to requested target"

      Help me to fix this.

      Delete