How the IoT example was created

The IoT example service uses an Event Sourced Entity. Event Sourced Entities capture each change as data, as opposed to overwriting existing values. They emit changes as events, which are persisted in a log that can be replayed. Event Sourcing provides complete traceability of device behavior for security, analytics, and simulation.

The following sections highlight the main steps to create the IoT stateful service:

Download the example project

Download the example source from GitHub for Java or for JavaScript:

Define service API and message types

Define the service API in gRPC .proto file format. As a best practice, the example uses two .proto files, one that defines the service and a second containing the domain-specific definitions for the entity. From the .proto files, the gRPC compiler creates client and server-side code that saves work for you and that enables Akka Serverless to serialize message data at runtime.

  1. View the IoT message definitions and service API:

    Javascript

    From the wirelessmesh directory, open the wirelessmeshservice.proto file.

    Java

    From the source/main/proto directory, open the wirelessmeshservice.proto file.

  2. Find the AddCustomerLocationCommand message and note that it includes a (akkaserverless.field).entity_key, which allows us to store and locate customers by a unique ID.

  3. Locate the WirelessMeshService definition and note the operations it supports for managing customers and their devices.

  4. From the same directory, open the wirelessmeshdomain.proto file and view the events that will be stored for the service.

Now, let’s look at the implementation.

Using Event Sourced Entities

The snippet below demonstrates how to use Event Sourced Entities:

JavaScript

From the file wirelessmesh.js:

const EventSourced = require("akkaserverless").EventSourced;
const eventPublisher = require("./eventPublisher.js");
const deviceClient = require("./deviceClient.js");

const entity = new EventSourced(
  ["wirelessmeshservice.proto", "wirelessmeshdomain.proto"],
  "wirelessmeshservice.WirelessmeshService",
  {
    persistenceId: "customer-location",
    snapshotEvery: 50,
    includeDirs: ["./"],
    serializeFallbackToJson: true // Enables JSON support for persistence
  }
);
Java

From the file WirelessMeshMain.java, the entity must be registered as shown in the following snippet:

public class WirelessMeshMain {

    private final static Logger LOG = LoggerFactory.getLogger(WirelessMeshMain.class);

    public static AkkaServerless wirelessMeshService =
            new AkkaServerless()
                    .registerEventSourcedEntity(
                            CustomerLocationEntity.class,
                            Wirelessmesh.getDescriptor().findServiceByName("WirelessMeshService"),
                            Wirelessmeshdomain.getDescriptor()
                    )
                    .registerAction(
                            PublishingAction.class,
                            Publishing.getDescriptor().findServiceByName("PublishingService"),
                            Wirelessmeshdomain.getDescriptor()
                    );

    public static void main(String... args) throws Exception {
        LOG.info("started");
        wirelessMeshService.start().toCompletableFuture().get();
    }
}

The CustomerLocationEntity will be seeded with the current state upon loading and thereafter will completely serve the backend needs for a particular device. If you want to compare the entities to a traditional relational database, you can look at each instance of these entities as being roughly equivalent to a row in a database, only each one is completely addressable and in memory.

The PublishingAction it’s triggered by each event received by the CustomerLocationEntity. This Action is in charge of publishing these events to a topic in Google Cloud Pub/Sub working in combination with the PublishingService. You can find the definition of this Service in the file publishing.proto.

How to connect to external systems

Your Akka Serverless services don’t exist in a vacuum, so you’ll need to connect from services to external systems. This IoT example needs to connect to Google Cloud Pub/Sub to publish the events generated from the Customer Location Entity.

To connect this IoT example with Google Cloud Pub/Sub you need to do the following.

  1. Create an Akkaserverless project to deploy the IoT example to. More info in here

  2. Package the project and deploy it. More info in here

  3. Configure the message broker to allow communication between IoT example and Google Cloud Pub/Sub. More info in here

We cover deployment in more detail in the next section.