Skip to content

Commit cf233ca

Browse files
Add app module deployment support (#1220)
* initial checkin * fix password and user in jdbc standalone xml * reset found flag * add ons password token * capture user in properties * initial merge from discovery of application module and added logic for replacing token with clear text value from properties etc ... * changes for url and sh script * add function to handle encrypt only password fields in app module xml * update logic to only encrypt password fields in jdbc app module * add userid to sh script * dont clear cache of other than credentials * change level of warning message * reverse revision * remove extra character in comments * remove unneeded argument * replace with extra tokens * requested fixes * code smells * encrypt password after all substitutions are done * revert changes * requested change * add jms app module for create * use helper method to be consistent Co-authored-by: Carolyn Rountree <[email protected]>
1 parent 4ac0077 commit cf233ca

File tree

11 files changed

+276
-20
lines changed

11 files changed

+276
-20
lines changed

core/src/main/java/oracle/weblogic/deploy/util/FileUtils.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,7 @@ public static byte[] readInputStreamToByteArray(InputStream input) throws IOExce
618618
}
619619

620620
public static File writeInputStreamToFile(InputStream input, String fileName) throws IOException {
621-
File tmpdir = new File(System.getProperty("java.io.tmpdir"));
621+
File tmpdir = getTmpDir();
622622
File file = new File(tmpdir, fileName);
623623
try (FileOutputStream fos = new FileOutputStream(file)) {
624624
byte[] byteArray = FileUtils.readInputStreamToByteArray(input);
@@ -627,6 +627,9 @@ public static File writeInputStreamToFile(InputStream input, String fileName) th
627627
return file;
628628
}
629629

630+
public static File getTmpDir() {
631+
return new File(System.getProperty("java.io.tmpdir"));
632+
}
630633

631634
public static void extractZipFileContent(WLSDeployArchive archiveFile, String zipEntry, String extractPath) {
632635
final String METHOD = "extractZipFileContent";

core/src/main/java/oracle/weblogic/deploy/util/WLSDeployArchive.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,15 @@ public String addApplication(String appPath) throws WLSDeployArchiveIOException
615615
return newName;
616616
}
617617

618+
public String replaceApplication(String appPath, String tempFile) throws WLSDeployArchiveIOException {
619+
final String METHOD = "replaceApplication";
620+
LOGGER.entering(CLASS, METHOD, appPath);
621+
getZipFile().removeZipEntry(appPath);
622+
String newName = addApplication(tempFile);
623+
LOGGER.exiting(CLASS, METHOD, newName);
624+
return newName;
625+
}
626+
618627
public String addApplicationFolder(String appName, String appPath)
619628
throws WLSDeployArchiveIOException {
620629
final String METHOD = "addApplicationFolder";

core/src/main/python/discover.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -219,21 +219,21 @@ def __process_domain_home(arg_map, wlst_mode):
219219
arg_map[CommandLineArgUtil.DOMAIN_HOME_SWITCH] = full_path
220220

221221

222-
def __discover(model_context, aliases, credential_injector, helper):
222+
def __discover(model_context, aliases, credential_injector, helper, extra_tokens):
223223
"""
224224
Populate the model from the domain.
225225
:param model_context: the model context
226226
:param aliases: aliases instance for discover
227227
:param credential_injector: credential injector instance
228228
:param helper: wlst_helper instance
229+
:param extra_tokens: dictionary to store non-credential tokens during credential search
229230
:return: the fully-populated model
230231
:raises DiscoverException: if an error occurred while discover the domain
231232
"""
232233
_method_name = '__discover'
233234
model = Model()
234235
base_location = LocationContext()
235236
__connect_to_domain(model_context, helper)
236-
237237
try:
238238
_add_domain_name(base_location, aliases, helper)
239239
DomainInfoDiscoverer(model_context, model.get_model_domain_info(), base_location, wlst_mode=__wlst_mode,
@@ -243,7 +243,8 @@ def __discover(model_context, aliases, credential_injector, helper):
243243
ResourcesDiscoverer(model_context, model.get_model_resources(), base_location, wlst_mode=__wlst_mode,
244244
aliases=aliases, credential_injector=credential_injector).discover()
245245
DeploymentsDiscoverer(model_context, model.get_model_app_deployments(), base_location, wlst_mode=__wlst_mode,
246-
aliases=aliases, credential_injector=credential_injector).discover()
246+
aliases=aliases, credential_injector=credential_injector,
247+
extra_tokens=extra_tokens).discover()
247248
__discover_multi_tenant(model, model_context, base_location, aliases, credential_injector)
248249
except AliasException, ae:
249250
wls_version = WebLogicHelper(__logger).get_actual_weblogic_version()
@@ -448,14 +449,15 @@ def __persist_model(model, model_context):
448449
__logger.exiting(class_name=_class_name, method_name=_method_name)
449450

450451

451-
def __check_and_customize_model(model, model_context, aliases, credential_injector):
452+
def __check_and_customize_model(model, model_context, aliases, credential_injector, extra_tokens):
452453
"""
453454
Customize the model dictionary before persisting. Validate the model after customization for informational
454455
purposes. Any validation errors will not stop the discovered model to be persisted.
455456
:param model: completely discovered model, before any tokenization
456457
:param model_context: configuration from command-line
457458
:param aliases: used for validation if model changes are made
458459
:param credential_injector: injector created to collect and tokenize credentials, possibly None
460+
:param extra_tokens: dictionary to handle non-credential tokenized arguments
459461
"""
460462
_method_name = '__check_and_customize_model'
461463
__logger.entering(class_name=_class_name, method_name=_method_name)
@@ -482,9 +484,12 @@ def __check_and_customize_model(model, model_context, aliases, credential_inject
482484

483485
# Apply the injectors specified in model_variable_injector.json, or in the target configuration.
484486
# Include the variable mappings that were collected in credential_cache.
487+
485488
variable_injector = VariableInjector(_program_name, model.get_model(), model_context,
486489
WebLogicHelper(__logger).get_actual_weblogic_version(), credential_cache)
487490

491+
variable_injector.add_to_cache(dictionary=extra_tokens)
492+
488493
inserted, variable_model, variable_file_name = variable_injector.inject_variables_keyword_file()
489494

490495
if inserted:
@@ -579,10 +584,11 @@ def main(model_context):
579584
else:
580585
__logger.info('WLSDPLY-06024', class_name=_class_name, method_name=_method_name)
581586

587+
extra_tokens = {}
582588
try:
583-
model = __discover(model_context, aliases, credential_injector, helper)
589+
model = __discover(model_context, aliases, credential_injector, helper, extra_tokens)
584590

585-
model = __check_and_customize_model(model, model_context, aliases, credential_injector)
591+
model = __check_and_customize_model(model, model_context, aliases, credential_injector, extra_tokens)
586592

587593
__remote_report(model_context)
588594
except DiscoverException, ex:

core/src/main/python/wlsdeploy/aliases/model_constants.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@
192192
MESSAGE_LOGGING_PARAMS = 'MessageLoggingParams'
193193
MESSAGING_BRIDGE = 'MessagingBridge'
194194
METHOD = 'Method'
195+
MODULE_TYPE = 'ModuleType'
195196
MULTICAST = 'Multicast'
196197
MULTICAST_ADDRESS = 'MulticastAddress'
197198
MULTICAST_PORT = 'MulticastPort'
@@ -287,6 +288,7 @@
287288
STORE = 'Store'
288289
SUB_DEPLOYMENT = 'SubDeployment'
289290
SUB_DEPLOYMENT_NAME = 'SubDeploymentName'
291+
SUB_MODULE_TARGETS = 'subModuleTargets'
290292
SYSTEM_COMPONENT = 'SystemComponent'
291293
SYSTEM_PASSWORD_VALIDATOR = 'SystemPasswordValidator'
292294
TARGET = 'Target'

core/src/main/python/wlsdeploy/tool/deploy/applications_deployer.py

Lines changed: 74 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from wlsdeploy.aliases.model_constants import APPLICATION
2929
from wlsdeploy.aliases.model_constants import DEPLOYMENT_ORDER
3030
from wlsdeploy.aliases.model_constants import LIBRARY
31+
from wlsdeploy.aliases.model_constants import MODULE_TYPE
3132
from wlsdeploy.aliases.model_constants import PARTITION
3233
from wlsdeploy.aliases.model_constants import PLAN_DIR
3334
from wlsdeploy.aliases.model_constants import PLAN_PATH
@@ -38,6 +39,8 @@
3839
from wlsdeploy.aliases.model_constants import SECURITY_DD_MODEL
3940
from wlsdeploy.aliases.model_constants import SOURCE_PATH
4041
from wlsdeploy.aliases.model_constants import STAGE_MODE
42+
from wlsdeploy.aliases.model_constants import SUB_DEPLOYMENT
43+
from wlsdeploy.aliases.model_constants import SUB_MODULE_TARGETS
4144
from wlsdeploy.aliases.model_constants import TARGET
4245
from wlsdeploy.aliases.model_constants import TARGETS
4346
from wlsdeploy.aliases.wlst_modes import WlstModes
@@ -48,6 +51,9 @@
4851
from wlsdeploy.util import dictionary_utils
4952
from wlsdeploy.util import model_helper
5053
from wlsdeploy.util import string_utils
54+
from wlsdeploy.tool.util import appmodule_helper
55+
56+
import wlsdeploy.util.variables as variables
5157

5258

5359
class ApplicationsDeployer(Deployer):
@@ -192,17 +198,23 @@ def __add_applications(self):
192198
self.logger.throwing(ex, class_name=self._class_name, method_name=_method_name)
193199
raise ex
194200

201+
module_type = dictionary_utils.get_element(application, MODULE_TYPE)
195202

196203
application_name = \
197-
self.version_helper.get_application_versioned_name(app_source_path, application_name)
204+
self.version_helper.get_application_versioned_name(app_source_path, application_name,
205+
module_type=module_type)
198206

199207
quoted_application_name = self.wlst_helper.get_quoted_name_for_wlst(application_name)
208+
200209
application_location.add_name_token(application_token, quoted_application_name)
201210

202211
self.wlst_helper.cd(root_path)
203212
deployer_utils.create_and_cd(application_location, existing_applications, self.aliases)
213+
204214
self._set_attributes_and_add_subfolders(application_location, application)
215+
205216
application_location.remove_name_token(application_token)
217+
self.__substitute_appmodule_token(app_source_path, module_type)
206218

207219
if app_source_path.startswith(WLSDeployArchive.ARCHIVE_STRUCT_APPS_TARGET_DIR):
208220
plan_dir = dictionary_utils.get_element(application, PLAN_DIR)
@@ -211,6 +223,34 @@ def __add_applications(self):
211223

212224
self.logger.exiting(class_name=self._class_name, method_name=_method_name)
213225

226+
def __substitute_appmodule_token(self, path, module_type):
227+
# we need to substitute any token in the app module xml file
228+
if self.version_helper.is_module_type_app_module(module_type):
229+
if os.path.isabs(path):
230+
abspath = path
231+
else:
232+
abspath = self.model_context.get_domain_home() + os.sep + path
233+
234+
original_variables = {}
235+
variable_file = self.model_context.get_variable_file()
236+
if variable_file is not None and os.path.exists(variable_file):
237+
original_variables = variables.load_variables(variable_file)
238+
239+
fh = open(abspath, 'r')
240+
text = fh.read()
241+
fh.close()
242+
newtext = variables.substitute_value(text, original_variables, self.model_context)
243+
# only jdbc and jms for now
244+
if module_type == 'jdbc':
245+
newtext = appmodule_helper.process_jdbc_appmodule_xml(newtext, self.model_context)
246+
elif module_type == 'jms':
247+
newtext = appmodule_helper.process_jms_appmodule_xml(newtext, self.model_context)
248+
249+
newfh = open(abspath, 'w')
250+
newfh.write(newtext)
251+
newfh.close()
252+
253+
214254
def __online_deploy_apps_and_libs(self, base_location):
215255
"""
216256
Deploy shared libraries and applications in online mode.
@@ -937,7 +977,8 @@ def __deploy_model_libraries(self, model_libs, lib_location):
937977
plan_file = dictionary_utils.get_element(lib_dict, PLAN_PATH)
938978
targets = dictionary_utils.get_element(lib_dict, TARGET)
939979
stage_mode = dictionary_utils.get_element(lib_dict, STAGE_MODE)
940-
options = _get_deploy_options(model_libs, lib_name, library_module='true')
980+
options, sub_module_targets = _get_deploy_options(model_libs, lib_name, library_module='true',
981+
application_version_helper=self.version_helper)
941982
for uses_path_tokens_attribute_name in uses_path_tokens_attribute_names:
942983
if uses_path_tokens_attribute_name in lib_dict:
943984
path = lib_dict[uses_path_tokens_attribute_name]
@@ -965,7 +1006,8 @@ def __deploy_model_applications(self, model_apps, app_location, deployed_applist
9651006
plan_file = dictionary_utils.get_element(app_dict, PLAN_PATH)
9661007
stage_mode = dictionary_utils.get_element(app_dict, STAGE_MODE)
9671008
targets = dictionary_utils.get_element(app_dict, TARGET)
968-
options = _get_deploy_options(model_apps, app_name, library_module='false')
1009+
options, sub_module_targets = _get_deploy_options(model_apps, app_name, library_module='false',
1010+
application_version_helper=self.version_helper)
9691011

9701012
# any attribute with 'uses_path_tokens' may be in the archive (such as SourcePath)
9711013
for uses_path_tokens_attribute_name in uses_path_tokens_attribute_names:
@@ -977,13 +1019,19 @@ def __deploy_model_applications(self, model_apps, app_location, deployed_applist
9771019
resource_group_template_name, resource_group_name, partition_name = \
9781020
self.__get_mt_names_from_location(location)
9791021

1022+
module_type = dictionary_utils.get_element(app_dict, MODULE_TYPE)
1023+
9801024
new_app_name = self.__deploy_app_online(app_name, src_path, targets, plan=plan_file,
9811025
stage_mode=stage_mode, partition=partition_name,
9821026
resource_group=resource_group_name,
9831027
resource_group_template=resource_group_template_name,
1028+
module_type=module_type,
1029+
sub_module_targets=sub_module_targets,
9841030
options=options)
9851031
location.remove_name_token(token_name)
9861032
deployed_applist.append(new_app_name)
1033+
self.__substitute_appmodule_token(path, module_type)
1034+
9871035

9881036
def __get_mt_names_from_location(self, app_location):
9891037
dummy_location = LocationContext()
@@ -1007,7 +1055,8 @@ def __get_mt_names_from_location(self, app_location):
10071055
return resource_group_template_name, resource_group_name, partition_name
10081056

10091057
def __deploy_app_online(self, application_name, source_path, targets, stage_mode=None, plan=None, partition=None,
1010-
resource_group=None, resource_group_template=None, options=None):
1058+
resource_group=None, resource_group_template=None, sub_module_targets=None,
1059+
module_type = None, options=None):
10111060
"""
10121061
Deploy an application or shared library in online mode.
10131062
:param application_name: the name of the app or library from the model
@@ -1050,7 +1099,8 @@ def __deploy_app_online(self, application_name, source_path, targets, stage_mode
10501099
if is_library:
10511100
computed_name = self.version_helper.get_library_versioned_name(source_path, application_name)
10521101
else:
1053-
computed_name = self.version_helper.get_application_versioned_name(source_path, application_name)
1102+
computed_name = self.version_helper.get_application_versioned_name(source_path, application_name,
1103+
module_type=module_type)
10541104

10551105
application_name = computed_name
10561106

@@ -1079,6 +1129,9 @@ def __deploy_app_online(self, application_name, source_path, targets, stage_mode
10791129
kwargs[key] = value
10801130
kwargs['timeout'] = self.model_context.get_model_config().get_deploy_timeout()
10811131

1132+
if self.version_helper.is_module_type_app_module(module_type) and sub_module_targets is not None:
1133+
kwargs[SUB_MODULE_TARGETS] = sub_module_targets
1134+
10821135
self.logger.fine('WLSDPLY-09320', type_name, application_name, kwargs,
10831136
class_name=self._class_name, method_name=_method_name)
10841137
self.wlst_helper.deploy_application(application_name, *args, **kwargs)
@@ -1093,7 +1146,6 @@ def __extract_source_path_from_archive(self, source_path, model_type, model_name
10931146
:param model_name: the element name (my-app, etc.), used for logging
10941147
"""
10951148
_method_name = '__extract_source_path_from_archive'
1096-
10971149
# source path may be may be a single file (jar, war, etc.)
10981150
if self.archive_helper.contains_file(source_path):
10991151
self.archive_helper.extract_file(source_path)
@@ -1192,7 +1244,7 @@ def __start_all_apps(self, deployed_app_list, base_location):
11921244
self.__start_app(app)
11931245

11941246

1195-
def _get_deploy_options(model_apps, app_name, library_module):
1247+
def _get_deploy_options(model_apps, app_name, library_module, application_version_helper):
11961248
"""
11971249
Get the deploy command options.
11981250
:param model_apps: the apps dictionary
@@ -1202,8 +1254,8 @@ def _get_deploy_options(model_apps, app_name, library_module):
12021254
"""
12031255
deploy_options = OrderedDict()
12041256
# not sure about altDD, altWlsDD
1257+
app = dictionary_utils.get_dictionary_element(model_apps, app_name)
12051258
for option in [DEPLOYMENT_ORDER, SECURITY_DD_MODEL, PLAN_STAGING_MODE, STAGE_MODE]:
1206-
app = dictionary_utils.get_dictionary_element(model_apps, app_name)
12071259
value = dictionary_utils.get_element(app, option)
12081260

12091261
option_name = ''
@@ -1224,8 +1276,21 @@ def _get_deploy_options(model_apps, app_name, library_module):
12241276

12251277
if len(deploy_options) == 0:
12261278
deploy_options = None
1227-
return deploy_options
12281279

1280+
module_type = dictionary_utils.get_element(app, MODULE_TYPE)
1281+
sub_module_targets = ''
1282+
if application_version_helper.is_module_type_app_module(module_type):
1283+
sub_deployments = dictionary_utils.get_element(app, SUB_DEPLOYMENT)
1284+
if sub_deployments is not None:
1285+
for sub_deployment in sub_deployments:
1286+
if sub_module_targets != '':
1287+
sub_module_targets += ','
1288+
name = sub_deployment
1289+
target = sub_deployments[name][TARGET]
1290+
sub_module_targets += '%s@%s' % (name, target)
1291+
1292+
1293+
return deploy_options, sub_module_targets
12291294

12301295
def _find_deployorder_list(apps_dict, ordered_list, order):
12311296
"""

core/src/main/python/wlsdeploy/tool/deploy/applications_version_helper.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def get_library_versioned_name(self, source_path, model_name, from_archive=False
8282
self.logger.exiting(class_name=self._class_name, method_name=_method_name, result=versioned_name)
8383
return versioned_name
8484

85-
def get_application_versioned_name(self, source_path, model_name, from_archive=False):
85+
def get_application_versioned_name(self, source_path, model_name, from_archive=False, module_type=None):
8686
"""
8787
Get the proper name of the deployable application that WLST requires in the target domain.
8888
This method is needed for the case where the application is explicitly versioned in its ear/war manifest.
@@ -100,6 +100,8 @@ def get_application_versioned_name(self, source_path, model_name, from_archive=F
100100

101101
# if no manifest version is found, leave the original name unchanged
102102
versioned_name = model_name
103+
if self.is_module_type_app_module(module_type):
104+
return model_name
103105

104106
try:
105107
manifest = self.__get_manifest(source_path, from_archive)
@@ -123,6 +125,12 @@ def get_application_versioned_name(self, source_path, model_name, from_archive=F
123125
self.logger.exiting(class_name=self._class_name, method_name=_method_name, result=versioned_name)
124126
return versioned_name
125127

128+
def is_module_type_app_module(self, module_type):
129+
if module_type in [ 'jms', 'jdbc', 'wldf']:
130+
return True
131+
else:
132+
return False
133+
126134
def __get_manifest(self, source_path, from_archive):
127135
"""
128136
Returns the manifest object for the specified path.

0 commit comments

Comments
 (0)