pyegeria 5.3.9.9.3__py3-none-any.whl → 5.5.3.3__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.
Potentially problematic release.
This version of pyegeria might be problematic. Click here for more details.
- commands/__init__.py +24 -0
- commands/cat/Dr-Egeria_md-orig.py +2 -2
- commands/cat/__init__.py +1 -17
- commands/cat/collection_actions.py +197 -0
- commands/cat/dr_egeria_command_help.py +372 -0
- commands/cat/dr_egeria_jupyter.py +7 -7
- commands/cat/dr_egeria_md.py +27 -182
- commands/cat/exp_list_glossaries.py +11 -14
- commands/cat/get_asset_graph.py +37 -267
- commands/cat/{get_collection.py → get_collection_tree.py} +10 -18
- commands/cat/get_project_dependencies.py +14 -14
- commands/cat/get_project_structure.py +15 -14
- commands/cat/get_tech_type_elements.py +16 -116
- commands/cat/glossary_actions.py +145 -298
- commands/cat/list_assets.py +3 -11
- commands/cat/list_cert_types.py +17 -63
- commands/cat/list_collections.py +46 -138
- commands/cat/list_deployed_catalogs.py +15 -27
- commands/cat/list_deployed_database_schemas.py +27 -43
- commands/cat/list_deployed_databases.py +16 -31
- commands/cat/list_deployed_servers.py +35 -54
- commands/cat/list_glossaries.py +18 -17
- commands/cat/list_projects.py +10 -12
- commands/cat/list_tech_type_elements.py +21 -37
- commands/cat/list_tech_types.py +13 -25
- commands/cat/list_terms.py +38 -79
- commands/cat/list_todos.py +4 -11
- commands/cat/list_user_ids.py +3 -10
- commands/cat/my_reports.py +559 -0
- commands/cat/run_report.py +394 -0
- commands/cat/run_report_orig.py +528 -0
- commands/cli/egeria.py +222 -247
- commands/cli/egeria_cat.py +68 -81
- commands/cli/egeria_my.py +13 -0
- commands/cli/egeria_ops.py +69 -74
- commands/cli/egeria_tech.py +17 -93
- commands/cli/ops_config.py +3 -6
- commands/{cat/list_categories.py → deprecated/list_data_designer.py} +53 -64
- commands/{cat/list_data_structures.py → deprecated/list_data_structures_full.py} +3 -6
- commands/deprecated/old_get_asset_graph.py +315 -0
- commands/my/__init__.py +0 -2
- commands/my/list_my_profile.py +27 -34
- commands/my/list_my_roles.py +1 -7
- commands/my/monitor_my_todos.py +1 -7
- commands/my/monitor_open_todos.py +6 -7
- commands/my/todo_actions.py +4 -5
- commands/ops/__init__.py +0 -2
- commands/ops/gov_server_actions.py +17 -21
- commands/ops/list_archives.py +17 -38
- commands/ops/list_catalog_targets.py +33 -40
- commands/ops/load_archive.py +35 -26
- commands/ops/{monitor_engine_activity_c.py → monitor_active_engine_activity.py} +51 -82
- commands/ops/{monitor_integ_daemon_status.py → monitor_daemon_status.py} +35 -55
- commands/ops/monitor_engine_activity.py +79 -77
- commands/ops/{monitor_gov_eng_status.py → monitor_engine_status.py} +10 -7
- commands/ops/monitor_platform_status.py +38 -50
- commands/ops/monitor_server_startup.py +6 -11
- commands/ops/monitor_server_status.py +7 -11
- commands/ops/orig_monitor_server_list.py +8 -8
- commands/ops/orig_monitor_server_status.py +1 -5
- commands/ops/refresh_integration_daemon.py +5 -5
- commands/ops/restart_integration_daemon.py +5 -5
- commands/ops/table_integ_daemon_status.py +6 -6
- commands/ops/x_engine_actions.py +7 -7
- commands/tech/__init__.py +0 -2
- commands/tech/{generic_actions.py → element_actions.py} +6 -11
- commands/tech/get_element_info.py +20 -29
- commands/tech/get_guid_info.py +23 -42
- commands/tech/get_tech_details.py +20 -35
- commands/tech/get_tech_type_template.py +28 -39
- commands/tech/list_all_om_type_elements.py +24 -30
- commands/tech/list_all_om_type_elements_x.py +22 -28
- commands/tech/list_all_related_elements.py +19 -28
- commands/tech/list_anchored_elements.py +22 -30
- commands/tech/list_asset_types.py +19 -24
- commands/tech/list_elements_by_classification_by_property_value.py +26 -32
- commands/tech/list_elements_by_property_value.py +19 -25
- commands/tech/list_elements_by_property_value_x.py +20 -28
- commands/tech/list_elements_for_classification.py +28 -41
- commands/tech/list_gov_action_processes.py +16 -27
- commands/tech/list_information_supply_chains.py +22 -30
- commands/tech/list_registered_services.py +14 -26
- commands/tech/list_related_elements_with_prop_value.py +15 -25
- commands/tech/list_related_specification.py +1 -4
- commands/tech/list_relationship_types.py +15 -25
- commands/tech/list_relationships.py +20 -36
- commands/tech/list_solution_blueprints.py +28 -33
- commands/tech/list_solution_components.py +23 -29
- commands/tech/list_solution_roles.py +21 -32
- commands/tech/list_tech_templates.py +51 -54
- commands/tech/list_valid_metadata_values.py +5 -9
- commands/tech/table_tech_templates.py +2 -6
- commands/tech/x_list_related_elements.py +1 -4
- examples/GeoSpatial Products Example.py +524 -0
- examples/Jupyter Notebooks/P-egeria-server-config.ipynb +2137 -0
- examples/Jupyter Notebooks/README.md +2 -0
- examples/Jupyter Notebooks/common/P-environment-check.ipynb +115 -0
- examples/Jupyter Notebooks/common/__init__.py +14 -0
- examples/Jupyter Notebooks/common/common-functions.ipynb +4694 -0
- examples/Jupyter Notebooks/common/environment-check.ipynb +52 -0
- examples/Jupyter Notebooks/common/globals.ipynb +184 -0
- examples/Jupyter Notebooks/common/globals.py +154 -0
- examples/Jupyter Notebooks/common/orig_globals.py +152 -0
- examples/format_sets/all_format_sets.json +910 -0
- examples/format_sets/custom_format_sets.json +268 -0
- examples/format_sets/subset_format_sets.json +187 -0
- examples/format_sets_save_load_example.py +291 -0
- examples/jacquard_data_sets.py +129 -0
- examples/output_formats_example.py +193 -0
- examples/test_jacquard_data_sets.py +54 -0
- examples/test_jacquard_data_sets_scenarios.py +94 -0
- md_processing/__init__.py +90 -0
- md_processing/command_dispatcher.py +33 -0
- md_processing/command_mapping.py +221 -0
- md_processing/data/commands/commands_data_designer.json +537 -0
- md_processing/data/commands/commands_external_reference.json +733 -0
- md_processing/data/commands/commands_feedback.json +155 -0
- md_processing/data/commands/commands_general.json +204 -0
- md_processing/data/commands/commands_glossary.json +218 -0
- md_processing/data/commands/commands_governance.json +3678 -0
- md_processing/data/commands/commands_product_manager.json +865 -0
- md_processing/data/commands/commands_project.json +642 -0
- md_processing/data/commands/commands_solution_architect.json +366 -0
- md_processing/data/commands.json +17568 -0
- md_processing/data/commands_working.json +30641 -0
- md_processing/data/gened_report_specs.py +6584 -0
- md_processing/data/generated_format_sets.json +6533 -0
- md_processing/data/generated_format_sets_old.json +4137 -0
- md_processing/data/generated_format_sets_old.py +45 -0
- md_processing/dr_egeria.py +182 -0
- md_processing/md_commands/__init__.py +3 -0
- md_processing/md_commands/data_designer_commands.py +1276 -0
- md_processing/md_commands/ext_ref_commands.py +530 -0
- md_processing/md_commands/feedback_commands.py +726 -0
- md_processing/md_commands/glossary_commands.py +684 -0
- md_processing/md_commands/governance_officer_commands.py +600 -0
- md_processing/md_commands/product_manager_commands.py +1266 -0
- md_processing/md_commands/project_commands.py +383 -0
- md_processing/md_commands/solution_architect_commands.py +1184 -0
- md_processing/md_commands/view_commands.py +295 -0
- md_processing/md_processing_utils/__init__.py +4 -0
- md_processing/md_processing_utils/common_md_proc_utils.py +1249 -0
- md_processing/md_processing_utils/common_md_utils.py +578 -0
- md_processing/md_processing_utils/determine_width.py +103 -0
- md_processing/md_processing_utils/extraction_utils.py +547 -0
- md_processing/md_processing_utils/gen_report_specs.py +643 -0
- md_processing/md_processing_utils/generate_dr_help.py +193 -0
- md_processing/md_processing_utils/generate_md_cmd_templates.py +144 -0
- md_processing/md_processing_utils/generate_md_templates.py +83 -0
- md_processing/md_processing_utils/md_processing_constants.py +1228 -0
- md_processing/md_processing_utils/message_constants.py +19 -0
- pyegeria/__init__.py +201 -443
- pyegeria/core/__init__.py +40 -0
- pyegeria/core/_base_platform_client.py +574 -0
- pyegeria/core/_base_server_client.py +573 -0
- pyegeria/core/_exceptions.py +457 -0
- pyegeria/core/_globals.py +60 -0
- pyegeria/core/_server_client.py +6073 -0
- pyegeria/core/_validators.py +257 -0
- pyegeria/core/config.py +654 -0
- pyegeria/{create_tech_guid_lists.py → core/create_tech_guid_lists.py} +0 -1
- pyegeria/core/load_config.py +37 -0
- pyegeria/core/logging_configuration.py +207 -0
- pyegeria/core/mcp_adapter.py +144 -0
- pyegeria/core/mcp_server.py +212 -0
- pyegeria/core/utils.py +405 -0
- pyegeria/deprecated/__init__.py +0 -0
- pyegeria/{_client.py → deprecated/_client.py} +62 -24
- pyegeria/{_deprecated_gov_engine.py → deprecated/_deprecated_gov_engine.py} +16 -16
- pyegeria/{classification_manager_omvs.py → deprecated/classification_manager_omvs.py} +1988 -1878
- pyegeria/deprecated/output_formatter_with_machine_keys.py +1127 -0
- pyegeria/{runtime_manager_omvs.py → deprecated/runtime_manager_omvs.py} +216 -229
- pyegeria/{valid_metadata_omvs.py → deprecated/valid_metadata_omvs.py} +93 -93
- pyegeria/{x_action_author_omvs.py → deprecated/x_action_author_omvs.py} +2 -3
- pyegeria/egeria_cat_client.py +25 -51
- pyegeria/egeria_client.py +140 -98
- pyegeria/egeria_config_client.py +48 -24
- pyegeria/egeria_tech_client.py +170 -83
- pyegeria/models/__init__.py +150 -0
- pyegeria/models/collection_models.py +168 -0
- pyegeria/models/models.py +654 -0
- pyegeria/omvs/__init__.py +84 -0
- pyegeria/omvs/action_author.py +342 -0
- pyegeria/omvs/actor_manager.py +5980 -0
- pyegeria/omvs/asset_catalog.py +842 -0
- pyegeria/omvs/asset_maker.py +2736 -0
- pyegeria/omvs/automated_curation.py +4403 -0
- pyegeria/omvs/classification_manager.py +11213 -0
- pyegeria/omvs/collection_manager.py +5780 -0
- pyegeria/omvs/community_matters_omvs.py +468 -0
- pyegeria/{core_omag_server_config.py → omvs/core_omag_server_config.py} +157 -157
- pyegeria/{data_designer_omvs.py → omvs/data_designer.py} +1991 -1691
- pyegeria/omvs/data_discovery.py +869 -0
- pyegeria/omvs/data_engineer.py +372 -0
- pyegeria/omvs/digital_business.py +1133 -0
- pyegeria/omvs/external_links.py +1752 -0
- pyegeria/omvs/feedback_manager.py +834 -0
- pyegeria/{full_omag_server_config.py → omvs/full_omag_server_config.py} +73 -69
- pyegeria/omvs/glossary_manager.py +3231 -0
- pyegeria/omvs/governance_officer.py +3009 -0
- pyegeria/omvs/lineage_linker.py +314 -0
- pyegeria/omvs/location_arena.py +1525 -0
- pyegeria/omvs/metadata_expert.py +668 -0
- pyegeria/omvs/metadata_explorer_omvs.py +2943 -0
- pyegeria/omvs/my_profile.py +1042 -0
- pyegeria/omvs/notification_manager.py +358 -0
- pyegeria/omvs/people_organizer.py +394 -0
- pyegeria/{platform_services.py → omvs/platform_services.py} +113 -193
- pyegeria/omvs/product_manager.py +1825 -0
- pyegeria/omvs/project_manager.py +1907 -0
- pyegeria/omvs/reference_data.py +1140 -0
- pyegeria/omvs/registered_info.py +334 -0
- pyegeria/omvs/runtime_manager.py +2817 -0
- pyegeria/omvs/schema_maker.py +446 -0
- pyegeria/{server_operations.py → omvs/server_operations.py} +27 -26
- pyegeria/omvs/solution_architect.py +6490 -0
- pyegeria/omvs/specification_properties.py +37 -0
- pyegeria/omvs/subject_area.py +1042 -0
- pyegeria/omvs/template_manager_omvs.py +236 -0
- pyegeria/omvs/time_keeper.py +1761 -0
- pyegeria/omvs/valid_metadata.py +3221 -0
- pyegeria/omvs/valid_metadata_lists.py +37 -0
- pyegeria/omvs/valid_type_lists.py +37 -0
- pyegeria/view/__init__.py +28 -0
- pyegeria/view/_output_format_models.py +514 -0
- pyegeria/view/_output_formats.py +14 -0
- pyegeria/view/base_report_formats.py +2719 -0
- pyegeria/view/dr_egeria_reports.py +56 -0
- pyegeria/view/format_set_executor.py +397 -0
- pyegeria/{md_processing_utils.py → view/md_processing_utils.py} +5 -5
- pyegeria/{mermaid_utilities.py → view/mermaid_utilities.py} +2 -154
- pyegeria/view/output_formatter.py +1297 -0
- pyegeria-5.5.3.3.dist-info/METADATA +218 -0
- pyegeria-5.5.3.3.dist-info/RECORD +241 -0
- {pyegeria-5.3.9.9.3.dist-info → pyegeria-5.5.3.3.dist-info}/WHEEL +2 -1
- pyegeria-5.5.3.3.dist-info/entry_points.txt +103 -0
- pyegeria-5.5.3.3.dist-info/top_level.txt +4 -0
- commands/cat/.DS_Store +0 -0
- commands/cat/README.md +0 -16
- commands/cli/txt_custom_v2.tcss +0 -19
- commands/my/README.md +0 -17
- commands/ops/README.md +0 -24
- commands/ops/monitor_asset_events.py +0 -108
- commands/tech/README.md +0 -24
- pyegeria/.DS_Store +0 -0
- pyegeria/README.md +0 -35
- pyegeria/_globals.py +0 -47
- pyegeria/_validators.py +0 -385
- pyegeria/asset_catalog_omvs.py +0 -864
- pyegeria/automated_curation_omvs.py +0 -3765
- pyegeria/collection_manager_omvs.py +0 -2744
- pyegeria/dr.egeria spec.md +0 -9
- pyegeria/egeria_my_client.py +0 -56
- pyegeria/feedback_manager_omvs.py +0 -4573
- pyegeria/glossary_browser_omvs.py +0 -3728
- pyegeria/glossary_manager_omvs.py +0 -2440
- pyegeria/m_test.py +0 -118
- pyegeria/md_processing_helpers.py +0 -58
- pyegeria/md_processing_utils_orig.py +0 -1103
- pyegeria/metadata_explorer_omvs.py +0 -2326
- pyegeria/my_profile_omvs.py +0 -1022
- pyegeria/output_formatter.py +0 -389
- pyegeria/project_manager_omvs.py +0 -1933
- pyegeria/registered_info.py +0 -167
- pyegeria/solution_architect_omvs.py +0 -2156
- pyegeria/template_manager_omvs.py +0 -1414
- pyegeria/utils.py +0 -197
- pyegeria-5.3.9.9.3.dist-info/METADATA +0 -72
- pyegeria-5.3.9.9.3.dist-info/RECORD +0 -143
- pyegeria-5.3.9.9.3.dist-info/entry_points.txt +0 -99
- /pyegeria/{_exceptions.py → deprecated/_exceptions.py} +0 -0
- {pyegeria-5.3.9.9.3.dist-info → pyegeria-5.5.3.3.dist-info/licenses}/LICENSE +0 -0
|
@@ -0,0 +1,1184 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This file contains blueprint/solution-related object_action functions for processing Egeria Markdown
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import sys
|
|
7
|
+
from datetime import datetime
|
|
8
|
+
from typing import Optional
|
|
9
|
+
|
|
10
|
+
from loguru import logger
|
|
11
|
+
from pygments.lexers import blueprint
|
|
12
|
+
from rich import print
|
|
13
|
+
from rich.console import Console
|
|
14
|
+
from rich.markdown import Markdown
|
|
15
|
+
|
|
16
|
+
from md_processing.md_processing_utils.common_md_proc_utils import (parse_upsert_command, parse_view_command)
|
|
17
|
+
from md_processing.md_processing_utils.common_md_utils import update_element_dictionary, set_element_prop_body, \
|
|
18
|
+
set_update_body, set_create_body, add_search_keywords, add_note_in_dr_e
|
|
19
|
+
from md_processing.md_processing_utils.extraction_utils import (extract_command_plus, update_a_command)
|
|
20
|
+
from md_processing.md_processing_utils.md_processing_constants import (load_commands)
|
|
21
|
+
from pyegeria import body_slimmer, EgeriaTech, PyegeriaException, print_basic_exception
|
|
22
|
+
|
|
23
|
+
load_commands('commands.json')
|
|
24
|
+
|
|
25
|
+
console = Console(width=int(200))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@logger.catch
|
|
29
|
+
def sync_chain_related_elements(egeria_client: EgeriaTech, guid:str, in_supply_chain_guids:list, display_name:str,
|
|
30
|
+
merge_update:bool):
|
|
31
|
+
if not merge_update:
|
|
32
|
+
rel_el_list = egeria_client._get_supply_chain_rel_elements(guid)
|
|
33
|
+
if rel_el_list is None:
|
|
34
|
+
logger.warning("Unexpected -> the list was None - assigning empty list")
|
|
35
|
+
rel_el_list = {}
|
|
36
|
+
|
|
37
|
+
as_is_parent_guids = set(rel_el_list.get("parent_guids", []))
|
|
38
|
+
|
|
39
|
+
to_be_parent_guids = set(in_supply_chain_guids) if in_supply_chain_guids is not None else set()
|
|
40
|
+
|
|
41
|
+
logger.trace(
|
|
42
|
+
f"as_is_parent supply chains: {list(as_is_parent_guids)} to_be_parent supply chains: {list(to_be_parent_guids)}")
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
parent_guids_to_remove = as_is_parent_guids - to_be_parent_guids
|
|
46
|
+
logger.trace(f"parent_guids_to_remove: {list(parent_guids_to_remove)}")
|
|
47
|
+
if len(parent_guids_to_remove) > 0:
|
|
48
|
+
for parent_guid in parent_guids_to_remove:
|
|
49
|
+
egeria_client.decompose_info_supply_chains(parent_guid, guid, None)
|
|
50
|
+
msg = f"Removed `{display_name}` from supply chain parent `{parent_guid}`"
|
|
51
|
+
logger.trace(msg)
|
|
52
|
+
|
|
53
|
+
parent_guids_to_add = to_be_parent_guids - as_is_parent_guids
|
|
54
|
+
logger.trace(f"parent supply chains_to_add: {list(parent_guids_to_add)}")
|
|
55
|
+
if len(parent_guids_to_add) > 0:
|
|
56
|
+
for parent_guid in parent_guids_to_add:
|
|
57
|
+
egeria_client.compose_info_supply_chains(parent_guid, guid, None)
|
|
58
|
+
msg = f"Added `{display_name}` to supply chain parent `{parent_guid}`"
|
|
59
|
+
logger.trace(msg)
|
|
60
|
+
|
|
61
|
+
else: # merge - add supply chain to parents
|
|
62
|
+
if in_supply_chain_guids:
|
|
63
|
+
for parent_guid in in_supply_chain_guids:
|
|
64
|
+
egeria_client.compose_info_supply_chains(parent_guid, guid, None)
|
|
65
|
+
msg = f"Added `{display_name}` to supply chain `{parent_guid}`"
|
|
66
|
+
logger.trace(msg)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@logger.catch
|
|
71
|
+
def sync_component_related_elements(egeria_client: EgeriaTech, object_type: str,
|
|
72
|
+
supply_chain_guids: list, parent_component_guids: list,
|
|
73
|
+
actor_guids: list, in_blueprint_guids: list, keywords: list[str], guid: str, qualified_name: str,
|
|
74
|
+
display_name: str, merge_update: bool = True) -> None:
|
|
75
|
+
"""Sync a components related elements.
|
|
76
|
+
|
|
77
|
+
"""
|
|
78
|
+
if not merge_update:
|
|
79
|
+
rel_el_list = egeria_client.get_component_related_elements(guid)
|
|
80
|
+
# should I throw an exception if empty?
|
|
81
|
+
|
|
82
|
+
as_is_actors = set(rel_el_list.get("actor_guids", []))
|
|
83
|
+
as_is_blueprints = set(rel_el_list.get("blueprint_guids", []))
|
|
84
|
+
as_is_parent_components = set(rel_el_list.get("parent_component_guids", []))
|
|
85
|
+
as_is_supply_chains = set(rel_el_list.get("supply_chain_guids", []))
|
|
86
|
+
as_is_keywords_list = set(rel_el_list.get("keywords_list", {}))
|
|
87
|
+
as_is_keywords = set(rel_el_list.get("keywords_list", {}).keys())
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
to_be_actors = set(actor_guids) if actor_guids is not None else set()
|
|
91
|
+
to_be_blueprints = set(in_blueprint_guids) if in_blueprint_guids is not None else set()
|
|
92
|
+
to_be_parent_components = set(parent_component_guids) if parent_component_guids is not None else set()
|
|
93
|
+
to_be_supply_chains = set(supply_chain_guids) if supply_chain_guids is not None else set()
|
|
94
|
+
to_be_keywords_list = set(keywords) if keywords is not None else set()
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
logger.trace(
|
|
98
|
+
f"as_is_sub_components: {list(as_is_parent_components)} to_be_sub_components: {list(to_be_parent_components)}")
|
|
99
|
+
logger.trace(f"as_is_actors: {list(as_is_actors)} to_be_actors: {list(to_be_actors)}")
|
|
100
|
+
logger.trace(f"as_is_blueprints: {list(as_is_blueprints)} to_be_blueprints: {list(to_be_blueprints)}")
|
|
101
|
+
|
|
102
|
+
keywords_to_add = to_be_keywords_list - as_is_keywords
|
|
103
|
+
logger.trace(f"keywords_to_add: {list(keywords_to_add)}")
|
|
104
|
+
if len(keywords_to_add) > 0:
|
|
105
|
+
for ds in keywords_to_add:
|
|
106
|
+
egeria_client.add_search_keyword_to_element(guid, ds)
|
|
107
|
+
msg = f"Added `{ds}` to component `{guid}`"
|
|
108
|
+
logger.trace(msg)
|
|
109
|
+
|
|
110
|
+
keywords_to_remove = as_is_keywords_list - to_be_keywords_list
|
|
111
|
+
logger.trace(f"keyword_to_remove: {list(keywords_to_remove)}")
|
|
112
|
+
if len(keywords_to_remove) > 0:
|
|
113
|
+
for ds in keywords_to_remove: ## change structure of get related elements to return pairs of keywords and guids
|
|
114
|
+
egeria_client.remove_search_keyword(rel_el_list['keywords_list'][ds])
|
|
115
|
+
msg = f"Removed `{ds}` from component `{guid}`"
|
|
116
|
+
logger.trace(msg)
|
|
117
|
+
|
|
118
|
+
parent_components_to_remove = as_is_parent_components - to_be_parent_components
|
|
119
|
+
logger.trace(f"sub_components_to_remove: {list(parent_components_to_remove)}")
|
|
120
|
+
if len(parent_components_to_remove) > 0:
|
|
121
|
+
for ds in parent_components_to_remove:
|
|
122
|
+
egeria_client.detach_sub_component(ds, guid, None)
|
|
123
|
+
msg = f"Removed `{display_name}` from component `{ds}`"
|
|
124
|
+
logger.trace(msg)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
parent_components_to_add = to_be_parent_components - as_is_parent_components
|
|
129
|
+
logger.trace(f"parent_components_to_add: {list(parent_components_to_add)}")
|
|
130
|
+
if len(parent_components_to_add) > 0:
|
|
131
|
+
for ds in parent_components_to_add:
|
|
132
|
+
egeria_client.link_subcomponent(ds, guid, None)
|
|
133
|
+
msg = f"Added `{display_name}` to component `{ds}`"
|
|
134
|
+
logger.trace(msg)
|
|
135
|
+
|
|
136
|
+
blueprints_to_remove = as_is_blueprints - to_be_blueprints
|
|
137
|
+
logger.trace(f"blueprints_to_remove: {list(blueprints_to_remove)}")
|
|
138
|
+
if len(blueprints_to_remove) > 0:
|
|
139
|
+
for bp in blueprints_to_remove:
|
|
140
|
+
egeria_client.detach_solution_component_from_blueprint(bp, guid, None)
|
|
141
|
+
msg = f"Removed `{display_name}` from blueprintt `{bp}`"
|
|
142
|
+
logger.trace(msg)
|
|
143
|
+
|
|
144
|
+
blueprints_to_add = to_be_blueprints - as_is_blueprints
|
|
145
|
+
logger.trace(f"blueprints_to_add: {list(blueprints_to_add)}")
|
|
146
|
+
if len(blueprints_to_add) > 0:
|
|
147
|
+
for bp in blueprints_to_add:
|
|
148
|
+
egeria_client.link_solution_component_to_blueprint(bp, guid, None)
|
|
149
|
+
msg = f"Added `{display_name}` to component `{bp}`"
|
|
150
|
+
logger.trace(msg)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
actors_to_remove = to_be_actors - as_is_actors
|
|
155
|
+
logger.trace(f"actors_to_remove: {list(actors_to_remove)}")
|
|
156
|
+
if len(actors_to_remove) > 0:
|
|
157
|
+
for actor in actors_to_remove:
|
|
158
|
+
egeria_client.detach_component_actore(actor, guid, None)
|
|
159
|
+
msg = f"Removed actor `{actor}` from component `{display_name}`"
|
|
160
|
+
logger.trace(msg)
|
|
161
|
+
|
|
162
|
+
actors_to_add = to_be_actors - as_is_actors
|
|
163
|
+
logger.trace(f"actors_to_add: {list(actors_to_add)}")
|
|
164
|
+
if len(actors_to_add) > 0:
|
|
165
|
+
for actor in actors_to_add:
|
|
166
|
+
egeria_client.link_component_to_actor(actor, guid, None)
|
|
167
|
+
msg = f"Added `{display_name}` to role `{actor}`"
|
|
168
|
+
logger.trace(msg)
|
|
169
|
+
|
|
170
|
+
supply_chains_to_remove = as_is_supply_chains - to_be_supply_chains
|
|
171
|
+
logger.trace(f"supply_chains_to_remove: {list(supply_chains_to_remove)}")
|
|
172
|
+
if len(supply_chains_to_remove) > 0:
|
|
173
|
+
for isc in supply_chains_to_remove:
|
|
174
|
+
egeria_client.detach_design_from_implementation(isc, guid)
|
|
175
|
+
msg = f"Removed `{isc}` from `{display_name}`"
|
|
176
|
+
logger.trace(msg)
|
|
177
|
+
supply_chains_to_add = to_be_supply_chains - as_is_supply_chains
|
|
178
|
+
logger.trace(f"supply_chains_to_add: {list(supply_chains_to_add)}")
|
|
179
|
+
if len(supply_chains_to_add) > 0:
|
|
180
|
+
body = {
|
|
181
|
+
"class": "NewRelationshipRequestBody",
|
|
182
|
+
"properties": {
|
|
183
|
+
"class": "ImplementedByProperties",
|
|
184
|
+
"description": "a blank description to satisfy the Egeria gods"
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
for isc in supply_chains_to_add:
|
|
188
|
+
egeria_client.link_design_to_implementation(isc, guid, body)
|
|
189
|
+
msg = f"Added `{isc}` to`{display_name}`"
|
|
190
|
+
logger.trace(msg)
|
|
191
|
+
logger.info(f"Replaced the related elements in `{display_name}`")
|
|
192
|
+
|
|
193
|
+
else: # merge - add field to related elements
|
|
194
|
+
if parent_component_guids:
|
|
195
|
+
for comp in parent_component_guids:
|
|
196
|
+
egeria_client.link_subcomponent(guid, comp, None)
|
|
197
|
+
msg = f"Added `{parent_component_guids}` to `{display_name}`"
|
|
198
|
+
logger.trace(msg)
|
|
199
|
+
|
|
200
|
+
if actor_guids:
|
|
201
|
+
for actor in actor_guids:
|
|
202
|
+
egeria_client.link_component_to_actor(actor, guid, None)
|
|
203
|
+
msg = f"Added `{actor_guids}` to `{display_name}`"
|
|
204
|
+
logger.trace(msg)
|
|
205
|
+
|
|
206
|
+
if in_blueprint_guids:
|
|
207
|
+
for bp in in_blueprint_guids:
|
|
208
|
+
egeria_client.link_solution_component_to_blueprint(bp, guid, None)
|
|
209
|
+
msg = f"Added `{in_blueprint_guids}` to `{display_name}`"
|
|
210
|
+
logger.trace(msg)
|
|
211
|
+
|
|
212
|
+
if keywords:
|
|
213
|
+
add_search_keywords(egeria_client, guid, keywords)
|
|
214
|
+
|
|
215
|
+
if supply_chain_guids:
|
|
216
|
+
body = {
|
|
217
|
+
"class": "NewRelationshipRequestBody",
|
|
218
|
+
"properties": {
|
|
219
|
+
"class": "ImplementedByProperties",
|
|
220
|
+
"description": "a blank description to satisfy the Egeria gods"
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
for isc in supply_chain_guids:
|
|
224
|
+
egeria_client.link_design_to_implementation(isc, guid, body)
|
|
225
|
+
msg = f"Added `{display_name}` to `{isc}`"
|
|
226
|
+
logger.trace(msg)
|
|
227
|
+
|
|
228
|
+
logger.info(f"Merged related elements in `{display_name}`")
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def sync_blueprint_related_elements(egeria_client: EgeriaTech, object_type: str, component_guids: list, guid: str,
|
|
232
|
+
qualified_name: str, display_name: str, replace_all_props: bool = True) -> None:
|
|
233
|
+
"""Sync a blueprints related elements.
|
|
234
|
+
|
|
235
|
+
"""
|
|
236
|
+
if replace_all_props:
|
|
237
|
+
bp_element = egeria_client.get_solution_blueprint_by_guid(guid)
|
|
238
|
+
solution_components = bp_element['solutionComponents']
|
|
239
|
+
as_is_components = {}
|
|
240
|
+
if len(solution_components) > 0:
|
|
241
|
+
for component in solution_components:
|
|
242
|
+
as_is_components.append(component['elementHeader']['guid'])
|
|
243
|
+
|
|
244
|
+
# should I throw an exception if empty?
|
|
245
|
+
|
|
246
|
+
to_be_components = set(component_guids) if component_guids is not None else set()
|
|
247
|
+
|
|
248
|
+
logger.trace(f"as_is_components: {list(as_is_components)} to_be_sub_components: {list(to_be_components)}")
|
|
249
|
+
|
|
250
|
+
components_to_remove = as_is_components - to_be_components
|
|
251
|
+
logger.trace(f"components_to_remove: {list(components_to_remove)}")
|
|
252
|
+
if len(components_to_remove) > 0:
|
|
253
|
+
for ds in components_to_remove:
|
|
254
|
+
egeria_client.detach_solution_component_from_blueprint(guid, ds, None)
|
|
255
|
+
msg = f"Removed `{ds}` from component `{display_name}`"
|
|
256
|
+
logger.trace(msg)
|
|
257
|
+
components_to_add = to_be_components - as_is_components
|
|
258
|
+
logger.trace(f"sub_components_to_add: {list(components_to_add)}")
|
|
259
|
+
if len(components_to_add) > 0:
|
|
260
|
+
for ds in components_to_add:
|
|
261
|
+
egeria_client.link_solution_component_to_blueprint(guid, ds, None)
|
|
262
|
+
msg = f"Added `{ds}` to component `{display_name}`"
|
|
263
|
+
logger.trace(msg)
|
|
264
|
+
|
|
265
|
+
logger.info(f"Replaced the related elements in `{display_name}`")
|
|
266
|
+
|
|
267
|
+
else: # merge - add field to related elements
|
|
268
|
+
if component_guids:
|
|
269
|
+
for comp in component_guids:
|
|
270
|
+
egeria_client.link_solution_component_to_blueprint(guid, comp, None)
|
|
271
|
+
msg = f"Added `{component_guids}` to `{display_name}`"
|
|
272
|
+
logger.trace(msg)
|
|
273
|
+
|
|
274
|
+
logger.info(f"Merged related elements in `{display_name}`")
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
@logger.catch
|
|
278
|
+
def process_blueprint_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
|
|
279
|
+
"""
|
|
280
|
+
Processes a solution blueprint create or update object_action by extracting key attributes such as
|
|
281
|
+
blueprint name, description, and usage from the given text.
|
|
282
|
+
|
|
283
|
+
:param txt: A string representing the input cell to be processed for
|
|
284
|
+
extracting blueprint-related attributes.
|
|
285
|
+
:param directive: an optional string indicating the directive to be used - display, validate or execute
|
|
286
|
+
:return: A string summarizing the outcome of the processing.
|
|
287
|
+
"""
|
|
288
|
+
command, object_type, object_action = extract_command_plus(txt)
|
|
289
|
+
print(Markdown(f"# {command}\n"))
|
|
290
|
+
parsed_output = parse_upsert_command(egeria_client, object_type, object_action, txt, directive)
|
|
291
|
+
|
|
292
|
+
valid = parsed_output['valid']
|
|
293
|
+
exists = parsed_output['exists']
|
|
294
|
+
|
|
295
|
+
qualified_name = parsed_output.get('qualified_name', None)
|
|
296
|
+
guid = parsed_output.get('guid', None)
|
|
297
|
+
journal_entry = parsed_output.get('Journey Entry', {}.get('value', None))
|
|
298
|
+
print(Markdown(parsed_output['display']))
|
|
299
|
+
|
|
300
|
+
logger.debug(json.dumps(parsed_output, indent=4))
|
|
301
|
+
|
|
302
|
+
attributes = parsed_output['attributes']
|
|
303
|
+
description = attributes.get('Description', {}).get('value', None)
|
|
304
|
+
display_name = attributes['Display Name'].get('value', None)
|
|
305
|
+
search_keywords = attributes['Search Keywords'].get('value', None)
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
component_guids = attributes.get('Solution Components', {}).get('guid_list', None)
|
|
310
|
+
|
|
311
|
+
status = attributes.get('Status', {}).get('value', None)
|
|
312
|
+
if status is None:
|
|
313
|
+
status = "ACTIVE"
|
|
314
|
+
|
|
315
|
+
replace_all_props = not attributes.get('Merge Update', {}).get('value', True)
|
|
316
|
+
|
|
317
|
+
if directive == "display":
|
|
318
|
+
|
|
319
|
+
return None
|
|
320
|
+
elif directive == "validate":
|
|
321
|
+
if valid:
|
|
322
|
+
print(Markdown(f"==> Validation of {command} completed successfully!\n"))
|
|
323
|
+
else:
|
|
324
|
+
msg = f"Validation failed for object_action `{command}`\n"
|
|
325
|
+
return valid
|
|
326
|
+
|
|
327
|
+
elif directive == "process":
|
|
328
|
+
prop_body = set_element_prop_body(object_type, qualified_name, attributes)
|
|
329
|
+
|
|
330
|
+
try:
|
|
331
|
+
if object_action == "Update":
|
|
332
|
+
if not exists:
|
|
333
|
+
msg = (f" Element `{display_name}` does not exist! Updating result document with Create "
|
|
334
|
+
f"object_action\n")
|
|
335
|
+
logger.error(msg)
|
|
336
|
+
print(Markdown(msg))
|
|
337
|
+
return update_a_command(txt, object_action, object_type, qualified_name, guid)
|
|
338
|
+
elif not valid:
|
|
339
|
+
return None
|
|
340
|
+
else:
|
|
341
|
+
print(Markdown(
|
|
342
|
+
f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
|
|
343
|
+
|
|
344
|
+
body = set_update_body(object_type, attributes)
|
|
345
|
+
body['properties'] = prop_body
|
|
346
|
+
egeria_client.update_solution_blueprint(guid, body)
|
|
347
|
+
if status:
|
|
348
|
+
egeria_client.update_solution_element_status(guid, status)
|
|
349
|
+
|
|
350
|
+
msg = f"Updated {object_type} `{display_name}` with GUID {guid}\n\n___"
|
|
351
|
+
update_element_dictionary(qualified_name, {
|
|
352
|
+
'guid': guid, 'display_name': display_name
|
|
353
|
+
})
|
|
354
|
+
logger.success(msg)
|
|
355
|
+
sync_blueprint_related_elements(egeria_client, object_type, component_guids, guid, qualified_name,
|
|
356
|
+
display_name, replace_all_props)
|
|
357
|
+
|
|
358
|
+
journal_entry_guid = add_note_in_dr_e(egeria_client, qualified_name, display_name, journal_entry)
|
|
359
|
+
logger.success(f"===> Updated {object_type} `{display_name}` related elements\n\n")
|
|
360
|
+
return egeria_client.get_solution_blueprints_by_name(qualified_name, output_format='MD', report_spec = "Solution-Blueprint-DrE")
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
elif object_action == "Create":
|
|
364
|
+
print(f"valid: {valid}, type: {type(valid)}")
|
|
365
|
+
try:
|
|
366
|
+
if valid is False and exists:
|
|
367
|
+
msg = (f" Data Specification `{display_name}` already exists and result document updated changing "
|
|
368
|
+
f"`Create` to `Update` in processed output\n\n___")
|
|
369
|
+
logger.error(msg)
|
|
370
|
+
print(Markdown(msg))
|
|
371
|
+
return update_a_command(txt, object_action, object_type, qualified_name, guid)
|
|
372
|
+
|
|
373
|
+
elif not valid:
|
|
374
|
+
msg = (f"==>{object_type} `{display_name}` is not valid and can't be created")
|
|
375
|
+
print(Markdown(msg))
|
|
376
|
+
logger.error(msg)
|
|
377
|
+
return
|
|
378
|
+
|
|
379
|
+
else:
|
|
380
|
+
body = set_create_body(object_type,attributes)
|
|
381
|
+
body['properties'] = prop_body
|
|
382
|
+
guid = egeria_client.create_solution_blueprint(body)
|
|
383
|
+
except Exception as e:
|
|
384
|
+
print(f"Unexpected error: {e}, {type(valid)}, {valid}")
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
if guid:
|
|
388
|
+
update_element_dictionary(qualified_name, {
|
|
389
|
+
'guid': guid, 'display_name': display_name
|
|
390
|
+
})
|
|
391
|
+
journal_entry_guid = add_note_in_dr_e(egeria_client, qualified_name, display_name, journal_entry)
|
|
392
|
+
msg = f"\n\nCreated Element `{display_name}` with GUID {guid}\n\n___"
|
|
393
|
+
print(Markdown(msg))
|
|
394
|
+
logger.success(msg)
|
|
395
|
+
return egeria_client.get_solution_blueprint_by_guid(guid, output_format='MD', report_spec = "Solution-Blueprint-DrE")
|
|
396
|
+
else:
|
|
397
|
+
msg = f"Failed to create element `{display_name}` with GUID {guid}\n\n___"
|
|
398
|
+
print(Markdown(msg))
|
|
399
|
+
logger.error(msg)
|
|
400
|
+
return None
|
|
401
|
+
|
|
402
|
+
except PyegeriaException as e:
|
|
403
|
+
print_basic_exception(e)
|
|
404
|
+
logger.error(f"Error performing {command}: {e}")
|
|
405
|
+
return None
|
|
406
|
+
else:
|
|
407
|
+
return None
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
# TODO - I think this comes after (or part of) doing the Actors
|
|
411
|
+
@logger.catch
|
|
412
|
+
def process_solution_roles_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
|
|
413
|
+
"""
|
|
414
|
+
Processes a solution role create or update object_action by extracting key attributes such as from the given text.
|
|
415
|
+
|
|
416
|
+
:param txt: A string representing the input cell to be processed for
|
|
417
|
+
extracting blueprint-related attributes.
|
|
418
|
+
:param directive: an optional string indicating the directive to be used - display, validate or execute
|
|
419
|
+
:return: A string summarizing the outcome of the processing.
|
|
420
|
+
"""
|
|
421
|
+
command, object_type, object_action = extract_command_plus(txt)
|
|
422
|
+
print(Markdown(f"# {command}\n"))
|
|
423
|
+
parsed_output = parse_upsert_command(egeria_client, object_type, object_action, txt, directive)
|
|
424
|
+
|
|
425
|
+
valid = parsed_output['valid']
|
|
426
|
+
exists = parsed_output['exists']
|
|
427
|
+
|
|
428
|
+
qualified_name = parsed_output.get('qualified_name', None)
|
|
429
|
+
guid = parsed_output.get('guid', None)
|
|
430
|
+
journal_entry = parsed_output.get('Journey Entry', {}.get('value', None))
|
|
431
|
+
print(Markdown(parsed_output['display']))
|
|
432
|
+
|
|
433
|
+
logger.debug(json.dumps(parsed_output, indent=4))
|
|
434
|
+
|
|
435
|
+
attributes = parsed_output['attributes']
|
|
436
|
+
description = attributes.get('Description', {}).get('value', None)
|
|
437
|
+
display_name = attributes['Display Name'].get('value', None)
|
|
438
|
+
search_keywords = attributes['Search Keywords'].get('value', None)
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
component_guids = attributes.get('Solution Components', {}).get('guid_list', None)
|
|
443
|
+
|
|
444
|
+
status = attributes.get('Status', {}).get('value', None)
|
|
445
|
+
if status is None:
|
|
446
|
+
status = "ACTIVE"
|
|
447
|
+
|
|
448
|
+
replace_all_props = not attributes.get('Merge Update', {}).get('value', True)
|
|
449
|
+
|
|
450
|
+
if directive == "display":
|
|
451
|
+
|
|
452
|
+
return None
|
|
453
|
+
elif directive == "validate":
|
|
454
|
+
if valid:
|
|
455
|
+
print(Markdown(f"==> Validation of {command} completed successfully!\n"))
|
|
456
|
+
else:
|
|
457
|
+
msg = f"Validation failed for object_action `{command}`\n"
|
|
458
|
+
return valid
|
|
459
|
+
|
|
460
|
+
elif directive == "process":
|
|
461
|
+
prop_body = set_element_prop_body(object_type, qualified_name, attributes)
|
|
462
|
+
|
|
463
|
+
try:
|
|
464
|
+
if object_action == "Update":
|
|
465
|
+
if not exists:
|
|
466
|
+
msg = (f" Element `{display_name}` does not exist! Updating result document with Create "
|
|
467
|
+
f"object_action\n")
|
|
468
|
+
logger.error(msg)
|
|
469
|
+
print(Markdown(msg))
|
|
470
|
+
return update_a_command(txt, object_action, object_type, qualified_name, guid)
|
|
471
|
+
elif not valid:
|
|
472
|
+
return None
|
|
473
|
+
else:
|
|
474
|
+
print(Markdown(
|
|
475
|
+
f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
|
|
476
|
+
|
|
477
|
+
body = set_update_body(object_type, attributes)
|
|
478
|
+
body['properties'] = prop_body
|
|
479
|
+
egeria_client.update_solution_blueprint(guid, body)
|
|
480
|
+
if status:
|
|
481
|
+
egeria_client.update_solution_element_status(guid, status)
|
|
482
|
+
|
|
483
|
+
msg = f"Updated {object_type} `{display_name}` with GUID {guid}\n\n___"
|
|
484
|
+
update_element_dictionary(qualified_name, {
|
|
485
|
+
'guid': guid, 'display_name': display_name
|
|
486
|
+
})
|
|
487
|
+
logger.success(msg)
|
|
488
|
+
sync_blueprint_related_elements(egeria_client, object_type, component_guids, guid, qualified_name,
|
|
489
|
+
display_name, replace_all_props)
|
|
490
|
+
|
|
491
|
+
journal_entry_guid = add_note_in_dr_e(egeria_client, qualified_name, display_name, journal_entry)
|
|
492
|
+
logger.success(f"===> Updated {object_type} `{display_name}` related elements\n\n")
|
|
493
|
+
return egeria_client.get_solution_blueprints_by_name(qualified_name, output_format='MD', report_spec = "Solution-Blueprint-DrE")
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
elif object_action == "Create":
|
|
497
|
+
print(f"valid: {valid}, type: {type(valid)}")
|
|
498
|
+
try:
|
|
499
|
+
if valid is False and exists:
|
|
500
|
+
msg = (f" Data Specification `{display_name}` already exists and result document updated changing "
|
|
501
|
+
f"`Create` to `Update` in processed output\n\n___")
|
|
502
|
+
logger.error(msg)
|
|
503
|
+
print(Markdown(msg))
|
|
504
|
+
return update_a_command(txt, object_action, object_type, qualified_name, guid)
|
|
505
|
+
|
|
506
|
+
elif not valid:
|
|
507
|
+
msg = (f"==>{object_type} `{display_name}` is not valid and can't be created")
|
|
508
|
+
print(Markdown(msg))
|
|
509
|
+
logger.error(msg)
|
|
510
|
+
return
|
|
511
|
+
|
|
512
|
+
else:
|
|
513
|
+
body = set_create_body(object_type,attributes)
|
|
514
|
+
body['properties'] = prop_body
|
|
515
|
+
guid = egeria_client.create_solution_blueprint(body)
|
|
516
|
+
except Exception as e:
|
|
517
|
+
print(f"Unexpected error: {e}, {type(valid)}, {valid}")
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
if guid:
|
|
521
|
+
update_element_dictionary(qualified_name, {
|
|
522
|
+
'guid': guid, 'display_name': display_name
|
|
523
|
+
})
|
|
524
|
+
journal_entry_guid = add_note_in_dr_e(egeria_client, qualified_name, display_name, journal_entry)
|
|
525
|
+
msg = f"\n\nCreated Element `{display_name}` with GUID {guid}\n\n___"
|
|
526
|
+
print(Markdown(msg))
|
|
527
|
+
logger.success(msg)
|
|
528
|
+
return egeria_client.get_solution_blueprint_by_guid(guid, output_format='MD', report_spec = "Solution-Blueprint-DrE")
|
|
529
|
+
else:
|
|
530
|
+
msg = f"Failed to create element `{display_name}` with GUID {guid}\n\n___"
|
|
531
|
+
print(Markdown(msg))
|
|
532
|
+
logger.error(msg)
|
|
533
|
+
return None
|
|
534
|
+
|
|
535
|
+
except PyegeriaException as e:
|
|
536
|
+
print_basic_exception(e)
|
|
537
|
+
logger.error(f"Error performing {command}: {e}")
|
|
538
|
+
return None
|
|
539
|
+
else:
|
|
540
|
+
return None
|
|
541
|
+
|
|
542
|
+
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
@logger.catch
|
|
546
|
+
def process_solution_component_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> \
|
|
547
|
+
Optional[str]:
|
|
548
|
+
"""
|
|
549
|
+
Processes a solution component create or update object_action by extracting key attributes such as
|
|
550
|
+
component name, description, and parent components from the given text.
|
|
551
|
+
|
|
552
|
+
:param txt: A string representing the input cell to be processed for
|
|
553
|
+
extracting component-related attributes.
|
|
554
|
+
:param directive: an optional string indicating the directive to be used - display, validate or execute
|
|
555
|
+
:return: A string summarizing the outcome of the processing.
|
|
556
|
+
"""
|
|
557
|
+
command, object_type, object_action = extract_command_plus(txt)
|
|
558
|
+
print(Markdown(f"# {command}\n"))
|
|
559
|
+
|
|
560
|
+
parsed_output = parse_upsert_command(egeria_client, object_type, object_action, txt, directive)
|
|
561
|
+
|
|
562
|
+
valid = parsed_output['valid']
|
|
563
|
+
exists = parsed_output['exists']
|
|
564
|
+
|
|
565
|
+
qualified_name = parsed_output.get('qualified_name', None)
|
|
566
|
+
guid = parsed_output.get('guid', None)
|
|
567
|
+
|
|
568
|
+
print(Markdown(parsed_output['display']))
|
|
569
|
+
|
|
570
|
+
logger.debug(json.dumps(parsed_output, indent=4))
|
|
571
|
+
|
|
572
|
+
attributes = parsed_output['attributes']
|
|
573
|
+
|
|
574
|
+
description = attributes.get('Description', {}).get('value', None)
|
|
575
|
+
display_name = attributes['Display Name'].get('value', None)
|
|
576
|
+
version_identifier = attributes.get('Version Identifier', {}).get('value', None)
|
|
577
|
+
solution_component_type = attributes.get('Solution Component Type', {}).get('value', None)
|
|
578
|
+
planned_deployed_impl_type = attributes.get('Planned Deployed Implementation Type', {}).get('value', None)
|
|
579
|
+
initial_status = attributes.get('Status', {}).get('value', None)
|
|
580
|
+
url = attributes.get('URL', {}).get('value', None)
|
|
581
|
+
search_keywords = attributes.get('Search Keywords', {}).get('value', None)
|
|
582
|
+
journal_entry = attributes.get('Journal Entry', {}).get('value', None)
|
|
583
|
+
user_defined_status = attributes.get('User Defined Status', {}).get('value', None)
|
|
584
|
+
if initial_status != "OTHER":
|
|
585
|
+
user_defined_status = None
|
|
586
|
+
|
|
587
|
+
# sub_component_names = attributes.get('Solution SubComponents', {}).get('name_list', None)
|
|
588
|
+
# sub_component_guids = attributes.get('Solution SubComponents', {}).get('guid_list', None)
|
|
589
|
+
actor_names = attributes.get('Actors', {}).get('name_list', None)
|
|
590
|
+
actor_guids = attributes.get('Actors', {}).get('guid_list', None)
|
|
591
|
+
in_blueprint_names = attributes.get('In Solution Blueprints', {}).get('name_list', None)
|
|
592
|
+
in_blueprint_guids = attributes.get('In Solution Blueprints', {}).get('guid_list', None)
|
|
593
|
+
in_supply_chain_names = attributes.get('In Information Supply Chains', {}).get('name_list', None)
|
|
594
|
+
in_supply_chain_guids = attributes.get('In Information Supply Chains', {}).get('guid_list', None)
|
|
595
|
+
in_component_names = attributes.get('In Solution Components', {}).get('name_list', None)
|
|
596
|
+
in_component_guids = attributes.get('In Solution Components', {}).get('guid_list', None)
|
|
597
|
+
parent_component_guids = attributes.get('Parent Components', {}).get('guid_list', None)
|
|
598
|
+
parent_component_names = attributes.get('Parent Components', {}).get('name_list', None)
|
|
599
|
+
|
|
600
|
+
effective_time = attributes.get('Effective Time', {}).get('value', None)
|
|
601
|
+
effective_from = attributes.get('Effective From', {}).get('value', None)
|
|
602
|
+
effective_to = attributes.get('Effective To', {}).get('value', None)
|
|
603
|
+
external_source_guid = attributes.get('External Source GUID', {}).get('value', None)
|
|
604
|
+
external_source_name = attributes.get('External Source Name', {}).get('value', None)
|
|
605
|
+
|
|
606
|
+
anchor_guid = attributes.get('Anchor ID', {}).get('guid', None)
|
|
607
|
+
parent_guid = attributes.get('Parent ID', {}).get('guid', None)
|
|
608
|
+
parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value', None)
|
|
609
|
+
parent_relationship_properties = attributes.get('Parent Relationship Properties', {}).get('value', None)
|
|
610
|
+
parent_at_end1 = attributes.get('Parent at End1', {}).get('value', True)
|
|
611
|
+
|
|
612
|
+
anchor_scope_guid = attributes.get('Anchor Scope GUID', {}).get('value', None)
|
|
613
|
+
is_own_anchor = attributes.get('Is Own Anchor', {}).get('value', True)
|
|
614
|
+
if parent_guid is None:
|
|
615
|
+
is_own_anchor = True
|
|
616
|
+
|
|
617
|
+
additional_prop = attributes.get('Additional Properties', {}).get('value', None)
|
|
618
|
+
additional_properties = json.loads(additional_prop) if additional_prop is not None else None
|
|
619
|
+
extended_prop = attributes.get('Extended Properties', {}).get('value', None)
|
|
620
|
+
extended_properties = json.loads(extended_prop) if extended_prop is not None else None
|
|
621
|
+
|
|
622
|
+
merge_update = attributes.get('Merge Update', {}).get('value', True)
|
|
623
|
+
|
|
624
|
+
|
|
625
|
+
|
|
626
|
+
if directive == "display":
|
|
627
|
+
|
|
628
|
+
return None
|
|
629
|
+
elif directive == "validate":
|
|
630
|
+
if valid:
|
|
631
|
+
print(Markdown(f"==> Validation of {command} completed successfully!\n"))
|
|
632
|
+
else:
|
|
633
|
+
msg = f"Validation failed for object_action `{command}`\n"
|
|
634
|
+
return valid
|
|
635
|
+
|
|
636
|
+
elif directive == "process":
|
|
637
|
+
try:
|
|
638
|
+
if object_action == "Update":
|
|
639
|
+
if not exists:
|
|
640
|
+
msg = (f"==> Element `{display_name}` does not exist! Updating result document with Create."
|
|
641
|
+
f"object_action\n")
|
|
642
|
+
logger.error(msg)
|
|
643
|
+
return update_a_command(txt, object_action, object_type, qualified_name, guid)
|
|
644
|
+
elif not valid:
|
|
645
|
+
logger.error(f"==> Element `{display_name}` entry is not valid. Please refer to the errors above.")
|
|
646
|
+
return None
|
|
647
|
+
else:
|
|
648
|
+
print(Markdown(
|
|
649
|
+
f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
|
|
650
|
+
|
|
651
|
+
body = body_slimmer({
|
|
652
|
+
"class": "UpdateElementRequestBody",
|
|
653
|
+
"externalSourceGUID": external_source_guid,
|
|
654
|
+
"externalSourceName": external_source_name,
|
|
655
|
+
"effectiveTime": effective_time,
|
|
656
|
+
"mergeUpdate": merge_update,
|
|
657
|
+
"forLineage": False,
|
|
658
|
+
"forDuplicateProcessing": False,
|
|
659
|
+
"properties": {
|
|
660
|
+
"class": "SolutionComponentProperties",
|
|
661
|
+
"qualifiedName": qualified_name,
|
|
662
|
+
"displayName": display_name,
|
|
663
|
+
"description": description,
|
|
664
|
+
"solutionComponentType": solution_component_type,
|
|
665
|
+
"plannedDeployedImplementationType": planned_deployed_impl_type,
|
|
666
|
+
"additionalProperties": additional_properties,
|
|
667
|
+
"extendedProperties": extended_properties,
|
|
668
|
+
"effectiveFrom": effective_from,
|
|
669
|
+
"effectiveTo": effective_to,
|
|
670
|
+
"URL": url
|
|
671
|
+
}
|
|
672
|
+
})
|
|
673
|
+
|
|
674
|
+
egeria_client.update_solution_component(guid, body)
|
|
675
|
+
msg = f"\n==>Updated {object_type} `{display_name}` with GUID {guid}\n"
|
|
676
|
+
logger.success(msg)
|
|
677
|
+
print(Markdown(msg))
|
|
678
|
+
update_element_dictionary(qualified_name, {
|
|
679
|
+
'guid': guid, 'display_name': display_name
|
|
680
|
+
})
|
|
681
|
+
# Sync Parent Components and Blueprints
|
|
682
|
+
sync_component_related_elements(egeria_client, object_type ,
|
|
683
|
+
in_supply_chain_guids,parent_component_guids,actor_guids,
|
|
684
|
+
in_blueprint_guids, search_keywords, guid, qualified_name,
|
|
685
|
+
display_name,
|
|
686
|
+
merge_update)
|
|
687
|
+
|
|
688
|
+
if journal_entry:
|
|
689
|
+
journal_entry_guid = add_note_in_dr_e(egeria_client, qualified_name, display_name, journal_entry)
|
|
690
|
+
return egeria_client.get_solution_component_by_guid(guid, output_format='MD', report_spec = "Solution-Component-DrE")
|
|
691
|
+
|
|
692
|
+
|
|
693
|
+
elif object_action == "Create":
|
|
694
|
+
if valid is False and exists:
|
|
695
|
+
msg = (f" {object_type} `{display_name}` already exists and result document updated changing "
|
|
696
|
+
f"`Create` to `Update` in processed output\n\n___")
|
|
697
|
+
logger.error(msg)
|
|
698
|
+
return update_a_command(txt, object_action, object_type, qualified_name, guid)
|
|
699
|
+
|
|
700
|
+
elif not valid:
|
|
701
|
+
msg = (f"==>{object_type} `{display_name}` is not valid and can't be created")
|
|
702
|
+
logger.error(msg)
|
|
703
|
+
return
|
|
704
|
+
|
|
705
|
+
else:
|
|
706
|
+
body = body_slimmer({
|
|
707
|
+
"class": "NewElementRequestBody",
|
|
708
|
+
"anchorGUID": anchor_guid,
|
|
709
|
+
"isOwnAnchor": is_own_anchor,
|
|
710
|
+
"parentGUID": parent_guid,
|
|
711
|
+
"parentRelationshipTypeName": parent_relationship_type_name,
|
|
712
|
+
"parentRelationshipProperties": parent_relationship_properties,
|
|
713
|
+
"parentAtEnd1": parent_at_end1,
|
|
714
|
+
"properties": {
|
|
715
|
+
"class": "SolutionComponentProperties",
|
|
716
|
+
"qualifiedName": qualified_name,
|
|
717
|
+
"displayName": display_name,
|
|
718
|
+
"description": description,
|
|
719
|
+
"solutionComponentType": solution_component_type,
|
|
720
|
+
"versionIdentifier" : version_identifier,
|
|
721
|
+
"plannedDeployedImplementationType": planned_deployed_impl_type,
|
|
722
|
+
"userDefinedStatus" : user_defined_status,
|
|
723
|
+
"additionalProperties": additional_properties,
|
|
724
|
+
"extendedProperties": extended_properties,
|
|
725
|
+
"effectiveFrom": effective_from,
|
|
726
|
+
"effectiveTo": effective_to,
|
|
727
|
+
"URL": url
|
|
728
|
+
},
|
|
729
|
+
"initialStatus": initial_status,
|
|
730
|
+
"externalSourceGUID": external_source_guid,
|
|
731
|
+
"externalSourceName": external_source_name,
|
|
732
|
+
"effectiveTime": effective_time,
|
|
733
|
+
"forLineage": False,
|
|
734
|
+
"forDuplicateProcessing": False
|
|
735
|
+
})
|
|
736
|
+
|
|
737
|
+
guid = egeria_client.create_solution_component(body)
|
|
738
|
+
if guid:
|
|
739
|
+
update_element_dictionary(qualified_name, {
|
|
740
|
+
'guid': guid, 'display_name': display_name
|
|
741
|
+
})
|
|
742
|
+
msg = f"\n\n==> Created Element `{display_name}` with GUID {guid}\n\n___"
|
|
743
|
+
logger.success(msg)
|
|
744
|
+
print(Markdown(msg))
|
|
745
|
+
|
|
746
|
+
if search_keywords:
|
|
747
|
+
add_search_keywords(egeria_client, guid, search_keywords)
|
|
748
|
+
|
|
749
|
+
if in_component_guids:
|
|
750
|
+
for comp in in_component_guids:
|
|
751
|
+
egeria_client.link_subcomponent(comp, guid, None)
|
|
752
|
+
msg = f"Added to parent components `{in_component_names}` "
|
|
753
|
+
logger.trace(msg)
|
|
754
|
+
|
|
755
|
+
if actor_guids:
|
|
756
|
+
for actor in actor_guids:
|
|
757
|
+
egeria_client.link_component_to_actor(actor, guid, None)
|
|
758
|
+
msg = f"Added `{actor_guids}` to `{display_name}`"
|
|
759
|
+
logger.trace(msg)
|
|
760
|
+
|
|
761
|
+
if in_blueprint_guids:
|
|
762
|
+
for bp in in_blueprint_guids:
|
|
763
|
+
egeria_client.link_solution_component_to_blueprint(bp, guid, None)
|
|
764
|
+
msg = f"Added `{display_name}`to blueprints `{in_blueprint_names}`"
|
|
765
|
+
logger.trace(msg)
|
|
766
|
+
|
|
767
|
+
if in_supply_chain_guids:
|
|
768
|
+
for isc in in_supply_chain_guids:
|
|
769
|
+
egeria_client.link_design_to_implementation(isc, guid, None)
|
|
770
|
+
msg = f"Added `{display_name}`to supply chain `{in_supply_chain_names}`"
|
|
771
|
+
logger.trace(msg)
|
|
772
|
+
journal_entry_guid = add_note_in_dr_e(egeria_client, qualified_name, display_name,
|
|
773
|
+
journal_entry)
|
|
774
|
+
|
|
775
|
+
return egeria_client.get_solution_component_by_guid(guid, output_format='MD')
|
|
776
|
+
else:
|
|
777
|
+
msg = f"Failed to create element `{display_name}` with GUID {guid}\n\n___"
|
|
778
|
+
logger.error(msg)
|
|
779
|
+
return None
|
|
780
|
+
|
|
781
|
+
except Exception as e:
|
|
782
|
+
logger.error(f"Error performing {command}: {e}")
|
|
783
|
+
return None
|
|
784
|
+
else:
|
|
785
|
+
return None
|
|
786
|
+
|
|
787
|
+
|
|
788
|
+
@logger.catch
|
|
789
|
+
def process_component_link_unlink_command(egeria_client: EgeriaTech, txt: str,
|
|
790
|
+
directive: str = "display") -> Optional[str]:
|
|
791
|
+
"""
|
|
792
|
+
Processes a link or unlink command to wire solution components.
|
|
793
|
+
|
|
794
|
+
:param txt: A string representing the input cell to be processed for
|
|
795
|
+
extracting blueprint-related attributes.
|
|
796
|
+
:param directive: an optional string indicating the directive to be used - display, validate or execute
|
|
797
|
+
:return: A string summarizing the outcome of the processing.
|
|
798
|
+
"""
|
|
799
|
+
command, object_type, object_action = extract_command_plus(txt)
|
|
800
|
+
print(Markdown(f"# {command}\n"))
|
|
801
|
+
|
|
802
|
+
parsed_output = parse_view_command(egeria_client, object_type, object_action, txt, directive)
|
|
803
|
+
|
|
804
|
+
print(Markdown(parsed_output['display']))
|
|
805
|
+
|
|
806
|
+
logger.debug(json.dumps(parsed_output, indent=4))
|
|
807
|
+
|
|
808
|
+
attributes = parsed_output['attributes']
|
|
809
|
+
|
|
810
|
+
component1 = attributes.get('Component1', {}).get('guid', None)
|
|
811
|
+
component2 = attributes.get('Component2', {}).get('guid', None)
|
|
812
|
+
label = attributes.get('Wire Label', {}).get('value', None)
|
|
813
|
+
description = attributes.get('Description', {}).get('value', None)
|
|
814
|
+
|
|
815
|
+
valid = parsed_output['valid']
|
|
816
|
+
exists = component1 is not None and component2 is not None
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
external_source_guid = attributes.get('External Source GUID', {}).get('value', None)
|
|
820
|
+
external_source_name = attributes.get('External Source Name', {}).get('value', None)
|
|
821
|
+
|
|
822
|
+
effective_time = attributes.get('Effective Time', {}).get('value', None)
|
|
823
|
+
effective_from = attributes.get('Effective From', {}).get('value', None)
|
|
824
|
+
effective_to = attributes.get('Effective To', {}).get('value', None)
|
|
825
|
+
|
|
826
|
+
additional_prop = attributes.get('Additional Properties', {}).get('value', None)
|
|
827
|
+
additional_properties = json.loads(additional_prop) if additional_prop is not None else None
|
|
828
|
+
extended_prop = attributes.get('Extended Properties', {}).get('value', None)
|
|
829
|
+
extended_properties = json.loads(extended_prop) if extended_prop is not None else None
|
|
830
|
+
|
|
831
|
+
if directive == "display":
|
|
832
|
+
|
|
833
|
+
return None
|
|
834
|
+
elif directive == "validate":
|
|
835
|
+
if valid:
|
|
836
|
+
print(Markdown(f"==> Validation of {command} completed successfully!\n"))
|
|
837
|
+
else:
|
|
838
|
+
msg = f"Validation failed for object_action `{command}`\n"
|
|
839
|
+
return valid
|
|
840
|
+
|
|
841
|
+
elif directive == "process":
|
|
842
|
+
try:
|
|
843
|
+
if object_action == "Unlink":
|
|
844
|
+
if not exists:
|
|
845
|
+
msg = (f" Link `{label}` does not exist! Updating result document with Link "
|
|
846
|
+
f"object_action\n")
|
|
847
|
+
logger.error(msg)
|
|
848
|
+
out = parsed_output['display'].replace('Link', 'Detach', 1)
|
|
849
|
+
return out
|
|
850
|
+
elif not valid:
|
|
851
|
+
return None
|
|
852
|
+
else:
|
|
853
|
+
print(Markdown(
|
|
854
|
+
f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
|
|
855
|
+
|
|
856
|
+
body = body_slimmer({
|
|
857
|
+
"class": "MetadataSourceRequestBody",
|
|
858
|
+
"externalSourceGUID": external_source_guid,
|
|
859
|
+
"externalSourceName": external_source_name,
|
|
860
|
+
"effectiveTime": effective_time,
|
|
861
|
+
"forLineage": False,
|
|
862
|
+
"forDuplicateProcessing": False
|
|
863
|
+
})
|
|
864
|
+
|
|
865
|
+
egeria_client.detach_solution_linking_wire(component1, component2, body)
|
|
866
|
+
|
|
867
|
+
logger.success(f"===> Detached segment with {label} from `{component1}`to {component2}\n")
|
|
868
|
+
out = parsed_output['display'].replace('Unlink', 'Link', 1)
|
|
869
|
+
|
|
870
|
+
return (out)
|
|
871
|
+
|
|
872
|
+
|
|
873
|
+
elif object_action == "Link":
|
|
874
|
+
if valid is False and exists:
|
|
875
|
+
msg = (f"--> Link called `{label}` already exists and result document updated changing "
|
|
876
|
+
f"`Link` to `Detach` in processed output\n")
|
|
877
|
+
logger.error(msg)
|
|
878
|
+
|
|
879
|
+
elif valid is False:
|
|
880
|
+
msg = f"==>{object_type} Link with label `{label}` is not valid and can't be created"
|
|
881
|
+
logger.error(msg)
|
|
882
|
+
return
|
|
883
|
+
else:
|
|
884
|
+
body = {
|
|
885
|
+
"class": "NewRelationshipRequestBody",
|
|
886
|
+
"effectiveTime": effective_time,
|
|
887
|
+
"forLineage": False,
|
|
888
|
+
"forDuplicateProcessing": False,
|
|
889
|
+
"properties": {
|
|
890
|
+
"class": "SolutionLinkingWireProperties",
|
|
891
|
+
"label": label,
|
|
892
|
+
"description": description,
|
|
893
|
+
"effectiveFrom": effective_from,
|
|
894
|
+
"effectiveTo": effective_to
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
egeria_client.link_solution_linking_wire(component1, component2, body)
|
|
899
|
+
msg = f"==>Created {object_type} link named `{label}`\n"
|
|
900
|
+
logger.success(msg)
|
|
901
|
+
print(Markdown(msg))
|
|
902
|
+
out = parsed_output['display'].replace('Link', 'Detach', 1)
|
|
903
|
+
return out
|
|
904
|
+
|
|
905
|
+
except Exception as e:
|
|
906
|
+
logger.error(f"Error performing {command}: {e}")
|
|
907
|
+
return None
|
|
908
|
+
else:
|
|
909
|
+
return None
|
|
910
|
+
|
|
911
|
+
|
|
912
|
+
|
|
913
|
+
@logger.catch
|
|
914
|
+
def process_information_supply_chain_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") \
|
|
915
|
+
-> \
|
|
916
|
+
Optional[str]:
|
|
917
|
+
"""
|
|
918
|
+
Processes a solution blueprint create or update object_action by extracting key attributes such as
|
|
919
|
+
blueprint name, description, and usage from the given text.
|
|
920
|
+
|
|
921
|
+
:param txt: A string representing the input cell to be processed for
|
|
922
|
+
extracting blueprint-related attributes.
|
|
923
|
+
:param directive: an optional string indicating the directive to be used - display, validate or execute
|
|
924
|
+
:return: A string summarizing the outcome of the processing.
|
|
925
|
+
"""
|
|
926
|
+
command, object_type, object_action = extract_command_plus(txt)
|
|
927
|
+
print(Markdown(f"# {command}\n"))
|
|
928
|
+
|
|
929
|
+
parsed_output = parse_upsert_command(egeria_client, object_type, object_action, txt, directive)
|
|
930
|
+
|
|
931
|
+
valid = parsed_output['valid']
|
|
932
|
+
exists = parsed_output['exists']
|
|
933
|
+
|
|
934
|
+
qualified_name = parsed_output.get('qualified_name', None)
|
|
935
|
+
guid = parsed_output.get('guid', None)
|
|
936
|
+
|
|
937
|
+
print(Markdown(parsed_output['display']))
|
|
938
|
+
|
|
939
|
+
logger.debug(json.dumps(parsed_output, indent=4))
|
|
940
|
+
|
|
941
|
+
attributes = parsed_output['attributes']
|
|
942
|
+
description = attributes.get('Description', {}).get('value', None)
|
|
943
|
+
display_name = attributes['Display Name'].get('value', None)
|
|
944
|
+
version_identifier = attributes.get('Version Identifier', {}).get('value', None)
|
|
945
|
+
journal_entry = attributes.get('Journal Entry', {}).get('value', None)
|
|
946
|
+
effective_time = attributes.get('Effective Time', {}).get('value', None)
|
|
947
|
+
effective_from = attributes.get('Effective From', {}).get('value', None)
|
|
948
|
+
effective_to = attributes.get('Effective To', {}).get('value', None)
|
|
949
|
+
|
|
950
|
+
nested_supply_chain_guids = attributes.get('Nested Information Supply Chains', {}).get('guid_list', None)
|
|
951
|
+
additional_prop = attributes.get('Additional Properties', {}).get('value', None)
|
|
952
|
+
additional_properties = json.loads(additional_prop) if additional_prop is not None else None
|
|
953
|
+
extended_prop = attributes.get('Extended Properties', {}).get('value', None)
|
|
954
|
+
extended_properties = json.loads(extended_prop) if extended_prop is not None else None
|
|
955
|
+
|
|
956
|
+
scope = attributes.get('Scope', {}).get('value', None)
|
|
957
|
+
purposes = attributes.get('Purposes', {}).get('value', None)
|
|
958
|
+
in_supply_chain_guids = attributes.get('In Information Supply Chain', {}).get('guid_list', None)
|
|
959
|
+
merge_update = attributes.get('Merge Update', {}).get('value', True),
|
|
960
|
+
|
|
961
|
+
|
|
962
|
+
if directive == "display":
|
|
963
|
+
|
|
964
|
+
return None
|
|
965
|
+
elif directive == "validate":
|
|
966
|
+
if valid:
|
|
967
|
+
print(Markdown(f"==> Validation of {command} completed successfully!\n"))
|
|
968
|
+
else:
|
|
969
|
+
msg = f"Validation failed for object_action `{command}`\n"
|
|
970
|
+
return valid
|
|
971
|
+
|
|
972
|
+
elif directive == "process":
|
|
973
|
+
try:
|
|
974
|
+
prop_body = {
|
|
975
|
+
"class": "InformationSupplyChainProperties", "effectiveFrom": effective_from,
|
|
976
|
+
"effectiveTo": effective_to, "extendedProperties": extended_properties,
|
|
977
|
+
"qualifiedName": qualified_name, "additionalProperties": additional_properties,
|
|
978
|
+
"displayName": display_name, "description": description, "scope": scope,
|
|
979
|
+
"purposes": purposes, "version": version_identifier
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
if object_action == "Update":
|
|
983
|
+
if not exists:
|
|
984
|
+
msg = (f" Element `{display_name}` does not exist! Updating result document with Create "
|
|
985
|
+
f"object_action\n")
|
|
986
|
+
logger.error(msg)
|
|
987
|
+
return update_a_command(txt, object_action, object_type, qualified_name, guid)
|
|
988
|
+
elif not valid:
|
|
989
|
+
return None
|
|
990
|
+
else:
|
|
991
|
+
print(Markdown(
|
|
992
|
+
f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
|
|
993
|
+
|
|
994
|
+
|
|
995
|
+
body = set_update_body("InformationSupplyChain", attributes)
|
|
996
|
+
body['properties'] = prop_body
|
|
997
|
+
egeria_client.update_info_supply_chain(guid, body)
|
|
998
|
+
|
|
999
|
+
sync_chain_related_elements(egeria_client, guid, in_supply_chain_guids, display_name, merge_update)
|
|
1000
|
+
logger.success(f"==> Updated {object_type} `{display_name}` with GUID {guid}\n\n")
|
|
1001
|
+
update_element_dictionary(qualified_name, {
|
|
1002
|
+
'guid': guid, 'display_name': display_name
|
|
1003
|
+
})
|
|
1004
|
+
journal_entry_guid = add_note_in_dr_e(egeria_client, qualified_name, display_name, journal_entry)
|
|
1005
|
+
|
|
1006
|
+
logger.success(f"===> Updated {object_type} `{display_name}` related elements\n\n")
|
|
1007
|
+
return egeria_client.get_info_supply_chain_by_guid(guid, output_format='MD', report_spec = "Information-Supply-Chain-DrE")
|
|
1008
|
+
|
|
1009
|
+
|
|
1010
|
+
elif object_action == "Create":
|
|
1011
|
+
if valid is False and exists:
|
|
1012
|
+
msg = (
|
|
1013
|
+
f"--> Data Specification `{display_name}` already exists and result document updated changing "
|
|
1014
|
+
f"`Create` to `Update` in processed output\n")
|
|
1015
|
+
logger.error(msg)
|
|
1016
|
+
return update_a_command(txt, object_action, object_type, qualified_name, guid)
|
|
1017
|
+
|
|
1018
|
+
elif valid is False:
|
|
1019
|
+
msg = f"==>{object_type} `{display_name}` is not valid and can't be created"
|
|
1020
|
+
logger.error(msg)
|
|
1021
|
+
return
|
|
1022
|
+
else:
|
|
1023
|
+
body = set_create_body("InformationSupplyChain", attributes)
|
|
1024
|
+
body['properties'] = prop_body
|
|
1025
|
+
|
|
1026
|
+
guid = egeria_client.create_info_supply_chain(body)
|
|
1027
|
+
if guid:
|
|
1028
|
+
msg = f"==>Created Element `{display_name}` with GUID {guid}\n"
|
|
1029
|
+
logger.success(msg)
|
|
1030
|
+
print(Markdown(msg))
|
|
1031
|
+
update_element_dictionary(qualified_name, {
|
|
1032
|
+
'guid': guid, 'display_name': display_name
|
|
1033
|
+
})
|
|
1034
|
+
if in_supply_chain_guids:
|
|
1035
|
+
for nested_chain in in_supply_chain_guids:
|
|
1036
|
+
egeria_client.compose_info_supply_chains(nested_chain, guid)
|
|
1037
|
+
|
|
1038
|
+
if journal_entry:
|
|
1039
|
+
journal_entry_guid = add_note_in_dr_e(egeria_client, qualified_name, display_name,
|
|
1040
|
+
journal_entry)
|
|
1041
|
+
if nested_supply_chain_guids:
|
|
1042
|
+
for nested_supply_chain in nested_supply_chain_guids:
|
|
1043
|
+
egeria_client.compose_info_supply_chains(guid, nested_supply_chain)
|
|
1044
|
+
|
|
1045
|
+
msg = f"==>Created Element `{display_name}` Relationships\n"
|
|
1046
|
+
logger.success(msg)
|
|
1047
|
+
print(Markdown(msg))
|
|
1048
|
+
return egeria_client.get_info_supply_chain_by_guid(guid, output_format='MD', report_spec="Information-Supply-Chain-DrE")
|
|
1049
|
+
else:
|
|
1050
|
+
msg = f"==>Failed to create element `{display_name}` with GUID {guid}\n"
|
|
1051
|
+
logger.error(msg)
|
|
1052
|
+
return None
|
|
1053
|
+
|
|
1054
|
+
except Exception as e:
|
|
1055
|
+
logger.error(f"Error performing {command}: {e}")
|
|
1056
|
+
return None
|
|
1057
|
+
else:
|
|
1058
|
+
return None
|
|
1059
|
+
|
|
1060
|
+
|
|
1061
|
+
|
|
1062
|
+
@logger.catch
|
|
1063
|
+
def process_information_supply_chain_link_unlink_command(egeria_client: EgeriaTech, txt: str,
|
|
1064
|
+
directive: str = "display") -> Optional[str]:
|
|
1065
|
+
"""
|
|
1066
|
+
Processes a link or unlink command to associate or break up peer supply chains..
|
|
1067
|
+
|
|
1068
|
+
:param txt: A string representing the input cell to be processed for
|
|
1069
|
+
extracting blueprint-related attributes.
|
|
1070
|
+
:param directive: an optional string indicating the directive to be used - display, validate or execute
|
|
1071
|
+
:return: A string summarizing the outcome of the processing.
|
|
1072
|
+
"""
|
|
1073
|
+
command, object_type, object_action = extract_command_plus(txt)
|
|
1074
|
+
print(Markdown(f"# {command}\n"))
|
|
1075
|
+
|
|
1076
|
+
parsed_output = parse_view_command(egeria_client, object_type, object_action, txt, directive)
|
|
1077
|
+
|
|
1078
|
+
print(Markdown(parsed_output['display']))
|
|
1079
|
+
|
|
1080
|
+
logger.debug(json.dumps(parsed_output, indent=4))
|
|
1081
|
+
|
|
1082
|
+
attributes = parsed_output['attributes']
|
|
1083
|
+
|
|
1084
|
+
segment1 = attributes.get('Segment1', {}).get('guid', None)
|
|
1085
|
+
segment2 = attributes.get('Segment2', {}).get('guid', None)
|
|
1086
|
+
label = attributes.get('Link Label', {}).get('value', None)
|
|
1087
|
+
description = attributes.get('Description', {}).get('value', None)
|
|
1088
|
+
|
|
1089
|
+
valid = parsed_output['valid']
|
|
1090
|
+
exists = segment1 is not None and segment2 is not None
|
|
1091
|
+
|
|
1092
|
+
|
|
1093
|
+
external_source_guid = attributes.get('External Source GUID', {}).get('value', None)
|
|
1094
|
+
external_source_name = attributes.get('External Source Name', {}).get('value', None)
|
|
1095
|
+
|
|
1096
|
+
effective_time = attributes.get('Effective Time', {}).get('value', None)
|
|
1097
|
+
effective_from = attributes.get('Effective From', {}).get('value', None)
|
|
1098
|
+
effective_to = attributes.get('Effective To', {}).get('value', None)
|
|
1099
|
+
|
|
1100
|
+
additional_prop = attributes.get('Additional Properties', {}).get('value', None)
|
|
1101
|
+
additional_properties = json.loads(additional_prop) if additional_prop is not None else None
|
|
1102
|
+
extended_prop = attributes.get('Extended Properties', {}).get('value', None)
|
|
1103
|
+
extended_properties = json.loads(extended_prop) if extended_prop is not None else None
|
|
1104
|
+
|
|
1105
|
+
if directive == "display":
|
|
1106
|
+
|
|
1107
|
+
return None
|
|
1108
|
+
elif directive == "validate":
|
|
1109
|
+
if valid:
|
|
1110
|
+
print(Markdown(f"==> Validation of {command} completed successfully!\n"))
|
|
1111
|
+
else:
|
|
1112
|
+
msg = f"Validation failed for object_action `{command}`\n"
|
|
1113
|
+
return valid
|
|
1114
|
+
|
|
1115
|
+
elif directive == "process":
|
|
1116
|
+
try:
|
|
1117
|
+
if object_action == "Unlink":
|
|
1118
|
+
if not exists:
|
|
1119
|
+
msg = (f" Link `{label}` does not exist! Updating result document with Link "
|
|
1120
|
+
f"object_action\n")
|
|
1121
|
+
logger.error(msg)
|
|
1122
|
+
out = parsed_output['display'].replace('Link', 'Detach', 1)
|
|
1123
|
+
return out
|
|
1124
|
+
elif not valid:
|
|
1125
|
+
return None
|
|
1126
|
+
else:
|
|
1127
|
+
print(Markdown(
|
|
1128
|
+
f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
|
|
1129
|
+
|
|
1130
|
+
body = body_slimmer({
|
|
1131
|
+
"class": "DeleteRelationshipRequestBody",
|
|
1132
|
+
"externalSourceGUID": external_source_guid,
|
|
1133
|
+
"externalSourceName": external_source_name,
|
|
1134
|
+
"effectiveTime": effective_time,
|
|
1135
|
+
"forLineage": False,
|
|
1136
|
+
"forDuplicateProcessing": False
|
|
1137
|
+
})
|
|
1138
|
+
|
|
1139
|
+
egeria_client.unlink_peer_info_supply_chains(segment1, segment2, body)
|
|
1140
|
+
|
|
1141
|
+
logger.success(f"===> Detached segment with {label} from `{segment1}`to {segment2}\n")
|
|
1142
|
+
out = parsed_output['display'].replace('Unlink', 'Link', 1)
|
|
1143
|
+
|
|
1144
|
+
return (out)
|
|
1145
|
+
|
|
1146
|
+
|
|
1147
|
+
elif object_action == "Link":
|
|
1148
|
+
if valid is False and exists:
|
|
1149
|
+
msg = (f"--> Link called `{label}` already exists and result document updated changing "
|
|
1150
|
+
f"`Link` to `Detach` in processed output\n")
|
|
1151
|
+
logger.error(msg)
|
|
1152
|
+
|
|
1153
|
+
elif valid is False:
|
|
1154
|
+
msg = f"==>{object_type} Link with label `{label}` is not valid and can't be created"
|
|
1155
|
+
logger.error(msg)
|
|
1156
|
+
return
|
|
1157
|
+
else:
|
|
1158
|
+
body = {
|
|
1159
|
+
"class": "NewRelationshipRequestBody",
|
|
1160
|
+
"effectiveTime": effective_time,
|
|
1161
|
+
"forLineage": False,
|
|
1162
|
+
"forDuplicateProcessing": False,
|
|
1163
|
+
"properties": {
|
|
1164
|
+
"class": "InformationSupplyChainLinkProperties",
|
|
1165
|
+
"label": label,
|
|
1166
|
+
"description": description,
|
|
1167
|
+
"effectiveFrom": effective_from,
|
|
1168
|
+
"effectiveTo": effective_to
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
egeria_client.link_peer_info_supply_chains(segment1, segment2, body)
|
|
1173
|
+
msg = f"==>Created {object_type} link named `{label}`\n"
|
|
1174
|
+
logger.success(msg)
|
|
1175
|
+
out = parsed_output['display'].replace('Link', 'Detach', 1)
|
|
1176
|
+
return out
|
|
1177
|
+
|
|
1178
|
+
|
|
1179
|
+
except Exception as e:
|
|
1180
|
+
logger.error(f"Error performing {command}: {e}")
|
|
1181
|
+
return None
|
|
1182
|
+
else:
|
|
1183
|
+
return None
|
|
1184
|
+
|