From the Oracle website -
Oracle Cloud Functions is a serverless platform that lets developers create, run, and scale applications without managing any infrastructure. Functions integrate with Oracle Cloud Infrastructure, platform services and SaaS applications. Because Functions is based on the open source Fn Project, developers can create applications that can be easily ported to other cloud and on-premises environments. Code based on Functions typically runs for short durations, and customers pay only for the resources they use.
These Functions can be written in a variety of languages - Java, Python, Node etc. You write and deploy the code, Oracle takes care of provisioning, scaling etc.
Think of blocks of code that generally do one thing, e.g. applying a discount to an order. These are stored as Docker images in a docker registry. They can be executed via CLI or HTTP request. We will be using the latter in our example.
So how do Functions enhance the OIC experience?
Here's one use case - Say you are porting SOA Composites to OIC and you make use of Java Embedding in your BPEL process. Where shall I put that code in OIC?
So let's implement a simple example -
Here is my Java class -
I realise the above is banal, but we can all extrapolate, correct?
Functions: creating an Application
Starting point is access to Oracle Functions -
Here I create an application - So what is an application?
Essentially a bucket for your functions e.g. HCM Functions, ERP Functions etc. It is also a unit at which resources can be allocated and configured. These resources can include subnet(s) allocated, whether logging is enabled etc.
Functions: creating a Function
I click on Getting Started
Launch Cloud Shell -
Note the initial setup cmds - you only need to do this once.
I do a fn list apps command and see my 3 apps, including oic-discount-app.
I now enter a cmd to create a Java function skeleton - fn init --runtime java oicdiscount-java
So what has been generated?
Let's look at the /src directory structure -
Let's look at main -
So here it has generated an example Hello World java -
I make a copy of this file, calling it OICDiscountFunction.java
I vi the result -
I can now delete the HelloWorld function -
So now I have my Java code defined, what about the other directory - /test?
As you can see, a tester class that invokes HelloWorld.
I could get remove the /test directory, but for the moment, let's amend to call our OICDiscountFunction. Same procedure- copy the existing Java file and amend as necessary.
Now I can remove the Hello tester -
Now back up to the top app directory -
I need to amend both these files, as they reference the HelloWorld demo.
As you can see here, I will need to change the cmd line.
All I need to change here is artifactId
This I change to oicdiscount
I could also add a property here to skip testing -
Thanks - Angelo Santagata - for pointing this out to me.
Now to deployment -
Validate it was successful -
I activate logging at Application level -
Calling Functions from OIC
My colleague Daniel Teixeira wrote a great blog post which helped me out. you can read it here
Step 1 is to create a REST Connection to OCI Functions -
So what will we need here?
1. base url
2. tenancy ocid
3. user ocid
4. private key
3 -5 can be found here -
API Keys can be created/uploaded here -
As you can see, the Fingerprint is also available here.
What about the base url?
Check out the Functions screen again - note the Invoke Endpoint url
take that url up to, but not including /20181201
For Security - we use OCI Signature Version 1
For Tenancy OCID -
I enter all the required fields - then Save and Test the REST Connection -
I create an App-Driven Orchestration in OIC -
Rest Trigger - Request -
I drop the OCI Functions REST Connection and configure as follows -
relative resource uri will be set to /2018.../invoke from the Invoke Endpoint.
Naturally I could do this somewhat more elegantly - but this is a simple demo, isn't it?
Request is defined as follows -
Use the same definition for the Response.
Now to the Mapping -
Source is the country from the Request -
Mapping will use the following OIC Advanced Mapping Functions -
oraext:encodeBase64 (/nssrcmpr:execute/nssrcdfl:request-wrapper/nssrcdfl:country ) )
Response Mapping - essentially we do the opposite -
oraext:decodeBase64 (oraext:encodeReferenceToBase64 ($ComputeDiscount/nsmpr0:executeResponse/ns25:streamReference ) )
Deploy and Test -
I can check out the OCI Logs -
A simple and effective combination - OIC and Oracle Functions.
Happy Christmas 2020 and may 2021 bring you more Health, Wealth and Happiness.