Sunday, May 10, 2026

OIC - OCI Java function code for RSA Encryption and Decryption

Function Java code:

package com.test.fn;

import java.security.*;

import java.security.spec.*;

import java.util.Base64;

import javax.crypto.Cipher;

import java.util.logging.*;

public class RSAEncryptDecrypt {

    private static final Logger logger = Logger.getLogger(RSAEncryptDecrypt.class.getName());

  public static class Input {

        public String message;

        public String secretKeyBase64;

        public String rsaMode;

        public String actionType; // ENCRYPT or DECRYPT

    }

    public static class Result {

        public String message;

        public String executionInfo;

    }

    public Result handleRequest(Input input) throws Exception {

        logger.log(Level.INFO, "OIC - message:", input.message);

        logger.log(Level.INFO, "OIC - secretKeyBase64:", input.secretKeyBase64);

        logger.log(Level.INFO, "OIC - rsaMode:", input.rsaMode);

        logger.log(Level.INFO, "OIC - actionType:", input.actionType);

        Result result = null;

        if ("DECRYPT".equals(input.actionType)) {

            result = decryptMyMessage(input);

        } else if ("ENCRYPT".equals(input.actionType)) {

            result = encryptMyMessage(input);

        } else {

            result = new Result();

            result.executionInfo = "ERROR: No proper action found , possible value "

                    + "is ENCRYPT or DECRYPT , recieved value:"

                    + input.actionType;

        }

        return result;

    }

// Method to encrypt plaintext using the RSA public key

 public Result encryptMyMessage(Input input) throws Exception {

     Result result = new Result();

     try {

         PublicKey publicKey = loadPublicKey(input.secretKeyBase64);

         Cipher cipher = Cipher.getInstance(input.rsaMode); // RSA encryption scheme

         cipher.init(Cipher.ENCRYPT_MODE, publicKey);

         byte[] encryptedBytes =                cipher.doFinal(input.message.getBytes());

         result.message =                 Base64.getEncoder().encodeToString(encryptedBytes);

         result.executionInfo = "SUCCESS";

     } catch (Exception e) {

         result.executionInfo = e.getMessage();

         logger.log(Level.INFO, "Error Details:", e.getMessage());

     }

     return result; // return as Base64 string

 }

 public Result decryptMyMessage(Input input) throws Exception {

     Result result = new Result();

     try {

         Cipher decryptCipher =

                 Cipher.getInstance(input.rsaMode);

         PrivateKey privateKey =                getPrivateKeyFromString(input.secretKeyBase64);         decryptCipher.init(Cipher.DECRYPT_MODE, privateKey);

         byte[] decryptedBytes =

                 decryptCipher.doFinal(                       Base64.getDecoder().decode(input.message));

         String myDecryptedMsg =

                 new String(decryptedBytes, "UTF-8");

         result.message = myDecryptedMsg;

         result.executionInfo = "SUCCESS";

     } catch (Exception e) {

         result.executionInfo = e.getMessage();

         logger.log(Level.INFO, "Error Details:", e.getMessage());

     }

     return result; // return as Base64 string

 }

// Converts a Base64-encoded public key string to PublicKey object

 public static PublicKey loadPublicKey(String base64PublicKey) throws Exception {

     byte[] keyBytes =            Base64.getDecoder().decode(base64PublicKey);

     X509EncodedKeySpec spec =

             new X509EncodedKeySpec(keyBytes);

     KeyFactory keyFactory =

             KeyFactory.getInstance("RSA");

     return keyFactory.generatePublic(spec);

 }

 // Convert Base64 string to PrivateKey

 public static PrivateKey getPrivateKeyFromString(String base64PrivateKey)

         throws Exception {

     byte[] keyBytes =            Base64.getDecoder().decode(base64PrivateKey);

     PKCS8EncodedKeySpec spec =

             new PKCS8EncodedKeySpec(keyBytes);

     KeyFactory factory =

             KeyFactory.getInstance("RSA");

     return factory.generatePrivate(spec);

 }

}

Java code Screenshots:





Friday, May 8, 2026

OIC - Improving OIC Performance – Avoid Large Payloads in String Variables | String Size Limit Warning Message

While working with large payloads in Oracle Integration Cloud (OIC), especially from BIP report responses, many developers store the complete response inside a string variable for later processing or logging.

This works initially, but when the payload becomes too large, OIC may start showing a warning like:

“String size limit”



This is commonly seen when the string exceeds around 10,000 characters (10K).

OIC Server limit:

If the size of a string variable exceeds 10,000 characters, a warning message is shown in the activity stream. Oracle Integration does not currently impose a limit on the size of string variables. However, this may be subject to change in the future, which could result in a flow execution failing when the limit is exceeded.

Common Scenario

We had a use case where:

OIC was calling a BIP Report

The report response contained a very large XML/Base64 payload

Entire response was stored in a string variable

Integration completed successfully, but OIC generated a warning notification

Typical warning behavior:

Integration still succeeds

Activity stream shows warning

OIC dashboard displays alert notification

Performance may degrade due to heavy in-memory string handling

Why This Happens

OIC internally maintains limits for string handling in memory.

When a very large payload is stored in:

Assign activity variables

String variables

Logger messages

Tracking fields

OIC raises a String Size Limit Warning.

This does not always fail the integration immediately, but it can:

Increase memory usage

Slow down execution

Create unnecessary activity stream overhead

Impact overall integration performance

Real Impact on Performance

Large string variables can cause:

1. Increased Memory Consumption

Huge payloads remain loaded in memory during runtime.

2. Slower Assign Activities

Assigning massive strings repeatedly increases processing time.

3. Activity Stream Overhead

OIC tries to maintain activity and debug information.

4. Payload Serialization Cost

Large string conversion operations impact performance.

5. Difficult Debugging

Very large payload logs become hard to analyze.

Recommended Resolution

1. Avoid Storing Full Payload in String Variables

Instead of:

Storing complete BIP response

Storing entire Base64 output

Keeping full XML/JSON in string variables

Store only:

Required nodes

Specific fields

IDs/status values

2. Use Stage File for Large Content

For large payload processing:

Write payload into Stage File

Process file stream-wise

Avoid keeping everything in memory

This is the best approach for:

Large XML

CSV

Base64 documents

Huge BIP outputs

3. Read Only Required Data

Instead of mapping the complete payload:

Extract only needed elements using:

XPath

JSON path

Stage File Read

Example:

Employee Number

Report Status

File Name

Document ID

Avoid unnecessary full payload assignments.

4. Avoid Logging Full Payloads

Do not log:

Entire XML

Complete Base64

Large JSON responses

Instead log:

Record count

Transaction ID

Small status messages

5. Use Attachments/File References When Possible

For document-heavy integrations:

Pass file references

Use attachments

Use opaque/binary handling

Instead of converting everything into strings.

Best Practice Architecture

Recommended flow:

Call BIP Report

Receive large payload

Store in Stage File / Attachment

Read only required fields

Pass file reference downstream

Avoid huge string variables

Key Takeaway

If OIC shows: String Size Limit Warning. it usually means: 

Integration processed a very large string payload

OIC memory threshold warning was triggered

Integration may still succeed

But performance optimization is needed

Reference:

https://community.oracle.com/customerconnect/discussion/926935/oic-string-size-limit-alert?utm_source=chatgpt.com


Thursday, May 7, 2026

OIC - Handling dynamic JSON Payloads in OIC Using Binary JSON Media Type

 In Oracle Integration Cloud (OIC), there are scenarios where the source system sends dynamic or variable JSON payloads through a REST service. Since the structure may change frequently, creating strict schemas becomes difficult.

In our requirement, the incoming JSON payload needs to be passed to the target Communication Cloud service as escaped JSON, while also reading only a few required fields from the payload for validations or processing.

Requirement

Expose a REST API in OIC.

Source system can send any type of JSON structure.

Need to avoid strict request schema dependency.

Read only required fields from the payload.

Pass the complete original JSON payload to Communication Cloud service as escaped JSON.

Solution Approach

1. Configure REST Trigger with Binary JSON Media Type

While creating the REST trigger:

Select Binary as the request payload type.

Set media type as:

Plain text

application/json

This allows OIC to accept any JSON structure dynamically without schema validation.


Benefit

No dependency on fixed JSON schema.

Supports variable or changing payload structures.

Prevents failures due to unexpected fields.

2. Read Required Fields Using Stage File Action

Since the payload is received as binary content:

Use Stage File → Read Entire File

Read the incoming payload as JSON.

From the Stage File schema, extract only the required fields needed for processing.

Example:

JSON

{

  "employeeId": "1001",

  "status": "ACTIVE",

  "dynamicData": {

      ...

  }

}

You may read only: employeeId , status without validating the complete payload structure.



3. Preserve Original JSON Payload

The key advantage of this approach is:

The original payload remains unchanged.

No need to reconstruct JSON again in mapper.

Entire payload can directly be forwarded to downstream systems.

4. Pass Complete Payload to Communication Cloud

The target Communication Cloud service expects escaped JSON.

Since the original payload is already preserved:

Map the complete payload directly to target request.

Use escaped JSON/string format as required by Communication Cloud API.

Example target payload:

JSON

{

  "payload": "{\"employeeId\":\"1001\",\"status\":\"ACTIVE\"}"

}


Architecture Flow

Plain text

  • Source System

      ↓

OIC REST Trigger

(Binary JSON Media Type)

      ↓

Stage File Read

(Read only required fields)

      ↓

Map Original Payload

      ↓

Communication Cloud REST Service

(Escaped JSON)

Advantages of This Approach

  • Supports dynamic JSON structures.
  • No schema maintenance effort.
  • Avoids trigger regeneration issues.
  • Easy handling of changing payloads.
  • Efficient for pass-through integrations.
  • Only required fields are parsed.

Conclusion

Using Binary JSON media type in OIC REST triggers is an effective solution when handling variable JSON payloads. By combining it with Stage File read operations, we can selectively access required fields while still forwarding the complete original payload to downstream systems like Communication Cloud without rebuilding the JSON structure.

Tuesday, May 5, 2026

OIC - Handling Unknown Record Types in OIC (Header / Detail / Footer Detection) | How to validate a string in yyyymmdd is in date format?

๐Ÿ“Œ Problem Statement

In one of our Oracle Integration Cloud (OIC) file-based integrations, the source file structure was unclear.

We were receiving records, but no explicit identifier was present to distinguish:

Header

Detail

Footer

However, we observed one consistent pattern: ๐Ÿ‘‰ Detail records always contain a date in YYYYMMDD format at a fixed position.

๐Ÿ’ก Solution Approach

We used this date pattern as a validation key to identify detail records.

✔️ Logic:

Extract substring from the record (specific position where date exists)

Convert it into proper date format (YYYY-MM-DD)

Compare with original substring

Count matching records

If count = 0 → No detail record → Fail validation

๐Ÿ› ️ OIC Implementation

Step 1: Extract Date from Record

Assume date starts at position 19 in the string:

Xpath

substring(ns30:Data, 19, 8)

Step 2: Convert to Proper Date Format

Xpath

concat(

  substring(ns30:Data, 19, 4), "-",

  substring(ns30:Data, 23, 2), "-",

  substring(ns30:Data, 25, 2)

)

Step 3: Validate Date Format

Xpath

xp20:format-dateTime(

  concat(

    substring(ns30:Data, 19, 4), "-",

    substring(ns30:Data, 23, 2), "-",

    substring(ns30:Data, 25, 2)

  ),

  "[Y0001][M01][D01]"

)

Step 4: Compare with Original Value

Xpath

xp20:format-dateTime(...) = substring(ns30:Data, 19, 8)

๐Ÿ‘‰ If TRUE → Valid date → Detail record

Step 5: Count Detail Records

Xpath

count(

  $ReadRawFile/nsmpr0:ReadResponse/ns30:RawFileRowSet/ns30:RawFileRow[

    xp20:format-dateTime(

      concat(

        substring(ns30:Data, 19, 4), "-",

        substring(ns30:Data, 23, 2), "-",

        substring(ns30:Data, 25, 2)

      ),

      "[Y0001][M01][D01]"

    ) = substring(ns30:Data, 19, 8)

  ]

)

๐Ÿšจ Final Validation Condition

Xpath

count(...) = 0

Meaning:

✅ If count > 0 → Detail records exist → Proceed

❌ If count = 0 → No detail records → Fail Integration

๐ŸŽฏ Key Benefits

No dependency on explicit record type indicators

Works with inconsistent file formats

Lightweight validation using XPath

Prevents downstream processing errors

⚡ Pro Tip

If date position may vary or data is dirty:

Use normalize-space() before substring

Add additional checks (length = 8, numeric check)

๐Ÿงพ Conclusion

When file structure is ambiguous, pattern-based validation (like date detection) is a powerful technique in OIC.

This approach ensures that only valid detail records are processed, improving reliability and 

Featured Post

OIC - OCI Java function code for RSA Encryption and Decryption

Function Java code: package com.test.fn; import java.security.*; import java.security.spec.*; import java.util.Base64; import javax.crypto.C...