How You Obtain External Information Using Extension Rules

You can call an external service from within an extension rule.

This is useful when you need to consult an external source to assist in the proper configuration of a model. It is often more efficient to obtain data (such as product specifications or government regulations) from an external source than to attempt to maintain it in your model.

In order to call an external service from an extension rule, you must:

  • Register a web service connection to be used by a service call

  • Define an extension rule in which the script calls the service using that connection

Registering the Web Service Connection

In order for Configurator to access an external web service, you must register a connection for it.

To define a web service connection:

  1. In the Setup and Maintenance work area, select Search from the task panel. Search for and select the task Manage External Service Details for Extensions.

  2. In the Web Service Details table, select Add Row from the Actions menu.

  3. From the Target System list, select a registered trading community partner application or Oracle Application.

  4. In the Connector Name field, enter the name that you will use to refer to the service, in your extension rule. such as AxelWS.

  5. In the Connector URL field, enter the URL to the external web service, such as http://axel04.com:7011/services/AxelServicesPort.

  6. From the Invocation Mode list, select Synchronous service, which is the mode supported.

  7. Optionally enter other service information that may be required for calling the web service, such as User Name and Password.

  8. Select Save and Close.

Defining the Extension Rule

In order for Configurator to call an external web service, you must define an extension rule that uses a particular API to call the service and specify the desired operation.

  1. Navigate to the Configurator Models work area.

  2. In a workspace, add your model and open it for editing.

  3. On the Rules tab of the Edit Configurator Model page, select Create Extension Rule from the Actions menu.

  4. In the Structure pane, select a base node for the rule, such as the root node of the model.

  5. In the Rule Text pane, enter a valid Groovy script that calls the external service. A sample script is provided in this topic.

  6. When defining the event binding for the rule, select when you want the service to be called:

    • To call the service when the configuration session begins, select postConfigInit.

    • To call the service when the associated model node value is changed, select postValueChange.

  7. For the example script provided, the event binding must have a Class of ScriptClass and a Method of getCpuHw(String region).

  8. The argument binding for the argument region must be a value that can be interpreted by the web service.

Calling an External Service

The example script provided here demonstrates the essential points of calling an external web service in an extension rule script.

Important points to remember:

  • It is essential to import the classes SoapServiceResponse and SoapServiceRequest. The need for other imports is determined by the desired behavior of your script.

  • When constructing the payload string, this example uses the namespace http://services.axel and the service method cpuHw. Assume that these are defined in the web service that you registered.

  • You must use the method invokeSoapService() from the configuration object to call the service, and pass it the connector name that you registered and the payload string that you constructed. In this example, the connector name is AxelWS.

  • Some external SOAP services can only be invoked using SOAP 1.1 specs. They don't work via SOAP 1.2, possibly because WSDL is only SOAP 1.1 compatible. In order to get around this issue, add the following HTTP headers when invoking such services from an extension rule:

    • Content-Type: text/xml

    • SOAPAction: executeWebCX

    Here is an example of how these HTTP headers can be set in an extension rule:

    SOAPMessage message  = request.getSoapMessage(); 
    message.getMimeHeaders().addHeader("Content-Type", "text/xml; charset=utf-8"); 
    message.getMimeHeaders().addHeader("SOAPAction", "executeWebCX");

    If these HTTP headers aren't set then a SOAP 1.1 call fails.

This example script constructs a SOAP message for a web service that tries to select some items:

import oracle.apps.scm.configurator.runtime.core.IRuntimeNode; 
import oracle.apps.scm.configurator.runtime.core.ServiceException; 
import oracle.apps.scm.configurator.runtime.core.SoapServiceRequest; 
import oracle.apps.scm.configurator.runtime.core.SoapServiceRequest.SOAP_PROTOCOL_TYPE; 
import oracle.apps.scm.configurator.runtime.core.SoapServiceResponse; 
import javax.xml.soap.SOAPBody; 
import javax.xml.soap.SOAPMessage; 
import javax.xml.soap.SOAPElement; 
import javax.xml.soap.SOAPBodyElement; 
import javax.xml.namespace.QName; 
import org.w3c.dom.Document; 
import org.w3c.dom.Element; 

public class WebCXmin implements Serializable { 
   public WebCXmin() { } 
   
   public String callWebService(IRuntimeNode node) { 
     SoapServiceRequest request = new SoapServiceRequest(node.getConfiguration()); 
     SOAPMessage message  = request.getSoapMessage(); 

     // create XML payload here 
     QName bodyName = new QName("ws", "executeWebCX"); 
     SOAPBodyElement bodyElement = request.getSoapBody().addBodyElement(bodyName); 
     bodyElement.addNamespaceDeclaration("ws", "http://services.axel/"); 
     bodyElement.setPrefix("ws");   
     
     QName className = new QName("className"); 
     SOAPElement classes = bodyElement.addChildElement(className);     
     classes.addTextNode("axel.ce.ws.webcx.DSPrimeTestCX"); 
     
     QName name = new QName("params"); 
     SOAPElement params = bodyElement.addChildElement(name); 
     
     QName entry = new QName("entry"); 
     SOAPElement entries = params.addChildElement(entry);     
     
     QName key = new QName("key"); 
     SOAPElement keys = entries.addChildElement(key);   
     keys.addTextNode("json"); 
     
     QName value = new QName("value"); 
     SOAPElement values = entries.addChildElement(value);   
     values.addTextNode("{\"qty\": 2, \"children\": [], \"type\": \"MI\", \"state\": [\"UTRU\", \"SELD\", \"USLD\"]}");     
     
     message.getMimeHeaders().addHeader("Content-Type", "text/xml; charset=utf-8"); 
     message.getMimeHeaders().addHeader("SOAPAction", "executeWebCX");     
     
     SoapServiceResponse response; 
     try { 
     // Invoke the external web service that was registered in the Setup and Maintenance work area 
        response = node.getConfiguration().invokeSoapService("AxelWS", request); 
     } catch (ServiceException e1) { 
        throw new Exception(" msg=" + e1.getMessage()); 
     } 

     def base = node; 
     def tf = base.getChildByName("TextFeature");         
     Document doc = response.getSoapBody().extractContentAsDocument(); 
     Element root = doc.getDocumentElement();           
     tf.textValue = "SOAP Body node: "+root.getFirstChild().getTextContent(); 


  } 
}