As a follow up after the vacations on the post Vert.x native image awesomeness!, I got some Twitter challenge about what about serverles?

This led to a couple of discussions and catching back with some interest on the OpenFaaS project. From here to create a simple template was just a couple of minutes.

So what is interesting about this? Well first the fact that we can use Java as a viable platform to write Functions . Functions are by definition, small units of code and easy to write. Given that Vert.x is a light framework making a function was a piece of cake!

OpenFaaS

From the OpenFaaS site you can read:

Run functions anywhere with the same unified experience - bring your laptop, your own on-prem hardware or create a cluster in the cloud. Pick Kubernetes or Docker to do the heavy lifting enabling you to build a scalable, fault-tolerant event-driven serverless platform for your applications.

The template

In order to run the example and template all you need is to setup your environment and install the faas-cli tool. For this I’d recommend you to read the nice docs on OpenFaaS.

Once the setup is complete we can start playing with Vert.x and Graal as a Function:

Get the template

The first step is to get the template, for this you need to run:

$ faas-cli template pull https://github.com/pmlopes/openfaas-svm-vertx Fetch templates from repository: https://github.com/pmlopes/openfaas-svm-vertx 2018/09/07 11:59:02 Attempting to expand templates from https://github.com/pmlopes/openfaas-svm-vertx 2018/09/07 11:59:05 Fetched 1 template(s) : [vertx-svm] from https://github.com/pmlopes/openfaas-svm-vertx

You should see some output similar to the listing above. Now that you have the template locally we can create our first function:

$ faas-cli new callme --lang vertx-svm Folder: callme created. ___ _____ ____ / _ \ _ __ ___ _ __ | ___|_ _ __ _/ ___| | | | | '_ \ / _ \ '_ \| |_ / _` |/ _` \___ \ | |_| | |_) | __/ | | | _| (_| | (_| |___) | \___/| .__/ \___|_| |_|_| \__,_|\__,_|____/ |_| Function created in folder: callme Stack file written: callme.yml

As this moment OpenFaaS just created the skeleton project for you, you can inspect it:

tree callme callme ├── pom.xml ├── README.md └── src └── main ├── java │ └── MyFunction.java ├── resources │ └── META-INF │ └── services │ └── xyz.jetdrone.openfaas.vertx.OpenFaaS └── svm └── reflection.json 7 directories, 5 files

As you can see it’s a trivial maven project with a single source file MyFunction.java . A close look at the source file you will find the code:

import io.vertx.ext.web.RoutingContext ; import xyz.jetdrone.openfaas.vertx.OpenFaaS ; public class MyFunction implements OpenFaaS { public MyFunction () { System . out . println ( "Loaded MyFunction!" ); } @Override public void handle ( RoutingContext ctx ) { ctx . response (). end ( "Hi!" ); } }

The constructor is optional so we could make the function even more minimal with:

import io.vertx.ext.web.RoutingContext ; import xyz.jetdrone.openfaas.vertx.OpenFaaS ; public class MyFunction implements OpenFaaS { @Override public void handle ( RoutingContext ctx ) { ctx . response (). end ( "Hi!" ); } }

If you were paying attention, there isn’t anything new here, the function is in fact a vertx-web handler, so you don’t need to learn a new framework to get into serverless. But one might ask why the need for a OpenFaaS interface then? The reason is because the entry point application will use Service Loaders to load any available implementations of the marker interface and will add them all to the server.

Build the function

$ faas-cli build -f callme.yml ... Successfully built f5e1266b0d32 Successfully tagged callme:latest Image: callme built.

The template will use a Dockerfile that will perform all the heavy work, grab a coffee until you’ll see the message above.

Deploy the function

$ faas-cli deploy -f callme.yml Deploying: callme. No existing service to remove Deployed. 200 OK URL: http://localhost:8080/function/callme

You can verify it using the web frontend usually running at http://localhost:8080 and it should look more or less like this:

Play with it

Either cURL , httpie or use your browser at http://localhost:8080/function/callme .

http http://127.0.0.1:8080/function/callme HTTP/1.1 200 OK Content-Length: 3 Content-Type: text/plain; charset=utf-8 Date: Fri, 07 Sep 2018 12:54:03 GMT X-Call-Id: a2978cfb-33de-48aa-bc1e-75d370834e87 X-Start-Time: 1536324843677727462 Hi!

Have fun!

Docker stats

So when we start our application and postgres and run docker stats we can see:

CONTAINER ID NAME CPU % MEM USAGE / LIMIT 6889f23e814b func_queue-worker.1.pa37e6ysx20dhfjpcdv9gpite 0.00% 2.496MiB / 50MiB f9025c9ce3ca func_gateway.1.qyvg40lzd60o5xez65y3t8rg3 1.34% 8.898MiB / 15.55GiB a175047e7fe5 callme.1.jbqbp8sd4psz6io1t0uhiq64m 2.49% 7.105MiB / 15.55GiB 40110b24cf82 func_nats.1.7gnn1jpmxe2kepqahrjjdeati 0.06% 5.875MiB / 125MiB cb00f7c89f32 func_alertmanager.1.kcwlcpm1kmq7gpqvy0t91psxa 0.14% 6.922MiB / 50MiB ed196726afbd func_prometheus.1.7vbsnyrytyl9hqu95w8z3ju3d 1.73% 33.34MiB / 500MiB 07dc59c14cf0 func_faas-swarm.1.yeh0xm62rhkebwlhmueqpv47f 0.00% 7.715MiB / 15.55GiB ^C

I’d say that it amazing a complex application running in 7MB of RAM which accounts BOTH for the function AND the watchdog!!!