pyegeria 5.3.9.9.7__py3-none-any.whl → 5.4.0__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.
- commands/cat/debug_log +2806 -0
- commands/cat/debug_log.2025-07-15_14-28-38_087378.zip +0 -0
- commands/cat/debug_log.2025-07-16_15-48-50_037087.zip +0 -0
- commands/cat/dr_egeria_command_help.py +273 -0
- commands/cat/dr_egeria_md.py +90 -20
- commands/cat/glossary_actions.py +2 -2
- commands/cat/list_collections.py +24 -10
- commands/cat/list_data_designer.py +183 -0
- md_processing/__init__.py +28 -5
- md_processing/data/commands.json +31474 -1096
- md_processing/dr_egeria_outbox-pycharm/.obsidian/app.json +1 -0
- md_processing/dr_egeria_outbox-pycharm/.obsidian/appearance.json +1 -0
- md_processing/dr_egeria_outbox-pycharm/.obsidian/core-plugins.json +31 -0
- md_processing/dr_egeria_outbox-pycharm/.obsidian/workspace.json +177 -0
- md_processing/dr_egeria_outbox-pycharm/monday/processed-2025-07-14 12:38-data_designer_out.md +663 -0
- md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 15:00-Derive-Dr-Gov-Defs.md +719 -0
- md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:13-Derive-Dr-Gov-Defs.md +41 -0
- md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:14-Derive-Dr-Gov-Defs.md +33 -0
- md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:50-Derive-Dr-Gov-Defs.md +192 -0
- md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-16 19:15-gov_def2.md +527 -0
- md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-17 12:08-gov_def2.md +527 -0
- md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-17 14:27-gov_def2.md +474 -0
- md_processing/family_docs/Data Designer/Create_Data_Class.md +164 -0
- md_processing/family_docs/Data Designer/Create_Data_Dictionary.md +30 -0
- md_processing/family_docs/Data Designer/Create_Data_Field.md +162 -0
- md_processing/family_docs/Data Designer/Create_Data_Specification.md +36 -0
- md_processing/family_docs/Data Designer/Create_Data_Structure.md +38 -0
- md_processing/family_docs/Data Designer/View_Data_Classes.md +78 -0
- md_processing/family_docs/Data Designer/View_Data_Dictionaries.md +78 -0
- md_processing/family_docs/Data Designer/View_Data_Fields.md +78 -0
- md_processing/family_docs/Data Designer/View_Data_Specifications.md +78 -0
- md_processing/family_docs/Data Designer/View_Data_Structures.md +78 -0
- md_processing/family_docs/Data Designer.md +842 -0
- md_processing/family_docs/Digital Product Manager/Add_Member->Collection.md +42 -0
- md_processing/family_docs/Digital Product Manager/Attach_Collection->Resource.md +36 -0
- md_processing/family_docs/Digital Product Manager/Create_Agreement.md +96 -0
- md_processing/family_docs/Digital Product Manager/Create_Data_Sharing_Agreement.md +72 -0
- md_processing/family_docs/Digital Product Manager/Create_DigitalSubscription.md +102 -0
- md_processing/family_docs/Digital Product Manager/Create_Digital_Product.md +134 -0
- md_processing/family_docs/Digital Product Manager/Link_Agreement_Items.md +60 -0
- md_processing/family_docs/Digital Product Manager/Link_Contracts.md +26 -0
- md_processing/family_docs/Digital Product Manager/Link_Digital_Product_-_Digital_Product.md +30 -0
- md_processing/family_docs/Digital Product Manager/Link_Subscribers.md +48 -0
- md_processing/family_docs/Digital Product Manager.md +668 -0
- md_processing/family_docs/Glossary/Attach_Category_Parent.md +18 -0
- md_processing/family_docs/Glossary/Attach_Term-Term_Relationship.md +26 -0
- md_processing/family_docs/Glossary/Create_Category.md +38 -0
- md_processing/family_docs/Glossary/Create_Glossary.md +42 -0
- md_processing/family_docs/Glossary/Create_Term.md +70 -0
- md_processing/family_docs/Glossary.md +206 -0
- md_processing/family_docs/Governance Officer/Create_Business_Imperative.md +106 -0
- md_processing/family_docs/Governance Officer/Create_Certification_Type.md +112 -0
- md_processing/family_docs/Governance Officer/Create_Governance_Approach.md +114 -0
- md_processing/family_docs/Governance Officer/Create_Governance_Obligation.md +114 -0
- md_processing/family_docs/Governance Officer/Create_Governance_Principle.md +114 -0
- md_processing/family_docs/Governance Officer/Create_Governance_Procedure.md +128 -0
- md_processing/family_docs/Governance Officer/Create_Governance_Process.md +122 -0
- md_processing/family_docs/Governance Officer/Create_Governance_Processing_Purpose.md +106 -0
- md_processing/family_docs/Governance Officer/Create_Governance_Responsibility.md +122 -0
- md_processing/family_docs/Governance Officer/Create_Governance_Rule.md +122 -0
- md_processing/family_docs/Governance Officer/Create_Governance_Strategy.md +106 -0
- md_processing/family_docs/Governance Officer/Create_License_Type.md +112 -0
- md_processing/family_docs/Governance Officer/Create_Naming_Standard_Rule.md +122 -0
- md_processing/family_docs/Governance Officer/Create_Regulation_Article.md +106 -0
- md_processing/family_docs/Governance Officer/Create_Regulation_Definition.md +118 -0
- md_processing/family_docs/Governance Officer/Create_Security_Access_Control.md +114 -0
- md_processing/family_docs/Governance Officer/Create_Security_Group.md +120 -0
- md_processing/family_docs/Governance Officer/Create_Service_Level_Objectives.md +122 -0
- md_processing/family_docs/Governance Officer/Create_Threat_Definition.md +106 -0
- md_processing/family_docs/Governance Officer/Link_Governance_Controls.md +32 -0
- md_processing/family_docs/Governance Officer/Link_Governance_Drivers.md +32 -0
- md_processing/family_docs/Governance Officer/Link_Governance_Policies.md +32 -0
- md_processing/family_docs/Governance Officer/View_Governance_Definitions.md +82 -0
- md_processing/family_docs/Governance Officer.md +2412 -0
- md_processing/family_docs/Solution Architect/Create_Information_Supply_Chain.md +70 -0
- md_processing/family_docs/Solution Architect/Create_Solution_Blueprint.md +44 -0
- md_processing/family_docs/Solution Architect/Create_Solution_Component.md +96 -0
- md_processing/family_docs/Solution Architect/Create_Solution_Role.md +66 -0
- md_processing/family_docs/Solution Architect/Link_Information_Supply_Chain_Peers.md +32 -0
- md_processing/family_docs/Solution Architect/Link_Solution_Component_Peers.md +32 -0
- md_processing/family_docs/Solution Architect/View_Information_Supply_Chains.md +32 -0
- md_processing/family_docs/Solution Architect/View_Solution_Blueprints.md +32 -0
- md_processing/family_docs/Solution Architect/View_Solution_Components.md +32 -0
- md_processing/family_docs/Solution Architect/View_Solution_Roles.md +32 -0
- md_processing/family_docs/Solution Architect.md +490 -0
- md_processing/md_commands/data_designer_commands.py +1192 -710
- md_processing/md_commands/glossary_commands.py +19 -32
- md_processing/md_commands/governance_officer_commands.py +420 -0
- md_processing/md_commands/product_manager_commands.py +1180 -0
- md_processing/md_commands/project_commands.py +5 -2
- md_processing/md_commands/solution_architect_commands.py +1140 -0
- md_processing/md_processing_utils/common_md_proc_utils.py +288 -96
- md_processing/md_processing_utils/common_md_utils.py +205 -6
- md_processing/md_processing_utils/debug_log +574 -0
- md_processing/md_processing_utils/dr-egeria-help-2025-07-17T17:22:09.md +2065 -0
- md_processing/md_processing_utils/extraction_utils.py +1 -1
- md_processing/md_processing_utils/generate_dr_help.py +165 -0
- md_processing/md_processing_utils/generate_md_cmd_templates.py +143 -0
- md_processing/md_processing_utils/generate_md_templates.py +92 -0
- md_processing/md_processing_utils/generated_help_terms.md +842 -0
- md_processing/md_processing_utils/md_processing_constants.py +94 -17
- pyegeria/__init__.py +1 -0
- pyegeria/_client.py +39 -1
- pyegeria/classification_manager_omvs.py +1 -1
- pyegeria/collection_manager_omvs.py +4667 -1178
- pyegeria/data_designer_omvs.py +348 -31
- pyegeria/egeria_tech_client.py +9 -25
- pyegeria/glossary_browser_omvs.py +5 -6
- pyegeria/glossary_manager_omvs.py +2 -2
- pyegeria/governance_officer_omvs.py +2367 -0
- pyegeria/output_formatter.py +157 -32
- pyegeria/solution_architect_omvs.py +5063 -1110
- pyegeria/utils.py +22 -2
- {pyegeria-5.3.9.9.7.dist-info → pyegeria-5.4.0.dist-info}/METADATA +3 -1
- pyegeria-5.4.0.dist-info/RECORD +243 -0
- {pyegeria-5.3.9.9.7.dist-info → pyegeria-5.4.0.dist-info}/entry_points.txt +5 -0
- commands/cat/.DS_Store +0 -0
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro.md +0 -254
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_more_terms.md +0 -696
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part1.md +0 -254
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part2.md +0 -298
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part3.md +0 -608
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part4.md +0 -94
- md_processing/dr_egeria_inbox/archive/freddie_intro.md +0 -284
- md_processing/dr_egeria_inbox/archive/freddie_intro_orig.md +0 -275
- md_processing/dr_egeria_inbox/archive/test-term.md +0 -110
- md_processing/dr_egeria_inbox/cat_test.md +0 -100
- md_processing/dr_egeria_inbox/data_field.md +0 -54
- md_processing/dr_egeria_inbox/data_spec.md +0 -77
- md_processing/dr_egeria_inbox/data_spec_test.md +0 -2406
- md_processing/dr_egeria_inbox/data_test.md +0 -86
- md_processing/dr_egeria_inbox/dr_egeria_intro_categories.md +0 -168
- md_processing/dr_egeria_inbox/dr_egeria_intro_part1.md +0 -280
- md_processing/dr_egeria_inbox/dr_egeria_intro_part2.md +0 -313
- md_processing/dr_egeria_inbox/dr_egeria_intro_part3.md +0 -1073
- md_processing/dr_egeria_inbox/dr_egeria_isc1.md +0 -44
- md_processing/dr_egeria_inbox/glossary_test1.md +0 -324
- md_processing/dr_egeria_inbox/rel.md +0 -8
- md_processing/dr_egeria_inbox/sb.md +0 -119
- md_processing/dr_egeria_inbox/search_test.md +0 -39
- md_processing/dr_egeria_inbox/solution-components.md +0 -154
- md_processing/dr_egeria_inbox/solution_blueprints.md +0 -118
- md_processing/dr_egeria_inbox/synonym_test.md +0 -42
- md_processing/dr_egeria_inbox/t1.md +0 -0
- md_processing/dr_egeria_inbox/t2.md +0 -268
- md_processing/dr_egeria_outbox/processed-2025-05-15 19:52-data_test.md +0 -94
- md_processing/dr_egeria_outbox/processed-2025-05-16 07:39-data_test.md +0 -88
- md_processing/dr_egeria_outbox/processed-2025-05-17 16:01-data_field.md +0 -56
- md_processing/dr_egeria_outbox/processed-2025-05-18 15:51-data_test.md +0 -103
- md_processing/dr_egeria_outbox/processed-2025-05-18 16:47-data_test.md +0 -94
- md_processing/dr_egeria_outbox/processed-2025-05-19 07:14-data_test.md +0 -96
- md_processing/dr_egeria_outbox/processed-2025-05-19 07:20-data_test.md +0 -100
- md_processing/dr_egeria_outbox/processed-2025-05-19 07:22-data_test.md +0 -88
- md_processing/dr_egeria_outbox/processed-2025-05-19 09:26-data_test.md +0 -91
- md_processing/dr_egeria_outbox/processed-2025-05-19 10:27-data_test.md +0 -91
- md_processing/dr_egeria_outbox/processed-2025-05-19 14:04-data_test.md +0 -91
- md_processing/md_commands/blueprint_commands.py +0 -303
- pyegeria/.DS_Store +0 -0
- pyegeria/m_test.py +0 -118
- pyegeria-5.3.9.9.7.dist-info/RECORD +0 -196
- /commands/cat/{list_data_structures.py → list_data_structures_full.py} +0 -0
- {pyegeria-5.3.9.9.7.dist-info → pyegeria-5.4.0.dist-info}/LICENSE +0 -0
- {pyegeria-5.3.9.9.7.dist-info → pyegeria-5.4.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,1180 @@
|
|
1
|
+
"""
|
2
|
+
This file contains product manager commands for processing Egeria Markdown
|
3
|
+
"""
|
4
|
+
import json
|
5
|
+
import os
|
6
|
+
import sys
|
7
|
+
from typing import Optional
|
8
|
+
|
9
|
+
from loguru import logger
|
10
|
+
from rich import print
|
11
|
+
from rich.console import Console
|
12
|
+
from rich.markdown import Markdown
|
13
|
+
|
14
|
+
from md_processing.md_processing_utils.common_md_proc_utils import (parse_upsert_command, parse_view_command)
|
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
|
18
|
+
from md_processing.md_processing_utils.extraction_utils import (extract_command_plus, update_a_command)
|
19
|
+
from md_processing.md_processing_utils.md_processing_constants import (load_commands, ERROR)
|
20
|
+
from pyegeria import DEBUG_LEVEL, body_slimmer
|
21
|
+
from pyegeria.egeria_tech_client import EgeriaTech
|
22
|
+
|
23
|
+
GERIA_METADATA_STORE = os.environ.get("EGERIA_METADATA_STORE", "active-metadata-store")
|
24
|
+
EGERIA_KAFKA_ENDPOINT = os.environ.get("KAFKA_ENDPOINT", "localhost:9092")
|
25
|
+
EGERIA_PLATFORM_URL = os.environ.get("EGERIA_PLATFORM_URL", "https://localhost:9443")
|
26
|
+
EGERIA_VIEW_SERVER = os.environ.get("EGERIA_VIEW_SERVER", "view-server")
|
27
|
+
EGERIA_VIEW_SERVER_URL = os.environ.get("EGERIA_VIEW_SERVER_URL", "https://localhost:9443")
|
28
|
+
EGERIA_INTEGRATION_DAEMON = os.environ.get("EGERIA_INTEGRATION_DAEMON", "integration-daemon")
|
29
|
+
EGERIA_INTEGRATION_DAEMON_URL = os.environ.get("EGERIA_INTEGRATION_DAEMON_URL", "https://localhost:9443")
|
30
|
+
EGERIA_ADMIN_USER = os.environ.get("ADMIN_USER", "garygeeke")
|
31
|
+
EGERIA_ADMIN_PASSWORD = os.environ.get("ADMIN_PASSWORD", "secret")
|
32
|
+
EGERIA_USER = os.environ.get("EGERIA_USER", "erinoverview")
|
33
|
+
EGERIA_USER_PASSWORD = os.environ.get("EGERIA_USER_PASSWORD", "secret")
|
34
|
+
EGERIA_WIDTH = os.environ.get("EGERIA_WIDTH", 220)
|
35
|
+
EGERIA_JUPYTER = os.environ.get("EGERIA_JUPYTER", False)
|
36
|
+
EGERIA_HOME_GLOSSARY_GUID = os.environ.get("EGERIA_HOME_GLOSSARY_GUID", None)
|
37
|
+
EGERIA_GLOSSARY_PATH = os.environ.get("EGERIA_GLOSSARY_PATH", None)
|
38
|
+
EGERIA_ROOT_PATH = os.environ.get("EGERIA_ROOT_PATH", "../../")
|
39
|
+
EGERIA_INBOX_PATH = os.environ.get("EGERIA_INBOX_PATH", "md_processing/dr_egeria_inbox")
|
40
|
+
EGERIA_OUTBOX_PATH = os.environ.get("EGERIA_OUTBOX_PATH", "md_processing/dr_egeria_outbox")
|
41
|
+
|
42
|
+
load_commands('commands.json')
|
43
|
+
debug_level = DEBUG_LEVEL
|
44
|
+
|
45
|
+
console = Console(width=int(200))
|
46
|
+
setup_log()
|
47
|
+
|
48
|
+
|
49
|
+
#
|
50
|
+
# Helper functions for the data designer commands
|
51
|
+
#
|
52
|
+
@logger.catch
|
53
|
+
def add_member_to_collections(egeria_client: EgeriaTech, collection_list: list, display_name: str,
|
54
|
+
guid: str) -> None:
|
55
|
+
"""
|
56
|
+
Add member to data dictionaries and data specifications.
|
57
|
+
"""
|
58
|
+
body = {
|
59
|
+
"class": "RelationshipRequestBody", "properties": {
|
60
|
+
"class": "CollectionMembershipProperties", "membershipRationale": "User Specified",
|
61
|
+
"notes": "Added by Dr.Egeria"
|
62
|
+
}
|
63
|
+
}
|
64
|
+
try:
|
65
|
+
if collection_list is not None:
|
66
|
+
for collection in collection_list:
|
67
|
+
egeria_client.add_to_collection(collection, guid, body)
|
68
|
+
msg = f"Added `{display_name}` member to `{collection}`"
|
69
|
+
logger.info(msg)
|
70
|
+
else:
|
71
|
+
logger.info("There were no data collections to add.")
|
72
|
+
return
|
73
|
+
|
74
|
+
except Exception as e:
|
75
|
+
console.print_exception()
|
76
|
+
|
77
|
+
|
78
|
+
@logger.catch
|
79
|
+
def remove_member_from_collections(egeria_client: EgeriaTech, collection_list: list, display_name: str,
|
80
|
+
guid: str) -> None:
|
81
|
+
try:
|
82
|
+
for collection in collection_list:
|
83
|
+
egeria_client.remove_from_collection(collection, guid)
|
84
|
+
msg = f"Removed `{display_name}` member from `{collection}`"
|
85
|
+
logger.info(msg)
|
86
|
+
return
|
87
|
+
|
88
|
+
except Exception as e:
|
89
|
+
console.print_exception()
|
90
|
+
|
91
|
+
|
92
|
+
@logger.catch
|
93
|
+
def update_data_collection_memberships(egeria_client: EgeriaTech, entity_type: str, guid_list: list,
|
94
|
+
collection_class: str, guid: str, display_name: str,
|
95
|
+
replace_all_props: bool = True) -> None:
|
96
|
+
""" update the collection membership of the element
|
97
|
+
|
98
|
+
If replace_all_props is set to True, all existing memberships are removed and new memberships are added.
|
99
|
+
If replace_all_props is set to False, only the new memberships are added.
|
100
|
+
"""
|
101
|
+
|
102
|
+
if replace_all_props:
|
103
|
+
match entity_type:
|
104
|
+
case "Data Specification":
|
105
|
+
get_command = egeria_client.get_collection_by_guid
|
106
|
+
case "Data Structure":
|
107
|
+
get_command = egeria_client.get_data_structure_by_guid
|
108
|
+
case "Data Field":
|
109
|
+
get_command = egeria_client.get_data_field_by_guid
|
110
|
+
case "Data Class":
|
111
|
+
get_command = egeria_client.get_data_class_by_guid
|
112
|
+
|
113
|
+
coll_list = egeria_client.get_data_memberships(get_command, guid)
|
114
|
+
if coll_list is None:
|
115
|
+
logger.warning("Unexpected -> the collection list was None - assigning empty dict")
|
116
|
+
coll_list = {}
|
117
|
+
# compare the existing collections to desired collections
|
118
|
+
if collection_class == "DataDictionary":
|
119
|
+
as_is = set(coll_list.get("DictList", {}))
|
120
|
+
elif collection_class == "DataSpec":
|
121
|
+
as_is = set(coll_list.get("SpecList", {}))
|
122
|
+
|
123
|
+
dict_set = set(coll_list.get("DictList", {}))
|
124
|
+
spec_set = set(coll_list.get("SpecList", {}))
|
125
|
+
to_be_set = set(guid_list) if guid_list is not None else set()
|
126
|
+
logger.debug(f"as_is: {as_is}")
|
127
|
+
logger.debug(f"to_be_set: {to_be_set}")
|
128
|
+
|
129
|
+
# Remove membership for collections that are in the as-is but not in the to-be
|
130
|
+
to_remove = as_is - to_be_set
|
131
|
+
logger.debug(f"to_remove: {to_remove}")
|
132
|
+
if len(to_remove) > 0:
|
133
|
+
remove_member_from_collections(egeria_client, to_remove, display_name, guid)
|
134
|
+
|
135
|
+
# add membership for collections that are in the to-be but are not in the as-is
|
136
|
+
to_add = to_be_set - as_is
|
137
|
+
logger.debug(f"to_add: {to_add}")
|
138
|
+
if len(to_add) > 0:
|
139
|
+
add_member_to_collections(egeria_client, to_add, display_name, guid)
|
140
|
+
else:
|
141
|
+
add_member_to_collections(egeria_client, guid_list, display_name, guid)
|
142
|
+
|
143
|
+
|
144
|
+
# @logger.catch
|
145
|
+
|
146
|
+
|
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.
|
311
|
+
|
312
|
+
"""
|
313
|
+
if terms:
|
314
|
+
terms = [terms]
|
315
|
+
|
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)
|
408
|
+
#
|
409
|
+
# Product Manager Commands
|
410
|
+
#
|
411
|
+
|
412
|
+
@logger.catch
|
413
|
+
def process_digital_product_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
|
414
|
+
"""
|
415
|
+
Processes a digital product create or update object_action by extracting key attributes such as
|
416
|
+
spec name, parent_guid, parent_relationship_type, parent_at_end_1, collection_type
|
417
|
+
|
418
|
+
:param txt: A string representing the input cell to be processed for
|
419
|
+
extracting glossary-related attributes.
|
420
|
+
:param directive: an optional string indicating the directive to be used - display, validate or execute
|
421
|
+
:return: A string summarizing the outcome of the processing.
|
422
|
+
"""
|
423
|
+
|
424
|
+
command, object_type, object_action = extract_command_plus(txt)
|
425
|
+
print(Markdown(f"# {command}\n"))
|
426
|
+
|
427
|
+
parsed_output = parse_upsert_command(egeria_client, object_type, object_action, txt, directive)
|
428
|
+
|
429
|
+
valid = parsed_output['valid']
|
430
|
+
exists = parsed_output['exists']
|
431
|
+
|
432
|
+
qualified_name = parsed_output.get('qualified_name', None)
|
433
|
+
guid = parsed_output.get('guid', None)
|
434
|
+
|
435
|
+
print(Markdown(parsed_output['display']))
|
436
|
+
|
437
|
+
logger.debug(json.dumps(parsed_output, indent=4))
|
438
|
+
|
439
|
+
attributes = parsed_output['attributes']
|
440
|
+
|
441
|
+
display_name = attributes['Display Name'].get('value', None)
|
442
|
+
description = attributes.get('Description',{}).get('value', None)
|
443
|
+
user_defined_status = attributes.get('User Defined Status',{}).get('value', None)
|
444
|
+
product_identifier = attributes.get('Product Identifier',{}).get('value', None)
|
445
|
+
product_name = attributes.get('Product Name',{}).get('value', None)
|
446
|
+
product_type = attributes.get('Product Type',{}).get('value', None)
|
447
|
+
|
448
|
+
|
449
|
+
|
450
|
+
product_description = attributes.get('Product Description',{}).get('value', None)
|
451
|
+
maturity = attributes.get('Maturity',{}).get('value', None)
|
452
|
+
service_life = attributes.get('Service Life',{}).get('value', None)
|
453
|
+
introduction_date = attributes.get('Introduction Date',{}).get('value', None)
|
454
|
+
next_version_date = attributes.get('Next Version Date',{}).get('value', None)
|
455
|
+
withdrawal_date = attributes.get('Withdrawal Date',{}).get('value', None)
|
456
|
+
|
457
|
+
collection_type = attributes.get('Collection Type', {}).get('value', None)
|
458
|
+
current_version = attributes.get('Version Identifier',{}).get('value', None)
|
459
|
+
product_manager = attributes.get('Product Manager',{}).get('value', None)
|
460
|
+
|
461
|
+
|
462
|
+
product_status = attributes.get('Status',{}).get('value', "ACTIVE")
|
463
|
+
|
464
|
+
anchor_guid = attributes.get('Anchor ID', {}).get('guid', None)
|
465
|
+
parent_guid = attributes.get('Parent ID', {}).get('guid', None)
|
466
|
+
parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value', None)
|
467
|
+
parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value',"CollectionMembership")
|
468
|
+
parent_at_end1 = attributes.get('Parent at End1', {}).get('value', True)
|
469
|
+
anchor_scope_guid = attributes.get('Anchor Scope GUID', {}).get('value', None)
|
470
|
+
is_own_anchor = attributes.get('Is Own Anchor', {}).get('value', True)
|
471
|
+
if parent_guid is None:
|
472
|
+
is_own_anchor = True
|
473
|
+
|
474
|
+
|
475
|
+
additional_prop = attributes.get('Additional Properties', {}).get('value', None)
|
476
|
+
additional_properties = json.loads(additional_prop) if additional_prop is not None else None
|
477
|
+
extended_prop = attributes.get('Extended Properties', {}).get('value', None)
|
478
|
+
extended_properties = json.loads(extended_prop) if extended_prop is not None else None
|
479
|
+
external_source_guid = attributes.get('External Source Name', {}).get('guid', None)
|
480
|
+
external_source_name = attributes.get('External Source Name', {}).get('value', None)
|
481
|
+
effective_time = attributes.get('Effective Time', {}).get('value', None)
|
482
|
+
for_lineage = attributes.get('For Lineage', {}).get('value', None)
|
483
|
+
for_duplicate_processing = attributes.get('For Duplicate Processing', {}).get('value', None)
|
484
|
+
|
485
|
+
replace_all_props = not attributes.get('Merge Update', {}).get('value', True)
|
486
|
+
|
487
|
+
if directive == "display":
|
488
|
+
|
489
|
+
return None
|
490
|
+
elif directive == "validate":
|
491
|
+
if valid:
|
492
|
+
print(Markdown(f"==> Validation of {command} completed successfully!\n"))
|
493
|
+
else:
|
494
|
+
msg = f"Validation failed for object_action `{command}`\n"
|
495
|
+
return valid
|
496
|
+
|
497
|
+
elif directive == "process":
|
498
|
+
try:
|
499
|
+
if object_action == "Update":
|
500
|
+
if not exists:
|
501
|
+
msg = (f" Element `{display_name}` does not exist! Updating result document with Create "
|
502
|
+
f"object_action\n")
|
503
|
+
logger.error(msg)
|
504
|
+
return update_a_command(txt, object_action, object_type, qualified_name, guid)
|
505
|
+
elif not valid:
|
506
|
+
return None
|
507
|
+
else:
|
508
|
+
print(Markdown(
|
509
|
+
f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
|
510
|
+
prop_body = set_prop_body(object_type,qualified_name,attributes)
|
511
|
+
|
512
|
+
body ={
|
513
|
+
"class": "UpdateElementRequestBody",
|
514
|
+
"properties": {
|
515
|
+
"class": "DigitalProductProperties",
|
516
|
+
"qualifiedName": qualified_name,
|
517
|
+
"userDefinedStatus": user_defined_status,
|
518
|
+
"name": display_name,
|
519
|
+
"description": description,
|
520
|
+
"identifier": product_identifier,
|
521
|
+
"productName": product_name,
|
522
|
+
"productType": product_type,
|
523
|
+
"maturity": maturity,
|
524
|
+
"serviceLife": service_life,
|
525
|
+
"introductionDate": introduction_date,
|
526
|
+
"nextVersionDate": next_version_date,
|
527
|
+
"withdrawDate": withdrawal_date,
|
528
|
+
"currentVersion": current_version,
|
529
|
+
"additionalProperties": additional_properties,
|
530
|
+
"extendedProperties": extended_properties,
|
531
|
+
},
|
532
|
+
"externalSourceGUID": external_source_guid,
|
533
|
+
"externalSourceName": external_source_name,
|
534
|
+
"effectiveTime": effective_time,
|
535
|
+
"forLineage": for_lineage,
|
536
|
+
"forDuplicateProcessing": for_duplicate_processing
|
537
|
+
}
|
538
|
+
|
539
|
+
egeria_client.update_digital_product(guid, body)
|
540
|
+
egeria_client.update_digital_product_status(guid, product_status)
|
541
|
+
|
542
|
+
logger.success(f"Updated {object_type} `{display_name}` with GUID {guid}\n\n___")
|
543
|
+
update_element_dictionary(qualified_name, {
|
544
|
+
'guid': guid, 'display_name': display_name
|
545
|
+
})
|
546
|
+
return egeria_client.get_collection_by_guid(guid, collection_type='Data Specification',
|
547
|
+
output_format='MD')
|
548
|
+
|
549
|
+
|
550
|
+
elif object_action == "Create":
|
551
|
+
if valid is False and exists:
|
552
|
+
msg = (f" Digital Product `{display_name}` already exists and result document updated changing "
|
553
|
+
f"`Create` to `Update` in processed output\n\n___")
|
554
|
+
logger.error(msg)
|
555
|
+
return update_a_command(txt, object_action, object_type, qualified_name, guid)
|
556
|
+
|
557
|
+
else:
|
558
|
+
body = {
|
559
|
+
"class": "NewDigitalProductRequestBody",
|
560
|
+
"isOwnAnchor": is_own_anchor,
|
561
|
+
"parentGUID": parent_guid,
|
562
|
+
"parentRelationshipTypeName": parent_relationship_type_name,
|
563
|
+
"parentAtEnd1": parent_at_end1,
|
564
|
+
"properties": {
|
565
|
+
"class": "DigitalProductProperties",
|
566
|
+
"qualifiedName": qualified_name,
|
567
|
+
"userDefinedStatus": user_defined_status,
|
568
|
+
"name": display_name,
|
569
|
+
"description" : description,
|
570
|
+
"identifier": product_identifier,
|
571
|
+
"productName": product_name,
|
572
|
+
"productType": product_type,
|
573
|
+
"maturity": maturity,
|
574
|
+
"serviceLife": service_life,
|
575
|
+
"introductionDate": introduction_date,
|
576
|
+
"nextVersionDate": next_version_date,
|
577
|
+
"withdrawDate": withdrawal_date,
|
578
|
+
"currentVersion": current_version,
|
579
|
+
|
580
|
+
"additionalProperties": additional_properties,
|
581
|
+
"extendedProperties": extended_properties,
|
582
|
+
},
|
583
|
+
"initialStatus": product_status,
|
584
|
+
"externalSourceGUID": external_source_guid,
|
585
|
+
"externalSourceName": external_source_name,
|
586
|
+
"effectiveTime" : effective_time,
|
587
|
+
"forLineage": for_lineage,
|
588
|
+
"forDuplicateProcessing": for_duplicate_processing
|
589
|
+
}
|
590
|
+
|
591
|
+
|
592
|
+
|
593
|
+
guid = egeria_client.create_digital_product(body)
|
594
|
+
if guid:
|
595
|
+
update_element_dictionary(qualified_name, {
|
596
|
+
'guid': guid, 'display_name': display_name
|
597
|
+
})
|
598
|
+
msg = f"Created Element `{display_name}` with GUID {guid}\n\n___"
|
599
|
+
logger.success(msg)
|
600
|
+
return egeria_client.get_collection_by_guid(guid, collection_type='Digital Product',
|
601
|
+
output_format='MD')
|
602
|
+
else:
|
603
|
+
msg = f"Failed to create element `{display_name}` with GUID {guid}\n\n___"
|
604
|
+
logger.error(msg)
|
605
|
+
return None
|
606
|
+
|
607
|
+
except Exception as e:
|
608
|
+
logger.error(f"Error performing {command}: {e}")
|
609
|
+
return None
|
610
|
+
else:
|
611
|
+
return None
|
612
|
+
|
613
|
+
|
614
|
+
@logger.catch
|
615
|
+
def process_agreement_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
|
616
|
+
"""
|
617
|
+
Processes an agreement create or update object_action by extracting key attributes such as
|
618
|
+
spec name, parent_guid, parent_relationship_type, parent_at_end_1, collection_type
|
619
|
+
|
620
|
+
:param txt: A string representing the input cell to be processed for
|
621
|
+
extracting glossary-related attributes.
|
622
|
+
:param directive: an optional string indicating the directive to be used - display, validate or execute
|
623
|
+
:return: A string summarizing the outcome of the processing.
|
624
|
+
"""
|
625
|
+
|
626
|
+
command, object_type, object_action = extract_command_plus(txt)
|
627
|
+
print(Markdown(f"# {command}\n"))
|
628
|
+
|
629
|
+
parsed_output = parse_upsert_command(egeria_client, object_type, object_action, txt, directive)
|
630
|
+
|
631
|
+
valid = parsed_output['valid']
|
632
|
+
exists = parsed_output['exists']
|
633
|
+
|
634
|
+
qualified_name = parsed_output.get('qualified_name', None)
|
635
|
+
guid = parsed_output.get('guid', None)
|
636
|
+
|
637
|
+
print(Markdown(parsed_output['display']))
|
638
|
+
|
639
|
+
logger.debug(json.dumps(parsed_output, indent=4))
|
640
|
+
|
641
|
+
attributes = parsed_output['attributes']
|
642
|
+
|
643
|
+
display_name = attributes['Display Name'].get('value', None)
|
644
|
+
description = attributes.get('Description',{}).get('value', None)
|
645
|
+
user_defined_status = attributes.get('User Defined Status',{}).get('value', None)
|
646
|
+
agreement_status = attributes.get('Status',{}).get('value', None)
|
647
|
+
agreement_identifier = attributes.get('Agreement Identifier',{}).get('value', None)
|
648
|
+
|
649
|
+
version_identifier = attributes.get('Version Identifier',{}).get('value', None)
|
650
|
+
|
651
|
+
actors = attributes.get('Agreement Actors',{}).get('value', None)
|
652
|
+
actor_names = attributes.get('Agreement Actors',{}).get('name_list', None)
|
653
|
+
actor_guids = attributes.get('Agreement Actors',{}).get('guid_list', None)
|
654
|
+
anchor_guid = attributes.get('Anchor ID', {}).get('guid', None)
|
655
|
+
parent_guid = attributes.get('Parent ID', {}).get('guid', None)
|
656
|
+
parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value', None)
|
657
|
+
parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value',"CollectionMembership")
|
658
|
+
parent_at_end1 = attributes.get('Parent at End1', {}).get('value', True)
|
659
|
+
anchor_scope_guid = attributes.get('Anchor Scope GUID', {}).get('value', None)
|
660
|
+
is_own_anchor = attributes.get('Is Own Anchor', {}).get('value', True)
|
661
|
+
if parent_guid is None:
|
662
|
+
is_own_anchor = True
|
663
|
+
|
664
|
+
|
665
|
+
additional_prop = attributes.get('Additional Properties', {}).get('value', None)
|
666
|
+
additional_properties = json.loads(additional_prop) if additional_prop is not None else None
|
667
|
+
extended_prop = attributes.get('Extended Properties', {}).get('value', None)
|
668
|
+
extended_properties = json.loads(extended_prop) if extended_prop is not None else None
|
669
|
+
external_source_guid = attributes.get('External Source Name', {}).get('guid', None)
|
670
|
+
external_source_name = attributes.get('External Source Name', {}).get('value', None)
|
671
|
+
effective_time = attributes.get('Effective Time', {}).get('value', None)
|
672
|
+
for_lineage = attributes.get('For Lineage', {}).get('value', None)
|
673
|
+
for_duplicate_processing = attributes.get('For Duplicate Processing', {}).get('value', None)
|
674
|
+
|
675
|
+
replace_all_props = not attributes.get('Merge Update', {}).get('value', True)
|
676
|
+
|
677
|
+
if directive == "display":
|
678
|
+
|
679
|
+
return None
|
680
|
+
elif directive == "validate":
|
681
|
+
if valid:
|
682
|
+
print(Markdown(f"==> Validation of {command} completed successfully!\n"))
|
683
|
+
else:
|
684
|
+
msg = f"Validation failed for object_action `{command}`\n"
|
685
|
+
return valid
|
686
|
+
|
687
|
+
elif directive == "process":
|
688
|
+
try:
|
689
|
+
if object_action == "Update":
|
690
|
+
if not exists:
|
691
|
+
msg = (f" Element `{display_name}` does not exist! Updating result document with Create "
|
692
|
+
f"object_action\n")
|
693
|
+
logger.error(msg)
|
694
|
+
return update_a_command(txt, object_action, object_type, qualified_name, guid)
|
695
|
+
elif not valid:
|
696
|
+
return None
|
697
|
+
else:
|
698
|
+
print(Markdown(
|
699
|
+
f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
|
700
|
+
|
701
|
+
product_body = {
|
702
|
+
"class": "AgreementProperties",
|
703
|
+
"qualifiedName": qualified_name,
|
704
|
+
"userDefinedStatus": user_defined_status,
|
705
|
+
"name": display_name,
|
706
|
+
"description": description,
|
707
|
+
"identifier": agreement_identifier,
|
708
|
+
"additionalProperties": additional_properties,
|
709
|
+
"extendedProperties": extended_properties,
|
710
|
+
}
|
711
|
+
|
712
|
+
body = set_update_body(object_type, attributes)
|
713
|
+
body['properties'] = product_body
|
714
|
+
|
715
|
+
egeria_client.update_agreement(guid, body, replace_all_props)
|
716
|
+
status_update_body = set_element_status_request_body(object_type, attributes)
|
717
|
+
egeria_client.update_agreement_status(guid, status_update_body)
|
718
|
+
|
719
|
+
logger.success(f"Updated {object_type} `{display_name}` with GUID {guid}\n\n___")
|
720
|
+
update_element_dictionary(qualified_name, {
|
721
|
+
'guid': guid, 'display_name': display_name
|
722
|
+
})
|
723
|
+
return egeria_client.get_collection_by_guid(guid, collection_type='Data Specification',
|
724
|
+
output_format='MD')
|
725
|
+
|
726
|
+
elif object_action == "Create":
|
727
|
+
if valid is False and exists:
|
728
|
+
msg = (f" Digital Product `{display_name}` already exists and result document updated changing "
|
729
|
+
f"`Create` to `Update` in processed output\n\n___")
|
730
|
+
logger.error(msg)
|
731
|
+
return update_a_command(txt, object_action, object_type, qualified_name, guid)
|
732
|
+
|
733
|
+
else:
|
734
|
+
body = {
|
735
|
+
"class": "NewAgreementRequestBody",
|
736
|
+
"isOwnAnchor": is_own_anchor,
|
737
|
+
"parentGUID": parent_guid,
|
738
|
+
"parentRelationshipTypeName": parent_relationship_type_name,
|
739
|
+
"parentAtEnd1": parent_at_end1,
|
740
|
+
"properties": {
|
741
|
+
"class": "AgreementProperties",
|
742
|
+
"qualifiedName": qualified_name,
|
743
|
+
"userDefinedStatus": user_defined_status,
|
744
|
+
"name": display_name,
|
745
|
+
"description" : description,
|
746
|
+
"identifier" : agreement_identifier,
|
747
|
+
"additionalProperties": additional_properties,
|
748
|
+
"extendedProperties": extended_properties,
|
749
|
+
},
|
750
|
+
"initialStatus": agreement_status,
|
751
|
+
"externalSourceGUID": external_source_guid,
|
752
|
+
"externalSourceName": external_source_name,
|
753
|
+
"effectiveTime" : effective_time,
|
754
|
+
"forLineage": for_lineage,
|
755
|
+
"forDuplicateProcessing": for_duplicate_processing
|
756
|
+
}
|
757
|
+
if object_type == "Data Sharing Agreement":
|
758
|
+
guid = egeria_client.create_data_sharing_agreement(body)
|
759
|
+
elif object_type == "Agreement":
|
760
|
+
guid = egeria_client.create_agreement(body)
|
761
|
+
|
762
|
+
if guid:
|
763
|
+
update_element_dictionary(qualified_name, {
|
764
|
+
'guid': guid, 'display_name': display_name
|
765
|
+
})
|
766
|
+
msg = f"Created Element `{display_name}` with GUID {guid}\n\n___"
|
767
|
+
logger.success(msg)
|
768
|
+
return egeria_client.get_collection_by_guid(guid, collection_type='Digital Product',
|
769
|
+
output_format='MD')
|
770
|
+
else:
|
771
|
+
msg = f"Failed to create element `{display_name}` with GUID {guid}\n\n___"
|
772
|
+
logger.error(msg)
|
773
|
+
return None
|
774
|
+
|
775
|
+
except Exception as e:
|
776
|
+
logger.error(f"Error performing {command}: {e}")
|
777
|
+
return None
|
778
|
+
else:
|
779
|
+
return None
|
780
|
+
|
781
|
+
|
782
|
+
def process_link_agreement_item_command(egeria_client: EgeriaTech, txt: str,
|
783
|
+
directive: str = "display") -> Optional[str]:
|
784
|
+
"""
|
785
|
+
Processes a link or unlink command to associate or break up peer governance definitions.
|
786
|
+
|
787
|
+
:param txt: A string representing the input cell to be processed for
|
788
|
+
extracting blueprint-related attributes.
|
789
|
+
:param directive: an optional string indicating the directive to be used - display, validate or execute
|
790
|
+
:return: A string summarizing the outcome of the processing.
|
791
|
+
"""
|
792
|
+
command, object_type, object_action = extract_command_plus(txt)
|
793
|
+
print(Markdown(f"# {command}\n"))
|
794
|
+
|
795
|
+
parsed_output = parse_view_command(egeria_client, object_type, object_action, txt, directive)
|
796
|
+
|
797
|
+
print(Markdown(parsed_output['display']))
|
798
|
+
|
799
|
+
logger.debug(json.dumps(parsed_output, indent=4))
|
800
|
+
|
801
|
+
attributes = parsed_output['attributes']
|
802
|
+
agreement = attributes.get('Agreement Name',{}).get('value', None)
|
803
|
+
agreement_guid = attributes.get('Definition 1', {}).get('guid', None)
|
804
|
+
item = attributes.get('Item Name',{}).get('value', None)
|
805
|
+
item_guid = attributes.get('Definition 2', {}).get('guid', None)
|
806
|
+
label = attributes.get('Link Label', {}).get('value', None)
|
807
|
+
description = attributes.get('Description', {}).get('value', None)
|
808
|
+
|
809
|
+
valid = parsed_output['valid']
|
810
|
+
exists = agreement_guid is not None and item_guid is not None
|
811
|
+
|
812
|
+
|
813
|
+
if directive == "display":
|
814
|
+
|
815
|
+
return None
|
816
|
+
elif directive == "validate":
|
817
|
+
if valid:
|
818
|
+
print(Markdown(f"==> Validation of {command} completed successfully!\n"))
|
819
|
+
else:
|
820
|
+
msg = f"Validation failed for object_action `{command}`\n"
|
821
|
+
return valid
|
822
|
+
|
823
|
+
elif directive == "process":
|
824
|
+
gov_peer_relationship_type = object_type[:-1].replace(" ","") + "Link"
|
825
|
+
|
826
|
+
try:
|
827
|
+
if object_action == "Detach":
|
828
|
+
if not exists:
|
829
|
+
msg = (f" Link `{label}` does not exist! Updating result document with Link "
|
830
|
+
f"object_action\n")
|
831
|
+
logger.error(msg)
|
832
|
+
out = parsed_output['display'].replace('Link', 'Detach', 1)
|
833
|
+
return out
|
834
|
+
elif not valid:
|
835
|
+
return None
|
836
|
+
else:
|
837
|
+
print(Markdown(
|
838
|
+
f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
|
839
|
+
body = set_metadata_source_request_body(object_type, attributes)
|
840
|
+
|
841
|
+
egeria_client.detach_agreement_item(agreement_guid, item_guid,body)
|
842
|
+
|
843
|
+
logger.success(f"===> Detached agreement item `{item}` from agreement `{agreement}`\n")
|
844
|
+
out = parsed_output['display'].replace('Unlink', 'Link', 1)
|
845
|
+
|
846
|
+
return (out)
|
847
|
+
|
848
|
+
elif object_action == "Link":
|
849
|
+
if valid is False and exists:
|
850
|
+
msg = (f"--> Link called `{label}` already exists and result document updated changing "
|
851
|
+
f"`Link` to `Detach` in processed output\n")
|
852
|
+
logger.error(msg)
|
853
|
+
|
854
|
+
elif valid is False:
|
855
|
+
msg = f"==>{object_type} Link with label `{label}` is not valid and can't be created"
|
856
|
+
logger.error(msg)
|
857
|
+
return
|
858
|
+
|
859
|
+
else:
|
860
|
+
body = set_rel_request_body(object_type, attributes)
|
861
|
+
item_props = {
|
862
|
+
"class": "AgreementItemProperties",
|
863
|
+
"agreementItemId": attributes["Agreement Item Id"],
|
864
|
+
"agreementStart": attributes["Agreement Start"],
|
865
|
+
"agreementEnd": attributes["Agreement End"],
|
866
|
+
"restrictions": attributes["Restrictions"],
|
867
|
+
"obligations": attributes["Obligations"],
|
868
|
+
"entitlements": attributes["Entitlements"],
|
869
|
+
"usageMeasurements": attributes["Usage Measurements"],
|
870
|
+
"effectiveFrom": attributes["Effective From"],
|
871
|
+
"effectiveTo": attributes["Effective To"]
|
872
|
+
|
873
|
+
}
|
874
|
+
egeria_client.link_agreement_item(agreement_guid,
|
875
|
+
item_guid, body)
|
876
|
+
msg = f"==>Linked {object_type} `{agreement} to item {item}\n"
|
877
|
+
logger.success(msg)
|
878
|
+
out = parsed_output['display'].replace('Link', 'Detach', 1)
|
879
|
+
return out
|
880
|
+
|
881
|
+
|
882
|
+
except Exception as e:
|
883
|
+
logger.error(f"Error performing {command}: {e}")
|
884
|
+
return None
|
885
|
+
else:
|
886
|
+
return None
|
887
|
+
|
888
|
+
|
889
|
+
|
890
|
+
#
|
891
|
+
# View commands
|
892
|
+
#
|
893
|
+
@logger.catch
|
894
|
+
def process_data_collection_list_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[
|
895
|
+
str]:
|
896
|
+
"""
|
897
|
+
Processes a Data Dictionary list object_action by extracting key attributes such as
|
898
|
+
search string from the given text.
|
899
|
+
|
900
|
+
:param txt: A string representing the input cell to be processed for
|
901
|
+
extracting term-related attributes.
|
902
|
+
:param directive: an optional string indicating the directive to be used - display, validate or execute
|
903
|
+
:return: A string summarizing the outcome of the processing.
|
904
|
+
"""
|
905
|
+
command, object_type, object_action = extract_command_plus(txt)
|
906
|
+
print(Markdown(f"# {command}\n"))
|
907
|
+
if object_type in ["Data Dictionary", "Data Dictionaries", "DataDict", "DataDictionary"]:
|
908
|
+
col_type = "DataDictionary"
|
909
|
+
elif object_type in ["Data Specification", "Data Specifications", "Data Specs"]:
|
910
|
+
col_type = "DataSpec"
|
911
|
+
else:
|
912
|
+
col_type = "Collection"
|
913
|
+
|
914
|
+
parsed_output = parse_view_command(egeria_client, object_type, object_action, txt, directive)
|
915
|
+
|
916
|
+
|
917
|
+
|
918
|
+
valid = parsed_output['valid']
|
919
|
+
print(Markdown(f"Performing {command}"))
|
920
|
+
print(Markdown(parsed_output['display']))
|
921
|
+
|
922
|
+
attr = parsed_output.get('attributes',{})
|
923
|
+
effective_time = attr.get('effectiveTime', {}).get('value', None)
|
924
|
+
as_of_time = attr.get('asOfTime', {}).get('value', None)
|
925
|
+
for_duplicate_processing = attr.get('forDuplicateProcessing', {}).get('value', False)
|
926
|
+
for_lineage = attr.get('forLineage',{}).get('value', False)
|
927
|
+
limit_result_by_status = attr.get('limitResultsByStatus',{}).get('value', ['ACTIVE'])
|
928
|
+
sequencing_property = attr.get('sequencingProperty',{}).get('value',"qualifiedName" )
|
929
|
+
sequencing_order = attr.get('sequencingOrder',{}).get('value', "PROPERTY_ASCENDING")
|
930
|
+
search_string = attr.get('Search String', {}).get('value', '*')
|
931
|
+
output_format = attr.get('Output Format', {}).get('value', 'LIST')
|
932
|
+
detailed = attr.get('Detailed', {}).get('value', False)
|
933
|
+
|
934
|
+
if directive == "display":
|
935
|
+
return None
|
936
|
+
elif directive == "validate":
|
937
|
+
if valid:
|
938
|
+
print(Markdown(f"==> Validation of {command} completed successfully!\n"))
|
939
|
+
else:
|
940
|
+
msg = f"Validation failed for object_action `{command}`\n"
|
941
|
+
logger.error(msg)
|
942
|
+
return valid
|
943
|
+
|
944
|
+
elif directive == "process":
|
945
|
+
try:
|
946
|
+
if not valid: # First validate the command before we process it
|
947
|
+
msg = f"Validation failed for {object_action} `{object_type}`\n"
|
948
|
+
logger.error(msg)
|
949
|
+
return None
|
950
|
+
|
951
|
+
list_md = f"\n# `{col_type}` with filter: `{search_string}`\n\n"
|
952
|
+
body = {
|
953
|
+
"class": "FilterRequestBody",
|
954
|
+
"asOfTime": as_of_time,
|
955
|
+
"effectiveTime": effective_time,
|
956
|
+
"forLineage": for_lineage,
|
957
|
+
"forDuplicateProcessing": for_duplicate_processing,
|
958
|
+
"limitResultsByStatus": limit_result_by_status,
|
959
|
+
"sequencingOrder": sequencing_order,
|
960
|
+
"sequencingProperty": sequencing_property,
|
961
|
+
"filter": search_string,
|
962
|
+
}
|
963
|
+
|
964
|
+
struct = egeria_client.find_collections_w_body(body, col_type, output_format=output_format)
|
965
|
+
if output_format == "DICT":
|
966
|
+
list_md += f"```\n{json.dumps(struct, indent=4)}\n```\n"
|
967
|
+
else:
|
968
|
+
list_md += struct
|
969
|
+
logger.info(f"Wrote `{col_type}` for search string: `{search_string}`")
|
970
|
+
|
971
|
+
return list_md
|
972
|
+
|
973
|
+
except Exception as e:
|
974
|
+
logger.error(f"Error performing {command}: {e}")
|
975
|
+
console.print_exception(show_locals=True)
|
976
|
+
return None
|
977
|
+
else:
|
978
|
+
return None
|
979
|
+
|
980
|
+
# TODO
|
981
|
+
def process_data_agreement_list_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[
|
982
|
+
str]:
|
983
|
+
"""
|
984
|
+
Processes a Data Dictionary list object_action by extracting key attributes such as
|
985
|
+
search string from the given text.
|
986
|
+
|
987
|
+
:param txt: A string representing the input cell to be processed for
|
988
|
+
extracting term-related attributes.
|
989
|
+
:param directive: an optional string indicating the directive to be used - display, validate or execute
|
990
|
+
:return: A string summarizing the outcome of the processing.
|
991
|
+
"""
|
992
|
+
command, object_type, object_action = extract_command_plus(txt)
|
993
|
+
print(Markdown(f"# {command}\n"))
|
994
|
+
|
995
|
+
parsed_output = parse_view_command(egeria_client, object_type, object_action, txt, directive)
|
996
|
+
|
997
|
+
attributes = parsed_output['attributes']
|
998
|
+
|
999
|
+
valid = parsed_output['valid']
|
1000
|
+
print(Markdown(f"Performing {command}"))
|
1001
|
+
print(Markdown(parsed_output['display']))
|
1002
|
+
|
1003
|
+
if directive == "display":
|
1004
|
+
return None
|
1005
|
+
elif directive == "validate":
|
1006
|
+
if valid:
|
1007
|
+
print(Markdown(f"==> Validation of {command} completed successfully!\n"))
|
1008
|
+
else:
|
1009
|
+
msg = f"Validation failed for object_action `{command}`\n"
|
1010
|
+
logger.error(msg)
|
1011
|
+
return valid
|
1012
|
+
|
1013
|
+
elif directive == "process":
|
1014
|
+
attributes = parsed_output['attributes']
|
1015
|
+
search_string = attributes.get('Search String', {}).get('value', '*')
|
1016
|
+
output_format = attributes.get('Output Format', {}).get('value', 'LIST')
|
1017
|
+
detailed = attributes.get('Detailed', {}).get('value', False)
|
1018
|
+
|
1019
|
+
try:
|
1020
|
+
if not valid: # First validate the command before we process it
|
1021
|
+
msg = f"Validation failed for {object_action} `{object_type}`\n"
|
1022
|
+
logger.error(msg)
|
1023
|
+
return None
|
1024
|
+
|
1025
|
+
list_md = f"\n# `{object_type}` with filter: `{search_string}`\n\n"
|
1026
|
+
struct = egeria_client.find_data_structures(search_string, output_format=output_format)
|
1027
|
+
|
1028
|
+
if output_format == "DICT":
|
1029
|
+
list_md += f"```\n{json.dumps(struct, indent=4)}\n```\n"
|
1030
|
+
else:
|
1031
|
+
list_md += struct
|
1032
|
+
logger.info(f"Wrote `{object_type}` for search string: `{search_string}`")
|
1033
|
+
|
1034
|
+
return list_md
|
1035
|
+
|
1036
|
+
except Exception as e:
|
1037
|
+
logger.error(f"Error performing {command}: {e}")
|
1038
|
+
console.print_exception(show_locals=True)
|
1039
|
+
return None
|
1040
|
+
else:
|
1041
|
+
return None
|
1042
|
+
|
1043
|
+
# TODO
|
1044
|
+
def process_subscription_list_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
|
1045
|
+
"""
|
1046
|
+
Processes a Data Dictionary list object_action by extracting key attributes such as
|
1047
|
+
search string from the given text.
|
1048
|
+
|
1049
|
+
:param txt: A string representing the input cell to be processed for
|
1050
|
+
extracting term-related attributes.
|
1051
|
+
:param directive: an optional string indicating the directive to be used - display, validate or execute
|
1052
|
+
:return: A string summarizing the outcome of the processing.
|
1053
|
+
"""
|
1054
|
+
command, object_type, object_action = extract_command_plus(txt)
|
1055
|
+
print(Markdown(f"# {command}\n"))
|
1056
|
+
|
1057
|
+
parsed_output = parse_view_command(egeria_client, object_type, object_action, txt, directive)
|
1058
|
+
|
1059
|
+
attributes = parsed_output['attributes']
|
1060
|
+
|
1061
|
+
valid = parsed_output['valid']
|
1062
|
+
print(Markdown(f"Performing {command}"))
|
1063
|
+
print(Markdown(parsed_output['display']))
|
1064
|
+
|
1065
|
+
if directive == "display":
|
1066
|
+
return None
|
1067
|
+
elif directive == "validate":
|
1068
|
+
if valid:
|
1069
|
+
print(Markdown(f"==> Validation of {command} completed successfully!\n"))
|
1070
|
+
else:
|
1071
|
+
msg = f"Validation failed for object_action `{command}`\n"
|
1072
|
+
logger.error(msg)
|
1073
|
+
return valid
|
1074
|
+
|
1075
|
+
elif directive == "process":
|
1076
|
+
attributes = parsed_output['attributes']
|
1077
|
+
search_string = attributes.get('Search String', {}).get('value', '*')
|
1078
|
+
output_format = attributes.get('Output Format', {}).get('value', 'LIST')
|
1079
|
+
detailed = attributes.get('Detailed', {}).get('value', False)
|
1080
|
+
as_of_time = attributes.get('AsOfTime', {}).get('value', None)
|
1081
|
+
effective_time = attributes.get('Effective Time', {}).get('value', None)
|
1082
|
+
sort_order = attributes.get('Sort Order', {}).get('value', None)
|
1083
|
+
order_property = attributes.get('Order Property', {}).get('value', None)
|
1084
|
+
starts_with = attributes.get('Start With', {}).get('value', True)
|
1085
|
+
ends_with = attributes.get('End With', {}).get('value', False)
|
1086
|
+
ignore_case = attributes.get('Ignore Case', {}).get('value', False)
|
1087
|
+
start_from = attributes.get('Start From', {}).get('value', 0)
|
1088
|
+
page_size = attributes.get('Page Size', {}).get('value', None)
|
1089
|
+
|
1090
|
+
try:
|
1091
|
+
if not valid: # First validate the command before we process it
|
1092
|
+
msg = f"Validation failed for {object_action} `{object_type}`\n"
|
1093
|
+
logger.error(msg)
|
1094
|
+
return None
|
1095
|
+
|
1096
|
+
list_md = f"\n# `{object_type}` with filter: `{search_string}`\n\n"
|
1097
|
+
body = {
|
1098
|
+
"class": "FilterRequestBody", "asOfTime": as_of_time, "effectiveTime": effective_time,
|
1099
|
+
"forLineage": False, "forDuplicateProcessing": False, "limitResultsByStatus": ["ACTIVE"],
|
1100
|
+
"sequencingOrder": sort_order, "sequencingProperty": order_property, "filter": search_string,
|
1101
|
+
}
|
1102
|
+
struct = egeria_client.find_data_fields_w_body(body, start_from, page_size, starts_with, ends_with,
|
1103
|
+
ignore_case, output_format)
|
1104
|
+
|
1105
|
+
if output_format == "DICT":
|
1106
|
+
list_md += f"```\n{json.dumps(struct, indent=4)}\n```\n"
|
1107
|
+
else:
|
1108
|
+
list_md += struct
|
1109
|
+
logger.info(f"Wrote `{object_type}` for search string: `{search_string}`")
|
1110
|
+
|
1111
|
+
return list_md
|
1112
|
+
|
1113
|
+
except Exception as e:
|
1114
|
+
logger.error(f"Error performing {command}: {e}")
|
1115
|
+
console.print_exception(show_locals=True)
|
1116
|
+
return None
|
1117
|
+
else:
|
1118
|
+
return None
|
1119
|
+
|
1120
|
+
# TODO
|
1121
|
+
def process_digital_product_list_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
|
1122
|
+
"""
|
1123
|
+
Processes a Data Dictionary list object_action by extracting key attributes such as
|
1124
|
+
search string from the given text.
|
1125
|
+
|
1126
|
+
:param txt: A string representing the input cell to be processed for
|
1127
|
+
extracting term-related attributes.
|
1128
|
+
:param directive: an optional string indicating the directive to be used - display, validate or execute
|
1129
|
+
:return: A string summarizing the outcome of the processing.
|
1130
|
+
"""
|
1131
|
+
command, object_type, object_action = extract_command_plus(txt)
|
1132
|
+
print(Markdown(f"# {command}\n"))
|
1133
|
+
|
1134
|
+
parsed_output = parse_view_command(egeria_client, object_type, object_action, txt, directive)
|
1135
|
+
|
1136
|
+
attributes = parsed_output['attributes']
|
1137
|
+
|
1138
|
+
valid = parsed_output['valid']
|
1139
|
+
print(Markdown(f"Performing {command}"))
|
1140
|
+
print(Markdown(parsed_output['display']))
|
1141
|
+
|
1142
|
+
if directive == "display":
|
1143
|
+
return None
|
1144
|
+
elif directive == "validate":
|
1145
|
+
if valid:
|
1146
|
+
print(Markdown(f"==> Validation of {command} completed successfully!\n"))
|
1147
|
+
else:
|
1148
|
+
msg = f"Validation failed for object_action `{command}`\n"
|
1149
|
+
logger.error(msg)
|
1150
|
+
return valid
|
1151
|
+
|
1152
|
+
elif directive == "process":
|
1153
|
+
attributes = parsed_output['attributes']
|
1154
|
+
search_string = attributes.get('Search String', {}).get('value', '*')
|
1155
|
+
output_format = attributes.get('Output Format', {}).get('value', 'LIST')
|
1156
|
+
detailed = attributes.get('Detailed', {}).get('value', False)
|
1157
|
+
|
1158
|
+
try:
|
1159
|
+
if not valid: # First validate the command before we process it
|
1160
|
+
msg = f"Validation failed for {object_action} `{object_type}`\n"
|
1161
|
+
logger.error(msg)
|
1162
|
+
return None
|
1163
|
+
|
1164
|
+
list_md = f"\n# `{object_type}` with filter: `{search_string}`\n\n"
|
1165
|
+
struct = egeria_client.find_data_classes(search_string, output_format=output_format)
|
1166
|
+
|
1167
|
+
if output_format == "DICT":
|
1168
|
+
list_md += f"```\n{json.dumps(struct, indent=4)}\n```\n"
|
1169
|
+
else:
|
1170
|
+
list_md += struct
|
1171
|
+
logger.info(f"Wrote `{object_type}` for search string: `{search_string}`")
|
1172
|
+
|
1173
|
+
return list_md
|
1174
|
+
|
1175
|
+
except Exception as e:
|
1176
|
+
logger.error(f"Error performing {command}: {e}")
|
1177
|
+
console.print_exception(show_locals=True)
|
1178
|
+
return None
|
1179
|
+
else:
|
1180
|
+
return None
|