As a follow up on my last blog about invoking OCI function from Event, I am happy to announce that OCI now supports calling OCI functions from OCI Notifications. This is a huge value add because the event, as I mentioned in my last blog post, is triggered by OCI when a new OCI resource is created/removed or when there is a change in the state of an OCI resource. While that is valuable in governance context and you can implement some use cases using object storage, you cannot do every use case effectively. While you can invoke a function directly from your application, Notifications provide you the pub/sub model to decouple producers and consumers and process data in asynchronous mode. Apart from that, notifications allow you to fan-out messages to a large number of recipients through different mechanisms like Slack, email, pager duty, and now functions.
You can trigger a notification from your application on an as-needed basis. For example:
At a high level, when two applications need to exchange or process data in asynchronous mode, you can invoke notification from the source when the data is ready. Notifications can invoke a function and function can manipulate the data if required and invoke target application to consume the data.
I will not go into an overview of the OCI services used because it was already covered in my last post. So let's go straight to use case implementation.
I am running a Python-based E-commerce application. When a user places an order, I want to send an email notification to the supplier that an order has been placed. I also want to invoke a function to process the order and generate a shipping label and update the order with the shipping label.
As a first step, I will create an OCI notification topic. Then I will write code to trigger a notification from my Ecommerece Python application. The next step is to write a function to process the order data and deploy it on OCI. Once the function is deployed, I can do the remaining plumbing which is to invoke the deployed function when the notification is triggered.
First of all, create a notification topic in OCI. Login to OCI console and create the OrderProcessing notification topic.
If you prefer to use OCI CLI, here is how you can create a topic.
Take note of the topic_id (OCID of the topic created) in the last step. We will use that in our application to trigger the notification. Before that, make sure you have downloaded OCI Python SDK and have made necessary configurations (For detailed Instructions see the Configuration chapter of the SDK). Below is the code snippet to trigger a notification from Python code. topic_id in the code is the topic OCID that you captured in the last step and newOrder is an object of OrderProcessing class. get_orderDetails function of OrderProcessing class should return the JSON representation of the object.
import oci, json from oci
import ons from oci.ons.models
import message_details from orders.models
messageToSend = message_details.MessageDetails()
messageToSend._title = "New Order has been placed:"
+ " by user: "
messageToSend._body = newOrder.get_orderDetails()
config = oci.config.from_file(
"$OCI_PROFILE"). #Replace $OCI_PROFILE with the name of OCI profile
ons_client = ons.NotificationDataPlaneClient(config)
ons_client.publish_message(topic_id,messageToSend) sendOCINotification(topic_id, newOrder)
Make sure your tenancy is set up for function development. Also, make sure that the client environment is configured against the OCI function. You can follow instructions from Oracle Function documentation. If you need more guidance on Python functions, you can check that on the fnproject tutorials.
Create a Python function to process orders and create an application for the function.
Then update the func.py file handler function to perform the action. Make sure you are able to import the OrderProcessing module or respective order module of your application. You will have to copy that to your function directory.
from orders.models import OrderProcessing
from fdk import response
def handler(ctx, data: io.BytesIO=None):
OrderProcessing = json.loads(data.getvalue())
shippingLabel = generateShippingLabel(OrderProcessing.orderData)
returnResponse = "The order " + OrderProcessing.orderData.orderID + " has been updated with shipping label: " + shippingLabel
except (Exception, ValueError) as ex:
Now you can deploy the function and test function invocation.
From the topic that you created in the first step, create subscriptions to invoke a function and send an email to the supplier.
The value that function brings is, let smart developers focus on what matters the most to the business like building functionalities that increase sales. Delegate the function of integrating with other homegrown or third-party services to OCI function. With this new feature, they can delegate calling function and retry calling if the call fails to OCI notifications. Other effective use cases of OCI function are,