@golemio/pid 6.0.1-dev.2901184022 → 6.0.1-dev.2912471131
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/architecture/diagrams/context.mmd +114 -0
- package/docs/architecture/diagrams/context.svg +1 -0
- package/docs/architecture/diagrams/platform-ingestion.mmd +94 -0
- package/docs/architecture/diagrams/platform-ingestion.svg +1 -0
- package/docs/architecture/diagrams/platform-serving.mmd +81 -0
- package/docs/architecture/diagrams/platform-serving.svg +1 -0
- package/docs/architecture/index.md +105 -0
- package/docs/assets/logos/README.md +38 -0
- package/docs/assets/logos/arriva.svg +9 -0
- package/docs/assets/logos/azure-blob-storage.svg +1 -0
- package/docs/assets/logos/azure-kubernetes-service.svg +1 -0
- package/docs/assets/logos/azure-table-storage.svg +1 -0
- package/docs/assets/logos/catch.png +0 -0
- package/docs/assets/logos/cd-telematika.png +0 -0
- package/docs/assets/logos/ceske-drahy.svg +15 -0
- package/docs/assets/logos/chaps.png +0 -0
- package/docs/assets/logos/citymove.png +0 -0
- package/docs/assets/logos/cloudflare.png +0 -0
- package/docs/assets/logos/dpp.svg +119 -0
- package/docs/assets/logos/envoy.svg +1 -0
- package/docs/assets/logos/golemio.svg +1 -0
- package/docs/assets/logos/google-maps.svg +78 -0
- package/docs/assets/logos/grafana-loki.png +0 -0
- package/docs/assets/logos/grafana.svg +57 -0
- package/docs/assets/logos/mikroelektronika.png +0 -0
- package/docs/assets/logos/nodejs.svg +39 -0
- package/docs/assets/logos/pid-litacka.svg +17 -0
- package/docs/assets/logos/pid.svg +1 -0
- package/docs/assets/logos/postgresql.svg +22 -0
- package/docs/assets/logos/rabbitmq.svg +54 -0
- package/docs/assets/logos/ropid.svg +1 -0
- package/docs/assets/logos/seznam.svg +115 -0
- package/docs/assets/logos/telmax.png +0 -0
- package/docs/assets/logos/typescript.svg +1 -0
- package/docs/assets/logos/valkey.svg +58 -0
- package/docs/assets/logos/varnish.svg +21 -0
- package/docs/asyncapi.yaml +5 -3
- package/docs/cache/types/redis.md +1 -1
- package/docs/implementation_documentation.md +40 -42
- package/docs/index.md +382 -0
- package/docs/jis/index.md +84 -94
- package/docs/openapi-input.yaml +3 -2
- package/docs/openapi-output.yaml +3 -1
- package/package.json +2 -2
- package/docs/architecture/pid_architecture_overview.drawio +0 -177
package/docs/jis/index.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Dokumentace propisu VYMI (JIS) dat do datové platformy
|
|
2
2
|
|
|
3
|
-
Data událostí a infotextů jsou z aplikace VYMI aktivně posílána (push) do datové platformy Golemio, vždy ihned po změně v datech. Dále existuje
|
|
3
|
+
Data událostí a infotextů jsou z aplikace VYMI aktivně posílána (push) do datové platformy Golemio, vždy ihned po změně v datech. Dále existuje pasivní načítání (pull) dat z VYMI do Golemia, které spouští pravidelně cron (každou minutu) nebo manuálně vývojář a slouží pro případ, že by došlo k výpadku aktivního posílání. Oba způsoby jsou zjednodušeně znázorněny na následujících dvou sekvenčních diagramech a podrobněji popsány v dalších sekcích.
|
|
4
4
|
|
|
5
5
|
Sekvenční diagram znázorňující proces aktivního posílání (push) dat:
|
|
6
6
|
|
|
@@ -20,11 +20,11 @@ Sekvenční diagram znázorňující proces pasivního načítání (pull) dat:
|
|
|
20
20
|
sequenceDiagram
|
|
21
21
|
participant vymi as Aplikace VYMI
|
|
22
22
|
participant golemio as Datová platforma Golemio
|
|
23
|
-
actor developer as Vývojář
|
|
23
|
+
actor developer as Vývojář nebo cron
|
|
24
24
|
|
|
25
25
|
developer->>golemio: Vyžádání načtení dat událostí nebo infotextů
|
|
26
|
-
golemio->>vymi: Pasivní načtení (pull) dat událostí nebo infotextů z VYMI
|
|
27
|
-
vymi->>golemio: Data událostí nebo infotextů
|
|
26
|
+
golemio->>vymi: Pasivní načtení (pull) dat událostí nebo infotextů z VYMI (s ETagem posledního načtení)
|
|
27
|
+
vymi->>golemio: Data událostí nebo infotextů (nebo HTTP 304, pokud se nezměnila)
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
## Změny dat ve VYMI
|
|
@@ -40,6 +40,7 @@ flowchart LR
|
|
|
40
40
|
vymi_create_event("`Vytvoření události`");
|
|
41
41
|
vymi_update_event("`Úprava události`");
|
|
42
42
|
vymi_update_event_after_duplicate("`Uložení události po duplikaci`");
|
|
43
|
+
vymi_disable_event("`Zneplatnění (smazání) nebo obnovení události`");
|
|
43
44
|
vymi_create_infotext("`Vytvoření infotextu`");
|
|
44
45
|
vymi_update_infotext("`Úprava infotextu`");
|
|
45
46
|
vymi_update_infotext_after_duplicate("`Uložení infotextu po duplikaci`");
|
|
@@ -47,6 +48,7 @@ flowchart LR
|
|
|
47
48
|
%% invisible unicode char due to https://github.com/orgs/community/discussions/106690
|
|
48
49
|
vymi_api_post_event["`HTTP POST s Ory Kratos session tokenem na http://api-vymi.golemio.cz/v1/events`"];
|
|
49
50
|
vymi_api_put_event["`HTTP PUT s Ory Kratos session tokenem na http://api-vymi.golemio.cz/v1/events/{eventId}`"];
|
|
51
|
+
vymi_api_put_event_disable["`HTTP PUT s Ory Kratos session tokenem na http://api-vymi.golemio.cz/v1/events/{eventId}/disable nebo /enable`"];
|
|
50
52
|
vymi_api_post_infotext["`HTTP POST s Ory Kratos session tokenem na http://api-vymi.golemio.cz/v1/events/{eventId}/infotexts`"];
|
|
51
53
|
vymi_api_put_infotext["`HTTP PUT s Ory Kratos session tokenem na http://api-vymi.golemio.cz/v1/events/{eventId}/infotexts/{infotextId}`"];
|
|
52
54
|
end
|
|
@@ -54,6 +56,7 @@ flowchart LR
|
|
|
54
56
|
subgraph "VYMI Back End"
|
|
55
57
|
vymi_events_controller_create["`V1EventsController.createEvent`"];
|
|
56
58
|
vymi_events_controller_update["`V1EventsController.updateEvent`"];
|
|
59
|
+
vymi_events_controller_disable["`V1EventsController.disableEvent / enableEvent`"];
|
|
57
60
|
vymi_infotexts_controller_create["`V1EventInfotextsController.createInfotext`"];
|
|
58
61
|
vymi_infotexts_controller_update["`V1EventInfotextsController.updateInfotext`"];
|
|
59
62
|
end
|
|
@@ -64,28 +67,33 @@ flowchart LR
|
|
|
64
67
|
vymi_create_event --> vymi_api_post_event;
|
|
65
68
|
vymi_update_event --> vymi_api_put_event;
|
|
66
69
|
vymi_update_event_after_duplicate --> vymi_api_put_event;
|
|
70
|
+
vymi_disable_event --> vymi_api_put_event_disable;
|
|
67
71
|
vymi_create_infotext --> vymi_api_post_infotext;
|
|
68
72
|
vymi_update_infotext --> vymi_api_put_infotext;
|
|
69
73
|
vymi_update_infotext_after_duplicate --> vymi_api_put_infotext;
|
|
70
74
|
|
|
71
75
|
vymi_api_post_event -- "`Přes VYMI Ory Oathkeeper`" --> vymi_events_controller_create;
|
|
72
76
|
vymi_api_put_event -- "`Přes VYMI Ory Oathkeeper`" --> vymi_events_controller_update;
|
|
77
|
+
vymi_api_put_event_disable -- "`Přes VYMI Ory Oathkeeper`" --> vymi_events_controller_disable;
|
|
73
78
|
vymi_api_post_infotext -- "`Přes VYMI Ory Oathkeeper`" --> vymi_infotexts_controller_create;
|
|
74
79
|
vymi_api_put_infotext -- "`Přes VYMI Ory Oathkeeper`" --> vymi_infotexts_controller_update;
|
|
75
80
|
|
|
76
81
|
vymi_events_controller_create -- "`UPSERT do tabulek vymi-alerts.public.events a vymi-alerts.public.event_routes`" --> vymi_pg;
|
|
77
82
|
vymi_events_controller_update -- "`UPSERT do tabulek vymi-alerts.public.events a vymi-alerts.public.event_routes`" --> vymi_pg;
|
|
78
|
-
|
|
79
|
-
|
|
83
|
+
vymi_events_controller_disable -- "`Nastavení / zrušení deleted_at v tabulkách vymi-alerts.public.events a vymi-alerts.public.infotexts (soft delete události i jejích infotextů)`" --> vymi_pg;
|
|
84
|
+
vymi_infotexts_controller_create -- "`UPSERT do tabulek vymi-alerts.public.infotexts, vymi-alerts.public.infotext_stops a vymi-alerts.public.infotext_presets`" --> vymi_pg;
|
|
85
|
+
vymi_infotexts_controller_update -- "`UPSERT do tabulek vymi-alerts.public.infotexts, vymi-alerts.public.infotext_stops a vymi-alerts.public.infotext_presets`" --> vymi_pg;
|
|
80
86
|
```
|
|
81
87
|
|
|
82
88
|
## Aktivní posílání (push) dat
|
|
83
89
|
|
|
84
|
-
Po uložení změn událostí a infotextů do VYMI PostgreSQL databáze dojde vždy k aktivnímu poslání (push) "aktuálních" dat z VYMI back end služby do Golemia za pomoci HTTP POST dotazu na Golemio Vehicle Positions (VP) Input Gateway (IG).
|
|
85
|
-
- u událostí se posílá pouze konkrétní nově
|
|
86
|
-
- všechny infotexty, které mají `status` `PUBLISHED`, `visibility` `PUBLIC` a zároveň `active_period_end` je `NULL` nebo >= aktuální čas, neboli lidsky všechny aktivní, budoucí a publikované (ne-draft) infotexty.
|
|
90
|
+
Po uložení změn událostí a infotextů do VYMI PostgreSQL databáze (vytvoření, úprava, zneplatnění nebo obnovení události; vytvoření nebo úprava infotextu) dojde vždy k aktivnímu poslání (push) "aktuálních" dat z VYMI back end služby do Golemia za pomoci HTTP POST dotazu na Golemio Vehicle Positions (VP) Input Gateway (IG).
|
|
91
|
+
- u událostí se posílá pouze konkrétní nově vytvořená, upravená, zneplatněná nebo obnovená událost (pole s nejvýše jednou položkou; pokud událost nesplňuje podmínky exportu uvedené v sekci [pasivního načítání](#pasivní-načítání-pull-dat), např. je draft, pošle se prázdné pole), nikoliv celý seznam aktuálních událostí. Po úpravě, zneplatnění nebo obnovení události se navíc pošle i celý seznam infotextů.
|
|
92
|
+
- u infotextů se vždy posílá celý seznam: všechny infotexty, které mají `status` `PUBLISHED`, `visibility` `PUBLIC`, nejsou smazané (`deleted_at` je `NULL`), mají alespoň jednu aktivní zastávku a zároveň `active_period_end` je `NULL` nebo >= aktuální čas (u infotextu, který konec aktivity dědí z události, se použije `active_period_end` události), neboli lidsky všechny aktivní, budoucí a publikované (ne-draft) infotexty.
|
|
87
93
|
|
|
88
|
-
|
|
94
|
+
Selhání odeslání VYMI pouze zaloguje a neopakuje ho; výpadek pokryje nejbližší pasivní načítání (pull).
|
|
95
|
+
|
|
96
|
+
VP Input Gateway data zvaliduje JSON schématem (`JISEventsJsonSchema`, resp. `JISInfotextsJsonSchema`; při chybě vrací HTTP 422, jinak HTTP 204) a zašle do odpovídající RabbitMQ fronty (události s příznakem `shouldTriggerWebhooks: true`), odkud je převezme VP Integration Engine, který data zapíše do VP PostgreSQL databáze (viz [Chování databáze v Golemio](#chování-databáze-v-golemio)). Po uložení události se odešle [webhook](#webhook-výstup-updateeventwebhooktask), po uložení infotextů se přenačte Redis cache infotextů.
|
|
89
97
|
|
|
90
98
|
Proces je podrobněji znázorněn na následujícím diagramu (detailnější prvky aplikační struktury jsou vynechány).
|
|
91
99
|
|
|
@@ -95,6 +103,7 @@ flowchart TB
|
|
|
95
103
|
subgraph "VYMI Back End"
|
|
96
104
|
vymi_events_controller_create["`V1EventsController.createEvent`"];
|
|
97
105
|
vymi_events_controller_update["`V1EventsController.updateEvent`"];
|
|
106
|
+
vymi_events_controller_disable["`V1EventsController.disableEvent / enableEvent`"];
|
|
98
107
|
vymi_infotexts_controller_create["`V1EventInfotextsController.createInfotext`"];
|
|
99
108
|
vymi_infotexts_controller_update["`V1EventInfotextsController.updateInfotext`"];
|
|
100
109
|
|
|
@@ -112,17 +121,20 @@ flowchart TB
|
|
|
112
121
|
subgraph "Golemio"
|
|
113
122
|
subgraph "Golemio VP Input Gateway"
|
|
114
123
|
golemio_events_controller["`JISEventsController`"];
|
|
115
|
-
golemio_infotexts_controller["`
|
|
124
|
+
golemio_infotexts_controller["`JISInfotextsController`"];
|
|
116
125
|
end
|
|
117
126
|
|
|
118
127
|
subgraph "Golemio RabbitMQ"
|
|
119
128
|
golemio_rabbit_refresh_events["`Fronta vehicle-positions.jis.refreshJISEvents`"];
|
|
120
129
|
golemio_rabbit_refresh_infotexts["`Fronta vehicle-positions.jis.refreshJISInfotexts`"];
|
|
130
|
+
golemio_rabbit_update_event_webhook["`Fronta vehicle-positions.jis.updateEventWebhook`"];
|
|
131
|
+
golemio_rabbit_refresh_infotexts_cache["`Fronta vehicle-positions.jis.refreshJISInfotextsCache`"];
|
|
121
132
|
end
|
|
122
133
|
|
|
123
134
|
subgraph "Golemio VP Integration Engine"
|
|
124
135
|
golemio_refresh_events_task["`RefreshJISEventsTask`"];
|
|
125
136
|
golemio_refresh_infotexts_task["`RefreshJISInfotextsTask`"];
|
|
137
|
+
golemio_update_event_webhook_task["`UpdateEventWebhookTask`"];
|
|
126
138
|
golemio_refresh_infotexts_cache_task["`RefreshJISInfotextsCacheTask`"];
|
|
127
139
|
end
|
|
128
140
|
|
|
@@ -130,14 +142,18 @@ flowchart TB
|
|
|
130
142
|
vp_redis[("`VP Redis (Valkey)`")];
|
|
131
143
|
end
|
|
132
144
|
|
|
145
|
+
webhook_targets["`Konzumenti webhooku (module.pid.jis.webhooks.eventUpdate.targets.\*)`"];
|
|
146
|
+
|
|
133
147
|
vymi_events_controller_create --> vymi_get_events;
|
|
134
148
|
vymi_events_controller_update --> vymi_get_events;
|
|
135
149
|
vymi_events_controller_update --> vymi_get_infotexts;
|
|
150
|
+
vymi_events_controller_disable --> vymi_get_events;
|
|
151
|
+
vymi_events_controller_disable --> vymi_get_infotexts;
|
|
136
152
|
vymi_infotexts_controller_create --> vymi_get_infotexts;
|
|
137
153
|
vymi_infotexts_controller_update --> vymi_get_infotexts;
|
|
138
154
|
|
|
139
|
-
vymi_get_events <-- "`SELECT aktuálních událostí z tabulek
|
|
140
|
-
vymi_get_infotexts <-- "`SELECT aktuálních infotextů z tabulek
|
|
155
|
+
vymi_get_events <-- "`SELECT aktuálních událostí z tabulek vymi-alerts.public.events, vymi-alerts.public.event_routes, vymi-alerts.public.routes a vymi-alerts.public.event_attachments`" --> vymi_pg;
|
|
156
|
+
vymi_get_infotexts <-- "`SELECT aktuálních infotextů z tabulek vymi-alerts.public.infotexts, vymi-alerts.public.infotext_stops a vymi-alerts.public.infotext_presets`" --> vymi_pg;
|
|
141
157
|
|
|
142
158
|
vymi_get_events --> golemio_api_post_events;
|
|
143
159
|
vymi_get_infotexts --> golemio_api_post_infotexts;
|
|
@@ -145,38 +161,40 @@ flowchart TB
|
|
|
145
161
|
golemio_api_post_events -- "`Přes Golemio Access Proxy`" --> golemio_events_controller;
|
|
146
162
|
golemio_api_post_infotexts -- "`Přes Golemio Access Proxy`" --> golemio_infotexts_controller;
|
|
147
163
|
|
|
148
|
-
golemio_events_controller --> golemio_rabbit_refresh_events;
|
|
164
|
+
golemio_events_controller -- "`shouldTriggerWebhooks: true`" --> golemio_rabbit_refresh_events;
|
|
149
165
|
golemio_infotexts_controller --> golemio_rabbit_refresh_infotexts;
|
|
150
166
|
|
|
151
167
|
golemio_rabbit_refresh_events --> golemio_refresh_events_task;
|
|
152
168
|
golemio_rabbit_refresh_infotexts --> golemio_refresh_infotexts_task;
|
|
153
169
|
|
|
154
170
|
golemio_refresh_events_task -- "`UPSERT do tabulek vehicle-positions.pid.jis_events a vehicle-positions.pid.jis_events_ropidgtfs_routes`" --> vp_pg;
|
|
155
|
-
|
|
156
|
-
|
|
171
|
+
golemio_refresh_events_task -- "`Jen pokud byla událost uložena`" --> golemio_rabbit_update_event_webhook;
|
|
172
|
+
golemio_rabbit_update_event_webhook --> golemio_update_event_webhook_task;
|
|
173
|
+
golemio_update_event_webhook_task -- "`HTTP POST`" --> webhook_targets;
|
|
157
174
|
|
|
158
|
-
|
|
175
|
+
golemio_refresh_infotexts_task -- "`UPSERT do tabulek vehicle-positions.pid.jis_infotexts, vehicle-positions.pid.jis_infotexts_ropidgtfs_stops a vehicle-positions.pid.jis_infotexts_presets, smazání chybějících`" --> vp_pg;
|
|
176
|
+
golemio_refresh_infotexts_task --> golemio_rabbit_refresh_infotexts_cache;
|
|
177
|
+
golemio_rabbit_refresh_infotexts_cache --> golemio_refresh_infotexts_cache_task;
|
|
178
|
+
|
|
179
|
+
golemio_refresh_infotexts_cache_task <-- "`SELECT infotextů se zastávkami`" --> vp_pg;
|
|
180
|
+
golemio_refresh_infotexts_cache_task -- "`Aktualizace cache jisCache:$setId:infotexts a jisCache:$setId:stops-infotexts`" --> vp_redis;
|
|
159
181
|
```
|
|
160
182
|
|
|
161
183
|
Formát zasílaných dat je dále více popsán v implementační dokumentaci ([události](../implementation_documentation.md#jis-events-1), [infotexty](../implementation_documentation.md#jis-infotexts-1)), stejně tak jako odkazy na [Input Gateway OpenAPI](../implementation_documentation.md#input-api) a popis [uložení dat](../implementation_documentation.md#uložení-dat) včetně databázového schema a popisu retence. Data infotextů jsou dále cachovány - tento proces je popsán v dokumentaci [Redis cache](../cache/types/redis.md#cache-pro-api-přestupních-tabulí-transfer-boards).
|
|
162
184
|
|
|
163
185
|
## Pasivní načítání (pull) dat
|
|
164
186
|
|
|
165
|
-
V případě potřeby (např. nedojde-li kvůli chybě k aktivnímu poslání dat) lze využít pasivní načtení (pull) dat z VYMI REST API do Golemia. Pro spuštění načtení může vývojář zaslat prázdnou zprávu do
|
|
187
|
+
V případě potřeby (např. nedojde-li kvůli chybě k aktivnímu poslání dat) lze využít pasivní načtení (pull) dat z VYMI REST API do Golemia. Pro spuštění načtení může vývojář zaslat prázdnou zprávu do RabbitMQ fronty `vehicle-positions.jis.fetchJISEvents` (události), resp. `vehicle-positions.jis.fetchJISInfotexts` (infotexty), kterou zkonzumuje VP Integration Engine a za pomoci HTTP GET dotazu získá data z VYMI back end služby. Získaná data zvaliduje stejným JSON schématem jako při aktivním posílání a zašle do fronty `refreshJISEvents`, resp. `refreshJISInfotexts`, odkud jsou zpracována stejně jako při aktivním posílání. Události z pasivního načítání mají příznak `shouldTriggerWebhooks: false`, tj. [webhook](#webhook-výstup-updateeventwebhooktask) se při nich neodesílá.
|
|
166
188
|
|
|
167
|
-
Kromě manuálního spuštění vývojářem je nyní navíc aktivní cron task, který každou minutu automaticky spouští pasivní načítání dat z VYMI do Golemia. Tento mechanismus zajišťuje vyšší odolnost proti výpadkům v aktivním posílání (push) dat.
|
|
189
|
+
Kromě manuálního spuštění vývojářem je nyní navíc aktivní cron task, který každou minutu automaticky spouští pasivní načítání dat z VYMI do Golemia (routing keys `cron.vehicle-positions.jis.fetchJISEvents` a `cron.vehicle-positions.jis.fetchJISInfotexts`). Tento mechanismus zajišťuje vyšší odolnost proti výpadkům v aktivním posílání (push) dat.
|
|
168
190
|
|
|
169
|
-
Při pasivním načítání dat z VYMI do Golemia se využívá mechanismus ETag, který umožňuje rozpoznat, zda se od posledního načtení data změnila. Díky tomu se při opakovaném dotazu přenášejí pouze nová nebo upravená data, zatímco v případě beze změny se vrací pouze informace o tom, že obsah zůstal stejný. Tento přístup zmenšuje objem přenášených dat a snižuje zátěž na databázi a server. ETagy jsou spravovány zvlášť pro události a pro infotexty, aby se změny každého typu vyhodnocovaly nezávisle.
|
|
191
|
+
Při pasivním načítání dat z VYMI do Golemia se využívá mechanismus ETag, který umožňuje rozpoznat, zda se od posledního načtení data změnila. Díky tomu se při opakovaném dotazu přenášejí pouze nová nebo upravená data, zatímco v případě beze změny se vrací pouze informace o tom, že obsah zůstal stejný. Tento přístup zmenšuje objem přenášených dat a snižuje zátěž na databázi a server. ETagy jsou spravovány zvlášť pro události a pro infotexty, aby se změny každého typu vyhodnocovaly nezávisle. ETag poslední odpovědi se ukládá v Redis (`jisMetadata:events`, `jisMetadata:infotexts`) a posílá se v hlavičce `If-None-Match`; při odpovědi HTTP 304 Not Modified se načítání ukončí bez dalšího zpracování.
|
|
170
192
|
|
|
171
193
|
Při pasivním načítání se z VYMI vždy přenačítají pouze aktuální (aktivní) události a infotexty:
|
|
172
|
-
- všechny události, které mají `status` `PUBLISHED
|
|
173
|
-
- všechny infotexty
|
|
194
|
+
- všechny události, které mají `status` `PUBLISHED` a zároveň `display_period_end` nebo `active_period_end` je `NULL` nebo >= aktuální čas, nebo mají `updated_at` z posledních 24 hodin, neboli lidsky všechny publikované (ne-draft) události, které jsou zobrazované, aktivní nebo byly upraveny v posledním dnu; zahrnuty jsou i smazané (zneplatněné) události s vyplněným `deleted_at`;
|
|
195
|
+
- všechny infotexty se stejnými podmínkami jako při aktivním posílání (viz výše).
|
|
174
196
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
Události – v Golemio databázi se uchovávají všechny historické i aktuální události. Staré záznamy se nepromazávají.
|
|
178
|
-
|
|
179
|
-
Infotexty – v Golemio databázi se uchovávají pouze aktivní infotexty. Neaktivní se při každém přenačtení promazávají.
|
|
197
|
+
Obsah exportu je shodný s daty aktivního posílání (`EventFacade.getFilteredCustomFormatList`, resp. `InfotextFacade.getFilteredCustomFormatList`). ETag generuje VYMI back end (Express) z těla odpovědi.
|
|
180
198
|
|
|
181
199
|
Proces je podrobněji znázorněn na následujícím diagramu (detailnější prvky aplikační struktury jsou vynechány).
|
|
182
200
|
|
|
@@ -200,6 +218,7 @@ flowchart TB
|
|
|
200
218
|
golemio_rabbit_fetch_infotexts["`Fronta vehicle-positions.jis.fetchJISInfotexts`"];
|
|
201
219
|
golemio_rabbit_refresh_events["`Fronta vehicle-positions.jis.refreshJISEvents`"];
|
|
202
220
|
golemio_rabbit_refresh_infotexts["`Fronta vehicle-positions.jis.refreshJISInfotexts`"];
|
|
221
|
+
golemio_rabbit_refresh_infotexts_cache["`Fronta vehicle-positions.jis.refreshJISInfotextsCache`"];
|
|
203
222
|
end
|
|
204
223
|
|
|
205
224
|
subgraph "Golemio VP Integration Engine"
|
|
@@ -218,14 +237,17 @@ flowchart TB
|
|
|
218
237
|
vp_redis[("`VP Redis (Valkey)`")];
|
|
219
238
|
end
|
|
220
239
|
|
|
221
|
-
vymi_get_events <-- "`SELECT aktuálních událostí z tabulek
|
|
222
|
-
vymi_get_infotexts <-- "`SELECT aktuálních infotextů z tabulek
|
|
240
|
+
vymi_get_events <-- "`SELECT aktuálních událostí z tabulek vymi-alerts.public.events, vymi-alerts.public.event_routes, vymi-alerts.public.routes a vymi-alerts.public.event_attachments`" --> vymi_pg;
|
|
241
|
+
vymi_get_infotexts <-- "`SELECT aktuálních infotextů z tabulek vymi-alerts.public.infotexts, vymi-alerts.public.infotext_stops a vymi-alerts.public.infotext_presets`" --> vymi_pg;
|
|
223
242
|
|
|
224
243
|
golemio_rabbit_fetch_events --> golemio_fetch_events_task;
|
|
225
244
|
golemio_rabbit_fetch_infotexts --> golemio_fetch_infotexts_task;
|
|
226
245
|
golemio_rabbit_refresh_events --> golemio_refresh_events_task;
|
|
227
246
|
golemio_rabbit_refresh_infotexts --> golemio_refresh_infotexts_task;
|
|
228
247
|
|
|
248
|
+
golemio_fetch_events_task <-- "`ETag jisMetadata:events`" --> vp_redis;
|
|
249
|
+
golemio_fetch_infotexts_task <-- "`ETag jisMetadata:infotexts`" --> vp_redis;
|
|
250
|
+
|
|
229
251
|
golemio_fetch_events_task --> golemio_api_get_events;
|
|
230
252
|
golemio_fetch_infotexts_task --> golemio_api_get_infotexts;
|
|
231
253
|
|
|
@@ -235,84 +257,52 @@ flowchart TB
|
|
|
235
257
|
vymi_exports_controller_get_events --> vymi_get_events;
|
|
236
258
|
vymi_exports_controller_get_infotexts --> vymi_get_infotexts;
|
|
237
259
|
|
|
238
|
-
|
|
239
|
-
|
|
260
|
+
golemio_fetch_events_task -- "`Data z VYMI (ne při HTTP 304), shouldTriggerWebhooks: false`" --> golemio_rabbit_refresh_events;
|
|
261
|
+
golemio_fetch_infotexts_task -- "`Data z VYMI (ne při HTTP 304)`" --> golemio_rabbit_refresh_infotexts;
|
|
240
262
|
|
|
241
263
|
golemio_refresh_events_task -- "`UPSERT do tabulek vehicle-positions.pid.jis_events a vehicle-positions.pid.jis_events_ropidgtfs_routes`" --> vp_pg;
|
|
242
|
-
golemio_refresh_infotexts_task -- "`UPSERT do tabulek vehicle-positions.pid.jis_infotexts a vehicle-positions.pid.
|
|
243
|
-
golemio_refresh_infotexts_task -->
|
|
264
|
+
golemio_refresh_infotexts_task -- "`UPSERT do tabulek vehicle-positions.pid.jis_infotexts, vehicle-positions.pid.jis_infotexts_ropidgtfs_stops a vehicle-positions.pid.jis_infotexts_presets, smazání chybějících`" --> vp_pg;
|
|
265
|
+
golemio_refresh_infotexts_task --> golemio_rabbit_refresh_infotexts_cache;
|
|
266
|
+
golemio_rabbit_refresh_infotexts_cache --> golemio_refresh_infotexts_cache_task;
|
|
244
267
|
|
|
245
|
-
golemio_refresh_infotexts_cache_task
|
|
268
|
+
golemio_refresh_infotexts_cache_task <-- "`SELECT infotextů se zastávkami`" --> vp_pg;
|
|
269
|
+
golemio_refresh_infotexts_cache_task -- "`Aktualizace cache jisCache:$setId:infotexts a jisCache:$setId:stops-infotexts`" --> vp_redis;
|
|
246
270
|
```
|
|
247
271
|
|
|
248
|
-
Zdroj a formát dat pro
|
|
272
|
+
Zdroj a formát dat pro pasivní načítání jsou dále více popsány v implementační dokumentaci ([události](../implementation_documentation.md#jis-events), [infotexty](../implementation_documentation.md#jis-infotexts)), stejně tak jako [worker a tasky](../implementation_documentation.md#jisworker) a popis [uložení dat](../implementation_documentation.md#uložení-dat) včetně databázového schema a popisu retence.
|
|
249
273
|
|
|
250
|
-
##
|
|
274
|
+
## Chování databáze v Golemio
|
|
251
275
|
|
|
252
|
-
|
|
276
|
+
Zpracování každé zprávy probíhá v jedné databázové transakci; při chybě (validace, databáze) se zpráva zahodí bez opakování a data zůstanou beze změny. Retence (promazávání) JIS dat v `DataRetentionWorker` neprobíhá.
|
|
253
277
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
278
|
+
Události – v Golemio databázi se uchovávají všechny historické i aktuální události. Staré záznamy se nepromazávají. Událost smazaná ve VYMI (`deleted_at`) zůstává uložena se sloupcem `deleted_timestamp` a z výstupů (custom-format export, `alerts.pb`) je vyfiltrována.
|
|
279
|
+
- zpráva s jedinou událostí (aktivní posílání; VYMI posílá vždy nejvýše jednu událost) se uloží, jen pokud událost v databázi ještě není, nebo má novější `last_modified_timestamp` než uložený `updated_timestamp`, nebo se změnil `deleted_at`; jinak se jako zastaralá přeskočí (ochrana proti souběhu) a webhook se neodešle;
|
|
280
|
+
- zpráva s více událostmi (pasivní načítání) se uloží celá (UPSERT), bez porovnání časů;
|
|
281
|
+
- vazby událostí na linky (`jis_events_ropidgtfs_routes`) se u událostí ze zprávy nahradí aktuálním stavem, chybějící vazby se smažou.
|
|
258
282
|
|
|
259
|
-
|
|
283
|
+
Infotexty – v Golemio databázi se uchovávají pouze aktivní infotexty. Každá zpráva obsahuje úplný seznam aktuálních infotextů:
|
|
284
|
+
- infotexty, které nemají ani zastávky (`informed_entity.stops`), ani presety (`informed_entity.presets`), se neukládají;
|
|
285
|
+
- infotexty (včetně vazeb na zastávky `jis_infotexts_ropidgtfs_stops` a presety `jis_infotexts_presets`), které v přijatém seznamu chybí, se smažou; prázdný seznam smaže všechny infotexty;
|
|
286
|
+
- existující infotext se přepíše, pokud je jeho `last_modified_timestamp` >= času posledního zápisu v Golemiu (`updated_at`), nebo se změnil `active_period`;
|
|
287
|
+
- po každém uložení se celá Redis cache infotextů `jisCache:*` přenačte (task `RefreshJISInfotextsCacheTask`).
|
|
260
288
|
|
|
261
|
-
|
|
289
|
+
## Výstupy dat
|
|
262
290
|
|
|
263
|
-
###
|
|
291
|
+
### Události — custom-format export (`GET /v1/jis/events/custom-format`)
|
|
264
292
|
|
|
265
|
-
|
|
293
|
+
Endpoint je interní (přístup jen s příslušnou rolí v Golemio Access Proxy). Vrací uložené události kromě smazaných (`deleted_timestamp`); interní události (`type` `INTERNAL`) jsou ve výchozím stavu vynechány a vrátí se jen při explicitním dotazu `type=INTERNAL`. Volitelné filtry: `organizationNames` (porovnává se po převodu na velká písmena), `type` a zobrazovací okno `displayPeriodStart`/`displayPeriodEnd` — událost je vrácena, pokud její `display_period` okno zasahuje do požadovaného intervalu (`display_period_end` je `NULL` nebo >= `displayPeriodStart` a zároveň `display_period_start` <= `displayPeriodEnd`):
|
|
266
294
|
|
|
267
|
-
|
|
295
|
+

|
|
268
296
|
|
|
269
|
-
|
|
297
|
+
### Události — GTFS-RT `alerts.pb`
|
|
270
298
|
|
|
271
|
-
|
|
299
|
+
Feed generuje `GenerateFilesTask` (`GtfsRealTimeWorker`) a obsahuje jen události, které mají `type` `INCIDENT`, organizaci z `module.pid.jis.gtfsRt.events.allowedOrgs.*`, nejsou smazané a `active_period_end` je `NULL` nebo >= aktuální čas. Entita má id `alert-{id události}`, `informedEntity` obsahuje `routeId` GTFS-známých tras (viz [asymetrie](#asymetrie-gtfs-rt-protobuf-alertspb-vs-custom-format-webhook-výstup)), `url` je v případě nevyplněné hodnoty nahrazeno odkazem na detail mimořádnosti na webu PID. Texty jsou jen v `cs`/`en`.
|
|
272
300
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
Pole `effects` může obsahovat 1–3 unikátní řetězcové hodnoty. Pouze `effects[0]` se mapuje na standardní GTFS-RT `Alert.effect`; zbývající hodnoty jsou dostupné výhradně v custom-format exportu.
|
|
282
|
-
|
|
283
|
-
### `informed_entity.routes[].route_details` (snímek GTFS atributů trasy)
|
|
284
|
-
|
|
285
|
-
Vedle kompatibilního identifikátoru `id` může VYMI u každé trasy poslat volitelné pole `route_details`
|
|
286
|
-
(`route_id`, `route_short_name`, `route_long_name` — může být `null`, `route_type`). Jde o snímek GTFS
|
|
287
|
-
atributů trasy v okamžiku, kdy VYMI událost odeslala — je zahrnut i pro trasy, které v aktuálním GTFS
|
|
288
|
-
JŘ už neexistují nebo jsou neaktivní. Pole je v PID vstupním schématu (`JISEventsJsonSchema`) volitelné
|
|
289
|
-
(není v `required` u položky `routes[]`), aby starší VYMI verze bez tohoto pole neselhávaly na validaci —
|
|
290
|
-
je ale u nového VYMI producenta odesíláno vždy.
|
|
291
|
-
|
|
292
|
-
`route_details` se ukládá tak, jak přišlo, do sloupce `jis_events_ropidgtfs_routes.route_details` (JSONB,
|
|
293
|
-
nullable). Čtecí modely (custom-format export `/v1/jis/events/custom-format` a webhook `UpdateEventWebhookTask`)
|
|
294
|
-
jsou **snapshot-first**: pokud je `route_details` u dané trasy vyplněné, použije se přímo bez dotazu do GTFS
|
|
295
|
-
dat. Teprve u starších řádků, které vznikly před zavedením tohoto sloupce a mají `route_details = null`, se
|
|
296
|
-
provede fallback dohledání aktuální GTFS trasy (`ropidgtfs_routes`) podle `id`. Pokud není k dispozici ani
|
|
297
|
-
snímek, ani odpovídající GTFS trasa, je daná trasa z výstupu vynechána (chování shodné s obdobím před
|
|
298
|
-
zavedením snímku, žádná regrese).
|
|
299
|
-
|
|
300
|
-
### Asymetrie GTFS-RT protobuf (`alerts.pb`) vs. custom-format / webhook výstup
|
|
301
|
-
|
|
302
|
-
`getCurrentIncidents` (zdroj pro `alerts.pb`) používá vůči `ropidgtfs_routes` `required: true` (inner join) —
|
|
303
|
-
událost, jejíž všechny trasy jsou v aktuálním GTFS neznámé nebo neaktivní, je z protobuf feedu úplně
|
|
304
|
-
vynechána; u smíšené události (část tras GTFS zná, část ne) zůstanou v `alerts.pb` jen GTFS-známé trasy.
|
|
305
|
-
Custom-format export a webhook naproti tomu GTFS-neznámé trasy zobrazují (díky `route_details` snímku).
|
|
306
|
-
Tato asymetrie je záměrná — `alerts.pb` konzumují GTFS-RT klienti, kteří GTFS-neznámou trasu stejně neumí
|
|
307
|
-
spárovat s jízdním řádem; custom-format/webhook konzumenti (např. web PID.cz) naopak potřebují zrušené/
|
|
308
|
-
neaktivní linky zobrazit i bez GTFS záznamu.
|
|
309
|
-
|
|
310
|
-
### Webhook výstup (`UpdateEventWebhookTask`)
|
|
311
|
-
|
|
312
|
-
Kromě uložení do databáze `UpdateEventWebhookTask` po přijetí události z VYMI odešle HTTP POST na cílové
|
|
313
|
-
adresy nakonfigurované v `module.pid.jis.webhooks.eventUpdate.targets.*`. Tělo požadavku má stejný tvar jako
|
|
314
|
-
`EventCustomFormat` (viz [openapi-output.yaml](../openapi-output.yaml)), navíc obsahuje pole
|
|
315
|
-
`deleted_timestamp` (čas smazání události, nebo `null`) — to `/v1/jis/events/custom-format` nevrací a slouží
|
|
316
|
-
konzumentům webhooku k rozpoznání smazaných událostí bez nutnosti dalšího dotazu. Trasy v `informed_entity.routes`
|
|
317
|
-
jsou stejně jako u custom-format výstupu snapshot-first s GTFS fallbackem pro starší řádky bez snímku;
|
|
318
|
-
při výpadku webhooku je fallbackem pro konzumenta dotaz na `/v1/jis/events/custom-format`.
|
|
301
|
+
### Infotexty — GTFS-RT `pid_display_alerts.pb`
|
|
302
|
+
|
|
303
|
+
Experimentální feed pro e-paper displeje, generovaný stejným taskem. Obsahuje infotexty navázané na uloženou událost (`event_id` → `jis_infotexts.jis_event_id`), které jsou právě aktivní (včetně časového okna `repeat`) a mají zastávky. Na každé zastávce zůstanou jen infotexty s nejvyšší závažností (`JISInfotextStopSuppressionFilter`). Entita má id `alert-{id infotextu}`, `informedEntity` obsahuje `stopId`, `severityLevel` je `WARNING` pro `display_type` `INLINE` a `SEVERE` pro `GENERAL`; `descriptionText` pochází z infotextu, ostatní pole (`cause`, `cause_detail`, `effect`, `url`, `header_text`) z navázané události (i typu `INTERNAL`).
|
|
304
|
+
|
|
305
|
+
### Infotexty — API odjezdových a přestupních tabulí
|
|
306
|
+
|
|
307
|
+
- `/v2/pid/departureboards`, `/v3/pid/transferboards` a `/v3/pid/infotexts` čtou infotexty z PostgreSQL; u odjezdových tabulí s parametrem `preset` se vrací jen infotexty navázané na daný preset (`jis_infotexts_presets.route_name`);
|
|
308
|
+
- `/v4/pid/transferboards` čte infotexty z Redis cache `jisCache:*`.
|
package/docs/openapi-input.yaml
CHANGED
|
@@ -11,9 +11,9 @@ info:
|
|
|
11
11
|
email: golemio@operatorict.cz
|
|
12
12
|
url: https://golemio.cz
|
|
13
13
|
servers:
|
|
14
|
-
- url: https://api.golemio.cz/
|
|
14
|
+
- url: https://api.golemio.cz/input-gateway/v1
|
|
15
15
|
description: Main (production) server
|
|
16
|
-
- url: https://rabin.golemio.cz/
|
|
16
|
+
- url: https://rabin.golemio.cz/input-gateway/v1
|
|
17
17
|
description: Test (development) server
|
|
18
18
|
tags:
|
|
19
19
|
- name: 🛤 Vehicle Positions
|
|
@@ -549,6 +549,7 @@ components:
|
|
|
549
549
|
- INCIDENT
|
|
550
550
|
- DISRUPTION
|
|
551
551
|
- SERVICE_CHANGE
|
|
552
|
+
- INTERNAL
|
|
552
553
|
header_text:
|
|
553
554
|
type: object
|
|
554
555
|
properties:
|
package/docs/openapi-output.yaml
CHANGED
|
@@ -2085,11 +2085,12 @@ paths:
|
|
|
2085
2085
|
schema:
|
|
2086
2086
|
type: string
|
|
2087
2087
|
example: "INCIDENT"
|
|
2088
|
-
description: Type of events to filter by.
|
|
2088
|
+
description: Type of events to filter by. Events of type INTERNAL are excluded from the response unless explicitly requested with this parameter.
|
|
2089
2089
|
enum:
|
|
2090
2090
|
- INCIDENT
|
|
2091
2091
|
- DISRUPTION
|
|
2092
2092
|
- SERVICE_CHANGE
|
|
2093
|
+
- INTERNAL
|
|
2093
2094
|
responses:
|
|
2094
2095
|
200:
|
|
2095
2096
|
description: OK
|
|
@@ -4111,6 +4112,7 @@ components:
|
|
|
4111
4112
|
- INCIDENT
|
|
4112
4113
|
- DISRUPTION
|
|
4113
4114
|
- SERVICE_CHANGE
|
|
4115
|
+
- INTERNAL
|
|
4114
4116
|
header_text:
|
|
4115
4117
|
type: object
|
|
4116
4118
|
properties:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@golemio/pid",
|
|
3
|
-
"version": "6.0.1-dev.
|
|
3
|
+
"version": "6.0.1-dev.2912471131",
|
|
4
4
|
"description": "Golemio PID Module",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"coverage:only": "c8 npm run test:only -- --reporter min",
|
|
64
64
|
"code-coverage": "run-s prepare-db typecheck build coverage:only",
|
|
65
65
|
"format:check-staged": "pretty-quick --staged --pattern '**/*.ts'",
|
|
66
|
-
"generate-docs": "typedoc --out docs/typedoc src",
|
|
66
|
+
"generate-docs": "typedoc --tsconfig tsconfig.build.json --out docs/typedoc src",
|
|
67
67
|
"lint": "eslint --cache \"{src,test}/**/*.ts\"",
|
|
68
68
|
"validate-dependencies": "dependency-cruiser --config .dependency-cruiser.cjs src"
|
|
69
69
|
},
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
<mxfile modified="2023-05-23T09:47:11.166Z" host="Electron" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/21.2.8 Chrome/112.0.5615.165 Electron/24.2.0 Safari/537.36" etag="4dM1wg4TBuCNhn9Dqkni" version="21.2.8" type="device">
|
|
2
|
-
<diagram id="WI9T0HZ2pTsCkuznbFz-" name="Page-1">
|
|
3
|
-
<mxGraphModel dx="1418" dy="828" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0">
|
|
4
|
-
<root>
|
|
5
|
-
<mxCell id="0" />
|
|
6
|
-
<mxCell id="1" parent="0" />
|
|
7
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-39" value="" style="rounded=1;whiteSpace=wrap;html=1;movable=0;resizable=0;rotatable=0;deletable=0;editable=0;locked=1;connectable=0;" vertex="1" parent="1">
|
|
8
|
-
<mxGeometry x="164.8" y="90" width="975.2" height="760" as="geometry" />
|
|
9
|
-
</mxCell>
|
|
10
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-20" value="" style="rounded=1;whiteSpace=wrap;html=1;align=left;" vertex="1" parent="1">
|
|
11
|
-
<mxGeometry x="380" y="127.4" width="140" height="198" as="geometry" />
|
|
12
|
-
</mxCell>
|
|
13
|
-
<mxCell id="AcxdMaKK0mU5kZiv2lnr-9" value="Azure Blob<br>Storage<br>" style="aspect=fixed;html=1;perimeter=none;align=center;shadow=0;dashed=0;image;fontSize=12;image=img/lib/mscae/BlobBlock.svg;" parent="1" vertex="1">
|
|
14
|
-
<mxGeometry x="422" y="396" width="62" height="53" as="geometry" />
|
|
15
|
-
</mxCell>
|
|
16
|
-
<mxCell id="Yb9yHQ_m3vMcTtYt7nYP-4" value="Cron" style="verticalLabelPosition=bottom;html=1;verticalAlign=top;align=center;strokeColor=none;fillColor=#2875E2;shape=mxgraph.azure.scheduler;pointerEvents=1;rotation=0;" parent="1" vertex="1">
|
|
17
|
-
<mxGeometry x="803" y="188" width="70" height="80" as="geometry" />
|
|
18
|
-
</mxCell>
|
|
19
|
-
<mxCell id="Yb9yHQ_m3vMcTtYt7nYP-5" value="Azure Flexible PostgreSQL" style="verticalLabelPosition=bottom;html=1;verticalAlign=top;align=center;strokeColor=none;fillColor=#2875E2;shape=mxgraph.azure.sql_database_sql_azure;rotation=0;" parent="1" vertex="1">
|
|
20
|
-
<mxGeometry x="615.25" y="560" width="70" height="80" as="geometry" />
|
|
21
|
-
</mxCell>
|
|
22
|
-
<mxCell id="Yb9yHQ_m3vMcTtYt7nYP-6" value="Uživatelé" style="verticalLabelPosition=bottom;html=1;verticalAlign=top;align=center;strokeColor=none;fillColor=#00BEF2;shape=mxgraph.azure.user;" parent="1" vertex="1">
|
|
23
|
-
<mxGeometry x="1213.25" y="564.5" width="47.5" height="50" as="geometry" />
|
|
24
|
-
</mxCell>
|
|
25
|
-
<mxCell id="Yb9yHQ_m3vMcTtYt7nYP-7" value="Input Gateway" style="sketch=0;html=1;dashed=0;whitespace=wrap;fillColor=#2875E2;strokeColor=#ffffff;points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];verticalLabelPosition=bottom;align=center;verticalAlign=top;shape=mxgraph.kubernetes.icon;prIcon=api" parent="1" vertex="1">
|
|
26
|
-
<mxGeometry x="425" y="145.2" width="50" height="48" as="geometry" />
|
|
27
|
-
</mxCell>
|
|
28
|
-
<mxCell id="Yb9yHQ_m3vMcTtYt7nYP-8" value="Output Gateway" style="sketch=0;html=1;dashed=0;whitespace=wrap;fillColor=#2875E2;strokeColor=#ffffff;points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];verticalLabelPosition=bottom;align=center;verticalAlign=top;shape=mxgraph.kubernetes.icon;prIcon=api" parent="1" vertex="1">
|
|
29
|
-
<mxGeometry x="800" y="560" width="80" height="70" as="geometry" />
|
|
30
|
-
</mxCell>
|
|
31
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-1" value="Data Proxy" style="pointerEvents=1;shadow=0;dashed=0;html=1;strokeColor=none;fillColor=#2875E2;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;align=center;outlineConnect=0;shape=mxgraph.veeam.2d.proxy_appliance;" vertex="1" parent="1">
|
|
32
|
-
<mxGeometry x="210" y="192" width="74.8" height="78" as="geometry" />
|
|
33
|
-
</mxCell>
|
|
34
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-2" value="API key Management" style="verticalLabelPosition=bottom;html=1;verticalAlign=top;align=center;strokeColor=none;fillColor=#2875E2;shape=mxgraph.azure.access_control;" vertex="1" parent="1">
|
|
35
|
-
<mxGeometry x="1016" y="384" width="50" height="50" as="geometry" />
|
|
36
|
-
</mxCell>
|
|
37
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-3" value="Integration Engine" style="sketch=0;html=1;dashed=0;whitespace=wrap;fillColor=#2875E2;strokeColor=#ffffff;points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];verticalLabelPosition=bottom;align=center;verticalAlign=top;shape=mxgraph.kubernetes.icon;prIcon=pod;rotation=0;" vertex="1" parent="1">
|
|
38
|
-
<mxGeometry x="601" y="380" width="80" height="70" as="geometry" />
|
|
39
|
-
</mxCell>
|
|
40
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-5" value="Permission proxy" style="sketch=0;html=1;dashed=0;whitespace=wrap;fillColor=#2875E2;strokeColor=#ffffff;points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];verticalLabelPosition=bottom;align=center;verticalAlign=top;shape=mxgraph.kubernetes.icon;prIcon=role;rotation=0;" vertex="1" parent="1">
|
|
41
|
-
<mxGeometry x="1002" y="562" width="80" height="70" as="geometry" />
|
|
42
|
-
</mxCell>
|
|
43
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-8" value="TCP Input Gateway" style="sketch=0;html=1;dashed=0;whitespace=wrap;fillColor=#2875E2;strokeColor=#ffffff;points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];verticalLabelPosition=bottom;align=center;verticalAlign=top;shape=mxgraph.kubernetes.icon;prIcon=master" vertex="1" parent="1">
|
|
44
|
-
<mxGeometry x="425" y="233.2" width="50" height="48" as="geometry" />
|
|
45
|
-
</mxCell>
|
|
46
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-9" value="RabbitMQ<br>" style="sketch=0;outlineConnect=0;fontColor=#232F3E;gradientColor=none;fillColor=#2875E2;strokeColor=none;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;pointerEvents=1;shape=mxgraph.aws4.mq_broker;fillStyle=auto;rotation=0;" vertex="1" parent="1">
|
|
47
|
-
<mxGeometry x="601" y="191.4" width="80" height="70" as="geometry" />
|
|
48
|
-
</mxCell>
|
|
49
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-12" value="Redis" style="outlineConnect=0;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;shape=mxgraph.aws3.cache_node;fillColor=#2875E2;gradientColor=none;" vertex="1" parent="1">
|
|
50
|
-
<mxGeometry x="812" y="380" width="60" height="63" as="geometry" />
|
|
51
|
-
</mxCell>
|
|
52
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-13" value="Url Proxy" style="image;aspect=fixed;html=1;points=[];align=center;fontSize=12;image=img/lib/azure2/ai_machine_learning/Translator_Text.svg;" vertex="1" parent="1">
|
|
53
|
-
<mxGeometry x="1016" y="740" width="50" height="50" as="geometry" />
|
|
54
|
-
</mxCell>
|
|
55
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-17" value="" style="shape=flexArrow;endArrow=classic;html=1;rounded=0;" edge="1" parent="1">
|
|
56
|
-
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
|
57
|
-
<mxPoint x="528.5" y="229" as="sourcePoint" />
|
|
58
|
-
<mxPoint x="588.5" y="229" as="targetPoint" />
|
|
59
|
-
</mxGeometry>
|
|
60
|
-
</mxCell>
|
|
61
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-21" value="" style="shape=flexArrow;endArrow=classic;html=1;rounded=0;" edge="1" parent="1">
|
|
62
|
-
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
|
63
|
-
<mxPoint x="300" y="233.20000000000002" as="sourcePoint" />
|
|
64
|
-
<mxPoint x="360" y="233.20000000000002" as="targetPoint" />
|
|
65
|
-
</mxGeometry>
|
|
66
|
-
</mxCell>
|
|
67
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-22" value="" style="shape=flexArrow;endArrow=classic;html=1;rounded=0;" edge="1" parent="1">
|
|
68
|
-
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
|
69
|
-
<mxPoint x="790" y="230" as="sourcePoint" />
|
|
70
|
-
<mxPoint x="700" y="229" as="targetPoint" />
|
|
71
|
-
</mxGeometry>
|
|
72
|
-
</mxCell>
|
|
73
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-23" value="" style="shape=flexArrow;endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1">
|
|
74
|
-
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
|
75
|
-
<mxPoint x="640" y="370" as="sourcePoint" />
|
|
76
|
-
<mxPoint x="640" y="295" as="targetPoint" />
|
|
77
|
-
</mxGeometry>
|
|
78
|
-
</mxCell>
|
|
79
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-24" value="cache pro výpočty" style="shape=flexArrow;endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1">
|
|
80
|
-
<mxGeometry y="-30" width="100" height="100" relative="1" as="geometry">
|
|
81
|
-
<mxPoint x="691" y="412" as="sourcePoint" />
|
|
82
|
-
<mxPoint x="791" y="412" as="targetPoint" />
|
|
83
|
-
<mxPoint as="offset" />
|
|
84
|
-
</mxGeometry>
|
|
85
|
-
</mxCell>
|
|
86
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-26" value="cache pro requesty" style="shape=flexArrow;endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1">
|
|
87
|
-
<mxGeometry y="-60" width="100" height="100" relative="1" as="geometry">
|
|
88
|
-
<mxPoint x="841" y="553" as="sourcePoint" />
|
|
89
|
-
<mxPoint x="841" y="473" as="targetPoint" />
|
|
90
|
-
<mxPoint as="offset" />
|
|
91
|
-
</mxGeometry>
|
|
92
|
-
</mxCell>
|
|
93
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-28" value="" style="shape=flexArrow;endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1">
|
|
94
|
-
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
|
95
|
-
<mxPoint x="1040" y="550" as="sourcePoint" />
|
|
96
|
-
<mxPoint x="1040" y="470" as="targetPoint" />
|
|
97
|
-
</mxGeometry>
|
|
98
|
-
</mxCell>
|
|
99
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-29" value="" style="shape=flexArrow;endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1">
|
|
100
|
-
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
|
101
|
-
<mxPoint x="890" y="600" as="sourcePoint" />
|
|
102
|
-
<mxPoint x="990" y="600" as="targetPoint" />
|
|
103
|
-
</mxGeometry>
|
|
104
|
-
</mxCell>
|
|
105
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-31" value="" style="shape=flexArrow;endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1">
|
|
106
|
-
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
|
107
|
-
<mxPoint x="1040" y="733" as="sourcePoint" />
|
|
108
|
-
<mxPoint x="1040" y="653" as="targetPoint" />
|
|
109
|
-
</mxGeometry>
|
|
110
|
-
</mxCell>
|
|
111
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-32" value="" style="endArrow=classic;html=1;rounded=0;" edge="1" parent="1">
|
|
112
|
-
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
|
113
|
-
<mxPoint x="1090" y="600" as="sourcePoint" />
|
|
114
|
-
<mxPoint x="1190" y="600" as="targetPoint" />
|
|
115
|
-
</mxGeometry>
|
|
116
|
-
</mxCell>
|
|
117
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-33" value="Informační tabule<br>" style="outlineConnect=0;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;shape=mxgraph.aws3.hardware_board;fillColor=#00BEF2;gradientColor=none;" vertex="1" parent="1">
|
|
118
|
-
<mxGeometry x="1202" y="714.75" width="84" height="100.5" as="geometry" />
|
|
119
|
-
</mxCell>
|
|
120
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-34" value="" style="endArrow=classic;html=1;rounded=0;" edge="1" parent="1">
|
|
121
|
-
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
|
122
|
-
<mxPoint x="1080" y="760" as="sourcePoint" />
|
|
123
|
-
<mxPoint x="1190" y="760" as="targetPoint" />
|
|
124
|
-
</mxGeometry>
|
|
125
|
-
</mxCell>
|
|
126
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-35" value="" style="shape=flexArrow;endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1">
|
|
127
|
-
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
|
128
|
-
<mxPoint x="690" y="594.5" as="sourcePoint" />
|
|
129
|
-
<mxPoint x="790" y="594.5" as="targetPoint" />
|
|
130
|
-
</mxGeometry>
|
|
131
|
-
</mxCell>
|
|
132
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-37" value="Realtime data" style="endArrow=classic;html=1;rounded=0;" edge="1" parent="1">
|
|
133
|
-
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
|
134
|
-
<mxPoint x="40" y="240" as="sourcePoint" />
|
|
135
|
-
<mxPoint x="200" y="240" as="targetPoint" />
|
|
136
|
-
</mxGeometry>
|
|
137
|
-
</mxCell>
|
|
138
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-38" value="Periodická aktualizace dat (jízdní řády apob.)" style="endArrow=classic;html=1;rounded=0;" edge="1" parent="1">
|
|
139
|
-
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
|
140
|
-
<mxPoint x="580" y="470" as="sourcePoint" />
|
|
141
|
-
<mxPoint x="50" y="564.5" as="targetPoint" />
|
|
142
|
-
<Array as="points">
|
|
143
|
-
<mxPoint x="460" y="565" />
|
|
144
|
-
</Array>
|
|
145
|
-
</mxGeometry>
|
|
146
|
-
</mxCell>
|
|
147
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-40" value="Datová platforma Golemio" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
|
148
|
-
<mxGeometry x="870" y="90" width="180" height="30" as="geometry" />
|
|
149
|
-
</mxCell>
|
|
150
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-43" value="" style="shape=flexArrow;endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1">
|
|
151
|
-
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
|
152
|
-
<mxPoint x="640.5" y="554" as="sourcePoint" />
|
|
153
|
-
<mxPoint x="640.5" y="474" as="targetPoint" />
|
|
154
|
-
</mxGeometry>
|
|
155
|
-
</mxCell>
|
|
156
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-50" value="" style="shape=flexArrow;endArrow=classic;html=1;rounded=0;" edge="1" parent="1">
|
|
157
|
-
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
|
158
|
-
<mxPoint x="450" y="330" as="sourcePoint" />
|
|
159
|
-
<mxPoint x="450" y="390" as="targetPoint" />
|
|
160
|
-
</mxGeometry>
|
|
161
|
-
</mxCell>
|
|
162
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-53" value="" style="shape=flexArrow;endArrow=classic;html=1;rounded=0;" edge="1" parent="1">
|
|
163
|
-
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
|
164
|
-
<mxPoint x="840" y="720" as="sourcePoint" />
|
|
165
|
-
<mxPoint x="840" y="660" as="targetPoint" />
|
|
166
|
-
</mxGeometry>
|
|
167
|
-
</mxCell>
|
|
168
|
-
<mxCell id="dkLkBtVoeD-QzUvh4KKE-54" value="" style="shape=flexArrow;endArrow=classic;html=1;rounded=0;" edge="1" parent="1">
|
|
169
|
-
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
|
170
|
-
<mxPoint x="590" y="420" as="sourcePoint" />
|
|
171
|
-
<mxPoint x="496" y="420" as="targetPoint" />
|
|
172
|
-
</mxGeometry>
|
|
173
|
-
</mxCell>
|
|
174
|
-
</root>
|
|
175
|
-
</mxGraphModel>
|
|
176
|
-
</diagram>
|
|
177
|
-
</mxfile>
|