From 06f2ddf61fe6d12c06de199018d48dc637f3ab8d Mon Sep 17 00:00:00 2001 From: Claudio Maggioni Date: Sat, 22 Apr 2023 15:56:29 +0200 Subject: [PATCH] homework 9 done, please check --- src/sa/model/connector-view.c5 | 11 ++++ .../0006-web-connector-between-engines.madr | 39 ++++++++++++ src/sa/model/index.md | 62 +++++++++++++++++++ 3 files changed, 112 insertions(+) create mode 100644 src/sa/model/connector-view.c5 create mode 100644 src/sa/model/decisions/0006-web-connector-between-engines.madr diff --git a/src/sa/model/connector-view.c5 b/src/sa/model/connector-view.c5 new file mode 100644 index 0000000..a224494 --- /dev/null +++ b/src/sa/model/connector-view.c5 @@ -0,0 +1,11 @@ +Device Engine <- MQTT <- MQTT Sensor +Device Engine <-> MQTT <-> MQTT Device + +Device Engine <-stream- Homekit Sensor +Device Engine <-stream-> HomeKit Device + +Device Engine -stream-> User Interface +Device Engine -> web Trigger API -> Trigger and Automation Engine +Trigger and Automation Engine -> web Scene API -> Scene Engine +Scene Engine -> web Devices API -> Device Engine +User Interface -> web Devices API -> Device Engine \ No newline at end of file diff --git a/src/sa/model/decisions/0006-web-connector-between-engines.madr b/src/sa/model/decisions/0006-web-connector-between-engines.madr new file mode 100644 index 0000000..ab0e6dd --- /dev/null +++ b/src/sa/model/decisions/0006-web-connector-between-engines.madr @@ -0,0 +1,39 @@ +## ADR #0006: The web connector is used to connect the engine components + +1. **What did you decide?** + + The web connector is the only component used to connect the engine components + of SmartHut in a ring architecture. + +2. **What was the context for your decision?** + + The chosen connector shall maintain the microservice-ready architecture of SmartHut that was designed in the component diagram. The chosen connector shall + be used to pass events (such as device updates) and commands (such as application of a scene) seamlessly. The chosen connector shall allow for concurrent access to resources. + +3. **What is the problem you are trying to solve?** + + Which connector is the most suited to connect the engine components toghether and to allow for an efficient flow of data between them? + +4. **Which alternative options did you consider?** + + - Disruptor + - Event bus + - Point-to-point web connectors + +5. **Which one did you choose?** + + - Point-to-point web connectors + +6. **What is the main reason for that?** + + Given the limited number of actors the connector type shall connect toghether, + one-to-many connectors do not pose a significant advantage compared to point-to-point connections and mainly introduce drawbacks, like weak definition of data structures and too loose coupling between components. The use of the web connector allows for well-defined endpoints and high degree of transparency while still allowing complex interactions to take place, like the coexistence of internal and external clients seamlessly acting on the same interface. + + Pros: + - Simple, well-defined architecture + - OpenAPI allows clear documentation of endpoints and data structures + - Transparent enough to allow external clients + + Cons: + - Tight coupling + - Cascading failover possible \ No newline at end of file diff --git a/src/sa/model/index.md b/src/sa/model/index.md index 23a24b2..da285ab 100644 --- a/src/sa/model/index.md +++ b/src/sa/model/index.md @@ -1294,6 +1294,68 @@ Exceed: introduce a new type of connector and update your existing process view } +I choose to define the MQTT protocol as a special kind of connector to better +highlight its resilient capabilities, like the support for 3 different levels of message delivery reliability and persistent sessions. In the diagram the connector +is represented with an abuse of notation, namely by introducing a box labeled "MQTT". Flow of messages is bidirectional for devices and from device to engine only for sensors. + +Note that the stream between an HomeKit device and the device engine is bidirectional even if the diagram does not show it. + +![Connector View Diagram](./connector-view.c5) + +![Architectural Decision Record](./decisions/0006-web-connector-between-engines.madr) + +### Process View + +Here is the updated process view to show the primitives of the MQTT connector. + +Use case: a user alters manually the state of device 'D' in the UI, and the device updates accordingly. Device 'D' is not part of any defined trigger. + +```puml +@startuml +title Process View: UI updates state of device + +box "IoT Devices" + participant "MQTT device 'D'" as ZD +end box + +box "User Interface" + participant "UI" as UI +end box + +box "Users and Devices" + participant "paho.mqtt.java" as ZIG + participant "Engine" as DI +end box + +box "Triggers and Automations" + participant "Engine" as T +end box + +DI -> ZIG: client.connect(...) +ZIG -> ZD: CONNECT reliability=2 +ZD -> ZIG: CONNACK +ZD -> ZIG: SUBSCRIBE "state-cmd" +ZIG -> ZD: MQTT ACK +ZIG -> ZD: SUBSCRIBE "state-update" +ZD -> ZIG: MQTT ACK +UI -> DI: HTTP 1.1 PUT /devices/{id}/state\n(update state) +DI -> ZIG: client.publish(\n TOPIC,\n new MqttMessage(...)\n);\n(request state update) +ZIG -> ZD: MQTT PUBLISH "state-cmd"\n(state update request) +ZIG -> ZD: MQTT PUBLISH "state-cmd"\n(resending, no ack received) +ZD -> ZIG: MQTT ACK +ZD -> ZIG: MQTT PUBLISH "state-update"\n(new state) +ZIG -> ZD: MQTT ACK +ZIG -> DI: subscriber.subscribe(...) observer called \n(successful application) +DI -> UI: s.getBasicRemote().sendText(...)\n(send new device state) +DI -> T: report latest device state +ZD -> ZIG: MQTT PUBLISH\n(new state, repeated message, ignoring) + +skinparam monochrome true +skinparam shadowing false +skinparam defaultFontName Courier +@enduml +``` + # Ex - Adapters and Coupling {.instructions