Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions PYEGERIA_ISSUES.md
Original file line number Diff line number Diff line change
Expand Up @@ -1119,6 +1119,49 @@ on an Egeria Server capability that doesn't exist yet — but the pyegeria/
Dr.Egeria-side work each will need once that capability ships is written
into the entry now, so it isn't rediscovered from scratch later.

### ISSUE-126: `ProductManager` and `DigitalBusiness` never set `collection_command_root`, so every inherited `CollectionManager` method that uses it raises `AttributeError`

**Layer:** pyegeria · **Status:** open, logged only, not fixed (awaiting approval) · **Found:** 2026-10-05,
live cleanup of a throwaway data contract (PR #427's live check).

**What:** `ProductManager.__init__` and `DigitalBusiness.__init__` call `ServerClient.__init__` directly instead
of `CollectionManager.__init__` (`GlossaryManager` does it correctly). `CollectionManager.__init__` is what sets
`self.collection_command_root`, which 27 of `CollectionManager`'s methods use, so on those two subclasses all of
them fail:

```python
pm = ProductManager(view_server, platform_url, user, pwd)
pm.delete_collection(guid, cascade=True)
# AttributeError: 'ProductManager' object has no attribute 'collection_command_root'
```

**Fix (not made):** call `CollectionManager.__init__` from both constructors, or set the attribute. A test that
constructs each `CollectionManager` subclass and asserts the attribute exists would have caught it.

---

### ISSUE-127: `CollectionManager.delete_collection(cascade=True)` silently never sends `cascadeDelete` -- same shape as ISSUE-62

**Layer:** pyegeria · **Status:** open, logged only, not fixed (awaiting approval) · **Found:** 2026-10-05, found
by capturing the request body while diagnosing a failed cleanup.

**What:** `_async_delete_collection` always pre-fills `body = {"class": "DeleteElementRequestBody"}` when none is
given and hands that dict to `_async_delete_element_request(url, body, cascade)`.
`validate_delete_element_request` applies `cascade_delete` only in its *no body* branch, so with that pre-filled dict
the flag is discarded. Captured: `delete_collection("g", cascade=True)` posts
`{'class': 'DeleteElementRequestBody', 'forLineage': False, 'forDuplicateProcessing': False}` with no
`cascadeDelete`. `MetadataExpert.delete_metadata_element(cascade_delete=True)` does send it.

**Fix (not made):** do not pre-fill the body (pass `None` so the helper applies the flag), or put `cascadeDelete` in
the pre-filled dict. Worth grepping for other callers that pre-fill a default dict *and* pass a cascade flag.

**Related, an Egeria quirk found alongside:** even with `cascadeDelete: true`, Egeria refused to delete a
`DataStructure` that still had a member `DataField` (`OMAG-GENERIC-HANDLERS-403-005 ... validateNoMemberDataFields`),
so a data contract imported by `import_data_contract*` has to be removed child-first: DataField, DataStructure,
Agreement.

---

### ISSUE-122: `AssetMaker.get_catalog_targets` / `get_catalog_target` send `metadataElementTypeName="CatalogTarget"` (a relationship type) — server rejects with OMAG-COMMON-400-019, surfaced as SERVER_ERROR_500

**Status: fixed on branch `fix/issue-122-catalog-target-type` (2026-10-04), pending PR/merge**
Expand Down
5 changes: 5 additions & 0 deletions docs/dr_egeria_manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,11 @@ Dr.Egeria organizes its commands into "families," each corresponding to a specif
- `Initiate Subscription`: take out a subscription to a digital product by running its subscription type (`ProvisioningActionProcess::<product>::Create Subscription::<type>`) with a `Subscription Requester` and `Destination Data Set`. This provisions the subscription, unlike `Create Digital Subscription`, which only records the element.
- `Cancel Subscription`: run the cancel process Egeria attached to the subscription when it was provisioned (found through its resource list).
- `Create Element`: the generic create-from-template command, moved here from Asset Maker.
- **Digital Products: subscription types and Bitol documents** (added 2026-10-05): Commands in the Digital Product Manager family that wrap `pyegeria/omvs/product_manager.py` (processors in `md_processing/v2/product_manager.py`). None is a create-or-update of a named element, so there is no `Update` form; each is safe to re-run.
- `Create Subscription Type`: add a one-time, periodic or ongoing-update subscription type to a `Digital Product`. Set `Subscription Kind` to `ONE_TIME`, `PERIODIC` (needs `Subscription Notification Interval`, in **minutes**) or `ONGOING_UPDATE` (also needs `Monitored Resources`, typically the product's asset). Egeria creates the product's notification type and the governance action process that `Initiate Subscription` runs to provision a subscription of this type; re-running reconciles an existing type rather than duplicating it. `Subscription Manager`, `Subscription License Type` and `Subscription Service Level Objective` default to the Baudot subscription manager and to those the product is governed by.
- `Import Data Contract` / `Import Data Product`: catalog an Open Data Contract Standard (ODCS) / Open Data Product Standard (ODPS) document as a `DataSharingAgreement` / a `DigitalProduct`. Re-importing the same version updates it; a new version creates new elements; a document with no `id` is skipped (reported as a failure).
- `Publish Data Contract` / `Publish Data Product`: send such a document to an `Integration Daemon`, which passes it to the connectors that registered a Bitol listener (Advanced).
- The document is read from the file named in `Document File` (YAML or JSON), resolved relative to the markdown file being processed, rather than written inline: YAML routinely contains `---` and `#` lines, which the extractor treats as horizontal rules and headings.
- **Schema Maker** (added 2026-09-11): The `pyegeria/omvs/schema_maker.py` surface — `Create`/`Update Schema Type` and `Create`/`Update Schema Attribute` (both upsert-capable, live-verified), `Create Schema Type From Template`/`Create Schema Attribute From Template`, 15 `Link`/`Detach` relationship command pairs (Nested Schema Attribute, Attribute for Schema, Foreign Key, External Schema Type, Map From/To Schema Type, Graph Edge, Query Target, Schema, Relational DB Schema, API Operations/Header/Request/Response, Schema Type Option — `Link Nested Schema Attribute` live-verified), and 3 `Add`/`Remove` classification pairs (Primary Key, Type Embedded Attribute, Calculated Value) on a schema attribute/column. Effectivity dates, Anchor ID, and Anchor Scope IDs are Advanced-level; everything else is Basic.

#### `Create Report`'s two Dictionary attributes, worked examples
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2605,6 +2605,181 @@
"max_cardinality": 1,
"level": "Advanced",
"Journal Entry": ""
},
"Digital Product": {
"variable_name": "digital_product",
"inUpdate": false,
"attr_labels": "",
"examples": "",
"default_value": "",
"valid_values": [],
"existing_element": "DigitalProduct",
"description": "The digital product the subscription type is added to (name, qualified name or GUID).",
"generated": false,
"style": "Reference Name",
"user_specified": true,
"unique": false,
"input_required": true,
"min_cardinality": 1,
"max_cardinality": 1,
"level": "Basic",
"Journal Entry": "Added 2026-10-05 -- product-manager subscription types and ODCS/ODPS documents."
},
"Subscription Kind": {
"variable_name": "subscription_kind",
"inUpdate": false,
"attr_labels": "",
"examples": "",
"default_value": "ONE_TIME",
"valid_values": [
"ONE_TIME",
"PERIODIC",
"ONGOING_UPDATE"
],
"existing_element": "",
"description": "How often subscribers are notified, and so how often the product's data is delivered: ONE_TIME (a single delivery, typically to evaluate the product), PERIODIC (every Subscription Notification Interval minutes) or ONGOING_UPDATE (when a Monitored Resource changes, but no more often than every Subscription Notification Interval minutes).",
"generated": false,
"style": "Valid Value",
"user_specified": true,
"unique": false,
"input_required": true,
"min_cardinality": 1,
"max_cardinality": 1,
"level": "Basic",
"Journal Entry": "Added 2026-10-05 -- product-manager subscription types and ODCS/ODPS documents."
},
"Subscription Manager": {
"variable_name": "subscription_manager",
"inUpdate": false,
"attr_labels": "",
"examples": "",
"default_value": "",
"valid_values": [],
"existing_element": "IntegrationConnector",
"description": "The integration connector that notifies subscribers. Defaults to the Baudot Digital Product Subscription Manager from the digital products content pack.",
"generated": false,
"style": "Reference Name",
"user_specified": true,
"unique": false,
"input_required": false,
"min_cardinality": 0,
"max_cardinality": 1,
"level": "Advanced",
"Journal Entry": "Added 2026-10-05 -- product-manager subscription types and ODCS/ODPS documents."
},
"Subscription License Type": {
"variable_name": "subscription_license_type",
"inUpdate": false,
"attr_labels": "",
"examples": "",
"default_value": "",
"valid_values": [],
"existing_element": "LicenseType",
"description": "The license type granted to a subscriber's asset. Defaults to the first license type the product is governed by.",
"generated": false,
"style": "Reference Name",
"user_specified": true,
"unique": false,
"input_required": false,
"min_cardinality": 0,
"max_cardinality": 1,
"level": "Advanced",
"Journal Entry": "Added 2026-10-05 -- product-manager subscription types and ODCS/ODPS documents."
},
"Subscription Service Level Objective": {
"variable_name": "subscription_service_level_objective",
"inUpdate": false,
"attr_labels": "",
"examples": "",
"default_value": "",
"valid_values": [],
"existing_element": "ServiceLevelObjective",
"description": "The service level objective the subscription offers. Defaults to the first service level objective the product is governed by.",
"generated": false,
"style": "Reference Name",
"user_specified": true,
"unique": false,
"input_required": false,
"min_cardinality": 0,
"max_cardinality": 1,
"level": "Advanced",
"Journal Entry": "Added 2026-10-05 -- product-manager subscription types and ODCS/ODPS documents."
},
"Subscription Notification Interval": {
"variable_name": "subscription_notification_interval",
"inUpdate": false,
"attr_labels": "",
"examples": "",
"default_value": "",
"valid_values": [],
"existing_element": "",
"description": "Minutes between notifications -- the delivery interval for a PERIODIC subscription, the minimum interval for an ONGOING_UPDATE one. In MINUTES (unlike the Governance Officer family's 'Notification Interval', which is milliseconds).",
"generated": false,
"style": "Simple Int",
"user_specified": true,
"unique": false,
"input_required": false,
"min_cardinality": 0,
"max_cardinality": 1,
"level": "Basic",
"Journal Entry": "Added 2026-10-05 -- product-manager subscription types and ODCS/ODPS documents."
},
"Monitored Resources": {
"variable_name": "monitored_resources",
"inUpdate": false,
"attr_labels": "",
"examples": "",
"default_value": "",
"valid_values": [],
"existing_element": "Referenceable",
"description": "For an ONGOING_UPDATE subscription: the elements whose changes trigger a notification -- typically the product's asset.",
"generated": false,
"style": "Reference Name List",
"user_specified": true,
"unique": false,
"input_required": false,
"min_cardinality": 0,
"max_cardinality": 1,
"level": "Basic",
"Journal Entry": "Added 2026-10-05 -- product-manager subscription types and ODCS/ODPS documents."
},
"Document File": {
"variable_name": "document_file",
"inUpdate": false,
"attr_labels": "",
"examples": "",
"default_value": "",
"valid_values": [],
"existing_element": "",
"description": "Path to a file holding the document (YAML or JSON): an Open Data Contract Standard (ODCS) data contract or an Open Data Product Standard (ODPS) data product. A relative path is resolved against the directory of the markdown file being processed.",
"generated": false,
"style": "Simple",
"user_specified": true,
"unique": false,
"input_required": true,
"min_cardinality": 1,
"max_cardinality": 1,
"level": "Basic",
"Journal Entry": "Added 2026-10-05 -- product-manager subscription types and ODCS/ODPS documents."
},
"Integration Daemon": {
"variable_name": "integration_daemon",
"inUpdate": false,
"attr_labels": "",
"examples": "",
"default_value": "",
"valid_values": [],
"existing_element": "SoftwareServer",
"description": "The integration daemon (a SoftwareServer) whose Bitol listeners receive the document.",
"generated": false,
"style": "Reference Name",
"user_specified": true,
"unique": false,
"input_required": true,
"min_cardinality": 1,
"max_cardinality": 1,
"level": "Basic",
"Journal Entry": "Added 2026-10-05 -- product-manager subscription types and ODCS/ODPS documents."
}
},
"bundles": {
Expand Down Expand Up @@ -2788,6 +2963,34 @@
"ISC Qualified Name",
"GUID"
]
},
"Subscription Type Base": {
"inherits": "Request Base",
"own_attributes": [
"Digital Product",
"Subscription Kind",
"Display Name",
"Description",
"Identifier",
"Subscription Notification Interval",
"Monitored Resources",
"Subscription Manager",
"Subscription License Type",
"Subscription Service Level Objective"
]
},
"Import Data Document Base": {
"inherits": "Request Base",
"own_attributes": [
"Document File"
]
},
"Publish Data Document Base": {
"inherits": "Request Base",
"own_attributes": [
"Integration Daemon",
"Document File"
]
}
},
"commands": {
Expand Down Expand Up @@ -3037,6 +3240,101 @@
"bundle": "Digital Subscriber",
"custom_attributes": [],
"Journal Entry": ""
},
"Create Subscription Type": {
"display_name": "create_subscription_type",
"qn_prefix": "",
"alternate_names": [],
"family": "Digital Product Manager",
"description": "Add a subscription type to a digital product: a one-time, periodic or ongoing-update way to subscribe. Creates the product's notification type and returns the governance action process that Initiate Subscription runs to provision a subscription of this type. Safe to re-run: an existing subscription type is brought into line with the request rather than duplicated.",
"verb": "Create",
"upsert": false,
"attach": false,
"level": "Basic",
"find_method": "",
"find_constraints": "",
"extra_find": "",
"extra_constraints": "",
"OM_TYPE": "SubscribingActionProcess",
"bundle": "Subscription Type Base",
"custom_attributes": [],
"Journal Entry": "Added 2026-10-05 -- product-manager subscription types and ODCS/ODPS documents."
},
"Import Data Contract": {
"display_name": "import_data_contract",
"qn_prefix": "",
"alternate_names": [],
"family": "Digital Product Manager",
"description": "Catalog an Open Data Contract Standard (ODCS) data contract file directly as an Agreement classified as a DataSharingAgreement. Re-importing the same contract version updates it; a new version creates new elements.",
"verb": "Import",
"upsert": false,
"attach": false,
"level": "Basic",
"find_method": "",
"find_constraints": "",
"extra_find": "",
"extra_constraints": "",
"OM_TYPE": "DataSharingAgreement",
"bundle": "Import Data Document Base",
"custom_attributes": [],
"Journal Entry": "Added 2026-10-05 -- product-manager subscription types and ODCS/ODPS documents."
},
"Import Data Product": {
"display_name": "import_data_product",
"qn_prefix": "",
"alternate_names": [],
"family": "Digital Product Manager",
"description": "Catalog an Open Data Product Standard (ODPS) data product file directly as a DigitalProduct. Re-importing the same product version updates it; a new version creates new elements.",
"verb": "Import",
"upsert": false,
"attach": false,
"level": "Basic",
"find_method": "",
"find_constraints": "",
"extra_find": "",
"extra_constraints": "",
"OM_TYPE": "DigitalProduct",
"bundle": "Import Data Document Base",
"custom_attributes": [],
"Journal Entry": "Added 2026-10-05 -- product-manager subscription types and ODCS/ODPS documents."
},
"Publish Data Contract": {
"display_name": "publish_data_contract",
"qn_prefix": "",
"alternate_names": [],
"family": "Digital Product Manager",
"description": "Send an ODCS data contract file to an integration daemon, which passes it on to the integration connectors that registered a Bitol listener.",
"verb": "Publish",
"upsert": false,
"attach": false,
"level": "Advanced",
"find_method": "",
"find_constraints": "",
"extra_find": "",
"extra_constraints": "",
"OM_TYPE": "SoftwareServer",
"bundle": "Publish Data Document Base",
"custom_attributes": [],
"Journal Entry": "Added 2026-10-05 -- product-manager subscription types and ODCS/ODPS documents."
},
"Publish Data Product": {
"display_name": "publish_data_product",
"qn_prefix": "",
"alternate_names": [],
"family": "Digital Product Manager",
"description": "Send an ODPS data product file to an integration daemon, which passes it on to the integration connectors that registered a Bitol listener.",
"verb": "Publish",
"upsert": false,
"attach": false,
"level": "Advanced",
"find_method": "",
"find_constraints": "",
"extra_find": "",
"extra_constraints": "",
"OM_TYPE": "SoftwareServer",
"bundle": "Publish Data Document Base",
"custom_attributes": [],
"Journal Entry": "Added 2026-10-05 -- product-manager subscription types and ODCS/ODPS documents."
}
}
}
Loading
Loading