Friday, July 25, 2025

OIC - Streamlined OIC Scheduled Integration for GL Fuel Cost Data Using ESS Job Callback and Event-Based File Processing Without Timeouts

Use Case

The organization needs to automate the extraction and delivery of GL Fuel Cost data generated from a BI Publisher report in Oracle Fusion ERP. The integration should be efficient, scalable, and must avoid long-running processes and timeouts within Oracle Integration Cloud (OIC).

The requirement includes:

  • Scheduled trigger to initiate the process.
  • Submission of the BI report using the Export ESS Job Wrapper.
  • Callback-based integration to handle ESS job completion.
  • Document download, decode, unzip, and CSV parsing.
  • Transformation and delivery of the processed data to a target system.

Optimized Solution Approach (Without Timeout)

1. Scheduled Integration – Submit ESS Job Only

  • Create a Scheduled Orchestration Integration in OIC.
  • Trigger the Export ESS Job Wrapper using the ERP Cloud Adapter.
    • Service: ErpIntegrationService
    • Operation: exportBulkData
  • Pass the following information:
    •  JobName: "JobPackageName,JobDefinitionName"
    • parameterList: concat(param1,param2)
    • JobOptions:  EnableEvent= Y to ensure callback is published.
  • Do not wait for completion in the same flow — this avoids long runtime and timeouts.





2. Callback Integration – Listen to ERP Event

  • Create a separate App-Driven Integration.
  • Use ERPIntegrationOutboundEvent as the trigger.
  • Apply a filter condition on Job Name or Report Path to restrict to only GL Fuel Cost report completions.

3. Get Report Output via Document ID

  • From the event payload, extract the Document ID.
  • Call the GetDocumentForDocumentId operation using ERP Cloud Adapter.
  • Retrieve the output as a base64-encoded ZIP.




4. Decode and Unzip File

  • Use OIC's base64 decode function.
  • Use Stage File – Unzip File action to extract files from the archive.
  • Use a For-Each loop to iterate through unzipped files.

5. Parse CSV and Transform Data

  • For files with .csv extension:
    • Use Stage File – Read File to parse contents.
    • Transform the data into the required target structure using Mapper.

6. Deliver Data to Target System

  • Send the formatted data to the external target (via REST, FTP, etc.).
  • Include proper error handling, logging, and retry logic for robustness.

Benefits of This Approach

  • Avoids Timeout: Processing is split between scheduler and callback flow, preventing long execution.
  • Event-Driven: Ensures OIC listens and responds only when the ESS job completes successfully.
  • Modular Design: Easier to maintain and enhance.
  • Optimized Performance: Resource-light scheduled flow, heavier processing is deferred to callback.

Ess job sample page:



Wednesday, July 23, 2025

OIC - How to add Filters while subscribing ERP business events in Oracle Integration

To add filters for the “specific” event in Oracle Integration Cloud (OIC), follow the steps below. These filters ensure that only relevant events are processed — e.g., only payments voided for a specific business unit or source system.


✅ Steps to Add Filters for “Payables Payment Voided” Event in OIC

Step 1: Create or Edit the Integration

  1. Open your OIC integration where you want to subscribe to the event.
  2. Use the ERP Cloud Adapter as a trigger.
  3. Choose the event:
    Business Event → Payables Payment Voided

Step 2: Configure the Event Adapter and Add Filter

After selecting the event:

  1. On the "Basic Info" screen, click Next.
  2. On the "Event Details" screen, scroll down to the Filter Expression section.
  3. You’ll see an “Add Filter Expression” button.

🔍 Example Payload Fields for Payables Payment Voided:

When the event is triggered, the payload might contain fields like:

<env:Body>
  <ns0:ApPaymentVoidedInfo 
xmlns:ns0="http://xmlns.oracle.com/apps/financials/payables/shared/paymentFile/common/publicEvents/ApPaymentVoided">
    <ns0:CheckId>121001</ns0:CheckId>
    <ns0:PaymentTypeFlag>A</ns0:PaymentTypeFlag>
    <ns0:OrgId>300000057802xxx</ns0:OrgId>
    <ns0:VendorName>ABC</ns0:VendorName>
    <ns0:VendorSiteCode/>
    <ns0:PartyId>100000286292xxx</ns0:PartyId>
    <ns0:PartySiteId>1000002862943xxx</ns0:PartySiteId>
    <ns0:CheckNumber>51817</ns0:CheckNumber>
    <ns0:CheckDate>2025-07-07T00:00:00</ns0:CheckDate>
    <ns0:Amount>1000</ns0:Amount>
    <ns0:CurrencyCode>HKD</ns0:CurrencyCode>
    <ns0:PaymentMethod>E_ACH_EPS_BATCH</ns0:PaymentMethod>
    <ns0:PaymentStatus>VOIDED</ns0:PaymentStatus>
    <ns0:BankAccountNum>XXXXXXXXX73303</ns0:BankAccountNum>
    <ns0:VoidDate>2025-07-07T00:00:00</ns0:VoidDate>
  </ns0:ApPaymentVoidedInfo>
</env:Body>

Step 3: Add Filter Expression

Run the integration once without filters, log the entire incoming payload using Logger, and confirm which keys you want to filter on. Use the body namespace here.

Sample 1: Check the payment method.

<xpathExpr xmlns:ns0="http://xmlns.oracle.com/apps/financials/payables/shared/paymentFile/common/publicEvents/ApPaymentVoided">

$eventPayload/ns0:PaymentMethod = 'E_ACH_EPS_BATCH_PC'

</xpathExpr>

Sample 2: substring and filter

<xpathExpr xmlns:ns0="http://xmlns.oracle.com/apps/financials/payables/shared/paymentFile/common/publicEvents/ApPaymentVoided">
substring($eventPayload/ns0:PaymentMethod, string-length($eventPayload/ns0:PaymentMethod) - 1) = 'PC'
</xpathExpr>
Sample 3:  for Any Import bulkFBdI use, ERP Integrtaion Inbound Event
<xpathExpr xmlns:ns0="http://xmlns.oracle.com/apps/financials/commonModules/shared">
  starts-with($eventPayload/ns0:JOBS[ns0:JOBNAME='Load Interface File for Import']/ns0:DOCUMENTNAME,
              'PC_test_AP')
</xpathExpr>


Why $eventPayload is used in <xpathExpr> in OIC:

In Oracle Integration Cloud (OIC) event subscriptions, when you're writing a filter expression inside <xpathExpr>, Oracle automatically binds the incoming event data (the event payload) to a variable named:

$eventPayload

This variable is your entry point to access the fields from the event payload using XPath expressions.



⚠️ Important Notes:

  • Fields must match payload field names exactly (case-sensitive).
  • Use AND, OR, =, !=, etc., as supported operators.
  • If unsure of available fields, log the payload in your integration to inspect its structure.

✅ Best Practice:

Run the integration once without filters, log the entire incoming payload using Logger, and confirm which keys you want to filter on.


Thursday, July 17, 2025

OIC - End-to-End OIC Integration for AP Invoice Payment Request Processing and Status Callbacks in Oracle Fusion | AP invoice Payment Request FBDI import and callback

🔹 Use Case

A source system sends AP Payable payment request data as REST JSON to Oracle Integration Cloud (OIC). OIC performs the following:

  1. Converts the incoming data into FBDI and property files.
  2. Zips and uploads them via ERP Fusion Adapter for bulk import.
  3. Handles invoice creation callback.
  4. On successful import, extracts the load interface ID and calls a BIP report to fetch invoice status.
  5. Sends the response back to the source over REST.
  6. Also handles callbacks for:
    • Payables Payment Created
    • Payables Payment Voided
  7. Uses Fusion REST API to get payment-related invoice info and sends status to the source.
  8. If payment is voided, calls an OOTB (out-of-the-box) fusion REST API to cancel the invoice in Fusion.

🔹 Solution Steps

1. Receive AP Invoice payment Request from Source

  • API: Expose OIC integration as REST endpoint.
  • Method: POST
  • Request Payload (Sample):
{
  "transactions": [
    {
      "partyCode": "G1235",
      "partyType": "ORGANIZATION",
      "partyCountryCode": "HK",
      "address": "Flat X 3/F,...",
      "city": "Kowloon",
      "bankCountryCode": "HK",
      "bankCurr": "HKD",
      "bankId": "004",
      "bankName": "Citi Bank N.A.",
      "bankAccountNumber": "1234",
      "bankHolderName": "name",
      "refundAmount": "500",
      "currencyCode": "HKD",
      "paymentDate": "2025/07/01",
      "invoiceNumber": "PC-10043534_6",
      "businessUnit": "test LIMITED",
      "source": "PC",
      "paymentMethod": "test",
      "payGroup": "PC_HSBC",
      "distributionCombination": "0100-631-000000-1207060101-0000-0000-000-000",
      "lineNumber": "1",
      "lineDescription": "1000000210+SDU2025R1"
    }
  ]
}

2. OIC - Create FBDI File & Properties File

  • Step: Map incoming JSON to AP Invoice FBDI template (usually AP_INVOICES_INTERFACE and AP_INVOICE_LINES_INTERFACE).
  • Step: Generate the FBDI CSV and properties file.
  • Step: Zip the files.

FBDI file format:
Transaction_Identifier,Party Name,Party Original System Reference,Party Type,Location Original System Reference,Country,Address Line1,Address Line2,Address Line3,Address Line4,Phonetic Address Line,Address Element Attribute5,Building,Floor Number,City,State,Province,County,Postal code,Postal Plus 4 code,Addressable Global Location Number,Language,Phone Country Code,Phone Area Code,Phone,Phone Extension,Payee E-mail address,Party Tax Registration Number,Account Country Code,Account Currency Code,Account Number,IBAN,Secondary Account Reference,Account Name,Account Type Code,Bank Name,Bank Branch Name,Bank Branch Number,BIC,Check Digits,Account Description,Account Alternate Name,Business Unit,Source,Ledger,Date,Source Currency,Description,Import Set,Legal Entity,Payment Terms,Payment Method,pay_Group,Liability Combination,Document Category Code,Voucher Number,Payment Reference,Payment Amount,Payment Reason Comments,URL Attachments,Document Category,Requester First Name,Requester Last Name,Requester E-mail,Requester Name,Payment Priority,Payment Message1,Payment Message2,Payment Message3,Attribute_Category,Attribute1,Attribute2,Attribute3,Attribute4,Attribute5,Attribute6,Attribute7,Attribute8,Attribute9,Attribute10,Attribute11,Attribute12,Attribute13,Attribute14,Attribute15,Line Number,Line Requester First Name,Line Requester Last Name,Line Requester E-mail,Line Requester Name,Line Description,Combination,Distribution Set,Line Attribute_Category,Line Attribute1,Line Attribute2,Line Attribute3,Line Attribute4,Line Attribute5,Line Attribute6,Line Attribute7,Line Attribute8,Line Attribute9,Line Attribute10,Line Attribute11,Line Attribute12,Line Attribute13,Line Attribute14,Line Attribute15,Line Attribute1,Line Attribute2,Line Attribute3,Line Attribute4,Line Attribute5,Line Attribute6,Line Attribute7,Line Attribute8,Line Attribute9,Line Attribute10,Line Attribute11,END

FBDI template:

Zip files:
<systemname>_<interfaceid>_Aap_YYYYMMDDhhmmds.zip
APPaymentRequests.csv
APPaymentRequests.properties

Properties files contents:
/oracle/apps/ess/financials/payables/invoices/transactions,APXPRIMPT,PC_INT388.1_AP_20250721021929,
300000005780278,#NULL,1000,PC,#NULL,N,300000005649365,#NULL,1


3. Upload to Fusion Using ERP Adapter

  • Operation: Import Bulk data into Oracle Erp Cloud - Import Payables Payment Requests
  • Adapter: ERP Integration Adapter
  • Required Info: UCM Account: fin$/payables$/import$
  • Enable callback






4. Callback: Invoice Load Completed

  • Callback Notification from Fusion: OIC receives callback with Load Interface ID.
Import Payables Payemnt Requests does not have any filter so we need to use ERP Integration Inbound Event. So that we can apply filter and identify for which system we are getting the callback.



Reference:

5. Call BI Report to Get Invoice Status

  • API: Oracle BI Report Web Service
  • Report Path: /Custom/AP/Invoice_Status_Report.xdo
  • Request:
<soapenv:Envelope ... >
  <soapenv:Body>
    <runReport>
      <reportRequest>
        <reportAbsolutePath>/Custom/AP/Invoice_Status_Report.xdo</reportAbsolutePath>
        <parameterNameValues>
          <item>
            <name>p_load_interface_id</name>
            <values>
              <item>1234567</item>
            </values>
          </item>
        </parameterNameValues>
      </reportRequest>
    </runReport>
  </soapenv:Body>
</soapenv:Envelope>
  • Response: XML/CSV with invoice number, status, rejection reason.
BIP report sql query:







6. Send Invoice Status Back to Source

  • Method: POST
  • Payload (Sample):
{
  "transactions": [
    {
      "invoiceNumber": "PC-1003423424",
      "status": "Invoice Created",
      "reason": "Bank details are missing",
      "date": "01.07.2025"
    }
  ]
}

7. Callback - Payables Payment Created

Since the PPR (Payment Process Request) process in ERP does not emit events for Payables Payment Created, we need to rely on the Payment File Created event instead.

  • Trigger: Payment created event in Fusion

Filter used:
<xpathExpr xmlns:ns0="http://xmlns.oracle.com/apps/financials/payments/fundsDisbursement/payments/model/entity/events">
  $eventPayload/ns0:PaymentProcessProfileName/ns0:newValue/@value = 'ABC_HSBC_ACH_HKD_PROF_PC'
</xpathExpr>

Call Fusion Rest API: Get Cheque id
GET /fscmRestApi/resources/11.13.18.05/payablesPayments




  • Call Fusion REST API: Get Child Invoices of Payment

  • GET /fscmRestApi/resources/11.13.18.05/payablesPayments/{CheckId}/child/relatedInvoices



  • Send Status to Source (Sample Payload):
{
  "transactions": [
    {
      "invoiceNumber": "PC-1003423424",
      "status": "Payment Created",
      "reason": "",
      "date": "01.07.2025"
    }
  ]
}

8. Callback - Payables Payment Voided

  • Trigger: Voided payment notification from Fusion.

Call REST API: Get related invoices for the Voided Payment.

  • API: GET /fscmRestApi/resources/11.13.18.05/payablesPayments/{CheckId}/child/relatedInvoices



Call Fusion REST API: Cancel Invoice

  • API: POST /fscmRestApi/resources/11.13.18.05/invoices/action/cancelInvoice





Notify Source System

  • POST Payload:
{
  "transactions": [
    {
      "invoiceNumber": "PC-1003423424",
      "status": "Payment Voided",
      "reason": "",
      "date": "01.07.2025"
    }
  ]
}

🔹 Final Integration Architecture

  1. Inbound:
    • Source → OIC (REST API with AP data)
    • OIC → Fusion (FBDI ZIP via ERP Adapter)
  2. Outbound:
    • OIC → BI Report → Invoice Status → Source
    • Fusion → OIC (Callbacks for Invoice Load, Payment Created, Payment Voided)
    • OIC → Fusion REST (to fetch/cancel)
    • OIC → Source (REST POST with status updates)

Next pending:

How to add Filters while subscribing events for specific system?

Wednesday, July 16, 2025

OIC - Tracking AP Invoice Import Status Using SQL for BI Publisher and OIC Integration

Use Case:

In Oracle Integration Cloud (OIC), when integrating accounts payable (AP) invoice data into Oracle Fusion ERP using the AP Payment Request Bulk Import process, it’s important to track which invoices have been successfully imported and which failed.

To automate this tracking, a BI Publisher Report is created with a SQL query that pulls invoice status from the AP_PAYMENT_REQUESTS_INT and AP_INTERFACE_REJECTIONS tables. The report is scheduled to output a CSV file, which is then picked up by OIC and sent to the target system or vendor for further processing or reconciliation.


Solution Steps:

SQL Query:

SELECT
    aii.invoice_num INVOICE_NUMBER,
    air.REJECTION_MESSAGE REJECTION_MESSAGE,
    CASE
        WHEN aii.STATUS = 'PROCESSED'
        THEN 'SUCCESS'
        ELSE 'ERROR'
    END IMPORT_STATUS
FROM
    AP_PAYMENT_REQUESTS_INT aii,
    AP_INTERFACE_REJECTIONS air
WHERE 1 = 1
AND air.parent_table = 'AP_PAYMENT_REQUESTS_INT'
AND aii.PAYMENT_REQUEST_INTERFACE_ID = air.parent_id
AND aii.LOAD_REQUEST_ID IN (:P_RequestId)
UNION
SELECT
    aii.invoice_num INVOICE_NUMBER,
    null REJECTION_MESSAGE,
    'SUCCESS' IMPORT_STATUS
FROM
    AP_PAYMENT_REQUESTS_INT aii
WHERE 1 = 1
AND aii.PAYMENT_REQUEST_INTERFACE_ID NOT IN (
    SELECT parent_id
    FROM AP_INTERFACE_REJECTIONS
    WHERE parent_table = 'AP_PAYMENT_REQUESTS_INT'
)
AND aii.STATUS = 'PROCESSED'
AND aii.LOAD_REQUEST_ID IN (:P_RequestId)

1. SQL Query Overview

The SQL query checks the status of each invoice request using a UNION of two SELECTs:

  • First part: Fetches both successful and rejected records by joining the interface table and rejection table.
  • Second part: Captures the remaining successful invoices not found in the rejection table.
Key Components:
  • invoice_num → The invoice number submitted.
  • REJECTION_MESSAGE → Error message if the record failed.
  • IMPORT_STATUS → 'SUCCESS' or 'ERROR' based on processing status or rejection presence.
  • :P_RequestId → Bind variable to dynamically filter the results for a specific load request.

2. Report Execution in BI Publisher

  • The SQL is used as a Data Set in the BI Publisher Data Model.
  • It takes the LOAD_REQUEST_ID as a parameter (:P_RequestId) from the OIC process.
  • The report is scheduled or triggered from OIC to output a CSV file.

3. Integration with OIC

  • OIC receives the CSV output file from BI Publisher.
  • Parses the invoice import result file.
  • Sends the status and details (e.g., rejection reason) back to the source system or vendor.

Benefits:

  • Automated visibility into which AP invoices were processed and which failed.
  • Improved traceability and reconciliation with source systems.
  • Reduces manual intervention and error tracking time.




Sunday, July 13, 2025

OIC - Extract RSA Public Key from a Certificate – Two Easy Methods (OpenSSL & Java)

📌 Use Case:

When integrating with third-party platforms (e.g., Oracle Integration Cloud, REST APIs with JWT, or SAML), you often receive a certificate. To validate tokens or signatures, you must extract the RSA public key from an X.509 certificate file (like .cer or .crt).


✅ Solution Steps

🔽 Input:

  • A .cer or .crt file (Base64-encoded X.509 format)
  • Goal: Extract the RSA public key in readable format

🔧 Option 1: Using OpenSSL (Command Line)

📥 Steps:

  1. Save your certificate as cert.pem (Base64 X.509 format).
  2. Run this command:
openssl x509 -in cert.pem -pubkey -noout > public_key.pem

✅ Output:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQE...
-----END PUBLIC KEY-----

📎 Notes:

  • Works on Linux/macOS/WSL/Windows with OpenSSL installed
  • Easy to use in automation scripts

☕ Option 2: Using Java Code (Without OpenSSL)

📥 Steps:

1. Convert .cer File to Base64 Text:

  • Open your .cer file (which is binary) in any Base64 encoder (e.g., PowerShell, online tool, or base64 CLI).
  • It should look like this:
-----BEGIN CERTIFICATE-----
MIIDczCCAlugAwIBAgIEXV...<trimmed>...C2s85w==
-----END CERTIFICATE-----




2. Copy Only the Certificate Key Part:

  • Copy the middle Base64 key part (remove headers and newlines).
  • Store it in a Java string like base64Cert in the code below.

✅ Java Code:

import java.io.ByteArrayInputStream;
import java.security.PublicKey;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Base64;

public class RSAPublicKeyExtractor {
    public static void main(String[] args) throws Exception {
        // Step 1: Paste your base64-encoded certificate string here
        String base64Cert = 
            "MIIDczCCAlugAwIBAgIEXV...<full cert key here>...C2s85w==";

        // Step 2: Decode the base64 string
        byte[] certBytes = Base64.getDecoder().decode(base64Cert);

        // Step 3: Convert to X.509 certificate
        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
        X509Certificate cert = (X509Certificate) certFactory
            .generateCertificate(new ByteArrayInputStream(certBytes));

        // Step 4: Extract public key
        PublicKey publicKey = cert.getPublicKey();

        // Step 5: Print the public key details
        System.out.println("Public Key Algorithm : " + publicKey.getAlgorithm());
        System.out.println("Public Key Format    : " + publicKey.getFormat());
        System.out.println("Public Key (Base64)  : ");
        System.out.println(Base64.getEncoder().encodeToString(publicKey.getEncoded()));
    }
}

🧾 Sample Output:

Public Key Algorithm : RSA
Public Key Format    : X.509
Public Key (Base64)  :
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArpM...


Thursday, July 10, 2025

OIC - Lessons Learned & Improvements in OIC Integrations

📘 Use Case

During various OIC projects, we identified recurring issues that impacted logging, error tracking, retry handling, and monitoring through tools like DataDog. Here’s a list of key observations and the solutions we applied.


1. Suppressed Error Details

  • Observation:
    OIC sends only a generic error message to DataDog or external logs, hiding the actual root cause.

  • Solution:
    Capture the actual faultMessage in error handlers and send it to DataDog along with other details for better troubleshooting.


2. No Retry for Temporary Errors

  • Observation:
    Transient connectivity or network issues fail immediately without any retry attempt.

  • Solution:
    Add retry logic using fault handlers or scopes for specific error types (like connection timeouts or 5xx errors).


3. Missing Correlation ID for Fusion Failures

  • Observation:
    When a Fusion ESS job fails, the logs don’t include any identifier like the ESS Job ID or request ID, making it hard to trace.

  • Solution:
    Extract and log the ESS request ID or other correlation IDs from Fusion and include them in your custom logs.


4. Payload Not Validated

  • Observation:
    OIC flows sometimes try to process empty or null payloads, which leads to schema errors or misleading messages.

  • Solution:
    Add condition checks early in the flow to verify if payloads contain data before proceeding to mappings or invokes.


5. Only Errors Logged, Not Success

  • Observation:
    DataDog or similar tools receive only error logs, and successful integrations are not tracked, affecting KPI reporting.

  • Solution:
    Log success cases as well, including important business identifiers like invoice number, PO number, or employee ID for better tracking.

6. Integration Timeout Not Handled

Observation:
Some long-running integrations fail due to timeout, especially when calling external systems that take time to respond.

Solution:
Adjust the timeout settings in the connection properties. Also, wrap such calls in a scope with timeout handling logic to provide custom error messages or fallback.

7. Overuse of Hardcoded Values

Observation:
Many integrations had hardcoded values for endpoints, credentials, or lookup keys, making them hard to migrate or scale.

Solution:
Use Lookups, Global Variables, and Connections smartly to externalize values. Parameterize as much as possible.

8. No Archival or Logging of Request Payloads

Observation:
When issues occurred, there was no record of what payload was received—making RCA difficult.

Solution:
Log incoming request payloads (masked if sensitive) to file server, UCM, or external logging systems before processing.

9. Overloaded Error Handlers Catching Everything

Observation:
A single generic error handler catches all faults, masking the actual error and causing confusion.

Solution:
Use specific fault handlers (like for Timeout, AuthenticationFailure, ServiceError) instead of one "catch-all" block. Customize messages accordingly.

10. Lack of Version Control or Documentation

Observation:
Integration flows were updated without tracking changes or maintaining documentation, making it difficult for others to manage.

Solution:
Maintain version notes or release logs.

Use naming conventions for integration versions.

Document integration logic, mappings, and lookups in a central repo or Confluence page.

11. Poor Use of Data Stitching (Unnecessary Variables)

Observation:
Multiple unnecessary variables and assignments are used where direct mapping or transformation would work.

Solution:
Optimize mappings and data handling. Use fewer intermediate variables and go for direct expressions or XSLT if needed.

12. Integration Not Idempotent

Observation:
Some integrations post the same data multiple times if retried, causing duplicates in target systems.

Solution:
Implement idempotency checks—use message IDs, reference numbers, or flags in the target system to avoid re-processing.

🎯 Outcome

Implementing these improvements helped us:

  • Get full visibility into success and failure cases
  • Reduce debugging time
  • Improve monitoring accuracy in tools like DataDog
  • Increase reliability of integrations with retry logic


Sunday, July 6, 2025

OIC - How to upload file to sharepoint using Microsoft graph API

📌 Use Case

In this use case, we are building an integration in Oracle Integration Cloud (OIC) that:

  1. Downloads a file from a File Server.
  2. Uploads that file to a specific SharePoint folder using Microsoft Graph API.

This is especially helpful in scenarios where enterprises manage data exports on file servers and want to automate data archival or sharing via SharePoint.


⚙️ Solution Design Overview

The integration follows these main steps:

  1. Trigger – A scheduled or REST-based trigger initiates the process.
  2. Fetch Site ID – Retrieves SharePoint Site ID using the server-relative path.
  3. Fetch Drive ID – Retrieves the Drive ID associated with the Site.
  4. Download File – Reads the file from the file server.
  5. Upload File – Uploads the file to SharePoint using Microsoft Graph API PUT call.

🔍 Step-by-Step Solution


✅ Step 1: Get SharePoint Site ID

  • REST Endpoint Name: GetSiteID
  • Method: GET
  • Relative URI:
    /sites/{tenant}.sharepoint.com%3A/sites/{server-relative-path}
    
  • Response Sample:
    {
      "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#sites/$entity",
      "createdDateTime": "2022-09-26T07:22:04.923Z",
      "description": "sp_org_app_DWCSSystemIntegration_qa",
      "id": "yourtenant.sharepoint.com,c87b311d-f1f0-4576-9f43-256b0366ccd4,315734c4-892c-486f-8901-5c8827144a16",
      "lastModifiedDateTime": "2024-08-23T11:25:16Z",
      "name": "sp_org_app_DWCSSystemIntegration_qa"
    }

✅ Step 2: Get SharePoint Drive ID

  • REST Endpoint Name: GetDriveID
  • Method: GET
  • Relative URI:
    /sites/{siteId}/drives
    
  • Query Parameter:
    $filter = name eq '<folder_name>'
    
  • Site ID is dynamically extracted from the previous response using an XSL mapping.

🧠 Conditionally Construct Filter Query:

  • Use substring-before() if parentpath has /
  • Else use as is

Sample response:

{

  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#drives",

  "value": [

    {

      "id": "b!0mFabc12345def6789ghiJKLmnopQRSTuvwxYZaBCDE",

      "driveType": "documentLibrary",

      "name": "Documents",

      "webUrl": "https://yourtenant.sharepoint.com/sites/testsite/Shared%20Documents",

      "createdDateTime": "2023-04-20T10:30:00Z",

      "lastModifiedDateTime": "2024-03-15T08:45:00Z",

      "createdBy": {

        "user": {

          "displayName": "Admin User",

          "id": "admin-user-id"

        }

      },

      "lastModifiedBy": {

        "user": {

          "displayName": "Admin User",

          "id": "admin-user-id"

        }

      }

    },

    {

      "id": "b!9xYz321klmn456uvwXYZabcDEfghiJKLMNoPQrsTUv",

      "driveType": "documentLibrary",

      "name": "Shared Documents",

      "webUrl": "https://yourtenant.sharepoint.com/sites/testsite/Shared%20Documents"

    }

  ]

}



✅ Step 3: Download File from File Server

  • Action: Use File Adapter with Native File System (FS)
  • Read Mode: Binary
  • Output: Stream Reference

✅ Step 4: Upload File to SharePoint

  • REST Endpoint Name: UploadFileToSharepoint
  • Method: PUT
  • Relative URI:
    /drives/{driveid}/root:/{filename}:/content
    
  • Payload Format: Binary
  • Content-Type: Set as dynamic or static depending on file type
    Example: text/csv or application/octet-stream

🧩 Key Integration Design Elements

Component Description
Trigger REST or Schedule Trigger
File Server Native File Adapter
SharePoint Microsoft Graph API
Mapping Used to extract siteId, build filter, and construct headers
Headers Content-Type (optional but recommended)
Payload Binary Stream from File Adapter

🛠️ Pre-requisites

  • Microsoft Graph OAuth 2.0 Authentication configured in OIC
  • SharePoint API permissions:
    • Sites.Read.All
    • Files.ReadWrite.All
  • File server connection configured
  • OIC connectivity agent if on-prem file server

📌 Conclusion

With this approach, you can automate file transfers between a File Server and SharePoint seamlessly using OIC. This design is scalable and allows for dynamic path and filename handling, making it robust for real-world enterprise use cases.


Implementation screenshots:

Trigger:



Get file from file server



Get site id




Get drive id






Upload file to sharepoint







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...