diff --git a/Makefile b/Makefile index 0620a007..02816daa 100644 --- a/Makefile +++ b/Makefile @@ -140,6 +140,10 @@ LOG_LEVEL ?= DEBUG MEMORY_MAX ?= 90% MEMORY_MIN ?= 70% +# Disable the semantic browser auto refresh +# More information is available in the "Capella/Base" documentation. +CAPELLA_DISABLE_SEMANTIC_BROWSER_AUTO_REFRESH ?= 1 + # If this option is set to 1, all tests that require a running t4c server # will be executed. To run these tests, you need a Makefile in # t4c/server with a target t4c/server/server that builds the t4c server @@ -291,6 +295,7 @@ capella/builder: run-capella/base: capella/base docker run $(DOCKER_RUN_FLAGS) \ + -e CAPELLA_DISABLE_SEMANTIC_BROWSER_AUTO_REFRESH=$(CAPELLA_DISABLE_SEMANTIC_BROWSER_AUTO_REFRESH) \ $(DOCKER_PREFIX)$<:$$(echo "$(DOCKER_TAG_SCHEMA)" | envsubst) run-jupyter-notebook: jupyter-notebook @@ -315,6 +320,8 @@ run-capella/remote: capella/remote -e XPRA_SUBPATH=$(XPRA_SUBPATH) \ -e MEMORY_MIN=$(MEMORY_MIN) \ -e MEMORY_MAX=$(MEMORY_MAX) \ + -e CAPELLA_DISABLE_SEMANTIC_BROWSER_AUTO_REFRESH=$(CAPELLA_DISABLE_SEMANTIC_BROWSER_AUTO_REFRESH) \ + -e LOG_LEVEL="$(LOG_LEVEL)" \ -p $(RDP_PORT):3389 \ -p $(WEB_PORT):10000 \ -p $(METRICS_PORT):9118 \ @@ -382,6 +389,8 @@ run-t4c/client/remote-legacy: t4c/client/remote -e XPRA_SUBPATH=$(XPRA_SUBPATH) \ -e MEMORY_MIN=$(MEMORY_MIN) \ -e MEMORY_MAX=$(MEMORY_MAX) \ + -e CAPELLA_DISABLE_SEMANTIC_BROWSER_AUTO_REFRESH=$(CAPELLA_DISABLE_SEMANTIC_BROWSER_AUTO_REFRESH) \ + -e LOG_LEVEL="$(LOG_LEVEL)" \ -p $(RDP_PORT):3389 \ -p $(WEB_PORT):10000 \ -p $(METRICS_PORT):9118 \ @@ -398,6 +407,8 @@ run-t4c/client/remote: t4c/client/remote -e XPRA_SUBPATH=$(XPRA_SUBPATH) \ -e MEMORY_MIN=$(MEMORY_MIN) \ -e MEMORY_MAX=$(MEMORY_MAX) \ + -e CAPELLA_DISABLE_SEMANTIC_BROWSER_AUTO_REFRESH=$(CAPELLA_DISABLE_SEMANTIC_BROWSER_AUTO_REFRESH) \ + -e LOG_LEVEL="$(LOG_LEVEL)" \ -p $(RDP_PORT):3389 \ -p $(WEB_PORT):10000 \ -p $(METRICS_PORT):9118 \ @@ -417,6 +428,8 @@ run-t4c/client/remote/pure-variants: t4c/client/remote/pure-variants -e CONNECTION_METHOD=$(CONNECTION_METHOD) \ -e XPRA_SUBPATH=$(XPRA_SUBPATH) \ -e WORKSPACE_DIR=/workspace/capella_pv \ + -e CAPELLA_DISABLE_SEMANTIC_BROWSER_AUTO_REFRESH=$(CAPELLA_DISABLE_SEMANTIC_BROWSER_AUTO_REFRESH) \ + -e LOG_LEVEL="$(LOG_LEVEL)" \ -p $(RDP_PORT):3389 \ -p $(WEB_PORT):10000 \ -p $(METRICS_PORT):9118 \ diff --git a/capella/setup/disable_semantic_browser_auto_refresh.py b/capella/setup/disable_semantic_browser_auto_refresh.py new file mode 100644 index 00000000..7f4836cd --- /dev/null +++ b/capella/setup/disable_semantic_browser_auto_refresh.py @@ -0,0 +1,161 @@ +# SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors +# SPDX-License-Identifier: Apache-2.0 +"""Module is documented in the function `main`.""" + +import fileinput +import logging +import os +import pathlib +import sys + +from lxml import etree + +NS_MAP = { + "xmi": "http://www.omg.org/XMI", + "xsi": "http://www.w3.org/2001/XMLSchema-instance", + "basic": "http://www.eclipse.org/ui/2010/UIModel/application/ui/basic", + "advanced": ( + "http://www.eclipse.org/ui/2010/UIModel/application/ui/advanced" + ), + "application": "http://www.eclipse.org/ui/2010/UIModel/application", + "menu": "http://www.eclipse.org/ui/2010/UIModel/application/ui/menu", +} +XPATH_EXPR = ( + "//persistedState[@key='memento'" + " and contains(@value, 'listeningToWorkbenchPageSelectionEvents')]" +) + +WORKSPACE_DIR = os.getenv("WORKSPACE_DIR", "/workspace") + +logging.basicConfig(level=os.getenv("LOG_LEVEL", "INFO")) +logger = logging.getLogger(__file__) + + +def main() -> None: + """Disable auto-refresh of semantic browser when setting exists. + + This script will disable the auto-refresh of the semantic browser in + Capella. A precondition is, that the according Capella configuration + entry already exists on disk. The script identifies the setting of + interest using ``lxml`` and an XPath query. The editing of the + configuration file is done in-place using the ``fileinput`` module + instead of writing it on disk with ``lxml``. This is done to avoid + issues with the file format. Capella mixes HTML into an XML file + and `lxml` escapes some HTML entities, which would break the file. + """ + _check_environment_variable() + logger.debug("Expecting the workspace to be at: `%s`", WORKSPACE_DIR) + file_path = ( + pathlib.Path(WORKSPACE_DIR) + / ".metadata" + / ".plugins" + / "org.eclipse.e4.workbench" + / "workbench.xmi" + ) + _check_for_file_existence(file_path) + + browser_autorefresh_line_no = _identify_semantic_browser_line_no(file_path) + + _replace_content_in_line_of_file( + file_path, + browser_autorefresh_line_no, + "listeningToWorkbenchPageSelectionEvents="1"", + "listeningToWorkbenchPageSelectionEvents="0"", + ) + + +def _check_environment_variable() -> None: + disable_semantic_browser_auto_refresh = os.getenv( + "CAPELLA_DISABLE_SEMANTIC_BROWSER_AUTO_REFRESH", "0" + ) + if disable_semantic_browser_auto_refresh not in ("0", "1"): + raise ValueError( + "Unsupported value for environment variable" + " `CAPELLA_DISABLE_SEMANTIC_BROWSER_AUTO_REFRESH`." + " Only `0` or `1` are supported." + ) + + if disable_semantic_browser_auto_refresh == "0": + logger.info( + "Environment variable" + " `CAPELLA_DISABLE_SEMANTIC_BROWSER_AUTO_REFRESH` is set to 0." + " The semantic browser auto refresh will not be disabled. ", + ) + sys.exit(0) + + logger.info( + "Identified that the environment variable" + " `CAPELLA_DISABLE_SEMANTIC_BROWSER_AUTO_REFRESH` is set to `1`." + " We will disable the auto-refresh of the semantic browser." + ) + + +def _check_for_file_existence(file_path: pathlib.Path) -> None: + if not file_path.is_file(): + logger.debug( + "File not found: `%s`." + " Cannot disable auto-refresh of semantic browser.", + file_path, + ) + sys.exit(0) + + +def _identify_semantic_browser_line_no(file_path: pathlib.Path) -> int: + root = etree.parse(file_path).getroot() + logger.debug( + "Searching for XPath expression: `%s` in the file `%s`", + XPATH_EXPR, + file_path, + ) + hit_elements = root.xpath(XPATH_EXPR, namespaces=NS_MAP) + if not hit_elements: + logger.debug("No elements found. Exiting.") + sys.exit(0) + + # Runtime lands here, when we found a setting that controls if the semantic + # browser should auto-refresh or not + persisted_state = hit_elements[0] + parent_element = persisted_state.getparent() + if ( + parent_element is None + or "elementId" not in parent_element.attrib + or "semanticbrowser" not in parent_element.attrib["elementId"].lower() + ): + sys.exit(0) + + browser_autorefresh_line_no = persisted_state.sourceline + logger.debug( + "Found element in line %s:%d", + file_path, + browser_autorefresh_line_no, + ) + return browser_autorefresh_line_no + + +def _replace_content_in_line_of_file( + file_path: pathlib.Path, line_no: int, old: str, new: str +) -> None: + with fileinput.input(file_path, inplace=True, backup=".bak") as file: + for cur_line_no, line in enumerate(file, start=1): + if cur_line_no != line_no: + sys.stdout.write(line) + continue + if old in line: + line = line.replace(old, new) + logger.info( + "Replaced `%s` with `%s` in line number: `%d`", + old, + new, + line_no, + ) + else: + logger.debug( + "Skipping replacement in line '%d' as it does not contain '%s'", + cur_line_no, + old, + ) + sys.stdout.write(line) + + +if __name__ == "__main__": + main() diff --git a/docs/docs/capella/base.md b/docs/docs/capella/base.md index 4a3a6904..ec3f18b1 100644 --- a/docs/docs/capella/base.md +++ b/docs/docs/capella/base.md @@ -220,6 +220,27 @@ Please download all packages and place the files in the folder `capella/libs`: ## Run the container +### Configuration Options + +There are a few configuration options that can be passed to the container. + +#### Semantic Browser Auto-refresh + +One +[performance recommendation](https://github.com/eclipse-capella/capella/blob/master/doc/plugins/org.polarsys.capella.th.doc/html/Performance%20Recommandations/Performance%20Recommandations.mediawiki#desynchronize-semantic-browser) +of the Capella team is to disable the semantic browser auto-refresh. + +The semantic browser synchronization is disabled by default in our containers. +To follow a more streamlined approach, it will also be disabled if actively +changed in the UI / workspace. + +To disable this behaviour and just keep the option as it is, pass the following +flag to the `docker run` command: + +```zsh +--env CAPELLA_DISABLE_SEMANTIC_BROWSER_AUTO_REFRESH=0 +``` + ### Locally on X11 systems If you don't need remote access, have a local X11 server running and just want @@ -248,7 +269,7 @@ docker run -d \ Capella should start after a few seconds. -### In a remote container (RDP) +### In a remote container Please follow the instructions on the [remote](../remote.md) page. When running the image, add the following variables to the `docker run` command: