Using Java APIs as REST Services

Overview

Java APIs are business interfaces based on Java classes. Some specialized Java APIs whose methods must use parameters of either serializable Java Beans or simple data types such as String, Int, and so forth can be categorized as Java Bean Services. Some Java class provides access to business logic governing the OA Framework-based components and pages. Such Java classes are called Application Module Services and are also categorized as a subtype of Java interface.

To locate these subtype of Java interfaces, perform a search by specifying "Interface Subtype" as the Category and "Java Bean Services" or "Application Module Services" as the Category Value. Both Java Bean Services and Application Module Services can be exposed as REST services only.

Once Java Bean Services or Application Module Services have been successfully deployed as REST services, an integration developer can invoke the deployed REST services from client program using languages like Java, PHP, Javascript, Python, and so on.

Service Invocation Examples

To better understand how to use Java APIs as REST services to fetch and use application data, this chapter includes service invocation examples for interface types of Java Bean Services and Application Module Services. Oracle JDeveloper 11g (11.1.1.6.0) is used in these examples to create projects with Java class and invoke the services.

Invoking a Java Bean Service Using HTTP GET Method

REST Service Invocation Scenario

Consider a Java Bean service 'REST Service Locator' (oracle.apps.fnd.rep.ws.service.EbsRestLocator) as an example to explain the REST service invocation. REST Service Locator is a sample Java API that consists of methods to retrieve details about deployed Oracle E-Business Suite REST services.

A Java client is used to make HTTP GET request to the getRestInterface service operation. The getRestInterface service operation returns the details of a REST service identified by its internal name.

In this example, HTTP Basic Authentication scheme is used to provide user name and password information in the HTTP request header. The user credentials are authenticated and authorized by the REST service provider of ISG. After the validation, the getRestInterface service operation processes the request for the authenticated user.

After the successful service invocation, the client will receive a REST response message with the details of the REST service whose internal name has been passed in the HTTP URL at runtime during the service invocation.

Invoking a REST Service Using Java

Based on the REST service invocation scenario, the following tasks are included in this section:

  1. Deploying a REST Service

  2. Creating a Security Grant

  3. Recording Resource Information from Deployed WADL

  4. Creating a Project with a Java Class

  5. Invoking a REST Service Using a Java Class

Deploying a REST Service

Use the following steps to deploy the Java Bean Service called REST Service Locator:

  1. Log in to Oracle E-Business Suite as a user who has the Integration Administrator role.

    Select the Integrated SOA Gateway responsibility and the Integration Repository link from the navigation menu.

  2. In the Integration Repository tab, click Search to access the main Search page.

  3. Click Show More Search Options to display more search fields.

    Enter the following key search values as the search criteria:

    • Category: Interface Subtype

    • Category Value: Java Bean Services

  4. Click Go.

    Click the REST Service Locator interface name link to open the interface details page.

  5. In the REST Web Service tab, enter the following information:

    REST Web Service Tab to Deploy a Java REST Service

    the picture is described in the document text

    • Service Alias: servicelocator

      The alias will be displayed as the service endpoint in the WADL and schema for the selected method or operation.

    • Select Desired Service Operations

      In the Service Operations region, HTTP method checkboxes are preselected.

      Please note that if a Java method is annotated with a specific HTTP method, then the corresponding HTTP method checkbox is preselected for that method. The administrator can change the HTTP method checkbox selection before deploying the service.

      For more Java Bean Services annotation guidelines, see Annotations for Java Bean Services.

      In this example, the 'getRestInterface' service operation has been annotated with the GET HTTP method; therefore, the GET checkbox is automatically selected.

    • In the REST Service Security region, ensure that at least one authentication type is selected.

  6. Click Deploy to deploy the service to an Oracle E-Business Suite WebLogic environment.

Once the REST service has been successfully deployed, 'Deployed' appears in the REST Service Status field along with the View WADL link. Click the View WADL link to view the deployed service WADL description.

For more information on deploying REST services, see Deploying REST Web Services, Oracle E-Business Suite Integrated SOA Gateway Implementation Guide.

Creating a Security Grant

After deploying the REST Service Locator as a REST service, the integration administrator can create a security grant to authorize the service or method access privileges to a specific user, a user group, or all users.

Use the following steps to create a security grant:

  1. Log in to Oracle E-Business Suite as a user who has the Integration Administrator role. Select the Integrated SOA Gateway responsibility and the Integration Repository link from the navigation menu.

  2. Perform a search to locate the REST Service Locator service the administrator just deployed earlier.

  3. In the interface details page of the selected custom Java Bean Services, click the Grants tab.

  4. Select the getRestInterface method checkbox and then click Create Grant.

    Interface Details Page with Grants Tab

    the picture is described in the document text

  5. In the Create Grants page, select "All User" as the Grantee Type.

    Note: In this example, the getRestInterface service operation is granted to all users. In actual implementation, you should define strict security rules. Create grant to a user or more appropriately to a group of users defined by roles and responsibilities.

    Create Grants Page

    the picture is described in the document text

    Click Create Grant. This grants the selected method access privilege to all Oracle E-Business Suite users.

Recording Resource Information from Deployed WADL

To obtain service resource information from the deployed WADL for the REST Service Locator service, an integration developer clicks the View WADL link in the REST Web Service tab.

The following WADL description appears:

<xml version="1.0" encoding="UTF-8"> 
<application name="EbsRestLocator" targetNamespace="http://xmlns.oracle.com/apps/fnd/soaprovider/pojo/ebsrestlocator/" 
xmlns:tns="http://xmlns.oracle.com/apps/fnd/soaprovider/pojo/ebsrestlocator/" 
xmlns="http://wadl.dev.java.net/2009/02" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:tns1="http://xmlns.oracle.com/apps/fnd/rest/locatorsvc/addgrant/" 
xmlns:tns2="http://xmlns.oracle.com/apps/fnd/rest/locatorsvc/addgrants/" 
xmlns:tns3="http://xmlns.oracle.com/apps/fnd/rest/locatorsvc/getoperations/" 
xmlns:tns4="http://xmlns.oracle.com/apps/fnd/rest/locatorsvc/getrestinterface/" 
xmlns:tns5="http://xmlns.oracle.com/apps/fnd/rest/locatorsvc/getrestinterfaces/" 
xmlns:tns6="http://xmlns.oracle.com/apps/fnd/rest/locatorsvc/removegrant/">
<grammars>
                <include href="http://<hostname>:<port>/webservices/rest/servicelocator/?XSD=addgrant.xsd" xmlns="http://www.w3.org/2001/XMLSchema" /> 
                        <include href="http://<hostname>:<port>/webservices/rest/servicelocator/?XSD=addgrants.xsd" xmlns="http://www.w3.org/2001/XMLSchema" /> 
                        <include href="http://<hostname>:<port>/webservices/rest/servicelocator/?XSD=getoperations.xsd" xmlns="http://www.w3.org/2001/XMLSchema" />
                        <include href="http://<hostname>:<port>/webservices/rest/servicelocator/?XSD=getrestinterface.xsd" xmlns="http://www.w3.org/2001/XMLSchema" /> 
                        <include href="http://<hostname>:<port>/webservices/rest/servicelocator/?XSD=getrestinterfaces.xsd" xmlns="http://www.w3.org/2001/XMLSchema" />
                        <include href="http://<hostname>:<port>/webservices/rest/servicelocator/?XSD=removegrant.xsd" xmlns="http://www.w3.org/2001/XMLSchema" />  
</grammars>
<resources base="http://<hostname>:<port>/webservices/rest/servicelocator/">
  <resource path="addGrant/">
/
   ...
  </resource path>
...
        <resource path="/getRestInterface/{irepClassName}/">
           <param name="irepClassName" style="template" required="true" type="xsd:string" /> 
                <method id="getRestInterface" name="GET">
                                <request>
                                        <param name="ctx_responsibility" type="xsd:string" style="query" required="false" />
              <param name="ctx_respapplication" type="xsd:string" style="query" required="false" />
                                        <param name="ctx_securitygroup" type="xsd:string" style="query" required="false" />
                                        <param name="ctx_nlslanguage" type="xsd:string" style="query" required="false" />
                                        <param name="ctx_orgid" type="xsd:int" style="query" required="false" />
                                </request>
                        <response>
                                        <representation mediaType="application/xml" type="tns4:getRestInterface_Output" /> 
                                        <representation mediaType="application/json" type="tns4:getRestInterface_Output" /> 
                                </response>
                        </method>
                </resource>
<resource path="removeGrant/">
/
   ...
</resource path>
</application>

Copy or record the following information which will be used later when defining a Java client:

Creating a Project with a Java Class

This section describes how to create a project with a Java class that will be used to invoke the REST Service Locator service.

To create a project and a Java class:

  1. Open Oracle JDeveloper.

  2. From the main menu, choose File > New.

    In the New Gallery window, expand the General category and select 'Applications'. In the Items list, select Custom Application.

    New Gallery Window in Oracle JDeveloper

    the picture is described in the document text

    Click OK. The "Create Custom Application - Name your application" page is displayed.

  3. Enter an appropriate name for the application in the Application Name field, for example ISGJavaRESTProject. Click Next.

  4. The "Create Custom Application - Name your project" page is displayed. Enter an appropriate name for the project in the Project Name field, for example ISGJavaRESTClient.

    In the Project Features tab, select 'Java' from the Available list. Move the selected feature from the "Available" window to the "Selected" window using the right arrow button.

    Click Next.

  5. Click Finish in the Configure Java Settings dialog box.

    The newly created project should be visible in the Projects workspace.

  6. Select and right-click on the project name you just created in the Application Navigator and choose New from the drop-down selection menu.

  7. In the New Gallery window, expand the General category and select 'Java'. In the Items list, select Class. Click OK.

  8. In the Create Java Class dialog, change the default class name to 'RestInvocationGETMethod'. Accept all other defaults and click OK.

  9. The new class opens automatically in the source editor, displaying the skeleton class definition.

    Replace the skeleton class definition with the following Java code:

    package isgrestget;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import com.sun.jersey.core.util.Base64;
    
    public class RestInvocationGETMethod {
    
            /**
             * This Method invokes the a rest service using HTTP GET Method with path parameter in URL
             */
            public static void invokeREST(String svcUrlStr,String username,String passwd,String pathParam) throws IOException {
                    String getURL = svcUrlStr + "/" + pathParam;
                    URL url = new URL(getURL);
                    //Obtaining connection to invoke the service
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    String auth = username + ":" + passwd;
                    byte[] bytes = Base64.encode(auth);
                    String authStr = new String(bytes);
    
                    //Setting Http header values
                    conn.setRequestMethod("GET");
                    conn.setRequestProperty("Authorization", "Basic " + authStr);
                    conn.setRequestProperty("Accept", "application/json");
                    conn.setRequestProperty("Content-Language", "en-US");
                    conn.setUseCaches(false);
                    conn.setDoInput(true);
                    conn.setDoOutput(true);
                    conn.connect();
                    System.out.println("\n 'GET' request sent to URL : " + url);
                    System.out.println("\n Response code - " + conn.getResponseCode());
                    //Get Response
                    String response = null;
                    try {
                            response = readHttpResponse(conn);
                    } finally {
                            if (conn != null)
                                    conn.disconnect();
                    }
                    //Show Response
                    System.out.println("Response is : \n" + response);
            }
    
            /**
             * This method reads response sent by the server and returns it in a string representation.
             */
            private static String readHttpResponse(HttpURLConnection conn) {
                    InputStream is = null;
                    BufferedReader rd = null;
                    StringBuffer response = new StringBuffer();
                    try {
                            if (conn.getResponseCode() >= 400) {
                                    is = conn.getErrorStream();
                            } else {
                                    is = conn.getInputStream();
                            }
                            rd = new BufferedReader(new InputStreamReader(is));
                            String line;
                            while ((line = rd.readLine()) != null) {
                                    response.append(line);
                                    response.append('\n');
                            }
                    } catch (IOException ioe) {
                            response.append(ioe.getMessage());
                    } finally {
                            if (is != null) {
                                    try {
                                            is.close();
                                    } catch (Exception e) {
                                    }
                            }
                            if (rd != null) {
                                    try {
                                            rd.close();
                                    } catch (Exception e) {
                                    }
                            }
                    }
                    return (response.toString());
            }
    
             public static void main(String[] args) throws Exception {
        String baseUrl = "http://<hostname>:<port>/webservices/rest/servicelocator";
        String svcUrlStr1 = baseUrl + "/getRestInterface";
        //Invoke REST service
        invokeREST(svcUrlStr1, "<EBS username>", "<password>", "PLSQL:FND_PROFILE");
            }
    }

    Please note that resource information recorded earlier from the deployed WADL is now placed in the baseUrl and svcUrlStr1 elements. PLSQL:FND_PROFILE is the interface internal name and that it is assumed to be deployed in the instance.

    Note: Use https (instead of http) in the baseUrl if your Oracle E-Business Suite instance is running on the TLS-enabled environment. Additionally, you need to import the TLS certificate into your client JVM's keystore.

  10. Replace <EBS hostname>:<port>, <EBS username>, and <password> with the actual values in the code.

  11. Save your work by selecting File > Save All.

  12. Add required library for JSON format:

    Use the following steps to add the required library file to the project properties.

    1. Select and right-click on the project name you just created earlier to open a selection menu.

    2. Select Project Properties from the menu.

      The Default Properties dialog box opens.

    3. Select Libraries and Classpath, and click Add Library. The Add Library dialog box opens.

    4. In the Add Library dialog box, select the Project folder and then click New.

      The Create Library dialog box opens.

    5. In the Library Name field, enter 'Jersey-bundle_1.0.0.0_1-1-5-1.jar'.

      Click Add Entry. The Select Path Entry dialog box appears.

    6. In the Select Path Entry dialog box, locate and select the 'Jersey-bundle_1.0.0.0_1-1-5-1.jar' file that you have downloaded. This adds it to the Classpath.

      Click OK. The 'Jersey-bundle_1.0.0.0_1-1-5-1.jar' is now added to the Project folder.

    7. The Project Properties dialog box appears. Click OK. This project is now set up with the required library.

      Project Properties Dialog

      the picture is described in the document text

Invoking a REST Service Using a Java Class

After creating a project with a Java class RestInvocationGETMethod.java, you need to compile and run the process to invoke the REST service.

Use the following steps to compile and run the Java class:

  1. In the Application Navigator, right-click on the RestInvocationGETMethod.java Java class you just created at the design time. Select Make from the menu.

  2. Right-click on the RestInvocationGETMethod.java Java class. Select Run from the menu.

Monitor and verify this process and check for successful compilation in the Log window.

Request Header Information

In this example, getRestInterface Java method is exposed as a REST service operation with the GET method. There is no input payload for the GET method. The path variable {irepClassName} is replaced with actual value "PLSQL:FND_PROFILE" sent as part of the HTTP URL shown below when the getRestInterface REST service operation is invoked.

URL = http://<hostname>:<port>/webservices/rest/servicelocator/getRestInterface/PLSQL:FND_PROFILE

Note: For GET requests, JSON is the default output response format. Use Accept header application/xml to receive response in XML format. If Content-Type header is sent in a GET HTTP request, it will be ignored.

 Request Headers
            Authorization: Basic xxxxxxxxxxxxxxxxxxxxxxxx
            Accept: application/json
            Content-Language: en-US

Viewing Output Message

When the REST service is successfully invoked, the following output in JSON format appears in the Log window:

{
 "OutputParameters" : {
  "EbsRestServiceBean" :  {
   "alternateAlias" : "plsql/PLSQL:FND_PROFILE",
   "serviceAlias" : "NotAnything",
   "serviceName" : "PLSQL:FND_PROFILE",
   "wadlUrl" : "http://<hostname>:<port>/webservices/rest/profile?WADL"
  } ,
  "ControlBean" :  {
   "fields" : null,
   "filter" : null,
   "limit" : null,
   "offset" : null
  }
 }
}

Note: The message payload used here is an example. You should use the actual definition of the service in XSD and WADL.

Notice that the service information identified by its internal name PLSQL:FND_PROFILE is returned. For example, the WADL URL, service name, and service alias are included as part of the response message.

Annotating and Invoking a Custom Java Bean Service

Since not all Java APIs registered in the Integration Repository can be exposed as REST services, only some specialized Java APIs described earlier with proper annotation can be exposed as REST services. To better understand how to annotate those specialized Java APIs as Java Bean Services, and how to invoke Java Bean Services with REST service security, this section describes the entire process from annotating a custom Java API to invoking the service using the HTTP GET method.

REST Service Invocation Scenario

This example uses a custom Java API called Employee Service (oracle.apps.per.sample.service.EmployeeInfo) to explain the entire annotation and upload processes as well as the service invocation. There are two invocation scenarios. One scenario is to get employee details, and the other one is to get direct reports for the logged in user.

To get employee details, an HTML page with Javascript is used to make an HTTP GET request to the getPersonInfo service operation contained in the custom API. An employee ID is provided at runtime for the service to retrieve the associated employee name and the employee's manager name. After the successful service invocation, the employee details corresponding to the employee ID are displayed in the HTML page.

To get direct reports for the logged in user, a different HTML page with Javascript is used in this scenario to make an HTTP GET request to the getDirectReports service operation. The logged in user credentials are provided when the getDirectReports service operation is invoked. After the successful service invocation, the logged in user's subordinates or the user's direct reports are displayed in the HTML page with the requested number of records shown in each page.

High Level Process Flow for Creating Custom Java Bean Services

To develop custom Java Bean Services, an integration developer needs to create and annotate the custom Java APIs based on the Integration Repository Annotation Standards for Java Bean Services. After the interface creation, an integration administrator needs to validate the annotated APIs. If no error occurs during the validation, the administrator will then upload the custom APIs to Oracle Integration Repository where they can be published as REST services through Oracle E-Business Suite Integrated SOA Gateway.

For annotation information, see: Annotations for Java Bean Services.

Annotating and Invoking a Custom Java Bean Service from HTML Pages with Javascript

Based on the REST service invocation scenario, the following tasks are included in this section:

  1. Creating and Compiling Custom Java APIs

  2. Deploying Custom Java Classes and Source Files

  3. Parsing and Uploading the Annotated Custom Java Bean Service to the Integration Repository

  4. Deploying a Custom Java Bean Service

  5. Creating a Security Grant

  6. Recording Resource Information from Deployed WADL

  7. Invoking a Custom REST Service from HTML Pages with Javascript

Creating and Compiling Custom Java APIs

This section describes how to create and annotate a custom Java Bean Service called Employee Information (oracle.apps.per.sample.service.EmployeeInfo).

Guidelines for Developing Custom Java APIs

During the planning stage, use the following guidelines to plan and develop the custom Java APIs that will be exposed as REST services through Oracle E-Business Suite Integrated SOA Gateway:

  1. Develop a Java class whose public methods provide business functionality. Business logic should be embedded into these public methods.

    • The custom Java APIs and method names will be used in web service URL. Therefore, ensure to provide friendly names.

    • If you need initialized Oracle E-Business Suite Context within the Java method, ensure the following:

      • Use ISG Context (IContext) to get handle to runtime information.

        For example, IContext ctx = ContextManager.getContext();

      • Retrieve fully initialized Oracle E-Business Suite WebAppsContext based on the request header / security token.

        For example, WebAppsContext wctx = (WebAppsContext) ctx.getExternalContext();

        WebAppsContext may be used later for application specific validation, such as fine grained access control.

    • You may use the Oracle E-Business Suite Integrated SOA Gateway database connections within the Java APIs.

      For example, conn = DBConnectionManager.getConnection();

    • Oracle E-Business Suite Integrated SOA Gateway provides a standard exception handling from the infrastructure. Ensure that the Java APIs throw or rethrow a throwable exception whenever an error condition occurs.

  2. If the above Java methods require complex data objects to be exchanged as input and output parameters, then develop Java Beans.

    Java Beans should:

    • Implement java.io.Serializable.

    • Have no-argument constructor.

    • Have accessor methods, following 'get' and 'set' naming convention, for private attributes.

Creating Custom Java APIs

In this example, you need a service that will return the details of a specific person in the hierarchy of the logged in user, as well as return all the reports of the logged in user.

To achieve this goal, create the following Java files:

To create and compile custom Java APIs:

Use the following steps to create and compile custom Java APIs:

  1. Open Oracle JDeveloper.

  2. From the main menu, choose File > New.

    In the New Gallery window, expand the General category and select 'Applications'. In the Items list, select Custom Application.

    Click OK. The "Create Custom Application - Name your application" page is displayed.

  3. Enter an appropriate name for the application in the Application Name field. Click Next.

  4. The "Create Custom Application - Name your project" page is displayed. Enter an appropriate name for the project in the Project Name field, for example 'ISGJava_RESTDemo'.

    In the Project Features tab, select 'Java' from the Available list. Move the selected feature from the "Available" window to the "Selected" window using the right arrow button.

    Click Next.

  5. Click Finish in the Configure Java Settings dialog box.

    The newly created project should be visible in the Projects workspace.

  6. Add required libraries:

    Use the following steps to add the required library files to the project properties.

    1. Select and right-click on the project name "ISGJava_RESTDemo" you just created earlier to open a selection menu.

    2. Select Project Properties from the menu.

      Drop-Down Menu to Select Project Properties

      the picture is described in the document text

      The Default Properties dialog box opens.

    3. Select Libraries and Classpath, and click Add Library. The Add Library dialog box appears.

    4. In the Add Library dialog box, select and expand the Extension folder and choose 'Oracle JDBC' from the list.

      Add Library Dialog

      the picture is described in the document text

      Click OK. Oracle JDBC is added to the Classpath Entries section.

    5. Click Add JAR/Directory. The Add Archive or Directory dialog box appears.

      Browse the directory and locate the 'fndall.jar' file. Click Select to add the selected 'fndall.jar' file.

      Add Archive or Directory Dialog

      the picture is described in the document text

      Use the same approach to add 'isgagent.zip' file to the Classpath Entries region in the Project Properties dialog.

      Project Properties Dialog with Added Libraries

      the picture is described in the document text

      Click OK. This project is now set up with the required libraries.

  7. Select and right-click on the project name "ISGJava_RESTDemo" you just created and choose New from the drop-down selection menu.

  8. In the New Gallery window, expand the General category and select 'Java'. In the Items list, select Class. Click OK.

  9. In the Create Java Class dialog, create a Java class called PersonBean.java with the following information:

    • Name: PersonBean

    • Package: oracle.apps.per.sample.beans

    • Extends: java.lang.Ojbect

    Create Java Class Dialog

    the picture is described in the document text

    Click OK. The new class opens automatically in the source editor. Use the following Java code for PersonBean.java.

    package oracle.apps.per.sample.beans;
    
    import java.io.Serializable;
    
    import java.util.Date;
    
    public class PersonBean implements Serializable {
    
      private static final long serialVersionUID = 1L;
    
      private int personId;
    
      private String firstName;
    
      private String lastName;
    
      private String salutaion;
    
      private String fullName;
    
      private String nameSuffix;
    
      private String emailAddress;
    
      private String employeeNumber;
    
      private String workPhone;
    
      private Date startDate;
    
      private int reportingLevel;
    
      private int supervisorPersonId;
    
      private String supervisorEmployeeNumber;
    
      private String supervisorFullName;
    
      private String reportingHierarchy;
    
    
      public void setPersonId(int personId) {
        this.personId = personId;
      }
    
      public int getPersonId() {
        return personId;
      }
    
      public void setFirstName(String firstName) {
        this.firstName = firstName;
      }
    
      public String getFirstName() {
        return firstName;
      }
    
      public void setLastName(String lastName) {
        this.lastName = lastName;
      }
    
      public String getLastName() {
        return lastName;
      }
    
      public void setSalutaion(String salutaion) {
        this.salutaion = salutaion;
      }
    
      public String getSalutaion() {
        return salutaion;
      }
    
      public void setFullName(String fullName) {
        this.fullName = fullName;
      }
    
      public String getFullName() {
        return fullName;
      }
    
      public void setEmailAddress(String emailAddress) {
        this.emailAddress = emailAddress;
      }
    
      public String getEmailAddress() {
        return emailAddress;
      }
    
      public void setEmployeeNumber(String employeeNumber) {
        this.employeeNumber = employeeNumber;
      }
    
      public String getEmployeeNumber() {
        return employeeNumber;
      }
    
      public void setStartDate(Date startDate) {
        this.startDate = startDate;
      }
    
      public Date getStartDate() {
        return startDate;
      }
    
      public void setNameSuffix(String nameSuffix) {
        this.nameSuffix = nameSuffix;
      }
    
      public String getNameSuffix() {
        return nameSuffix;
      }
    
      public void setWorkPhone(String workPhone) {
        this.workPhone = workPhone;
      }
    
      public String getWorkPhone() {
        return workPhone;
      }
    
      public void setReportingLevel(int reportingLevel) {
        this.reportingLevel = reportingLevel;
      }
    
      public int getReportingLevel() {
        return reportingLevel;
      }
    
      public void setSupervisorPersonId(int supervisorPersonId) {
        this.supervisorPersonId = supervisorPersonId;
      }
    
      public int getSupervisorPersonId() {
        return supervisorPersonId;
      }
    
      public void setSupervisorEmployeeNumber(String supervisorEmployeeNumber) {
        this.supervisorEmployeeNumber = supervisorEmployeeNumber;
      }
    
      public String getSupervisorEmployeeNumber() {
        return supervisorEmployeeNumber;
      }
    
      public void setSupervisorFullName(String supervisorFullName) {
        this.supervisorFullName = supervisorFullName;
      }
    
      public String getSupervisorFullName() {
        return supervisorFullName;
      }
    
      public void setReportingHierarchy(String reportingHierarchy) {
        this.reportingHierarchy = reportingHierarchy;
      }
    
      public String getReportingHierarchy() {
        return reportingHierarchy;
      }
    
    }
    
  10. Repeat steps 7, 8, and 9 to create the following two Java classes:

    • PerServiceException.java with the following information:

      • Name: PerServiceException

      • Package: oracle.apps.per.sample.common

      • Extends: java.lang.Ojbect

      Use the following Java code for PerServiceException.java:

      package oracle.apps.per.sample.common;
      
      import oracle.apps.fnd.isg.app.ebs.rt.common.ServiceException;
      
      public class PerServiceException extends ServiceException {
      
        public PerServiceException(String message) {
            super(message);
        }
      
        public PerServiceException(Throwable t) {
            super(t);
        }
      
        public PerServiceException(String message, Throwable t) {
            super(message, t);
        }
      
        public PerServiceException(String errorCode, String message, Throwable t) {
            super(errorCode, message, t);
        }
      
      }
      
    • EmployeeInfo.java with the following information:

      • Name: EmployeeInfo

      • Package: oracle.apps.per.sample.service

      • Extends: java.lang.Ojbect

      Use the following Java code for EmployeeInfo.java:

      package oracle.apps.per.sample.service;
      
      import java.sql.Connection;
      import java.sql.SQLException;
      
      import java.util.ArrayList;
      import java.util.HashMap;
      import java.util.List;
      import java.util.Map;
      
      import oracle.apps.fnd.common.WebAppsContext;
      import oracle.apps.fnd.isg.common.IContext;
      import oracle.apps.fnd.isg.common.mgr.ContextManager;
      import oracle.apps.fnd.isg.common.mgr.DBConnectionManager;
      import oracle.apps.per.sample.beans.PersonBean;
      import oracle.apps.per.sample.common.PerServiceException;
      
      import oracle.jdbc.OraclePreparedStatement;
      import oracle.jdbc.OracleResultSet;
      
      
      /**
       * A sample class to demonstrate how Java API can use the ISG REST framework. This class provides
       * methods to retrieve list of direct reports, all reports of a person. It also has methods to
       * retrieve personal details and accrual balance of a person.
       * @rep:scope public
       * @rep:product PER
       * @rep:displayname Employee Information
       * @rep:category IREP_CLASS_SUBTYPE JAVA_BEAN_SERVICES
       */
      public class EmployeeInfo {
      
        public EmployeeInfo() {
          super();
        }
      
        /**
           * This method returns a list of direct reports of the requesting user.
           *
           * @return List of person records who are direct reports
           * @rep:paraminfo {@rep:innertype oracle.apps.per.sample.beans.PersonBean}
           * @rep:scope public
           * @rep:displayname Get Direct Reports
           * @rep:httpverb get
           * @rep:category BUSINESS_ENTITY sample
           */
        // Demonstration of list return type
       public List<PersonBean> getDirectReports() throws PerServiceException {
      
          // Get the ISG context, which has runtime information
          IContext ctx = ContextManager.getContext();
          // Retrieve fully initialized webappscontext, as per the request header / security token
          WebAppsContext wctx = (WebAppsContext) ctx.getExternalContext();
      
          // Use webappscontext for apps specific validation e.g. fine grained access control etc.
          int userId = wctx.getUserId();
          String userName = wctx.getUserName().toUpperCase();
      
          // Here we intend to filter based on the specific user who is invoking the service
          String filter = " AND LEVEL = 2 START WITH USER_NAME = :1";
      
          List<PersonBean> personList = null;
          try {
            Map<Integer, PersonBean> map = makeBean(filter, userName);
            if (map != null)
              personList = new ArrayList<PersonBean>(map.values());
          } catch (SQLException sqle) {
            throw new PerServiceException("SQL error while getting the all reports", sqle);
          }
      
          return(personList);
        } 
      /**
           * This method returns an array of all reports of the requesting user.
           *
           * @return Array of person records who are reporting into the requesting user's organization hierarchy
           * @rep:scope public
           * @rep:displayname Get All Reports
           * @rep:httpverb get
           * @rep:category BUSINESS_ENTITY sample
           */
        // Demonstration of array return type
       public PersonBean[] getAllReports() throws PerServiceException {
      
          // Get the ISG context, which has runtime information
          IContext ctx = ContextManager.getContext();
          // Retrieve fully initialized webappscontext, as per the request header / security token
          WebAppsContext wctx = (WebAppsContext) ctx.getExternalContext();
      
      
          // Use webappscontext for apps specific validation e.g. fine grained access control etc.
          int userId = wctx.getUserId();
          String userName = wctx.getUserName().toUpperCase();
      
          // Here we intend to filter based on the specific user who is invoking the service
          String filter = " START WITH USER_NAME = :1 ";
      
          PersonBean[] array = null;
      
          try {
            Map<Integer, PersonBean> map = makeBean(filter, userName);
            if (map != null)
              array = map.values().toArray(new PersonBean[map.size()]);
          } catch (SQLException sqle) {
            throw new PerServiceException("SQL error while getting the direct reports", sqle);
          }
      
          return(array);
      
        }
      
        /**
         * This method returns the person details for a specific person id. Throws error if the person
         * is not in requesting user's org hierarchy.
         *
         * @return Details of a person in the logged on user's org hierarchy.
         * @param personId Person Identifier
         * @rep:paraminfo {@rep:required} {@rep:key_param}
         * @rep:scope public
         * @rep:displayname Get Person Details
         * @rep:httpverb get
         * @rep:category BUSINESS_ENTITY sample
         */
        // Demonstration of simple navigation using path param
        public PersonBean getPersonInfo(int personId) throws PerServiceException {
      
          // Get the ISG context, which has runtime information
          IContext ctx = ContextManager.getContext();
          // Retrieve fully initialized webappscontext, as per the request header / security token
          WebAppsContext wctx = (WebAppsContext) ctx.getExternalContext();
      
          // Use webappscontext for apps specific validation e.g. fine grained access control etc.
          int userId = wctx.getUserId();
          String userName = wctx.getUserName().toUpperCase();
      
          String filter = " START WITH USER_NAME = :1 ";
          Map<Integer, PersonBean> map = null;
          try {
            map = makeBean(filter, userName);
          } catch (SQLException sqle) {
            throw new PerServiceException("SQL error while getting the direct reports", sqle);
          }
      
          if (map == null)
            throw new PerServiceException(PerServiceException.AUTHORIZATION_FAILURE, "No org hierarchy found for user - " + userName, null);
      
          boolean doesExist = map.containsKey(personId);
          if (!doesExist)
            throw new PerServiceException(PerServiceException.AUTHORIZATION_FAILURE, "The given person " + personId + " either does not exist or does not belong to the current user's - " + userName + " hierarchy", null);
      
          PersonBean bean = map.get(personId);
      
          return(bean);
      
        }
      
        /************************* private members ****************************/
      
        private Map<Integer, PersonBean> makeBean(String sqlFilter, String userName) throws SQLException {
      
          Connection conn = null;
          OraclePreparedStatement stmt = null;
          OracleResultSet rs = null;
          HashMap<Integer, PersonBean> personMap = new HashMap<Integer, PersonBean>();
          IContext ctx = ContextManager.getContext();
      
          try {
      
            String sql = GET_PERSON_INFO1 + sqlFilter;
      
            // preferred way of obtaining connection, rather than from WebAppsContext
            conn = DBConnectionManager.getConnection();
            stmt = (OraclePreparedStatement) conn.prepareStatement(sql);
            stmt.setString(1, userName);
            rs = (OracleResultSet) stmt.executeQuery();
      
            while (rs != null && rs.next()) {
      
              int personId = rs.getInt(1);
              String firstName = rs.getString(2);
              String lastName = rs.getString(3);
              String title = rs.getString(4);
              String fullName = rs.getString(5);
              String nameSuffix = rs.getString(6);
              String empNumber = rs.getString(7);
              String emailAddr = rs.getString(8);
              String workPhone = rs.getString(9);
              int supervisorId = rs.getInt(10);
              java.util.Date startDate = rs.getDate(12);
              int level = rs.getInt(16);
              String supervisorName = rs.getString(17);
              String supervisorEmpNumber = rs.getString(18);
              String reporting = rs.getString(19);
      
              // Do any data validation / transformation if necessary, here
      
              PersonBean personBean = new PersonBean();
      
              // Set the information into the serializable bean
              personBean.setPersonId(personId);
              personBean.setFirstName(firstName);
              personBean.setLastName(lastName);
              personBean.setSalutaion(title);
              personBean.setFullName(fullName);
              personBean.setNameSuffix(nameSuffix);
              personBean.setEmployeeNumber(empNumber);
              personBean.setEmailAddress(emailAddr);
              personBean.setWorkPhone(workPhone);
              personBean.setSupervisorPersonId(supervisorId);
              personBean.setStartDate(startDate);
              personBean.setReportingLevel(level);
              personBean.setSupervisorFullName(supervisorName);
              personBean.setSupervisorEmployeeNumber(supervisorEmpNumber);
              personBean.setReportingHierarchy(reporting);
      
              personMap.put(personId, personBean);
      
            }
      
          } finally {
      
            if (rs != null) {
              try { rs.close(); } catch (Exception e) {};
              rs = null;
            }
      
            if (stmt != null) {
              try { stmt.close(); } catch (Exception e) {};
              stmt = null;
            }
      
            // preferred way of closing the connection
            DBConnectionManager.closeConnection(conn);
      
          }
      
          return(personMap);
      
        }
      
        private static final String GET_PERSON_INFO1 = "SELECT  DISTINCT  E.PERSON_ID, E.FIRST_NAME, E.LAST_NAME, E.TITLE, E.FULL_NAME, E.SUFFIX,\n" +
                                                "E.EMPLOYEE_NUMBER, E.EMAIL_ADDRESS, E.WORK_TELEPHONE, E.SUPERVISOR_ID,\n" +
                                                "E.SUPERVISOR_ASSIGNMENT_ID, E.EFFECTIVE_START_DATE, E.EFFECTIVE_END_DATE,\n" +
                                                "E.USER_ID, E.USER_NAME, LEVEL, PRIOR E.FULL_NAME, PRIOR E.EMPLOYEE_NUMBER,\n" +
                                                "SYS_CONNECT_BY_PATH(E.FULL_NAME, '/')\n" +
                                                "FROM\n" +
                                                "(SELECT PPF.PERSON_ID,\n" +
                                                "PPF.FIRST_NAME,\n" +
                                                "PPF.LAST_NAME,\n" +
                                                "PPF.TITLE,\n" +
                                                "PPF.FULL_NAME,\n" +
                                                "PPF.SUFFIX,\n" +
                                                "PPF.EMPLOYEE_NUMBER,\n" +
                                                "PPF.EMAIL_ADDRESS,\n" +
                                                "PPF.WORK_TELEPHONE,\n" +
                                                "PAF.SUPERVISOR_ID,\n" +
                                                "PAF.SUPERVISOR_ASSIGNMENT_ID,\n" +
                                                "GREATEST(PPF.EFFECTIVE_START_DATE,    PAF.EFFECTIVE_START_DATE) EFFECTIVE_START_DATE, \n" +
                                                "LEAST(PPF.EFFECTIVE_END_DATE,    PAF.EFFECTIVE_END_DATE) EFFECTIVE_END_DATE,\n" +
                                                "FUR.USER_ID,\n" +
                                                "FUR.USER_NAME\n" +
                                                "FROM FND_USER FUR, PER_ALL_PEOPLE_F PPF,\n" +
                                                "PER_ALL_ASSIGNMENTS_F PAF\n" +
                                                "WHERE PPF.PERSON_ID = PAF.PERSON_ID (+)\n" +
                                                "AND PPF.BUSINESS_GROUP_ID = PAF.BUSINESS_GROUP_ID (+)\n" +
                                                "AND (SYSDATE BETWEEN PPF.EFFECTIVE_START_DATE\n" +
                                                "AND PPF.EFFECTIVE_END_DATE\n" +
                                                "AND SYSDATE BETWEEN PAF.EFFECTIVE_START_DATE\n" +
                                                "AND PAF.EFFECTIVE_END_DATE)\n" +
                                                "AND FUR.EMPLOYEE_ID = PPF.PERSON_ID\n" +
                                                ") E\n" +
                                                "CONNECT BY SUPERVISOR_ID = PRIOR PERSON_ID";
      
      }
      
  11. Save your work by selecting File > Save All.

  12. Select and right-click on the project name "ISGJava_RESTDemo" and choose Make Project1.jpr from the drop-down selection menu. The compilation process starts.

    Verify that the compilation process is successful in the Message - Log window.

Deploying Custom Java Classes and Source Files

Once the custom Java API has been successfully created, the integration developer needs to copy these newly-created Java classes and source files to a target instance.

For information on how to deploy these custom Java classes, refer to Section 5: Deploying Custom Application Tier Objects, Deploying Customizations in Oracle E-Business Suite Release 12.2, My Oracle Support Knowledge Document 1577661.1.

After the successful deployment to a target instance, stop and restart the managed server.

Parsing and Uploading the Annotated Custom Java Bean Service to the Integration Repository

Once the custom Java classes have been successfully deployed to a target instance, the integration administrator needs to validate the annotated custom interface definition Employee Information against the annotation standards for Java Bean Services using Integration Repository Parser. During the validation, if no error occurs, an iLDT file will be generated. The administrator will then upload the generated iLDT file to Oracle Integration Repository.

Perform the following steps to parse and upload the annotated custom interface definition Employee Information to Oracle Integration Repository:

  1. Source the environment in the run file system and set CLASSPATH to include all libraries and JAR files used by the custom Java API.

  2. Ensure the annotated custom interface definition and related Java classes are located in the target instance.

    Verification of the Annotated Custom Interface Definition

    the picture is described in the document text

  3. Run the Integration Repository Parser using the following command to validate the annotated custom interface definition against the annotation standards:

    $IAS_ORACLE_HOME/perl/bin/perl $FND_TOP/bin/irep_parser.pl -g -v -username=sysadmin per:patch/115/java:EmployeeInfo.java:12.2=EmployeeInfo.java

    Integration Repository Parser Command Process and Validation

    the picture is described in the document text

    The EmployeeInfo_java.ildt file is successfully generated after the validation.

  4. Upload the generated EmployeeInfo_Java.ildt file to the Integration Repository by using the following FNDLOAD command:

    $FND_TOP/bin/FNDLOAD <APPS username> @TWO_TASK 0 Y UPLOAD $FND_TOP/patch/115/import/wfirep.lct EmployeeInfo_java.ildt
    ORACLE Password:
  5. Verify the generated log file to view the upload details.

    Upload Details in the Log File

    the picture is described in the document text

    Notice that the upload process has been completed successfully.

  6. Search the uploaded custom Java Service Beans interface "Employee Information" from the Integration Repository.

    Click the Employee Information name link to open the interface details page.

Deploying a Custom Java Bean Service

Use the following steps to deploy the custom interface as a REST service:

  1. Log in to Oracle E-Business Suite as a user who has the Integration Administrator role.

    Select the Integrated SOA Gateway responsibility and the Integration Repository link from the navigation menu.

  2. In the Integration Repository tab, click Search to access the main Search page.

  3. Click Show More Search Options to display more search fields.

    Select 'Custom' in the Interface Source field.

  4. Click Go.

    Click the "Employee Information" interface name link to open the interface details page.

  5. In the REST Web Service tab, enter the following information:

    • Service Alias: empinfo

      The alias will be displayed as the service endpoint in the WADL and schema for the selected method or operation.

    • Select the 'POST' checkbox for the Get Person Details Java method. Leave the rest of preselected checkboxes unchanged.

    • In the REST Service Security region, ensure that at least one authentication type is selected.

  6. Click Deploy to deploy the service to an Oracle E-Business Suite WebLogic environment.

Once the REST service has been successfully deployed, 'Deployed' appears in the REST Service Status field, along with the View WADL link. Click the View WADL link to view the deployed service WADL description.

For more information on deploying REST services, see Deploying REST Web Services, Oracle E-Business Suite Integrated SOA Gateway Implementation Guide.

Creating a Security Grant

After deploying the custom interface "Employee Information" as a REST service, the integration administrator can create a security grant to authorize the service access privileges to all users.

Use the following steps to create a security grant:

  1. Log in to Oracle E-Business Suite as a user who has the Integration Administrator role. Select the Integrated SOA Gateway responsibility and the Integration Repository link from the navigation menu.

  2. Perform a search to locate the "Employee Information" service the administrator just deployed earlier.

  3. Select the "Employee Information" name link from the search result table to display the interface details page. Click the Grants tab.

  4. Select the Employee Information service and then click Create Grant.

  5. In the Create Grants page, select "All Users" as the Grantee Type.

    Note: In this example, the Employee Information service is granted to all users. In actual implementation, you should define strict security rules. Create grant to a user or more appropriately to a group of users defined by roles and responsibilities.

    Click Create Grant. This grants the selected service access privilege to all Oracle E-Business Suite users.

Recording Resource Information from Deployed WADL

To obtain service resource information from the deployed WADL for the custom Employee Information service, click the View WADL link in the REST Web Service tab.

The following WADL description appears:

<xml version="1.0" encoding="UTF-8"> 
<application name="EmployeeInfo" targetNamespace="http://xmlns.oracle.com/apps/per/soaprovider/pojo/employeeinfo/"
 xmlns:tns="http://xmlns.oracle.com/apps/per/soaprovider/pojo/employeeinfo/" 
 xmlns="http://wadl.dev.java.net/2009/02" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
 xmlns:tns1="http://xmlns.oracle.com/apps/fnd/rest/empinfo/getallreports/" 
 xmlns:tns2="http://xmlns.oracle.com/apps/fnd/rest/empinfo/getdirectreports/" 
 xmlns:tns3="http://xmlns.oracle.com/apps/fnd/rest/empinfo/getpersoninfo/">

<grammars>
                <include href="http://<hostname>:<port>/webservices/rest/empinfo/?XSD=getallreports.xsd" xmlns="http://www.w3.org/2001/XMLSchema" /> 
                        <include href="http://<hostname>:<port>/webservices/rest/empinfo/?XSD=getdirectreports.xsd" xmlns="http://www.w3.org/2001/XMLSchema" /> 
                        <include href="http://<hostname>:<port>/webservices/rest/empinfo/?XSD=getpersoninfo.xsd" xmlns="http://www.w3.org/2001/XMLSchema" />
</grammars>
<resources base="http://<hostname>:<port>/webservices/rest/empinfo/">
  <resource path="/getAllReports/">
        <method id="getAllReports" name="GET">
                <request>
                          <param name="ctx_responsibility" type="xsd:string" style="query" required="false" />
           <param name="ctx_respapplication" type="xsd:string" style="query" required="false" />
                                <param name="ctx_securitygroup" type="xsd:string" style="query" required="false" />
                                <param name="ctx_nlslanguage" type="xsd:string" style="query" required="false" />
                                <param name="ctx_orgid" type="xsd:int" style="query" required="false" />
                        </request>
                        <response>
                                        <representation mediaType="application/xml" type="tns1:getAllReports_Output" /> 
                                        <representation mediaType="application/json" type="tns1:getAllReports_Output" /> 
                                </response>
                        </method>
                </resource> 
 <resource path="/getDirectReports/">
                <method id="getDirectReports" name="GET">
                                <request>
                                        <param name="ctx_responsibility" type="xsd:string" style="query" required="false" />
              <param name="ctx_respapplication" type="xsd:string" style="query" required="false" />
                                        <param name="ctx_securitygroup" type="xsd:string" style="query" required="false" />
                                        <param name="ctx_nlslanguage" type="xsd:string" style="query" required="false" />
                                        <param name="ctx_orgid" type="xsd:int" style="query" required="false" />
                                </request>
                        <response>
                                        <representation mediaType="application/xml" type="tns2:getDirectReports_Output" /> 
                                        <representation mediaType="application/json" type="tns2:getDirectReports_Output" /> 
                                </response>
                        </method>
                </resource>
 <resource path="="/getPersonInfo/ {personId}/">
  <param name="personId" style="template" required="true" type="xsd:int" /> 
        <method id="getPersonInfo" name="GET">
                <request>
                          <param name="ctx_responsibility" type="xsd:string" style="query" required="false" />
           <param name="ctx_respapplication" type="xsd:string" style="query" required="false" />
                                <param name="ctx_securitygroup" type="xsd:string" style="query" required="false" />
                                <param name="ctx_nlslanguage" type="xsd:string" style="query" required="false" />
                                <param name="ctx_orgid" type="xsd:int" style="query" required="false" />
                        </request>
                        <response>
                                        <representation mediaType="application/xml" type="tns3:getPersonInfo_Output" /> 
                                        <representation mediaType="application/json" type="tns3:getPersonInfo_Output" /> 
                                </response>
                        </method>
                </resource> 
 <resource path="/getPersonInfo/">
                <method id="getPersonInfo" name="POST">
                                <request>
                                   <representation mediaType="application/xml" type="tns3:getPersonInfo_Input" /> 
                                        <representation mediaType="application/xml" type="tns3:getPersonInfo_Output" />   
                                </request>
                        <response>
                                   <representation mediaType="application/xml" type="tns3:getPersonInfo_Input" /> 
                                        <representation mediaType="application/xml" type="tns3:getPersonInfo_Output" />                           </response>
                        </method>
                </resource>
  </resource path>
</application>

Copy or record the following information which will be used later when defining a Java client:

Invoking a Custom REST Service from HTML Using Javascript

This example contains two invocation scenarios:

  1. Get employee personal information by invoking the getPersonInfo REST service operation

  2. Get direct reports for the logged in user by invoking the getDirectReports REST service operation with pagination control parameter

Scenario 1: Get Employee Personal Information

Use the following steps to invoke the deployed the getPersonInfo REST service operation:

  1. Create an HTML file using any text editor with the following content:

    Replace <hostname>:<port>, <EBS username>, and <password> with the actual values in the code.

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
     <head>
      <title>Oracle E-Business Suite Integrated SOA Gateway - REST Services Sample</title>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <style>
                    table,th,td
                    {
                            border:1px solid black;
                            border-collapse:collapse;
                    }
                    th,td
                    {
                            padding:5px;
                    }
      </style
      <script language="javascript">
       function getEmpDetails()
                    {
                            var xmlhttp;
                            if (window.XMLHttpRequest)
                            {// code for IE7+, Firefox, Chrome, Opera, Safari
                                    xmlhttp=new XMLHttpRequest();
                            }
                            else
                            {// code for IE6, IE5
                                    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
                            }
                            xmlhttp.onreadystatechange=function()
                            {
                                    if (xmlhttp.readyState==4 && xmlhttp.status==200)
                                    {
                                            var det = eval( "(" +  xmlhttp.responseText + ")");
                                            document.getElementById('div1').innerHTML=det.OutputParameters.PersonBean[0].fullName;
                                            document.getElementById('div2').innerHTML=det.OutputParameters.PersonBean[0].supervisorFullName;
                                    }
                            }
    
                            var empno = document.getElementById("empno");
                            var url = "http://<hostname>:<port>/webservices/rest/empinfo/getPersonInfo/" + empno.value;
    
                            xmlhttp.open('GET',url,true,"<EBS username>", "<password>");
                            xmlhttp.send();
                    }
     </script>
    </head>
    <body>
     <center><h1>Oracle E-Business Suite Integrated SOA Gateway - REST Services Sample</h1>
             <h2>Path Parameter Example</h2>
     </center>
      <h3>This example demonstrates the use of Path Parameters in REST Service URL.
            ISG REST Service expects personId as input.     personId was annotated as key_param. Hence, it can be sent as part of GET request URL.
            This example does not set Accept header in HTTP Request. REST Service returns response in JSON format (JSON is default message format).<br><br>
    Enter employee id and click Get Details button. ISG REST Service will be invoked. Employee Name and his / her Manager's Name will be displayed.<br>
    </h3>
     <center><table>
    <tr>
      <td>Enter Employee ID</td>
      <td><input type="text" id="empno" size="10"/> <input type="button" value="Get Details" onclick="getEmpDetails()"/>
    </tr>
    <tr>
      <td>Employee Name</td>
      <td><div id="div1/></div></td>
    </tr>
    <tr>
      <td>Manager Name</td>
      <td><div id="div1/></div></td>
    </tr>
    </table>
    </body>
    </html>

    This invocation scenario uses the path parameter {personId} to obtain the employee ID at runtime. The getPersonInfo service operation is then invoked through the HTTP GET request.

    <resource path="="getPersonInfo/{personId}/">
      <param name="personId" style="template" required="true" type="xsd:int"/>
        <method id="getPersonInfo" name="GET">
    

    The path parameter {personId} was annotated earlier in @rep:key_param and can be sent as a GET request URL.

    This example does not set the Accept header in the GET request. The REST service returns a response message in the default JSON format.

  2. View the HTML page in a browser window.

    HTML Page to Invoke a REST Service for Path Parameter Example

    the picture is described in the document text

  3. Enter an Employee ID (path parameter {personId}), such as 13137, in the HTML page and click Get Details. This invokes the getPersonInfo REST service operation and returns the associated employee's name and the manager's name of the employee.

    In this example, Taylor, Mr. Steve who has the employee ID 13137 is displayed as the Employee Name; Bennett, Terrence G (Terry) who is Taylor's manager is displayed as Manager Name.

    Note: Employee details in this example represent a fictitious sample (based upon made up data used in the Oracle Demo Vision instance). Any similarity to actual persons, living or dead, is purely coincidental and not intended in any manner.

    HTML Page with Employee Personal Information

    the picture is described in the document text

Scenario 2: Get Direct Reports for the Logged in User

Use the following steps to invoke the deployed the getDirectReports REST service operation:

  1. Create an HTML file using any text editor with the following content:

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
     <head>
      <title>Oracle E-Business Suite Integrated SOA Gateway - REST Services Sample</title>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <style>
                    table,th,td
                    {
                            border:1px solid black;
                            border-collapse:collapse;
                    }
                    th,td
                    {
                            padding:5px;
                    }
      </style
      <script language="javascript">
       function getPrev()
                    {
                            offset = parseInt(offset) - 3;
                            getDirectReports(offset);
                    }
    
                    function getNext()
                    {
                            offset = parseInt(offset) + 3;
                            getDirectReports(offset);
                    }
    
                    function getDirectReports(offsetP)
                    {
                            var xmlhttp;
                            if (window.XMLHttpRequest)
                            {// code for IE7+, Firefox, Chrome, Opera, Safari
                                    xmlhttp=new XMLHttpRequest();
                            }
                            else
                            {// code for IE6, IE5
                                    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
                            }
                            xmlhttp.onreadystatechange=function()
                            {
                                    if (xmlhttp.readyState==4 && xmlhttp.status==200)
                                    {
    
                                            xmlDoc=xmlhttp.responseXML;
                                            txt="";
                                            retRows=0;
                                            x=xmlDoc.getElementsByTagName("PersonBean");
    
                                            if (x.length > 0)
                                            {
                                                    txt = "<br><table border = \"1\"><tr><th>Employee Id</th><th>Employee Name</th></tr>";
                                            }
                                            else
                                            {
                                                    txt = "No records to display";
                                            }
    
                                            for (i=0;i<3;i++)
                                            {
                                                    txt = txt + "<tr><td>" + xmlDoc.getElementsByTagName("personId")[i].firstChild.nodeValue + "+ xmlDoc.getElementsByTagName("personId")[i].firstChild.nodeValue + "</td>";      
                                                    txt = txt + "<td>" + xmlDoc.getElementsByTagName("fullName")[i].firstChild.nodeValue + " + xmlDoc.getElementsByTagName("fullName")[i].firstChild.nodeValue + "</td></tr>";    
                                            }
    
                                            if (x.length > 0)
                                            {
                                                    txt = txt + "</table><br>"; 
                                            }
    
                                            y=xmlDoc.getElementsByTagName("ControlBean");
                                            rOffset = xmlDoc.getElementsByTagName("offset")[0].firstChild.nodeValue;
                                            rFrom = 1 + parseInt(rOffset);
                                            rTo = 3 + parseInt(rOffset);
                                            txt = txt + "Displaying " + rFrom;
                                            txt = txt + " to " + rTo + " records.<br>";
                                            document.getElementById("div1").innerHTML=txt;
    
                                            if(offsetP > 2) {
                                                    document.getElementById("div2").innerHTML="<input type=\"button\" value=\"Previous\" onclick=\"getPrev()\"/>";
                                            }
                                            else
                                            {
                                                    document.getElementById("div2").innerHTML="";
                                            }
    
                                            if(x.length == 4) {
                                                    document.getElementById("div3").innerHTML="<input type=\"button\" value=\"Next\" onclick=\"getNext()\"/>";
                                            }
                                            else
                                            {
                                                    document.getElementById("div3").innerHTML="";
                                            }
    
    
                                    }
                            }
    
            var url = "http://<hostname>:<port>/webservices/rest/empinfo/getDirectReports/?ctx_orgid=204&limit=4&offset" + offsetP;
    
                            xmlhttp.open('GET',url,true);
                            xmlhttp.setRequestHeader("Accept", "application/xml");
                            xmlhttp.send();
                    }
     </script>        
    </head>
    <body>
     <center><h1>Oracle E-Business Suite Integrated SOA Gateway - REST Services Sample</h1>
             <h2>Pagination Control Parameters Example</h2>
     </center>
      <h3>This example demonstrates the use of Pagination Control Parameters. When you click Get Directs button, ISG REST Service will be invoked. Provide EBS username
            and password. On successful invocation, the first 3 direct reports (employees) of the logged in user will be displayed. Next and Previous buttons will be displayed
            based on the number of records.
    </h3>
     <center>
            <input type="button" value="Get Directs" onclick="getDirectReports(0)"/>
            <div id="div1/></div>
       <div id="div2/></div>
       <div id="div3/></div>
     </center>
    
    <script type="text/javascript"><!--
            offset=0;
        //--></script>
    
    </body>
    </html>

    This invocation scenario uses the pagination control parameter offset defined in the Javascript to limit the number of records returned at runtime and for pagination when the getDirectReports service operation is invoked through the HTTP GET request.

    <script language="javascript">
    ...
                            
            var url = "http://<hostname>:<port>/webservices/rest/empinfo/getDirectReports/?ctx_orgid=204&limit=4&offset" + offsetP;
    
                            xmlhttp.open('GET',url,true);
                            xmlhttp.setRequestHeader("Accept", "application/xml");
                            xmlhttp.send();
                    }
    </script>         
    

    This example sets the Accept header in the GET request. The REST service returns a response message in XML format.

  2. View the HTML page in a browser window.

    HTML Page to Invoke a REST Service for Pagination Control Parameters Example

    the picture is described in the document text

  3. Click Get Directs in the HTML page. This invokes the getPersonInfo REST service operation. A pop-up window appears requiring you to enter the user name and password.

    After you entered the user name and password and clicked OK, the service returns the first three direct reports (employees) of the user you just entered in the table. Click Next to display the next three records retrieved from the direct reports list. Click Previous to display the last three records from the current direct reports list.

    HTML Page with Direct Reports Shown as the Results

    the picture is described in the document text

    Note: Employee details shown in the above screenshot represent a fictitious sample (based upon made up data used in the Oracle Demo Vision instance). Any similarity to actual persons, living or dead, is purely coincidental and not intended in any manner.

Invoking an Application Module Service Using Token Based Authentication and XML Payload

REST Service Invocation Scenario

Take an Application Module Service called 'Approvals Management' (oracle.apps.fnd.wf.worklist.service.rt.server.WFWorklistServiceAMImpl) as an example to explain the REST service invocation. The Get Open Notifications (getOpenNotifications) REST service operation contained in this interface is used in this example to return a list of all open notifications for the current user.

When consequent HTTP requests are received, the getOpenNotifications service operation is invoked to fetch all open workflow notifications for the current user based on the input payload sent in XML format as a REST request. You can retrieve results in a batch by providing page size and page number in the request.

Since password is not provided in this request, token based security method is used to authenticate the user credentials. The security Login service is launched to create an Oracle E-Business Suite user session and returns the session ID as cookie in place of password for user authentication.

After validation, the getOpenNotifications REST service operation can be invoked to return all open notification in XML format as part of the output response message.

Prerequisites to Use an Application Module Service

Before performing the design-time tasks, ensure the following tasks are in place:

Obtaining Needed Library for This Example

To successfully invoke the REST service with payload in XML format, you need to obtain the following library available at <$COMMON_TOP>/java/lib directory for this example:

This library file will be added to the project later at the design time during the project creation.

Setting Variables in RESTHeader for an HTTP Request

In REST services, application context values can be passed in the 'RESTHeader' element before invoking a REST service.

These RESTHeader elements are Responsibility, RespApplication, SecurityGroup, NLSLanguage, and Org_Id.

For more information about the RESTHeader elements, see REST Header for Application Context.

Invoking a REST Service Using Java

Based on the REST service invocation scenario, the following tasks are included in this section:

  1. Deploying a REST Service

  2. Recording the Deployed WADL URL

  3. Creating a Security

  4. Creating a Project with a Java Class

  5. Invoking a REST Service Using a Java Class

Deploying a REST Service

Use the following steps to deploy the Application Module Service called 'Approvals Management':

  1. Log in to Oracle E-Business Suite as a user who has the Integration Administrator role. Select the Integrated SOA Gateway responsibility and then choose the Integration Repository link from the navigation menu.

  2. In the Integration Repository tab, click Search to access the main Search page.

  3. Click Show More Search Options to display more search fields.

    Enter the following key search values as the search criteria:

    • Category: Interface Subtype

    • Category Value: Application Module Services

  4. Click Go.

    Click the 'Approvals Management' interface name link to open the interface details page.

  5. In the REST Web Service tab, enter the following information:

    REST Web Service Tab

    the picture is described in the document text

    • Service Alias: notification

      The alias will be displayed as the service endpoint in the WADL and schema for the selected method or service operation which is getOpenNotifications in this example.

    • In the Service Operations region, select 'Get Open Notifications' (getOpenNotifications).

      The selected method will be exposed as a REST service operation.

    • In the REST Service Security region, ensure that at least one authentication type is selected.

  6. Click Deploy to deploy the service to an Oracle E-Business Suite WebLogic environment.

Once the REST service has been successfully deployed, 'Deployed' appears in the REST Service Status field, along with the View WADL link allowing you to view the WADL description.

For more information on deploying REST services, see Deploying REST Web Services, Oracle E-Business Suite Integrated SOA Gateway Implementation Guide.

Recording the Deployed WADL URL

To obtain service resource information from the deployed WADL for the 'Approvals Management' REST service, an integration developer clicks the View WADL link in the REST Web Service tab.

REST Web Service Tab with Deployed "View WADL" Link Highlighted

the picture is described in the document text

Copy or record the following information from the WADL description which will be used later when defining a Java client:

Creating a Security Grant

After deploying the 'Approvals Management' interface as a REST service, the integration administrator can create a security grant to authorize the service or method access privileges to a specific user, a user group, or all users.

Use the following steps to create a security grant:

  1. Log in to Oracle E-Business Suite as a user who has the Integration Administrator role. Select the Integrated SOA Gateway responsibility and the Integration Repository link from the navigation menu.

  2. Perform a search to locate the Approvals Management service the administrator just deployed earlier.

  3. In the interface details page of the selected Approvals Management service, click the Grants tab.

  4. Select the getOpenNotifications method checkbox and then click Create Grant.

  5. In the Create Grants page, select "All User" as the Grantee Type.

    Note: In this example, the getOpenNotifications service operation is granted to all users. In actual implementation, you should define strict security rules. Create grant to a user or more appropriately to a group of users defined by roles and responsibilities.

    Click Create Grant. This grants the selected method access privilege to all Oracle E-Business Suite users.

    Interface Details Page with Grants Tab

    the picture is described in the document text

Creating a Project with a Java Class

This section describes how to create a project with a Java class (AMClient.java) and XML payload that will be used to invoke the 'Approvals Management' REST service.

To create a project with a Java class:

  1. In Oracle JDeveloper, choose File > New from the main menu.

    In the New Gallery window, expand the General category and select 'Applications'. In the Items list, select Custom Application.

    Click OK. The "Create Custom Application - Name your application" page is displayed.

  2. Enter an appropriate name for the application in the Application Name field. Click Next.

  3. The "Create Custom Application - Name your project" page is displayed. Enter an appropriate name for the project in the Project Name field, for example 'ISGAMClient'.

    In the Project Features tab, select 'Java' from the Available list. Move the selected feature from the "Available" window to the "Selected" window using the right arrow button.

    Click Next

  4. Click Finish in the Configure Java Settings dialog box.

  5. In the Application Navigator and right-click on the project you just created, and choose New from the drop-down menu.

  6. In the New Gallery window, expand the General category and select 'Java'. In the Items list, select Class. Click OK.

  7. In the Create Java Class dialog, change the default class name to 'AMClient'. Accept all other defaults and click OK.

  8. The new class opens automatically in the source editor, displaying the skeleton class definition.

    Replace the skeleton class definition with the following Java code:

    package sample;
    
    import java.net.HttpURLConnection;
    import java.net.URL;
    import com.sun.jersey.core.util.Base64;
    import java.io.BufferedReader;
    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.parsers.DocumentBuilder;
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    
    public class AMClient {
        public AMClient() {
            super();
        }
    
     private static final String xmlRequest1 = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
     "<getOpenNotifications_Input>\n" +   
     "  <RESTHeader>\n" + 
     "      <NLSLanguage>AMERICAN</NLSLanguage>\n" + 
     "      <Org_Id>202</Org_Id>\n" +
     "      <RespApplication>SYSADMIN</RespApplication>\n" +
     "      <Responsibility>SYSTEM_ADMINISTRATOR</Responsibility>\n" +
     "      <SecurityGroup>STANDARD</SecurityGroup>\n" +
     "  </RESTHeader>\n" + 
     "<InputParameters>\n" + 
     "  <pageSize>3</pageSize>\n" +
     "  <pageNumber>1</pageNumber>\n" +
     "</InputParameters>\n" + 
     "</getOpenNotifications_Input>"; 
    
        /**
         * This method invokes the EBS Login service. It authenticates login credentials and  returns accessTokenName and 
         * accessToken values after successful validation of login credentials.
         */
        private static String[] getAccessToken(String baseUrl, String username,String passwd) throws Exception {
    
                String loginUrl = baseUrl + "/login";
                URL url = new URL(loginUrl);
                //Obtaining connection to invoke login service.
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                String auth = username + ":" + passwd;
                byte[] bytes = Base64.encode(auth);
                String authStr = new String(bytes);
                //Setting Http request method
                conn.setRequestMethod("GET");
                //Setting the Http header values
                conn.setRequestProperty("Authorization", "Basic " + authStr);
                conn.setRequestProperty("Accept", "application/xml");
                conn.setUseCaches(false);
                conn.setDoInput(true);
                conn.setDoOutput(true);
                conn.connect();
                String response = null;
                //Get Response
                try {
                        response = readHttpResponse(conn);
                } finally {
                        if (conn != null)
                                conn.disconnect();
                }
                //Parsing Response to obtain 
                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                DocumentBuilder builder = factory.newDocumentBuilder();
                ByteArrayInputStream input =  new ByteArrayInputStream(response.getBytes("UTF-8"));
                Document doc = builder.parse(input);
                Element eAccessToken = (Element) doc.getElementsByTagName("accessToken").item(0);
                String strAccessToken = eAccessToken.getTextContent();
                Element eTokenName = (Element) doc.getElementsByTagName("accessTokenName").item(0);
                String strTokenName = eTokenName.getTextContent();
    
                return (new String[] { strTokenName, strAccessToken });
        }
        
        /**
         * This method reads response sent by the server and returns it in a string representation.
         */
        private static String readHttpResponse(HttpURLConnection conn) {
                InputStream is = null;
                BufferedReader rd = null;
                StringBuffer response = new StringBuffer();
                try {
                        if (conn.getResponseCode() >= 400) {
                                is = conn.getErrorStream();
                        } else {
                                is = conn.getInputStream();
                        }
                        rd = new BufferedReader(new InputStreamReader(is));
                        String line;
                        while ((line = rd.readLine()) != null) {
                                response.append(line);
                                response.append('\n');
                        }
                } catch (IOException ioe) {
                        response.append(ioe.getMessage());
                } finally {
                        if (is != null) {
                                try {
                                        is.close();
                                } catch (Exception e) {
                                }
                        }
                        if (rd != null) {
                                try {
                                        rd.close();
                                } catch (Exception e) {
                                }
                        }
                }
                return (response.toString());
        }
    
        /**
         * This method invokes Workflow Notification rest service using the accessTokenName and accessToken values returned by EBS login service
         */
        public static void invokeRESTService(String svcUrlStr, String tokenName,String tokenValue) throws IOException {
    
            URL url = new URL(svcUrlStr);
            //Obtaining connection to invoke the service
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            //Setting Http header values
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/xml");
            //Adding the accessTokenName and accessToken as Cookies
            conn.addRequestProperty("Cookie", tokenName + "=" + tokenValue);
            conn.setRequestProperty("Accept", "application/xml");
            conn.setUseCaches(false);
            conn.setDoInput(true);
            conn.setDoOutput(true);
            //Send request
            OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
            wr.write(xmlRequest1.toCharArray());
            wr.flush();
            wr.close();
            conn.connect();
            System.out.println("Response code - " + conn.getResponseCode());
            //Get Response 
            String response = null;
            try {
                    response = readHttpResponse(conn);
            } finally {
                    if (conn != null)
                            conn.disconnect();
            }
            //Show Response
            System.out.println("Response is : \n" + response);
        }
    
        public static void main(String[] args) throws Exception {
            AMClient aMClient = new AMClient();
            String baseUrl = "http://<EBS hostname>:<port>/webservices/rest";
            String svcUrlStr1 = baseUrl + "/notification/getOpenNotifications/";
            System.out.println("Calling EBS Login Service");
            //Get Access Token by invoking AOL Login Service
            String[] token = getAccessToken(baseUrl, "<EBS username>", "<password>");
            System.out.println("Obtained EBS Access Token");
            //Invoke REST service using the Access Token
            invokeRESTService(svcUrlStr1, token[0], token[1]);
          }
    }

    Please note that resource information recorded earlier from the deployed WADL is now placed in the baseUrl and svcUrlStr1 elements.

    Note: Use https (instead of http) in the baseUrl if your Oracle E-Business Suite instance is running on the TLS-enabled environment. Additionally, you need to import the TLS certificate into your client JVM's keystore.

  9. Replace <EBS hostname>:<port>, <EBS username>, and <password> with the actual values in the code.

  10. Add the required library to process XML payload:

    Use the following steps to add the required library file to the project properties.

    1. Select and right-click on the project name you just created earlier to open a selection menu.

    2. Select Project Properties from the menu.

      The Default Properties dialog box opens.

    3. Select Libraries and Classpath, and click Add Library. The Add Library dialog box opens.

      Project Properties Dialog and Add Library Dialog

      the picture is described in the document text

    4. In the Add Library dialog box, select the Project folder and then click New.

      The Create Library dialog box opens.

    5. In the Library Name field, enter 'jersey-bundle_1.0.0.0_1-1-5-1.jar'.

      Click Add Entry. The Select Path Entry dialog box appears.

    6. In the Select Path Entry dialog box, locate and select the 'jersey-bundle_1.0.0.0_1-1-5-1.jar' file that you have downloaded. This adds it to the Classpath.

      Click OK. The 'jersey-bundle_1.0.0.0_1-1-5-1.jar' is now added to the Project folder.

      Add Library Dialog with Selected Library

      the picture is described in the document text

    7. The Project Properties dialog box appears. Click OK. This project is now set up with the required library.

  11. Save your work by selecting File > Save All.

Invoking a REST Service Using a Java Class

After creating a project with a Java class AMClient.java, you need to compile and run the process to invoke the 'Approvals Management' REST service.

Use the following steps to compile and run the Java class:

  1. In the Application Navigator, right-click on the AMClient.java Java class you just created at the design time. Select Make from the menu.

  2. Right-click on the AMClient.java Java class and select Run from the menu.

Monitor and verify this process and check for successful compilation in the Log window.

Viewing Output Message

When the 'Approvals Management' REST service is successfully invoked, the following response appears:

Calling EBS Login Service
Obtained EBS Access Token
Response code - 200
Response is : 
<?xml version = '1.0' encoding = 'UTF-8'?>
<getOpenNotifications_Output xmlns:ns="http://xmlns.oracle.com/apps/fnd/rest/output">
  <ns:OutputParameters>
         <ns:Output>
                <ns:WFApprovalsBean 
xmlns:ns2="http://xmlns.oracle.com/apps/fnd/wf/worklist/service/rt/artifacts/fault/" 
xmlns:ns1="http://xmlns.oracle.com/apps/fnd/wf/worklist/service/rt/artifacts/notificationdetails/" 
xmlns:ns="http://xmlns.oracle.com/apps/fnd/rest/notification/getOpenNotifications" 
xmlns:ns0="http://xmlns.oracle.com/apps/fnd/wf/worklist/service/rt/artifacts/directoryservices/">
                        <ns:output>
                          <notifications count="23">
                                <notification>
                                  <NotificationId>7857291</NotificationId>
                                  <Subject>Standard Purchase Order  6562  has been approved</Subject>
                                  <Language>US</Language>
                                  <BeginDate>30-Sep-2010 01:25:03</BeginDate>
                                  <Status>Open</Status>
                                  <FromUser>Brown, Casey</FromUser>
                                  <Name>POAPPRV</Name>
                                  <SentTime>30-Sep-2010</SentTime>

<NotificationLink>OA.jsp?OAFunc=FND_WFNTF_DETAILS&NtfId=7857291&amp;....</NotificationLink>

                                  <ns1:result/>
                           </notification>
                                <notification>
                                  <NotificationId>7857248</NotificationId>
                                  <Subject>Standard Purchase Order  6561  has been approved</Subject>
                                  <Language>US</Language>
                                  <BeginDate>30-Sep-2010 01:20:27</BeginDate>
                                  <Status>Open</Status>
                                  <FromUser>Brown, Casey</FromUser>
                                  <Name>POAPPRV</Name>
                                  <SentTime>30-Sep-2010</SentTime>
        
<NotificationLink>OA.jsp?OAFunc=FND_WFNTF_DETAILS&NtfId=7857248&amp;.....</NotificationLink>

                                  <ns1:result/>
                           </notification>
                                <notification>
                                  <NotificationId>7747986</NotificationId>
                                  <Subject>Standard Purchase Order  6549  has been approved</Subject>
                                  <Language>US</Language>
                                  <BeginDate>13-Sep-2010 17:00:54</BeginDate>
                                  <Status>Open</Status>
                                  <FromUser>Stock, Pat</FromUser>
                                  <Name>POAPPRV</Name>
                                  <SentTime>13-Sep-2010</SentTime>

<NotificationLink>OA.jsp?OAFunc=FND_WFNTF_DETAILS&NtfId=7747986&amp;......</NotificationLink>
      
                             <ns1:result/>
                           </notification>
           </notifications>
          </ns:output>
                        </ns:WFApprovalsBean>
                  </ns:Output>
                  <ns:ControlBean>
                    <ns:filter/>
                         <ns:limit/>
                    <ns:offset/>
                         <ns:sort/>
        </ns:ControlBean>
     </ns:OutputParameters>
 </getOpenNotifications_Output>

In this example, the response message in XML format provides three open workflow notifications in the first page.