handlers.relation_sync_handler
Synchronizes relations from one fact sheet type to another fact sheet type.
Relation triangle:
- There are 3 fact sheet types: 0, 1 and 2.
- rel_0_to_1 and rel_1_to_2 are leading.
- rel_0_to_2 is derived from the two leading relations.
Example: A Server with the ITComponents "Windows Server 2019" and "IBM DB2" is linked to an Application. Then this automation links the ITComponents "Windows Server 2019" and "IBM DB2" to the Application as well. If the Server is removed from the Application or upgraded to another operating system, the ITComponents of the Application are kept consistent automatically (outdated ones removed, new ones added).
You can set the config value "delete_outdated" to False (default: True) if you don't want to
automatically clean up outdated relations. Works if you touch rel_0_to_1 or rel_1_to_2.
WARNING: If this is set to True, it really removes all relations between fs0 and fs2 that don't have a linking
fs1 between them! In the "Server" example, it really removes all ITComponents from an Application that are not
linked to any of the Application's Servers, also the manually-linked ones. If you don't want that, set
keep_manual_relations to True.
Managed relations: every rel_0_to_2 relation that has a linking fs1 gets a generated description, ending with
description_suffix in square brackets (default: "ARONIS_AUTOLINK" -> "[ARONIS_AUTOLINK]"). With
trace_relations (default: False), the description lists the linking fs1 fact sheets as Markdown links;
without, it only names the fs1 fact sheet type. description_prefix replaces that leading English sentence
with your own text (e.g. in your workspace's language). The description is rewritten whenever it is outdated (a
manual relation becomes managed, or - with trace_relations - its fs1 links change).
With keep_manual_relations, only relations carrying the suffix (or provided by the fs1 of a just-removed
relation) are deleted - this also works when the fs1 was archived, whose relations LeanIX no longer exposes.
Run an initial sync after activating this, so all existing relations get their description.
Restoring an archived fs1 recovers its relations (RelationRecoveredEvent, handled like RelationCreatedEvent), so
the rel_0_to_2 relations its archiving removed come back. Requires RELATION_RECOVERED in the webhook's tag sets
(default for new webhooks; existing ones: add it in the Webhooks manager).
An initial sync also applies delete_outdated: without keep_manual_relations, it deletes every rel_0_to_2
relation without a linking fs1; with it, only managed ones (none right after migrating unmarked relations).
You can set the config value "watch_auto_relations" to True (default: False) if you want to monitor freshly created/modified/deleted rel_0_to_2 relations and see if the edit was ok, or if it needs to be reverted.
A deleted rel_0_to_2 relation that still has a linking fs1 is restored (as a managed relation). Without
keep_manual_relations, a manual rel_0_to_2 relation created / updated without a linking fs1 is deleted as
well. Managed relations (description suffix) are never deleted this way: LeanIX shows freshly written relations
with a delay, so one the sync just created can look unjustified for a few seconds - if it really is outdated, the
regular sync deletes it. The config syncs as usual, too. Note: ANY deleted relation that still has a linking fs1
is restored, also one a user deleted on purpose - to get rid of it, remove the rel_0_to_1 or rel_1_to_2 relation.
The two configs for permanent use (delete_outdated / keep_manual_relations / watch_auto_relations):
- true / true / true: outdated relations are deleted, wrongly deleted ones restored, manual ones are kept.
- true / false / true: same, but manual relations are not allowed (deleted right away / on the next sync).
Other combinations are meant for rollout only (e.g.
delete_outdatedfalse for a careful first activation,watch_auto_relationsfalse during the initial sync).
Whenever you set up a new relation_sync automation, make sure to follow this procedure:
- Deactivate the Webhook
- Create the feature config using watch_auto_relations=false
- Trigger the initial full sync in the web UI
- Update the feature config: watch_auto_relations=true
- Re-activate the webhook.
Declare the exact fact-sheet data this handler needs, so the webhook event loop (process_event in workspace/views_module.py) can load a single lean FastFactSheet per event instead of the full fact sheet.
Return a dict:
{
"fields": [
Return None (the default) to signal "requirements cannot be declared statically" - e.g. handlers that exec/eval config-supplied code. The event loop then loads the full fact sheet for that event, so correctness is always preserved. This is a standalone hook (deliberately not tied to the initial_sync_* hooks, which are slated to migrate onto it later).
Called automatically whenever a FactSheetUpdated event comes in via webhook.
For a leading relation (rel_0_to_1 / rel_1_to_2, either direction): the fs0 / fs2 end(s) to re-sync, as (corner, fs1, mode) tuples - mode None for an fs0 corner, "reverse" for an fs2 corner. Decided by the relation type, not the fact sheet type, so that configs with identical fact sheet types work, e.g. (Organization, Organization, Application) with relToParent: there, both ends of a relToParent relation are Organizations, but only the "from" end of relToParent (= the "to" end of relToChild) is the fs0.
Legacy detection of auto-created relations (before descriptions were managed): the fact sheets the fs1 of a
just-removed relation is linked to. Empty if the fs1 is archived (LeanIX hides its relations) or gone - the
managed description (see is_managed) covers those cases.
True if a rel_0_to_2 relation was created / taken over by this handler (its description carries the suffix).
Description of a managed rel_0_to_2 relation. With trace_relations: one Markdown link per linking fs1, sorted,
so both triangle corners (normal and reverse mode) generate exactly the same text and never flip-flop.
Without: a fixed sentence naming the fs1 fact sheet type.
description_prefix (if set) replaces that leading sentence verbatim - e.g. in the workspace's language.
The id of the rel_0_to_2 relation from_id -> to_id if it must be deleted: NO fs1 links the two fact
sheets AND it is a manual relation (no managed description). None otherwise, or if a request failed.
Relations this handler creates (sync / restore) always carry the managed description. LeanIX returns freshly written relations with a delay, so such a relation, created for a brand-new rel_0_to_1 / rel_1_to_2 relation, may look unjustified for a few seconds - the marker tells it apart from a manual one without waiting. (If it really is outdated, the regular sync deletes it.)
True / False whether an fs1 links the two fact sheets; None if the request failed.
The fs1 fact sheets (dicts with id, type, displayName) linking from_id and to_id (fs0 and fs2, in either
order); None if the request failed.