Build and deploy the IoT example

After confirming prerequisites and downloading the example as described in downloading the project, you can build and deploy it as described below. As mentioned previously, Google Cloud Pub/Sub and the LIFX bulb are optional.

Optional - Prepare Google Cloud Pub/Sub

To connect to Google Cloud Pub/Sub, the easiest method is to authenticate using a service account new tab. After creating your service account, you need to download the service account key as a JSON file called mycreds.json.

Next, you’ll need to build a base image that contains the mycreds.json file and sets the environment variable GOOGLE_APPLICATION_CREDENTIALS to the service account key. You can build the docker image with by running:

docker build -f prereq.Dockerfile . -t mybaseimage
The new container will be named mybaseimage and will be used in subsequent steps. Note that pushing containers with service account keys to a public docker registry is a potentially dangerous situation. Therefore, we highly recommend using a private container registry.

Optional - Connect to a LIFX bulb

You can use a LIFX bulb as a stand in for a wirelessmesh device and have it respond when you toggle the device nightlight. To connect a LIFX bulb to the IoT example:

  • Have an operational LIFX bulb.

  • Have an authorization token from LIFX.

  • When you create your customer location in the example, set the access token to the authorizaton token from LIFX.

  • When you activate the device in this app, make sure it has the same device id as your bulb.

See the LIFX website new tab for more information on LIFX bulbs.

Build the IoT service container

To build the service container, follow these steps:

  1. If you are not connecting to Google Cloud Pub/Sub:

    1. From the wirelessmesh example directory, open Dockerfile.

    2. Comment out lines 14 and 15 that define the Google credentials.

    3. Save the file.

    1. From the top level example directory, open pom.xml.

    2. Comment out line 58, <from>mybaseimage</from>.

    3. Remove the comment from line 59 to enable <from>adoptopenjdk/openjdk8</from>.

    4. Update line 56 with your Docker Hub username and save the file.

  2. Build the container:


    From the wirelessmesh directory of the example:

    1. Set your Docker Hub username:

      export DOCKER_USER=<your dockerhub username>
    2. Build:

      npm run dockerbuild

    1. From the root example directory, run:

      mvn clean install

      The command mvn clean install will create a new Docker image based on mybaseimage or on adoptopenjdk/openjdk8.

      The result of the command should be:

      $ mvn clean install
      [INFO] ------------------------------------------------------------------------
      [INFO] ------------------------------------------------------------------------
      [INFO] Total time:  01:31 min
      [INFO] Finished at: 2021-01-20T16:20:29-08:00
      [INFO] ------------------------------------------------------------------------

    == Deploy your container

To deploy the IoT container as a service in Akka Serverless, you’ll need to:

  1. Push the container to a container registry by substituting your username and the correct URL in the following command:

    docker push -t <registry url>/<registry username>/akkaserverless-wirelessmesh-java:latest
  2. If you are not logged into Akka Serverless, log in using either the Console or the CLI:

    1. Sign in to your Akka Serverless account at:

      The Projects page opens.

    2. Click the Add New Project card.

    3. In the Project name field, enter IoT.

    4. Click submit.

      Your project should appear in the Projects list. An Akka Serverless administrator will need to activate the project before you can use it.

    1. Log into your account:

      akkasls auth login

      The Login page launches in a browser.

    2. Enter your credentials.

      An authorization page displays.

    3. Click Authorize

    4. In the CLI, create a IoT project to deploy the IoT service:

      akkasls project new IoT
    5. Set the IoT project to be your current project:

      akkasls config set project IoT

      An Akka Serverless administrator will need to activate the project before you can use it.

  3. Deploy the container using either the Console or the CLI:

    1. In the Services pane, click +.

    2. Enter wirelessmesh and click Next.

    3. Enter the path to your container image, which will be something like:

      <registry url>/<registry username>/akkaserverless-wirelessmesh-java:latest

    4. Click Next.

    5. Skip adding environment variables and click Next.

    6. Move the sliders to add a route and enable CORS, click Next.

    7. Click Finish.

    8. Scroll down to find the Routes panel and copy the Hostname. You will use it for the next exercise.

    1. Set Iot to be the current project:

      akkasls config set project IoT
    2. Deploy the service by substituting your registry URL and username in the following command:

      akkasls services deploy wirelessmesh <registry url>/<registry username>/akkaserverless-wirelessmesh-java:latest
    3. Expose a route and enable CORS:

      akkasls service expose shoppingcart --enable-cors wirelessmesh

      Akka Serverless returns the hostname where your service is exposed, which will be similar to the following:

    You will use the exposed hostname in the next exercise.

Now you are ready to try it out!

Exercising the example

You can exercise the example by sending HTTP requests. This section provides instructions for using Postman, but you should be able to extrapolate how to use curl or another HTTP client. For the first request, we will provide all steps to use Postman’s web UI. For subsequent requests, we just provide the type of method, the URL, and the body.

The first request

Create the first Postman request:

  1. You can create a request from several locations in Postman. For example, from the Get Started list in your workspace, click Create a request.

    An untitled request displays:

    new request
  2. From the method type (Get) dropdown, select the POST method.

  3. For the request URL, where <hostname> is the Hostname for your exposed service, enter:

  4. Click Body.

  5. Select Raw and from the type drop-down, select JSON.

  6. Add the body:

    '{"customerLocationId": "my-first-location", "accessToken": "my lifx access token if applicable"}'
  7. Click Send.

    You should see a response of 200(OK) {}, which will be the response of all POSTs to this example.

Add a location and a device

Follow these steps to add a location and a device:

  1. Create a GET request with the following request URL:


    You should see a JSON response containing your customer location and no devices.

  2. Create a POST request to https://<hostname>/wirelessmesh/activate-device with the JSON body:

    {"customerLocationId": "my-first-location", "deviceId": "my-first-device"}
  3. Create a POST request to https://<hostname>.com/wirelessmesh/assign-room with the JSON body:

    {"customerLocationId": "my-first-location", "deviceId": "my-first-device", "room": "office"}
  4. Create a POST request to https://<hostname>/wirelessmesh/toggle-nightlight with the JSON body:

    {"customerLocationId": "my-first-location", "deviceId": "my-first-device"}
  5. Rerun the get-customer-location request

    You should see a JSON response with your customer location, and a collection of your single device with the room assigned and the nightlight on.

Remove the device and location

To remove the device and location:

  1. Create a POST request to https://<hostname>/wirelessmesh/remove-device with the body:

    {"customerLocationId": "my-first-location", "deviceId": "my-first-device"}

    You should see a response that shows no devices.

  2. Create a POST request to `\https://<hostname>/wirelessmesh/remove-customer-location' with the body:

    {"customerLocationId": "my-first-location"}

Rerun the get-customer-location request, and you will see a server error since it no longer exists.

Congratulations, you’ve deployed and tested your first stateful service! Learn how it was implemented on the next page.