Skip to content

fix(multi-link): surface relationship GUIDs, add Update commands for MULTI_LINK types (ISSUE-68) - #278

Merged
dwolfson merged 6 commits into
odpi:mainfrom
dwolfson:fix/pyegeria-http-endpoint-audit
Aug 18, 2026
Merged

fix(multi-link): surface relationship GUIDs, add Update commands for MULTI_LINK types (ISSUE-68)#278
dwolfson merged 6 commits into
odpi:mainfrom
dwolfson:fix/pyegeria-http-endpoint-audit

Conversation

@dwolfson

Copy link
Copy Markdown
Member

Summary

Follow-up to #275 (merged): the multi-link relationship work described in
PYEGERIA_ISSUES.md's ISSUE-68.

  • _async_new_relationship_request now returns the created relationship's
    GUID instead of discarding it; surfaced through SolutionLinkingWire and
    8 more MULTI_LINK relationship types' _async_link_X wrappers and Dr.Egeria
    processors (GovernanceLinkProcessor, ActionProcessStepLinkProcessor).
  • New pyegeria/core/relationship_multiplicity.py: async_is_multi_link() /
    async_get_relationship_category(), backed by
    ValidMetadataManager.get_all_relationship_defs()'s relationshipCategory
    field -- the real, live-queryable multi-link signal.
  • New SupportedGovernanceService OMVS wrapper (asset_maker.py) -- had
    dedicated attach/update/detach REST endpoints but no pyegeria wrapper at
    all; confirmed live against the server's OpenAPI spec.
  • New Dr.Egeria commands Update Certification, Update License,
    Update Next Process Step -- Update was never auto-generated for a
    Link-family compact command before; these follow the same hand-added
    pattern as the existing Update Lineage Relationship.
  • Found and fixed a real, pre-existing bug surfaced while verifying the new
    Update commands live: AsyncBaseCommandProcessor.execute()'s shared
    Create↔Update upsert-rewrite logic wasn't gated for relationship-only
    processors, so it silently rewrote UpdateCreate for any of them --
    this already affected the shipped Update Lineage Relationship command,
    just never exercised with a full valid attribute set before now.

Full detail, including what was investigated and deliberately not
built (3 relationship types with no Egeria-side REST endpoint at all, 5
types where Egeria itself has no GUID-targeted detach), is in
PYEGERIA_ISSUES.md's ISSUE-68.

Testing

  • New unit tests: test_relationship_multiplicity.py,
    test_solution_linking_wire_multilink.py,
    test_governance_link_multilink_guid.py,
    test_supported_governance_service.py,
    test_multilink_update_commands.py.
  • Full pytest tests/micro-tests/ green throughout.
  • Live-verified against a running Egeria server: relationship-category
    detection, SupportedGovernanceService routing, and all 3 new Update
    commands (plus the pre-existing Update Lineage Relationship, to confirm
    the shared-code fix) via --validate.

🤖 Generated with Claude Code

Egeria-api-asset-maker.http documents dedicated attach/update/detach
endpoints for SupportedGovernanceService (governance-engines/{guid}/
supported-governance-services/{guid}/attach, supported-governance-
services/{guid}/update, supported-governance-services/{guid}/detach)
that had no pyegeria wrapper at all -- confirmed via the live server's
OpenAPI spec that the endpoints exist and are GUID-based for
update/detach. The .http file's own comment already documents this as
multi-link: "the same governance engine may call the same governance
service many times, each with a different request type. The unique
identifier of the new relationship is returned so it can be updated or
removed later."

New: _async_link_supported_governance_service / link_supported_governance_service
(returns the new relationship's GUID via the fixed
_async_new_relationship_request), _async_update_supported_governance_service /
update_supported_governance_service, _async_detach_supported_governance_service /
detach_supported_governance_service.

Live-verified routing against a running server (fake GUIDs correctly
reach createRelatedElementsInStore / return 404s, not URL/shape errors,
for attach/update/detach). New unit tests
(test_supported_governance_service.py) confirm URL construction and
GUID return without a live server.

No Dr.Egeria compact command exists for this relationship type yet --
out of scope here; this commit is the OMVS wrapper only (see ISSUE-68 in
PYEGERIA_ISSUES.md).

The other 3 OMVS-wrapper gaps found in the original MULTI_LINK audit
(AssociatedSecurityList, DataLineageRelationship, NetworkGatewayLink)
were NOT built: checked against a live server's OpenAPI spec as well as
the repo's .http ground truth and found no dedicated REST endpoint for
any of the three at all (AssociatedSecurityListProperties exists only as
a schema, referenced by zero paths) -- only the generic, awkward
MetadataExpert endpoint could create them (CLAUDE.md's documented
ElementProperties/propertyValueMap gotcha), a materially different task
than wrapping a real dedicated endpoint. Flagged for the user rather
than guessing at undocumented URLs.

Signed-off-by: Dan Wolfson <dan.wolfson@pdr-associates.com>
…ense/Next Process Step (ISSUE-68)

Update was never auto-generated for a Link-family compact command
(build_command_variants' LINK_VERBS has no "Update"); the only prior
example was Lineage Linker's hand-added "Update Lineage Relationship".
Adds the same pattern for the 3 MULTI_LINK relationship types where the
OMVS layer's Update is already GUID-based and a Dr.Egeria Link command
already exists:

- New compact commands (via the Dr.Egeria Spec Editor's REST API, per
  CLAUDE.md): "Update Certification", "Update License"
  (commands_governance_officer_compact.json), "Update Next Process Step"
  (commands_action_author.json). Each reuses its sibling Link command's
  existing attributes (minus the two endpoint-resolution attributes
  Update doesn't need) via a new bundle.
- GovernanceLinkProcessor.apply_changes(): new Update branch for
  Certification/License, resolving the relationship GUID via the
  existing _resolve_relationship_guid() and calling
  _async_update_certification/_async_update_license. Registered
  explicitly in dr_egeria.py (register_governance_processors()'s family
  loop routes any non-Link verb to GovernanceProcessor, the *element*
  processor, by default -- same override pattern as "Create Embedded
  Process").
- ActionProcessStepLinkProcessor.apply_changes(): new Update branch for
  NextGovernanceActionProcessStep, calling
  _async_update_next_action_process_step (auto-routed via the family
  loop's existing om_type special-case, no explicit reg() needed). Also
  fixed the Link branch to capture and display the GUID
  _async_setup_next_action_process_step now returns (previously
  discarded, same gap as the other Link-branch fixes in the prior
  commit).
- "Update Agreement Actor" was considered and dropped: checked
  Egeria-api-collection-manager.http directly and AgreementActor has no
  update endpoint at all, only attach/detach.

Second bug found and fixed while verifying these live (blocked the
feature, not part of the original request): AsyncBaseCommandProcessor
.execute()'s step 5 (the shared Create<->Update upsert-transition logic)
was not gated by supports_target_element_lookup() like steps 1a/3/7 are.
A relationship-only processor (as_is_element always None, no
qualified_name) silently had its verb rewritten Update -> Create --
confirmed live on both the 3 new commands here AND, independently, the
pre-existing "Update Lineage Relationship" (apparently never exercised
through --validate/--process with a full valid attribute set before).
Fixed by gating the existence/rewrite side effects on
supports_target_element_lookup() (current_qn itself stays unconditional,
since it's read later in the method regardless) and overriding that
method to return False in GovernanceLinkProcessor,
ActionProcessStepLinkProcessor, LineageLinkProcessor, and
UpdateLineageRelationshipProcessor. Not comprehensively audited: every
other relationship-only processor has the same latent exposure but none
currently register an Update-verb command, so it's dormant for them --
flagged in PYEGERIA_ISSUES.md as a structural risk for the next one
added, not fixed preemptively.

New tests: test_multilink_update_commands.py (6 tests). All 3 new
commands (plus "Update Lineage Relationship", to confirm the shared-code
fix) live-verified via --validate against a running server -- each now
correctly keeps verb=Update through execute() instead of silently
becoming Create. Full pytest tests/micro-tests/ green throughout.

Signed-off-by: Dan Wolfson <dan.wolfson@pdr-associates.com>
…g fix

Extends the ISSUE-68 writeup with the SupportedGovernanceService wrapper
follow-up, the 5 total MULTI_LINK types with no Egeria-side GUID-targeted
detach endpoint (ValidValuesImplementation + 4 more found on re-check:
MediaReference/ExternalReferenceLink/CitedDocumentLink/AgreementItem),
the 3 missing-OMVS-wrapper types checked against a live server's OpenAPI
spec and left unbuilt (no dedicated endpoint exists for any of them),
and the new Update Certification/License/Next Process Step commands
plus the AsyncBaseCommandProcessor upsert-rewrite bug they surfaced and
fixed.

Signed-off-by: Dan Wolfson <dan.wolfson@pdr-associates.com>
@dwolfson
dwolfson merged commit 123748b into odpi:main Aug 18, 2026
1 check passed
@dwolfson
dwolfson deleted the fix/pyegeria-http-endpoint-audit branch August 19, 2026 08:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant