Azure Functions with supersonic Java
Tags: java, azure, quarkus, maven
Published: 2021-04-09 08:59:22

---
title: Azure Functions with supersonic Java 
published: true
description: Java is not dead and it is keeping up with the tendencies. Going serverless with Java became easier with the Quarkus framework. 
tags: #java #azure #quarkus #maven 
//cover_image: https://direct_url_to_image.jpg
---

#Intro

Serverless is becoming an alternative way of creating and deploying some types of services due to the fast delivery and cost-efficient project management [1]. The way that serverless applications work allows for high availability with a cost-efficient delivery by “turning ON“ our application only when it is being requested and thus saving resources on “dead“ hours.

Java, as it was until recently, wasn’t adequately fit to handle fast boot-ups (needed to wake up the application) and low resource consumption (yes, serverless doesn’t mean there is no server. There is a server and one must pay for it and the resources it uses). 

This is where Quarkus and Microprofile [3;4] come to the rescue allowing for a serverless service fully built on Java.

Function as a Service (FaaS) “is an event-driven computing execution model where developers write logic that is deployed in containers fully managed by a platform, then executed on demand.” [5]

#Prerequisites

1. Azure subscription and The Azure CLI
2. Java JDK 7, 8, 11, 13, 15
3. Maven v3
4. A pinch of programming skills 

#Sample Application

We start off by having to have a service to deploy that fits the need for it to be FaaS [1;5]. For the sake of simplicity, this example will be a basic service where there is a 1-minute timer that reads an in-memory database (DB) and increments a row with the current timestamp. It should also provide a way of getting this information so it will have a microservice with an HTTP GET operation.

## Time to replicate

Assuming you already have an Azure subscription it is expected to replicate this example in less than one hour.

## Download Code Base

Access https://code.quarkus.io/ and start selecting the options and dependencies needed. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xg3ltprmzhjjwp7tdsz1.png)

Group | com.example

Artifact | quarkus-functions-sample

Build Tool | Maven

Version | 1.0.0-Snapshot

Then we choose what dependencies we will need, do not worry if you miss dependencies here because you can always add them later. 

So, for now, we know that we want azure functions, and we will need to create a REST service. Let’s also check if there is something for the timer as well. Let's start typing in the dependencies: 

For REST, we choose RESTeasy JAX-rs

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j0r3eko9xfcpxndb6fai.png)

For Azure functions, we type “functions” and select the “Azure functions HTTP“

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x966ndq8qe8s99qw1iu7.png)

And let's try the scheduler for the timer

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l3qmycgx78pgqswaahuf.png)

Last we also select the dependencies for the in-memory database.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uz4mexm9s2ppssny0xil.png)

Finally, we download the application (notice that they provide articles for you to read based on the selected dependencies )

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f8b35g4e9lprpv7jttai.png)
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7y46ramo795vfcqkhu6c.png)

We can see that there are many things configured therefore our job will be to code mostly

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uw9co6ipkarsb1xay5xz.png)

# Hands-On

We start off by configuring the database, and the entities to access the data.

in the file:

`src\main\resources\application.properties`

add the following code:
```
quarkus.http.root-path=/api
quarkus.package.type=uber-jar
quarkus.datasource.db-kind=h2
quarkus.datasource.username=sa
quarkus.datasource.password=sa
quarkus.datasource.jdbc.url=jdbc:h2:mem:public;MODE=PostgreSQL
quarkus.hibernate-orm.database.generation=drop-and-create
```

And create a file [src/main/resources/import.sql] with the initial data:

```
INSERT INTO quafun
(id, current)
VALUES(1, '1615195937');
```

Check that you have all of these dependencies:

### pom.xml
```
<dependencies>
		<dependency>
			<groupId>io.quarkus</groupId>
			<artifactId>quarkus-azure-functions-http</artifactId>
		</dependency>
		<dependency>
			<groupId>io.quarkus</groupId>
			<artifactId>quarkus-resteasy</artifactId>
		</dependency>
		<dependency>
			<groupId>io.quarkus</groupId>
			<artifactId>quarkus-resteasy-jsonb</artifactId>
		</dependency>
		<dependency>
			<groupId>io.quarkus</groupId>
			<artifactId>quarkus-scheduler</artifactId>
		</dependency>
		<dependency>
			<groupId>io.quarkus</groupId>
			<artifactId>quarkus-arc</artifactId>
		</dependency>
		<dependency>
			<groupId>io.quarkus</groupId>
			<artifactId>quarkus-junit5</artifactId>
			<scope>test</scope>
		</dependency>

		<!-- Hibernate ORM specific dependencies -->
		<dependency>
			<groupId>io.quarkus</groupId>
			<artifactId>quarkus-hibernate-orm-panache</artifactId>
		</dependency>

		<!-- JDBC driver dependencies -->
		<dependency>
			<groupId>io.quarkus</groupId>
			<artifactId>quarkus-jdbc-h2</artifactId>
		</dependency>
	</dependencies>
```

On the java side we need a JPA entity and a repository to manage the data and an API class:

### Quafun.java
``` 
@Entity(name = "quafun")
public class Quafun {

  @Id
  private long id;
  private String current;
  
  public Quafun() {
  }

  public Quafun(long nextLong, long currentTimeMillis) {
    this.id = nextLong;
    this.current = "" + currentTimeMillis;

  }

  public long getId() {
    return id;
  }

  public void setId(long id) {
    this.id = id;
  }

  public String getCurrent() {
    return current;
  }

  public void setCurrent(String current) {
    this.current = current;
  }

}
```

### QuafunRepo.java

```
@ApplicationScoped
public class QuafunRepo implements PanacheRepository<Quafun> {

}
```

A controller for the REST interface

### QuafunController.java 
```
@Path("/quarkus-function")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class QuafunController {
  private static final Logger LOGGER = Logger.getLogger(QuafunController.class.getName());

  @Inject
  QuafunRepo repo;

  @GET
  public List<Quafun> getAll() {
    LOGGER.info("[RETRIEVE-OPERATION] Get All Data");

    return repo.findAll().list();

  }
}
``` 

And a Scheduler to do an operation regularly. 

### QuafunScheduler.java 

```
@ApplicationScoped
public class QuafunScheduler {
  private static final Logger LOGGER = Logger.getLogger(QuafunScheduler.class.getName());

  @Inject
  QuafunRepo repo;

  @Scheduled(every = "1m")
  @Transactional
  void updateRepo() {
    LOGGER.info("[AUTO-OPERATION] Scheduller called");
    Quafun quafun = new Quafun(new Random().nextLong(), System.currentTimeMillis());
    repo.persist(quafun);

  }

}
```

#Beam me Up

The next step is to deliver our application to the cloud. There are several ways of achieving this, like terraform for example here [6], but for the sake of simplicity, this example will use Maven to deploy to Azure.

## Link Maven to Azure

As we selected “Azure Functions HTTP“ for dependencies much of the needed information will be already placed in our pom.xml : 
```
...
<properties>
		<azure.functions.maven.plugin.version>1.3.2</azure.functions.maven.plugin.version>
		<compiler-plugin.version>3.8.1</compiler-plugin.version>
		<function>greeting</function>
		<functionAppName>${artifactId}-<####INSERT-UUID_HERE####></functionAppName>
		<functionAppRegion>westus</functionAppRegion>
		<functionResourceGroup>java-functions-group</functionResourceGroup>
...
```

## Deploy

Deploying is the easy part! We need to be logged in! Past this into a command line: 

`az login`

and then we just tell our application to deploy itself: 

`mvn clean install azure-functions:deploy`

if everything went fine we have : 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tn4qqttxqrowz00tvljz.png)

And we may test it by calling the URL:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nwzsec5c7k3lozez0oko.png)

And watching the metrics and check our logging messages:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7a3vrf31x1dx54rcyxyx.png)

```
2021-03-31T11:04:04.514 [Information] INFO: [RETRIEVE-OPERATION] Get All Data
...
2021-03-31T11:04:33.017 [Information] INFO: [AUTO-OPERATION] Scheduller called
```

# Happy coding!

From here on we are able to create and deploy functions with the full potential of  Java. 

Another topic to consider for functions and Java is the Funqy HTTP [7] which provides less overhead for functions.

\#Koerber

#Refs

[1] https://www.thoughtworks.com/radar/techniques/serverless-architecture

[2] https://docs.microsoft.com/en-us/azure/developer/java/eclipse-microprofile/deploy-microprofile-quarkus-java-app-with-maven-plugin

[3] https://quarkus.io/

[4] https://microprofile.io/

[5] https://www.redhat.com/en/topics/cloud-native-apps/what-is-serverless?sc_cid=7013a0000026GRyAAM&gclid=CjwKCAiA65iBBhB-EiwAW253W-6QT-UZ2rkqC5FPUVKxXR3Xr4FOrTAi_KYt8ROWySeb9JshOvEm6hoCTJQQAvD_BwE&gclsrc=aw.ds.

[6] https://www.maxivanov.io/deploy-azure-functions-with-terraform/

[7] https://quarkus.io/guides/funqy-http