OCI increases Notifications fan-out by adding Functions support

February 25, 2020 | 5 minute read
Kiran Thakkar
Consulting Solutions Architect
Text Size 100%:

Overview

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:

  1. Trigger a notification when a user account is created in your application which in turn can call a function to generate user activation email (Note that this is not OCI IAM user. This is application user.).
  2. Trigger a notification when a user places an order to buy merchandise. That notification can call a function to generate a shipping label and update the order with shipping label information.
  3. When an expense report for the user is approved, you can trigger a notification event that can invoke a function to reimburse the user.

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.

Objective

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.

Implementation

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. 

Create an OCI Notification topic

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.

Trigger notification from Python application

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
import OrderProcessing
def sendOCINotification(topic_id,newOrder):
    messageToSend = message_details.MessageDetails()
    messageToSend._title = "New Order has been placed:"
        + newOrder.orderData.orderID
        + " by user: "
        + newOrder.userData.userID
    messageToSend._body = newOrder.get_orderDetails()
    config = oci.config.from_file(
        "~/.oci/config",
        "$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)

 

Write and deploy the function to process incoming order data

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. 

import io
import json
from orders.models import OrderProcessing
from fdk import response
def handler(ctx, data: io.BytesIO=None):
    try:
        OrderProcessing = json.loads(data.getvalue())
        shippingLabel = generateShippingLabel(OrderProcessing.orderData)
        OrderProcessing.setShippingLabel(shippingLabel)
        returnResponse = "The order " + OrderProcessing.orderData.orderID + " has been updated with shipping                 label: " + shippingLabel
    except (Exception, ValueError) as ex:
        print(str(ex))
    return response.Response(
        ctx, response_data=json.dumps(
            {"message": returnResponse}),
            headers={"Content-Type": "application/json"}
     )

Now you can deploy the function and test function invocation.

Configure email and function subscription

From the topic that you created in the first step, create subscriptions to invoke a function and send an email to the supplier.

Conclusion

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,

  • Filtering and transforming data on the fly either when the data is created or when the data is updated
  • Trigger birthright provisioning for the user when a new user account is created
  • Reindex the data or invalidate the cache when the data has changed
  • With notifications being able to call functions, functions can also be used to respond to an OCI Alarm to either scale-out or trigger service fail-over script.  

References

Kiran Thakkar

Consulting Solutions Architect

Kiran Thakkar is an expert in Identity and Access Management with more than 10 years of experience in the space. He is also OCI certified Associate Architect and help customers on OCI use cases. He is believer in blockchain technology and follows that space as it grows.


Previous Post

Deploying Oracle Data Integrator Marketplace in a Private Subnet with Autonomous Database

Dayne Carley | 13 min read

Next Post


Basic troubleshooting tools - Part 1

Ionut Neubauer | 12 min read