Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(adr): addition of north-south messaging ADR #656

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
d91baa3
feat(adr): addition of north-south messaging ADR
jpwhitemn Dec 22, 2021
388c44f
feat(adr): add ADR images
jpwhitemn Dec 22, 2021
061ba0a
feat(adr): addressed review comments by cloudxx8 and TomBrennan-Eaton
jpwhitemn Jan 11, 2022
665398e
feat(adr): address several review comments and questions
jpwhitemn Jan 19, 2022
534edea
feat(adr): rewrite of the ADR with input from early reviews
jpwhitemn Jan 22, 2022
c3040e5
feat(adr): fixed image reference
jpwhitemn Jan 22, 2022
9ff59cb
feat(adr): address review comments by @lenny-intel and @iain-anderson
jpwhitemn Feb 10, 2022
0440947
feat(adr): cleanup after conversation with @lenny-intel
jpwhitemn Feb 11, 2022
cfc325b
feat(adr): addressed comments made during core WG of 2-24-22
jpwhitemn Feb 25, 2022
cec8507
feat(adr): address review comments of 2-28-22 monthly arch meeting
jpwhitemn Feb 28, 2022
f098b8e
feat(adr): updated based on review comments from @tonyespy and core w…
jpwhitemn Mar 12, 2022
7beae6a
feat(adr): changes and additions per monthly architect meeting review…
jpwhitemn Mar 29, 2022
daa4e2a
feat(adr): changes made per @lenny-intel review of new internal messa…
jpwhitemn Mar 29, 2022
39aa35c
feat(adr): latest review changes per @tonyespy and @lenny-intel
jpwhitemn Apr 5, 2022
db95495
feat(adr): changes to command query JSON and query message response p…
jpwhitemn Apr 8, 2022
19b473f
feat(adr): address comments/issues from tonyespy review of 4/22/22
jpwhitemn Apr 26, 2022
8093ad9
feat(adr): added note that implementation of error code with enumerat…
jpwhitemn Apr 27, 2022
a1f9f9a
feat(adr): set status to approved and update TOC to include already a…
jpwhitemn Apr 28, 2022
413d63e
Merge branch 'main' into adr-0023-north-south-message-bus
jpwhitemn Apr 28, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs_src/design/TOC.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@
| [0018 Service Registry](./adr/0018-Service-Registry.md) | Service registry usage for EdgeX services |
| [0019 EdgeX-CLI V2](./adr/core/0019-EdgeX-CLI-V2.md) | EdgeX-CLI V2 Implementation |
| [0020 Delay start services (SPIFFE/SPIRE)](./adr/security/0020-spiffe.md) | Secret store tokens for delayed start services |
| [0023 North South Messaging](./adr/0023-North-South-Messaging.md) | Provide for messaging from north side systems through command down to device services | |
158 changes: 158 additions & 0 deletions docs_src/design/adr/0023-North-South-Messaging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
# North-South Messaging

## Status

** Proposed **
(as of 12/21/21)

## Context and Proposed Design

Today, data flowing from sensors/devices (the "southside") through EdgeX to enterprise applications, databases and cloud-based systems (the "northside") can be accomplished via REST or Message bus. That is, sensor or device data collected by a device service can be sent via REST or message bus to core data. Core data then relays the data to application services via message bus, but the sensor data can also be sent directly from device services to application services via message bus (by passing core data). The message bus is implemented via Redis Pub/Sub (default) or via MQTT. From the application services, data can be sent to northside endpoints in any number of ways – including via MQTT.
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved

So, in summary, data can be collected from a sensor or device and be sent from the southside to the northside entirely using message bus technology when desired.

!!! Note
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved
The message bus may also be implemented in Zero MQ but with some limitations. As Zero MQ is being deprecated in EdgeX, it will not be considered further in this ADR.

Communications from a 3rd party system (enterprise application, cloud application, etc.) to EdgeX in order to acuate a device or get the latest information from a sensor is accomplished via REST. The 3rd party system makes a REST call of the command service which then relays a request to a device service also using REST. There is no built in means to make a message-based request of EdgeX or the devices/sensors it manages.

In a future release of EdgeX, there is a desire to allow 3rd party systems to make requests of the southside via message bus. Specifically, a 3rd party system will send a command request via message to the command service via the allowed message bus implementations (which could be MQTT or Redis Pub/Sub today). The command service would then relay the message request via message bus to the managing device service. (The command service would also perform any translations on the request as it does for REST requests today.) The device service would use the message to trigger action on the device/sensor as it does when it receives a REST request today and respond via message bus back to the command service. In turn, the command service would respond to the 3rd party system via message bus.
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved

### Design

The command service requires the means to subscribe to the EdgeX or external (as a 3rd party may want to use their message bus to send commands) message bus. It would use the messaging client (go-mod-messaging) to create a new MessageClient, connect to a message bus, and subscribe to a configured message topic.
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved

The command service would also publish messages to device service topics using the go-mod-messaging MessageClient. It would relay any command request to a designated topic for the device service which would be subscribed to the topic.

Likewise, the device services must use the messaging client (go-mod-messaging for Go services and C alternative for C services) to create a new MessageClient, connect to the message bus and subscribe to configured message topics to receive actuation messages from the command service.
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved

Because any actuation request may require a response on the part of EdgeX, the command service must provide the means to receive an optional response message from the device services and publish a response back to the 3rd party caller via message bus as well.
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved

The command message request messages should contain a correlation identifier which would be added to any response so that the 3rd party system would know to associate the responses to the original request.

The device service message command subscription, response publishing and general handling should be implemented in the SDKs versus individually in the device services.

!!! Note
Message responses are not guaranteed (on the part of the device service to the command service or from the command service back to the originating command requester). Both the command service and the original 3rd party system making the command request bear the burden to manage timeouts (and possibly resending the request) if there is no response.
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved


![image](command-msg.png)
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved

### Message Structure

The messages to the command service and those relayed to the device service would mimic their REST alternatives. The difference is that the HTTP REST requests
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved

- have a header which contain the correlation id.
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved

- have a path that contains the target device and command name

- are made via SET or PUT methods signaling get or set actions on the device.

The message bus and the messages on the bus need this additional information. To address this, the command requests must be embedded in a "wrapper message" structure that would contain the additional elements that would be present in the HTTP request messages.

![image](command-msg-structure.png)

Specifically, the message structure would look something like the following:

``` json
{
"correlation-id": "14a42ea6-c394-41c3-8bcd-a29b9f5e6835",
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved
"method": "SET",
"deviceName": "sensor01",
"command": "command01",
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved
"request":
{
"requestId": "e6e8a2f4-eb14-4649-9e2b-175247911369",
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved
"AHU-TargetTemperature": "28.5",
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved
"AHU-TargetBand": "4.0",
"AHU-TargetHumidity": {
"Accuracy": "0.2-0.3% RH",
"Value": 59
}
}
```
Note, this message structure may not be complete as is meant to represent the general structure. Additional fields may be added in order to align with the HTTP message structure.

Response messages would be similarly wrapped so as to preserve the request id - if nothing else.

``` json
{
"correlation-id": "14a42ea6-c394-41c3-8bcd-a29b9f5e6835",
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved
"response":
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved
{
"requestId": "e6e8a2f4-eb14-4649-9e2b-175247911369",
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved
"apiVersion": "v2",
"requestId": "e6e8a2f4-eb14-4649-9e2b-175247911369",
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved
"statusCode": 0,
"message": "string"
}
}
```

### Configuration

The configuration or the command service must provide the details in order to subscribe to command messages from any 3rd party system and publish to a response topic. The subscription configuration would be similar to how core data is configured to subscribe to messages from any device service and publish to topics to get messages to application services. However, the command service will actually need to have two sets of subscription and two sets of publishing topics.

The command service would subscribe to any command topic ("edgex/request/command/#") to receive requests from the 3rd party system. It must then relay these messages (via publish) to the device service actuation topics.
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved

As each device service will have a topic assigned to it, the device service name and device name will be added to the destination topic ("edgex/request/actuate/<device-service>/<device-name>") when command relays the actuation request messages to device services.
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved

The command service must then subscribe to another topic ("edgex/response/actuate/#") to receive actuation responses from the device services. It then relays those responses on to the 3rd party apps by publishing those responses to a response topic ("edgex/response/command").
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved

![image](command-service-topics.png)
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved

``` toml
[MessageQueue]
Protocol = "redis"
Host = "localhost"
Port = 6379
Type = "redis"
AuthMode = "usernamepassword" # required for redis messagebus (secure or insecure).
SecretName = "redisdb"
SubscribeResponseActuateTopic = "edgex/response/actuate/#"
PublishActuateTopicPrefix = "edgex/actuate/ " # /<device-service>/<device-name> will be added to this Publish Topic prefix
SubscribeRequestCommandTopic = "edgex/request/command/#"
PublishCommandResponseTopic = "edgex/response/command"
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved
```

Device services must similarly be configured for subscribing to actuation commands and responding to them by publishing to the response topic.

``` toml
[MessageQueue]
Protocol = "redis"
Host = "localhost"
Port = 6379
Type = "redis"
AuthMode = "usernamepassword" # required for redis messagebus (secure or insecure).
SecretName = "redisdb"
SubscribeRequestActateTopic = "edgex/request/actuate/<device-service>/#"
PublishActuateResponseTopic = "edgex/response/actuate/<device-service>/"
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved
```

Questions:
- Would we need multiple 3rd party response topics? Or would one setup separate command services for each 3rd party?
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved
- Do we need separate topics for all the devices or would one on the device service suffice?
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved
- Ans: we have defined the deviceName in the payload, so one topic should be sufficient for Device Service- edgex/request/actuate/<device-service>
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved

- Should the command service be allowed to subscribe to the external message broker from a 3rd party? If it subscribes to the EdgeX message bus (internally) only, we might need additional services to relay the data to EdgeX message bus from the external source (depending on security and accessibility to the external message bus).
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved

- Dynamic configuration is not a user friendly operation. We might want to think about creating additional APIs for Adding/Updating/Deleting/Query the external subscription (and store them to the RedisDB).
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved

- Is it acceptable for more than one response to be published by the device service on the same correlation ID? Eg, send back "Acknowledged", then "Scheduled", then "Starting", then "Done" statuses?
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved
- Ans: it is not possible for REST requests today and so it is assumed that is not going to happen via messaging today.
jpwhitemn marked this conversation as resolved.
Show resolved Hide resolved

- Would it make sense to echo the command name into the response, as a reality check?
- Ans: adds length and complexity to the response today that one could say is handled by using the correlation id to track it to the original request. Can revisit if necessary.

!!! INFO
This ADR does not handle securing the message bus communications between services. This need is to be covered universally in an upcoming ADR.

## Consequences

The implementation of north-to-south message bus communications could be accomplished in phases

1. Command service to receive and respond via message bus
2. Device services in Go receive and respond via message bus
3. Device services in C receive and respond via message bus

## References
Binary file added docs_src/design/adr/command-msg-structure.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs_src/design/adr/command-msg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs_src/design/adr/command-service-topics.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.