Introduction:
- OIC SOAP Adapter is an extensively used adapter to expose a soap-based external interface on cloud for many other applications to access.
- Today, any integration within OIC uses exposes a single operation in it's interface.
- If your implementation needs to support multiple operations, each operation requires a separate integration to be developed with an interface exposed causing the linear complexity in O(n), with n being the number of operations to be exposed.
Problem Statement:
Expose multiple operations using single soap integration. Is this possible?
Analysis and Solution:
Yes, it is certainly possible with a workaround and some limitations.
Workaround steps:
- Create one integration per an operation that needs to be implemented (which will be called as child flows from here on).
- Create a soap connection that uses the above exposed OIC wsdl and runtime credentials with corresponding security policy (which will be called as child connections from here on).
- Repeat 1 & 2 for all required number of operations.
- Create a generic wsdl interface and a soap trigger connection to use this. This wsdl interface uses anyType payload with a generic operation name.
- Create an integration using above connection as trigger (which will be called as parent flow from here on) that will call the child integrations.
- Once the trigger is configured, parse the payload to identify the operation and identify an unique condition to determine which child to be invoked.
- Use switch action with conditions to uniquely identify the child invocations.
- Use invoke activity with child connections in each condition
Generic interface for parent flow. The wsdl should support any type of payload:
<definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://mock.service.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://mock.service.com/" name="EchoMultiOpsImplService">
<types>
<xs:schema xmlns:tns="http://mock.service.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.0" targetNamespace="http://mock.service.com/">
<xs:element name="echoAny" type="tns:echoAnyType"/>
<xs:element name="echoAnyResponse" type="tns:echoAnyType"/>
<xs:complexType name="echoAnyType">
<xs:sequence>
<xs:element name="xml" type="xs:anyType"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</types>
<message name="echoSingle">
<part name="parameters" element="tns:echoAny"/>
</message>
<message name="echoSingleResponse">
<part name="parameters" element="tns:echoAnyResponse"/>
</message>
<portType name="EchoAny">
<operation name="echoAny">
<input wsam:Action="http://mock.service.com/echoSingle" message="tns:echoSingle"/>
<output wsam:Action="http://mock.service.com/echoSingleResponse" message="tns:echoSingleResponse"/>
</operation>
</portType>
</definitions>
Converting the entire child node of xml element to a string:
xmlDataAsString = ora:getContentAsString(/nsmpr8:echoAny/xml/*)
Identify the root-element from the child-element of xml tag.
xmlDataRoot = substring-before(substring-after($xmlDataAsString, '<'),'>')
There can be case where the root element can be one of below types :
<rootElement>
<rootElement xmlns="someTargetNamespace">
<nsprefix:rootElement xmlns:nsprefix="someTargetNamespace">
The value of $xmlDataRoot, we expect here should have only 'rootElement' so we can route it appropriately. So we will add a switch action to handle this and update the variable using assign actions (pseudo-code shown below)
if $xmlDataRoot contains ' '(space) --> substring-before($xmlDataRoot,' ')
if $xmlDataRoot contains : --> substring-after($xmlDataRoot,':')
The final value of $xmlDataRoot at this point will return the value - 'rootElement'.
Now based on the rootelement we will create a switch and call each operartion.
Used xml payload for login operation:
<login>
<AccountNumber>111</AccountNumber>
<UserNane>abc</UserName>
<Password>pwd</Password>
</login>
For Base64 opaque schema, follow my blog:
https://soalicious.blogspot.com/2022/02/xsd-opaque-schema.html
Poc Screenshots:
Create a generic soap connection.