diff --git a/core/src/main/python/compare_model.py b/core/src/main/python/compare_model.py index 97702f5cc5..2974699515 100644 --- a/core/src/main/python/compare_model.py +++ b/core/src/main/python/compare_model.py @@ -1,4 +1,4 @@ -# Copyright (c) 2020, 2022, Oracle and/or its affiliates. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. # # ------------ @@ -14,23 +14,22 @@ import os import sets import sys -import traceback import java.io.File as JFile import java.io.FileOutputStream as JFileOutputStream import java.io.IOException as JIOException import java.io.PrintWriter as JPrintWriter from java.lang import System + from oracle.weblogic.deploy.compare import CompareException from oracle.weblogic.deploy.exception import ExceptionHelper from oracle.weblogic.deploy.util import CLAException from oracle.weblogic.deploy.util import FileUtils -from oracle.weblogic.deploy.util import PyWLSTException +from oracle.weblogic.deploy.util import TranslateException from oracle.weblogic.deploy.util import VariableException from oracle.weblogic.deploy.validate import ValidateException from oracle.weblogic.deploy.yaml import YamlException -import oracle.weblogic.deploy.util.TranslateException as TranslateException from wlsdeploy.aliases.aliases import Aliases from wlsdeploy.aliases.wlst_modes import WlstModes from wlsdeploy.exception import exception_helper @@ -326,14 +325,6 @@ def main(model_context): except CompareException, ce: _exit_code = ExitCode.ERROR __logger.severe('WLSDPLY-05704', ce.getLocalizedMessage(), class_name=_class_name, method_name=_method_name) - except PyWLSTException, pe: - _exit_code = ExitCode.ERROR - __logger.severe('WLSDPLY-05704', pe.getLocalizedMessage(), class_name=_class_name, method_name=_method_name) - except: - exc_type, exc_obj, exc_tb = sys.exc_info() - _exit_code = ExitCode.ERROR - ee_string = traceback.format_exception(exc_type, exc_obj, exc_tb) - __logger.severe('WLSDPLY-05704', ee_string) __logger.exiting(class_name=_class_name, method_name=_method_name, result=_exit_code) return _exit_code diff --git a/core/src/main/python/wlsdeploy/tool/compare/model_comparer.py b/core/src/main/python/wlsdeploy/tool/compare/model_comparer.py index f197b8c319..a066b9e6ec 100644 --- a/core/src/main/python/wlsdeploy/tool/compare/model_comparer.py +++ b/core/src/main/python/wlsdeploy/tool/compare/model_comparer.py @@ -1,10 +1,9 @@ """ -Copyright (c) 2021, 2022, Oracle and/or its affiliates. +Copyright (c) 2021, 2023, Oracle and/or its affiliates. Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. """ from java.util import Properties -from oracle.weblogic.deploy.aliases import AliasException from oracle.weblogic.deploy.util import PyOrderedDict from wlsdeploy.aliases import alias_utils @@ -12,13 +11,14 @@ from wlsdeploy.aliases.alias_constants import PROPERTIES from wlsdeploy.aliases.location_context import LocationContext from wlsdeploy.aliases.model_constants import APPLICATION -from wlsdeploy.aliases.model_constants import KUBERNETES +from wlsdeploy.aliases.model_constants import CRD_MODEL_SECTIONS from wlsdeploy.aliases.model_constants import LIBRARY from wlsdeploy.logging.platform_logger import PlatformLogger from wlsdeploy.util import dictionary_utils from wlsdeploy.util import model_helper import wlsdeploy.util.unicode_helper as str_helper + class ModelComparer(object): """ Class for comparing two WDT models. @@ -308,18 +308,8 @@ def _compare_attribute_sc(self, current_value, past_value, location, key, change if current_value != past_value: if type(current_value) == list: current_list = list(current_value) - previous_list = list(past_value) - - change_list = list(previous_list) - for item in current_list: - if item in previous_list: - change_list.remove(item) - else: - change_list.append(item) - for item in previous_list: - if item not in current_list: - change_list.remove(item) - change_list.append(model_helper.get_delete_name(item)) + past_list = list(past_value) + self._compare_lists(current_list, past_list, key, change_folder) elif isinstance(current_value, Properties): self._compare_properties(current_value, past_value, key, change_folder) @@ -339,26 +329,18 @@ def _compare_attribute(self, current_value, past_value, location, key, change_fo """ if current_value != past_value: attribute_type = self._aliases.get_model_attribute_type(location, key) - if attribute_type in ALIAS_LIST_TYPES: + if self._is_jvm_args_key(key, location): + current_text = self._get_jvm_args_text(current_value) + previous_text = self._get_jvm_args_text(past_value) + if current_text != previous_text: + comment = key + ": '" + str_helper.to_string(previous_text) + "'" + change_folder.addComment(key, comment) + change_folder[key] = current_text + + elif attribute_type in ALIAS_LIST_TYPES: current_list = alias_utils.create_list(current_value, 'WLSDPLY-08001') previous_list = alias_utils.create_list(past_value, 'WLSDPLY-08000') - - change_list = list(previous_list) - for item in current_list: - if item in previous_list: - change_list.remove(item) - else: - change_list.append(item) - for item in previous_list: - if item not in current_list: - change_list.remove(item) - change_list.append(model_helper.get_delete_name(item)) - - current_text = ','.join(current_list) - previous_text = ','.join(previous_list) - comment = key + ": '" + previous_text + "' -> '" + current_text + "'" - change_folder.addComment(key, comment) - change_folder[key] = ','.join(change_list) + self._compare_lists(current_list, previous_list, key, change_folder) elif attribute_type == PROPERTIES: self._compare_properties(current_value, past_value, key, change_folder) @@ -396,6 +378,32 @@ def _compare_properties(self, current_value, past_value, key, change_folder): if property_dict: change_folder[key] = property_dict + def _compare_lists(self, current_list, past_list, key, change_folder): + """ + Compare values of a list attribute from the current and past folders. + The change value and any comments will be added to the change folder. + :param current_list: the value from the current model + :param past_list: the value from the past model + :param key: the key of the attribute + :param change_folder: the folder in the change model to be updated + """ + change_list = list(past_list) + for item in current_list: + if item in past_list: + change_list.remove(item) + else: + change_list.append(item) + for item in past_list: + if item not in current_list: + change_list.remove(item) + change_list.append(model_helper.get_delete_name(item)) + + current_text = ','.join(current_list) + previous_text = ','.join(past_list) + comment = key + ": '" + previous_text + "' -> '" + current_text + "'" + change_folder.addComment(key, comment) + change_folder[key] = ','.join(change_list) + def _check_key(self, key, location): """ Determine if the specified key and location will be compared. @@ -405,11 +413,35 @@ def _check_key(self, key, location): """ _method_name = '_check_key' - if (location is None) and (key == KUBERNETES): - self._logger.info('WLSDPLY-05713', KUBERNETES, class_name=self._class_name, method_name=_method_name) + if (location is None) and (key in CRD_MODEL_SECTIONS): + self._logger.info('WLSDPLY-05713', key, class_name=self._class_name, method_name=_method_name) return False return True + def _is_jvm_args_key(self, key, location): + """ + Determine if the specified attribute requires special JVM argument processing. + :param key: the key to be checked + :param location: the location to be checked + :return: True if the attribute requires special processing, False otherwise + """ + set_method_info = self._aliases.get_model_mbean_set_method_attribute_names_and_types(location) + return key in set_method_info and set_method_info[key]['set_method'] == 'set_jvm_args' + + def _get_jvm_args_text(self, value): + """ + Return the normalized text for the specified JVM arguments value. + These attributes have special handling for create and deploy, + so list delimiter comparison will not cover all the cases. + :param value: the value to be converted, may be a list, string, or None + :return: the normalized text value + """ + if isinstance(value, basestring): + value = value.split() + if isinstance(value, list): + return ' '.join(value) + return value + def _finalize_folder(self, current_folder, past_folder, change_folder, location): """ Perform any adjustments after a folder has been evaluated. diff --git a/core/src/main/resources/oracle/weblogic/deploy/aliases/category_modules/ServerTemplate.json b/core/src/main/resources/oracle/weblogic/deploy/aliases/category_modules/ServerTemplate.json index e45f74d545..ebf0614f4e 100644 --- a/core/src/main/resources/oracle/weblogic/deploy/aliases/category_modules/ServerTemplate.json +++ b/core/src/main/resources/oracle/weblogic/deploy/aliases/category_modules/ServerTemplate.json @@ -1042,7 +1042,7 @@ "ClassPath": [ {"version": "[12.1.2,)", "wlst_mode": "both", "wlst_name": "ClassPath", "wlst_path": "WP001", "default_value": null, "wlst_type": "delimited_string[path_separator]", "preferred_model_type": "delimited_string", "uses_path_tokens": "true"} ], "JavaHome": [ {"version": "[12.1.2,)", "wlst_mode": "both", "wlst_name": "JavaHome", "wlst_path": "WP001", "default_value": null, "wlst_type": "string", "uses_path_tokens": "true"} ], "JavaVendor": [ {"version": "[12.1.2,)", "wlst_mode": "both", "wlst_name": "JavaVendor", "wlst_path": "WP001", "default_value": null, "wlst_type": "string" } ], - "Arguments": [ {"version": "[12.1.2,)", "wlst_mode": "both", "wlst_name": "Arguments", "wlst_path": "WP001", "default_value": null, "wlst_type": "delimited_string[space]" } ], + "Arguments": [ {"version": "[12.1.2,)", "wlst_mode": "both", "wlst_name": "Arguments", "wlst_path": "WP001", "default_value": null, "wlst_type": "delimited_string[space]", "set_method": "MBEAN.set_jvm_args"} ], "MaxRestartCount": [ {"version": "[12.1.2,)", "wlst_mode": "offline", "wlst_name": "MaxRestartCount", "wlst_path": "WP001", "default_value": 0, "wlst_type": "integer" } ], "MwHome": [ {"version": "[12.1.3,)", "wlst_mode": "both", "wlst_name": "${MwHome:MWHome}", "wlst_path": "WP001", "default_value": null, "wlst_type": "string", "uses_path_tokens": "true"} ], "Notes": [ {"version": "[12.1.2,)", "wlst_mode": "both", "wlst_name": "Notes", "wlst_path": "WP001", "default_value": null, "wlst_type": "string" } ],