High Level Architecture

Figure 1, “Overview of components” shows an overview of the different components involved in a deployment. These can also be found as root level elements in the repository.

Overview of components
Figure 1. Overview of components
IoT Connectivity

This is the source of the events which should be processed by Doppelgaenger, and the target for commands. This can be Drogue Cloud, but it could also be some other component, like a standard MQTT Broker or a Kafka topic.

Events in this system do not need to be in the format of Doppelgaenger. This system is not considered part of Doppelgaenger.


The injector extracts events from an external IoT connectivity system and injects them into Doppelgaengner.

It will translate between the external IoT connectivity protocol (e.g. MQTT) and the internal Kafka topic. It will also translate from an external payload format, into a Doppelgaenger event.


Kafka is being used to stream events into the system, but also to stream internal events between components.


The processor takes events from the stream and executes the events. Events are mostly updating thing states.

The processor loads the current state, executes the command, reconciles the thing, persists the new state, and sends out events generated by the process.


The persistent storage for the state. This can be PostgreSQL directly, but also any other database which uses the PostgreSQL protocol and syntax.

As there are no hard references between things, it is actually possible to have multiple PostgreSQL instances, and shard the things among them.


Things can request to be woken up after a certain time, to re-process, re-try, or reconcile. The waker will send "wakeup" events to Kafka, when the wake period expires.


The backend services provides an API to the Things. This API can be used to manage things, but also to listen to state changes. It should not be used to stream data into the system.