Spring Support for Dispatch

Nicholas Tenczar
dispatchframework
Published in
4 min readMay 11, 2018

Several weeks ago Dispatch released support for creating Java functions through a new Java base image. If you are interested in Dispatch support for your favorite language see Ivan’s blog on adding a language to Dispatch. In this blog we are going to stick with Java and discuss how we support one of Java’s most popular frameworks, Spring. From its early days as a simple Java/J2EE application framework to the Java developer’s Swiss Army knife, Spring has been used to build lightly coupled, highly cohesive applications. Today we will see how to build these applications in Dispatch.

At its core Spring is a dependency injection / inversion of control container. It manages the lifecycles of the important beans in your application. This includes bean creation and wiring of disparate dependent beans. In a serverless world these facilities are less relevant due to the high level of specificity in serverless functions. A given Dispatch function is unlikely to include more than a dozen beans, which seems hardly worth the overhead of initializing the Spring application context. But Spring can do more than just manage beans; it provides support for aspect oriented programming.

Our simple application will use aspect oriented programming (AOP) to log invocations of our function and track execution time. Developers could use this audit data to isolate bottlenecks, provision more hardware, or improve the efficiency of their function. For this example we won’t focus on the business logic of the function rather we’ll concern ourselves with logging the execution time of the business logic. The following is the definition of a trivial AspectJ aspect that advises any method annotated with the custom annotation @Loggable

Whenever an @Loggable method is called, this advice will time the execution of the method and then post it to an external service. For this example, I’m posting to a sample REST API, but this could be any auditing/logging service you want. Also notice the use of Spring’s RestTemplate. This class provides for transparent serialization/deserialization of domain objects with zero configuration required by the end user. We will come back to the definition of RestTemplate later.

Now that we have our logging aspect we need the business logic that it will advise. In this case we are going to use a factorial calculator for its simplicity. Here is the definition of our calculator, notice the use of the @Loggable annotation.

Finally we need to define the function that Dispatch will execute in response to events or function invocation requests.

Here our FunctionHandler accepts the FactorialCalculator in its constructor and then calls the calculate method in its own apply method. The Result class acts as a wrapper for the result, but it could be replaced BigInteger just as easily.

With these pieces in place we just need to initialize all of these beens in our Spring context and enable AspectJ auto proxying. Here is the full definition of the function class that we will place to Dispatch.

How do you run this in Dispatch? I’m going to assume you have your own Dispatch instance running in a Kubernetes cluster. If you need help setting up a Dispatch install you can use our Getting Started doc found here. With Dispatch installed and the cli configured on your machine you can use the following command to create the base image.

dispatch create base-image java-base dispatchframework/java-base:0.0.3

You can use dispatch get base-image to watch the progress of the base image provisioning. When the status shows as READY you can move on to creating the image.

dispatch create image java-aop java-base --runtime-deps pom.xml

In this case pom.xml is file containing the maven dependencies for our function.

Finally let’s create the function using the HelloSpringAuditing.java file from earlier.

dispatch create function java-aop audit-fn HelloSpringAuditing.java

Again we can use dispatch get function to wait for the function to be ready. Once it is ready we can execute the function using:

dispatch exec audit-fn --input "50" --wait --json

If everything worked you should see output like this:

This was a quick overview of using Spring in your Dispatch functions. If you are interested in how this support was added you can take a look at the java base image found here, and for more on Dispatch in general you can check out our website at dispatchframework.io.

{"blocking": true,"executedTime": 1525897389,"faasId": "ed641f45-a575-49a1-898d-bbb1a57f9fa7","finishedTime": 1525897391,"functionId": "64defab7-e212-4837-9a91-4d639c0b7aa9","functionName": "log-fn","input": 50,"logs": {"stderr": null,"stdout": ["Got response with id 101 and body: Method BigInteger io.dispatchframework.javabaseimage.HelloSpringAuditing$FactorialCalculator.calculate(int) executed in 30ms."]},"name": "4463f1f3-7197-4247-8b76-603c4eb550bd","output": {"computedFactorial": 3.0414093201713376e+64},"reason": null,"secrets": [],"services": null,"status": "READY","tags": []}

This was a quick overview of using Spring in your Dispatch functions. If you are interested in how this support was added you can take a look at the java base image found here, and for more on Dispatch in general you can check out our website at dispatchframework.io.

--

--