X

Best Practices from Oracle Development's A‑Team

Calling SOAP Services from Visual Builder

Tim Bennett
CX Solution Architect

Introduction

Oracle Visual Builder (VB) has out of box support for calling REST services and can be configured to make calls directly from the client, or via the server proxy. There is no obvious support for making SOAP calls. While it is possible to make client side SOAP calls from javascript, without the VB Connection framework, the authentication would need to be handled by the client code and there is a high chance of a CORS error.

This post shows how the VB Service Connection framework can be used to make SOAP calls. By using a VB Service Connection, such calls inherit other connection capabilities such as the use of the proxy and authentication mechanisms.

 

Example Use Case

The example uses Visual Builder federated with Fusion Sales, and the endpoint being called is the runReport method of the BIP ExternalReport service:

https://{hostname}/xmlpserver/services/ExternalReportWSSService?wsdl

Note that this service supports security policy "wss11_saml_or_username_token_with_message_protection_service_policy" (see later for the significance of this).

Note - the objective of this post is to demonstrate how to setup and call the SOAP endpoint, it is not necessarily an endorsement of this use case. The use of the response within a VB page is beyond the scope of the article and it assumes a basic knowledge of Visual Builder, so the detailed steps required to reproduce the example are not covered.

 

Method

Overview

The steps to configure and make the call are:

  • Recommended - test the service in SOAP UI or similar to make sure the required endpoint, payload and parameters are known 
  • Define the SOAP endpoint as a VB Service Connection
  • Call the service from a Page Module function

 

Define the SOAP endpoint as a VB Service Connection

In VB, navigate to the Service Connections, create a new connection, and select Define by Endpoint

Enter the URL for the service, in this example it is:

https://{hostname}/xmlpserver/services/ExternalReportWSSService

 

Configure the service as per the screen shots below:

 

Things to note:

  • Method is POST
  • Authentication is Oracle Cloud Account. The same SAML token as is used for FA REST calls will be used (ref security policy in the WSDL above)
  • Always use the Proxy - this will ensure the call is made from the VB server, thus avoiding CORS errors
  • Add a Request Static Header - Content-Type : 'application/soap+xml;charset=UTF-8'
  • Set the request and response example body to {}

 

Note the Service Name and the Endpoint ID. In this example these are xmlpserverServices and postExternalReportWSSService

 

 

Call the service from a Page Module function

The easiest way to demonstrate the connection and confirm it is working is to create a VB page with a Text Area and a Button - the Button will call an action chain that calls the service and maps the response to the Text Area.

Steps:

  • Create a page with a Text Area and a Button
  • Create a Page variable called reportData and bind the Text Area to this variable
  • Create a new Event on the button, and select  "Quick Start: ojAction". This will create a listener on the button and an empty Action Chain.
  • Add a reference the the Service Connection to the Application metadata

 

Action Chain

The Action Chain has 2 steps:

  • Call Module Function - this function makes the SOAP call. The example uses 2 parameters, map these to suit your service
  • Assign Variables - this maps the response from the module function to the reportData page variable

 

Module Function

The module function uses the VB Rest Helper Utility. This utility allows calling REST endpoints, which are defined in the service definitions. See the VB Documentation for further information.

 

//Add the VB REST helper
define(['vb/helpers/rest'], function(Rest) {
  'use strict';

  var PageModule = function PageModule() {};

  PageModule.prototype.callSOAP = function(reportName, partyNumber) {

    var self = this;

    return new Promise(function(resolve, reject) {
      //SOAP template, use string substitution to set parameters
      self.soapTemplate =
        ' \
		xmlns:pub="http://xmlns.oracle.com/oxp/service/PublicReportService"> \
          \
          \
          \
            \
             csv \
               -1 \
               XXXX \
                \
                  \
                   Customer Number \
                    \
                      ZZZZ \
                    \
                  \
                \
            \
          \
          \
         ';

      self.soapRequest = self.soapTemplate.replace("XXXX", reportName)
        .replace("ZZZZ", partyNumber);
      \\Endpoint is servicename/endpoint ID
      self.endpoint =
        'xmlpserverServices/postExternalReportWSSService';

      Rest.get(self.endpoint).body(self.soapRequest).fetch().then(
        response => {
          // response processing will be service specific
         // If response is an FA Business Object, then use an xml2json function
          self.xmlResponse = $.parseXML(response.body);
          self.reportBytes = self.xmlResponse.getElementsByTagName(
            "ns2:reportBytes")[0].textContent;
          self.reportCSV = atob(self.reportBytes.split("/")[1]);
          resolve(self.reportCSV);
        });

    });

  };

  return PageModule;
});

Assign the result of the Action Chain to the reportData variable

 

Add the service reference to the Application metadata

 

 

Conclusion

This method has been tested with Fusion business object services and the BIP report service. As illustrated above, by retrieving the BIP report data as csv, the parsing of the response is very easy. When calling a Fusion Business object service the response payloads can be large XML files, so the best way to handle these is to use an xml2json function and then map the parsed response to a suitable variable.

The above demonstrates the basic setup required to make a call. An alternative solution is to wrap the call in a CCA and pass everything required to make the call, including the SOAP body (or a reference to it), as parameters. By doing this, one CCA could be used to call many SOAP end points.

 

 

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha

Recent Content