How to Invoke an OCI Function from the Oracle Integration Cloud

 Article originally posted on the Oracle Integration Blog.

 How to Invoke an OCI Function from the Oracle Integration Cloud

The Oracle Cloud Infrastructure (OCI) offers a great set of services that can be very useful in combination with Oracle Integration Cloud (OIC) for a wide variety of use cases. Things like the Object Storage, Oracle Streaming Service, Functions etc, can easily be accessed from OIC. The OCI ecosystem has a rich set of API’s that can be used for that purpose – https://docs.cloud.oracle.com/en-us/iaas/api/#/

In this post I am going to show how to deploy a Function, and how to Invoke it from OIC.

What are Functions

“Oracle Functions is based on Fn Project. Fn Project is an open source, container native, serverless platform that can be run anywhere, It’s easy to use, supports every programming language, and is extensible and performant.”

How to Start

There is extended documentation and plenty of blogs & tutorials that provide a comprehensive deep dive into OCI , Docker Images and Functions etc.

Being this an Integration Blog, we will focus on the OIC side of things, while providing some tutorials on how to setup an OCI Function.

If you already have a deployed Function, you can skip the next section.

Pushing an Image to Oracle Cloud Infrastructure Registry (OCIR)

A Function is stored as Docker image in OCIR, hence we need to push our image before invoking a Function.

If you are new to this please follow this TUTORIALNoteworthy to mention that the tutorial is easier if you use the Oracle Cloud Shell. This way there is no need to install anything.

At the end of the tutorial you will have  pulled the helloworld image from DockerHub, tagged it, and pushed it to Oracle Cloud Infrastructure Registry.

Below is my OCIR list of repositories.

Documentation available here !

Create & Deploy a Function

To Create & Deploy a Function please follow this TUTORIAL!

At the end you will have a deployed function that can be invoked via several different methods, but we are interested in the HTTP Requests.

Invoke the Function (REST)

How can we test the REST API for the Function?

Normally I use POSTMAN to test all my REST requests before jumping into OIC. This time however I took a different approach and followed this excellent guide that uses CURL: https://www.ateam-oracle.com/oracle-cloud-infrastructure-oci-rest-call-walkthrough-with-curl

It provides a bash script for which you only need to configure the security parameters and the REST endpoint.

And the Function returns the expected concatenation of : Hello + “my input message”

How to Invoke the Function from OIC

Create a REST Connection

You will need to collect some information in order to fill the required parameters.

Connection Type REST API Base URL
Connection URL https://xxxxxxxx.eu-frankfurt-1.functions.oci.oraclecloud.com xxxxxxx is the Function Unique ID.The easy way is to get this from the console, in the function details.

Adjust the region accordingly.

Security OCI Signature Version 1
Tenancy OCID

Open the navigation menu, under Governance and Administration, go to Administration and click Tenancy Details.

The tenancy OCID is shown under Tenancy Information. Click Copy to copy it to your clipboard.

User OCID

Open the Profile menu (User menu icon ) and click User Settings.

The user OCID is shown under User Information. Click Copy to copy it to your clipboard.

Private Key https://docs.cloud.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm#two
Fingerprint https://docs.cloud.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm#three

Create an Integration

For this demo use case I will create an AppDriven Orchestration with:

  • REST Trigger
  • REST InvokeFunction
  • Return the Function response

This Integration starts with a REST Trigger that takes one parameter as input.

The Function Hello-World takes one parameter as input and returns a concatenation of Hello, <input message>!

We then map the Function response to the output.

I will focus on the REST InvokeFunction activity.

REST Function Invoke

First we look at the Oracle OCI API’s reference where can see the URI and the required parameters.

The FunctionId in the POST URI is the Function OCID and can be found in the Oracle Cloud Console. This is not the same as the Function unique identifier from the REST connection properties. Here we need the OCID.

POST /20181201/functions/{functionId}/actions/invoke

In a real implementation I would obviously not pass the URI hardcoded, but instead use a variable for it. This is the lazy approach 😊

We check the box for Request Payload and Receive Response.

Now at this time you need to tell the REST adapter what kind of Payload and Media Type your function expects. The Hello-World Function expects a plain text as input. The REST adapter allows to easily choose payload format from XML and JSON, but for plain text we need to actually choose Binary as the payload and then set the media-type as “text/plain”.

We do exactly the same thing for the Response.

Since the Binary Payload format expects a stream reference type, we need an additional step in order to properly map this.

This article provides a very clear step by step: https://www.ateam-oracle.com/invoke-rest-endpoint-with-plain-text-payload

Basically we need to perform some encoding/decoding to the input string before passing it along to the REST Function Invoke

  • decodeBase64ToReference( encodeBase64( input))

When we put this to test is quite straightforward! The embedded REST testing capabilities in OIC really make life easier.

Please note that the first time the Function runs, the image is pulled from the registry, and executed as a container. The subsequent requests are sent to the same container. After some idle time, the container is removed. More details on the invocation here.

And we can verify in the OCI Console Logs the successful invocation of the Function.

Conclusion:

Invoking a Function is just one of the many benefits of working alongside the OCI services. It allows OIC to invoke custom code deployed in this serverless framework, thus expanding its range of capabilities.