Skip to content

Commit 14b0a5f

Browse files
authored
Architecture documentation (#117)
1 parent 3adca67 commit 14b0a5f

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
---
2+
sidebar_position: 1
3+
---
4+
5+
# Overall architecture
6+
7+
At the heart of the manager, is the [Container](https://www.javadoc.io/doc/io.openremote/openremote-container/latest/org/openremote/container/Container.html) class that manages the life cycle of all the services, including loading and starting them at launch.
8+
Those services are defined in [manager/src/main/resources/META-INF/services/org.openremote.model.ContainerService](https://github.com/openremote/openremote/blob/master/manager/src/main/resources/META-INF/services/org.openremote.model.ContainerService)
9+
10+
A service is a component whose lifecycle is managed by the Container, and that provides some functionality. All services implement the [ContainerService](https://www.javadoc.io/doc/io.openremote/openremote-model/latest/org/openremote/model/ContainerService.html) interface.
11+
12+
Fundamentally, OpenRemote is a context broker, storing information about [Asset](https://www.javadoc.io/doc/io.openremote/openremote-model/latest/org/openremote/model/asset/Asset.html)s in a database. Assets have a type ([AssetDescriptor](https://www.javadoc.io/doc/io.openremote/openremote-model/latest/org/openremote/model/asset/AssetDescriptor.html)) that defines their schema. The schema defines the attributes assets have, along with meta information about them.
13+
# Event driven mechanism
14+
15+
The whole system is event driven. Different types of events can occur in the system, all inheriting from the root [Event](https://www.javadoc.io/doc/io.openremote/openremote-model/latest/org/openremote/model/event/Event.html) class.
16+
17+
18+
```mermaid
19+
---
20+
title: Key Event classes
21+
---
22+
classDiagram
23+
24+
Event <|-- SharedEvent
25+
SharedEvent <|-- AttributeEvent
26+
SharedEvent <|-- ReadAssetTreeEvent
27+
SharedEvent <|-- ReadAssetsEvent
28+
SharedEvent <|-- AssetsEvent
29+
SharedEvent <|-- RulesEngineStatusEvent
30+
SharedEvent <|-- AssetTreeEvent
31+
SharedEvent <|-- ReadAssetEvent
32+
SharedEvent <|-- AssetEvent
33+
SharedEvent <|-- ReadAttributeEvent
34+
Event <|-- OutdatedAttributeEvent
35+
```
36+
37+
Implementation note: Apache [Camel](https://camel.apache.org) is used as a basic building block of the system and used extensively in events routing.
38+
39+
## AttributeEvent
40+
41+
One very important event type is [AttributeEvent](https://www.javadoc.io/doc/io.openremote/openremote-model/latest/org/openremote/model/attribute/AttributeEvent.html), which represents the value of an asset's attribute at a given point in time. It is through this event that the "live" value of an attribute (i.e. the value in the database) is updated.
42+
43+
### Events ingress
44+
45+
Those events can enter the system through different channels.
46+
47+
#### From outside the system
48+
49+
See [Manager APIs](https://docs.openremote.io/docs/user-guide/manager-apis/) for information on the different APIs.
50+
51+
##### Via publishing on MQTT topics
52+
53+
Clients can post on `writeattributevalue` or `writeattribute` topics.
54+
This is handled in [DefaultMQTTHandler.onPublish()](https://github.com/openremote/openremote/blob/151af17d0e502f0fa7a377cd34b8416350bc1794/manager/src/main/java/org/openremote/manager/mqtt/DefaultMQTTHandler.java#L342).
55+
56+
##### Via REST API
57+
58+
Several endpoints allow to add or update one or more attributes.
59+
60+
[Write to a single attribute](https://docs.openremote.io/docs/rest-api/write-attribute-value)- `PUT {assetId}/attribute/{attributeName}`
61+
[Write to a single attribute with a timestamp](https://docs.openremote.io/docs/rest-api/write-attribute-value-1) - `PUT {assetId}/attribute/{attributeName}/{timestamp}`
62+
[Update attribute values](https://docs.openremote.io/docs/rest-api/write-attribute-values) - `PUT attributes`
63+
[Update attribute values with timestamps](https://docs.openremote.io/docs/rest-api/write-attribute-events) - `PUT attributes/timestamp`
64+
65+
All above end up being handled by [AssetResourceImpl.doAttributeWrite()](https://github.com/openremote/openremote/blob/151af17d0e502f0fa7a377cd34b8416350bc1794/manager/src/main/java/org/openremote/manager/asset/AssetResourceImpl.java#L580).
66+
67+
##### Via WebSocket API
68+
69+
[AttributeEvent](https://www.javadoc.io/doc/io.openremote/openremote-model/latest/org/openremote/model/attribute/AttributeEvent.html) arriving on WebSocket are handled by [ClientEventService](https://www.javadoc.io/doc/io.openremote/openremote-manager/latest/org/openremote/manager/event/ClientEventService.html).
70+
71+
#### From inside the system
72+
73+
[AssetProcessingService.sendAttributeEvent()](https://github.com/openremote/openremote/blob/151af17d0e502f0fa7a377cd34b8416350bc1794/manager/src/main/java/org/openremote/manager/asset/AssetProcessingService.java#L317) can be used by any component in the system to post an [AttributeEvent](https://www.javadoc.io/doc/io.openremote/openremote-model/latest/org/openremote/model/attribute/AttributeEvent.html) for processing.
74+
75+
### Events processing
76+
77+
Regardless of how events enter the system, they are handled through a Camel Direct component with URI "direct://AttributeEventProcessor".
78+
This is wired to the [AssetProcessingService](https://www.javadoc.io/doc/io.openremote/openremote-manager/latest/org/openremote/manager/asset/AssetProcessingService.html), that manages the processing chain all those events go through.
79+
80+
[AssetProcessingService.processAttributeEvent()](https://github.com/openremote/openremote/blob/151af17d0e502f0fa7a377cd34b8416350bc1794/manager/src/main/java/org/openremote/manager/asset/AssetProcessingService.java#L341) is really where all processing happens.
81+
82+
A lock is immediately taken on the asset (assetId based) and during this lock:
83+
- [Asset](https://www.javadoc.io/doc/io.openremote/openremote-model/latest/org/openremote/model/asset/Asset.html) is retrieved from DB
84+
- An enriched event is created with the attribute and the old value/timestamp
85+
- The event is validated (based on constraints defined on the attribute)
86+
- The event goes through a chain of interceptor ([AttributeEventInterceptor](https://www.javadoc.io/doc/io.openremote/openremote-manager/latest/org/openremote/manager/event/AttributeEventInterceptor.html)). If an interceptor intercepts the event, it does not go further in the chain and its processing is stopped here.
87+
This is currently used by [Agent](https://www.javadoc.io/doc/io.openremote/openremote-model/latest/org/openremote/model/asset/agent/Agent.html)s and Gateways.
88+
- Unless the event is outdated, it's used to update the attribute's current value (persisted in the database) and is published to a series of subscribers (via [ClientEventService](https://www.javadoc.io/doc/io.openremote/openremote-manager/latest/org/openremote/manager/event/ClientEventService.html)).
89+
- If it is outdated, it's re-published as an [OutdatedAttributeEvent](https://www.javadoc.io/doc/io.openremote/openremote-manager/latest/org/openremote/manager/asset/OutdatedAttributeEvent.html) instead, so [AssetDatapointService](https://www.javadoc.io/doc/io.openremote/openremote-manager/latest/org/openremote/manager/datapoint/AssetDatapointService.html) can still store history data if required.

0 commit comments

Comments
 (0)