Spring Cloud function Helloworld on AWS and local!!

In this article, we’ll learn how to use Spring Cloud Function. Serverless function using spring cloud function.

A serverless function is a modern industry buzzword and the reason behind that is boost in cloud computing.

credit goes to gitconnected

As part of this article, We’ll build and run a simple Spring Cloud Function locally and then deploy it to the AWS cloud platform.

Spring Cloud Function is a project with the following high-level goals as per spring cloud official website:

  • 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.

If you could able to understand the above things you will be able to relate things this with any serverless technology by any cloud provider. The reason behind serverless is concentrating on business logic, not on infra and any other things.

Features:

There are below number features spring cloud function provides.

  • Choice of programming styles — reactive, imperative or hybrid.
  • Function composition and adaptation (e.g., composing imperative functions with reactive).
  • Support for reactive function with multiple inputs and outputs allowing merging, joining and other complex streaming operations to be handled by functions.
  • Transparent type conversion of inputs and outputs.
  • Packaging functions for deployments, specific to the target platform (e.g., Project Riff, AWS Lambda and more)
  • Adapters to expose a function to the outside world as HTTP endpoints etc.
  • Deploying a JAR file containing such an application context with an isolated classloader, so that you can pack them together in a single JVM.
  • Compiling strings which are Java function bodies into bytecode, and then turning them into @Beans that can be wrapped as above.
  • Adapters for AWS Lambda, Microsoft Azure, Apache OpenWhisk and possibly other “serverless” service providers.
pivotal

Let us deep dive and do some coding.

We will take one simple example 

  • Convert a String to lower case, using a String method
  • And a HelloWorld greeting message using a dedicated class.

For this example, I am using Maven you can use Gradle as a build tool as well. 

#add spring cloud function dependency
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-function-web</artifactId>
<version>1.0.1.RELEASE</version>
</dependency>

First Spring Cloud Function:

We will expose @Bean of type function using spring cloud function. As part of this code, we are exposing toLowerCase functionality as a spring cloud function.

@SpringBootApplication
public class CloudFunctionApp {
public static void main(String[] args) {
SpringApplication.run(CloudFunctionApp.class, args);
}
@Bean
public Function<String, String> lowerCaseString() {
return value -> new StringBuilder(value).toString().toLowerCase().toString();
}
}

Test this functionality in our local using curl command

curl localhost:8087/lowerCaseString -H "Content-Type: text/plain" -d "Spring cloud FUNCTION"

The endpoint is the name of the bean. here it is lowerCaseString.

Spring Cloud Function in Packages:

In the above we have exposed @Bean as method Apart from this, we could also write our software as classes that implement the functional interface Function<T, R>. We can specify the packages to scan for relevant beans in the application.properties file.

package com.techwasti.spring.cloudfunction.functions;


public class Hello implements Function<String, String> {
@Override
public String apply(String s) {
return "Hello " + s + ", and welcome to Server less world!!!";
}
}

Also as mentioned above add below line in application.properties file

spring.cloud.function.scan.packages=com.techwasti.spring.cloudfunction.functions

We can also test this one in our local

curl localhost:8080/hello -H "Content-Type: text/plain" -d "Maheshwar"

The endpoint is the name of the class that implements the functional interface.

Spring Cloud Function on AWS:

The best thing about the spring ecosystem is seamless adoption and customization. The same applies to Spring Cloud Function, spring cloud function so powerful is that we can build Spring enabled functions that are cloud-agnostic. Spring cloud function provides abstraction API and adapter so that we can build function tests on local and deploy on any cloud provider such as AWS, Azure or Google Cloud platform without changing any of the business logic.

AWS is a popular one so for this exercise we choose AWS. 

Remember we have used above spring cloud function maven dependency we need the same one for this as 

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-function-web</artifactId>
<version>1.0.1.RELEASE</version>
</dependency>
##to handle AWS lambda we need below dependency 
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-events</artifactId>
<version>2.0.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>1.1.0</version>
<scope>provided</scope>
</dependency>

We are going to upload the artifact generated by the maven build to AWS Lambda, we need to build an artifact that is shaded, which means, it has all the dependencies burst out as individual class files instead of jars.

We are adding spring-boot-thin-layout dependency that helps us to reduce the size of the artifact by excluding some dependencies that are not needed.

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot.experimental</groupId>
<artifactId>spring-boot-thin-layout</artifactId>
<version>1.0.10.RELEASE</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>aws</shadedClassifierName>
</configuration>
</plugin>
</plugins>
</build>

If we are shipping our spring cloud function such as lower case String converter to handle this over AWS we need Handler

public class MyHelloWorldHandlers extends SpringBootRequestHandler<String, String> {

}

Spring Cloud Function AWS also ships with SpringBootStreamHandler and FunctionInvokingS3EventHandler as well.

This is just an empty class but it plays a very important role in both acting as an entry point and also defines the input and output types.

How Does AWS lambda Know Which Spring Cloud Function to Invoke?

In our example, if we have more than one spring cloud function How AWS know which one we have to invoke,

Even if we have more than one Spring Cloud Function in our application, AWS can invoke only one of them.

We have to specify the cloud function name in an environment variable called FUNCTION_NAME on the AWS console.

Upload function over AWS and Test:

Now we are ready to upload spring cloud function over AWS.

On the AWS Lambda console page, in the Function code section, we can select a Java 8runtime and simply click Upload. As I mentioned we need to specify handler as well i.e MyHelloWorldHandlers.

And then specify FUNCTION_NAME in environment variable as lowerCaseString.

it’s time for us to test the Lambda spring cloud function by creating a test event and supplying a sample string such as “Spring CLOUD function”, then save it and, then click the Test button. Similar way we can test the “hello” spring cloud function by changing the value of FUNCTION_NAME parameter. 

Spring Cloud Function is a powerful tool for decoupling the business logic from any specific runtime environment.

References:

Introducing Spring Cloud Function
Spring Cloud Function is a new project with the following high-level goals: Promote the implementation of business…spring.io

Spring Cloud Function
Spring Cloud Function features: Choice of programming styles – reactive, imperative or hybrid. Function composition and…spring.io

AWS lambda HelloWorld!!!

AWS Lambda is an event-driven, serverless computing platform provided by Amazon as a part of the Amazon Web Services. It is a computing service that runs code in response to events and automatically manages the computing resources required by that code. It was introduced in November 2014.

Function as a Service — FAAS (Server less)

In this tutorial, we are taking an existing blueprint hello world example to explore lambda. 

AWS Lambda provides you with computing power in the cloud by allowing you to execute code without standing up or managing servers.

AWS Lambda is offer service to run code without thinking about the server and pay only for the compute time you consume.

Topics Covered:-

  • Author a Lambda function using Node.js via the aws management console
  • Test a Lambda function via the aws console

Tips

  • Lambda is found under the Compute section on the AWS Management Console.
  • Lambdas have a time limit of 15 minutes.
  • The code you run on AWS Lambda is called a “Lambda function.”
  • Lambda code can be triggered by other AWS services.
  • AWS Lambda supports Java, Go, PowerShell, Node.js, C#/.NET, Python, and Ruby. There is a Runtime API that allows you to use other programming languages to author your functions.
  • Lambda code can be authored via the management console.

Go to Lambda →Click on create function → in search select Runtime and runtime environment is nodejs you can select what you prefer.

Then select the hello-world blueprint.

Steps:-

  1. Create a Lambda Function:- Enter function name. Execution role select “Choose or create an execution role” 

2. Click on create function:- 

3. Click on the Test button to provide some test data:- provide some test data and click on creat button

Once this is done scroll down, you will see code editor and on top of that “Test” button is there click on it and you will see the result on the console.

This is very basic let us do one thing modify the existing function line no 5 with below line of code and save 

body: JSON.stringify('Hello ' + event.key1 + ' from Maheshwar!'),

Scroll down to the “Basic settings” section.

  • For the Description, enter “My Function”.
  • Change the “TimeOut” from 3 seconds to 5 minutes.
  • Click the “Save” button in the upper right-hand corner.

Now Test your code changes and enjoy!!

FireStore now supports IN Queries & array-contains!!

Firestore with new in and array-contains-any queries.

This is the good news for cloud firestore developers, the pain point they are facing unable to use of ‘in’ operator.

Image result for firestore

Cloud FireStore is NoSQL database built for global apps.

Cloud Firestore is a NoSQL document database that lets you easily store, sync, and query data for your mobile and web apps — at a global scale. Cloud Firestore is a flexible, scalable database for mobile, web, and server development from Firebase and Google Cloud Platform.

The importance of ‘in’ is like a pinch of salt in day to day life.

In Query:

With the in query, you can query a specific field for multiple values (up to 10) in a single query. You do this by passing a list containing all the values you want to search in, and Cloud Firestore will match any document whose field equals one of those values.

in queries are the best way to run simple OR queries in Cloud Firestore. For instance, if the database for your E-commerce app had a customer_orders collection and you wanted to find which orders had a “Ready to ship”, “Out for delivery” or “Completed” status, this is now something you can do with a single query, like so:

collection(“orders”)
.where(
“status”, 
“in”, 
[“Ready to ship”, “Out For Delivery”, “Completed”]
)

one more example:-

citiesRef.where('country', 'in', ['India', 'Japan','CostaRica']);

array-contains-any query:

Firestore launched another feature similar to the in query, the array-contains-any query. This feature allows you to perform array-contains queries against multiple values at the same time.

In your e-commerce site has plenty of products with an array of categories that every item belongs in, and you want to fire a query to fetch products with a category such as “Appliances” or “Electronics” then.

collection(“products”).where(
 “category”,
 “array-contains-any”,
 [“Appliances”,”Electronics”]
)

one more example: 

citiesRef.where('regions', 'array-contains-any',
['west_coast', 'east_coast']);

Note:- These queries are also supported in the Firebase console, which gives you the ability to try them out on your dataset before you start modifying your client code.

Remember:

  • As we mentioned earlier, you’re currently limited to a maximum of 10 different values in your queries.
  • You can have only one of these types of operations in a single query. You can combine these with most other query operations, however.

References:-

https://firebase.googleblog.com/2019/11/cloud-firestore-now-supports-in-queries.html

https://firebase.google.com/docs/firestore/query-data/queries