3333
3434import java .io .File ;
3535import java .io .IOException ;
36+ import java .lang .System .Logger ;
37+ import java .lang .System .Logger .Level ;
3638import java .nio .file .Files ;
3739import java .time .Duration ;
3840import java .util .List ;
39- import java .util .logging . Level ;
41+ import java .util .function . Supplier ;
4042
4143import org .glassfish .api .ActionReport ;
4244import org .glassfish .api .ActionReport .ExitCode ;
5052import static com .sun .enterprise .admin .servermgmt .cli .ServerLifeSignChecker .step ;
5153import static com .sun .enterprise .universal .process .ProcessUtils .loadPid ;
5254import static com .sun .enterprise .universal .process .ProcessUtils .waitForNewPid ;
55+ import static com .sun .enterprise .universal .process .ProcessUtils .waitWhileIsAlive ;
5356import static com .sun .enterprise .util .SystemPropertyConstants .KEYSTORE_PASSWORD_DEFAULT ;
5457import static com .sun .enterprise .util .SystemPropertyConstants .MASTER_PASSWORD_ALIAS ;
5558import static com .sun .enterprise .util .SystemPropertyConstants .MASTER_PASSWORD_FILENAME ;
5659import static com .sun .enterprise .util .SystemPropertyConstants .MASTER_PASSWORD_PASSWORD ;
5760import static com .sun .enterprise .util .SystemPropertyConstants .TRUSTSTORE_FILENAME_DEFAULT ;
58- import static java .util .logging .Level .FINER ;
59- import static java .util .logging .Level .FINEST ;
61+ import static java .lang .System .Logger .Level .DEBUG ;
62+ import static java .lang .System .Logger .Level .INFO ;
63+ import static java .lang .System .Logger .Level .TRACE ;
6064
6165/**
6266 * A class that's supposed to capture all the behavior common to operation on a "local" server.
6367 *
6468 * @author Byron Nevins
6569 */
6670public abstract class LocalServerCommand extends CLICommand {
67-
71+ private static final Logger LOG = System . getLogger ( LocalServerCommand . class . getName ());
6872 private static final LocalStringsImpl I18N = new LocalStringsImpl (LocalDomainCommand .class );
6973 private ServerDirs serverDirs ;
7074
@@ -105,20 +109,24 @@ protected final HostAndPort getReachableAdminAddress(File domainXml) throws Comm
105109
106110 private HostAndPort findReachableAdminAddress (String userHost , Integer userPort , Boolean userSecure , File domainXml )
107111 throws CommandException {
112+ LOG .log (DEBUG , "findReachableAdminAddress(userHost={0}, userPort={1}, userSecure={2}, domainXml={3})" ,
113+ userHost , userPort , userSecure , domainXml );
108114 // Respect user provided values
109115 if (userHost != null && userPort != null && userSecure != null ) {
110116 HostAndPort endpoint = new HostAndPort (userHost , userPort , userSecure );
111117 return ProcessUtils .isListening (endpoint ) ? endpoint : null ;
112118 }
113119 // default: DAS always has the name "server"
114- final List <HostAndPort > xml = getAdminAddress (domainXml , "server" );
120+ final List <HostAndPort > xml = getAdminAddresses (domainXml , "server" );
115121 if (xml .isEmpty ()) {
116122 String host = userHost == null ? DEFAULT_HOSTNAME : userHost ;
117123 Integer port = userPort == null ? DEFAULT_ADMIN_PORT : userPort ;
118124 boolean secure = userSecure == null ? false : userSecure ;
119125 HostAndPort endpoint = new HostAndPort (host , port , secure );
126+ LOG .log (INFO , "Checking candidate: " + endpoint );
120127 return ProcessUtils .isListening (endpoint ) ? endpoint : null ;
121128 }
129+ LOG .log (TRACE , () -> "Checking candidates: " + xml );
122130 for (HostAndPort candidate : xml ) {
123131 final String host = userHost == null ? candidate .getHost () : userHost ;
124132 final int port = userPort == null ? candidate .getPort () : userPort ;
@@ -136,9 +144,10 @@ private HostAndPort findReachableAdminAddress(String userHost, Integer userPort,
136144 * For remote access it uses command line arguments and defaults.
137145 *
138146 * @return list of HostAndPort objects with admin server addresses. Never null.
139- * @throws CommandException in case of parsing errors
147+ * @throws IllegalStateException in case of parsing errors
140148 */
141- protected final List <HostAndPort > getAdminAddress (File domainXml , String serverName ) throws CommandException {
149+ protected final List <HostAndPort > getAdminAddresses (File domainXml , String serverName )
150+ throws IllegalStateException {
142151 if (!isLocal ()) {
143152 // We don't have any access to changes.
144153 return List .of (getUserProvidedAdminAddress ());
@@ -147,11 +156,11 @@ protected final List<HostAndPort> getAdminAddress(File domainXml, String serverN
147156 MiniXmlParser parser = new MiniXmlParser (domainXml , serverName );
148157 List <HostAndPort > addrSet = parser .getAdminAddresses ();
149158 if (addrSet .isEmpty ()) {
150- throw new CommandException (I18N .get ("NoAdminPort" ));
159+ throw new IllegalStateException (I18N .get ("NoAdminPort" ));
151160 }
152161 return addrSet ;
153162 } catch (MiniXmlParserException ex ) {
154- throw new CommandException (I18N .get ("NoAdminPortEx" , ex ), ex );
163+ throw new IllegalStateException (I18N .get ("NoAdminPortEx" , ex ), ex );
155164 }
156165 }
157166
@@ -178,7 +187,7 @@ protected final boolean isLocal() {
178187 protected final void setLocalPassword () {
179188 String pw = serverDirs == null ? null : serverDirs .getLocalPassword ();
180189 programOpts .setPassword (pw == null ? null : pw .toCharArray (), LOCAL_PASSWORD );
181- logger . finer ( ok (pw ) ? "Using local password" : "Not using local password" );
190+ LOG . log ( DEBUG , () -> ok (pw ) ? "Using local password" : "Not using local password" );
182191 }
183192
184193 protected final void unsetLocalPassword () {
@@ -220,7 +229,7 @@ protected final String readFromMasterPasswordFile() {
220229 PasswordAdapter pw = new PasswordAdapter (mpf .getAbsolutePath (), MASTER_PASSWORD_PASSWORD .toCharArray ());
221230 return pw .getPasswordForAlias (MASTER_PASSWORD_ALIAS );
222231 } catch (Exception e ) {
223- logger .log (Level .WARNING , "A master password file reading error: " + e .toString (), e );
232+ LOG .log (Level .WARNING , "A master password file reading error: " + e .toString (), e );
224233 return null ;
225234 }
226235 }
@@ -230,15 +239,15 @@ protected final boolean verifyMasterPassword(String mpv) {
230239 }
231240
232241 protected boolean loadAndVerifyKeystore (File jks , String mpv ) {
233- logger .log (FINEST , "loading keystore: " + jks );
242+ LOG .log (DEBUG , "loading keystore: " + jks );
234243 if (jks == null || mpv == null ) {
235244 return false ;
236245 }
237246 try {
238247 new KeyTool (jks , mpv .toCharArray ()).loadKeyStore ();
239248 return true ;
240249 } catch (Exception e ) {
241- logger .log (FINER , e .getMessage (), e );
250+ LOG .log (DEBUG , e .getMessage (), e );
242251 return false ;
243252 }
244253 }
@@ -268,7 +277,7 @@ protected final String getMasterPassword() throws CommandException {
268277 masterPassword = retry (countOfRetries );
269278 }
270279 }
271- logger .log (FINER , "Time spent in master password extraction: {0} ms" , (System .currentTimeMillis () - start ));
280+ LOG .log (DEBUG , "Time spent in master password extraction: " + (System .currentTimeMillis () - start ) + " ms" );
272281 return masterPassword ;
273282 }
274283
@@ -283,13 +292,13 @@ protected final boolean isThisServer(File ourDir, String directoryKey) {
283292 }
284293
285294 ourDir = getUniquePath (ourDir );
286- logger .log (FINER , "Check if server is at location {0}" , ourDir );
295+ LOG .log (DEBUG , "Check if server is at location {0}" , ourDir );
287296
288297 try {
289298 RemoteCLICommand cmd = new RemoteCLICommand ("__locations" , programOpts , env );
290299 ActionReport report = cmd .executeAndReturnActionReport (new String [] { "__locations" });
291300 String theirDirPath = report .findProperty (directoryKey );
292- logger .log (FINER , "Remote server has root directory {0}" , theirDirPath );
301+ LOG .log (DEBUG , "Remote server has root directory {0}" , theirDirPath );
293302
294303 if (ok (theirDirPath )) {
295304 File theirDir = getUniquePath (new File (theirDirPath ));
@@ -315,14 +324,14 @@ protected final Long getServerPid() {
315324 if (report .getActionExitCode () == ExitCode .SUCCESS ) {
316325 long pidFromAdmin = Long .parseLong (report .findProperty ("Pid" ));
317326 if (pidFromFile == null || !pidFromFile .equals (pidFromAdmin )) {
318- logger .log (Level .SEVERE , "PID should be the same: PID from file = " + pidFromFile
327+ LOG .log (Level .ERROR , "PID should be the same: PID from file = " + pidFromFile
319328 + ", while PID received from admin endpoint = " + pidFromAdmin );
320329 }
321330 return pidFromAdmin ;
322331 }
323332 return null ;
324333 } catch (Exception e ) {
325- logger .log (Level .SEVERE , "The server PID could not be resolved, sending PID from file: " + pidFromFile , e );
334+ LOG .log (Level .ERROR , "The server PID could not be resolved, sending PID from file: " + pidFromFile + "." , e );
326335 return pidFromFile ;
327336 }
328337 }
@@ -331,35 +340,50 @@ protected final Long getServerPid() {
331340 * Waits until server stops
332341 *
333342 * @param pid
334- * @param oldAdminAddress
343+ * @param adminAddress
335344 * @param timeout can be null
336345 * @throws CommandException if we time out.
337346 */
338- protected final void waitForStop (final Long pid , final HostAndPort oldAdminAddress , final Duration timeout )
347+ protected final void waitForStop (final Long pid , final HostAndPort adminAddress , final Duration timeout )
339348 throws CommandException {
340- logger .log (Level .FINEST , "waitForStop(pid={0}, oldAdminAddress={1}, timeout={2})" ,
341- new Object [] {pid , oldAdminAddress , timeout });
349+ LOG .log (DEBUG , "waitForStop(pid={0}, oldAdminAddress={1}, timeout={2})" , pid , adminAddress , timeout );
342350
343351 final boolean printDots = !programOpts .isTerse ();
344- final boolean stopped = pid == null || ProcessUtils .waitWhileIsAlive (pid , timeout , printDots );
345- if (!stopped ) {
346- throw new CommandException ("Timed out waiting for the server to stop." );
352+
353+ final Duration portTimeout ;
354+ if (pid == null ) {
355+ portTimeout = timeout ;
356+ } else {
357+ portTimeout = step ("Waiting for the death of the process with pid " + pid , timeout ,
358+ () -> waitWhileIsAlive (pid , timeout , printDots ));
359+ if (ProcessUtils .isAlive (pid )) {
360+ throw new CommandException ("Timed out waiting for the server process to stop." );
361+ }
362+ }
363+ if (adminAddress == null ) {
364+ return ;
347365 }
366+ LOG .log (INFO , "Waiting until admin endpoint {0} is free." , adminAddress );
367+ final boolean stopped = ProcessUtils .waitWhileListening (adminAddress ,
368+ portTimeout == null ? Duration .ofHours (1L ) : portTimeout , printDots );
369+ if (stopped ) {
370+ return ;
371+ }
372+ throw new CommandException ("Timed out waiting for the server to stop." );
348373 }
349374
350375 /**
351376 * Waits until server is running - with different pid
352377 *
353378 * @param oldPid
354379 * @param lifeSignCheck
355- * @param adminEndpoints
380+ * @param adminEndpointsSupplier
356381 * @param timeout can be null
357382 * @throws CommandException if we time out.
358383 */
359384 protected final String waitForStart (final Long oldPid , final ServerLifeSignCheck lifeSignCheck ,
360- final List <HostAndPort > adminEndpoints , final Duration timeout ) throws CommandException {
361- logger .log (Level .FINEST , "waitForStart(oldPid={0}, adminEndpoints={1}, timeout={2})" ,
362- new Object [] {oldPid , adminEndpoints , timeout });
385+ final Supplier <List <HostAndPort >> adminEndpointsSupplier , final Duration timeout ) throws CommandException {
386+ LOG .log (DEBUG , "waitForStart(oldPid={0}, adminEndpoints, timeout={1})" , oldPid , timeout );
363387
364388 final boolean printDots = !programOpts .isTerse ();
365389 final File pidFile = getServerDirs ().getPidFile ();
@@ -378,7 +402,16 @@ protected final String waitForStart(final Long oldPid, final ServerLifeSignCheck
378402 throw new CommandException (reportPidFileIssue (pidFile ));
379403 }
380404
381- logger .log (Level .INFO , () -> "Waiting until start of " + lifeSignCheck .getServerTitleAndName () + " completes." );
405+ try {
406+ resetServerDirs ();
407+ setLocalPassword ();
408+ } catch (Exception e ) {
409+ LOG .log (Level .WARNING , "The endpoint is alive, but we failed to reset the local password." , e );
410+ }
411+
412+ LOG .log (INFO , () -> "Waiting until start of " + lifeSignCheck .getServerTitleAndName () + " completes." );
413+
414+ final List <HostAndPort > adminEndpoints = adminEndpointsSupplier .get ();
382415 final ServerLifeSignChecker checker = new ServerLifeSignChecker (lifeSignCheck , pidFile , adminEndpoints , printDots );
383416 final GlassFishProcess process = GlassFishProcess .of (pid );
384417 final ServerLifeSigns signs = checker .watchStartup (process , startTimeout );
@@ -424,14 +457,14 @@ private String loadRestartLog(final File logFile ) {
424457 return null ;
425458 }
426459 try {
427- String report = "Found restart log file content: \n *********** \n "
428- + Files .readString (serverDirs .getRestartLogFile ().toPath ()) + "\n ********** \n " ;
460+ String report = "Found restart log file content: \n ########## \n "
461+ + Files .readString (serverDirs .getRestartLogFile ().toPath ()) + "\n ########## \n " ;
429462 // The log is there just to diagnose failed start phase of the restart.
430463 // We don't want to delete it if we cannot load it.
431464 logFile .delete ();
432465 return report ;
433466 } catch (IOException e ) {
434- logger .log (Level .WARNING , "Failed to read the restart log file: " + serverDirs .getRestartLogFile (), e );
467+ LOG .log (Level .WARNING , "Failed to read the restart log file: " + serverDirs .getRestartLogFile (), e );
435468 return null ;
436469 }
437470 }
@@ -448,7 +481,7 @@ protected final long getUptime() throws CommandException {
448481 throw new CommandException (I18N .get ("restart.dasNotRunning" ));
449482 }
450483
451- logger .log (FINER , "server uptime: {0}" , up_ms );
484+ LOG .log (DEBUG , () -> "Server uptime: " + up_ms + " ms" );
452485 return up_ms ;
453486 }
454487
@@ -495,7 +528,7 @@ private File getJKS() {
495528 if (mp .canRead ()) {
496529 return mp ;
497530 }
498- logger .log (FINEST , "File does not exist or is not readable: {0}" , mp );
531+ LOG .log (DEBUG , "File does not exist or is not readable: {0}" , mp );
499532 return null ;
500533 }
501534
0 commit comments