
The Apress logo.
This Apress imprint is published by the registered company APress Media, LLC, part of Springer Nature.
The registered company address is: 1 New York Plaza, New York, NY 10004, U.S.A.
I would like to dedicate this book to my wife Vijaya and my wonderful children Pooja and Deepika, who stuck with me through the trials and tribulations during the writing of this book. I also dedicate this to my mom, Kalpana Parasuraman.
I entered the field of Information Technology (IT) 25 years ago, after spending time in sales and marketing. I was an average programmer and was never into hardcore programming. During my early life in IT, I worked as part of a team that built a baseball simulator for the Detroit Tigers. I helped build a video capture driver for that simulator using C++. Even though this was a great project with a lot of visibility, it was never my real passion to be a hard-core programmer.
I soon gravitated toward solution architecture. This seemed to perfectly tie my marketing skills to my technology skills. I began looking at solutions from a marketing lens. This approach formed the basis for writing this book. Because, what good is a technology if we do not know how to apply it in real life?
Functional programming was an emerging technology. Cloud providers such as AWS, Google, and Azure created serverless environments, with innovations such as Firecracker virtualization techniques, that allowed infrastructure to scale down to zero. This allowed customers to derive huge cost savings by not paying for resources that were not in use and subscribing to a pay-per-use model.
Initially, development of these functions that run on serverless environments were built on either NodeJS or Python. These functions were also vendor-specific. Spring.io developed the Spring Cloud Function framework, which allowed the functions to run in a cloud-agnostic environment. The focus was on the “write once, deploy anywhere” concept. This was a game changer in the cloud functions world.
Prior to writing this book, I was a staunch evangelist of Pivotal Cloud Foundry and Kubernetes. I promoted writing code that was portable. When Knative came into being in 2018 as a joint effort between IBM and Google, I was excited. Knative was designed as a serverless infrastructure on top of Kubernetes and made the serverless infrastructure portable. Combining the power and portability of Spring Cloud Function and Knative, you have a true portable system with zero scale-down capabilities.
This was something that I wanted to write and evangelize about. But I felt that writing about the technology and how it worked would not be that exciting. I wanted to write about how people could use this technology in the real world.
In this book, you will see how to program and deploy real-life examples using Spring Cloud Function. It starts with examples of writing code and deploying to AWS Lambda, Google Cloud Function, and Azure Function serverless environments. It then introduces you to the Knative on Kubernetes environment. Writing code and deploying is not enough. Automating the deployment is key in large-scale, distributed environments. You also see how to automate the CI/CD pipeline through examples.
This books also takes you into the world of data pipelines, AI/ML, and IoT. This book finishes up with real-world examples in oil and gas (IoT), manufacturing (IoT), and conversational AI (retail). This book touches on AWS, the Google Cloud Platform (GCP), Azure, IBM Cloud, and VMware Tanzu.
The code for these projects is provided on GitHub at https://github.com/banup-kubeforce. It is also available at github.com/apress/practical-spring-cloud-function. This allows you to get up to speed on the technologies. So, after completing this book, you will have hands-on experience with AI/ML, IoT, data pipelines, CI/CD, and of course Spring Cloud Function.
I hope you enjoy reading and coding this book.
It has been a great privilege to write this book and help you understand real-world implementations of Spring Cloud Function. Thank you for reading it.
After my presentation at SpringOne 2020, I received a message on LinkedIn from Steve Anglin at Apress. Steve asked me if I would be willing to write a book about Spring Cloud Function. I was a bit hesitant at first, given that I was occupied with many client engagements, which were taking up most of my work hours. I was worried that I would not do the subject justice, due to my preoccupation with my clients. But after a long contemplation and a heartfelt discussion with my family, I decided to take it on.
I want to thank Steve Anglin, Associate Editorial Director, for reaching out to me and providing me this opportunity to write a book on Spring Cloud Function.
Mark Powers, the Editorial Operations Manager, was instrumental in helping me bring this book to close. With his incessant prodding and nudging, he helped me reached the finish line. Thanks, Mark.
Manuel Jordan, the technical reviewer, was immensely helpful. His comments kept me honest and prevented me from cutting corners. He helped improve the quality of the solutions that I present in this book. Thanks, Manuel.
I also want to thank Nirmal Selvaraj and others at Apress, who worked to bring this book to fruition.
This book would not be possible without the help of my wife Vijaya and daughters Pooja and Deepika, who provided the much-needed emotional support through this journey.

The photograph of Banu Parasuraman.

The photograph of Manuel Jordan Elera.
This chapter explores Spring Cloud Function using a sample use case—an HRM (Human Resources Management) system. The focus is on systems that reside in an enterprise. The chapter touches on the FaaS (Functions as a Service) concept and explains how it is gaining momentum in the enterprise. The chapter also digs deeper into its implementations in the cloud. You will learn about some of the portability issues present at the code and container level and read about concepts such as Knative on Kubernetes, which includes container portability. You will also learn about some high-level implementations of Spring Cloud Function on AWS, GCP, Azure, VMware Tanzu, and Red Hat OpenShift.
The function code encapsulates the business logic in any language, such as Java, C#, Python, Node, and so on.
The underlying container hosts an application server and an operating system.

An illustration describes a container containing function code, app server, and operating system. An events cloud flows a consumer to a container, and a container flows a supplier to an events cloud.
FaaS component architecture
Imagine all the infrastructure needed to run a single payroll application on the cloud. This application may consume only 16GB of RAM and eight vCPUs, but you are charged continuously for the entire duration that the application is active. Using a simple AWS pricing formula, this works out to around $1,000 per year. This cost is for the whole time the application is hosted and active, regardless of use. Of course, you can cost-justify it through a TCO (Total Cost of Ownership) calculation, which helps you determine how your application can bring in revenue or value that compensates for the expense. This revenue-generation model is more suitable to applications that generate revenue for the company, such as an ecommerce site. It is more difficult to prove the value that a supporting application, running in the backend of an enterprise, brings to a company.
The value equation gets more complex if you plan to migrate an extensive portfolio of apps in your enterprise.
What is the current infrastructure supporting the apps?
What is the utilization of these apps?
10% with 80% utilization
40% with 50% utilization
50% with 20% utilization
If you calculate the billing cost using an AWS cost calculator, you see that you will spend $1 million per year. This spend is for applications that are critical and highly utilized, as well as for applications that are minimally utilized. This cost is due to the fact that the cloud providers charge for the entire duration the application is active and consuming the infrastructure. The key here is that the infrastructure is fully allocated for the application’s life. Imagine how much you could save if the infrastructure was allocated only for the duration that the application was active and serving. This would be a great cost and resource saving approach. Cloud providers have thought through this because they also faced the pressure of finite infrastructure and considered the time needed to provision additional infrastructure.
To work around the problem of finite infrastructure utilization, AWS created Lambda serverless functions. This was a genius invention. Subscribers to this service pay only for the time the application is invoked. The infrastructure is unallocated when it is not invoked. This way, AWS can save on infrastructure by repurposing the infrastructure for other needy applications while transferring the cost savings to the customer. This is a win-win. It’s worth considering whether you can apply this same approach to all the enterprise applications in your company today. You would be able to save a lot of money. Also, if you were to bring this technology to the datacenter, you would be able to reap the benefits that AWS realized. Isn’t this wonderful?
Timecard system to get the hours employees worked in a month
Performance evaluation system
Peer feedback system
Inflation adjustment calculator system
The outgoing interface to the IRS
The outgoing interface to the medical insurance provider
An outgoing interface to the internal web portal where employees can download their paystubs
Fourteen dedicated middleware application servers
Two RDBMS database stores
Two integration tools such as message queues and FTP
Four dedicated bare-metal servers, with each server configured with 128GB RAM, 32 CPUs, 4TB of HDD, 10TB of vSAN, and the like
The key factor in determining whether this application can be hosted on a serverless functions infrastructure like Lambda is the time it takes for the application to boot up (the startup time or cold start) and the time it takes for the application to shut down (the shutdown time). The faster the startup and shutdown times, the larger the cost savings.
It is also important that these times be quick so that they don’t cause disruptions. If you were to research the startup times for large enterprise applications like the payroll application, you would find that it is not pretty. An average startup time is around 15 minutes for all components to come up and another 15 minutes for the application to come down. This would not fly. Imagine if you deployed this application to an AWS Lambda serverless function. Thirty minutes of downtime for each invocation? This will not work. Your users would abandon the application entirely. As you can see, large applications cannot benefit from resource release and resource reassignment because they take a long time to start up and shut down, which would impact the general operation of the application.
Can you make this large payroll application behave in an expected way for serverless functions? The answer is yes. A lot of refactoring is required, but it can be done.
Serverless function code that serves the functions
Serverless infrastructure (containers) that supports the code

A circle diagram depicts the cloud strategy for all organizations. 2% single private, and 9% single public, 89% multi-cloud. Multi-cloud is separated into 80% hybrid cloud, 7% multiple public, and 2% multiple private.
Multi-cloud adoption report Source: https://info.flexera.com/CM-REPORT-State-of-the-Cloud?lead_source=Website%20Visitor&id=Blog
In a multi-cloud world, it is essential that enterprises subscribe to services that can be easily ported between clouds. This is especially important for commodity services.
FaaS, or serverless functions, have of late become a commodity with all the providers having some services around FaaS. It is therefore imperative that FaaS containers not have proprietary code.
Serverless functions become portable when they do not use proprietary code. Portable serverless functions allow for workload mobility across clouds. If, for instance, AWS Lambda functions are costly and Azure Functions are cheap, enterprises can avail the cost savings and move that Lambda workload to Azure Functions with very little effort.
The subsequent sections discuss in detail these portability issues and explain how you can solve them.
Listing 1-1 shows the sample AWS Lambda code written in Java. This code was generated using the AWS SAM (Serverless Application Model) template. When observing the code, you can see that the AWS-specific library references and method calls bind the code to AWS. It is not much, but it is potent. In an enterprise, you typically have hundreds if not thousands of pieces of code that you must refactor if you want to move this type of code to another cloud provider. This is a costly affair.
Listing 1-1.Sample Code Using the AWS SAM Framework

A framework of amazon web services serverless application model. Package HelloWorld. It describes amazon web service-specific code and method calls that bind the code to amazon web services.
The following section explores the portability of the underlying serverless container, which impacts how multi-cloud migrations are conducted.
What about Lambda’s underlying serverless framework? Is it portable?
If you deep dive into AWS Lambda, the virtualization technology used is Firecracker. Firecracker uses KVM (a kernel-based virtual machine) to create and manage microVMs. You can find more information on Firecracker at https://aws.amazon.com/blogs/aws/firecracker-lightweight-virtualization-for-serverless-computing/.
The minimalist design principle that Firecracker is built on allows for fast startup and shutdown times. Google Cloud Functions, on the other hand, use gVisor and are not compatible with Firecracker. gVisor is an application kernel for containers. More information can be found at https://github.com/google/gvisor.
Azure Functions take a totally different approach of using the PaaS offering app service as their base. So, you can see that the major cloud providers use their own frameworks for the managing functions’ containers. This makes it difficult for functions to move between clouds in a multi-cloud environment. This portability issue becomes more pronounced due to the lack of portability at the container level.

A comparison table. Function codes for Lambda of them are Lambda run time, sandbox, guest O S. For Google, gVisor, Host Kernel, and Google computes engine. For Azure, some of them are language runtime, and web jobs script runtime.
Serverless architecture comparison
You can see that the code and containers both differ from the provider and are not easily portable.
Portability of code
Portability of the serverless container
Cold start of the serverless environment
How do you solve these issues?
Enter Spring Cloud Function and Knative. Spring Cloud Function addresses function code portability, and Knative addresses container portability.
Information on Spring Cloud Function is available at https://spring.io/projects/spring-cloud-function, and information about Knative is available at https://knative.dev/docs/.
The following sections deep dive into each of these topics.
A hybrid cloud comprises a private cloud and a public cloud and is managed as one entity. Multi-cloud includes more than one public cloud and does not have a private cloud component.
Promote the implementation of business logic via functions.
Decouple the development lifecycle of business logic from any specific runtime target so that the same code can run as a web endpoint, a stream processor, or a task.
Support a uniform programming model across serverless providers, as well as the ability to run standalone (locally or in a PaaS).
Enable Spring Boot features (auto-configuration, dependency injection, metrics) on serverless providers.
Source: https://spring.io/projects/spring-cloud-function
The key goals are decoupling from a specific runtime and supporting a uniform programming model across serverless providers.
Using Spring Boot
Wrapper beans for Function<T, R> (Predicate), Consumer<T>, and Supplier<T>
Packaging functions for deployments to target platforms such as AWS Lambda, Azure Functions, Google Cloud Functions, and Knative using adapters
Another exciting aspect of Spring Cloud Function is that it enables functions to be executed locally. This allows developers to unit test without deploying to the cloud

A model diagram describes the deployment of the spring cloud function. Spring cloud function deployed to Amazon cloud, Google cloud, and Azure using implementation-specific libraries.
Deploying Spring Cloud Function directly to FaaS environments provided by the cloud providers

A model diagram describes the deployment of the spring cloud function plus K native. It deployed to hyper-scale clouds and on-prem or hybrid.
Deploying Spring Cloud Function on Knative serverless configured on Kubernetes environments provided by the cloud providers
When Spring Cloud Function is containerized on Knative, it can be deployed to any Kubernetes offering, whether on the cloud or on-premises. This is the preferred way to deploy it on hybrid and multi-cloud environments.

A diagram describes normal traffic flows to hosted applications, and traffic spike flows to burst applications. A corporate data center and public cloud synchronize with hosted and burst applications.
Cloud bursting
Figure 1-6 shows that, to compensate for the lack of resources in a private cloud during a traffic spike, resources are allocated to the public cloud where the traffic is routed. When the traffic spike goes down, the public cloud resources are removed. This allows for targeted use of costs and resources—that is, it uses additional resources only during the traffic spike period. The burst of activity during an eCommerce event like Cyber Monday is a great example of a traffic spike.
This cannot be easily achieved with just a portable code. You need containers that are also portable. This way, containers can be moved across cloud boundaries to accommodate traffic spikes. In Figure 1-6, you can see that VMs from VMware are used as containers. Since the VMs hosted in the datacenter and hosted in the cloud are similar in construct, cloud bursting is possible.
Applying this to Functions as a Service, you need a new way to make the underlying serverless containers portable.
One such revolutionary approach in the cloud function world is Knative. The next section dives deep into Knative.
What was the need for containers /serverless platforms?
Over the course of the evolution of IT, there has been a need for secure isolation of running processes. In the early 90’s, chroot jail-based isolation allowed developers to create and host a virtualized copy of the software system. In 2008 Linux Containers (LXC) was introduced which gave the developers a virtualized environment. In 2011 Cloud Foundry introduced the concept of a container, and with Warden in 2019 container orchestration became a reality. Docker, introduced in 2013, provided containers that can host any operating system. Kubernetes, introduced in 2014, provided the capability to orchestrate containers based on Docker. Finally, Knative, introduced in 2018, extended Kubernetes to enable serverless workloads to run on Kubernetes clusters.
Serverless workloads (Knative) grew out of the need to help developers rapidly create and deploy applications without worrying about the underlying infrastructure. The serverless computing model takes care of provisioning, management, scheduling, and patching and allows cloud providers to develop the “pay only for resources used” model.
With Knative, you can create portable serverless containers that run on any Kubernetes environment. This allows for FaaS to be portable in a multi-cloud or hybrid-cloud environment.

A diagram describes the servers deployed in months, virtual machines deployed in minutes, containers deployed in seconds, and serverless deployed in milliseconds.
Serverless deploys the quickest
Knative is an extension of Kubernetes that enables serverless workloads to run on Kubernetes clusters. Working with Kubernetes is a pain. The amount of tooling that is required to help developers move their code from the IDE to Kubernetes defeats the purpose of the agility that Kubernetes professes to bring to the environment. Knative automates the process of build packages and deploying to Kubernetes by provider operators that are native to Kubernetes. Hence, the names “K” and “Native”.
Serving: Provides components that enable rapid deployment of serverless containers, autoscaling, and point-in-time snapshots
Eventing: Helps developers use event-driven architecture by providing tools to route events from producers to subscribers/sinks
You can read more about Knative at https://Knative.dev/docs.
Let’s look at how you can apply serverless functions to a real-life example.

A table describes business functions databases and integrations. Some of them are in business functions of reading employee records, and payment information in a database of employee records, and in Integrations of I R S.
Payroll application components

A flow diagram describes the employee records and monthly pay data flows to validate employee data to compute salary. Monthly pay rates and tax tables flow to compute salary and some of them are taxes and savings information.
Payroll application flow

An architecture diagram describes an Oracle database of employee records and monthly pay data flows to validate employee data to compute salary. Monthly pay rates and tax tables flow to compute salary.
Current payroll architecture
Using this use case, the following sections explore how you can leverage Spring Cloud Function to modernize and transform this application into a highly efficient, scalable, and portable system.
Spring Cloud Function Support Among Cloud Providers
AWS | Azure | IBM Cloud | On-Premises | |
|---|---|---|---|---|
Lambda | Azure Functions | Cloud Functions | IBM Functions | Tanzu with Knative |
EKS with Knative | AKS with Knative | GKE with Knative | Tanzu with Knative | OpenShift with Knative |
Fargate with Knative | ARO with Knative | OpenShift with Knative | OpenShift with Knative | Any Kubernetes offering with Knative |
ROSA with Knative | Tanzu with Knative | Tanzu with Knative | IBM Kubernetes with Knative | |
Tanzu with Knative |

An architecture diagram describes a relational database of employee records and monthly pay data flows to validate employee data to compute salary. Monthly pay rates and tax tables flow to compute salary.
Spring Cloud Function on AWS
Deploy SAP ECC on the AWS EC2 instances.
Deploy Oracle DB as an RDS instance.
Configure the SAP to Oracle integration.
Deploy Spring Cloud Function to AWS.
Set up the Amazon API Gateway.
Set up Amazon SQS for messaging.

An architecture diagram describes a relational database of employee details flows to validation to compute salary. Pay rates and tax flow to compute salary. It flows through Amazon S Q S to the spring cloud function.
Spring Cloud Function on Knative on AWS
Deploy SAP ECC on AWS EC2 instances.
Deploy Oracle DB as an RDS instance.
Configure the SAP to Oracle integration.
Set up Knative on an AWS EKS cluster.
Deploy Spring Cloud Function on Knative.
Set up the Amazon API Gateway.
Set up Amazon SQS for messaging.
GCP Cloud Functions provide a cloud alternative to AWS Lambda Functions. The GCP offering is newer than Lambda, but with the Anthos strategy, it is gaining a good amount of the function space. Spring.io works closely with Google to make the Spring.io components work seamlessly with the GCP components.
Deploy SAP ECC onto GCE.
Deploy Oracle DB on GCE VMs, as there is no AWS RDS-like service on GCP.
Configure the SAP to Oracle integration.
Set up a GCP Cloud Function project.
Deploy Spring Cloud Function onto GCP Cloud Functions.
Deploy Apigee on GCP to host function APIs.
Set up the Google Cloud pub/sub messaging platform.

An architecture diagram describes an Oracle on G C E V Ms of employee details flows to validation to compute salary. It flows through the cloud pub to the spring cloud function.
Spring Cloud Function on GCP
Knative, as discussed, is a way to make the functions portable. Knative, incidentally, was created by Google. With GCP, you can set up Knative on GKE, which is the Kubernetes engine provided by Google.
Deploy SAP ECC as a Docker image onto the GKE cluster.
Deploy Oracle DB as a Docker image onto the GKE cluster.
Configure the SAP to Oracle integration.
Configure a GKE cluster with Knative.
Deploy Spring Cloud Function onto Knative.
Set up the Apigee API Gateway.
Set up RabbitMQ on GKE for messaging.
Set up Google cloud pub/sub.

An architecture diagram describes an Oracle on G C E V Ms of employee details flows to validation to compute salary. Pay rates and tax flow to compute salary. It flows through the cloud pub to the spring cloud function.
Spring Cloud Function on Knative on GCP
Spring Cloud Function deployed on Azure Functions is not portable due to the explicit use of an Azure Function Invoker class. While Lambda and Google Cloud Functions require a change to Pom.xml (if you are using Maven), Azure needs an additional class. This makes it less portable. If you have a portfolio of one thousand Spring Cloud Functions in AWS that you need to move to Azure, you have to do a lot of development activity. This is disruptive.
Deploy SAP ECC on Azure VMs.
Deploy Oracle DB on Azure VMs.
Configure the SAP to Oracle integration.
Configure Azure Functions.
Deploy Spring Cloud Function on Azure Functions.
Set up the Azure API Gateway on Azure.
Set up Azure Queue storage on Azure for messaging.

An architecture diagram describes an Oracle on Azure V Ms of employee details flows to validation to compute salary. It flows through the Azure queue to the Azure plus spring cloud function.
Spring Cloud Function on Azure
Knative on Azure AKS is the only option for deploying Spring Cloud Function on Azure that makes it portable. As in any Kubernetes implementation, it requires an implementation of Knative to run the functions. Transforming the payroll application to AKS requires an AKS cluster.
Deploy SAP ECC on Azure VMs.
Deploy Oracle DB on Azure VMs.
Configure the SAP to Oracle integration.
Configure an AKS cluster with Knative.
Deploy Spring Cloud Function onto Knative.
Set up an Azure API Gateway on AKS.
Set up Azure Queue on Azure for messaging.

An architecture diagram describes an Oracle on Azure V Ms of employee details flows to validation to compute salary. It flows through the Azure queue storage to the A K S plus K native spring cloud function.
Spring Cloud Function on Knative on Azure
VMware Tanzu is an evolution of Pivotal Cloud Foundry (PCF). Those who are familiar with PCF should be aware of the “cf push” experience. It was a one-click provisioning approach and was very popular in the developer community. This is the same experience that Knative provides through its Knative build feature. To transform the payroll application to run on VMware Tanzu, you need the Tanzu Kubernetes grid, also known as TKG. TKG is built using the main branch of Kubernetes code. This can be deployed on-premises and in the cloud and can facilitate a multi-cloud or hybrid-cloud strategy. You can start up an instance of TKG on AWS, Azure, or Google by subscribing to the service in the provider’s marketplace.
In a datacenter, you need a collection of servers or a hyper-converged infrastructure like VxRail with PRA (Pivotal Ready Architecture). You also need to upgrade your vSphere to Version 7.
Deploy SAP ECC as a Docker image onto TKG.
Deploy Oracle DB as a Docker image onto TKG.
Configure the SAP to Oracle integration.
Configure a TKG cluster with Knative.
Deploy Spring Cloud Function onto Knative.
Set up a Spring Cloud Gateway on TKG as an API Gateway.
Set up RabbitMQ on TKG for messaging.

An architecture diagram describes an Oracle on docker plus T K G of employee details flows to validation to compute salary. It flows through the rabbit M Q to the T K G plus K native spring cloud function.
Spring Cloud Function on TKG

A diagram describes the cluster. It contains Tanzu Kubernetes grid, network, and services. It connected with the K 8s control plane through the v Sphere distributed switch of the management and workload port group.
Four-node VxRail P570F cluster for vSphere with Tanzu and HAProxy
Red Hat OpenShift can be an on-premises option for deploying Spring Cloud Function. As in any Kubernetes implementation, it requires an implementation of Knative to run the functions. OpenShift has its own serverless implementation, called OpenShift serverless. Transforming the payroll application to OpenShift requires an OpenShift cluster.
Deploy SAP ECC as a Docker image onto OpenShift cluster.
Deploy an Oracle DB as a Docker image onto the OpenShift cluster.
Configure the SAP to Oracle integration.
Configure an OpenShift cluster with Knative.
Deploy Spring Cloud Function onto Knative.
Set up a Red Hat 3scale API Gateway on OpenShift.
Set up RabbitMQ on TKG for messaging.

An architecture diagram describes an Oracle on docker plus open shift of employee details flows to validation to compute salary. It flows through the rabbit M Q to the open shift serverless plus spring cloud function.
Spring Cloud Function on Red Hat OpenShift
This chapter discussed FaaS environments, Spring Cloud Function, and Knative. You saw that FaaS containers/environments provided by AWS, Google, or Microsoft Azure are not portable, as the underlying components that host the FaaS environment do not have the same architecture, which makes it difficult to move or migrate FaaS containers between cloud providers. You also saw that Spring Cloud Function can abstract the dependent AWS and Google libraries and provide a portable alternative. Spring Cloud Function on Knative can improve developer productivity by “writing once and deploying anywhere.” You saw how to apply Spring Cloud Function and Knative to an enterprise payroll application and learned about the various implementation approaches. The next chapter walks through the deployments step-by-step. You will also see how to develop and deploy code to various targets, such as AWS, GCP, Azure, OpenShift, and VMware Tanzu. This will help you understand the power of Spring Cloud Function.
This chapter discusses how to develop code using Spring Cloud Function and deploy it to environments in the cloud, on-premises (on a premises datacenter), and on your laptop. It includes a step-by-step approach to coding and deploying the function.
Set up the IDE for the Spring Boot framework.
Add JPA, H2 (this example uses an embedded database to demonstrate the CRUD operations), Spring Cloud Function, and Spring Web Support.
Complete the code for EmployeeFunction, EmployeeConsumer, and EmployeeSupplier.
Note that the code remains the same in all environments; the only change you make is to the pom.xml file. There is also an introduction to a FunctionInvoker <Message<String>, <String> class regarding Azure Functions. Azure build looks for this class during the build process. Another difference you will notice with Azure is that you have to use JDK 11 and above to get the Azure templates in the IDE.
Create a Docker image of the code.
Set up Knative on all environments.
Deploy the code to Knative.
Deployment of Spring Cloud Function to Knative will demonstrate true portability.
You also see how to use a single IDE such as IntelliJ or VS Code to perform all the functions (i.e., building and deploying to the target environments).
I have used multiple devices to set up the local and on-premises Kubernetes environments. I recommend that VMware VMs be used. You can get the VMware workstation player from VMware for free at https://www.vmware.com/products/workstation-player.html. You can also use other alternatives, such as Windows Subsystem for Linux (WSL) or Virtual Box.
All the code is available on GitHub at https://github.com/banup-kubeforce payroll-h2.git.
Happy coding!
This is a preliminary step that you undertake to determine if the Spring Cloud Function works. This will set the stage for deployment.
An IDE such as IntelliJ, Eclipse, Spring IDE, or Red Hat Code Ready workspace
Maven or Gradle
Postman for testing
Code from GitHub at https://github.com/banup-kubeforce/payroll.git
Step 1: Create the Spring Boot scaffolding.
Step 2: Create the employee model.
Step 3: Write the consumer.
Step 4: Write the supplier.
Step 5: Write the function.
Step 6: Deploy and run the code locally.
Step 7: Test the function.
I am using IntelliJ, as it makes me more productive with all the capabilities such as plugins for the cloud, Docker, Maven, and so on.

An application screenshot. The left side contains project types and the right side contains new project configurations. Some of them are severed U R L, name, location, language, type, group, and artifact.
Spring Initializer set up in IntelliJ

An application screenshot of a new project. It contains a set of dependencies on the left side. From dependencies, a function is selected, Function description and add dependencies are on the right side.
Pick the dependencies for the project

A screenshot of the spring boot deployment logs. It allows for the function to be tested by tools.
Spring Boot deploy and run

A screenshot of testing in postman. The page contains authorization, headers, body, pre-request script, tests, and settings. The body contains the name, employee identifier, email, and salary.
Testing in Postman
Upon clicking the Finish button, the IDE will create the code bits and take you to the project screen. Alternatively, you can bring the code down from GitHub by cloning the project.
pom.xml File with Maven Dependencies
application.properties
PayrollApplication.java, as shown Listing 2-3, is the main entry point for the application. It is important to define three beans that represent the consumer, supplier, and function, so that these functions can be accessed after deployment.
PayrollApplication.java
Once the scaffolding and code bits are completed, you are ready for the next step, which is to create the model for your employee.
The model creates the getters and setters for the ID, name, employee ID, email, and salary.
I created this manually, but you can generate this using the Spring JPA data model generator for data that resides in an RDBM such as Oracle, MYSQL, or SQL Server, or a document database such as MongoDB. The database support for the generation of code using Spring JPA depends on the adapter and can be found at https://docs.spring.io/spring-integration/reference/html/jpa.html#jpa.
Employee Entity Model
Once the model is created/generated, you can proceed with coding the consumer that will write to the database and the supplier that will read from the database.
Employee Entity Model
The supplier function in this example allows you to get all the data in the database. You can change it to suit your needs.
EmployeeSupplier.java
EmployeeFunction.java
The use of SpringApplication allows you to keep the code up and running so that you can test the function with tools such as Postman.
In this step, you run the code just like you would for any other Spring Boot code.
Note that the code runs and is available in port 8080.
This allows for the function to be tested by tools such as Postman and curl.
You can use curl or Postman to test your function. Here I use Postman. You can download Postman at https://www.postman.com/downloads/.
You can test all the three interfaces here, but when you go to Lambda or other environments, you will be restricted to just one interface.

A screenshot of the H 2 console. S Q L statement is Select star from an employee. The employee details are I D, email, employee identifier, name, and salary.
H2 console showing the employee table being updated with the data
This completes the steps for creating, running, and testing the code of a local function.
In the following sections, you’ll see how to use the same code with little to no changes and deploy it to a serverless function container of your choice.
This section discusses deploying the code that you created into AWS Lambda.
You have to do a little bit of tweaking to make the code compatible with Lambda. The tweaking is not too disruptive. Again, going back to real situations where you have over a thousand functions you want to move to AWS, this tweak will not be that significant. Of course, it depends on what cloud provider you are starting to create functions for. Ideally, I have seen enterprises gravitate toward Lambda, but there are enterprises that start with Azure or Google. In any case, making these functions portable across clouds requires a few code changes and some pom.xml changes.
AWS account
AWS Lambda Function subscription
AWS CLI (optional)
Code from GitHub at https://github.com/banup-kubeforce/payroll-aws
Step 1: First follow Steps 1-6 outlined in Section 2.1. The code remains the same for any serverless offerings from the cloud providers.
PayrollAwsApplication.java
The next step is to change the pom.xml file to add the AWS Lambda adapter.
The pom.xml File
The POM needs to be changed to accommodate the Spring Cloud Function adapter for AWS, Lambda events, and the Maven shade plugin (optional).
These changes will create a package that can be deployed to AWS Lamdba.

A screenshot of Run Maven. The left side contains project details. The right side contains Maven. Some of them are packages run Maven build, run payroll-a w s, debug payroll-a w s, and profile payroll-a w s.
Run Maven:package from the IDE
Step 4: Create a function definition in AWS Lambda.
Log in to AWS and subscribe to AWS Lambda. Information on how to subscribe to Lambda is available at https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html.

A screenshot of Create function. It contains the author from scratch and uses a blueprint, and container image. Author from scratch contains basic information, permissions, and advanced settings.
AWS lambda dashboard to create a function

A screenshot of an employee consumer page. It contains a function overview and employee consumer layers.
Upload the JAR file into the AWS Lambda dashboard
Upload the JAR file created in Step 3 and provide the settings, as illustrated in Figure 2-7.

A screenshot of the edit runtime setting page. The page contains runtime settings, runtime as Java 11, handler, and architecture.
AWS Lambda runtime settings
Set the handler as shown. The Lambda function handler is the method in your function code that processes events. This will indicate that the Spring Cloud Function adapter will be invoked when the function is called. I used Java 11. Refer to the pom.xml.
Once you click Save, you can start your testing process.

A screenshot of the function overview page from the test function. The page contains employee consumer layers and descriptions. Last modified details, function A R N, and function U R L.
AWS Lamba Functions Test tab
The testing dashboard allows you to send a JSON file as an event to trigger the function.

A screenshot of the test event page. It contains test event action, event name, event sharing settings as private, and template-optional. Event J S O N contains name, employee identifier, email, and salary.
Testing the dasboard

A screenshot of an execution result of success. The page contains the details of the test, summary, and log output. Summaries of code, request I D, duration.
AWS Lambda function test results
You will use the same example from Section 2.1 and modify it a bit to make it run on Google Cloud Functions. The approach is similar to AWS Lambda, but you will be leveraging Google’s libraries.
Google account
Subscription to Google Cloud Functions
Google CLI (this is critical as it is a more efficient way than going through the Google Portal)
Code from GitHub at https://github.com/banup-kubeforce/payroll-gcp
PayrollGcpApplication.java
Step 2: Configure POM. The pom.xml file needs to be modified to include the Spring Cloud Function adapter and any plugins that are specific to GCP. See Listing 2-11.
The pom.xml File

A screenshot of G cloud C L I execution results. It uses the C L I to accomplish the task. Some of the details on the page contain available memory M b, build I D, build name, docket registry, and entry point.
Gcloud CLI execution results

A screenshot of the Google cloud function dashboard. It contains cloud functions and functions. Some of the details it contains the environment, name, last deployed, region, trigger, runtime, and memory allocated.
Cloud Functions dashboard
Now you can test it to verify that it works.
Step 4: Test the function in GCP. Google provides a way to test from the website itself. You can provide the input in the form of the JSON file, as you did before, and then execute the tests.

A set of two screenshots of the cloud functions testing dashboard. a. Google cloud platform described triggering event. b. Cloud functions payroll g c p.
Cloud Functions testing dashboard
You will use the same example from Section 2.1 and modify it a bit to make it run on Azure Functions. You will see that the approach for Azure Functions is different from AWS or Google. You have to add another class called EmployeeConsumerHandler, which extends a FunctionInvoker<I,O>. This FunctionInvoker class is merely a pass through for the EmployeeConsumer function.
Azure account
Subscription to Azure Functions
Azure Functions CLI. You can download the tools at https://docs.microsoft.com/en-us/azure/azure-functions/functions-run-local
Code from GitHub at https://github.com/banup-kubeforce/payroll-azure
Step 1: Follow Steps 1-6 outlined in Section 2.1.
You have to introduce a FunctionInvoker <I,O> class, which makes the code non-portable to other cloud providers. While AWS and Google externalize the invocation of the function, as you have seen in previous sections, Azure forces you to provide a handler class that extends a FunctionInvoker.
EmployeeConsumerHandler.java

A screenshot of the Maven package. The left side contains coding. The right side contains commands. Run payroll Azure package command is selected.
The Maven package
You have to run the maven clean command before you run the maven package command. These commands are under the Lifecycle menu in the Maven window. Run the Maven package to get the deployable JAR file. These JAR files are stored in the target folder in your project directory

A screenshot of a successful package. It contains payroll Azure package logs.
Azure Functions build and succcessful package
Step 3: Deploy the function in Azure. You will see some artifacts created in the target folder. Payroll-azure-0.0.1-SNAPSHOT.jar is the file you are interested in. This file needs to be deployed to the Azure Cloud.
IntelliJ has a feature/plugin for Azure that you can enable. Once you enable that feature, you can perform Azure Function-based activities from the IDE.

A screenshot of payroll-azure. The left side contains projects. Target is selected. In coding payroll, a function is selected. The right side contains the commands. Azure-function deploy is selected.
Use Azure Functions, Deploy in Maven to deploy to Azure
After the function is successfully deployed to the Azure Cloud, you can use the URL provided to runs tests in Postman or proceed to the Azure Functions console to test.

A screenshot of the function application. A payroll-azure function is selected. In the payroll-azure function, the function tag is selected, and it contains the name, trigger, and status.
Azure Functions Console
You will see that the function is deployed in Azure and is running.

A screenshot of employee consumer code plus test page. The test tag is selected. In payroll-azure, employee consumer input is the H T T P method, key, query, headers, and body. It contains a run page.
Run test with input

A screenshot of employee consumer code plus test page. Code plus test tag is selected. The output is the H T T P response code, successful H T T P response content. It contains the run logs.
Successful run of the test

A screenshot of the execution log. It contains creating cluster k native. Some of the checks are to ensure node image, prepare nodes, and writing configuration. The output is you can now use your cluster.
Cluster has been successfully created
Figure 2-21 shows successful execution of the test.
This section explores another way to deploy Spring Cloud Function. Kubernetes, as you might be aware, is a portable approach to containerization and running containers. Kubernetes allows you to host containers that are packaged as images and deployed on Kubernetes pods.
Knative is an environment that sits on Kubernetes and can host a function. Chapter 1 explained how the cloud providers created environments such as AWS Lambda that could start up on demand and shut down when a resource is not in use. Similarly, you can create such an on-demand environment with Knative for functions. This section explores how to set up the Knative environment locally, which is difficult with AWS and Google Functions, and deploy and work with your functions locally and on the cloud. This section starts with local deployment and then moves on to the cloud.
You will notice that I used EmployeeSupplier as the function. To do this, you need to prepopulate the H2 database with some data so that you can query the database using the EmployeeSupplier function.
Docker on Mac, Linux, or Windows
Kind (Kubernetes in Docker)
Knative serving
IntelliJ, Eclipse, VS Code, or other IDEs
Code from GitHub
Here is the process of setting up Kubernetes and Knative and deploying Spring Cloud Function.
Step 1: Set up a Kubernetes cluster locally. In this step, you install a local Kubernetes cluster. You deploy a KIND (Kubernetes IN Docker). Cluster. Of course, you can use Minikube or Minishift to deploy locally.
Install Docker.
Install Docker
Install Kubectl.
This step is required, as you need Kubectl to interact with the Kubernetes cluster
Install KIND.
Now you have the KIND bits that will allow you to install the cluster and deploy Knative.
Step 2: Configure Knative. In order to configure Knative, you need a KIND cluster. You will create a cluster with custom configuration.
Create clusterconfig.yaml and Run the Create Cluster
Knative serving (information about Knative serving is available at https://knative.dev/docs/serving)
Kourier is a lightweight Knative serving ingress and is available at https://github.com/knative-sandbox/net-kourier.
Magic DNS is a DNS provider and is available at https://knative.dev/docs/install/yaml-install/serving/install-serving-with-yaml/#configure-dns.
Install the Knative serving components (i.e., crds and core):
Set up networking using Kourier:
Change the file to use nodePort, as shown in Listing 2-15.
Configure nodePort
Install Kourier.

A screenshot of the execution log. It includes configuration, service account, cluster role, deployment, and service of kourier. The output is service kourier-internal created.
Kourier is installed successfully
Set Kourier as the default networking layer by installing the following patch:
Set up a wildcard DNS with sslip.io:
Patch with sslip.io:
Get the status of the pods in the Knative serving:

A screenshot of the run log. It includes Kubert l get pods k native serving name, an activator, autoscaler, default domain, and domain mapping.
Knative services pods are up and running
The Dockerfile
Push to Dockerhub. You can use the IDEs Docker features to push it to the Docker registry, as shown in Figure 2-25.

A screenshot of the docker file. The left side contains the project. A docker file is selected. Push image page created. It contains a registry, namespace, repository, and tag.
Docker Push from IntellJ
payroll.yaml
The next step is to deploy the app to Knative.
A YAML execution gives you more control over the target environment. Note this URL, as it is required for the testing step. The URL shown here for example is https://payroll.default.127.0.0.1.sslip.io.
You can run the following command to get the URL and check if the endpoint is ready for testing.

A screenshot of the test with the postman. The authorization tag is selected and the body contains I D, name, email, salary, and employee identifier.
Test with Postman
In this section, you created a KIND-based Kubernetes cluster, configured Knative, and deployed the application. You created a portable image that can be deployed to any Kubernetes cluster that has been configured with Knative.
This section looks at deploying to an AWS EKS cluster that has Knative configured. You will see similarities to Section 2.5, because you create the cluster, enable Knative, and deploy a Docker image.
AWS subscription (https://aws.amazon.com/)
AWS CLI, which can be found at https://aws.amazon.com/cli/
Eksctl CLI (https://eksctl.io/)
Knative serving (https://knative.dev/docs/serving)
Knative CLI (https://knative.dev/docs/client/install-kn/)
IntelliJ, Eclipse, VS Code, or other IDEs
Code from GitHub
Docker image registered in the Docker hub
cluster.yaml

A screenshot of amazon elastic Kubernetes service. The payroll cluster contains an overview and its node's details. They are node name, instance type, node group, created, and status.
EKS console
You will see that the dashboard shows the name of the cluster you provided in the Listing 2-18 and the creation of three nodes as set for desiredCapacity in the listing.

A screenshot of elastic Kubernetes service running logs. It contains Kubect l get pods all namespaces, name, ready, status, restarts, and age. All namespaces were running successfully.
EKS cluster running successfully

A screenshot of K native components running logs. It contains name, ready, status, restarts, and age. All namespaces were running status.
Knative components running on EKS
Install and Configure Knative
Step 3: Containerize the app with Docker and push it to a repository (optional).
The Dockerfile

A screenshot of payroll. The left side contains the project. In that, a docker file is selected. The push image page is created. It includes a registry, namespace, repository, and tag.
Docker push from the IntelliJ IDE

A screenshot of the deploy image of the docker hub. The general page contains spring cloud functions, docker commands, tags and scans, and automated builds.
Dockerhub with the deployed image
Step 5: Deploy the app to Knative on EKS. In this step, you create a YAML file and set the location of the image that you will deploy to Knative.
The payroll.yaml File
Deploy the app to Knative on EKS.

A screenshot of payroll deployment logs. The run commands are route is still working to reflect, configuration payroll is waiting, waiting for a load balancer to be ready, and ready to serve.
Payroll is deployed successfully
The URL that you need for testing or posting is payroll.default.13.58.221.247.sslip.io
Step 6: Testing. Use the URL you got in Step 5 and run the test. The URL in this case is https://payroll.default.13.58.221.247.sslip.io/employeeConsumer

A screenshot of the postman page. The header tags are home, workspace, A P I network, reports, and explore. The body contains the name, employee identifier, email, and salary.
Test Is Postman with the URL

A screenshot of cluster running logs. It contains the name, location, master version, master I P, machine type, node version, number of nodes, and status.
Cluster is up and running
This section looks at deploying to GCP a GKE cluster that has Knative configured. You will see similarities to Section 2.5, because you create the cluster, enable Knative, and deploy a Docker image.
GCP subscription (https://cloud.google.com/)
The Gcloud CLI, which can be found at https://cloud.google.com/sdk/docs/install
kubectl (https://kubernetes.io/docs/tasks/tools/)
Knative serving (https://knative.dev/docs/serving)
Knative CLI (https://knative.dev/docs/client/install-kn/)
IntelliJ, Eclipse, VS Code, or other IDEs
Code from GitHub (optional if you use the image from Dockerhub)
Docker image registered in the Docker hub
Step 1: Set up a Kubernetes cluster with GKE. In this step, you create a GKE cluster. Make sure you have the sufficient permissions to create the cluster. Additional information can be found at https://cloud.google.com/kubernetes-engine/docs/deploy-app-cluster.
Create a Cluster in GCP

A screenshot of the status of the G K E cluster. It contains the name, status, roles, age, and version. All the statuses were ready.
Status of GKE cluster

A screenshot of the Google Kubernetes engine. Cluster tag selected. It contains Kubernetes clusters. Its overview contains status, name, location, number of nodes, total v C P Us, and total memory.
GKE Dashboard on Google Cloud

A screenshot of Kourier running logs. It contains namespace, type, and patch. The network was successfully dispatched.
Kourier has been successfully patched
Step 2: Configure Knative on GKE. This step is similar to what you did earlier with EKS or local Kubernetes:
Install the Knative serving components by running the following commands:
Install the Kourier components required for ingress by running the following command:
Configure Kourier for ingress with the following command:
Apply the default domain using the following command:
Check the status of the Knative components by running the following command:
Run the following command to get the Kourier ingress information:
Now that you have Knative configured and running, you can proceed to the next step of pushing the app image to Knative.
Step 3: Containerize the app with Docker and push it to a repository (optional).
The Dockerfile that Helps Create the Container and Image

A screenshot of K native serving running logs. It contains name, ready, status, restarts, and age. All namespaces were running successfully.
Knative services are running successfully

A screenshot of Kourier service status run logs. It contains name, type, cluster I P, external I P, ports, and age.
Kourier service status shows an external IP

A screenshot of payroll. The left side contains the project. In that, a docker file is selected. The push image page is created. It includes a registry, namespace, repository, and tag.
Docker push from the IDE

A screenshot of the deployment image of the docker hub. It contains spring cloud functions, docker commands, tags and scans, and automated builds.
Dockerhub with the deployed image

A screenshot of payroll application run logs. The commands are route is still working, configuration payroll is waiting, and ready to serve. Output is service payroll created to the latest revision.
Payroll app deployed on GKE with Knative

A screenshot of the successful testing with the postman. The header tags are home, workspaces, A P I network, reports, and explore. The body contains the name, employee identifier, email, and salary.
Successful testing with Postman

A screenshot of A K S cluster running logs. It contains names, statuses, roles, and ages. All the clusters were in ready status.
The AKS Cluster is ready

A screenshot of Kourier ingress patched running logs. It contains namespace, type merge, and patch. The output-configured network is patched.
Kourier ingress is patched

A screenshot of the application deployed on A K S with K native logs. The commands are route is still working, and ready to serve. Output is service payroll created to the latest revision.
The app is successfully deployed on AKS with Knative

A screenshot of testing of the payroll on A K S with K native. The collections tag was selected and displayed create collection tag. The body contains the name, employee identifier, email, and salary.
Successful test of the payroll example on AKS with Knative

A screenshot of the installation of T K G bits on a local machine running logs. Installing builder, cluster, Kubernetes release, login, and management cluster. The output is installation completed.
Successful installation of TKG bits on a local machine

A screenshot of install of the T K G cluster. It contains the core package repo status. the output is cluster created.
Successful install of TKG Cluster

A screenshot of application deployment on T K G with K native logs. The commands are route still working, and ready to serve. The output is the service payroll created to the latest revision payroll.
App deployment on TKG with Knative
Once the push is successful, you can navigate to Dockerhub to check for the deployment of the image, as shown in Figure 2-41.
Figure 2-42 shows the results of running the kn cli. A YAML execution gives you more control over the target environment. Note the URL, as it is required for the testing step. The URL shown here for example is https://payroll.default.34.69.156.24.sslip.io.
Step 6: Test. Use the DNS name provided in Step 5 to test against the following URL:
https://payroll.default.34.69.156.24.sslip.io/employeeConsumer
Now you have successfully deployed the payroll app on GKE with Knative.
This section looks at deploying to an Azure AKS cluster that has Knative configured. You will see similarities to Section 2.5, because you create the cluster, enable Knative, and deploy a Docker image.
Azure subscription (https://portal.azure.com/)
Azure CLI, which can be found at https://docs.microsoft.com/en-us/cli/azure/install-azure-cli
kubectl (https://kubernetes.io/docs/tasks/tools/)
Knative serving (https://knative.dev/docs/serving)
Knative CLI (https://knative.dev/docs/client/install-kn/)
IntelliJ, Eclipse, VS Code, or other IDEs
Code from GitHub (optional if you just use the image from Dockerhub)
Docker image registered in Docker hub
Step 1: Set up a Kubernetes cluster with AKS. In this step, you create an AKS cluster. Make sure you have the sufficient permissions to create the cluster. Additional information can be found at https://docs.microsoft.com/en-us/azure/aks/learn/quick-kubernetes-deploy-cli.
The Dockerfile
Set up Kubeconfig
Check the Status
Step 2: Configure Knative on AKS. This step is similar to what you did earlier with EKS or local Kubernetes.
Get the Ingress Information
Now that you have the Knative configured and running, you can proceed to the next step of pushing the app image to Knative.
Step 3: Containerize the app with Docker and push it to a repository. Follow Step 3 in Sections 2.5, 2.6, or 2.7 if you choose to create and deploy an image to the Dockerhub repository.
Step 4: Deploy the app to Knative on AKS. Here again, I use the Knative CLI kn to deploy the app, as it convenient for this simple exercise.
Deploy Payroll Apps
Note the URL that is generated. You will use this URL for testing.
Step 5: Test. Use the DNS name provided in Step 4 to test against the following URL:
https://payroll.default.20.121.248.sslip.io/employeeConsumer
As with other Kubernetes offerings, setting up and installing Knative on TKG on your local laptop is pretty straightforward.
VMware released a community edition that can be locally installed. Additional information can be found at https://tanzucommunityedition.io/download/.
TKG download (https://tanzucommunityedition.io/download/)
kubectl (https://kubernetes.io/docs/tasks/tools/)
Knative serving (https://knative.dev/docs/serving)
Knative CLI (https://knative.dev/docs/client/install-kn/)
IntelliJ, Eclipse, VS Code, or other IDEs
Code from GitHub (optional if you just use the image from the Dockerhub)
Docker image registered in the Docker hub
Step1: Set up TKG locally.
Step2: Create a Kubernetes Cluster for your app.
Step 3: Install Knative on TKG cluster.
Step 4: Deploy the app on Knative.
Step 1: Set up TKG locally. Follow the instructions provided on the website to set up TKG locally. This will give you an unmanaged cluster.
Figure 2-48 shows a successful install.
You will get a message that the payroll cluster has been completed, as shown in Figure 2-49.
Step 4: Deploy the app on Knative, as shown in Figure 2-50.
Note the URL provided. In this case, it is http://payroll.default.127.0.0.241.nip.io.
Step 5: Test Follow Section 2.5, Step 5 and use Postman or curl to test against the http://payroll.default.127.0.0.241.nip.io/employeeConsumer URL.
This completes the successful deployment of Tanzu Kubernetes Grid or TKG.
This chapter explained how Spring Cloud Function can be developed and deployed to various target platforms, including AWS Lambda, Google Functions, Azure Functions, and Kubernetes environments such as AWS EKS, Google’s GKE, Azure AKS, VMware Tanzu, and the like. With Kubernetes, you were able to use Knative to deploy the same image to all the other Kubernetes flavors without changing the code. Knative ensures that the code is portable across any Kubernetes platform. This is critical, as it ensures movement to any cloud with minimal disruptions. To summarize, you should now have a good understanding of how to build serverless functions with Spring Cloud Function. The next chapter looks at how to automate the deployment process for Spring Cloud Function.
As you learned in Chapter 2, you can build a Spring Cloud Function and deploy it to multiple environments. You can use various manual methods such as Azure-Function:Deploy, Gcloud CLI, AWS CLI, Kubectl, and Knative CLI. These manual approaches are not sustainable in an enterprise with many different teams, a lot of programmers, and a lot of code. It will be a management nightmare if every team member uses their own method to build and deploy code. Also, as you can see, this process is repeatable. Since it is a repeatable process, there is a chance to leverage automation.
This chapter explores ways to automate the deployment process. It leverages some popular approaches for automating your deploys. It explores GitHub Actions for deploying Lambda, Google Cloud Functions, and Azure Functions and you will integrate with ArgoCD to push to a Kubernetes/Knative environment. While you can use GitHub Actions alone for all environments, that would require custom scripting to push to Kubernetes. ArgoCD has built-in hooks to deploy to Kubernetes, which is the preferred way. More information on GitHub Actions can be found at https://github.com/features/actions, and information on ArgoCD can be found at https://argoproj.github.io/cd/.
Let’s dig a bit deeper into GitHub Actions and ArgoCD.

A screenshot of the banup-kubeforce window. Tab action is selected. It describes all workflows. It contains runs from all workflows, events, statuses, brands, and actors.
Creating a new GitHub Actions workflow

A screenshot of the banup-kubeforce window. Tab actions is selected which displays a message to choose a workflow.
Workflow marketplace to choose your workflow setup

A screenshot of a banup-kubeforce window. Tab code is selected. Code is present on the left side of the window. The right side of the window contains feature actions under the tab marketplace. The featured actions are upload a build artifact and set up Java J D K.
Workflow page to create custom workflows
Workflow for Payroll Function to be Deployed on AWS Lambda

A screenshot of workflow code elaboration. It contains name, on-push, jobs, runs-on ubuntu-latest, steps, uses, and run along with its details.
Work flow code elaboration

A screenshot of chapter 3 S C F plus Lambda. Build-deploy is selected under jobs. Build-deploy window contains set up job, run action, run a w s-actions, build with Maven, run Sam package and deploy, post run a w s, etc.
A successful execution of the workflow
Declarative means configuration is guaranteed by a set of facts instead of by a set of instructions.
Declarative GitOps allows the programmer or the ones who created the application to control the configuration of the environment in which the environment will run. This means the programmer does not have to rely on different teams, such as infrastructure or DevOps teams, to manage the pieces of the application. The programmers are in control, and this is a good thing.
ArgoCD set up is mostly programmatic and relies on the underlying Kubernetes configmaps. This is, as you can see, is different from other tools like Jenkins.
Here is how I set up the ArgoCD environment.
A Kubernetes cluster
Kubectl CLI configured to access your cluster
ArgoCD CLI installation instructions can be found at https://argo-cd.readthedocs.io/en/stable/cli_installation/
Step 1: Create a namespace for ArgoCD.

A screenshot of creating an Argo C D namespace. The screenshot reads, dollar sign Kubectl create namespace Argo c d namespace forward slash Argo c d created.
Create an ArgoCD namespace

A screenshot describes the status of an Argo C D installation run logs. It includes name, status, restarts, etc.
View the status of an ArgoCD installation
Now you can see that the ArgoCD services are up and running. Notice that an external IP has not been associated with service/argocd-server.

A screenshot of the external I P of Argo c d-server run logs. It contains name, type, cluster-I P, external-I P, port, and age.
Take note of the external IP of argocd-server
You will see an external IP associated with argocd-server. This will allow you to connect to the argocd-server.
Before you start to use ArgoCD, you need to change the “admin” user password. You can use Kubectl to read the secret associated with the “admin” user.

A screenshot of getting the password of admin user. The screenshot depicts a code.
Get the password of the "admin" user
The output of this command is the password for the “admin” user.
You can now log in using the web browser. Then navigate to the 20.119.112.240 URL to change the password.

A screenshot of logging in to Argo C D run logs. If it gets a warning error, the command is a certificate signed by an unknown authority. Run logs contain details and the admin logged in successfully.
Log in to ArgoCD

A screenshot of deploying an application in Argo C D U I. It depicts Payroll-h 2 which contains project, labels, status, repository, path, destination, etc. The status is healthy and synced.
ArgoCD UI showing an app deployed
Now that you have learned about GitHub Actions and ArgoCD, you can move on to deploying your application and automating the CI/CD process.
You will use the same example from Chapter 2, but instead of using the EmployeeConsumer interface, this example uses EmployeeSupplier. In order to do that, you need a prepopulated database. You’ll then query the database using a supplier function. You can find the code at https://github.com/banup-kubeforce/payroll-h2.
Here are the required changes.
Schema.sql
Data.sql

A screenshot of the spring boot project structure. In a project structure, the s r c folder is selected. It contains a resources folder. Resources folder includes data. s q l, and schema. s q l folders along with other folders.
Spring Boot project structure with data.sql and schema.sql
Application.properties
Also add spring.jpa.defer-datasource-initialization=true to ensure that the data gets populated on startup.
No other code changes are required. It is important to note that the changes you made only affect the configuration file.
As discussed in the introduction of this chapter, you’ll use two tools for the CI/CD process. GitHub Actions can be used as a tool for both CI (Continuous Integration) and CD (Continuous Deployment), while ArgoCD is a CD tool.
ArgoCD was designed for Kubernetes, so you can leverage this tool exclusively for Knative/Kubernetes deployment. You’ll use GitHub Actions for serverless environments such as Lambda.
Figure 3-13 shows the flow when deploying to serverless environments like AWS Lambda, Google Cloud Functions, and Azure Functions.
Create code and push/commit code to GitHub.
GitHub Actions senses the event trigger of the commit and starts the build and deploy process to the serverless environments defined in the actions script.

A flow diagram of deploying to serverless functions. The code created is pushed to GitHub through Git flows repo name and branch name. Event-triggered from GitHub results in GitHub actions and deploys to spring cloud function.
Deploying to serverless functions environments
Figure 3-13 shows the flow when deploying Spring Cloud Function to a Kubernetes environment with Knative configured.
Create code and push/commit code to GitHub.
GitHub Actions senses the event trigger of the commit and starts the build process and deploys the created container image into Docker Hub.
ArgoCD polls for changes in GitHub and triggers a “sync.” It then retrieves the container image from Docker hub and deploys to Knative on Kubernetes. See Figure 3-14.

A flow diagram describes deploying to a Knative-kubernetes environment. Commit code through Git is pushed to GitHub. Event-triggered GitHub actions are pushed to docker and synced and pulled to Argo. It deploys the spring cloud function on kubernetes.
Deploying to a Knative-Kubernetes environment
This section looks at the process of deploying the Spring Cloud Function to the target environments such as AWS Lambda, Google Cloud Functions, Azure Functions, and Knative on Kubernetes.
Deploying to AWS Lambda requires using a SAM (Serverless Application Model) based GitHub Actions script. This section explains how to use SAM and GitHub Actions. There is no additional coding required.
AWS account
AWS Lambda Function subscription
S3 bucket to store the code build
AWS CLI (optional) to verify deployments through the CLI
Code from GitHub at https://github.com/banup-kubeforce/payroll-aws-h2

A flow diagram describes deploying spring cloud function with GitHub actions. Commit code through Git is pushed to GitHub. Event-triggered GitHub actions deploy spring cloud function on lambda.
Deploying Spring Cloud Function with GitHub Actions on AWS Lambda
Step 1: Spring Cloud Function code in GitHub.
Push the code to GitHub. You can bring down code from GitHub at https://github.com/banup-kubeforce/payroll-aws-h2. This code can be modified to your specs and deployed to the repository of your choice.
Step 2: Implement GitHub Actions with AWS SAM. AWS SAM (Serverless Application Model) is a framework for building serverless applications. More information can be found at https://aws.amazon.com/serverless/sam/.
AWS has a sample SAM-based actions script that is available in the GitHub marketplace that you can leverage. This script will execute the SAM commands.
Workflow for Payroll Function to be Deployed on AWS Lambda

A screenshot of the ban up-Kubeforce window. The settings tab is selected. It displays action secrets and environmental secrets with its details.
Actions secrets for credentials and configuration

A screenshot of the banup-kubeforce window. The build deploy button is selected. It displays a new window on build deploy which includes set up job, build with Maven, run Sam package, etc.
A successful execution of GitHub Actions on AWS Lambda

A screenshot of A W S Lambda window. The function is selected. It displayed the function name.
Function created after execution of GitHub Actions

A screenshot of the Lambda function window. It depicts function overview with its description.
Testing if the function was successful. See the JSON response
In Figure 3-19, you can see that the test was successful and see a JSON result of what is in the database.
Deploying to GCP Cloud Functions using GitHub Actions is a bit intrusive, as you have to add a MANIFEST.MF file to the resources folder. See the code in GitHub.
A GitHub repository with the code. The code at https://github.com/banup-kubeforce/payroll-gcp-h2.git can be leveraged
Google accountSubscribe to Google Cloud Functions
Gcloud CLI is optional if you are just using the GitHub Actions dashboard

A flow diagram describes G C P and GitHub actions flow. Commit code through Git is pushed to GitHub. Event-triggered GitHub actions deploy spring cloud function in google cloud function.
GCP and GitHub Actions flow
Step 1: Spring Cloud Function code in GitHub. Push your code to GitHub. If you have cloned the https://github.com/banup-kubeforce/payroll-gcp-h2.git then you have everything that you need to push the code to your repository.
Step 2: Set up Cloud Functions actions.
Use deploy-cloud-functions runner
Use gcloud-cli
Workflow for Payroll Function to be Deployed on GCP Cloud Functions
Note that you will have to store your GCP_CREDENTIALS in the GitHub Secrets dashboard.
As in the previous example with AWS Lambda, note that the steps to check out, set up, and build Maven are the same. For the authentication and deployment, you use the Google Cloud CLI. The Set up Cloud SDK task will download and set up the Google CLI. You can use the same command line script that you used when you deployed from a laptop in Chapter 2.

A screenshot of the banup-kubeforce window. The build deploy button is selected. A new window on build deployment is displayed, it includes set up job, build with Maven, run Sam package, etc.
GitHub Actions gets triggered by a code commit
Once the actions successfully complete the job, you can go to the Google Cloud Functions dashboard and test the function. Again, you execute a simple GET against the EmployeeSupplier function.
Step 4: Test the function.

A screenshot of the unauthenticated set for payroll-g c p- h 2 which is allowed. It includes a link to 1st gen payroll along with other details.
Allow unauthenticated set for Payroll-gcp-h2

A screenshot of the google cloud window. It displays cloud functions. In payroll-g c p-h 2, a function is selected. It configures triggering events and displays the test command.
Successful output of the Spring Cloud Function test in GCP Cloud Functions
Spring Cloud Function on Azure Functions require a bit of tweaking, as you learned in Chapter 2. This is because the configuration is not externalized, as with AWS Lambda or GCP Cloud Functions. This does not mean that you cannot deploy easily. You have to understand how Azure Function code interprets Spring Cloud Function code and execute. See Chapter 2 for discussions around this issue; make sure that you execute and test locally before pushing to the Azure cloud.

A flow diagram describes flow of spring cloud function deployment on azure. Commit code through Git is pushed to GitHub. Event-triggered GitHub actions and deploy spring cloud function in Azure functions.
Flow of Spring Cloud Function deployment on Azure
Workflow for Payroll Function to be Deployed on Azure Functions

A screenshot of the summary window. The build and deploy button is selected which displays build deployment window which includes set up job, build with Maven, run Sam package, etc.
Successful deployment of Payroll Spring Cloud Function using GitHub Actions

A screenshot of the azure functions dashboard. Functions selected under payroll-kubeforce includes name, trigger and status with its details.
Azure Functions dashboard showing the function employeeSupplier has been deployed

A screenshot of the employee supplier dashboard. The tab overview is selected. The get function under overview is selected which displays essentials along with other details such as function app, status, etc.
Click the Get Function URL on the employeeSupplier dashboard

A screenshot of the employee supplier dashboard. The tab overview is selected. It displays the Get function U r l along with the default function key and ok tab.
Get the URL of the function
The URL of the function is https://payroll-kubeforce.azurewebsites.net/api/employeeSupplier. Use this URL for testing.
Step 4: Testing. You will use an external testing tool to see if the deployed functions work. The tool you use here is Postman.

A screenshot of the window of testing of the payroll-Kubeforce azure website. The tab body is selected. It displays options raw, binary, and Graph Q L along with other details.
Successful test result with Postman
This completes the deployment of Spring Cloud Function on Azure Functions using GitHub Actions.
The CI/CD for deploying Spring Cloud Function on Knative are similar for every Kubernetes. The only change is the cluster name. This section uses ArgoCD (http://argoproj.github.io) for CD even though you can achieve the same result with GitHub Actions. I found GitHub Actions a bit code-intensive. I wanted to separate the CD process and have a good visual tool that shows the deployment. ArgoCD provides a good visual interface.
To have a common repository for all the cloud environments, you’ll use Docker hub in this example. Docker hub provides a good interface for managing images and it is popular with developers. If you use ECR, GCR, or ACR, you’ll experience vendor lock-in.
Get the code from GitHub. You can use https://github.com/banup-kubeforce/payroll-h2.git or push your custom code
A Dockerhub account
A Dockerfile to push to Dockerhub
Actions code in your GitHub project
Access to a Kubernetes Cluster with Knative configured
ArgoCD up and running
An app in ArgoCD that is configured to poll the GitHub project

A flow diagram describes deployment flow for spring cloud function with Github actions and Argo C D. Commit code through Git pushes it to GitHub. Event-triggered Github actions push to docker and pull and sync to Argo. It deploys spring cloud function in kubernetes.
Deployment flow for Spring Cloud Function with GitHub Actions and ArgoCD
Once you have the prerequisites set up, you can begin configuring an automated CI/CD pipeline. For this example implementation, you’ll use the code from GitHub at https://github.com/banup-kubeforce/payroll-h2.git.
Step 1: Spring Cloud Function code in GitHub. Push your code to GitHub. You can use the code for payroll-h2 in GitHub.
Workflow for Payroll Function Image to be Pushed to Docker Hub

A screenshot of the payroll-Kubeforce window. In settings, action is selected. It displays environment and repository secrets and their details.
GitHub Secrets store for configurations and credentials
Step 3: Execute GitHub Actions to build and push the Docker image.

A screenshot of the banup-kubeforce window. The docker button is selected. under docker the following is displayed setup job, set up Q E M U, build with Maven, run the Sam package, etc.
Successful run of GitHub Actions
Step 4: Configure ArgoCD.
ArgoCD Script to Create a Project and Point to the payroll-h2 Repo

A screenshot of the application window. It depicts the Payroll-h 2 which includes project, labels, status, repository, path, destination, etc. The status is healthy and synced.
Application payroll-h2 deployed on ArgoCD
Step 5: Sync the project in Argo CD.

A screenshot of the repository window. It depicts type, name, repository, and connection status.
Connect payroll-h2 to the repo using HTTPS

A screenshot of payroll-h 2 window. It depicts the project, labels, status, repository, target, path, destination, and name. The status is healthy and synced.
The SYNC button on payroll-h2 app in ArgoCD

A screenshot of deploying the application window. Select synced button. Payroll-h 2 is displayed. It includes app health, current synchronize status, and last synchronize result.
Successful run of the sync showing the deployment flow

A screenshot of Kubernetes services dashboard. It displays payroll c l s t r of services and ingresses. Services and ingresses are selected and the status all are ok.
Successful deployment of Spring Cloud Function (payroll-h2) on Azure
Step 7: Testing. The best way to get the URL to test is to connect to the cluster via the command line and get the URL, as explained in Chapter 2.

A screenshot of service list run logs. It contains name, U R L, latest, age, conditions, ready, and reason.
URL for testing payroll-h2

A screenshot of the Get window. params selected. It contains query parameters of key, value, description, and bulk edit. The body includes a code with other tabs such as pretty, raw, preview, etc.
Successful execution of test against payroll-h2 deployed on AKS Knative
This completes the successful deployment using GitHub Actions and ArgoCD.
In this chapter, you learned how to set up some CI/CD tools to create an automated deployment for your Spring Cloud Function.
You learned how to trigger the deployment of functions on Lambda, Google Cloud Functions, and Azure Functions.
You also learned that you can combine the build of Docker images stored in Docker hub and ArgoCD to deploy the image to any Kubernetes cluster that is running Knative.
If you want to achieve “write-once deploy-anywhere,” you have to look at using Kubernetes and Knative. Spring Cloud Function is really a portable function.
Spring Cloud Function plays a critical role in the hybrid cloud or on-premises/private cloud space. Building events/data pipelines that span across the local datacenter and the cloud increases complexity due to the firewall boundaries. Data pipelines play an important role when you want to acquire, move, or transform data as it comes (streaming) or when it’s offline (batch).
So, what are event data pipelines?

An illustration depicts the OnStar event-driven data pipeline implementation for vehicles. The vehicle sends data to nearby Cell tower, Cell tower relays data to OnStar datacenter. OnStar datacenter routes information to the call center. Through this emergency services such as police, medical response team and towing company are activated.
An example event-driven data pipeline implementation for vehicles using OnStar
All data regarding the incident is collated, processed, analyzed, and sent to various target systems, both internal and external to OnStar. This is an example of event data pipeline.
A data pipeline is a set of processes that takes raw data from disparate sources, and then filters, transforms, and moves the data to target stores, where it can be analyzed and presented in a visually compelling way.

An illustration depicts the data pipeline as a set of processes that ingests the structured or unstructured data and retrieves and transforms the data through data lakes or data warehouses which is further analyzed through A I or M L processes.
Data pipeline process
The data can also be unstructured or structured. Unstructured data can be from a multitude of resources, including Internet-based platforms such as Twitter, to an automotive device emanating data.
Structured data usually originates from within the company’s applications. This data needs to be combined at a landing zone of object stores. These object stores can be on-premises or in the cloud. Once the data is ingested into the object stores, it is then retrieved and transformed, usually through an ETL process in other datastores such as data lakes or data warehouses. This data is then further analyzed using BI tools such as Power BI and Tableau or further processed with the AI/ML processes.
This whole process—from data ingestion to consumption—is called the data pipeline.
Let’s dive a bit deeper into the various sub-processes outlined in the data pipeline process.
Acquiring data is the first step in the data pipeline process. Here, business owners and data architects decide on what data to use to fulfil the requirements for a specific use case.
For example, in the case of a collision event detection for OnStar, the data needs to be acquired from sensors. This sensor data then needs to be combined with data from internal and external partners, like finance, towing partners, rental partners, and so on.
Data Identification
Data | Type of Data | Data Source |
|---|---|---|
Sensor | Unstructured (JSON, CSV) | Sensors |
Rental info | Relational (RDBMS) | External rental agency |
User info | Relational (RDBMS) | OnStar registration |
Vehicle info | Relational (RDBMS) | Vehicle data systems |
Towing info | Relational (RDBMS) | External towing company |
The data from various sources is acquired and stored as raw data into the store of choice. The method of ingestion can be stream-based or batch-based.
For example, in the case of OnStar, sensor data is streamed at regular intervals or is event-based. Other data, such as rental info, can either be batch based or on-demand query driven. The raw datastore can be an S3 object store hosted in the cloud or on-premises.
The data that is stored raw in the object store is then processed. The process may include converting or transforming unstructured data into structured data and storing it in an RDBMS database.
For example, in OnStar, partner data and internal data will be combined and transformed into a common data model. The sensor data will also be transformed into an RDBMS format.
Once the data is transformed, it is then loaded into a single or multiple databases with a common schema. This schema is based on a predefined data model specific to the use case. The target datastore can be a data lake or another RDBMS store. Here again, it depends on the type of analysis that needs to be done.
For example, if this an OLTP type of analysis, the data needs to be processed and sent to requesting systems quickly. This would require an RDBMS store. Data that needs to be available for reporting and research can be stored in a data lake.
During this sub-process, the data that is stored in a data lake or RDBMs will be analyzed using tools such as Tableau, Power BI, or a dedicated web page for reporting.
In the case of OnStar, data that is stored in the data lake will be analyzed using Tableau or Power BI, while the data that needs immediate attention will be analyzed by a custom dashboard or reporting interface on the web.
Spring Cloud Function plays an integral role in the whole process, especially when combined with tools such as Spring Cloud Data Flow, AWS Glue, Azure Data Factory, Google’s data flow, and so on. You will dive deep into these tools in this chapter.
Spring Cloud Data Flow (SCDF) is a Spring.io-based product that supports the creation and deployment of a data pipeline. It supports batch and event-driven data, which makes it versatile. SCDF pipelines can be built programmatically or wired up through a GUI. It is heavily based on the Spring Framework and Java, which makes it very popular among Spring developers.

A screenshot of a S C D F. It shows the stream vehicle data pipelines definition, status and applications.
A sample graphical representation of a data pipeline in SCDF
As you can see from the dashboard, you can build stream-based or batch-based (task) data pipelines and manage these through a single dashboard.
SCDF, unlike other the data pipeline tools available in the cloud, can be deployed in a Kubernetes, Docker, or Cloud Foundry environment, making it a portable tool for data pipeline development and deployment.
Spring Cloud Function and SCDF are perfectly matched, as they are built out of the same framework, Spring. You can deploy Spring Cloud Function as a source, processor, sink, or as a trigger for the pipeline. Since the data pipelines are usually invoked sporadically for processing data, you can optimize utilization of resources and costs with a Spring Cloud Function.
Let’s look at a sample implementation of Spring Cloud Function with SCDF.
In this example, you will build a simple data pipeline using RabbitMQ as a source, do a simple transformation, and store the messages in a log. You will publish sample vehicle information into a RabbitMQ topic called VehicleInfo and do a simple transformation, then store it in a log file.
RabbitMQ ➤ Transform ➤ Log
SCDF deployed on Kubernetes or locally in Docker
Kubernetes or Docker
A RabbitMQ cluster/instance
A queue to publish messages
Code from GitHub at https://github.com/banup-kubeforce/SCDF-Rabbit-Function.git
Additional prerequisites for each environment can be found at https://dataflow.spring.io/docs/installation
Local machine: Docker Compose is an easy way to get an instance of Spring Cloud Data Flow up and running. The details of the installation are available at https://dataflow.spring.io/docs/installation/local/docker/
Kubernetes: Instructions for installing this on Kubernetes are available athttps://dataflow.spring.io/docs/installation/kubernetes/.

A screenshot depicts the helm command to install the S C D F. It consists of name, last deployed, namespace, status, test suite, notes, chart name, chart version and app version.
Successful execution of a helm chart for SCDF

A screenshot depicts the command to get external I P of the S C D F. The command used is dollar kubect 1 get pods-n s c d f-system.
Get the external IP of the SCDF

A screenshot depicts the command to get the status of the S C D F. The command used is dollar kubect 1 get s v c-n s c d f-system.
Get the status of SCDF
You can now access SCDF using the external IP. For example, http://20.241.228.184:8080/dashboard
The next step is to add applications. Spring provides a standard set of templates that you can use to build your pipeline.
Step 2: Add Applications to your SCDF Instance

A screenshot depicts the S C D F add application view to create a data pipeline.
Add application view in SCDF

A screenshot depicts the options to add applications and docker-based or rabbit M Q kafka-based.
Pick the starters of your choice. If SDCF is deployed in Kubernetes, pick Docker based starters
Figure 4-8 shows you the options to add applications that are custom built through the Registering One or More Applications option. You import the application coordinates from an HTTP URI or use a properties file. There is also an option to import some prebuilt starters from Spring. Furthermore, you can choose starters that are Maven- or Docker-based or RabbitMQ- or Kafka-based. RabbitMQ and Kafka are used as backbone messaging systems for internal SCDF components and not for external use. When deploying to a Kubernetes cluster, you have to choose a Docker-based starter. When deploying locally in a Docker environment, you can choose between Maven and Docker-based starters.

A screenshot depicts the S C D F running on a Kubernetes environment and prebuilt templates installed in S C D F.
Prebuilt templates are installed in SCDF
These prebuilt templates come in three categories—source, processor, and sink. They allow you to wire up a data pipeline without the need for coding. If you want a custom component, you can follow the examples in https://dataflow.spring.io/docs/stream-developer-guides/.
The next step is to create a stream using the starter templates you loaded.
Step 3: Create a Stream

A screenshot depicts the streams button to create a stream in the streams dashboard.
The Streams dashboard
Pick the source.

A screenshot depicts the create stream and picking the available option from the source.
Create a source
Pick a processor.

A screenshot depicts a selection and creation of a processor for the transform component.
Create a processor
Pick a sink.

A screenshot depicts a selection and creation of a sink for the log component.
Create a sink

A screenshot depicts wiring the data pipeline by dragging the output of the first component to the input of the second component.
Wiring the data pipeline
Configure RabbitMQ.

Two screenshot depicts the configured Rabbit M Q and the properties of the Rabbit. It consists of a username, password, port and host.
Set the properties for rabbit
Configure the transform.

A screenshot depicts the properties for transform. It consists of general and spel. function and update and cancel buttons.
Set the transform properties
Configure the sink.

A screenshot depicts setting properties for log. It represents general, log along with cancel and update buttons.
Setting properties for the log
Wire up the data pipeline.

A screenshot depicts the wiring up of the data pipeline. It represents stream D S L expression on create stream dashboard.
Wire up the data pipeline
Deploy the stream

A screenshot depicts the successful deployment of a data pipeline by an external Spring Cloud Function.
Successful deployment of a data pipeline
Step 4: Create a function to publish data to RabbitMQ
Here, you create a Spring Cloud Function to publish the data to start the data-pipeline process.
SenderConfig
QueueSender
SenderFunction
A POM with the necessary dependencies for RabbitMQ and Spring Cloud Functions, as shown in Listing 4-1.
pom.xml with RabbitMQ Dependencies
application.properties
1. Create the SenderConfig Component
application.properties
2. Create the QueueSender Component
QueueSender.java
3. Wrap the Sender in Spring Cloud Function framework
SenderFunction.java
Step 5: Test the function using Postman
Use the GET function on Postman and provide the URL to the senderFunction.

A screenshot depicts the G E T function on Postman with the U R L.
You should get the result shown in this image.
Check the RabbitMQ queue for any messages.

A screenshot depicts the Rabbit M Q Queue for any messages. It represents Exchange, Routing key, Redelivered, Properties, and Payload under the Queries tab with a message the server reported 0 messages remaining.
Now you have a function that can post messages to a RabbitMQ topic. The SCDF data pipeline will be listening to the queue and will start processing.

A screenshot depicts the details of the vehicle data pipeline. It shows the logs associated with each of the components to monitor.
Details of the VehicleDataPipeline stream
You have seen how to create a data pipeline in SCDF that monitors a topic in RabbitMQ. You created a Spring Cloud Function that posts messages into the RabbitMQ topic. Spring Cloud Function can also be deployed as a source in SCDF; more information on how to develop code for SCDF is available on the SCDF site.
AWS Glue works very similarly to Spring Cloud Data Flow in that you can wire up a data pipeline that has a source, processor, and sink. More information can be found at https://us-east-2.console.aws.amazon.com/gluestudio/home?region=us-east-2#/.
Spring Cloud Function can participate in the data pipeline process as a trigger, or simply by integrating with one of the components in the data pipeline.
For example, if you have AWS Kinesis as a source and you need to get data from a vehicle, you can have Spring Cloud Function stream the data that it gets into AWS Kinesis.
In the example in this section, you will be publishing data into AWS Kinesis and then kick off an AWS Glue job manually.
The flow will be:
Spring Cloud Function ➤ Kinesis ➤ AWS Glue Job ➤ S3
Subscription to AWS, AWS Glue job, Kinesis, and S3
AWS Glue job with Kinesis as the source and S3 as the target
Code from GitHub at https://github.com/banup-kubeforce/Kinesis_trigger.git
It is assumed that you have some knowledge of AWS Glue, as we do not delve into the details of this product. The focus is on creating the Spring Cloud Function.
You can get to Kinesis at https://us-east-1.console.aws.amazon.com/kinesis/home?region=us-east-1#/home.

A screenshot depicts the setup for Kinesis to create a data stream for a vehicle. It shows the data stream configuration, data stream capacity and data stream settings.
Create a vehicledatastream in AWS Kinesis

A screenshot depicts the active vehicle data stream under the monitoring tab.
vehicledatastream is active
You can now connect and publish to the stream using your Spring Cloud Function.
You can access the AWS Glue Studio at https://us-east-1.console.aws.amazon.com/gluestudio/home?region=us-east-1#/.
Once you have the subscription, you can begin creating a glue job.

A screenshot depicts the creation of a job on A W S glue studio.
AWS Glue Studio, Create a Job
Create a job called vehicledatapipeline. Use Amazon Kinesis as the source and Amazon S3 as the target. Ensure that you set the proper configurations for each of these components.

A screenshot depicts the Configuration of amazon kinesis as the source and amazon S 3 integration for each component.
Configure Kinesis and S3 integration
Now you have a job in AWS Glue that you can trigger manually or via a function.
application.properties
pom.xml dependecies
TrackDetail.java
ProducerService.java
ProducerServiceImpl.java
ProducerFunction.java

A screenshot depicts the successful run of the function.
Successful run of the function
8: Test with Postman. Run a POST-based test against ProducerFunction to publish data into Kinesis.

A screenshot depicts the post-based test against the producer function. It includes the tabs params, authorization, headers, body, pre-request script, tests, and settings with a button to send.
Postman test
You will get a message that the data is saved.

A screenshot depicts the data metrics found on the kinesis dashboard.
Kinesis dashboard showing the data metrics
10: Run Glue manually. From the Glue Studio, start the process by clicking Run, as shown in Figure 4-24.

A screenshot depicts the glue job run from the glue studio.
The Glue job run
In this section, you learned how to create a Spring Cloud Function that can post data into AWS Kinesis that is part of the data pipeline. You learned that you can publish data into Kinesis and trigger the AWS Glue pipeline manually, but I also encourage you to explore other ways you can implement Spring Cloud Function for AWS Glue, such as creating and deploying triggers. More information on how to create AWS Glue triggers in Spring is available at https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/examples-glue.html.
Google Cloud Dataflow is very similar to Spring Cloud Data Flow, in that it allows you to wire up a data pipeline with a source, processor, and sink. The Dataflow product is easier to develop with. You can read about Dataflow and its capabilities at https://cloud.google.com/dataflow.
For the example in this section, you will create a dataflow that includes cloud pub/sub:
Spring Cloud Function ➤Dataflow {Cloud Pub/Sub ➤ Cloud Storage}
Subscription to Google Data Flow
A cloud pub/sub instance
A cloud storage bucket
Code from GitHub at https://github.com/banup-kubeforce/GooglePubSub
Step 1: Create and configure a cloud pub/sub instance.
Before coming to this step, ensure that you are subscribed to cloud pub/sub. Also ensure that you have proper subscriptions to the APIs.

A screenshot depicts the creation and configuration of cloud pub or sub-instance in google cloud.
Cloud Pub/Sub with a topic

A screenshot depicts the google cloud storage with vehicle bucket 1. It includes the tabs create and refresh with a list of names under buckets.
Google Cloud Storage with vehiclebucket1
Now you are ready to build the Dataflow data pipeline.
Step 3: Create a data pipeline. Navigate to the Dataflow dashboard and create a pipeline. I created a pipeline using a prebuilt template.
1: Pick the template

A screenshot of a data flow option in google cloud. It shows the template used to create the data pipeline in the drop-down and the filter option shows many data flow template formats.
Create a data pipeline from the template
2: Set the parameters for pub/sub and cloud storage.

A screenshot depicts the data flow parameter setup. It shows the option to create a pipeline template, data flow template, regional endpoint, input pub per subtopic, output file name prefix and temporary file location.
Complete the parameters set up for Dataflow
3: Verify the creation of the data pipeline.

A screenshot depicts the successful creation of vehicle data pipeline and its pipeline summary.
Successful creation of vehicledatapipeline

A screenshot depicts the created job from the template in google cloud.
An associated job is created

A screenshot depicts the graphical representation of the job. It consists of read pub-sub event, a 5-meter window and write files.
Execution of the pipeline

A screenshot depicts the vehicle bucket details. It consists of vehicle bucket 1, location, storage class, public access and protection, under the objects tab, it shows the vehicle info.
The bucket shows the posted document
Step 4: Create the Spring Cloud Function.
MessageEntity class to formulate the message
TrackDetail class as the entity class
PubSubPublisher class that subscribes to the topic and publishes data
ProducerFunction class to implement the Spring Cloud Function
Maven dependencies
Maven Dependencies
application.properties
1: Create the MessageEntity class.
MessageEntity.java
2: Create the TrackDetail class.
TrackDetail.java
3: Create the PubSubPublisher.
PubSubPublisher.java
4: Create the Spring Cloud Function.
ProducerFunction.java
5: Run the application and test if a message is published to Cloud Pub/Sub.

A screenshot depicts the message posted in the pub per sub console in google cloud.
The message has been posted in Cloud Pub/Sub
6: Verify is the message has been loaded into Cloud Storage.

A screenshot depicts the cloud storage console to verify that the message has been loaded into the storage. It shows the bucket details of vehicle bucket one.
The message is loaded into Cloud Storage
In this section, you learned how to use Spring Cloud Function to trigger a Google Cloud Dataflow-based data pipeline.
This chapter explained how to create dataflow and data pipelines, whether on-premises using SCDF or in the cloud. For the cloud, you can use SCDF or cloud-native tools.
Spring Cloud Function is versatile and can be used in the context of data pipelines as a trigger or as part of the flow.
With AWS Glue and Google Data Flow, you saw that you can use Spring Cloud Function as a trigger for the flows. This requires some additional coding by adding some relevant libraries and invoking the flow.
Upcoming chapters discuss other use cases of Spring Cloud Function.
This chapter looks at how Spring Cloud Function can be leveraged in AI/ML. You learn about the AI/ML process and learn where Spring Cloud Function fits in the process. You also learn about some of the offerings from the cloud providers, such as AWS, Google, and Azure.
Before delving into the details of Spring Cloud Function implementation, you need to understand the AI/ML process. This will set the stage for implementing Spring Cloud Function.

A process of the M L lifecycle. The 4 processing steps are, gathering requirements, setting A I slash M L pipeline, performing A I slash M L, and monitoring.
ML lifecycle
Model requirements
This is an important step in the AI/ML process. This determines the ultimate success or failure of the AI/ML model activity. The requirements for models must match the business objectives.
What is the return on investment (ROI) expected from this activity?
What are the objectives? Examples may include reduce manufacturing costs, reduce equipment failures, or improve operator productivity.
What are the features that need to be included in the model?
In character recognition, it can be histograms counting the number of black pixels along horizontal and vertical directions, the number of internal holes, and so on.
In speech recognition, it can be recognizing phonemes.
In computer vision, it can be a lot of features such as objects, edges, shape size, depth, and so on.
What datasets to integrate
What are the sources
Are the datasets available
Data cleaning: This activity involves removing inaccurate or noisy records from the dataset. This may include fixing spelling and syntax errors, standardizing datasets, removing empty fields, and removing duplicate data. 45 percent of a data scientist’s time is spent on cleaning data (https://analyticsindiamag.com/data-scientists-spend-45-of-their-time-in-data-wrangling/).
Data labeling: Tagging or labeling raw data such as images, videos, text, audio, and so on, is an important part of the AI/ML activity. This makes the data meaningful and allows the machine learning model to identify a particular class of objects. This helps a lot in the supervised learning activities such as image classification, image segmentation, and so on.
Feature engineering: This refers to all activities that are performed to extract and select features for machine learning models. This includes the use of domain knowledge to select and transform the most relevant variables from raw data to create predictive models. The goal of feature engineering is to improve the performance of machine learning algorithms. The success or failure of the predictive model is determined by feature engineering and ensure that the model will be comprehensible to humans.
Train model: In this step the machine learning algorithm is fed with sufficient training data to learn from. The training model dataset consists of sample output data and the corresponding sets of input data that influence the output. This is a iterative process that takes the input data through the algorithm and correlates it against the sample output. The result is then used to modify the model. This iterative process is called “model fitting” until the model precision meets the goals.
Model evaluation: This process involves using metrics to understand the model’s performance, including its strengths and weaknesses. For example, doing a classification prediction, the metrics can include true positives, true negatives, false positives, and false negatives. Other derived metrics can be accuracy, precision, and recall. Model evaluation allows you to determine how well the model is doing, the usefulness of the model, how additional model training will improve performance, and whether you should include more features.
Deploy model: This process involves deploying a model to a live environment. These models can then be exposed to other processes through the method of model serving. The deployment of models can involve a process of storing the models in a store such as Google Cloud Storage.
Monitoring the AI/ML models
In this process, you want to make sure that the model is working properly and that the model predictions are effective. The reason you need to monitor model is that models may degrade over time due to these factors:
Variance in deployed data
Variance refers to the sensitivity of the learning algorithms to the training dataset. Every time you try to fit a model, the output parameters may vary ever so slightly, which will alter the predictions. In a production environment where the model has been deployed, these variances may have a significant impact if they’re not corrected in time.
Changes in data integrity
Machine learning data is dynamic and requires tweaking to ensure the right data is supplied to the model. There are three types of data integrity problems—missing values, range violations, and type mismatches. Constant monitoring and management of these types of issues is important for a good operational ML.
Data drift
Data drift occurs when the training dataset does not match the data output in production.
Concept drift
Concept drift is the change in relationships between input and output data over time. For example, when you are trying to predict consumer purchasing behavior, the behavior may be influenced by factors other than what you specified in the model. factors that are not explicitly used in the model prediction are called hidden contexts.
Let’s evaluate these activities from a compute perspective. This will allow us to determine what kind of compute elements we can assign to these process
Some of the activities in this process are short lived and some are long running process. For example, deploying models and accessing the deployed models is a short lived process. While Training models and model evaluation require both a manual and programmatic intervention and will take a lot of processing time.
Where to Use Spring Cloud Function in the AI/ML Process
AI/ML Process | Human | Compute | |
|---|---|---|---|
Spring Cloud Function (Short Run) | Batch (Long Run) | ||
Model requirements | Human/manual process | ||
Collect data | Integration triggers, data pipeline sources or sinks | Data pipeline process-Transformation | |
Data cleaning | Integration triggers | Transformation process | |
Data labeling | Tagging discrete elements-updates, deletes | Bulk tagging | |
Feature engineering | Manual | ||
Train model | Trigger for training | Training process | |
Model evaluation | Manual | Triggers for evaluation | Bulk evaluation |
Deploy models | Model serving, model | Bulk storage | |
Monitoring models | alerts |
AI/ML processes require varying compute and storage requirements. Depending on the model size, the time taken to train, the complexity of the model, and so on, the process may require different compute and storage at different times. So, the environment should be scalable. In earlier days, AI/ML activities were conducted with a fixed infrastructure, through over-allocated VMs, dedicated bare metal servers, or parallel or concurrent processing units. This made the whole process costly and it was left to companies with deep pockets to be able to conduct proper AI/ML activities.
Today, with all the cloud providers providing some level of AI/ML activities through an API or SaaS approach, and with the ability to pay per use or pay as you go, companies small and big have begun to utilize AI/ML in their compute activities.
Codeless inference makes getting started easy
Scalable infrastructure
No management of infrastructure required
Separate storage for the model, which is very convenient for tracking versions of the model and for comparing their performance
Cost structure allows you to pay per use
Ability to use different frameworks

A pictorial horizontal bar graph of the most popular programming languages. It mentions the logo of worldwide languages with percentages and a laptop image. Python has the highest at 25.95 and Ruby, has the lowest at 1.53.
AI/ML language popularity
It is very important to understand that the popularity of a language does not equate to it being a good, robust, secure language for use in AI/ML.
Enterprises have standardized on Java, so they prefer to have their AI/ML platform written in Java to ease the integration into existing systems.
Apache.org , the open source community for Java, is very robust and has many libraries and tools that have been tuned toward speed of compute, data processing, and so on. Tools such as Hadoop, Hive, and Spark are integral to the AI/ML process. Developers can easily use these tools and libraries in their java code.
Java can be used at all touchpoints in the AI/ML process, including data collection, cleansing, labeling, model training, and so on. This way you can standardize on one language for AI/ML needs.
JVMs allow for applications to be portable across different machine types.
Due to Java’s object-oriented mechanisms and JVMs, it is easier to scale.
Java-based computation for AI/ML can be made to perform faster with some tuning at the algorithm and JVM level. Therefore, it is a preferred language for sites like Twitter, Facebook, and so on.
Java is a strong typing programming language, meaning developers must be explicit and specific about variables and types of data.
Finally, production codebases are often written in Java. If you want to build an enterprise-grade application, Java is the preferred language.
Since Java is a preferred enterprise language for AI/ML, we can safely say that Spring Cloud Function is a better framework to use when developing enterprise-grade functions for AI/ML.
This chapter explores the different offerings from the different cloud providers and explains how you can use Spring Cloud Function with these offerings.
A lot of frameworks have been developed in Java that can be leveraged using the Spring Framework. The latest of these frameworks was developed by AWS and is called DJL (Deep Java Library). This library can integrate with PyTorch, TensorFlow, Apache MXNet, ONNX, Python, and TFLite based models.
One of the important capabilities that you need is model serving, where you can leverage Spring Cloud Function to serve trained models, and DJL provides this capability out of the box. It’s called djl-serving.

An illustrated model of the on-prem data center. The flow of data includes trained model data, the model serving, an enterprise application, a firewall, and an external application.
On-premises and Spring Cloud Function deployment for model serving
Before you explore the cloud provider’s option, it’s a good idea try this out locally. To do that, you need a framework installed and access to a good tensor model and an image. The framework that you use in this example is called djl-serving.
Deep Java Library (DJL) https://docs.djl.ai/ is a high-level, engine-agnostic Java framework for deep learning. It allows you to connect to any framework like TensorFlow or PyTorch and conduct AI/ML activities from Java.

A model of layers of the deep java library. It includes a java framework with a logo of spring boot, and spring cloud function. An M L framework of m x net, Tensor flow, PyTorch. Deep Lava Library is mentioned between the frameworks.
Deep Java Library (DJL) layers
There are many components in DJL that are useful to look at, but the DJL serving is interesting.
djl-serving Run with a Tensorflow Model
On subsequent runs, the model server will be available at port 8080 at http://localhost:8080.

A photograph of a kitten with closed eyes and legs laid out.
Image of a kitten for the model to predict
Next, run the following and you will see the output with probabilities.

A screenshot of the window. It has the class name and probability input and outputs. It represents the D J L results.
DJL results for the image

An X-ray image. It diagnosis the lungs using a saved model.
Xray image provided to the saved_model
Next, you see how you can use DJL to create a Spring Cloud Function to serve models.
For this example, we borrow an example from DJL called pneumonia detection. This sample is available at https://github.com/deepjavalibrary/djl-demo/tree/master/pneumonia-detection.
This example uses an Xray image from https://djlai.s3.amazonaws.com/resources/images/chest_xray.jpg.
It predicts using a model from https://djl-ai.s3.amazonaws.com/resources/demo/pneumonia-detection-model/saved_model.zip.
The Spring Cloud Function you create will take an image, load the model, and provide a prediction, as in the cat example.
DJL libraries
A model: https://djl-ai.s3.amazonaws.com/resources/demo/pneumonia-detection-model/saved_model.zip
The URL of the image to analyze: https://djl-ai.s3.amazonaws.com/resources/images/chest_xray.jpg
Step 1: Create the Spring Cloud Function with DJL framework. Add dependencies to the Hadoop file.
Dependencies for DJL
Step 2: Create the Spring Cloud Function.
XRAYFunction.java
Step 3: Test locally. Run the Spring Cloud Function and invoke the endpoint http://localhost:8080/xrayFunction

A screenshot of the postman testing. It highlights the local host, body, and row options with a testing program.
Testing with a POST in Postman

A screenshot of programming functions with number, date, and time. It represents the results from image evaluation.
Prediction results from the image evaluation

A flow diagram of the saved model. It classifies as training and deployment. It represents the tensor flow components. The output from the training is sent to the saved model and further to the deployment.
TensorFlow components1
This section successfully demonstrated that Spring Cloud Function can act as a model server in AI/ML. This is a critical function, as you can move the loading and serving of models from traditional servers to a function-based, “pay-per-use” model.
You also learned how to use deep learning Java libraries in your functions. You can deploy this Spring Cloud Function to any cloud, as shown in Chapter 2.
This section explores the model serving on Google. It uses TensorFlow, which is a Google product from AI/ML and explains how to build and save an AI model with datasets such as MNIST (https://en.wikipedia.org/wiki/MNIST_database).
TensorFlow was developed by Google and is an open source platform for machine learning. It is an interface for expressing and executing machine learning algorithms. The beauty of TensorFlow is that a model expressed in TensorFlow can be executed with minimal changes on mobile devices, laptops, or large-scale systems with multiple GPUs and CPUs. TensorFlow is flexible and can express a lot of algorithms, including training and inference algorithms for deep neural networks, speech recognition, robotics, drug discovery, and so on.
In Figure 5-9, you can see that TensorFlow can be deployed to multiple platforms and has many language interfaces. Unfortunately, TensorFlow is written in Python, so most of the models are written and deployed in Python. This poses a unique challenge for enterprises who have standardized on Java.
Even though TensorFlow is written in Python, there are lots of frameworks written in Java that work on a saved model.
Let’s look at how you can work with TensorFlow on the Google Cloud platform.
Google and AI/ML Environment2
A table with 4 columns and 6 rows. The column headers are the features, compute engine, A L platform prediction, and cloud functions. It categorizes features and descriptions. |
As you can see from Table 5-2, cloud functions are recommended for experimentation. Google recommends Compute Engine with TF Serving, or its SaaS platform (AI Platform) for predictions for production deployments.
The issue with this approach is that a function-based approach is more than just an experimentation environment. Functions are a way of saving on cost while exposing the serving capabilities for predictions through APIs. It is a serverless approach, so enterprises do not have to worry about scaling.
In this section you see how to train an AI model locally and upload it to Google Cloud Storage. You will then download the model and test an image through a Cloud Function API. You will use a model that is based on MNIST. More about MNIST can be found at https://en.wikipedia.org/wiki/MNIST_database.

A model of spring cloud function. It indicates the tensor flow of H T T P J SON request, cloud storage, and cloud function with two logos of spring cloud function, and deep java library.
Spring Cloud Function with DJL and TensorFlow
You use the same example outlined at https://cloud.google.com/blog/products/ai-machine-learning/how-to-serve-deep-learning-models-using-tensorflow-2-0-with-cloud-functions. This will allow you to concentrate more on the Spring Cloud Function code that you will be creating rather than the actual implementation in Python.
You will then serve the model using Spring Cloud Function.
Step 2: Create a project. Create a project called MNIST and then create a main.py file with the code in Listing 5-4. I used PyCharm to run this code.
main.py
The key is tf.saved_model.save(model, export_dir="c://Users//banua//Downloads/MNIST/models").
This will save the model so that any model server can use it.
Step 3: Run the project.

A screenshot of the window. It represents the successful run of M N I S T. The pop-up text reads as generated model files located in the root of the project.
Successful run of MNIST and model building
Zip the assets, variables, and the saved_model.pb. file as Savedmodel3.zip and upload it to the Google Cloud Storage.
Step 4: Upload the models into Cloud Storage. Navigate to your Google Cloud Console and subscribe to Cloud Storage. It is available at cloud.google.com.
Create a storage bucket in Google Cloud Storage and upload the two files into the storage bucket. Use the defaults for this example. If you are using free credits from Google, this storage should be covered.

A screenshot of the Google cloud storage bucket. It includes the name of the bucket, choosing store data, choosing default storage, choosing control access, and protecting access with highlighted lines.
Google Cloud Storage Bucket creation steps
Name your bucket mnist-soc and leave the others set to the defaults; then click Create.

A screenshot of a mnist soc application. It highlights the object option and mentions the model's name, size, and type. It represents the models located in cloud storage.
Models deployed into Cloud Storage

A screenshot represents the U R L for a model. It indicates a mnist soc application with a live object option. It highlights the public and authentication U R L with a link.
URL for the savedmodel3.zip
The URL you use for testing this example is https://storage.googleapis.com/mnist-soc/savedmodel3.zip.
The test image you use for this example is https://storage.googleapis.com/mnist-soc/test.png.
Note that the function that you created in Section 5.2 will be deployed in Step 5. If you use savedmodel3.zip and test.png, it will fail. But you will know that the function is working because you will get an error message that the model could not be loaded. This is an acceptable outcome for the model you created.
Step 5: Deploy the Spring Cloud Function to Google Functions. In this step, you take the function you created in Section 5.2 and deploy it into the Google Cloud Functions environment. The prerequisites and steps are the same as discussed in Chapter 2.
Google account
Subscription to Google Cloud Functions
Google CLI (This is critical, as it is a more efficient way than going through the Google Portal)
Code from GitHub at https://github.com/banup-kubeforce/DJLXRay-GCP.git
Dependencies for GCP Added
Deploy the Spring Cloud Function to Google Cloud Functions. Make sure that you build and package before you run the following command. A JAR file must be present in the target/deploy directory in the root of your project.

A screenshot of multiple programming functions. It denotes the deployed function, memory, and time.
Successfully deployed function with the specifed memory and timeout

A screenshot includes functions and cloud functions in the console. It highlights the create function and refresh. It indicates a filter option with details of the first gen.
Function shows up in the console

A screenshot highlights the cloud function, D J L X ray -G C P. The testing option with Test the function is highlighted. The test was successfully executed.
Successful execution of the test

A screenshot of the window denotes the multiple output logs. It highlights one log code no-16392, code- 200 with box .It displays the execution time.
Logs show the execution times
This section explored the capabilities of TensorFlow and explained how you can use DJL and Spring Cloud Function together to access a saved TensorFlow model. DJL makes it easy for Java programmers to access any of the saved models generated using Python frameworks, such as PyTorch (pytorch.org) and TensorFlow.
You also found that you have to set the memory and timeout based on the saved model size and store the model closer to the function, such as in Google’s storage offerings.
This section emulates what you did in Chapter 2 for Lambda. It is best to finish that exercise before trying this one.
AWS account
AWS Lambda function subscription
AWS CLI (optional)
Code from GitHub at https://github.com/banup-kubeforce/DJLXRay-AWS.git
Step 1: Prep your Lambda environment. Ensure that you have access and a subscription to the AWS Lambda environment.
DJL Dependencies
Step 3: Deploy the Spring Cloud Function to Lambda. You should follow the process outlined in Chapter 2 to build and package the Spring Cloud Function and deploy it to Lambda.

A screenshot of the window of the successful execution. It highlights the body and pretty options and mentions the class name with probability.
Successful execution
This section explores the offering from AWS called SageMaker and shows how you can use Spring Cloud Function with it.

A model of the A W S sage maker. The process includes labeling data, building, training, tuning, deploying, and discovering. Each step has a logo associated with it.
AWS SageMaker flow
SageMaker allows you to build and deploy models with Python as the language of choice, but when it comes to endpoints, there are Java SDKs much like AWS Glue that create prediction APIs or serve models for further processing. You can leverage Lambda functions for these APIs.
So, as you saw in TensorFlow, you have to work in Python and Java to model and expose models for general-purpose use.
Let’s run through a typical example and see if you can then switch to exposing APIs in Spring Cloud Function.
This example uses the same sample to build, train, and deploy as in this hands-on tutorial in AWS.
https://aws.amazon.com/getting-started/hands-on/build-train-deploy-machine-learning-model-sagemaker/

A screenshot of the create notebook instance. It includes Notebook instance settings, Permissions, and encryption. It asks for the notebook instance name, type, elastic inference, platform identifier, and I A M role.
Notebook instance in SageMaker with properties set

A screenshot of the deployment of the notebook. It highlights the amazon sage maker and search notebook instance. It asks for name, instance, creation time, status, and actions.
Successful deployment of the notebook

A screenshot of the jupyter notebook. It highlights the option for new notebooks. It has the title files, running, cluster, sage maker example, and conda.
Pick a framework in the Jupyter notebook
As you can see from the list, most frameworks use Python. This example uses conda_python3, as suggested in the AWS tutorial.

A screenshot of the window of the Jupyter notebook code. It creates a sage maker for instance. In this program, the log mentions import libraries, defines I A M role, X G boost container.
Code to create a SageMaker instance

A screenshot of the window for the creation of a bucket. This program includes the bucket name, steps, and process. The bucket was created successfully.
Create a bucket

A screenshot of the window for downloading the data to a data frame. The program includes the process of trying, except, and printing data.
Download the data into a dataframe

A screenshot of the window for the work on the dataset. The program includes splitting the dataset to train data, test data, split data, and print.
Work on the dataset

A screenshot of the window for inputs and outputs. It indicates the training of the model with 3 steps.
Train the model

A screenshot of the window with the input and outputs. It indicates the S 3 training completion. It mentions that the training job was completed.
Training is complete

A screenshot of the window for the deployment of the model. It indicates the programming function.
Deploy the model

A screenshot of the window of Amazon sage maker. It has endpoints that include the name, A R N, creation time, status, and last update.
Endpoint of the deployment

A screenshot of the window indicates the endpoint settings. It includes the name, type, A R N, creation time, status, last updated, U R L.
Details of the endpoint
AWS SDK Dependencies

A screenshot of the window with the programming function input and output components. It represents the sage maker supplier in Java.
SageMakerSupplier.java
Deploy the function in Lambda, as shown in Chapter 2.
This section explained how to create and deploy a model in AWS SageMaker. You then called the SageMaker endpoint using the SageMaker JDK client in the Spring Cloud Function, which was deployed in AWS Lambda.
The Java-based Lambda function can be tuned to be more responsive and have a shorter cold startup time by using mechanisms such GraalVMs.
As you learned in this chapter, you can serve models using Spring Cloud Function. But you also learned that serving models using Spring Cloud Function and Java is a stretch because the AI/ML models are written in Python. While Python may be popular, it is also important to note that in an enterprise, Java is king. Finding ways to leverage Java in AI/ML is the key to having an integrated environment within your enterprise. Cold starts of Python-based functions take a long time. This is where using Java and frameworks such as GraalVM speeds up the startup times.
The next chapter explores some real-world use cases of IoT and Conversation AI and explains how Spring Cloud Function can be used.
This chapter covers Spring Cloud Function implementations with IoT. You'll see some real-world examples from manufacturing and logistics. You explore how Spring Cloud Function can operate with existing IoT platforms on the cloud and in datacenters. You also explore some specific implementations in Penske, which is interesting, as they can be applied to nearly all IoT-related scenarios.
Before you explore the solutions, you need to dive a bit into IoT and understand the status of the IoT market. You'll also look at some surveys on why Java is the preferred enterprise language for IoT development.
IoT (Internet of Things) has been growing and is expected to grow 22 percent in 2022. This phenomenal growth has led to a plethora of data that needs to be acquired and processed.
According to a study by IoT Analytics Research in September 2021, the IoT device market is expected to grow phenomenally and by 2025 it is predicted to reach 25 billion devices. More about the study is available at https://iotbusinessnews.com/2021/09/23/13465-number-of-connected-iot-devices-growing-9-to-12-3-billion-globally-cellular-iot-now-surpassing-2-billion/.
With this growth potential, you can safely assume that the supporting technologies will also grow. These technologies not only include hardware sensors and IoT gateways, but also technologies such as microservices and functions. The IoT industry is best suited to implement these technologies, as they are highly distributed and rely heavily on the software components to be small and efficient.
Serverless function-based environments that are triggered on demand are perfectly suited to IoT, as they can save significant cost. Traditional approaches to IoT relied on dedicated applications running 24/7. They used up a lot of resources, adding to the cost of operation. With the nearly ephemeral nature of serverless functions, this cost can be moved to the “pay per use” approach.
Java was designed with IoT in mind. If you look at early Java examples from Sun Microsystems, you will see that synchronization of digital clocks was referred to often.
Java has been ported to many microcontrollers.
Java is designed to run in a resource-constrained environment such as sensors.
JVM makes code portable across platforms; you write once run anywhere.
As per the IoT survey done by iot.eclipse.org, which is available at https://iot.eclipse.org/community/resources/iot-surveys/assets/iot-developer-survey-2020.pdf, you can see that Java is the preferred language, both in the edge and in the cloud. Implementations on the edge are moving to containerization, per the study. This is great for Knative on Kubernetes installations on the edge.
Furthermore, the Spring Framework has been the platform of choice for many IIoT (Industrial IoT) projects. You can review a presentation at a SpringOne event in 2017 at https://youtu.be/MReQD9tXQuA.
Components like Spring Cloud Streams, Spring Cloud Data Flow, Spring Integration, Spring MQTT, Spring Data, and Spring XD play a significant role in IoT data acquisition, storing, and the transformation pipeline.
Consider this example implementation of Spring and its components in a connected fleet scenario.

A diagram depicts components of Penske’s connected fleet. The truck fleet sends 2 billion pings per day to poller apps, which along with spring cloud data flow streams, and microservices connect to the Tanzu application service. Kafka on A W S along with V M ware Tanzu gemfire, Postgres, and Greenplum receive this data. Business users, real time analytics, and wavefront for observability as a service are the end users.
Penske connected fleet implementation with Spring Cloud
More information is available on the SpringOne website at https://springone.io/2020/sessions/iot-scale-event-stream-processing-for-predictive-maintenance-at-penske.

A flow diagram depicts the I o T process flow that starts from I o T sensors, stream acquisition, raw storage, transformation, data lake storage, and ends in analysis.
IoT Process flow
As in any data pipeline process, the IoT process includes acquiring data from sensors in the field. This data is then stored, transformed, and loaded into data lakes for further analysis.
Depending on the type of application, sensors send data either through a trigger event such as a repair or collision or via regular intervals. These intervals are 30 seconds to a minute in the case of logistics tracking or every few hours in the case of maintenance data. The data usually comes in as streams that need to be acquired. The most popular mechanism for acquisition is Apache Kafka.
Since the sensors send data in intervals, it is best to have the input handled by a cloud function rather than dedicated microservices. Dedicated microservices need to be served up in an environment and do not have the ability to scale down to zero when invoked. They can only be provisioned in environments that need to be available when invoked. This makes microservices a costly approach. Functions, on the other hand, are only invoked when there is an event trigger. Utilization of resources goes down to zero if they are not invoked. This is because the underlying serverless infrastructure such as Lambda and Knative can be scaled down to zero when not invoked.
This makes it a more cost-effective alternative. This applies to both on-premises and on the cloud. If it is on-premises, the argument against cloud functions on a serverless environment would be that the infrastructure cost has already been accounted for. Therefore, a dedicated microservice that is always on would be feasible. Wasting resources because you have them is not a prudent way to efficiently use IT. With functions running on serverless environments, such as Knative running on OpenShift or VMware Tanzu, on-premises would help save resources that could be used to run other activities. The on-premise resources are finite, so it's prudent to make the best use of them.
Consider a use case where an automotive assembly plant wants to ensure that its robots are performing well. The engineers want to ensure that each of the robot's data is monitored for any anomalies and, in an event of a breakdown, the engineers are alerted. The assembly plant is firewalled and any data that needs to be analyzed can be sent to the cloud.

A flow diagram has 2 modules with 3 steps. Step 1, in the automotive assembly plant module, sensors send data to spring cloud components on-premises, A W S lambda and I o T greengrass. Step 2, In A W S cloud module I o T core receives data from the plant module through a firewall and sends it to Lambda. Step 3, data from lambda is stored in amazon's simple storage service, S 3.
Manufacturing plant process flow with AWS and Spring Cloud Function
AWS IoT Greengrass on-premises
Prebuilt AWS Lambda functions that capture the sensor data
AWS IoT core on cloud
Spring Cloud Function running on AWS Lambda
S3 storage to store the data

A table of 5 rows and 2 columns. It describes components and their description. Components are A W S I o T greengrass on-premises, prebuilt A W S lambda functions that capture the sensor data, A W S I o T core on a cloud, spring cloud function running on A W S lambda, and A W S S 3.
You can build the solution using AWS IoT Greengrass and leverage a Spring Cloud Function that is deployed on Lambda. The point of this exercise is to understand the capabilities of Spring Cloud Function as a component that is integral to the solution.
The AWS IoT Greengrass implementation extends AWS Cloud to on-premises. You can run Lambda functions on Greengrass’s edge.
Step 1: Install AWS IoT Greengrass. Install AWS IoT Greengrass on a device (https://docs.aws.amazon.com/greengrass/v1/developerguide/install-ggc.html). To test it, I installed the software on Windows. I used the tutorial at https://aws.amazon.com/blogs/iot/aws-iot-greengrass-now-supports-the-windows-operating-system/ to get my first Greengrass implementation.
Once you have AWS IoT up and running, you need to create a function to connect to devices and collect data. Let’s create a sample function.
Step 2: Spring Cloud Function to publish an MQTT message. You can clone the project from GitHub at https://github.com/banup-kubeforce/AWSIots3-V2.git.
Devices communicate with MQTT, so you need to leverage MQTT as a protocol. Create a Spring Cloud Function that publishes an MQTT message and create a consumer function to call MQTT publish.
MqttConsumer.java
Next, create a publish class to publish messages to MQTT.
MqttPublish.java
Step 3: Deploy the Spring Cloud Function on AWS Greengrass locally.
AWS provides a great guide for deploying Lambda function on Greengrass at Run Lambda functions on the AWS IoT Greengrass core - AWS IoT Greengrass (amazon.com).

A screenshot of the A W S I o T management console. Monitor tab on the left is selected. It has I o T metrics and job execution metrics options. I o T metrics has 4 graphs with headings that include successful connections and protocol rates. Other main tabs on the left are connect, test, and manage.
AWS IoT Management console with some successful connections
Step 4: Create a Spring Cloud Function to get data from the IoT core. Create a class to subscribe and get messages from Mqtt.
MqttSubscriber.java with Command-Line Utilities to Publish to AWS IoT
S3upload.java
IoTConsumer.java
This function can be deployed as a Lambda function, as shown in Chapter 2.
You can find a sample execution and the outcomes on GitHub at https://github.com/banup-kubeforce/AWSIots3-V2.git.
In this section, you were able to deploy AWS IoT Greengrass locally, deploy a local Lambda function with Spring Cloud function code, publish data to the cloud, and store the data into S3 with another Spring Cloud function.
This is straightforward, as AWS has Java-based SDKs to help build the Spring Cloud Function clients. You also learned that you can deploy Lambda functions locally.
This is the same use case as in the prior example, where an automotive assembly plant wants to ensure that its robots are performing well. The data from the sensors needs to be collected and analyzed for anomalies. Each assembly plant is walled off from the public Internet through firewalls.
The solution with Azure is very similar to the one you saw with AWS Greengrass. You need a way to get the device information from the plant floor, analyze it, and respond to it with an action within the plant floor, and then send the data to the cloud for further processing. Actionable insights are made closer to the devices.
Azure IoT Edge Device
Azure IoT hub
Spring Cloud Function running on Azure Functions environment and deployed on the Azure IoT Edge
Azure Blob store to store data in the cloud

A diagram of azure I o T edge device has azure I o T edge runtime that connects to 3 modules telemetry, insight, and action. Telemetry includes temperature and pressure. Insight includes azure streaming analytics and azure M L. Action includes spring cloud function and azure functions.
Azure IoT Edge Device implementation
This hub is a managed service offering from Azure that allows you to collect data from IoT devices and send them to other Azure services for further processing. This is an IoT gateway where you can connect and manage your devices through a single portal. More information can be found at https://docs.microsoft.com/en-us/azure/architecture/reference-architectures/iot.
Spring Cloud Function will be deployed on the Azure IoT Edge devices. Azure IoT Edge allows for deployment of containerized functions. More information can be found at https://learn.microsoft.com/en-us/azure/iot-edge/tutorial-deploy-function?view=iotedge-1.4.

A flow diagram has 2 modules. In the automotive assembly plant module, sensors send data to azure I o T edge device by T C P I P. The data is then sent via the plant firewall, to the azure cloud module, which has components, azure I o T hub, spring cloud function azure functions environment, and azure blob store.
Manufacturing plant processing using Azure and Spring Cloud Function
Let’s implement this solution.
VS Studio Code configured for Spring Boot, as this has a very good integration with Azure IoT
Azure Container Registry to store your containerized Spring Cloud Function
Code from GitHub at https://github.com/banup-kubeforce/AzureIoTSimulator.git
Azure IoTEdge and Azure IoTHub set up and configured
Step 1: Install an Azure IoT Edge device. You can follow the instructions at https://docs.microsoft.com/en-us/azure/iot-edge/quickstart-linux?view=iotedge-2020-11 to enable either a Windows or Linux device.
Step 2: Connect the device to Azure IoT. Since you cannot deploy the Azure Stack hub, it is best to use an Azure IoT hub on the web.
You can enable it on the Azure Portal. More information on how to configure your edge devices to connect to the IoT hub is available at https://docs.microsoft.com/en-us/azure/iot-edge/quickstart-linux?view=iotedge-2020-11.

A screenshot of a Microsoft azure portal. The I o T hub subscription page is selected. The management tab has headings, scale tier and units, and role-based access control with options under them. Other tabs on top are basics, networking, tags, and review plus create.
IoT hub subscription in Azure Portal
Step 3: Create a Spring Cloud Function and deploy it on Azure IoT Edge.
This code is available at https://github.com/banup-kubeforce/AzureIoTSimulator.git.
You can create a Spring Cloud Function that sends information from the edge device to the IoT hub. Make sure you have the connection string that you created in Step 1.
Step 4: Deploy the function into Azure Function on the edge devices.
You will have to containerize the function as discussed in Chapter 2. Instead of pushing to Dockerhub, you have to push it to Azure Container Registry. Information on Azure Container Registry is available at https://azure.microsoft.com/en-us/products/container-registry/.
Create a deployment for a single device.
Select deployment.amd64.jso in the config folder. Click Select Edge Deployment Manifest.
Expand the modules to see a list of deployed and running modules. See Figure 6-8.

A flow diagram. The development machine stage connects to the azure cloud function, which in turn deploys to the I o T edge device function. The azure I o T edge runtime uses the sensor and function and sends insights back to the azure cloud I o T hub.
Azure function deployment on the IoT edge devices using Azure IoT Edge runtime Source: https://learn.microsoft.com/en-us/azure/iot-edge/media/tutorial-deploy-function/functions-architecture.png?view=iotedge-1.4
This section showed that you can take the same use case of the manufacturing assembly plant and sensors and apply an Azure IoT solution to it.
You created a Spring Cloud Function and deployed it to Azure IoTEdge using the Azure Function. Detailed information is provided on GitHub at https://github.com/banup-kubeforce/AzureIoTSimulator.git.
You also learned that you can use the Azure IoT Edge devices with Azure IoT Edge runtime to collect data from sensors. This is very similar to how it is done in AWS.
Enterprises that do not want to use any of the cloud provider’s IoT components can offload the collection of sensor data to third-party companies. These third-party companies can then send the data as streams or a batch it to systems that are hosted within the enterprise's datacenter.

An illustrated diagram. The fleet management sends G P S and vehicle Information via a cell tower to a third-party cloud I o T gateway. The gateway triggers a spring cloud function to send data to the Kubernetes platform, which is either on OpenShift or V M ware Tanzu.
Fleet management example
Components Description
- A table with 5 rows and 2 columns. The column headers are components and descriptions. Components are the third-party I o T gateway providers, Kubernetes platform on-premises, spring cloud data flow, spring cloud functions on knative, and S 3 bucket hosted in the data center. |
Third-party IoT gateway providers such as Michelin, Erickson, Samsara, and so on
Kubernetes platform on-premises such as OpenShift or VMware Tanzu
Spring Cloud Data Flow
S3 bucket hosted in the datacenter, like Minio or Ceph
Spring Cloud Function on Knative
Step 1: Contact your third-party provider to get the information about their IoT hub. Since the work of acquiring the sensor data is offloaded to third-party providers, you can assume that data will be accumulated and routed to the third-party cloud from the vehicles.
Once the data is accumulated at the third-party gateway, it gets routed to the company's datacenter via an invocation of a function.
Install Spring Cloud Data Flow in a Kubernetes environment like OpenShift or VMware Tanzu
Create a Spring Cloud Data Flow data pipeline.

A screenshot of a spring cloud data flow window. The streams tab is selected. Create stream is the page header. A search option is next to a data pipeline with blocks rabbit, transform, and s 3. The cancel and create stream buttons are below.
Spring Cloud Data Flow
This example uses RabbitMQ as the source and S3 Minio/Ceph as the sink.
Step 3: Publish to RabbitMQ. See Chapter 4 for details of publishing to RabbitMQ.
Step 4: Deploy the Spring Cloud Function on Knative, as you did in Chapter 2, and expose a public endpoint for the IoT gateway to connect.
This completes the implementation of an on-premises solution that uses a third-party IoT gateway. You can leverage the serverless environment, just like AWS Lambda or Azure Functions. Knative on Kubernetes provides that serverless environment to run the Spring Cloud Function.
You leveraged Spring Cloud Data Flow as the data pipeline to collect and process the sensor data.
More information on the project is available at https://github.com/banup-kubeforce/onpremIoT.git.
As you learned in this chapter, you can build IoT-based solutions using Spring Cloud Function, both in an on-premises environment, and as well as in AWS and Azure.
Spring Cloud Function is one of the most versatile frameworks in the Java world. It can be deployed on proprietary cloud-based serverless environments and on Knative, making it a very portable component.
Whether it is a manufacturing plant walled off from the public Internet or on the road with fleet management, you can build secure and reliable solutions with Spring Cloud Function.
This chapter explores some of the industry-specific implementations of Spring Cloud Function.
It leverages the IBM Cloud offering to demonstrate that Spring Cloud Function is supported on any cloud offering.
Some of the examples in this chapter are real-world scenarios in which functions play a critical role. For example, a function that sends alarms about pipeline leaks and a chat function that helps customers solve problems.
This section looks at how Spring Cloud Function can be used in the context of natural gas pipelines.
Miles and miles of gas pipelines need to be constantly monitored for leaks, cracks, temperature fluctuations, and pressure issues in order to avoid costly breakdowns in the transmission of gas and to avoid explosions.

A schema of implementation of gas pipeline. It includes a Gas pipeline, sensors, I o T gateway, cellular network, M Q T T, and a monitoring dashboard.
Gas pipeline IoT implementation
Components for an Example Solution
Sensor | The Preferred Sensor |
|---|---|
IoT Gateway | Your preferred gateway product |
IBM Cloud Functions | |
IBM Watson IoT Platform | |
IBM Watson IoT Platform – Message Gateway | |
IBM Event Streams | |
IBM Cloudant DB |
There are multiple parameters that need to be measured and tracked when monitoring the health of a pipeline. This data can be categorized into asset and external data.
Asset data can include pressure, flow rate, wall thickness, and cracks. External data can include temperature, humidity, pH levels, and soil resistivity. Smart sensors can be installed along the length of the pipeline to transmit information to a nearby IoT gateway.
These devices act as sensor data aggregators and send the acquired data to receiving systems like the Watson IoT platform. They also allow the Watson IoT platform to connect and manage sensor devices. There are many cloud-ready gateways in the market.
These cloud-ready gateways allow for connectivity to different cloud platforms, including Azure, AWS, the Watson IoT platform, and so on.
IBM Cloud offers serverless cloud functions that can be either scripted on the web-based console or deployed on Docker containers. If you are developing in Java and dotnet, you need to use the Docker option. Alternatively, Knative on Kubernetes is offered as a way to deploy Spring Cloud Function with Docker images. More information is available at https://www.ibm.com/cloud/functions.
This product from IBM also allows you to set up and manage connected devices. It has a dashboard that offers device management, MQTT support, data lifecycle management, and secure communication with TLS for MQTT. More information is available at https://www.ibm.com/cloud/internet-of-things.
IBM Message Gateway receives the message that IoT sensors send and sends it to platforms such as IBM Event Streams.
More information is available at https://www.ibm.com/docs/en/wip-mg.
This is based on Apache Kafka and allows for managing streaming event data coming from the IBM Watson IoT platform. More information is available at https://www.ibm.com/cloud/event-streams.
This is a fully managed distributed database that allows for storing data from the IBM Watson IoT platform. You can find more information at https://www.ibm.com/cloud/cloudant.

A flow model of data sensor. The sensor sends information to the I B M cloud via M Q T T, event streams, and the spring cloud function. Finally, it is stored in a database.
Use case for sensor data consumption flow
Figure 7-2 shows the flow that this example plans to achieve.
The focus is on creating a Spring Cloud Function that receives the message published to a topic called "Sensor-topic” in event streams and stores it into the Cloudant DB.
Step 1: Register with IBM Cloud and subscribe to Watson IoT platform.
You can start at https://www.ibm.com/cloud/internet-of-things and click Get Started to start the process.

A screenshot of the window titled I B M cloud Watson. It consists of the I o T platform application with a Create option. It has to select a location, select a pricing plan, and configure your resource.
IBM Cloud Watson IOT
Step 2: Add devices that need to be monitored.

A screenshot of the window titled I B M Watson I o T platform. It has an add device page with Identify, device type and device I D options.
Add Device page

A screenshot of the Watson I o T platform window. It has a browse device application to add devices and applications consisting of device ID, status, device type, class ID, address, and locations.
Add devices on the Watson IoT platform
Step 3: Subscribe to the IBM event streams.

A screenshot of I B M cloud window with event streams. It has to Create, a platform, public cloud, satellite, location, ad select pricing plan options.
IBM Cloud event streams
You then stipulate where you want to run the event stream—on a public cloud or satellite, as well as the cloud instance location. Then select your pricing plan (the Lite option is free), give it a name, and assign a resource group. You can also provide some identification tags. This will create the event stream.
Step 4: Create a topic with the required parameters.

A screenshot of the event stream dashboard. It selects the topics with options of name, partitions, retention time, retention size, and cleanup policy.
Create event stream
Step 5: Deploy a function to IBM Cloud.
This step does not use the IBM Cloud functions that come out of the box. You can use the IBM Kubernetes services to build and deploy your Spring Cloud Function on a Knative service. You can get to the IBM Kubernetes service by searching the IBM Cloud or catalog or by going directly to https://cloud.ibm.com/kubernetes/catalog/create.
Now create a bare minimum cluster that is free. This is what I like about the IBM Cloud; you are really getting a free service even for a Kubernetes cluster. This is unlike other cloud providers, where you must pay for the underlying compute and storage.
If you are creating a free cluster, be aware that this cluster will be deleted after 30 days.

A screenshot of the I B M Kubernetes cluster dashboard. It has options of create, plan details, Kubernetes version, and resource details.
Subscribe to IBM Kubernetes

A screenshot of the I B M cluster dashboard. Overview with the details, node health is included.
Successful creation of the cluster

A set of instructions after creating the cluster. It has 3 steps to connect to the cluster which include login, setting the context, and verifying. At the bottom, it has a tip.
Some boilerplate instructions after creating the cluster

A screenshot image of running the command to connect to the cluster.
Your kubectl is configured to connect to the cluster

A screenshot of a command to be run to set the context to the Kubernetes cluster.
Establish the connection to your cluster

A screenshot to run the command to install Knative c r d s. 12 configurations appeared in the console.
Knative crds are created

A screenshot to run the command for installing the Knative serving core.
Knative serving core is deployed

A screenshot to run the command for Istio installation. It has 2 highlighted texts among multiple components.
Istio is successfully deployed

A screenshot to run the command to construct network components.
Network components of Istio are created

A screenshot of running the command to install Magic D N S.
Default domain (Magic DNS) created

A screenshot of the running of Knative components. It has the name, ready, restarts, and age as column labels.
Knative components are running
Once the status is Running, you can deploy Spring Cloud Function.
Step 6: Create a Cloudant database. Navigate to your subscription on the IBM Cloud and click Create Resource. Search for Cloudant.

A screenshot of the window titled I B M cloud. It displays a resource list of the name, group, location, product, status, and tags as column labels.
IBM Cloud resources

A screenshot of the I B M cloud's Cloudant-p 5. It includes the overview, capacity, and docs as column labels. The overview includes deployment details.
IBM Cloud Cloudant specs

A screenshot of the I B M cloud. It displays the Cloudant database with database creation options and the format of the database indicated by an arrow.
Cloudant DB
Step 7: Create a Spring Cloud Function to connect to the event streams and Cloudant DB. You can download it at https://github.com/banup-kubeforce/IBMIoTV2.
Dependencies
Cloudant and IBM Event Streams Configuration
CloudantConsumer.java
CloudantConnector.java
EventStreamsSupplier.java (See GitHub for the Latest)
The EventStreamsSupplier function connects to the IBM event streams and gets the data in the sensors-topic. It then stores this data in the Cloudant sensordb.
Step 8: Deploy the Spring Cloud Function to Knative on the Kubernetes cluster. Refer to Chapter 2 for deploying Spring Cloud Function on Knative.

A screenshot of the output of the program event streams supplier function running locally.
Running the EventStreamsSupplier locally

A screenshot of the sensor D B program. It selects the database option with save changes. It has options to upload an attachment, clone the database and delete.
IoT data stored in CloudantDB
This section explored the world of IoT from an IBM Cloud and IBM Watson IoT perspective. Figure 7-24 shows the various components of the IoT platform that were covered.
You also saw that you can build functions with Spring Cloud Function and deploy them on IBM Cloud on Kubernetes.

A flow diagram of Watson's end-to-end flow. Context starts from I o T devices leading to Watson I o T platform service, Event streams, and dashboard. Finally leads to customer systems, app developer architect, and I B M cloud.
Watson IoT context

A schema of healthcare context has circles with big data. The central part has aggregation, analysis, and action flowing from the top to the bottom. The aggregation is further connected to other components.
Healthcare context Source: https://www.researchgate.net/publication/330249318/figure/fig1/AS:713182909829120@1547047464835/Conceptualizing-big-data-in-healthcare-Health-system-data-are-aggregated-with-data.png (Creative commons license https://creativecommons.org/licenses/by/4.0/)
The use case here is that a patient walks into a hospital complaining of a pain in the back, near the spine. The pain has been persistent and they want a quick diagnosis.
The patient is admitted into the hospital by means of a patient portal and check-in process.
Initial patient analysis is done using EHRs and patient-provided information, such as quality of life, pain, expectations, and so on.
The doctor recommends imaging and laboratory tests.
The patient is provided with a smart wearable that tracks their movement in the hospital.
Once the imaging, laboratory tests, and other pertinent information comes in, the doctors use their smart AI diagnostic portal to diagnose possible conditions.
The doctor informs the patient of the diagnosis.
Patient portal for intake of patient information (data acquisition)
Intake and aggregate patient surveys and patient history (data aggregation)
Labs and imaging (image data)
Diagnosis (data analysis and AI recommendations)
Smart wearables (IoT streaming data)

A schema to depict the spring cloud function application. It has 5 components listed patient portal, initial patient analysis, labs and imaging, diagnosis, and smart bands and devices. Icons related to these components are beside.
Applications of Spring Cloud Function in the various healthcare flows
AI and retail are inextricably tied at the hip. Humans enjoy shopping, mall strolling, online shopping, and just online browsing. They constantly encounter AI by way of targeted advertising, product recommendations, and product placements. Many of these features are run by robots. This means that AI and retail are converging.
Based on Fortune business insights, the retail AI market is expected to reach $19.9 billion by 2027, with a growth rate of 34.4 percent from 2020 to 2027 (Source: https://www.meticulousresearch.com/product/artificial-intelligence-in-retail-market-4979).
Predictive analytics using Big Data
Demand forecasting
Visual searching
Recommender systems
Chatbots
Augmented reality
Brand management
COVID-19 changed the way that AI interacted with retail. AI powered by chatbots rose to prominence.
Chatbots—or conversational AI—in fact became the AI interface for retail. Most communication with a product or support team is initiated using an AI interactive session. Better customer experience through these chatbots is of paramount importance to retailers. If the chatbots were bad, the customer would move on to another retailer. So brand management, recommendations, predictions, and forecasting all relied on how the chatbot interacted with the customers and if it extracted the right information to provide the customers with the best experience.
IBM, AWS, Azure, Google, and other cloud providers focused their attention on capturing the conversational AI market, as every retailer was clamoring for an edge with these customer interactions.
You will look at how IBM approached conversational AI and at how Spring Cloud Function plays a role in connecting systems with people.
The IBM conversational AI offering includes a wide array of products on the IBM Cloud and on cloud paks. Cloud paks are software that can be deployed to any cloud.
IBM Cloud provides both generic Kubernetes and Red Hat OpenShift Kubernetes, while the cloud paks are offered on Red Hat OpenShift. Spring Cloud Function can be deployed on any Kubernetes offering.

A schema of artificial intelligence conversational concepts. It has data sources, conversational artificial intelligence processing, conversation channels, and outcomes. All these have sub-components.
Conversational AI concept

A schema of artificial intelligence conversational system. It starts with conversational endpoints, then to EDGE services, I B M cloud, and to the user. The I B M cloud has components associated with it.
Conversational AI systems view
Edge services
Edge services allow the flow of data on the Internet. These services include DNS, CDNs, firewalls, load balancers, and so on.
IBM Watson Assistant
Watson Assistant enables you to create virtual agents and chatbots that combine machine learning, natural language processing, and graphical tools to design your conversational flows. Additional information is available at https://www.ibm.com/products/watson-assistant.
IBM Watson Discovery Services
Watson Discovery Services helps you ingest, parse, index, and annotate content. The ingested data can come from internal and external data sources. Additional information is available at https://www.ibm.com/cloud/watson-discovery.
Watson Speech to Text
Watson Speech to Text converts voice to text. Additional information is available at https://www.ibm.com/cloud/watson-speech-to-text.
Spring Cloud Function deployed on Knative on OpenShift (IBM Cloud)
Spring Cloud Function can be deployed on OpenShift in the IBM Cloud. Knative has to be configured on OpenShift. This process is outlined in the Knative deployment discussion throughout this book.
DB2 on cloud
This is a fully managed SQL database on the cloud. Information about DB2 on cloud can be found at https://www.ibm.com/cloud/db2-on-cloud.
Cloudant DB
This is a fully managed distributed database ideal for web and mobile apps and storing IoT or mobile data. More information can be found at https://www.ibm.com/cloud/cloudant.
Once you create and deploy a Spring Cloud Function, you need to be able to call it from the Watson Assistant. This can be done by means of Webhooks.
The call must be a POST HTTP request. You can use your consumer function here.
The request body must be a JSON object (Content-Type: application/json).
The response must be a JSON object (Accept: application/json).
The call must return in eight seconds or fewer. This is an important requirement and can easily be met with Spring Cloud Function.
Step 1: Write the Spring Cloud Function code. The Watson Assistant requires an OpenAPI specification. Add the code in this section to your Pom.xml file.
Open API Dependencies to Connect to the Watson Assistant
inventory.java
InventoryConsumer.java
InventoryFunction.java
InventorySupplier.java
Deploy this code into an IBM Kubernetes Knative instance, as shown in Chapter 2 for Knative.
This code will now have an OpenAPI definition. This will allow the Watson Assistant to communicate with your function You can use this to configure the custom extensions in the Watson Assistant.
Tell the user what Apple products are available.
Tell them how many iMacs are in stock.
Log in to the IBM Cloud (http://cloud.ibm.com).

A screenshot of the I B M cloud dashboard. It has different options including building a dashboard, resource summary, planned maintenance, and I B M cloud status.
IBM Cloud dashboard
Sign up for the Watson Assistant and create an instance.
You can arrive at the Watson Assistant dashboard by searching the IBM Cloud portal or using this link https://cloud.ibm.com/catalog/services/watson-assistant.

A screenshot of I B M cloud with Watson assistant signup page. It has different options including the plan, features, and pricing details.
The Watson Assistant signup page
Create and personalize your assistant.

A screenshot of the create your first assistance page. It has options to enter the assistant name, description, and language.
Create your assistant
Choose your options. You will be provided a preview of the chat window.

A screenshot of the personalize your assistant creation. It has options to choose the instance where the assistance needs to be deployed and other options.
Create an assistant with a template

A screenshot of the Watson Personalize your assistance page. It has the option to personalize the assistant with Facebook and tell us about yourself.
Assistant with a Facebook template

A screenshot of the home page of the new Watson assistant. It has the option to get started and to create a conversation.
The assistant has been created successfully
Create an action.
Create an action that helps you to interact with the customers. You can do this by choosing Create Your First Action under the Create a Conversation section of the page. You can choose to use a template or create this from scratch.

A screenshot to create your action. It highlights the text and the steps to create action. The steps are set by the assistant, name, choose to start from scratch, choose options, and fill in options 1 and 2.
Flow of activities to create your action

A screenshot of the Greet customer page. It has options to create an action in 2 steps by selecting the options available.
Create an action

A screenshot of the I B M Watson assistant page. It has options for home, actions, preview, publish, environments, and analyze.
Add an integration to support calling the Spring Cloud Function
Build a custom extension.

A screenshot of the Watson assistant page. It displays the Integration catalog with the option to build custom extensions.
Build a custom extension from the integration catalog

A screenshot of the I B M Watson assistant page. It displays the custom extension page with options to enter the basic information.
Provide the custom extension information

A screenshot of the I B M Watson assistant. It displays the custom extension page with options to review extensions including servers and operations.
Add Open API URL for the deployed Spring Cloud Function

A screenshot of the I B M Watson assistant. It displays the extension setup page with check inventory in extensions and inventory supplier in operations tabs.
Apply the custom extension

A screenshot of the I B M Watson assistant. It displays the completed custom extension page with a confirmation that step 1 is taken without condition.
The custom extension is available for the action
You can now can retest your chat interface by going back to the chat that you created.
See GitHub at https://github.com/banup-kubeforce/Watson-imacs.git for additional information. Deploy the code in your environment and integrate. This is a fun exercise.
This chapter looked at some real-world use cases and deployed Spring Cloud Function in IBM Cloud.
This demonstrates the true "write once, deploy anywhere" capability of Spring Cloud Function.
The chapter also looked at what IBM Cloud has to offer. IBM Cloud is versatile and has many products that have been built and optimized over the years. You saw how IBM Cloud can be used in the oil and gas, healthcare, and retail markets.
There are many other use cases in which you can apply Spring Cloud Function, and it can be an alternative to a microservices architecture or can coexist with one. The decision to use functions over microservices needs to be carefully analyzed for cost, scalability, and performance before deciding on an approach.