Greeter Example with Docker Compose

This example is intended as a follow-up after completion of the Java SDK Showcase Tutorial. If you‘re already familiar with the Java SDK fundamentals and would like to get a better understanding of how a realistic StateFun application looks like, then you’re in the right place! Otherwise, we highly suggest taking a look at the Showcase tutorial first.

This example works with Docker Compose, and runs a few services that build up an end-to-end StateFun application:

  • Functions service that runs your functions and expose them through an HTTP endpoint.
  • StateFun runtime processes (a manager plus workers) that will handle ingress, egress, and inter-function messages as well as function state storage in a consistent and fault-tolerant manner.

To motivate this example, we'll implement a simple user greeter application, which has two functions - a UserFn that expects UserLogin JSON events from an ingress and keeps in state storage information about users, and a GreetingsFn that accepts user information to generate personalized greeting messages that are sent to users via an egress.

Directory structure

  • src/, pom.xml and Dockerfile: These files and directories are the contents of a Java Maven project which builds our functions service, hosting the UserFn and UserLogin behind a HTTP endpoint. Check out the source code under src/main/java. The Dockerfile is used to build a Docker image for our functions service.
  • module.yaml: The Module Specification file to be mounted to the StateFun runtime process containers. This configures a few things for a StateFun application, such as the service endpoints of the application's functions, as well as definitions of Ingresses and Egresses which the application will use.
  • docker-compose.yml: Docker Compose file to spin up everything.

Prerequisites

  • Docker
  • Docker Compose

Running the example

First, lets build the example. From this directory, execute:

$ docker-compose build

This pulls all the necessary Statefun Docker image, and also builds the functions service image. This can take a few minutes as it also needs to build the function's Java project.

Afterward the build completes, start running all the services:

$ docker-compose up

Play around!

The greeter application allows you to do the following actions:

  • Create a greeting for a user via sending a UserLogin message to the user function

In order to send messages to the Stateful Functions application you can run:

$ curl -X PUT -H "Content-Type: application/vnd.greeter.types/UserLogin" -d '{"user_id": "1", "user_name": "Joe", "login_type": "WEB"}' localhost:8090/greeter.fns/user/1

You can take a look at what messages are being sent to the Playground egress:

$ curl -X GET localhost:8091/greetings

Messages

The messages are expected to be encoded as JSON.

  • UserLogin: {"user_id": "1", "user_name": "Joe", "login_type": "WEB"}, user_id is the id of the user function

What's next?

You can also try modifying the function code in the src/main/java directory, and do a zero-downtime upgrade of the functions. Some ideas you can try out:

  • Add some more state to be persisted by the UserFn. For example, let it additionally keep track of the user's previous login location.
  • Or maybe just simply changing the greetings message generated by the GreetingsFn!

After you've finished changing the function code, you can do a hot redeploy of your functions service:

$ docker-compose up -d --build greeter-functions

This rebuilds the functions service image with the updated code, and restarts the service with the new image.