From 5c20ba4cf068b58b9af0285451231e6d2a9efbb1 Mon Sep 17 00:00:00 2001 From: Derek Sharpe Date: Wed, 23 Oct 2019 11:46:22 -0500 Subject: [PATCH 1/3] if delete notation affects previous model, just delete key from dict during merge --- core/src/main/python/deploy.py | 1 - .../main/python/wlsdeploy/util/cla_helper.py | 26 ++++++----- core/src/test/python/merge_model_test.py | 44 +++++++++++++++++++ .../python/wlsdeploy/util/cla_helper_test.py | 16 ++++++- 4 files changed, 73 insertions(+), 14 deletions(-) create mode 100644 core/src/test/python/merge_model_test.py diff --git a/core/src/main/python/deploy.py b/core/src/main/python/deploy.py index e66852c2e..17e70c8b1 100644 --- a/core/src/main/python/deploy.py +++ b/core/src/main/python/deploy.py @@ -45,7 +45,6 @@ from wlsdeploy.util.cla_utils import CommandLineArgUtil from wlsdeploy.util.model import Model from wlsdeploy.util.model_context import ModelContext -from wlsdeploy.util.model_translator import FileToPython from wlsdeploy.util.weblogic_helper import WebLogicHelper wlst_extended.wlst_functions = globals() diff --git a/core/src/main/python/wlsdeploy/util/cla_helper.py b/core/src/main/python/wlsdeploy/util/cla_helper.py index f35beaac1..74da82bc2 100644 --- a/core/src/main/python/wlsdeploy/util/cla_helper.py +++ b/core/src/main/python/wlsdeploy/util/cla_helper.py @@ -150,7 +150,8 @@ def _merge_dictionaries(dictionary, new_dictionary, variable_map): # the new key should replace the existing one - delete the existing key and add the new one elif replace_key: del dictionary[dictionary_key] - dictionary[new_key] = new_value + if not deployer_utils.is_delete_name(new_key): + dictionary[new_key] = new_value # the key is in both dictionaries - merge if the values are dictionaries, otherwise replace the value else: @@ -175,16 +176,15 @@ def _find_dictionary_merge_key(dictionary, new_key, variable_map): if new_key in dictionary: return new_key, False - if variable_map is not None: - new_is_delete = deployer_utils.is_delete_name(new_key) - match_new_key = _get_merge_match_key(new_key, variable_map) + new_is_delete = deployer_utils.is_delete_name(new_key) + match_new_key = _get_merge_match_key(new_key, variable_map) - for dictionary_key in dictionary.keys(): - dictionary_is_delete = deployer_utils.is_delete_name(dictionary_key) - match_dictionary_key = _get_merge_match_key(dictionary_key, variable_map) - if match_dictionary_key == match_new_key: - replace_key = new_is_delete != dictionary_is_delete - return dictionary_key, replace_key + for dictionary_key in dictionary.keys(): + dictionary_is_delete = deployer_utils.is_delete_name(dictionary_key) + match_dictionary_key = _get_merge_match_key(dictionary_key, variable_map) + if match_dictionary_key == match_new_key: + replace_key = new_is_delete != dictionary_is_delete + return dictionary_key, replace_key return None, False @@ -197,7 +197,11 @@ def _get_merge_match_key(key, variable_map): :param variable_map: variable map to use for substitutions :return: the key to use for matching """ - match_key = variables.substitute_key(key, variable_map) + if variable_map is not None: + match_key = variables.substitute_key(key, variable_map) + else: + match_key = key + if deployer_utils.is_delete_name(match_key): match_key = deployer_utils.get_delete_item_name(match_key) return match_key diff --git a/core/src/test/python/merge_model_test.py b/core/src/test/python/merge_model_test.py new file mode 100644 index 000000000..05ae5590d --- /dev/null +++ b/core/src/test/python/merge_model_test.py @@ -0,0 +1,44 @@ +""" +Copyright (c) 2019, Oracle Corporation and/or its affiliates. All rights reserved. +Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. +""" +import unittest +import os + +import java.util.logging.Level as JLevel + +from wlsdeploy.util import cla_helper + + +class MergeModelTest(unittest.TestCase): + """ + This test verifies merge model functionality provided in cla_helper.py. + """ + _resources_dir = '../../test-classes/' + + # def testSingleModel(self): + # model_name = 'derek1' + # model_file_path = os.path.join(self._resources_dir, '%s.yaml' % model_name) + # + # merged_model = cla_helper.merge_model_files(model_file_path) + # target = open('single.json', 'a') + # target.write(str(merged_model)) + # print 'SINGLE MODEL' + # print merged_model + + def testJndiReplacement(self): + model_name1 = 'derek1' + model_name2 = 'derek2' + model_list = self.__get_model_path(model_name1) + "," + self.__get_model_path(model_name2) + + merged_model = cla_helper.merge_model_files(model_list) + target = open('merged.json', 'a') + target.write(str(merged_model)) + print 'MERGED MODEL' + print str(merged_model) + + def __get_model_path(self, name): + return os.path.join(self._resources_dir, '%s.yaml' % name) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/core/src/test/python/wlsdeploy/util/cla_helper_test.py b/core/src/test/python/wlsdeploy/util/cla_helper_test.py index d90ced89b..8728fd4d0 100644 --- a/core/src/test/python/wlsdeploy/util/cla_helper_test.py +++ b/core/src/test/python/wlsdeploy/util/cla_helper_test.py @@ -99,7 +99,7 @@ def testMergeNameToProperty(self): self._check_merged_server(dictionary, '@@PROP:server1a@@') - # an element with delete notation should replace a base element with a matching name and no notation. + # an element with delete notation should remove a base element with a matching name. def testMergeDeletedNameToName(self): dictionary = _build_model_one('m1') new_dictionary = _build_delete_model('m1') @@ -108,8 +108,20 @@ def testMergeDeletedNameToName(self): cla_helper._merge_dictionaries(dictionary, new_dictionary, variables) # print("Merged model: " + str(dictionary)) + servers = dictionary['Servers'] + self.assertEquals(0, len(servers), "there should be no servers after delete") + + # an element with delete notation should leave a base element with a matching delete notation. + def testMergeDeletedNameToDeleteName(self): + dictionary = _build_delete_model('m1') + new_dictionary = _build_delete_model('m1') + variables = {} + + cla_helper._merge_dictionaries(dictionary, new_dictionary, variables) + # print("Merged model: " + str(dictionary)) + server = self._check_single_server(dictionary, '!m1') - self.assertEquals(0, len(server), "delete server should have no attributes") + self.assertEquals(0, len(server), "server should have no attributes") # an element should replace a base element with a matching name and delete notation. def testMergeNameToDeletedName(self): From d3d6347bdcc527b89efd19c28fd1f4cad3bbd3c8 Mon Sep 17 00:00:00 2001 From: Derek Sharpe Date: Wed, 23 Oct 2019 12:07:25 -0500 Subject: [PATCH 2/3] removed extra test --- core/src/test/python/merge_model_test.py | 44 ------------------------ 1 file changed, 44 deletions(-) delete mode 100644 core/src/test/python/merge_model_test.py diff --git a/core/src/test/python/merge_model_test.py b/core/src/test/python/merge_model_test.py deleted file mode 100644 index 05ae5590d..000000000 --- a/core/src/test/python/merge_model_test.py +++ /dev/null @@ -1,44 +0,0 @@ -""" -Copyright (c) 2019, Oracle Corporation and/or its affiliates. All rights reserved. -Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. -""" -import unittest -import os - -import java.util.logging.Level as JLevel - -from wlsdeploy.util import cla_helper - - -class MergeModelTest(unittest.TestCase): - """ - This test verifies merge model functionality provided in cla_helper.py. - """ - _resources_dir = '../../test-classes/' - - # def testSingleModel(self): - # model_name = 'derek1' - # model_file_path = os.path.join(self._resources_dir, '%s.yaml' % model_name) - # - # merged_model = cla_helper.merge_model_files(model_file_path) - # target = open('single.json', 'a') - # target.write(str(merged_model)) - # print 'SINGLE MODEL' - # print merged_model - - def testJndiReplacement(self): - model_name1 = 'derek1' - model_name2 = 'derek2' - model_list = self.__get_model_path(model_name1) + "," + self.__get_model_path(model_name2) - - merged_model = cla_helper.merge_model_files(model_list) - target = open('merged.json', 'a') - target.write(str(merged_model)) - print 'MERGED MODEL' - print str(merged_model) - - def __get_model_path(self, name): - return os.path.join(self._resources_dir, '%s.yaml' % name) - -if __name__ == '__main__': - unittest.main() \ No newline at end of file From 11ab77c65f83fb17900c68642905c620357a89a6 Mon Sep 17 00:00:00 2001 From: Derek Sharpe Date: Wed, 23 Oct 2019 12:24:11 -0500 Subject: [PATCH 3/3] update readme for change in functionality --- README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f14ea8414..987b35193 100644 --- a/README.md +++ b/README.md @@ -305,25 +305,29 @@ If variable properties are used in element names, such as ```@@PROP:my-server@@` #### Multiple Models and Delete Notation -A named element using [delete notation](#declaring-named-mbeans-to-delete) will completely replace an element with a matching name and no delete notation in a previous model. For example, if Model 1 looks like: +A named element using [delete notation](#declaring-named-mbeans-to-delete) will completely delete an element with a matching name and no delete notation in a previous model. For example, if Model 1 looks like: ```yaml topology: Server: m1: ListenPort: 7000 Notes: "Server 1" + m2: + ListenPort: 9000 ``` and Model 2 looks like: ```yaml topology: Server: - !m1: + !m2: ``` The resulting model would be: ```yaml topology: Server: - !m1: + m1: + ListenPort: 7000 + Notes: "Server 1" ``` Similarly, an element without delete notation will completely replace an element with a matching name that has delete notation in a previous model. For example, if Model 1 looks like: