@klok-integration/cli 0.7.302 → 0.7.309
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/assets/agents/knowledge/glossary.md +4 -1
- package/assets/agents/knowledge/platform-rules.md +15 -3
- package/assets/agents/knowledge/roles/integration-architect.md +11 -1
- package/assets/agents/knowledge/roles/integration-developer.md +9 -3
- package/assets/agents/skills/klok-route/SKILL.md +7 -3
- package/assets/agents/skills/klok-solution/SKILL.md +2 -1
- package/dist/cli.js +7 -7
- package/package.json +1 -1
|
@@ -15,7 +15,10 @@ it as the source does.
|
|
|
15
15
|
| Tenant | An organisation on the platform, and its security boundary; every topic, ODL object and GitLab group belongs to one tenant |
|
|
16
16
|
| Domain | A business area inside a tenant. `common` is shared by the tenant's domains, `public` is open to anyone |
|
|
17
17
|
| Route, route id | One Camel route per Java class (except a `KlokRestApi`, one per operation, and a `KlokRuntimeInstanceRoute`, one per instance `<RouteId>#<instanceKey>`). Its id is `<TENANTSHORT><NNN><LEG><seq>_<Description>`, for example `KLK007T1_PublishKlokStandard`; the class name is the id |
|
|
18
|
-
| Leg | The letter in a route id: I ingress
|
|
18
|
+
| Leg | The letter in a route id: I ingress, P processing, E egress, A API, S sub route, T timer |
|
|
19
|
+
| Ingress, egress | An ingress is a route that takes a message from outside the platform onto the broker; an egress takes a message off the broker to the outside. An ingress is an onramp or a channel adapter, an egress an offramp or a channel adapter. As a word for a service (`klok-postmark-ingress`) it says what the service is, never a permission |
|
|
20
|
+
| Onramp, offramp | An onramp is an ingress with mapping: the system's own format (class X) becomes a platform model (class A, B or C) before it reaches the broker. An offramp is an egress that maps a platform model to the receiving system's format at the last moment |
|
|
21
|
+
| Channel adapter | An ingress or egress that only converts the protocol (HTTP to the broker, the broker to SFTP); the payload stays as it was received. Good design when it is motivated, for example receiving with minimal handling so that no call is lost while a later leg maps; a system's format put on the broker without such a reason is an anti-pattern |
|
|
19
22
|
| Tenant short name | `TENANTSHORT`, three upper case letters that start every solution and route id of a tenant: the first three consonants of the tenant's name (`KLK` for klok, `DGR` for degerfors), decided by the platform |
|
|
20
23
|
| Solution | The business flow a set of routes implements; its id is the route id's prefix, for example `KLK007`. The id is allocated once, by a merge request in the tenant's `integration-solutions` registry, and never reused; a solution is reserved, active or retired |
|
|
21
24
|
| Solution document | The `README.md` of a solution in the tenant's `integration-solutions` registry: its services, legs and flows, kept true to what is built |
|
|
@@ -12,9 +12,20 @@ documentation or the dependency catalog can give you.
|
|
|
12
12
|
possible by hand in GitLab.
|
|
13
13
|
* Systems talk to the broker, never to each other. Point-to-point calls, a shared database or a shared file system
|
|
14
14
|
between systems are not a Klok design.
|
|
15
|
-
*
|
|
16
|
-
|
|
15
|
+
* Ingress and egress are the routes that take messages from outside onto the broker and off the broker to the
|
|
16
|
+
outside. An ingress is an **onramp** (with mapping: system format X to a platform model A, B or C) or a
|
|
17
|
+
**channel adapter** (protocol conversion only, the payload stays as received); an egress is an offramp or a sink
|
|
18
|
+
channel adapter.
|
|
19
|
+
* Transform at the edge. When data from one system is to reach other systems or domains, the onramp transforms
|
|
20
|
+
it from the system's format to a class C or B model, and the offramp transforms it to the receiving system's
|
|
17
21
|
format at the last moment. Replacing a system then changes only its own ingress and egress.
|
|
22
|
+
* A channel adapter that puts a system's format on the broker is good design when it is motivated: you receive
|
|
23
|
+
with as little handling as possible so that no call from the system is lost, the message waits safely on the
|
|
24
|
+
topic (it can be processed again, or wait for a receiving system that is down), and a later processing leg or
|
|
25
|
+
egress maps it. The solution document says why, which leg maps, and that no other system or domain reads the X
|
|
26
|
+
topic. Example: Postmark inbound mail in KLK006, received by a channel adapter in `klok-postmark-ingress` so that a support mail never bounces while a product is redeployed. Letting class X onto the broker carelessly and without such a
|
|
27
|
+
reason is an anti-pattern and breaks Klok best practice; ask of every ingress "onramp or channel adapter, and
|
|
28
|
+
why?" (https://docs.klok.dev/klok-integration-strategy-and-tactics/platform-2-0/ingress-and-egress/).
|
|
18
29
|
* Prefer fact events (the whole object) over notifications (an id only).
|
|
19
30
|
* Hierarchy: tenant (the security boundary; every topic, ODL object and GitLab group belongs to one), then domain
|
|
20
31
|
(a business area inside the tenant). Domain `common` is shared by the tenant's domains, `public` is open to
|
|
@@ -45,7 +56,8 @@ documentation or the dependency catalog can give you.
|
|
|
45
56
|
* out of the platform: `KlokOfframpRoute`, `KlokOfframpRouteSync` (serves requests from the broker),
|
|
46
57
|
`KlokOfframpRouteWithResult`;
|
|
47
58
|
* on the broker: `KlokProcessingRoute`, `KlokSchemaUpgradeBridge` / `KlokSchemaDowngradeBridge`;
|
|
48
|
-
* protocol only,
|
|
59
|
+
* protocol only, the payload as received (a channel adapter, see the principles): `KlokChannelAdapterSourceRoute`
|
|
60
|
+
/ `KlokChannelAdapterSinkRoute`;
|
|
49
61
|
* APIs: `KlokRestApi` with one `KlokRestApiHandlerRoute` per operation; a SOAP API is a `KlokCustomRoute` with
|
|
50
62
|
camel-cxf; long-running work is a `KlokAsyncTaskWorkerRoute` behind a 202 with a task reference;
|
|
51
63
|
* everything else: `KlokCustomRoute`; reusable pieces: `KlokSubRoute`, `KlokEnrichSubRoute`.
|
|
@@ -86,7 +86,10 @@ Into the platform:
|
|
|
86
86
|
* A webhook sender: `KlokWebhookOnrampRoute`.
|
|
87
87
|
* The caller needs a full business reply now: `KlokOnrampRouteSync`. Call it coupling and debt, with an aggressive
|
|
88
88
|
timeout.
|
|
89
|
-
* Same payload, protocol only: `KlokChannelAdapterSourceRoute`.
|
|
89
|
+
* Same payload, protocol only: `KlokChannelAdapterSourceRoute`. Either the payload already is the model its readers
|
|
90
|
+
need, or receiving with minimal handling is the point (no call may be lost, the message must wait on the topic
|
|
91
|
+
for a receiver that is down) and a later leg maps. Write the reason in the solution document; a system's format
|
|
92
|
+
let onto the broker without one is the anti-pattern.
|
|
90
93
|
|
|
91
94
|
Out of the platform:
|
|
92
95
|
|
|
@@ -176,6 +179,13 @@ synchronous bridge, a timeout of about ten seconds, `[TACTICAL]` on the solution
|
|
|
176
179
|
the target is down. The strategy-aligned alternative: `KlokOnrampRoute` answering 202 with a task reference, and the
|
|
177
180
|
front end polling or listening on a websocket. If they keep the bridge, write down the debt and the unwind condition.
|
|
178
181
|
|
|
182
|
+
**Postmark inbound mail for five products.** A support mail must not bounce because QuickRace is redeployed or
|
|
183
|
+
down for a day of planned upgrade. Ingress: a channel adapter per account in
|
|
184
|
+
`klok-postmark-ingress` (KLK006): receive the webhook, put the payload on a topic unchanged, answer Postmark once
|
|
185
|
+
the broker has it. An egress per product delivers each message to the right inbox and maps there. The solution
|
|
186
|
+
document names the reason and the mapping leg; no other domain reads the Postmark topic. That is a motivated
|
|
187
|
+
channel adapter, not `[TACTICAL]`.
|
|
188
|
+
|
|
179
189
|
**"The offramp can just read the CRM database for the e-mail field."** Reject: that couples the offramp to CRM's
|
|
180
190
|
schema. CRM publishes customer facts; if the e-mail is missing, extend the fact event or add an enricher in
|
|
181
191
|
processing against a master data API on the platform. No SQL credential crosses a domain boundary.
|
|
@@ -30,7 +30,9 @@ Walk it from the top; do not pick a base class from habit.
|
|
|
30
30
|
(the egress then owns retries, dead letters and alerts);
|
|
31
31
|
* a webhook: `KlokWebhookOnrampRoute`;
|
|
32
32
|
* the caller needs a full business reply now: `KlokOnrampRouteSync`, hard coupling, use rarely;
|
|
33
|
-
* the payload
|
|
33
|
+
* protocol only, the payload as received: `KlokChannelAdapterSourceRoute`, when the payload already is the
|
|
34
|
+
model the readers need, or when receiving with minimal handling is the motivated design and a later leg
|
|
35
|
+
maps (see *Channel adapters and APIs*).
|
|
34
36
|
* Out of the platform:
|
|
35
37
|
* transform into the target's format: `KlokOfframpRoute`;
|
|
36
38
|
* same format: `KlokChannelAdapterSinkRoute`;
|
|
@@ -175,8 +177,12 @@ its own `retry.*`, `dlq.*` or `failure.*` keys; configure its caller.
|
|
|
175
177
|
|
|
176
178
|
## Channel adapters and APIs
|
|
177
179
|
|
|
178
|
-
A channel adapter
|
|
179
|
-
a field is mapped it is an onramp or an offramp.
|
|
180
|
+
A channel adapter only converts the protocol: the same payload over another protocol, only `fromUri()` and
|
|
181
|
+
`toUri()`. As soon as a field is mapped it is an onramp or an offramp. Use a source channel adapter for a system's
|
|
182
|
+
own format only for a reason the solution document states: you must accept every call without losing a message, so
|
|
183
|
+
the route does as little as possible, the message waits on the topic, and a processing leg or the egress maps it
|
|
184
|
+
later (Postmark inbound mail in KLK006). A system's format on the broker without that reason, read by other domains,
|
|
185
|
+
is the anti-pattern the refusals below describe.
|
|
180
186
|
|
|
181
187
|
`KlokRestApi` declares its operations in `get()`, `post()`, `put()` and `delete()`, one `KlokRestApiHandlerRoute`
|
|
182
188
|
per operation; an operation's route id is `<ApiRouteId>.<verb><path>`. Errors are answered as JSON
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: klok-route
|
|
3
|
-
description: Write or change a Camel route on the Klok Quarkus extension 2.0 (onramp, processing, offramp, REST API handler, async task worker, custom route) with the correct naming, topics and topic purpose, configuration, error handling, tests and klok-docs. Use for any change inside a Klok integration project.
|
|
3
|
+
description: Write or change a Camel route on the Klok Quarkus extension 2.0 (onramp, channel adapter, processing, offramp, REST API handler, async task worker, custom route) with the correct naming, topics and topic purpose, configuration, error handling, tests and klok-docs. Use for any change inside a Klok integration project.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Writing a Klok route
|
|
@@ -13,8 +13,12 @@ motivates.
|
|
|
13
13
|
|
|
14
14
|
## Steps
|
|
15
15
|
|
|
16
|
-
1. **Pick the pattern.** Ingress from a system: `KlokOnrampRoute<SYS, DOM
|
|
17
|
-
`
|
|
16
|
+
1. **Pick the pattern.** Ingress from a system: an onramp, `KlokOnrampRoute<SYS, DOM>`, which maps; or a channel
|
|
17
|
+
adapter, `KlokChannelAdapterSourceRoute<MODEL>`, which only converts the protocol, when receiving with minimal
|
|
18
|
+
handling is the motivated design and a later leg maps (the solution document says why; a system's own format
|
|
19
|
+
let onto the broker without a reason is an anti-pattern,
|
|
20
|
+
https://docs.klok.dev/klok-integration-strategy-and-tactics/platform-2-0/ingress-and-egress/); transformation
|
|
21
|
+
between datamodels: `KlokProcessingRoute<IN, OUT>`; egress to a system: `KlokOfframpRoute<DOM, SYS>`; synchronous request/reply:
|
|
18
22
|
the `Sync` variants; REST: `KlokRestApi` plus one `KlokRestApiHandlerRoute` per operation; long running work:
|
|
19
23
|
`KlokAsyncTaskWorkerRoute<REQ, RES>`; anything else: `KlokCustomRoute`.
|
|
20
24
|
2. **Name it.** `<TENANTSHORT><NNN><LEG><seq>_<Description>`, one class per route. `<TENANTSHORT><NNN>` is the id of
|
|
@@ -45,7 +45,8 @@ shared platform service) in `klok/integration-solutions`.
|
|
|
45
45
|
6. **Classify every service** the solution needs: *new project*, *new routes in an existing project*, *reused,
|
|
46
46
|
slight change*, *reused as is*, *client change*. Name the repository of each.
|
|
47
47
|
7. **Map the legs.** For every route: id (`<TENANTSHORT><NNN><LEG><seq>_<Description>`, leg and sequence not used
|
|
48
|
-
before — `klok solutions check` reports duplicates), project, pattern base class
|
|
48
|
+
before — `klok solutions check` reports duplicates), project, pattern base class (for an ingress: onramp or
|
|
49
|
+
channel adapter, and why — a channel adapter needs its reason and the leg that maps), topics with their purpose,
|
|
49
50
|
datamodels and their class, task types, configuration keys, and how the legs interact (diagrams in the flows
|
|
50
51
|
section). Route configuration and details stay in the project's `klok-docs/`; the solution links there.
|
|
51
52
|
8. **Choose the technology deliberately.**
|