Wednesday, May 21, 2025

OIC - Transforming anyType XML to a Namespaced Fragment using XSLT in Integration Flows | Dynamic XML Transformation: Namespace Remapping with xsl:apply-templates in XSLT

Use Case:

In enterprise integrations using Oracle Integration Cloud (OIC) or similar middleware, you may encounter services that accept or return XML fragments typed as xsd:anyType. These fragments can contain any structure, and the lack of a fixed schema or namespace binding makes it difficult to directly map elements in transformations.

For example, a source service might wrap business logic (like GetMeterReadings) inside a generic RequestMessage node with dynamic content. The requirement is to extract the GetMeterReadings fragment and pass it along to the target system with a well-defined target namespace.


Solution:

To handle this dynamic anyType payload, we use XSLT (Extensible Stylesheet Language Transformations) to:

  • Extract the desired fragment (GetMeterReadings) from the dynamic XML.
  • Reconstruct it in a known target namespace (myns1 in this case).
  • Maintain attribute and nested node integrity.

Here’s how it works:

1. Define a generic template to re-map all nodes into a target namespace:

<xsl:template match="*">
    <xsl:element name="myns1:{local-name()}">
        <xsl:apply-templates select="@* | node()"/>
    </xsl:element>
</xsl:template>

2. Apply the template only to the fragment of interest (GetMeterReadings) inside an anyType payload:

<xsl:apply-templates select="//inpl:RequestMessage/inpl:Request/*:GetMeterReadings"/>

3. Declare the required namespaces in the XSLT header:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:inpl="http://example.com/source"
                xmlns:myns1="http://example.com/target"
                exclude-result-prefixes="inpl"
                version="1.0">

Result:

The output of this transformation will be a GetMeterReadings element, moved into the myns1 namespace, ready to be used by the target system.

This approach ensures robust handling of anyType payloads in integrations and allows you to enforce consistent target schemas, even when the source is non-standard.




Monday, May 19, 2025

OIC - Handling any Type Field Mapping in Oracle Integration Cloud (OIC) | Use of Local-namespace() function and apply template

Usecase: 

While building an integration in OIC, you may come across a requirement where the target SOAP or XML structure contains a field of type <any> (or xs:anyType). These fields are placeholders meant to accept any valid XML content, but OIC’s Mapper UI doesn’t allow direct drag-and-drop mappings for such fields.

This can be confusing and frustrating, especially when you're trying to pass a dynamic XML or construct a custom payload. Here's how to deal with this in a clean and simple way.


Solution Steps

Step 1: Identify the <any> Field

In your target structure, locate the field labeled as <any> or marked with type xs:anyType.

Step 2: Switch to XSLT View

In the Mapper canvas:

  • Click on the </> icon (usually found in the upper right of the mapping panel).
  • This will open the raw XSLT mapping code.
Step 3: Manually Add a Custom XML Payload

Here, insert a valid XML snippet that the target system expects. Example:

<any>
  <ns1:CustomData xmlns:ns1="http://example.com/schema">
    <ns1:DeviceId>{/ns0:TriggerService/Request/GetMeterReadings/EndDevice}</ns1:DeviceId>
    <ns1:ReadingType>{/ns0:TriggerService/Request/GetMeterReadings/ReadingType}</ns1:ReadingType>
  </ns1:CustomData>
</any>

Replace /ns0:TriggerService/... with actual source path expressions from your input.

Step 4: Validate and Save
  • Ensure the XML syntax is correct.
  • Click Validate in the mapper toolbar.
  • Save your changes and return to the visual canvas.
Optional: Use JavaScript or Stage File for Complex Data

If the XML is very dynamic:

  • Use a JavaScript action to build the payload.
  • Or read it from a stage file and assign it as a single string/XML object.

Used code: we have used local-namespace() function and apply template

<xsl:param name="tracking_var_3" xml:id="id_21"/>
<xsl:template match="/" xml:id="id_11">
  <nstrgmpr:OutboundSOAPRequestDocument xml:id="id_12">
    <nstrgmpr:Body>
      <ns2:RequestMessage>
        <ns2:Header>
          <ns2:Verb>
            <xsl:value-of select="//*[local-name()='RequestMessage']//*[local-name()='Header']/*[local-name()='Verb']/text()"/>
          </ns2:Verb>
          <ns2:Noun>
            <xsl:value-of select="//*[local-name()='RequestMessage']//*[local-name()='Header']/*[local-name()='Noun']/text()"/>
          </ns2:Noun>
          <ns2:Timestamp>
            <xsl:value-of select="//*[local-name()='RequestMessage']//*[local-name()='Header']/*[local-name()='Timestamp']/text()"/>
          </ns2:Timestamp>
          <ns2:Source>
            <xsl:value-of select="//*[local-name()='RequestMessage']//*[local-name()='Header']/*[local-name()='Source']/text()"/>
          </ns2:Source>
          <ns2:ReplyAddress>
            <xsl:value-of select="//*[local-name()='RequestMessage']//*[local-name()='Header']/*[local-name()='ReplyAddress']/text()"/>
          </ns2:ReplyAddress>
          <ns2:MessageID>
            <xsl:value-of select="//*[local-name()='RequestMessage']//*[local-name()='Header']/*[local-name()='MessageID']/text()"/>
          </ns2:MessageID>
          <ns2:CorrelationID>
            <xsl:value-of select="//*[local-name()='RequestMessage']//*[local-name()='Header']/*[local-name()='CorrelationID']/text()"/>
          </ns2:CorrelationID>
        </ns2:Header>
        <ns2:Request>
          <xsl:apply-templates select="//*[local-name()='RequestMessage']"/>
        </ns2:Request>
      </ns2:RequestMessage>
    </nstrgmpr:Body>
  </nstrgmpr:OutboundSOAPRequestDocument>
</xsl:template>

<xsl:template match="//*[local-name()='RequestMessage']">
  <nsd10:GetMeterReadings>
    <xsl:for-each select="*[local-name()='Request']/*[local-name()='GetMeterReadings']/*[local-name()='EndDeviceAsset']">
      <nsd10:EndDevice>
        <nsd10:Names>
          <nsd10:name>
            <xsl:value-of select="*[local-name()='mRID']/text()"/>
          </nsd10:name>
        </nsd10:Names>
      </nsd10:EndDevice>
    </xsl:for-each>
    <xsl:for-each select="*[local-name()='Request']/*[local-name()='GetMeterReadings']/*[local-name()='ReadingType']">
      <nsd10:ReadingType>
        <xsl:value-of select="*[local-name()='name']/text()"/>
      </nsd10:ReadingType>
    </xsl:for-each>
  </nsd10:GetMeterReadings>
</xsl:template>
</xsl:stylesheet>

Screenshot:


Conclusion

Although <any> fields are not directly mappable in OIC’s graphical interface, you can still pass data to them using XSLT view and inserting well-formed XML manually. This gives you flexibility while still adhering to schema requirements.


Tuesday, May 13, 2025

OIC - Simulating External SOAP Service Calls in OIC Without Agent Using a Stub Integration

Use Case:

In Oracle Integration Cloud (OIC), we had a requirement to integrate with an external SOAP service that mandates an agent setup. However, due to agent issues during development, we needed a workaround to simulate the SOAP service response and continue functional testing. The goal was to create a stub service that mimics the real SOAP service, allowing us to test our main integration flow without dependency on the actual external system or agent setup.

Solution Steps:

  1. Create a Stub SOAP Connection:

    • Created a new SOAP connection in OIC without agent setup and basic authentication.
    • Uploaded the WSDL (with embedded XSD) of the external service to this connection.
    • Ensured that the connection is fully functional for internal calls.

  2. Develop a Stub Integration:

    • Built a separate OIC integration that uses the above SOAP connection as a trigger.
    • Hardcoded a sample SOAP response that mimics the external service's expected response.
    • This stub acts as a mock service and can be updated later with more realistic data if needed.


  3. Modify the Main Integration:

    • In the main integration (which originally called the external SOAP service), replaced the invoke to the external service with an invoke to the stub SOAP connection.
    • Used a dynamic approach to set Endpoint URL and SOAP Action in the invoke properties to point to the stub integration endpoint.

  4. Use a Lookup to Manage Endpoint Properties:

    • Created an OIC Lookup table to store environment-specific endpoint URLs and SOAP Actions.
    • This makes switching between the stub and real service (during SIT/UAT) seamless by just updating the lookup values.
  5. Mapping and Testing:

    • Mapped the request payload to match the expected structure of the original service.
    • Verified the response from the stub integration is structurally and functionally valid.
    • Ensured the integration behaves as if it's communicating with the actual external service.

Outcome:

This stub-based approach enabled functional testing of the main integration flow without waiting for the agent setup. It allowed developers and testers to validate business logic early, improving delivery timelines. Later in SIT/UAT, switching to the real service will only require updating the lookup to point to the actual endpoint.


Friday, May 9, 2025

OIC - Resolving "SOAP Header Security was not understood" invoking Web Services

Use Case:

In a utility integration scenario using MultiSpeak-compliant web services, a SOAP request fails with the error:
"CASDK-0033: Received a SOAP fault... Fault Code : soap:MustUnderstand – SOAP header Security was not understood."
This typically occurs when integrating Oracle Integration Cloud (OIC) with a third-party endpoint that requires WS-Security headers.

Root Cause:

The SOAP request included a <wsse:Security> block with mustUnderstand="1", but the target endpoint does not understand or support WS-Security headers in that format.
Alternatively, the expected security token or credentials were missing or not compliant with the service’s expected authentication scheme.

Solution Steps:

Step 1: Understand the Error Message

Error:

Fault Code : soap:MustUnderstand  
Fault String : SOAP header Security was not understood.

This indicates that the service could not process the WS-Security headers, often because it does not support them or requires a different security configuration.

Full error details:

CASDK-0033: Received a SOAP fault while invoking endpoint target: https://<host>/CC/WebAPI/MRCB.asmx.

This indicates a processing exception on the service endpoint side. Please check service side logs to further diagnose the problem

<![CDATA[

Fault Code : soap:MustUnderstand

Fault String : SOAP header Security was not understood.

]]>

Step 2: Analyze the SOAP Request

The failing payload included this header:

<wsse:Security env:mustUnderstand="1" ...>
  <wsu:Timestamp ...>
    <wsu:Created>...</wsu:Created>
    <wsu:Expires>...</wsu:Expires>
  </wsu:Timestamp>
</wsse:Security>

This was likely injected by a policy in Oracle Integration Cloud (OIC) or a SOAP client security configuration.

Step 3:  Suppress the insertion of timestamp in the request from the soap invoke connection. This will remove the Security Header from the request.

Reason: The target service does not support WS-Security, modify the request to remove the <wsse:Security> block completely.

Connection snap:


Failing payload:

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">

  <env:Header>

    <tns:MultiSpeakMsgHeader env:mustUnderstand="0" UserID="xxxx" Pwd="xxxx" xmlns:tns="http://www.multispeak.org/Version_5.0"/>

    <wsse:Security env:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">

      <wsu:Timestamp wsu:Id="TS-84" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">

        <wsu:Created>2025-05-09T09:07:58.512Z</wsu:Created>

        <wsu:Expires>2025-05-09T10:07:58.512Z</wsu:Expires>

      </wsu:Timestamp>

    </wsse:Security>

  </env:Header>

  <env:Body>

    <tns:MeterAddNotification xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:tns="http://www.multispeak.org/Version_5.0">

      <tns:addedMeters>

        <tns:meter>

          <tns:meterNo>2345</tns:meterNo>

          <tns:utilityInfo>

            <tns:servLoc>SL#1435</tns:servLoc>

          </tns:utilityInfo>

        </tns:meter>

      </tns:addedMeters>

    </tns:MeterAddNotification>

  </env:Body>

</env:Envelope>

Updated working payload:

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">

  <env:Header>

    <tns:MultiSpeakMsgHeader env:mustUnderstand="0" UserID="xxxx" Pwd="xxxx" xmlns:tns="http://www.multispeak.org/Version_5.0"/>

  </env:Header>

  <env:Body>

    <tns:MeterAddNotification xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:tns="http://www.multispeak.org/Version_5.0">

      <tns:addedMeters>

        <tns:meter>

          <tns:meterNo>2345</tns:meterNo>

          <tns:utilityInfo>

            <tns:servLoc>SL#1435</tns:servLoc>

          </tns:utilityInfo>

        </tns:meter>

      </tns:addedMeters>

    </tns:MeterAddNotification>

  </env:Body>

</env:Envelope>

Step 4: Test the Integration

Resend the modified payload from OIC or any SOAP client (e.g., SOAP UI or Postman with SOAP support). The endpoint should now process the request successfully.



Thursday, May 8, 2025

OIC - Combining Source File Records into a Single Line in Oracle Integration Cloud (OIC)

Working...

Issue Statement:

In many real-time integrations, especially in ERP or data migration scenarios, source files are received in a structured format (e.g., one header record followed by multiple detail records). However, certain downstream systems or services may require this data to be flattened into a single string line (e.g., HeaderDetailDetailDetail...) before further processing. Oracle Integration Cloud (OIC) does not offer a direct activity to do this in a single step, so a custom approach is required.

Solution Steps:

Technique 1 : for small size source file

Read the file:

Read the source file as raw line by line using a sample csv file uaing ftp adapter.


Write File using stage and translate for each line new line :

translate(ns22:FileData, "&#xA;&#xD;", "")

This XSLT function removes newline (&#xA;) and carriage return (&#xD;) characters from each line, which is essential when combining multiple lines into a single line in OIC.


Technique 2: For bigger size file - 10k ~ 30k size.

TBD


Monday, May 5, 2025

OIC - How will you handle error in OIC integration? If you are processing multiple records, how will you ensure all the records are processed even if a single record errors out?

How will you handle error in OIC integration? If you are processing multiple records, how will you ensure all the records are processed even if a single record errors out?

Answer:

In Oracle Integration Cloud (OIC), when processing multiple records (for example, a JSON array or CSV data), handling errors gracefully is crucial to prevent the entire integration from failing due to a single bad record. Here's how to ensure all records are processed even if one fails:

  1. Use a For-Each Action:
    Loop through the array or list of records using the For-Each action so each record is processed individually.

  2. Wrap Logic Inside a Scope:
    Place your main processing logic for each record inside a Scope activity.

  3. Add Fault Handler to Scope:
    Inside the Scope, add a Fault Handler to catch any errors specific to that record and log or handle them (e.g., write to a log file, invoke an error-handling integration, or call a notification).

  4. Continue on Error:
    Since the fault is handled within the loop, the integration will not fail globally and will continue to the next record in the For-Each.

  5. Track Success and Failures:
    Optionally, maintain a status array or write results to a lookup, object store, or DB table indicating success or failure for each record.

This way, each record is treated independently, and errors in one record do not block the processing of others.


OIC Lookup Import Error – "The Type, Name and Description Line is Invalid" [Resolved]

Issue Case:

While trying to re-import a modified Lookup CSV file back into Oracle Integration Cloud (OIC), an error occurred:

"Failed to import lookup file ‘XYZ.csv’. The lookup is formatted incorrectly. The Type, Name and Description line is invalid."

This happened despite exporting the Lookup directly from OIC and only updating its rows.

Root Cause:
Upon opening the exported CSV file in Notepad, it was observed that the header line:

Type,Name,Description,,,,,,,

...contained extra trailing commas. These additional commas beyond the expected three fields caused the file to be rejected by OIC during import, as it violates the expected format.

Solution Steps:

  1. Open the exported Lookup CSV file using Notepad or any plain text editor.
  2. Locate the first line that should read:
    Type,Name,Description
    
  3. Remove all extra commas after "Description" so that only three fields are defined in the header row.
  4. Save the file with the same CSV format (UTF-8 or ANSI).
  5. Retry the import in OIC — it should now succeed without error.




Featured Post

OIC - OIC Utility to Reprocess Failed Real-Time Integration JSON Payloads

📌 Use Case In real-time OIC integrations, JSON payloads are exchanged with external systems via REST APIs. When such integrations fail (du...