Skip to content

Commit d3e1f2a

Browse files
Wdt 481 write restart file (#757)
* grab restart information from activate * Add restart information * write restart information to stdout and to restart file
1 parent e42cec7 commit d3e1f2a

File tree

12 files changed

+233
-7
lines changed

12 files changed

+233
-7
lines changed

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

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
/*
2-
* Copyright (c) 2017, 2020, Oracle Corporation and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2017, 2020, Oracle Corporation and/or its affiliates.
33
* Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
44
*/
55
package oracle.weblogic.deploy.util;
66

77
import java.io.ByteArrayOutputStream;
88
import java.io.File;
99
import java.io.FileInputStream;
10+
import java.io.FileNotFoundException;
1011
import java.io.FileOutputStream;
1112
import java.io.FilenameFilter;
1213
import java.io.IOException;
1314
import java.io.InputStream;
15+
import java.io.PrintWriter;
1416
import java.nio.file.Files;
1517
import java.nio.file.Paths;
1618
import java.nio.file.attribute.PosixFilePermission;
@@ -697,6 +699,26 @@ public static void extractZipFileContent(WLSDeployArchive archiveFile, String zi
697699
}
698700

699701
}
702+
703+
/**
704+
* Return a PrintWriter instance for the provided file name.
705+
* @param fileName Name of output file
706+
* @return PrintWriter instance which is automatically closed
707+
* @throws IllegalArgumentException if the file is not writable
708+
*/
709+
public static PrintWriter getPrintWriter(String fileName) {
710+
String METHOD = "getPrintWriter";
711+
validateWritableFile(fileName);
712+
try {
713+
return new PrintWriter(new File(fileName));
714+
} catch (FileNotFoundException ioe) {
715+
String message = ExceptionHelper.getMessage("WLSDPLY-01103", fileName);
716+
IllegalArgumentException iae = new IllegalArgumentException(message);
717+
LOGGER.throwing(CLASS, METHOD, iae);
718+
throw iae;
719+
}
720+
}
721+
700722
///////////////////////////////////////////////////////////////////////////
701723
// Private helper methods //
702724
///////////////////////////////////////////////////////////////////////////

core/src/main/python/deploy.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
CommandLineArgUtil.ADMIN_PASS_SWITCH,
6363
CommandLineArgUtil.USE_ENCRYPTION_SWITCH,
6464
CommandLineArgUtil.PASSPHRASE_SWITCH,
65+
CommandLineArgUtil.OUTPUT_DIR_SWITCH,
6566
CommandLineArgUtil.DISCARD_CURRENT_EDIT_SWITCH,
6667
CommandLineArgUtil.ROLLBACK_IF_RESTART_REQ_SWITCH
6768
]
@@ -160,6 +161,7 @@ def __deploy_online(model, model_context, aliases):
160161
__wlst_helper.activate(model_context.get_model_config().get_activate_timeout())
161162
if restart_required:
162163
exit_code = CommandLineArgUtil.PROG_RESTART_REQUIRED
164+
deployer_utils.list_restarts(model_context)
163165
except BundleAwareException, ex:
164166
__release_edit_session_and_disconnect()
165167
raise ex

core/src/main/python/update.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
CommandLineArgUtil.USE_ENCRYPTION_SWITCH,
6666
CommandLineArgUtil.PASSPHRASE_SWITCH,
6767
CommandLineArgUtil.ROLLBACK_IF_RESTART_REQ_SWITCH,
68+
CommandLineArgUtil.OUTPUT_DIR_SWITCH,
6869
CommandLineArgUtil.UPDATE_RCU_SCHEMA_PASS_SWITCH,
6970
CommandLineArgUtil.DISCARD_CURRENT_EDIT_SWITCH
7071
]
@@ -176,6 +177,7 @@ def __update_online(model, model_context, aliases):
176177

177178

178179
def __check_update_require_domain_restart(model_context):
180+
_method_name = '__check_update_require_domain_restart'
179181
exit_code = 0
180182
try:
181183
# First we enable the stdout again and then redirect the stdoout to a string output stream
@@ -197,6 +199,8 @@ def __check_update_require_domain_restart(model_context):
197199
__wlst_helper.activate(model_context.get_model_config().get_activate_timeout())
198200
if restart_required:
199201
exit_code = CommandLineArgUtil.PROG_RESTART_REQUIRED
202+
deployer_utils.list_restarts(model_context)
203+
200204
except BundleAwareException, ex:
201205
__release_edit_session_and_disconnect()
202206
raise ex

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

Lines changed: 152 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,33 @@
11
"""
2-
Copyright (c) 2017, 2020, Oracle Corporation and/or its affiliates. All rights reserved.
2+
Copyright (c) 2017, 2020, Oracle Corporation and/or its affiliates.
33
Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
44
"""
5+
import os
6+
57
from sets import Set
68

79
from java.io import IOException
810
from java.net import URI
911
from java.security import NoSuchAlgorithmException
1012

13+
from oracle.weblogic.deploy.deploy import DeployException
1114
from oracle.weblogic.deploy.util import FileUtils
15+
from oracle.weblogic.deploy.util import StringUtils
1216
from oracle.weblogic.deploy.util import PyWLSTException
1317
from oracle.weblogic.deploy.util import WLSDeployArchive
1418

1519
from wlsdeploy.aliases.location_context import LocationContext
20+
from wlsdeploy.aliases.model_constants import CLUSTER
21+
from wlsdeploy.aliases.model_constants import DYNAMIC_CLUSTER_SIZE
22+
from wlsdeploy.aliases.model_constants import DYNAMIC_SERVERS
1623
from wlsdeploy.aliases.model_constants import FILE_URI
1724
from wlsdeploy.aliases.model_constants import JDBC_DRIVER_PARAMS
1825
from wlsdeploy.aliases.model_constants import JDBC_RESOURCE
1926
from wlsdeploy.aliases.model_constants import JDBC_SYSTEM_RESOURCE
27+
from wlsdeploy.aliases.model_constants import SERVER
28+
from wlsdeploy.aliases.model_constants import SERVER_NAME_PREFIX
29+
from wlsdeploy.aliases.model_constants import SERVER_NAME_START_IDX
30+
from wlsdeploy.aliases.validation_codes import ValidationCodes
2031
from wlsdeploy.aliases.wlst_modes import WlstModes
2132
from wlsdeploy.exception import exception_helper
2233
from wlsdeploy.exception.expection_types import ExceptionType
@@ -415,3 +426,143 @@ def get_file_hash(file_name):
415426
raise ex
416427
_logger.exiting(class_name=_class_name, method_name=_method_name, result=result)
417428
return result
429+
430+
431+
def get_cluster_for_server(server_name, aliases):
432+
"""
433+
Get the Cluster name for the existing server name for additional information to mine for the update action.
434+
:param server_name: name of the server
435+
:param aliases: alias context instance
436+
:return: cluster name: name of the cluster the server belongs to, or None if stand-alone or server does not exist
437+
"""
438+
_method_name = 'get_cluster_for_server'
439+
_logger.entering(server_name, class_name=_class_name, method_name=_method_name)
440+
location = LocationContext()
441+
location.append_location(SERVER)
442+
name_token = aliases.get_name_token(location)
443+
location.add_name_token(name_token, server_name)
444+
attr_path = aliases.get_wlst_attributes_path(location)
445+
cluster_name = None
446+
try:
447+
_wlst_helper.cd(attr_path)
448+
cluster_name = _wlst_helper.get(CLUSTER)
449+
except DeployException, de:
450+
_logger.fine('WLSDPLY-09205', server_name, str(location), de.getLocalizedMessage,
451+
SERVER, class_name=_class_name, method_name=_method_name)
452+
_logger.exiting(result=cluster_name, class_name=_class_name, method_name=_method_name)
453+
return cluster_name
454+
455+
456+
def list_restarts(model_context):
457+
"""
458+
Get the list of restarts and save this list in format to restart.file
459+
in the -output_dirs location. If the output_dirs is not included, bypass
460+
writing to the restart file.
461+
:param model_context: instance of the tool model context
462+
"""
463+
_method_name = 'list_restarts'
464+
_logger.entering(model_context.get_output_dir(), class_name=_class_name, method_name=_method_name)
465+
restart_list = get_list_of_restarts()
466+
output_dirs = model_context.get_output_dir()
467+
if output_dirs is not None:
468+
file_name = os.path.join(output_dirs, 'restart.file')
469+
pw = FileUtils.getPrintWriter(file_name)
470+
for entry in restart_list:
471+
line = '%s:%s:%s:%s' % (entry[0], entry[1], entry[2], entry[3])
472+
_logger.finer('WLSDPLY-09208', line, class_name=_class_name, method_name=_method_name)
473+
pw.println(line)
474+
pw.close()
475+
_logger.exiting(class_name=_class_name, method_name=_method_name)
476+
477+
478+
def get_list_of_restarts():
479+
"""
480+
Return the restart checklist from the online domain instance. Log each instance of the restart checklist
481+
:return: String buffer of restart information
482+
"""
483+
_method_name = 'get_list_of_restarts'
484+
restart_list = []
485+
_wlst_helper.cd('/')
486+
cmo = _wlst_helper.get_cmo()
487+
for server in _wlst_helper.get_server_runtimes():
488+
resources = server.getPendingRestartSystemResources()
489+
is_restart = server.isRestartRequired()
490+
if len(resources) > 0 or is_restart:
491+
server_name = server.getName()
492+
cluster = server.getClusterRuntime()
493+
cluster_name = ''
494+
if cluster is not None:
495+
cluster_name = cluster.getName()
496+
prt_cluster = cluster_name
497+
if cluster_name == '':
498+
prt_cluster = 'standalone'
499+
for resource in server.getPendingRestartSystemResources():
500+
line = list()
501+
line.append(cluster_name)
502+
line.append(server_name)
503+
line.append(resource)
504+
value = cmo.lookupSystemResource(resource)
505+
res_type = ''
506+
if value is not None:
507+
res_type = value.getType()
508+
line.append(res_type)
509+
restart_list.append(line)
510+
_logger.warning('WLSDPLY-09207', resource, res_type, server_name, prt_cluster,
511+
class_name=_class_name, method_name=_method_name)
512+
if is_restart:
513+
line = list()
514+
line.append(cluster_name)
515+
line.append(server_name)
516+
line.append('')
517+
line.append('')
518+
restart_list.append(line)
519+
_logger.warning('WLSDPLY-09206', server_name, prt_cluster,
520+
class_name=_class_name, method_name=_method_name)
521+
return restart_list
522+
523+
524+
def check_if_dynamic_cluster(server_name, cluster_name, aliases):
525+
"""
526+
Determine if the server is part of a dynamic cluster.
527+
:param server_name: Name of the server to check
528+
:param cluster_name: Name of the cluster the server belongs to, or None if stand-alone
529+
:param aliases: aliases context instance
530+
:return: True if part of a dynamic cluster
531+
"""
532+
_method_name = 'check_if_dynamic_cluster'
533+
# check wls version first either here or before caller. preferably here
534+
location = LocationContext()
535+
location.append_location(CLUSTER)
536+
location.add_name_token(aliases.get_name_token(location), cluster_name)
537+
attr_path = aliases.get_wlst_attributes_path(location)
538+
539+
try:
540+
_wlst_helper.cd(attr_path)
541+
except DeployException, de:
542+
_logger.fine('WLSDPLY-09205', cluster_name, str(location), de.getLocalizedMessage,
543+
CLUSTER, class_name=_class_name, method_name=_method_name)
544+
return True
545+
location.append_location(DYNAMIC_SERVERS)
546+
location.add_name_token(aliases.get_name_token(location), cluster_name)
547+
attr_path = aliases.get_wlst_attributes_path(location)
548+
try:
549+
_wlst_helper.cd(attr_path)
550+
except DeployException:
551+
return False
552+
attr_name = aliases.get_wlst_attribute_name(location, DYNAMIC_CLUSTER_SIZE)
553+
dynamic_size = _wlst_helper.get(attr_name)
554+
attr_name = aliases.get_wlst_attribute_name(location, SERVER_NAME_PREFIX)
555+
prefix = _wlst_helper.get(attr_name)
556+
starting = 1
557+
present, __ = aliases.is_valid_model_attribute_name(location, SERVER_NAME_START_IDX)
558+
if present == ValidationCodes.VALID:
559+
attr_name = aliases.get_model_attribute_name(location, SERVER_NAME_START_IDX)
560+
starting = _wlst_helper.get(attr_name)
561+
if dynamic_size > 0 and prefix is not None and server_name.startswith(prefix):
562+
split_it = server_name.split(prefix)
563+
if len(split_it) == 2:
564+
number = StringUtils.stringToInteger(split_it[1].strip())
565+
if number is not None and starting <= number < (dynamic_size + starting):
566+
return True
567+
return False
568+

core/src/main/python/wlsdeploy/tool/discover/discoverer.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,11 +279,13 @@ def _find_names_in_folder(self, location):
279279
class_name=_class_name, method_name=_method_name)
280280
else:
281281
folder_path = self._aliases.get_wlst_list_path(location)
282-
_logger.finest('WLSDPLY-06111', folder_path, class_name=_class_name, method_name=_method_name)
282+
_logger.fine('WLSDPLY-06111', folder_path, class_name=_class_name, method_name=_method_name)
283283
if self._wlst_helper.path_exists(folder_path):
284284
self.wlst_cd(folder_path, location)
285285
names = self._wlst_helper.lsc()
286-
_logger.finest('WLSDPLY-06146', names, location, class_name=_class_name, method_name=_method_name)
286+
_logger.fine('WLSDPLY-06146', names, location, class_name=_class_name, method_name=_method_name)
287+
else:
288+
_logger.fine('Path {0} does not exist', folder_path, class_name=_class_name, method_name=_method_name)
287289
return names
288290

289291
def _find_singleton_name_in_folder(self, location):

core/src/main/python/wlsdeploy/tool/discover/topology_discoverer.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from wlsdeploy.aliases.location_context import LocationContext
1717
from wlsdeploy.aliases.model_constants import MODEL_LIST_DELIMITER
1818
from wlsdeploy.aliases.model_constants import KSS_KEYSTORE_FILE_INDICATOR
19+
from wlsdeploy.aliases.validation_codes import ValidationCodes
1920
from wlsdeploy.aliases.wlst_modes import WlstModes
2021
from wlsdeploy.exception import exception_helper
2122
from wlsdeploy.exception.expection_types import ExceptionType
@@ -772,8 +773,8 @@ def _dynamic_server(self, server, location):
772773
prefix = self._wlst_helper.get(attr_name)
773774
starting = 1
774775
present, __ = self._aliases.is_valid_model_attribute_name(location,
775-
model_constants.SERVER_NAME_PREFIX)
776-
if present:
776+
model_constants.SERVER_NAME_START_IDX)
777+
if present == ValidationCodes.VALID:
777778
attr_name = self._aliases.get_model_attribute_name(cluster_location,
778779
model_constants.SERVER_NAME_START_IDX)
779780
starting = self._wlst_helper.get(attr_name)

core/src/main/python/wlsdeploy/tool/util/wlst_helper.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -892,18 +892,20 @@ def activate(self, timeout):
892892
"""
893893
Activate changes saved during the current edit session but not yet deployed.
894894
:param timeout: Timeout for the activate command
895+
:return ActivationTaskMBean: with the state of the changes, and the server status for the activated changes
895896
:raises: Exception for the specified tool type: if a WLST error occurs
896897
"""
897898
_method_name = 'activate'
898899
self.__logger.entering(timeout, class_name=self.__class_name, method_name=_method_name)
899900
try:
900-
self.__load_global('activate')(timeout)
901+
activate_status = self.__load_global('activate')(timeout)
901902
except self.__load_global('WLSTException'), e:
902903
pwe = exception_helper.create_exception(self.__exception_type, 'WLSDPLY-00053',
903904
_format_exception(e), error=e)
904905
self.__logger.throwing(class_name=self.__class_name, method_name=_method_name, error=pwe)
905906
raise pwe
906907
self.__logger.exiting(class_name=self.__class_name, method_name=_method_name)
908+
return activate_status
907909

908910
def get_existing_object_list(self, wlst_objects_path):
909911
"""
@@ -1432,6 +1434,30 @@ def get_quoted_name_for_wlst(self, name):
14321434
self.__logger.finest('WLSDPLY-0098', class_name=self.__class_name, method_name=_method_name)
14331435
return result
14341436

1437+
def get_server_runtimes(self):
1438+
"""
1439+
Return the ServerRuntimeMBeans instances for the domain
1440+
:return: list of server runtimes
1441+
"""
1442+
return self.get_domain_runtime_service().getServerRuntimes()
1443+
1444+
def get_domain_runtime_service(self):
1445+
"""
1446+
Return the DomainRuntimeServiceMBean instance.
1447+
:return: DomainRuntimeServiceMBean for the domain
1448+
"""
1449+
_method_name = 'get_domain_runtime_service'
1450+
self.__logger.entering(class_name=self.__class_name, method_name=_method_name)
1451+
try:
1452+
drs = self.__load_global('domainRuntimeService')
1453+
except self.__load_global('WLSTException'), e:
1454+
pwe = exception_helper.create_exception(self.__exception_type, 'WLSDPLY-00127',
1455+
_format_exception(e), error=e)
1456+
self.__logger.throwing(class_name=self.__class_name, method_name=_method_name, error=pwe)
1457+
raise pwe
1458+
self.__logger.exiting(class_name=self.__class_name, method_name=_method_name, result=drs)
1459+
return drs
1460+
14351461
def __ls(self, method_name, ls_type, path=None, log_throwing=True):
14361462
"""
14371463
Private helper method shared by various API methods

core/src/main/resources/oracle/weblogic/deploy/messages/wlsdeploy_rb.properties

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ WLSDPLY-00123=Setting the server group {0} on dynamic cluster {1} failed : {2}
109109
WLSDPLY-00124=Entering is_set({0}) method
110110
WLSDPLY-00125=is_set({0}) in {1} mode failed: {2}
111111
WLSDPLY-00126=Exiting is_set({0}) method
112+
WLSDPLY-00127=Unable to load the DomainRuntimeService from the WLST globals : {0}
112113

113114

114115
###############################################################################
@@ -1005,6 +1006,7 @@ WLSDPLY_09015=Online update has been rollback because the flag rollback_if_requi
10051006
restart: {0}
10061007
WLSDPLY-09016=There are outstanding changes but -discard_current_edit has been specified, all changes have been \
10071008
discarded before processing update.
1009+
WLSDPLY-09017=Server {0} in
10081010
# wlsdeploy/tool/deploy/deployer_utils.py
10091011
WLSDPLY-09100=Existing object names are {0}
10101012
WLSDPLY-09101=Creating MBean type {1} with name {0}
@@ -1028,6 +1030,10 @@ WLSDPLY-09202=Set method {0} not implemented for attribute {1} in location {2}
10281030
WLSDPLY-09203=The model element {0} is not valid for WLS version {1}, so it will be omitted from deployment
10291031
WLSDPLY-09204=Model attribute {0} at model location {1} with value {2} references a location inside \
10301032
the archive file {3} that does not exist
1033+
WLSDPLY-09205=Unable to locate the indicated {3} {0} at location {1} : {2}
1034+
WLSDPLY-09206=Server {0} ({1}) requires a restart
1035+
WLSDPLY-09207=Domain resource {0} ({1}) on server {2} ({3}) requires a restart
1036+
WLSDPLY-09208=Formatted restart line : {0}
10311037

10321038
# wlsdeploy/tool/deploy/application_deployer.py
10331039
WLSDPLY-09300=No shared libraries found in {0} with name {1}

installer/src/main/bin/deployApps.cmd

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ ECHO [-domain_type ^<domain_type^>]
7979
ECHO [-wlst_path ^<wlst_path^>]
8080
ECHO [-rollback_if_require_restart]
8181
ECHO [-discard_current_edit]
82+
ECHO [-output_dir]
8283
ECHO [-admin_url ^<admin_url^>
8384
ECHO -admin_user ^<admin_user^>
8485
ECHO ]
@@ -118,6 +119,8 @@ ECHO rollback_if_require_restart - rollback the changes if the upda
118119
ECHO.
119120
ECHO discard_current_edit - discard all existing changes before starting update
120121
ECHO.
122+
ECHO output_dir - if present, write restart information to this directory as restart.file
123+
ECHO.
121124
ECHO The -use_encryption switch tells the program that one or more of the
122125
ECHO passwords in the model or variables files are encrypted. The program will
123126
ECHO prompt for the decryption passphrase to use to decrypt the passwords.

0 commit comments

Comments
 (0)