pyegeria 5.4.0.23__py3-none-any.whl → 5.4.0.25__py3-none-any.whl

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.
Files changed (54) hide show
  1. commands/cat/debug_log +7967 -465
  2. commands/cat/debug_log.2025-08-15_09-14-07_444802.zip +0 -0
  3. commands/cat/debug_log.2025-08-16_10-21-59_388912.zip +0 -0
  4. commands/cat/debug_log.2025-08-17_11-34-27_981852.zip +0 -0
  5. commands/cat/dr_egeria_md.py +36 -6
  6. commands/cat/logs/pyegeria.log +3 -135
  7. md_processing/.DS_Store +0 -0
  8. md_processing/__init__.py +12 -6
  9. md_processing/data/commands.json +8523 -2234
  10. md_processing/dr_egeria_inbox/gov_def.md +76 -18
  11. md_processing/dr_egeria_inbox/img.png +0 -0
  12. md_processing/dr_egeria_inbox/product.md +185 -24
  13. md_processing/dr_egeria_outbox/.obsidian/workspace.json +5 -5
  14. md_processing/dr_egeria_outbox/monday/processed-2025-08-19 07:05-product.md +426 -0
  15. md_processing/dr_egeria_outbox/monday/processed-2025-08-19 07:56-product.md +212 -0
  16. md_processing/dr_egeria_outbox/monday/processed-2025-08-19 09:43-product.md +201 -0
  17. md_processing/dr_egeria_outbox/tuesday/processed-2025-08-19 10:55-product.md +209 -0
  18. md_processing/md_commands/governance_officer_commands.py +247 -178
  19. md_processing/md_commands/product_manager_commands.py +730 -580
  20. md_processing/md_processing_utils/common_md_proc_utils.py +170 -12
  21. md_processing/md_processing_utils/common_md_utils.py +126 -28
  22. md_processing/md_processing_utils/extraction_utils.py +2 -2
  23. md_processing/md_processing_utils/md_processing_constants.py +14 -10
  24. pyegeria/.DS_Store +0 -0
  25. pyegeria/__init__.py +1 -1
  26. pyegeria/_client_new.py +61 -12
  27. pyegeria/_exceptions_new.py +6 -0
  28. pyegeria/_output_formats.py +42 -2
  29. pyegeria/collection_manager.py +79 -14
  30. pyegeria/{data_designer_omvs.py → data_designer.py} +1171 -1675
  31. pyegeria/glossary_browser.py +1259 -0
  32. pyegeria/{glossary_manager_omvs.py → glossary_manager.py} +1181 -1099
  33. pyegeria/governance_officer.py +1 -3
  34. pyegeria/load_config.py +1 -1
  35. pyegeria/models.py +37 -4
  36. pyegeria/output_formatter.py +2 -1
  37. pyegeria/project_manager.py +1952 -0
  38. pyegeria/utils.py +5 -2
  39. {pyegeria-5.4.0.23.dist-info → pyegeria-5.4.0.25.dist-info}/METADATA +1 -1
  40. {pyegeria-5.4.0.23.dist-info → pyegeria-5.4.0.25.dist-info}/RECORD +43 -44
  41. md_processing/dr_egeria_outbox/friday/processed-2025-07-18 15:00-product.md +0 -62
  42. md_processing/dr_egeria_outbox/friday/processed-2025-07-18 15:13-product.md +0 -62
  43. md_processing/dr_egeria_outbox/friday/processed-2025-07-20 13:23-product.md +0 -47
  44. md_processing/dr_egeria_outbox/friday/processed-2025-08-01 11:55-data_test3.md +0 -503
  45. md_processing/dr_egeria_outbox/monday/processed-2025-07-14 12:38-data_designer_out.md +0 -663
  46. md_processing/dr_egeria_outbox/monday/processed-2025-07-21 10:52-generated_help_report.md +0 -2744
  47. md_processing/dr_egeria_outbox/monday/processed-2025-07-21 18:38-collections.md +0 -62
  48. md_processing/dr_egeria_outbox/monday/processed-2025-08-01 11:34-gov_def.md +0 -444
  49. md_processing/dr_egeria_outbox/processed-2025-08-03 16:05-glossary_list.md +0 -37
  50. pyegeria/glossary_browser_omvs.py +0 -3840
  51. pyegeria/governance_officer_omvs.py +0 -2367
  52. {pyegeria-5.4.0.23.dist-info → pyegeria-5.4.0.25.dist-info}/LICENSE +0 -0
  53. {pyegeria-5.4.0.23.dist-info → pyegeria-5.4.0.25.dist-info}/WHEEL +0 -0
  54. {pyegeria-5.4.0.23.dist-info → pyegeria-5.4.0.25.dist-info}/entry_points.txt +0 -0
@@ -13,11 +13,12 @@ from rich.markdown import Markdown
13
13
 
14
14
  from md_processing.md_processing_utils.common_md_proc_utils import (parse_upsert_command, parse_view_command)
15
15
  from md_processing.md_processing_utils.common_md_utils import update_element_dictionary, setup_log, set_update_body, \
16
- set_element_status_request_body, set_prop_body, set_metadata_source_request_body, set_peer_gov_def_request_body, \
17
- set_rel_request_body, set_create_body, set_collection_classifications, set_collection_property_body
16
+ set_element_status_request_body, set_prop_body, set_delete_request_body, set_rel_request_body, set_peer_gov_def_request_body, \
17
+ set_rel_request_body, set_create_body, set_collection_classifications, set_product_body
18
+
18
19
  from md_processing.md_processing_utils.extraction_utils import (extract_command_plus, update_a_command)
19
20
  from md_processing.md_processing_utils.md_processing_constants import (load_commands, ERROR)
20
- from pyegeria import DEBUG_LEVEL, body_slimmer, to_pascal_case
21
+ from pyegeria import DEBUG_LEVEL, body_slimmer, to_pascal_case, PyegeriaException, print_basic_exception, print_exception_table
21
22
  from pyegeria.egeria_tech_client import EgeriaTech
22
23
 
23
24
  GERIA_METADATA_STORE = os.environ.get("EGERIA_METADATA_STORE", "active-metadata-store")
@@ -56,7 +57,7 @@ def add_member_to_collections(egeria_client: EgeriaTech, collection_list: list,
56
57
  Add member to data dictionaries and data specifications.
57
58
  """
58
59
  body = {
59
- "class": "RelationshipRequestBody", "properties": {
60
+ "class": "NewRelationshipRequestBody", "properties": {
60
61
  "class": "CollectionMembershipProperties", "membershipRationale": "User Specified",
61
62
  "notes": "Added by Dr.Egeria"
62
63
  }
@@ -144,267 +145,267 @@ def update_data_collection_memberships(egeria_client: EgeriaTech, entity_type: s
144
145
  # @logger.catch
145
146
 
146
147
 
147
- @logger.catch
148
- def add_field_to_data_structures(egeria_client: EgeriaTech, display_name: str, struct_list: list, guid) -> None:
149
- """
150
- Add data field to data structures.
151
- """
152
-
153
- try:
154
- for structure_guid in struct_list:
155
- egeria_client.link_member_data_field(structure_guid, guid, None)
156
- msg = f"Added `{display_name}` to structure `{structure_guid}`"
157
- logger.info(msg)
158
- return
159
-
160
- except Exception as e:
161
- console.print_exception()
162
-
163
-
164
- @logger.catch
165
- def remove_field_from_data_structures(egeria_client: EgeriaTech, display_name: str, struct_list: list,
166
- guid: str) -> None:
167
- """Remove a data field from a list of data structures."""
168
- try:
169
- for structure_guid in struct_list:
170
- egeria_client.detach_member_data_field(structure_guid, guid, None)
171
- msg = f"Removed `{display_name}` from structure `{structure_guid}`"
172
- logger.info(msg)
173
- return
174
-
175
- except Exception as e:
176
- console.print_exception()
177
-
178
-
179
- @logger.catch
180
- def sync_data_field_rel_elements(egeria_client: EgeriaTech, structure_list: list, parent_field_list: list, terms: list,
181
- data_class_guid: str, guid: str, display_name: str,
182
- replace_all_props: bool = True) -> None:
183
- """Sync a field's related elements.
184
-
185
- TODO: Need to add data class support when ready and may need to revisit bodies.
186
-
187
- """
188
- if terms:
189
- terms = [terms]
190
-
191
- if replace_all_props:
192
- rel_el_list = egeria_client.get_data_field_rel_elements(guid)
193
- # should I throw an exception if empty?
194
- if rel_el_list is None:
195
- logger.warning("Unexpected -> the list was None - assigning empty list")
196
- rel_el_list = {}
197
-
198
- as_is_data_structs = set(rel_el_list.get("data_structure_guids", []))
199
- as_is_parent_fields = set(rel_el_list.get("parent_guids", []))
200
- as_is_assigned_meanings = set(rel_el_list.get("assigned_meanings_guids", []))
201
- as_is_data_classes = set(rel_el_list.get("data_class_guids", []))
202
-
203
- to_be_data_structs = set(structure_list) if structure_list is not None else set()
204
- to_be_parent_fields = set(parent_field_list) if parent_field_list is not None else set()
205
- to_be_assigned_meanings = set(terms) if terms is not None else set()
206
- to_be_data_classes = set([data_class_guid]) if data_class_guid is not None else set()
207
-
208
- logger.trace(f"as_is_data_structs: {list(as_is_data_structs)} to_be_data_struct: {list(to_be_data_structs)}")
209
- logger.trace(
210
- f"as_is_parent_fields: {list(as_is_parent_fields)} to_be_parent_fields: {list(to_be_parent_fields)}")
211
- logger.trace(f"as_is_assigned_meanings: {list(as_is_assigned_meanings)} to_be_assigned_meanings: "
212
- f"{list(to_be_assigned_meanings)}")
213
- logger.trace(f"as_is_data_classes: {list(as_is_data_classes)} to_be_assigned_data_classes: "
214
- f"{list(to_be_data_classes)}")
215
-
216
- data_struct_to_remove = as_is_data_structs - to_be_data_structs
217
- logger.trace(f"data_struct_to_remove: {list(data_struct_to_remove)}")
218
- if len(data_struct_to_remove) > 0:
219
- for ds in data_struct_to_remove:
220
- egeria_client.detach_member_data_field(ds, guid, None)
221
- msg = f"Removed `{display_name}` from structure `{ds}`"
222
- logger.trace(msg)
223
- data_struct_to_add = to_be_data_structs - as_is_data_structs
224
- logger.trace(f"data_struct_to_add: {list(data_struct_to_add)}")
225
- if len(data_struct_to_add) > 0:
226
- for ds in data_struct_to_add:
227
- egeria_client.link_member_data_field(ds, guid, None)
228
- msg = f"Added `{display_name}` to structure `{ds}`"
229
- logger.trace(msg)
230
-
231
- parent_field_to_remove = to_be_parent_fields - as_is_parent_fields
232
- logger.trace(f"parent_field_to_remove: {list(parent_field_to_remove)}")
233
- if len(parent_field_to_remove) > 0:
234
- for field in parent_field_to_remove:
235
- egeria_client.detach_nested_data_field(field, guid, None)
236
- msg = f"Removed `{display_name}` from field `{field}`"
237
- logger.trace(msg)
238
- parent_field_to_add = to_be_parent_fields - as_is_parent_fields
239
- logger.trace(f"parent_field_to_add: {list(parent_field_to_add)}")
240
- if len(parent_field_to_add) > 0:
241
- for field in parent_field_to_add:
242
- egeria_client.link_nested_data_field(field, guid, None)
243
- msg = f"Added `{display_name}` to field `{field}`"
244
- logger.trace(msg)
245
-
246
- terms_to_remove = as_is_assigned_meanings - to_be_assigned_meanings
247
- logger.trace(f"terms_to_remove: {list(terms_to_remove)}")
248
- if terms:
249
- for term in terms_to_remove:
250
- egeria_client.detach_semantic_definition(guid, term, None)
251
- msg = f"Removed `{term}` from `{display_name}`"
252
- logger.trace(msg)
253
- terms_to_add = to_be_assigned_meanings - as_is_assigned_meanings
254
- logger.trace(f"terms_to_add: {list(terms_to_add)}")
255
- if len(terms_to_add) > 0:
256
- for term in terms_to_add:
257
- egeria_client.link_semantic_definition(guid, term, None)
258
- msg = f"Added `{term}` to`{display_name}`"
259
- logger.trace(msg)
260
-
261
- classes_to_remove = as_is_data_classes - to_be_data_classes
262
- logger.trace(f"classes_to_remove: {list(classes_to_remove)}")
263
- if len(terms_to_remove) > 0:
264
- for dc in classes_to_remove:
265
- body = {
266
- "class": "MetadataSourceRequestBody", "forLineage": False, "forDuplicateProcessing": False
267
- }
268
- egeria_client.detach_data_class_definition(guid, dc, body)
269
- msg = f"Removed `{dc}` from `{display_name}`"
270
- logger.trace(msg)
271
- classes_to_add = to_be_data_classes - as_is_data_classes
272
- logger.trace(f"classes_to_add: {list(classes_to_add)}")
273
- if len(terms_to_add) > 0:
274
- for dc in classes_to_add:
275
- body = {
276
- "class": "RelationshipRequestBody", "forLineage": False, "forDuplicateProcessing": False
277
- }
278
- egeria_client.link_data_class_definition(guid, dc, body)
279
- msg = f"Added `{dc}` to`{display_name}`"
280
- logger.trace(msg)
281
-
282
-
283
- else: # merge - add field to related elements
284
- if structure_list:
285
- add_field_to_data_structures(egeria_client, display_name, structure_list, guid)
286
- msg = f"Added `{display_name}` to `{structure_list}`"
287
- logger.trace(msg)
288
-
289
- if parent_field_list:
290
- for field in parent_field_list:
291
- egeria_client.link_nested_data_field(field, guid, None)
292
- msg = f"Added `{display_name}` to `{field}`"
293
- logger.trace(msg)
294
- if terms:
295
- for term in terms:
296
- egeria_client.link_semantic_definition(guid, term, None)
297
- msg = f"Added `{term}` to `{display_name}`"
298
- logger.trace(msg)
299
-
300
- if data_class_guid:
301
- egeria_client.link_data_class_definition(guid, data_class_guid)
302
- msg = f"Added `{data_class_guid}` to `{display_name}`"
303
- logger.trace(msg)
304
-
305
-
306
- @logger.catch
307
- def sync_data_class_rel_elements(egeria_client: EgeriaTech, containing_data_class_guids: list, terms: list,
308
- specializes_data_classes: list, guid: str, display_name: str,
309
- replace_all_props: bool = True) -> None:
310
- """Sync a data class' related elements.
148
+ # @logger.catch
149
+ # def add_field_to_data_structures(egeria_client: EgeriaTech, display_name: str, struct_list: list, guid) -> None:
150
+ # """
151
+ # Add data field to data structures.
152
+ # """
153
+ #
154
+ # try:
155
+ # for structure_guid in struct_list:
156
+ # egeria_client.link_member_data_field(structure_guid, guid, None)
157
+ # msg = f"Added `{display_name}` to structure `{structure_guid}`"
158
+ # logger.info(msg)
159
+ # return
160
+ #
161
+ # except Exception as e:
162
+ # console.print_exception()
163
+ #
164
+ #
165
+ # @logger.catch
166
+ # def remove_field_from_data_structures(egeria_client: EgeriaTech, display_name: str, struct_list: list,
167
+ # guid: str) -> None:
168
+ # """Remove a data field from a list of data structures."""
169
+ # try:
170
+ # for structure_guid in struct_list:
171
+ # egeria_client.detach_member_data_field(structure_guid, guid, None)
172
+ # msg = f"Removed `{display_name}` from structure `{structure_guid}`"
173
+ # logger.info(msg)
174
+ # return
175
+ #
176
+ # except Exception as e:
177
+ # console.print_exception()
178
+ #
311
179
 
312
- """
313
- if terms:
314
- terms = [terms]
180
+ # @logger.catch
181
+ # def sync_data_field_rel_elements(egeria_client: EgeriaTech, structure_list: list, parent_field_list: list, terms: list,
182
+ # data_class_guid: str, guid: str, display_name: str,
183
+ # replace_all_props: bool = True) -> None:
184
+ # """Sync a field's related elements.
185
+ #
186
+ # TODO: Need to add data class support when ready and may need to revisit bodies.
187
+ #
188
+ # """
189
+ # if terms:
190
+ # terms = [terms]
191
+ #
192
+ # if replace_all_props:
193
+ # rel_el_list = egeria_client.get_data_field_rel_elements(guid)
194
+ # # should I throw an exception if empty?
195
+ # if rel_el_list is None:
196
+ # logger.warning("Unexpected -> the list was None - assigning empty list")
197
+ # rel_el_list = {}
198
+ #
199
+ # as_is_data_structs = set(rel_el_list.get("data_structure_guids", []))
200
+ # as_is_parent_fields = set(rel_el_list.get("parent_guids", []))
201
+ # as_is_assigned_meanings = set(rel_el_list.get("assigned_meanings_guids", []))
202
+ # as_is_data_classes = set(rel_el_list.get("data_class_guids", []))
203
+ #
204
+ # to_be_data_structs = set(structure_list) if structure_list is not None else set()
205
+ # to_be_parent_fields = set(parent_field_list) if parent_field_list is not None else set()
206
+ # to_be_assigned_meanings = set(terms) if terms is not None else set()
207
+ # to_be_data_classes = set([data_class_guid]) if data_class_guid is not None else set()
208
+ #
209
+ # logger.trace(f"as_is_data_structs: {list(as_is_data_structs)} to_be_data_struct: {list(to_be_data_structs)}")
210
+ # logger.trace(
211
+ # f"as_is_parent_fields: {list(as_is_parent_fields)} to_be_parent_fields: {list(to_be_parent_fields)}")
212
+ # logger.trace(f"as_is_assigned_meanings: {list(as_is_assigned_meanings)} to_be_assigned_meanings: "
213
+ # f"{list(to_be_assigned_meanings)}")
214
+ # logger.trace(f"as_is_data_classes: {list(as_is_data_classes)} to_be_assigned_data_classes: "
215
+ # f"{list(to_be_data_classes)}")
216
+ #
217
+ # data_struct_to_remove = as_is_data_structs - to_be_data_structs
218
+ # logger.trace(f"data_struct_to_remove: {list(data_struct_to_remove)}")
219
+ # if len(data_struct_to_remove) > 0:
220
+ # for ds in data_struct_to_remove:
221
+ # egeria_client.detach_member_data_field(ds, guid, None)
222
+ # msg = f"Removed `{display_name}` from structure `{ds}`"
223
+ # logger.trace(msg)
224
+ # data_struct_to_add = to_be_data_structs - as_is_data_structs
225
+ # logger.trace(f"data_struct_to_add: {list(data_struct_to_add)}")
226
+ # if len(data_struct_to_add) > 0:
227
+ # for ds in data_struct_to_add:
228
+ # egeria_client.link_member_data_field(ds, guid, None)
229
+ # msg = f"Added `{display_name}` to structure `{ds}`"
230
+ # logger.trace(msg)
231
+ #
232
+ # parent_field_to_remove = to_be_parent_fields - as_is_parent_fields
233
+ # logger.trace(f"parent_field_to_remove: {list(parent_field_to_remove)}")
234
+ # if len(parent_field_to_remove) > 0:
235
+ # for field in parent_field_to_remove:
236
+ # egeria_client.detach_nested_data_field(field, guid, None)
237
+ # msg = f"Removed `{display_name}` from field `{field}`"
238
+ # logger.trace(msg)
239
+ # parent_field_to_add = to_be_parent_fields - as_is_parent_fields
240
+ # logger.trace(f"parent_field_to_add: {list(parent_field_to_add)}")
241
+ # if len(parent_field_to_add) > 0:
242
+ # for field in parent_field_to_add:
243
+ # egeria_client.link_nested_data_field(field, guid, None)
244
+ # msg = f"Added `{display_name}` to field `{field}`"
245
+ # logger.trace(msg)
246
+ #
247
+ # terms_to_remove = as_is_assigned_meanings - to_be_assigned_meanings
248
+ # logger.trace(f"terms_to_remove: {list(terms_to_remove)}")
249
+ # if terms:
250
+ # for term in terms_to_remove:
251
+ # egeria_client.detach_semantic_definition(guid, term, None)
252
+ # msg = f"Removed `{term}` from `{display_name}`"
253
+ # logger.trace(msg)
254
+ # terms_to_add = to_be_assigned_meanings - as_is_assigned_meanings
255
+ # logger.trace(f"terms_to_add: {list(terms_to_add)}")
256
+ # if len(terms_to_add) > 0:
257
+ # for term in terms_to_add:
258
+ # egeria_client.link_semantic_definition(guid, term, None)
259
+ # msg = f"Added `{term}` to`{display_name}`"
260
+ # logger.trace(msg)
261
+ #
262
+ # classes_to_remove = as_is_data_classes - to_be_data_classes
263
+ # logger.trace(f"classes_to_remove: {list(classes_to_remove)}")
264
+ # if len(terms_to_remove) > 0:
265
+ # for dc in classes_to_remove:
266
+ # body = {
267
+ # "class": "MetadataSourceRequestBody", "forLineage": False, "forDuplicateProcessing": False
268
+ # }
269
+ # egeria_client.detach_data_class_definition(guid, dc, body)
270
+ # msg = f"Removed `{dc}` from `{display_name}`"
271
+ # logger.trace(msg)
272
+ # classes_to_add = to_be_data_classes - as_is_data_classes
273
+ # logger.trace(f"classes_to_add: {list(classes_to_add)}")
274
+ # if len(terms_to_add) > 0:
275
+ # for dc in classes_to_add:
276
+ # body = {
277
+ # "class": "RelationshipRequestBody", "forLineage": False, "forDuplicateProcessing": False
278
+ # }
279
+ # egeria_client.link_data_class_definition(guid, dc, body)
280
+ # msg = f"Added `{dc}` to`{display_name}`"
281
+ # logger.trace(msg)
282
+ #
283
+ #
284
+ # else: # merge - add field to related elements
285
+ # if structure_list:
286
+ # add_field_to_data_structures(egeria_client, display_name, structure_list, guid)
287
+ # msg = f"Added `{display_name}` to `{structure_list}`"
288
+ # logger.trace(msg)
289
+ #
290
+ # if parent_field_list:
291
+ # for field in parent_field_list:
292
+ # egeria_client.link_nested_data_field(field, guid, None)
293
+ # msg = f"Added `{display_name}` to `{field}`"
294
+ # logger.trace(msg)
295
+ # if terms:
296
+ # for term in terms:
297
+ # egeria_client.link_semantic_definition(guid, term, None)
298
+ # msg = f"Added `{term}` to `{display_name}`"
299
+ # logger.trace(msg)
300
+ #
301
+ # if data_class_guid:
302
+ # egeria_client.link_data_class_definition(guid, data_class_guid)
303
+ # msg = f"Added `{data_class_guid}` to `{display_name}`"
304
+ # logger.trace(msg)
315
305
 
316
- if replace_all_props:
317
- rel_el_list = egeria_client.get_data_class_rel_elements(guid)
318
- if rel_el_list is None:
319
- logger.warning("Unexpected -> the list was None - assigning empty list")
320
- rel_el_list = {}
321
- if terms:
322
- terms = [terms]
323
-
324
- as_is_nested_classes = set(rel_el_list.get("nested_data_class_guids", []))
325
- as_is_assigned_meanings = set(rel_el_list.get("assigned_meanings_guids", []))
326
- as_is_specialized_classes = set(rel_el_list.get("specialized_data_class_guids", []))
327
-
328
- to_be_nested_classes = set(containing_data_class_guids) if containing_data_class_guids is not None else set()
329
- to_be_assigned_meanings = set(terms) if terms is not None else set()
330
- to_be_specialized_classes = set([specializes_data_classes]) if specializes_data_classes is not None else set()
331
-
332
- logger.trace(
333
- f"as_is_nested_classes: {list(as_is_nested_classes)} to_be_nested_classes: {list(to_be_nested_classes)}")
334
- logger.trace(f"as_is_assigned_meanings: {list(as_is_assigned_meanings)} to_be_assigned_meanings: "
335
- f"{list(to_be_assigned_meanings)}")
336
- logger.trace(f"as_is_specialized_classes: {list(as_is_specialized_classes)} to_be_specizialized_data_classes: "
337
- f"{list(to_be_specialized_classes)}")
338
-
339
- nested_classes_to_remove = to_be_nested_classes - as_is_nested_classes
340
- logger.trace(f"nested_classes_to_remove: {list(nested_classes_to_remove)}")
341
- if len(nested_classes_to_remove) > 0:
342
- for field in nested_classes_to_remove:
343
- egeria_client.detach_nested_data_class(field, guid, None)
344
- msg = f"Removed `{display_name}` from field `{field}`"
345
- logger.trace(msg)
346
- nested_classes_to_add = to_be_nested_classes - as_is_nested_classes
347
- logger.trace(f"nested_classes_to_add: {list(nested_classes_to_add)}")
348
- if len(nested_classes_to_add) > 0:
349
- for field in nested_classes_to_add:
350
- egeria_client.link_nested_data_class(field, guid, None)
351
- msg = f"Added `{display_name}` to field `{field}`"
352
- logger.trace(msg)
353
-
354
- terms_to_remove = as_is_assigned_meanings - to_be_assigned_meanings
355
- logger.trace(f"terms_to_remove: {list(terms_to_remove)}")
356
- if len(terms_to_remove) > 0:
357
- for term in terms_to_remove:
358
- egeria_client.detach_semantic_definition(guid, term, None)
359
- msg = f"Removed `{term}` from `{display_name}`"
360
- logger.trace(msg)
361
- terms_to_add = to_be_assigned_meanings - as_is_assigned_meanings
362
- logger.trace(f"terms_to_add: {list(terms_to_add)}")
363
- if len(terms_to_add) > 0:
364
- for term in terms_to_add:
365
- egeria_client.link_semantic_definition(guid, term, None)
366
- msg = f"Added `{term}` to`{display_name}`"
367
- logger.trace(msg)
368
-
369
- specialized_classes_to_remove = as_is_specialized_classes - to_be_specialized_classes
370
- logger.trace(f"classes_to_remove: {list(specialized_classes_to_remove)}")
371
- if len(terms_to_remove) > 0:
372
- for dc in specialized_classes_to_remove:
373
- body = {
374
- "class": "MetadataSourceRequestBody", "forLineage": False, "forDuplicateProcessing": False
375
- }
376
- egeria_client.detach_specialist_data_class(guid, dc, body)
377
- msg = f"Removed `{dc}` from `{display_name}`"
378
- logger.trace(msg)
379
- specialized_classes_to_add = to_be_specialized_classes - as_is_specialized_classes
380
- logger.trace(f"classes_to_add: {list(specialized_classes_to_add)}")
381
- if len(specialized_classes_to_add) > 0:
382
- for dc in specialized_classes_to_add:
383
- body = {
384
- "class": "RelationshipRequestBody", "forLineage": False, "forDuplicateProcessing": False
385
- }
386
- egeria_client.link_specialist_data_class(guid, dc, body)
387
- msg = f"Added `{dc}` to`{display_name}`"
388
- logger.trace(msg)
389
-
390
-
391
- else: # merge - add field to related elements
392
- if containing_data_class_guids:
393
- for field in containing_data_class_guids:
394
- egeria_client.link_nested_data_class(field, guid, None)
395
- msg = f"Added `{display_name}` to `{field}`"
396
- logger.trace(msg)
397
-
398
- if terms:
399
- for term in terms:
400
- egeria_client.link_semantic_definition(guid, term, None)
401
- msg = f"Added `{term}` to `{display_name}`"
402
- logger.trace(msg)
403
- if specializes_data_classes:
404
- for el in specializes_data_classes:
405
- egeria_client.link_specialist_data_class(guid, el)
406
- msg = f"Linked `{el}` to `{display_name}`"
407
- logger.trace(msg)
306
+ #
307
+ # @logger.catch
308
+ # def sync_data_class_rel_elements(egeria_client: EgeriaTech, containing_data_class_guids: list, terms: list,
309
+ # specializes_data_classes: list, guid: str, display_name: str,
310
+ # replace_all_props: bool = True) -> None:
311
+ # """Sync a data class' related elements.
312
+ #
313
+ # """
314
+ # if terms:
315
+ # terms = [terms]
316
+ #
317
+ # if replace_all_props:
318
+ # rel_el_list = egeria_client.get_data_class_rel_elements(guid)
319
+ # if rel_el_list is None:
320
+ # logger.warning("Unexpected -> the list was None - assigning empty list")
321
+ # rel_el_list = {}
322
+ # if terms:
323
+ # terms = [terms]
324
+ #
325
+ # as_is_nested_classes = set(rel_el_list.get("nested_data_class_guids", []))
326
+ # as_is_assigned_meanings = set(rel_el_list.get("assigned_meanings_guids", []))
327
+ # as_is_specialized_classes = set(rel_el_list.get("specialized_data_class_guids", []))
328
+ #
329
+ # to_be_nested_classes = set(containing_data_class_guids) if containing_data_class_guids is not None else set()
330
+ # to_be_assigned_meanings = set(terms) if terms is not None else set()
331
+ # to_be_specialized_classes = set([specializes_data_classes]) if specializes_data_classes is not None else set()
332
+ #
333
+ # logger.trace(
334
+ # f"as_is_nested_classes: {list(as_is_nested_classes)} to_be_nested_classes: {list(to_be_nested_classes)}")
335
+ # logger.trace(f"as_is_assigned_meanings: {list(as_is_assigned_meanings)} to_be_assigned_meanings: "
336
+ # f"{list(to_be_assigned_meanings)}")
337
+ # logger.trace(f"as_is_specialized_classes: {list(as_is_specialized_classes)} to_be_specizialized_data_classes: "
338
+ # f"{list(to_be_specialized_classes)}")
339
+ #
340
+ # nested_classes_to_remove = to_be_nested_classes - as_is_nested_classes
341
+ # logger.trace(f"nested_classes_to_remove: {list(nested_classes_to_remove)}")
342
+ # if len(nested_classes_to_remove) > 0:
343
+ # for field in nested_classes_to_remove:
344
+ # egeria_client.detach_nested_data_class(field, guid, None)
345
+ # msg = f"Removed `{display_name}` from field `{field}`"
346
+ # logger.trace(msg)
347
+ # nested_classes_to_add = to_be_nested_classes - as_is_nested_classes
348
+ # logger.trace(f"nested_classes_to_add: {list(nested_classes_to_add)}")
349
+ # if len(nested_classes_to_add) > 0:
350
+ # for field in nested_classes_to_add:
351
+ # egeria_client.link_nested_data_class(field, guid, None)
352
+ # msg = f"Added `{display_name}` to field `{field}`"
353
+ # logger.trace(msg)
354
+ #
355
+ # terms_to_remove = as_is_assigned_meanings - to_be_assigned_meanings
356
+ # logger.trace(f"terms_to_remove: {list(terms_to_remove)}")
357
+ # if len(terms_to_remove) > 0:
358
+ # for term in terms_to_remove:
359
+ # egeria_client.detach_semantic_definition(guid, term, None)
360
+ # msg = f"Removed `{term}` from `{display_name}`"
361
+ # logger.trace(msg)
362
+ # terms_to_add = to_be_assigned_meanings - as_is_assigned_meanings
363
+ # logger.trace(f"terms_to_add: {list(terms_to_add)}")
364
+ # if len(terms_to_add) > 0:
365
+ # for term in terms_to_add:
366
+ # egeria_client.link_semantic_definition(guid, term, None)
367
+ # msg = f"Added `{term}` to`{display_name}`"
368
+ # logger.trace(msg)
369
+ #
370
+ # specialized_classes_to_remove = as_is_specialized_classes - to_be_specialized_classes
371
+ # logger.trace(f"classes_to_remove: {list(specialized_classes_to_remove)}")
372
+ # if len(terms_to_remove) > 0:
373
+ # for dc in specialized_classes_to_remove:
374
+ # body = {
375
+ # "class": "MetadataSourceRequestBody", "forLineage": False, "forDuplicateProcessing": False
376
+ # }
377
+ # egeria_client.detach_specialist_data_class(guid, dc, body)
378
+ # msg = f"Removed `{dc}` from `{display_name}`"
379
+ # logger.trace(msg)
380
+ # specialized_classes_to_add = to_be_specialized_classes - as_is_specialized_classes
381
+ # logger.trace(f"classes_to_add: {list(specialized_classes_to_add)}")
382
+ # if len(specialized_classes_to_add) > 0:
383
+ # for dc in specialized_classes_to_add:
384
+ # body = {
385
+ # "class": "RelationshipRequestBody", "forLineage": False, "forDuplicateProcessing": False
386
+ # }
387
+ # egeria_client.link_specialist_data_class(guid, dc, body)
388
+ # msg = f"Added `{dc}` to`{display_name}`"
389
+ # logger.trace(msg)
390
+ #
391
+ #
392
+ # else: # merge - add field to related elements
393
+ # if containing_data_class_guids:
394
+ # for field in containing_data_class_guids:
395
+ # egeria_client.link_nested_data_class(field, guid, None)
396
+ # msg = f"Added `{display_name}` to `{field}`"
397
+ # logger.trace(msg)
398
+ #
399
+ # if terms:
400
+ # for term in terms:
401
+ # egeria_client.link_semantic_definition(guid, term, None)
402
+ # msg = f"Added `{term}` to `{display_name}`"
403
+ # logger.trace(msg)
404
+ # if specializes_data_classes:
405
+ # for el in specializes_data_classes:
406
+ # egeria_client.link_specialist_data_class(guid, el)
407
+ # msg = f"Linked `{el}` to `{display_name}`"
408
+ # logger.trace(msg)
408
409
  #
409
410
  # Product Manager Commands
410
411
  #
@@ -442,37 +443,7 @@ def process_collection_upsert_command(egeria_client: EgeriaTech, txt: str, direc
442
443
  attributes = parsed_output['attributes']
443
444
 
444
445
  display_name = attributes['Display Name'].get('value', None)
445
- description = attributes.get('Description',{}).get('value', None)
446
- user_defined_status = attributes.get('User Defined Status',{}).get('value', None)
447
-
448
- collection_classification = attributes.get('Collection Classification', {}).get('value', None)
449
-
450
- current_version = attributes.get('Version Identifier',{}).get('value', None)
451
-
452
- # status = attributes.get('Status',{}).get('value', "ACTIVE")
453
-
454
- anchor_guid = attributes.get('Anchor ID', {}).get('guid', None)
455
- parent_guid = attributes.get('Parent ID', {}).get('guid', None)
456
- parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value', None)
457
- parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value',"CollectionMembership")
458
- parent_at_end1 = attributes.get('Parent at End1', {}).get('value', True)
459
- anchor_scope_guid = attributes.get('Anchor Scope GUID', {}).get('value', None)
460
- is_own_anchor = attributes.get('Is Own Anchor', {}).get('value', True)
461
- if parent_guid is None:
462
- is_own_anchor = True
463
-
464
-
465
- additional_prop = attributes.get('Additional Properties', {}).get('value', None)
466
- additional_properties = json.loads(additional_prop) if additional_prop is not None else None
467
- extended_prop = attributes.get('Extended Properties', {}).get('value', None)
468
- extended_properties = json.loads(extended_prop) if extended_prop is not None else None
469
- external_source_guid = attributes.get('External Source Name', {}).get('guid', None)
470
- external_source_name = attributes.get('External Source Name', {}).get('value', None)
471
- effective_time = attributes.get('Effective Time', {}).get('value', None)
472
- for_lineage = attributes.get('For Lineage', {}).get('value', None)
473
- for_duplicate_processing = attributes.get('For Duplicate Processing', {}).get('value', None)
474
-
475
- replace_all_props = not attributes.get('Merge Update', {}).get('value', True)
446
+ status = attributes.get('Status', {}).get('value', None)
476
447
 
477
448
  if directive == "display":
478
449
 
@@ -486,6 +457,11 @@ def process_collection_upsert_command(egeria_client: EgeriaTech, txt: str, direc
486
457
 
487
458
  elif directive == "process":
488
459
  try:
460
+ if object_type in ["Root Collection", "Folder"]:
461
+ obj = "Collection"
462
+ else:
463
+ obj = object_type
464
+
489
465
  if object_action == "Update":
490
466
  if not exists:
491
467
  msg = (f" Element `{display_name}` does not exist! Updating result document with Create "
@@ -497,19 +473,20 @@ def process_collection_upsert_command(egeria_client: EgeriaTech, txt: str, direc
497
473
  else:
498
474
  print(Markdown(
499
475
  f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
500
- prop_body = set_collection_property_body(object_type,qualified_name,attributes)
476
+ prop_body = set_prop_body(obj,qualified_name,attributes)
501
477
 
502
- body = set_update_body(object_type, attributes)
503
- body['properties'] = set_collection_property_body(object_type,qualified_name,attributes)
478
+ body = set_update_body(obj, attributes)
479
+ body['properties'] = set_prop_body(obj,qualified_name,attributes)
504
480
 
505
- egeria_client.update_collection_w_body(guid, body)
506
- # egeria_client.update_collection_status(guid, status)
481
+ egeria_client.update_collection(guid, body)
482
+ if status:
483
+ egeria_client.update_collection_status(guid, status)
507
484
 
508
485
  logger.success(f"Updated {object_type} `{display_name}` with GUID {guid}\n\n___")
509
486
  update_element_dictionary(qualified_name, {
510
487
  'guid': guid, 'display_name': display_name
511
488
  })
512
- return egeria_client.get_collection_by_guid(guid, collection_type='Data Specification',
489
+ return egeria_client.get_collection_by_guid(guid, element_type='Data Specification',
513
490
  output_format='MD')
514
491
 
515
492
 
@@ -522,27 +499,31 @@ def process_collection_upsert_command(egeria_client: EgeriaTech, txt: str, direc
522
499
 
523
500
  else:
524
501
  body = set_create_body(object_type,attributes)
525
- body["initialClassifications"] = set_collection_classifications(object_type, attributes)
526
- body["properties"] = set_collection_property_body(object_type, qualified_name,attributes)
527
502
 
503
+ # if this is a root or folder (maybe more in the future), then make sure that the classification is set.
504
+ body["initialClassifications"] = set_collection_classifications(object_type, attributes, ["Folder", "Root Collection"])
505
+ body["properties"] = set_prop_body(obj, qualified_name,attributes)
528
506
 
529
- guid = egeria_client.create_collection_w_body(body)
507
+
508
+ guid = egeria_client.create_collection(body = body)
530
509
  if guid:
531
510
  update_element_dictionary(qualified_name, {
532
511
  'guid': guid, 'display_name': display_name
533
512
  })
534
513
  msg = f"Created Element `{display_name}` with GUID {guid}\n\n___"
535
514
  logger.success(msg)
536
- return egeria_client.get_collection_by_guid(guid, collection_type='Digital Product',
537
- output_format='MD')
515
+ return egeria_client.get_collection_by_guid(guid, obj, output_format='MD')
538
516
  else:
539
517
  msg = f"Failed to create element `{display_name}` with GUID {guid}\n\n___"
540
518
  logger.error(msg)
541
519
  return None
542
520
 
521
+ except PyegeriaException as e:
522
+ logger.error(f"Pyegeria error performing {command}: {e}")
523
+ print_basic_exception(e)
524
+ return None
543
525
  except Exception as e:
544
526
  logger.error(f"Error performing {command}: {e}")
545
- return None
546
527
  else:
547
528
  return None
548
529
 
@@ -569,6 +550,7 @@ def process_digital_product_upsert_command(egeria_client: EgeriaTech, txt: str,
569
550
  qualified_name = parsed_output.get('qualified_name', None)
570
551
  guid = parsed_output.get('guid', None)
571
552
 
553
+
572
554
  print(Markdown(parsed_output['display']))
573
555
 
574
556
  logger.debug(json.dumps(parsed_output, indent=4))
@@ -576,50 +558,8 @@ def process_digital_product_upsert_command(egeria_client: EgeriaTech, txt: str,
576
558
  attributes = parsed_output['attributes']
577
559
 
578
560
  display_name = attributes['Display Name'].get('value', None)
579
- description = attributes.get('Description',{}).get('value', None)
580
- user_defined_status = attributes.get('User Defined Status',{}).get('value', None)
581
- product_identifier = attributes.get('Product Identifier',{}).get('value', None)
582
- product_name = attributes.get('Product Name',{}).get('value', None)
583
- product_type = attributes.get('Product Type',{}).get('value', None)
584
-
585
-
586
-
587
- product_description = attributes.get('Product Description',{}).get('value', None)
588
- maturity = attributes.get('Maturity',{}).get('value', None)
589
- service_life = attributes.get('Service Life',{}).get('value', None)
590
- introduction_date = attributes.get('Introduction Date',{}).get('value', None)
591
- next_version_date = attributes.get('Next Version Date',{}).get('value', None)
592
- withdrawal_date = attributes.get('Withdrawal Date',{}).get('value', None)
593
-
594
- collection_type = attributes.get('Collection Type', {}).get('value', None)
595
- current_version = attributes.get('Version Identifier',{}).get('value', None)
596
561
  product_manager = attributes.get('Product Manager',{}).get('value', None)
597
-
598
-
599
- product_status = attributes.get('Status',{}).get('value', "ACTIVE")
600
-
601
- anchor_guid = attributes.get('Anchor ID', {}).get('guid', None)
602
- parent_guid = attributes.get('Parent ID', {}).get('guid', None)
603
- parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value', None)
604
- parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value',"CollectionMembership")
605
- parent_at_end1 = attributes.get('Parent at End1', {}).get('value', True)
606
- anchor_scope_guid = attributes.get('Anchor Scope GUID', {}).get('value', None)
607
- is_own_anchor = attributes.get('Is Own Anchor', {}).get('value', True)
608
- if parent_guid is None:
609
- is_own_anchor = True
610
-
611
-
612
- additional_prop = attributes.get('Additional Properties', {}).get('value', None)
613
- additional_properties = json.loads(additional_prop) if additional_prop is not None else None
614
- extended_prop = attributes.get('Extended Properties', {}).get('value', None)
615
- extended_properties = json.loads(extended_prop) if extended_prop is not None else None
616
- external_source_guid = attributes.get('External Source Name', {}).get('guid', None)
617
- external_source_name = attributes.get('External Source Name', {}).get('value', None)
618
- effective_time = attributes.get('Effective Time', {}).get('value', None)
619
- for_lineage = attributes.get('For Lineage', {}).get('value', None)
620
- for_duplicate_processing = attributes.get('For Duplicate Processing', {}).get('value', None)
621
-
622
- replace_all_props = not attributes.get('Merge Update', {}).get('value', True)
562
+ product_status = attributes.get('Product Status',{}).get('value', None)
623
563
 
624
564
  if directive == "display":
625
565
 
@@ -644,43 +584,21 @@ def process_digital_product_upsert_command(egeria_client: EgeriaTech, txt: str,
644
584
  else:
645
585
  print(Markdown(
646
586
  f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
647
- prop_body = set_prop_body(object_type,qualified_name,attributes)
648
-
649
- body ={
650
- "class": "UpdateElementRequestBody",
651
- "properties": {
652
- "class": "DigitalProductProperties",
653
- "qualifiedName": qualified_name,
654
- "userDefinedStatus": user_defined_status,
655
- "name": display_name,
656
- "description": description,
657
- "identifier": product_identifier,
658
- "productName": product_name,
659
- "productType": product_type,
660
- "maturity": maturity,
661
- "serviceLife": service_life,
662
- "introductionDate": introduction_date,
663
- "nextVersionDate": next_version_date,
664
- "withdrawDate": withdrawal_date,
665
- "currentVersion": current_version,
666
- "additionalProperties": additional_properties,
667
- "extendedProperties": extended_properties,
668
- },
669
- "externalSourceGUID": external_source_guid,
670
- "externalSourceName": external_source_name,
671
- "effectiveTime": effective_time,
672
- "forLineage": for_lineage,
673
- "forDuplicateProcessing": for_duplicate_processing
674
- }
587
+ prop_body = set_product_body(object_type,qualified_name,attributes)
588
+ body = set_update_body(object_type, attributes)
589
+ body['properties'] = set_prop_body(object_type,qualified_name,attributes)
590
+ # Todo: Update product manager later?
675
591
 
676
592
  egeria_client.update_digital_product(guid, body)
677
- egeria_client.update_digital_product_status(guid, product_status)
593
+ # if product_status:
594
+ # egeria_client.update_digital_product_status(guid, product_status)
595
+
678
596
 
679
597
  logger.success(f"Updated {object_type} `{display_name}` with GUID {guid}\n\n___")
680
598
  update_element_dictionary(qualified_name, {
681
599
  'guid': guid, 'display_name': display_name
682
600
  })
683
- return egeria_client.get_collection_by_guid(guid, collection_type='Data Specification',
601
+ return egeria_client.get_collection_by_guid(guid, element_type='Digital Product',
684
602
  output_format='MD')
685
603
 
686
604
 
@@ -692,49 +610,21 @@ def process_digital_product_upsert_command(egeria_client: EgeriaTech, txt: str,
692
610
  return update_a_command(txt, object_action, object_type, qualified_name, guid)
693
611
 
694
612
  else:
695
- body = {
696
- "class": "NewDigitalProductRequestBody",
697
- "isOwnAnchor": is_own_anchor,
698
- "parentGUID": parent_guid,
699
- "parentRelationshipTypeName": parent_relationship_type_name,
700
- "parentAtEnd1": parent_at_end1,
701
- "properties": {
702
- "class": "DigitalProductProperties",
703
- "qualifiedName": qualified_name,
704
- "userDefinedStatus": user_defined_status,
705
- "name": display_name,
706
- "description" : description,
707
- "identifier": product_identifier,
708
- "productName": product_name,
709
- "productType": product_type,
710
- "maturity": maturity,
711
- "serviceLife": service_life,
712
- "introductionDate": introduction_date,
713
- "nextVersionDate": next_version_date,
714
- "withdrawDate": withdrawal_date,
715
- "currentVersion": current_version,
716
-
717
- "additionalProperties": additional_properties,
718
- "extendedProperties": extended_properties,
719
- },
720
- "initialStatus": product_status,
721
- "externalSourceGUID": external_source_guid,
722
- "externalSourceName": external_source_name,
723
- "effectiveTime" : effective_time,
724
- "forLineage": for_lineage,
725
- "forDuplicateProcessing": for_duplicate_processing
726
- }
727
-
728
-
729
-
730
- guid = egeria_client.create_digital_product(body)
613
+ body = set_create_body(object_type, attributes)
614
+ body["initialClassifications"] = set_collection_classifications(object_type, attributes,[])
615
+ prop_body = set_product_body(object_type, qualified_name, attributes)
616
+ body["properties"] = prop_body
617
+
618
+ guid = egeria_client.create_digital_product(body_slimmer(body))
731
619
  if guid:
732
620
  update_element_dictionary(qualified_name, {
733
621
  'guid': guid, 'display_name': display_name
734
622
  })
623
+ # Todo: Add product manager link later? Agreements?
624
+
735
625
  msg = f"Created Element `{display_name}` with GUID {guid}\n\n___"
736
626
  logger.success(msg)
737
- return egeria_client.get_collection_by_guid(guid, collection_type='Digital Product',
627
+ return egeria_client.get_collection_by_guid(guid, element_type='Digital Product',
738
628
  output_format='MD')
739
629
  else:
740
630
  msg = f"Failed to create element `{display_name}` with GUID {guid}\n\n___"
@@ -758,11 +648,13 @@ def process_agreement_upsert_command(egeria_client: EgeriaTech, txt: str, direct
758
648
  :param directive: an optional string indicating the directive to be used - display, validate or execute
759
649
  :return: A string summarizing the outcome of the processing.
760
650
  """
761
-
762
651
  command, object_type, object_action = extract_command_plus(txt)
763
652
  print(Markdown(f"# {command}\n"))
764
653
 
765
654
  parsed_output = parse_upsert_command(egeria_client, object_type, object_action, txt, directive)
655
+ if not parsed_output:
656
+ logger.error(f"No output for `{object_action}`")
657
+ return None
766
658
 
767
659
  valid = parsed_output['valid']
768
660
  exists = parsed_output['exists']
@@ -777,38 +669,7 @@ def process_agreement_upsert_command(egeria_client: EgeriaTech, txt: str, direct
777
669
  attributes = parsed_output['attributes']
778
670
 
779
671
  display_name = attributes['Display Name'].get('value', None)
780
- description = attributes.get('Description',{}).get('value', None)
781
- user_defined_status = attributes.get('User Defined Status',{}).get('value', None)
782
- agreement_status = attributes.get('Status',{}).get('value', None)
783
- agreement_identifier = attributes.get('Agreement Identifier',{}).get('value', None)
784
-
785
- version_identifier = attributes.get('Version Identifier',{}).get('value', None)
786
-
787
- actors = attributes.get('Agreement Actors',{}).get('value', None)
788
- actor_names = attributes.get('Agreement Actors',{}).get('name_list', None)
789
- actor_guids = attributes.get('Agreement Actors',{}).get('guid_list', None)
790
- anchor_guid = attributes.get('Anchor ID', {}).get('guid', None)
791
- parent_guid = attributes.get('Parent ID', {}).get('guid', None)
792
- parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value', None)
793
- parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value',"CollectionMembership")
794
- parent_at_end1 = attributes.get('Parent at End1', {}).get('value', True)
795
- anchor_scope_guid = attributes.get('Anchor Scope GUID', {}).get('value', None)
796
- is_own_anchor = attributes.get('Is Own Anchor', {}).get('value', True)
797
- if parent_guid is None:
798
- is_own_anchor = True
799
-
800
-
801
- additional_prop = attributes.get('Additional Properties', {}).get('value', None)
802
- additional_properties = json.loads(additional_prop) if additional_prop is not None else None
803
- extended_prop = attributes.get('Extended Properties', {}).get('value', None)
804
- extended_properties = json.loads(extended_prop) if extended_prop is not None else None
805
- external_source_guid = attributes.get('External Source Name', {}).get('guid', None)
806
- external_source_name = attributes.get('External Source Name', {}).get('value', None)
807
- effective_time = attributes.get('Effective Time', {}).get('value', None)
808
- for_lineage = attributes.get('For Lineage', {}).get('value', None)
809
- for_duplicate_processing = attributes.get('For Duplicate Processing', {}).get('value', None)
810
-
811
- replace_all_props = not attributes.get('Merge Update', {}).get('value', True)
672
+ status = attributes.get('Status', {}).get('value', None)
812
673
 
813
674
  if directive == "display":
814
675
 
@@ -822,6 +683,11 @@ def process_agreement_upsert_command(egeria_client: EgeriaTech, txt: str, direct
822
683
 
823
684
  elif directive == "process":
824
685
  try:
686
+ if object_type in ["Data Sharing Agreement"]:
687
+ obj = "Agreement"
688
+ else:
689
+ obj = object_type
690
+
825
691
  if object_action == "Update":
826
692
  if not exists:
827
693
  msg = (f" Element `{display_name}` does not exist! Updating result document with Create "
@@ -833,32 +699,23 @@ def process_agreement_upsert_command(egeria_client: EgeriaTech, txt: str, direct
833
699
  else:
834
700
  print(Markdown(
835
701
  f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
836
-
837
- product_body = {
838
- "class": "AgreementProperties",
839
- "qualifiedName": qualified_name,
840
- "userDefinedStatus": user_defined_status,
841
- "name": display_name,
842
- "description": description,
843
- "identifier": agreement_identifier,
844
- "additionalProperties": additional_properties,
845
- "extendedProperties": extended_properties,
846
- }
702
+ prop_body = set_prop_body(obj, qualified_name, attributes)
847
703
 
848
704
  body = set_update_body(object_type, attributes)
849
- body['properties'] = product_body
705
+ body['properties'] = set_prop_body(object_type, qualified_name, attributes)
850
706
 
851
- egeria_client.update_agreement(guid, body, replace_all_props)
852
- status_update_body = set_element_status_request_body(object_type, attributes)
853
- egeria_client.update_agreement_status(guid, status_update_body)
707
+ egeria_client.update_agreement(guid, body)
708
+ # if status is not None and status !={}:
709
+ # egeria_client.update_agreement_status(guid, status)
854
710
 
855
711
  logger.success(f"Updated {object_type} `{display_name}` with GUID {guid}\n\n___")
856
712
  update_element_dictionary(qualified_name, {
857
713
  'guid': guid, 'display_name': display_name
858
714
  })
859
- return egeria_client.get_collection_by_guid(guid, collection_type='Data Specification',
715
+ return egeria_client.get_collection_by_guid(guid, element_type='Data Specification',
860
716
  output_format='MD')
861
717
 
718
+
862
719
  elif object_action == "Create":
863
720
  if valid is False and exists:
864
721
  msg = (f" Digital Product `{display_name}` already exists and result document updated changing "
@@ -867,58 +724,43 @@ def process_agreement_upsert_command(egeria_client: EgeriaTech, txt: str, direct
867
724
  return update_a_command(txt, object_action, object_type, qualified_name, guid)
868
725
 
869
726
  else:
870
- body = {
871
- "class": "NewAgreementRequestBody",
872
- "isOwnAnchor": is_own_anchor,
873
- "parentGUID": parent_guid,
874
- "parentRelationshipTypeName": parent_relationship_type_name,
875
- "parentAtEnd1": parent_at_end1,
876
- "properties": {
877
- "class": "AgreementProperties",
878
- "qualifiedName": qualified_name,
879
- "userDefinedStatus": user_defined_status,
880
- "name": display_name,
881
- "description" : description,
882
- "identifier" : agreement_identifier,
883
- "additionalProperties": additional_properties,
884
- "extendedProperties": extended_properties,
885
- },
886
- "initialStatus": agreement_status,
887
- "externalSourceGUID": external_source_guid,
888
- "externalSourceName": external_source_name,
889
- "effectiveTime" : effective_time,
890
- "forLineage": for_lineage,
891
- "forDuplicateProcessing": for_duplicate_processing
892
- }
893
- if object_type == "Data Sharing Agreement":
894
- guid = egeria_client.create_data_sharing_agreement(body)
895
- elif object_type == "Agreement":
896
- guid = egeria_client.create_agreement(body)
727
+ body = set_create_body(object_type, attributes)
728
+
729
+ # if this is a root or folder (maybe more in the future), then make sure that the classification is set.
730
+ body["initialClassifications"] = set_collection_classifications(object_type, attributes,
731
+ ["Data Sharing Agreement"])
732
+ body["properties"] = set_prop_body(obj, qualified_name, attributes)
897
733
 
734
+ guid = egeria_client.create_agreement(body=body)
898
735
  if guid:
899
736
  update_element_dictionary(qualified_name, {
900
737
  'guid': guid, 'display_name': display_name
901
738
  })
902
739
  msg = f"Created Element `{display_name}` with GUID {guid}\n\n___"
903
740
  logger.success(msg)
904
- return egeria_client.get_collection_by_guid(guid, collection_type='Digital Product',
905
- output_format='MD')
741
+ return egeria_client.get_collection_by_guid(guid, obj, output_format='MD')
906
742
  else:
907
743
  msg = f"Failed to create element `{display_name}` with GUID {guid}\n\n___"
908
744
  logger.error(msg)
909
745
  return None
910
746
 
747
+ except PyegeriaException as e:
748
+ logger.error(f"Pyegeria error performing {command}: {e}")
749
+ print_exception_table(e)
750
+ return None
911
751
  except Exception as e:
912
752
  logger.error(f"Error performing {command}: {e}")
913
- return None
914
753
  else:
915
754
  return None
916
755
 
917
756
 
757
+
758
+
759
+
918
760
  def process_link_agreement_item_command(egeria_client: EgeriaTech, txt: str,
919
761
  directive: str = "display") -> Optional[str]:
920
762
  """
921
- Processes a link or unlink command to associate or break up peer governance definitions.
763
+ Processes a link or unlink command to add or remove an agreement item.
922
764
 
923
765
  :param txt: A string representing the input cell to be processed for
924
766
  extracting blueprint-related attributes.
@@ -936,9 +778,9 @@ def process_link_agreement_item_command(egeria_client: EgeriaTech, txt: str,
936
778
 
937
779
  attributes = parsed_output['attributes']
938
780
  agreement = attributes.get('Agreement Name',{}).get('value', None)
939
- agreement_guid = attributes.get('Definition 1', {}).get('guid', None)
781
+ agreement_guid = attributes.get('Agreement Name', {}).get('guid', None)
940
782
  item = attributes.get('Item Name',{}).get('value', None)
941
- item_guid = attributes.get('Definition 2', {}).get('guid', None)
783
+ item_guid = attributes.get('Item Name', {}).get('guid', None)
942
784
  label = attributes.get('Link Label', {}).get('value', None)
943
785
  description = attributes.get('Description', {}).get('value', None)
944
786
 
@@ -971,21 +813,8 @@ def process_link_agreement_item_command(egeria_client: EgeriaTech, txt: str,
971
813
  else:
972
814
  print(Markdown(
973
815
  f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
974
- body = set_metadata_source_request_body(object_type, attributes)
975
- item_props = {
976
- "class": "AgreementItemProperties",
977
- "agreementItemId": attributes["Agreement Item Id"],
978
- "agreementStart": attributes["Agreement Start"],
979
- "agreementEnd": attributes["Agreement End"],
980
- "restrictions": attributes["Restrictions"],
981
- "obligations": attributes["Obligations"],
982
- "entitlements": attributes["Entitlements"],
983
- "usageMeasurements": attributes["Usage Measurements"],
984
- "effectiveFrom": attributes["Effective From"],
985
- "effectiveTo": attributes["Effective To"]
986
-
987
- }
988
- body['properties'] = item_props
816
+ body = set_delete_request_body(object_type, attributes)
817
+
989
818
  egeria_client.detach_agreement_item(agreement_guid, item_guid,body)
990
819
 
991
820
  logger.success(f"===> Detached agreement item `{item}` from agreement `{agreement}`\n")
@@ -1000,7 +829,7 @@ def process_link_agreement_item_command(egeria_client: EgeriaTech, txt: str,
1000
829
  logger.error(msg)
1001
830
 
1002
831
  elif valid is False:
1003
- msg = f"==>{object_type} Link with label `{label}` is not valid and can't be created"
832
+ msg = f"==>{object_type} Link with Agreement `{agreement}` and item `{item}` is not valid and can't be created"
1004
833
  logger.error(msg)
1005
834
  return
1006
835
 
@@ -1008,15 +837,16 @@ def process_link_agreement_item_command(egeria_client: EgeriaTech, txt: str,
1008
837
  body = set_rel_request_body(object_type, attributes)
1009
838
  item_props = {
1010
839
  "class": "AgreementItemProperties",
1011
- "agreementItemId": attributes["Agreement Item Id"],
1012
- "agreementStart": attributes["Agreement Start"],
1013
- "agreementEnd": attributes["Agreement End"],
1014
- "restrictions": attributes["Restrictions"],
1015
- "obligations": attributes["Obligations"],
1016
- "entitlements": attributes["Entitlements"],
1017
- "usageMeasurements": attributes["Usage Measurements"],
1018
- "effectiveFrom": attributes["Effective From"],
1019
- "effectiveTo": attributes["Effective To"]
840
+ "agreementItemId": attributes.get("Agreement Item Id",{}).get("value", None),
841
+ "agreementItemTypeName": attributes.get("Agreement Item Type",{}).get("value", None),
842
+ "agreementStart": attributes.get("Agreement Start",{}).get("value", None),
843
+ "agreementEnd": attributes.get("Agreement End",{}).get("value", None),
844
+ "restrictions": attributes.get("Restrictions",{}).get("value", None),
845
+ "obligations": attributes.get("Obligations",{}).get("value", None),
846
+ "entitlements": attributes.get("Entitlements",{}).get("value", None),
847
+ "usageMeasurements": attributes.get("Usage Measurements",{}).get("value", None),
848
+ "effectiveFrom": attributes.get("Effective From",{}).get("value", None),
849
+ "effectiveTo": attributes.get("Effective To",{}).get("value", None)
1020
850
 
1021
851
  }
1022
852
  body['properties'] = item_props
@@ -1034,19 +864,128 @@ def process_link_agreement_item_command(egeria_client: EgeriaTech, txt: str,
1034
864
  else:
1035
865
  return None
1036
866
 
867
+ def process_add_to_collection_command(egeria_client: EgeriaTech, txt: str,
868
+ directive: str = "display") -> Optional[str]:
869
+ """
870
+ Processes a link or unlink command to add or remove a member to/from a collection..
871
+
872
+ :param txt: A string representing the input cell to be processed for
873
+ extracting blueprint-related attributes.
874
+ :param directive: an optional string indicating the directive to be used - display, validate or execute
875
+ :return: A string summarizing the outcome of the processing.
876
+ """
877
+ command, object_type, object_action = extract_command_plus(txt)
878
+ print(Markdown(f"# {command}\n"))
879
+
880
+ parsed_output = parse_view_command(egeria_client, object_type, object_action, txt, directive)
1037
881
 
882
+ print(Markdown(parsed_output['display']))
1038
883
 
1039
- #
1040
- # View commands
1041
- #
1042
- @logger.catch
1043
- def process_collection_list_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
884
+ logger.debug(json.dumps(parsed_output, indent=4))
885
+
886
+ attributes = parsed_output['attributes']
887
+ element_guid = attributes.get('Element Id',{}).get('guid', None)
888
+ collection_guid = attributes.get('Collection Id', {}).get('guid', None)
889
+ membership_rationale = attributes.get('Membership Rationale',{}).get('value', None)
890
+ expression = attributes.get('Expression', {}).get('value', None)
891
+ confidence = attributes.get('Confidence', {}).get('value', None)
892
+ membership_status = attributes.get('Membership Status', {}).get('value', None)
893
+ user_defined_status = attributes.get('User Defined Status', {}).get('value', None)
894
+ steward = attributes.get('Steward', {}).get('guid', None)
895
+ steward_type_name = attributes.get('Steward Type Name', {}).get('value', None)
896
+ steward_property_name = attributes.get('Steward Property Name', {}).get('value', None)
897
+ source = attributes.get('Source', {}).get('value', None)
898
+ notes = attributes.get('Notes', {}).get('value', None)
899
+ glossary_term = attributes.get('Glossary Term', {}).get('value', None)
900
+ journal_entry = attributes.get('Journal Entry', {}).get('value', None)
901
+
902
+
903
+ valid = parsed_output['valid']
904
+ exists = agreement_guid is not None and item_guid is not None
905
+
906
+
907
+ if directive == "display":
908
+
909
+ return None
910
+ elif directive == "validate":
911
+ if valid:
912
+ print(Markdown(f"==> Validation of {command} completed successfully!\n"))
913
+ else:
914
+ msg = f"Validation failed for object_action `{command}`\n"
915
+ return valid
916
+
917
+ elif directive == "process":
918
+ prop_body = {
919
+ "class" : "CollectionMembershipProperties",
920
+ "membershipRationale": membership_rationale,
921
+ "expression": expression,
922
+ "membershipStatus": membership_status,
923
+ "userDefinedStatus": user_defined_status,
924
+ "confidence": confidence,
925
+ "steward": steward,
926
+ "stewardTypeName": steward_type_name,
927
+ "stewardPropertyName": steward_property_name,
928
+ "source": source,
929
+ "notes": notes,
930
+ }
931
+ try:
932
+ if object_action == "Detach":
933
+ if not exists:
934
+ msg = (f" Link `{label}` does not exist! Updating result document with Link "
935
+ f"object_action\n")
936
+ logger.error(msg)
937
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
938
+ return out
939
+ elif not valid:
940
+ return None
941
+ else:
942
+ print(Markdown(
943
+ f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
944
+ body = set_delete_request_body(object_type, attributes)
945
+
946
+ egeria_client.remove_from_collection(collection_guid, element_guid,body)
947
+
948
+ logger.success(f"===> Detached element `{element_guid}` from collection `{collection_guid}`\n")
949
+ out = parsed_output['display'].replace('Unlink', 'Link', 1)
950
+
951
+ return (out)
952
+
953
+ elif object_action == "Link":
954
+ if valid is False and exists:
955
+ msg = (f"--> Link called `{label}` already exists and result document updated changing "
956
+ f"`Link` to `Detach` in processed output\n")
957
+ logger.error(msg)
958
+
959
+ elif valid is False:
960
+ msg = f"==>{object_type} Link with label `{label}` is not valid and can't be created"
961
+ logger.error(msg)
962
+ return
963
+
964
+ else:
965
+ body = set_rel_request_body(object_type, attributes)
966
+
967
+ body['properties'] = prop_body
968
+ egeria_client.add_to_collection(collection_guid,
969
+ element_guid, body)
970
+ msg = f"==>Linked `{element_guid}` to collection `{collection_guid}` \n"
971
+ logger.success(msg)
972
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
973
+ return out
974
+
975
+
976
+ except Exception as e:
977
+ logger.error(f"Error performing {command}: {e}")
978
+ return None
979
+ else:
980
+ return None
981
+
982
+ def process_product_dependency_command(egeria_client: EgeriaTech, txt: str,
983
+ directive: str = "display") -> Optional[str]:
1044
984
  """
1045
- Processes a Data Dictionary list object_action by extracting key attributes such as
1046
- search string from the given text.
985
+ Processes a link or unlink command to associate or break up a dependency between digital products..
1047
986
 
1048
987
  :param txt: A string representing the input cell to be processed for
1049
- extracting term-related attributes.
988
+ extracting blueprint-related attributes.
1050
989
  :param directive: an optional string indicating the directive to be used - display, validate or execute
1051
990
  :return: A string summarizing the outcome of the processing.
1052
991
  """
@@ -1055,76 +994,287 @@ def process_collection_list_command(egeria_client: EgeriaTech, txt: str, directi
1055
994
 
1056
995
  parsed_output = parse_view_command(egeria_client, object_type, object_action, txt, directive)
1057
996
 
1058
- col_type = to_pascal_case(object_type) if object_type != "Collections" else None
997
+ print(Markdown(parsed_output['display']))
998
+
999
+ logger.debug(json.dumps(parsed_output, indent=4))
1000
+
1001
+ attributes = parsed_output['attributes']
1002
+ digital_product1_guid = attributes.get('Digital Product 1', None)
1003
+ digital_product2_guid = attributes.get('Digital Product 2', None)
1004
+ label = attributes.get('Label',{}).get('value', None)
1005
+ description = attributes.get('Description', {}).get('value', None)
1006
+ effective_from = attributes.get('Effective From', {}).get('value', None)
1007
+ effective_to = attributes.get('Effective To', {}).get('value', None)
1008
+
1059
1009
 
1060
1010
  valid = parsed_output['valid']
1061
- print(Markdown(f"Performing {command}"))
1011
+ exists = agreement_guid is not None and item_guid is not None
1012
+
1013
+
1014
+ if directive == "display":
1015
+
1016
+ return None
1017
+ elif directive == "validate":
1018
+ if valid:
1019
+ print(Markdown(f"==> Validation of {command} completed successfully!\n"))
1020
+ else:
1021
+ msg = f"Validation failed for object_action `{command}`\n"
1022
+ return valid
1023
+
1024
+ elif directive == "process":
1025
+ prop_body = {
1026
+ "class" : "DigitalProductDependencyProperties",
1027
+ "label": label,
1028
+ "description": description,
1029
+ "effectiveFrom": effective_from,
1030
+ "effectiveTo": effective_to
1031
+ }
1032
+
1033
+ try:
1034
+ if object_action == "Detach":
1035
+ if not exists:
1036
+ msg = (f" Link `{label}` does not exist! Updating result document with Link "
1037
+ f"object_action\n")
1038
+ logger.error(msg)
1039
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
1040
+ return out
1041
+ elif not valid:
1042
+ return None
1043
+ else:
1044
+ print(Markdown(
1045
+ f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
1046
+ body = set_delete_request_body(object_type, attributes)
1047
+
1048
+ egeria_client.detach_digital_product_dependency(digital_product1_guid, digital_product2_guid,body)
1049
+
1050
+ logger.success(f"===> Detached dependency between products `{digital_product1_guid}` and `{digital_product2_guid}`\n")
1051
+ out = parsed_output['display'].replace('Unlink', 'Link', 1)
1052
+
1053
+ return (out)
1054
+
1055
+ elif object_action == "Link":
1056
+ if valid is False and exists:
1057
+ msg = (f"--> Link called `{label}` already exists and result document updated changing "
1058
+ f"`Link` to `Detach` in processed output\n")
1059
+ logger.error(msg)
1060
+
1061
+ elif valid is False:
1062
+ msg = f"==>{object_type} Link with label `{label}` is not valid and can't be created"
1063
+ logger.error(msg)
1064
+ return
1065
+
1066
+ else:
1067
+ body = set_rel_request_body(object_type, attributes)
1068
+
1069
+ body['properties'] = prop_body
1070
+ egeria_client.link_digital_product_dependency(digital_product1_guid,
1071
+ digital_product2_guid, body)
1072
+ msg = f"==>Linked dependency from digital product `{digital_product1_guid}` to product `{digital_product2_guid}` \n"
1073
+ logger.success(msg)
1074
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
1075
+ return out
1076
+
1077
+
1078
+ except Exception as e:
1079
+ logger.error(f"Error performing {command}: {e}")
1080
+ return None
1081
+ else:
1082
+ return None
1083
+
1084
+ def process_attach_collection_command(egeria_client: EgeriaTech, txt: str,
1085
+ directive: str = "display") -> Optional[str]:
1086
+ """
1087
+ Processes a link or unlink command to attach a collection to a resources.
1088
+
1089
+ :param txt: A string representing the input cell to be processed for
1090
+ extracting blueprint-related attributes.
1091
+ :param directive: an optional string indicating the directive to be used - display, validate or execute
1092
+ :return: A string summarizing the outcome of the processing.
1093
+ """
1094
+ command, object_type, object_action = extract_command_plus(txt)
1095
+ print(Markdown(f"# {command}\n"))
1096
+
1097
+ parsed_output = parse_view_command(egeria_client, object_type, object_action, txt, directive)
1098
+
1062
1099
  print(Markdown(parsed_output['display']))
1063
1100
 
1064
- attr = parsed_output.get('attributes',{})
1065
- columns = attr.get('Columns',{}).get('value',None).replace("'", '"')
1101
+ logger.debug(json.dumps(parsed_output, indent=4))
1102
+
1103
+ attributes = parsed_output['attributes']
1104
+ collection_guid = attributes.get('Collection Id', {}).get('guid', None)
1105
+ resource_guid = attributes.get('Resource Id', {}).get('guid', None)
1106
+ resource_use = attributes.get('Resource Use', {}).get('value', None)
1107
+ resource_description = attributes.get('Resource Description', {}).get('value', None)
1108
+ resource_properties = attributes.get('Resource Properties', {}).get('value', None)
1109
+ effective_from = attributes.get('Effective From', {}).get('value', None)
1110
+ effective_to = attributes.get('Effective To', {}).get('value', None)
1111
+
1112
+
1113
+ valid = parsed_output['valid']
1114
+ exists = agreement_guid is not None and item_guid is not None
1066
1115
 
1067
- try:
1068
- columns_list = json.loads(columns)
1069
- except Exception as e:
1070
- print(e)
1071
- exit(1)
1072
-
1073
- effective_time = attr.get('effectiveTime', {}).get('value', None)
1074
- as_of_time = attr.get('asOfTime', {}).get('value', None)
1075
- for_duplicate_processing = attr.get('forDuplicateProcessing', {}).get('value', False)
1076
- for_lineage = attr.get('forLineage',{}).get('value', False)
1077
- limit_result_by_status = attr.get('limitResultsByStatus',{}).get('value', [])
1078
- sequencing_property = attr.get('sequencingProperty',{}).get('value',"qualifiedName" )
1079
- sequencing_order = attr.get('sequencingOrder',{}).get('value', "PROPERTY_ASCENDING")
1080
- search_string = attr.get('Search String', {}).get('value', '*')
1081
- search_string = search_string if search_string != "*" else None
1082
- output_format = attr.get('Output Format', {}).get('value', 'LIST')
1083
- detailed = attr.get('Detailed', {}).get('value', False)
1084
1116
 
1085
1117
  if directive == "display":
1118
+
1086
1119
  return None
1087
1120
  elif directive == "validate":
1088
1121
  if valid:
1089
1122
  print(Markdown(f"==> Validation of {command} completed successfully!\n"))
1090
1123
  else:
1091
1124
  msg = f"Validation failed for object_action `{command}`\n"
1092
- logger.error(msg)
1093
1125
  return valid
1094
1126
 
1095
1127
  elif directive == "process":
1128
+ prop_body = {
1129
+ "class" : "ResourceListProperties",
1130
+ "resourceUse": resource_use,
1131
+ "resourceDescription": resource_description,
1132
+ "resourceProperties": resource_properties,
1133
+ "effectiveFrom": effective_from,
1134
+ "effectiveTo": effective_to
1135
+ }
1136
+
1096
1137
  try:
1097
- if not valid: # First validate the command before we process it
1098
- msg = f"Validation failed for {object_action} `{object_type}`\n"
1099
- logger.error(msg)
1100
- return None
1101
-
1102
- list_md = f"\n# `{col_type}` with filter: `{search_string}`\n\n"
1103
- body = {
1104
- "class": "FilterRequestBody",
1105
- "asOfTime": as_of_time,
1106
- "effectiveTime": effective_time,
1107
- "forLineage": for_lineage,
1108
- "forDuplicateProcessing": for_duplicate_processing,
1109
- "limitResultsByStatus": limit_result_by_status,
1110
- "sequencingOrder": sequencing_order,
1111
- "sequencingProperty": sequencing_property,
1112
- "filter": search_string,
1113
- }
1114
-
1115
- struct = egeria_client.find_collections_w_body(body, col_type,
1116
- output_format = output_format, columns=columns_list)
1117
- if output_format == "DICT":
1118
- list_md += f"```\n{json.dumps(struct, indent=4)}\n```\n"
1119
- else:
1120
- list_md += struct
1121
- logger.info(f"Wrote `{col_type}` for search string: `{search_string}`")
1138
+ if object_action == "Detach":
1139
+ if not exists:
1140
+ msg = (f" Link `{label}` does not exist! Updating result document with Link "
1141
+ f"object_action\n")
1142
+ logger.error(msg)
1143
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
1144
+ return out
1145
+ elif not valid:
1146
+ return None
1147
+ else:
1148
+ print(Markdown(
1149
+ f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
1150
+ body = set_delete_request_body(object_type, attributes)
1151
+
1152
+ egeria_client.detach_collection(resource_guid, collection_guid,body)
1153
+
1154
+ logger.success(f"===> Detached linkage between resource `{resource_guid}` and collection`{collection_guid}`\n")
1155
+ out = parsed_output['display'].replace('Unlink', 'Link', 1)
1156
+
1157
+ return (out)
1158
+
1159
+ elif object_action == "Link":
1160
+ if valid is False and exists:
1161
+ msg = (f"--> Link called `{label}` already exists and result document updated changing "
1162
+ f"`Link` to `Detach` in processed output\n")
1163
+ logger.error(msg)
1164
+
1165
+ elif valid is False:
1166
+ msg = f"==>{object_type} Link with label `{label}` is not valid and can't be created"
1167
+ logger.error(msg)
1168
+ return
1169
+
1170
+ else:
1171
+ body = set_rel_request_body(object_type, attributes)
1172
+
1173
+ body['properties'] = prop_body
1174
+ egeria_client.attach_collection(resource_guid,
1175
+ collection_guid, body)
1176
+ msg = f"==>Attached collection `{collection_guid}` to resource `{resource_guid}` \n"
1177
+ logger.success(msg)
1178
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
1179
+ return out
1180
+
1181
+
1182
+ except Exception as e:
1183
+ logger.error(f"Error performing {command}: {e}")
1184
+ return None
1185
+ else:
1186
+ return None
1187
+
1188
+ def process_attach_subscriber_command(egeria_client: EgeriaTech, txt: str,
1189
+ directive: str = "display") -> Optional[str]:
1190
+ """
1191
+ Processes a link or unlink command to attach a subscriber to a subscription.
1192
+
1193
+ :param txt: A string representing the input cell to be processed for
1194
+ extracting blueprint-related attributes.
1195
+ :param directive: an optional string indicating the directive to be used - display, validate or execute
1196
+ :return: A string summarizing the outcome of the processing.
1197
+ """
1198
+ command, object_type, object_action = extract_command_plus(txt)
1199
+ print(Markdown(f"# {command}\n"))
1200
+
1201
+ parsed_output = parse_view_command(egeria_client, object_type, object_action, txt, directive)
1202
+
1203
+ print(Markdown(parsed_output['display']))
1204
+
1205
+ logger.debug(json.dumps(parsed_output, indent=4))
1206
+
1207
+ attributes = parsed_output['attributes']
1208
+ subscriber_guid = attributes.get('Subscriber', {}).get('guid', None)
1209
+ subscription_guid = attributes.get('Subscription', {}).get('guid', None)
1210
+
1211
+ valid = parsed_output['valid']
1212
+
1213
+ if directive == "display":
1214
+
1215
+ return None
1216
+ elif directive == "validate":
1217
+ if valid:
1218
+ print(Markdown(f"==> Validation of {command} completed successfully!\n"))
1219
+ else:
1220
+ msg = f"Validation failed for object_action `{command}`\n"
1221
+ return valid
1222
+
1223
+ elif directive == "process":
1224
+ prop_body = {
1225
+ "class": "DigitalSubscriberProperties",
1226
+ "subscriberId": attributes.get('Subscriber Id', {}).get('value', None),
1227
+ "effectiveFrom": attributes.get('Effective From', {}).get('value', None),
1228
+ "effectiveTo": attributes.get('Effective To', {}).get('value', None),
1229
+ }
1230
+
1231
+ try:
1232
+ if object_action == "Detach":
1233
+ if not exists:
1234
+ msg = (f" Link `{label}` does not exist! Updating result document with Link "
1235
+ f"object_action\n")
1236
+ logger.error(msg)
1237
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
1238
+ return out
1239
+ elif not valid:
1240
+ return None
1241
+ else:
1242
+ print(Markdown(
1243
+ f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
1244
+ body = set_delete_request_body(object_type, attributes)
1245
+
1246
+ egeria_client.detach_subscriber(subscriber_guid, subscription_guid,body)
1247
+
1248
+ logger.success(f"===> Detached linkage between subscriber `{subscriber_guid}` and subscription`{subscription_guid}`\n")
1249
+ out = parsed_output['display'].replace('Unlink', 'Link', 1)
1250
+
1251
+ return (out)
1252
+
1253
+ elif object_action == "Link":
1254
+ if valid is False and exists:
1255
+ msg = (f"--> Link called `{label}` already exists and result document updated changing "
1256
+ f"`Link` to `Detach` in processed output\n")
1257
+ logger.error(msg)
1258
+
1259
+ elif valid is False:
1260
+ msg = f"==>{object_type} Subscription link `{subscriber_guid}` is not valid and can't be created"
1261
+ logger.error(msg)
1262
+ return
1263
+
1264
+ else:
1265
+ body = set_rel_request_body(object_type, attributes)
1266
+
1267
+ body['properties'] = prop_body
1268
+ egeria_client.link_subscriber(subscriber_guid,
1269
+ subscription_guid, body)
1270
+ msg = f"==>Attached subscriber `{subscriber_guid}` to subscription `{subscriber_guid}` \n"
1271
+ logger.success(msg)
1272
+ out = parsed_output['display'].replace('Link', 'Detach', 1)
1273
+ return out
1122
1274
 
1123
- return list_md
1124
1275
 
1125
1276
  except Exception as e:
1126
1277
  logger.error(f"Error performing {command}: {e}")
1127
- console.print_exception(show_locals=True)
1128
1278
  return None
1129
1279
  else:
1130
1280
  return None