OpenWhisk: Polyglot Application with IBM Cloud Functions

Ernese Norelus
10 min readJun 3, 2019

--

Serverless (Functions-as-a-Service) computing is the next step in cloud evolution.

Figure 1: OpenWhisk Abstract Architecture Diagram. Image credit: Apache OpenWhisk™.

This blog is co-authored with Enrique (Ike) Relucio as part of our IBM Garage Engagements. Developing a single application is easy, but how do you go about showing extensible use of cloud-native features with multiple functions? We wanted to show a bit more than the traditional HelloWorld.

In recent years, the conversations have been predominantly on microservices. We have since built a great deal of architecture supporting the transformation to Cloud. Serverless is the next step in cloud evolution. With regards to Serverless, there are four concepts that you need to understand as an architect or developer: packages, actions, rules, and triggers (PART). If you master these four concepts, you are nearly 80% done with regards to Apache OpenWhisk concepts. IBM Cloud Functions is IBM’s commercial implementation of OpenWhisk, which exposes application logic by implementing Serverless microservices.

You might ask, what is a good use case for using Serverless, also know as Functions-as-a-Service (FaaS)? Well, we are glad you asked! In this blog, we are going to take you on a Serverless journey, and shed light on a real-world Serverless project.

In this blog post, we’ll explore and demonstrate the fundamentals of Apache OpenWhisk on IBM Cloud with IBM Functions and demonstrate setting up and running it as well. We will also show integration with various services, including the Cloudant database and develop the different implementation languages, such as Node.js, Python, and Java as a polyglot application. The events triggered will invoke third-party service integration, such as Cloudant database and email notification.

Figure 2: A high-level view of the Serverless solution

For more literature on IBM Cloud Functions, please visit this site. While you are there, go ahead and create an account for yourself if you don’t already have an account with IBM Cloud. The free tier quota is sufficient for completing this tutorial. You can also use other Serverless framework, but our focus is on IBM Cloud Functions and OpenWhisk. The application will be running on premises.

This project contains a sample polyglot application to send either emails or text messages to specific users depending on which information have provided in their profiles.

We are going to demo a polyglot Serverless application built with OpenWhisk on IBM Cloud.

What is Serverless Computing?

Serverless computing is a cloud-computing execution model of a software design pattern where a third-party service hosts applications (not to be confused with no server is required, which is something we often get asked) and is best described with the following characteristics:

  • Has emphasis on code snippets rather than on servers of platforms
  • Executes code without the need to provision resources
  • Functions as a fundamental unit of deployment and follows the concept of FaaS (Function as a Service) with a very well defined purpose.
  • Is a short process that could last milliseconds rather than minutes
  • The function is the unit of control

Introduction to Apache OpenWhisk

OpenWhisk was originally developed at IBM as part of the Bluemix platform, now known as IBM Cloud. It was donated to the Apache Foundation, thus its new name Apache OpenWhisk, is under IBM’s commercial offering called IBM Cloud Functions, and is hosted on IBM Cloud.

Apache OpenWhisk (Incubating) is an open source, distributed Serverless platform that executes functions (fx) in response to events at any scale. OpenWhisk manages the infrastructure, servers and scaling using Docker containers so you can focus on building amazing and efficient applications.

The OpenWhisk platform supports a programming model in which developers write functional logic (called Actions), in any supported programming language, that can be dynamically scheduled and run in response to associated events (via Triggers) from external sources (Feeds) or from HTTP requests. The project includes a REST API-based Command Line Interface (CLI) along with other tooling to support packaging, catalog services and many popular container deployment options. *

OpenWhisk Architecture

A few paragraphs ago, we alluded that you only needed to understand four critical parts of OpenWhisk, which were: actions, packages, triggers, and rules. It’s now time to elaborate a bit on each point and walk you through the process of using each one.

  • Actions are stateless code snippets that run on the Apache OpenWhisk platform. You can develop an action (or function) via Node.js, Swift, Java, Go, Scala, Python, PHP, Ruby and Ballerina. You can create and customize your own executables as Zip Actions which run on the Docker runtime by using the Docker SDK. Actions can be explicitly invoked or run in response to an event. In either case, each run of an action results in an activation record that is identified by a unique activation ID. The input to an action and the result of an action are a dictionary of key-value pairs, where the key is a string and the value a valid JSON value. 1 2
  • Triggers are associated with those feeds and fire when an event occurs where developers can map actions to triggers using rules.
  • Rules are used for wiring an action or series of actions for a given trigger name by an event as input. Multiple triggers can invoke the same action.
  • Packages provide event feeds; they are a way of keeping actions grouped. Anyone can create a new package for others to use, and similar to actions, they can have parameters as well.
Figure 3: OpenWhisk Architecture

End-to-end OpenWhisk Polyglot Application

In recent years, Serverless programming models have become much easier to develop because of their rich set of runtimes, features, supported platforms, and the current runtime supported languages including native support.

Adopting software engineering best practices for Serverless applications, it is advised to keep functions small and focused on a single task. Small single-purpose functions are easier to develop, test, and debug.

We will explore how to develop and deploy end-to-end Serverless applications in the cloud using IBM Cloud Functions. To make things interesting, we will use the concept of polyglot, where we will leverage on some core functionalities of OpenWhisk, such as Node.js for the Cloudant database, Java for the landing page, and Python for email notification, as depicted below:

Figure 4: End-to-end OpenWhisk Polyglot Application

Although the component architecture is self-explanatory, it never hurts to be sure the audience understands the concepts by providing a bit more detail. We will explore all the topics discussed earlier and make this come to life in this demo:

1- Trigger: Comes from web page (a class of events that belongs to an application; anything that is an event is known as a trigger).

2- Action: Up on submission request from web page; it’s the event-handler that responds to an event; this is where you write your code; an action is associated with a trigger.

3- The Cloud Functions actions use IBM Cloudant to store entries from Web page.

4- An email is sent every time a new entry is created in Cloudant database as Rule (send some event).

As depicted above; the developer only needs to care about implementing the desired application logic — the system handles the rest.

Prerequisites

To follow along, you are required to have these accounts and tools in place:

Setting up the environment

We have created a git repo with the steps needed so that you can reproduce the demo if you need a local instance running on a vagrant box with IP 192.168.99.157.

You will need to have all of the below installs to run the demo if you want to follow along, as for the IBM Cloud Functions CLI it is included in the script below.

Login into IBM Cloud

The necessary steps were already done from the section above Setting up the environment. To access your account the credentials are required, follow the steps below to start your IBM Cloud Functions.

ibmcloud login -a https://api.ng.bluemix.net --sso
ibmcloud plugin install cloud-functions
ibmcloud fn namespace list
#ibmcloud target -o <org_name> -s <space_name>
ibmcloud target -o ernese@sg.ibm.com -s cloudnative-dev
ibmcloud regions
Figure 5: Login into IBM Cloud

Creating the Cloudant Database Instance

Follow along with the creation of the Cloudant database instance. Then bind the Cloudant instance to the newly created package so that the credentials are automatically made available. The credentials key with the embedded username and password as part of the event source for the OpenWhisk functions:

ibmcloud cf create-service cloudantNoSQLDB Lite testdb
ibmcloud cf service testdb | grep "create succeeded" # this will indicate once the testdb is created!
ibmcloud cf create-service-key testdb myapp
ibmcloud cf service-key testdb myapp
Figure 6: Creating the Cloudant Database Instance

Create Cloudant Package

In the steps above, we created the Cloudant Database Instance; now, we need to refresh the package so that the database gets associated with the right Cloudant instance and credentials.

ibmcloud fn package refresh
ibmcloud fn package list

Create Cloudant database table with the cURL command below:

export CLOUDANT='<URL>' # the url is taken from the CLI above in section "Creating the Cloudant Database Instance"!
curl -s -X PUT $CLOUDANT/testdb

Create SendGrid email

To create and send email using SendGrid, you need to do the following:

  • Create a SendGrid account
  • Create an API Key
  • Modify file with the right API Key shown below with — ‘Authorization’: ‘Bearer <Sendgrid’s key>’
Create SendGrid email

Copy Bluemix_testdb_theKey/Create-document

You must copy the Endpoint from this screen to add this into your Java Guest application so that you can connect to the Cloudant database.

Figure 7: Copy Bluemix_testdb_theKey/Create-document

Create Guest book Application

The Guest book Application is already provided, so make sure you copy the right credentials in the DoIt.java code below. These details are required to be changed:

myurl = new URL(“url from — Endpoints of Bluemix_testdb_theKey/create-document”); String username = “username — from running ‘ibmcloud cf service-key testdb myapp’”; String password = “password — from running ‘ibmcloud cf service-key testdb myapp’”;

To build and run the application:

cd ~/artefacts/java/
mvn install
mvn liberty:run-server

Create Trigger, Action, and Rule for new Guest

Rules bind triggers to actions. When triggers are fired, all actions connected via rules are invoked with the trigger event. Multiple rules can refer to the same trigger supporting multiple listeners to the same event. Now that we have all the pieces in place, let’s start creating the triggers, actions, and rules to support the new Guest application written in Java.

cd ~/artefacts/python
ibmcloud fn action update sendMailPY.py sendMailPY --kind python:3
ibmcloud fn trigger create data-inserted-trigger --feed Bluemix_testdb_theKey/changes --param dbname testdb

ibmcloud fn action create guest-sequence --sequence Bluemix_testdb_theKey/read,sendMailPY

ibmcloud fn rule create log-guest data-inserted-trigger guest-sequence
ibmcloud fn rule enable log-guest

Run demo

Let’s combine all the concepts discussed in the blog post. Open your browser and type: http://192.168.99.157:9080/ and you shall get the landing page below:

Now that it’s pushed to docker hub we can pull it in to OpenWhisk.

Figure 8: Guestbook application

Open your Cloudant database; you should have at least one record inserted into the database.

Figure 9: Cloudant database entries

Open your email. You should have received an email titled: “Inserted into a Cloudant DB”.

Figure 10: Email from Inserted into a Cloudant DB

Clean up

It’s now time to clean up, all the service-key, service, trigger, action, and rule will be deleted upon running the commands below:

ibmcloud cf delete-service-key testdb myapp
ibmcloud service delete testdb
ibmcloud fn trigger delete data-inserted-trigger
ibmcloud fn action delete sendMailPY
ibmcloud fn action delete guest-sequence
ibmcloud fn rule delete log-guest

Conclusion

This blog post took you through a walkthrough that covered a real-life scenario of deploying a production version of your application. You’ve been able to use IBM Cloud Functions and connect to a Cloudant database. And you’ve been able to create Serverless actions in Java, Node.js, and Python as part of a Polyglot Application. Apache OpenWhisk has an impressive set of features to help with this problem, triggers, and rules! We hope you learned a lot from this experience, and we look forward to our next knowledge sharing session.

Thoughts and ideas are much appreciated! And if you would like to learn more about how you can co-create with the IBM Garage, please visit https://www.ibm.com/garage

Attribution

Special thank you to Enrique (Ike) Relucio from IBM Garage ASEAN, as this was his idea to come up with the scenario and also for his help in debugging maven script and Cloudant database trigger issues!

References

For more details on Apache OpenWhisk and Serverless computing, refer to the reference section below where you can find many read up on Functions-as-a-Service and code snippets from the references below that we highlighted and a few posts we urge you to visit to gain the most out this blog post.

Bring your plan to the IBM Garage.
Are you ready to learn more about working with the IBM Garage? We’re here to help. Contact us today to schedule time to speak with a Garage expert about your next big idea. Learn about our IBM Garage Method, the design, development and startup communities we work in, and the deep expertise and capabilities we bring to the table.

Schedule a no-charge visit with the IBM Garage.

--

--

Ernese Norelus

Ernese is responsible for providing technical oversight to Cloud client projects!