Responder Simulator Deep Dive

1. Overview

The Emergency Response Demo application requires the movement of responders. For the purpose of the demo, these responders along with their movement (to the pick-up point and to the evacuation center) are simulated. The ER-Demo’s responder-simulator is responsible for moving responders around the map during missions.

1.1. Audience

  • Business Application developers and architects

1.2. Goal

The purpose of the document is to provide a technical deep-dive into the Responder Simulator of the Emergency Response Demo application. Via review of this single project, you will gain an advanced understanding of how various components of the Red Hat Application Services portfolio interact to provide meaningful, reactive and scalability business services in the cloud.

2. Pre-reqs

2.1. Skills

  1. Familiarity with terminology used in the Red Hat’s Emergency Response Demo application
  2. Experience with Red Hat Data Grid
  3. Experience with Red Hat AMQ Streams / Apache Kafka
  4. Experience with Red Hat Build of Quarkus
  5. Experience with Microprofile specification along with SmallRye / Mutiny Reactive framework
  6. Experience with Apache Kafka Streams with Quarkus

2.2. Tools

You will need an Java IDE. Red Hat recommends one of the following:

  • VSCode with the following plugins:
    • Language Support for Java by Red Hat
    • Quarkus
    • Tools for MicroProfile
  • Red Hat CodeReady Studio (based on Eclipse)
  • Red Hat CodeReady Workspaces (based on Eclipse Che)

2.3. Code

The source code that will be in review is found at the following URL:

Clone this project and load it into your favorite IDE for Java development.

NOTE: Red Hat recommends the following IDEs:

3. Review environment properties

At runtime, environment variables set in the responder-simulator container will be injected from two properties files that complement each other.

In your IDE, open the following two files:

  • src/main/resources/ This file is parsed at build-time by the Quarkus compiler. These properties (along with any additional are included in the responder-simulator container.
  • etc/ files. This file is not parsed at build-time. Instead, the properties in this file reflect equivalent properties that are loaded into a config map (when ER-Demo is provisioned) and are read at boot time by Quarkus.

3.1. Kafka Channels

  1. Notice that the first set of properties define incoming and outgoing Microprofile channels for communication with Red Hat AMQ Streams
  • src/main/resources/
    # Configure the Kafka sources
  • etc/
  1. The responder-simulator consumes MissionStartedEvent messages from the topic-mission-event topic. Subsequently, as the mission progresses, it produces a JSON message to the topic-responder-location-update topic that is similar to the following:
    "responderId": "21",
    "missionId": "a6af2762-2ffc-4484-94bd-8ad2111d721c",
    "incidentId": "96287834-811f-4108-98bf-cc4ed21881f5",
    "status": "MOVING",
    "lat": 34.0187,
    "lon": -77.8986,
    "human": false,
    "continue": true

3.2. Data Grid Clients

  1. In support of the responder-simulator service, Data Grid is used as an in-memory grid for the following:
    • responder state
    • responder-simulator state

    Follow-on sections of this document will elaborate.

  2. As part of the Emergency Response Demo provisioning process, Red Hat Data Grid is installed. The responder-simulator is a client of Red Hat Data Grid.

  3. Make note of the following DataGrid client related properties:
    • etc/
      # Name of Data Grid cache for responder state
      # Name of Data Grid cache for responder-simulator state

3.3. Kafka Streams Client

  1. In the responder-simulator service, Kafka Streams captures responder related state and exposes this data to assist in the generation of simulated responder moves. Follow-on sections of this document will elaborate.
  2. As part of the Emergency Response Demo provisioning process, the Kafka Streams component of Red Hat AMQ Streams is installed . The responder-simulator is a client of this Kafka Streams component.
  3. Make note of the following Kafka Streams related properties:
    • etc/

3.4. Responder Simulator


4. Review Java source files


The purpose of this ApplicationScope object is to make Responder state available to the Responder Simulator. The Responder state is stored in Red Hat Data Grid. This class manages the lifecycle of that Responder data in Data Grid.

This Java class implements org.apache.kafka.streams.state.KeyValueStore. It is invoked by the TopologyProducer object when responder state change events are consumed and an Apache Kafka Streams ktable is created from these events.

4.2. Review

The purpose of this ApplicationScope object is to make Responder Location state available to the Responder Simulator. Responder Location state is stored in Red Hat Data Grid. This class manages the lifecycle of this Responder Location state in Data Grid.


The purpose of the ApplicationScope TopologyProducer is to create a Kafka Streams ktable that facilitates lookups of responders with their latest locations.

It implements a function that randomly selects the distance of the next responder move based on a configuration variation.


The purpose of the ApplicationScope ResponderService is to serve as a Kafka Streams client that can retrieve details of a responder from a Kafka Streams ktable.

It implements a function called that returns a Responder object given the responderId.


The purpose of the ApplicationScope Simulator object is to simulate movement of responders during a mission.

This Simulator object tranforms MissionCreated events into a ResponderLocation object. This ResponderLocation object is persisted in Red Hat Data Grid by invoking the ResponderLocationRepository object.

5. Test Your Understanding

  1. Given the default configurations in the responder-simulator-quarkus project, what is the range of a possible distances that a responder can move ?
  2. The return type of the ResponderService.responder(String id) function is: Uni . What is the value add of leveraging this MicroProfile API as the return type as an alternative to returning a *Responder* domain model object ?