All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.netbeans.modules.glassfish.common.BasicTask Maven / Gradle / Ivy

There is a newer version: RELEASE240
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.netbeans.modules.glassfish.common;

import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.netbeans.modules.glassfish.tooling.GlassFishStatus;
import static org.netbeans.modules.glassfish.tooling.GlassFishStatus.OFFLINE;
import static org.netbeans.modules.glassfish.tooling.GlassFishStatus.ONLINE;
import static org.netbeans.modules.glassfish.tooling.GlassFishStatus.SHUTDOWN;
import static org.netbeans.modules.glassfish.tooling.GlassFishStatus.STARTUP;
import org.netbeans.modules.glassfish.tooling.TaskEvent;
import org.netbeans.modules.glassfish.tooling.TaskState;
import org.netbeans.modules.glassfish.tooling.TaskStateListener;
import org.netbeans.modules.glassfish.tooling.data.GlassFishServer;
import org.netbeans.modules.glassfish.tooling.data.GlassFishStatusTask;
import org.netbeans.modules.glassfish.common.status.WakeUpStateListener;
import org.netbeans.modules.glassfish.spi.GlassfishModule;
import org.openide.util.NbBundle;

/**
 * Basic common functionality of commands execution.
 * 

* @author Peter Williams, Tomas Kraus */ public abstract class BasicTask implements Callable { //////////////////////////////////////////////////////////////////////////// // Inner classes // //////////////////////////////////////////////////////////////////////////// /** * Notification about server state check results while waiting for server * to start. *

* Handles initial period of time after starting server. * At least port checks are being executed periodically so this class will * be called back in any situation. */ protected static class StartStateListener extends WakeUpStateListener { //////////////////////////////////////////////////////////////////////// // Instance attributes // //////////////////////////////////////////////////////////////////////// /** Is server starting in profiling mode? */ private final boolean profile; /** GlassFish process being started. */ private volatile Process process; //////////////////////////////////////////////////////////////////////// // Constructors // //////////////////////////////////////////////////////////////////////// /** * Constructs an instance of state check results notification. *

* @param profile Server is starting in profiling mode when * true. */ protected StartStateListener(final boolean profile) { super(); this.profile = profile; this.process = null; } //////////////////////////////////////////////////////////////////////// // Getters and setters // //////////////////////////////////////////////////////////////////////// /** * Set GlassFish process being started. *

* @param process GlassFish process being started. */ void setProcess(final Process process) { this.process = process; } //////////////////////////////////////////////////////////////////////// // Methods // //////////////////////////////////////////////////////////////////////// /** * Callback to notify about current server status after every check * when enabled. *

* Wake up startup thread when administrator port is active * in profiling mode or when illegal state was detected. *

* @param server GlassFish server instance being monitored. * @param status Current server status. * @param task Last GlassFish server status check task details. */ @Override public void currentState(final GlassFishServer server, final GlassFishStatus status, final GlassFishStatusTask task) { switch(status) { // Consider server as ready when at least process exists // when running in profiling mode. case OFFLINE: case STARTUP: if (profile && process != null) { wakeUp(); } break; // Interrupt waiting for illegal states. case ONLINE: case SHUTDOWN: wakeUp(); break; } } } /** * Notification about server state check results while waiting for server * to shut down. *

* Handles period of time until server shuts down completely. * At least port checks are being executed periodically so this class will * be called back in any situation. */ protected static class ShutdownStateListener extends WakeUpStateListener { //////////////////////////////////////////////////////////////////////// // Constructors // //////////////////////////////////////////////////////////////////////// /** * Constructs an instance of state check results notification. */ protected ShutdownStateListener() { super(); } //////////////////////////////////////////////////////////////////////// // Methods // //////////////////////////////////////////////////////////////////////// /** * Callback to notify about current server status after every check * when enabled. *

* Wake up restart thread when server is not in SHUTDOWN * state. *

* @param server GlassFish server instance being monitored. * @param status Current server status. * @param task Last GlassFish server status check task details. */ @Override public void currentState(final GlassFishServer server, final GlassFishStatus status, final GlassFishStatusTask task) { if (status != SHUTDOWN) { wakeUp(); } } } /** * State change request data. */ protected static class StateChange { //////////////////////////////////////////////////////////////////////// // Instance attributes // //////////////////////////////////////////////////////////////////////// /** Command execution task. */ private final BasicTask task; /** New state of current command execution. */ private final TaskState result; /** Event that caused state change. */ private final TaskEvent event; /** Message bundle key. */ private final String msgKey; /** Message arguments. */ private final String[] msgArgs; //////////////////////////////////////////////////////////////////////// // Constructors // //////////////////////////////////////////////////////////////////////// /** * Constructs an instance of state change request data. *

* @param task Command execution task. * @param result New state of current command execution. * @param event Event that caused state change. * @param msgKey Message bundle key. */ protected StateChange(final BasicTask task, final TaskState result, final TaskEvent event, final String msgKey) { this.task = task; this.result = result; this.event = event; this.msgKey = msgKey; this.msgArgs = null; } /** * Constructs an instance of state change request data. *

* @param task Command execution task. * @param result New state of current command execution. * @param event Event that caused state change. * @param msgKey Message bundle key. * @param msgArgs Message arguments. */ protected StateChange(final BasicTask task, final TaskState result, final TaskEvent event, final String msgKey, final String... msgArgs) { this.task = task; this.result = result; this.event = event; this.msgKey = msgKey; this.msgArgs = msgArgs; } //////////////////////////////////////////////////////////////////////// // Methods // //////////////////////////////////////////////////////////////////////// /** * Call all registered callback listeners to inform about state change. *

* @return Passed new state of current command. */ protected TaskState fireOperationStateChanged() { return task.fireOperationStateChanged( result, event, msgKey, msgArgs); } } //////////////////////////////////////////////////////////////////////////// // Class attributes // //////////////////////////////////////////////////////////////////////////// /** Local logger. */ private static final Logger LOGGER = GlassFishLogger.get(BasicTask.class); /** Wait duration (ms) between server status checks. */ public static final int DELAY = 250; /** Maximum amount of time (in ms) to wait for server to start. */ public static final int START_TIMEOUT = 300000; /** Maximum amount of time (in ms) to wait for server to stop. */ public static final int STOP_TIMEOUT = 180000; /** Maximum amount of time (in ms) to wait for server to open debug port * during startup. */ public static final int START_ADMIN_PORT_TIMEOUT = 120000; /** Delay why waiting server to shut down (in ms). */ public static final int RESTART_DELAY = 5000; /** Port check idle (in ms). */ public static final int PORT_CHECK_IDLE = 500; /** Unit (ms) for the DELAY and START_TIMEOUT constants. */ public static final TimeUnit TIMEUNIT = TimeUnit.MILLISECONDS; //////////////////////////////////////////////////////////////////////////// // Instance attributes // //////////////////////////////////////////////////////////////////////////// /** GlassFish instance accessed in this task. */ GlassfishInstance instance; /** Callback to retrieve state changes. */ protected TaskStateListener [] stateListener; /** Name of GlassFish instance accessed in this task. */ protected String instanceName; /** Task thread when inside call method. */ protected volatile Thread taskThread; //////////////////////////////////////////////////////////////////////////// // Abstract methods // //////////////////////////////////////////////////////////////////////////// /** * Command execution is implemented as call() method in child * classes. *

* @return Command execution result. */ @Override public abstract V call(); //////////////////////////////////////////////////////////////////////////// // Constructors // //////////////////////////////////////////////////////////////////////////// /** * Constructs an instance of BasicTask class. *

* @param instance GlassFish instance accessed in this task. * @param stateListener Callback listeners used to retrieve state changes. */ protected BasicTask(GlassfishInstance instance, TaskStateListener... stateListener) { this.instance = instance; this.stateListener = stateListener; this.instanceName = instance.getProperty( GlassfishModule.DISPLAY_NAME_ATTR); this.taskThread = null; } //////////////////////////////////////////////////////////////////////////// // Methods // //////////////////////////////////////////////////////////////////////////// /** * Initialize task thread when call method is started. *

* This should be called immediately after call method * is started from inside. */ protected void setTaskThread() { taskThread = Thread.currentThread(); } /** * Clear task thread when call method is exiting. *

* This should be called when call method * is exiting. */ protected void clearTaskThread() { taskThread = null; } /** * Initialize GlassFisg server startup monitoring. *

* Creates and registers listener to monitor server status during startup. * Switches server status monitoring into startup mode. *

* @param profile Server is starting in profiling mode when * true. * @return Listener instance when server startup monitoring was successfully * initialized or null when something failed. */ protected StartStateListener prepareStartMonitoring(final boolean profile) { StartStateListener listener = new StartStateListener(profile); if (GlassFishStatus.start(instance, false, listener, GlassFishStatus.ONLINE, GlassFishStatus.SHUTDOWN)) { GlassFishStatus.addCheckListener(instance, listener); return listener; } else { GlassFishStatus.removeListener(instance, listener); return null; } } /** * Force initialization of GlassFisg server startup monitoring. *

* Creates and registers listener to monitor server status during startup. * Switches server status monitoring into startup mode. *

* @param profile Server is starting in profiling mode when * true. * @return Listener instance when server startup monitoring was successfully * initialized or null when something failed. */ protected StartStateListener forceStartMonitoring(final boolean profile) { StartStateListener listener = new StartStateListener(profile); if (GlassFishStatus.start(instance, true, listener, GlassFishStatus.OFFLINE, GlassFishStatus.ONLINE, GlassFishStatus.SHUTDOWN, GlassFishStatus.UNKNOWN)) { GlassFishStatus.addCheckListener(instance, listener); return listener; } else { return null; } } /** * Initialize GlassFisg server startup monitoring. *

* Creates and registers listener to monitor server status during shutdown. *

* @return Listener instance when server startup monitoring was successfully * initialized or null when something failed. */ protected ShutdownStateListener prepareShutdownMonitoring() { ShutdownStateListener listener = new ShutdownStateListener(); if (GlassFishStatus.addListener(instance, listener, true, GlassFishStatus.OFFLINE)) { return listener; } else { GlassFishStatus.removeListener(instance, listener); return null; } } /** * Wait for server to start up. *

* Wait until server starts. *

* @param force Force server startup mode. * @param profile Server is starting in profiling mode when * true. * @return {@see StateChange} request on failure or null on success. */ protected StateChange waitStartUp(final boolean force, final boolean profile) { StartStateListener listener = force ? forceStartMonitoring(profile) : prepareStartMonitoring(profile); if (listener == null) { return new StateChange(this, TaskState.FAILED, TaskEvent.ILLEGAL_STATE, "BasicTask.waitShutDown.listenerError", instanceName); } long start = System.currentTimeMillis(); LOGGER.log(Level.FINEST, NbBundle.getMessage(RestartTask.class, "BasicTask.waitShutDown.waitingTime", new Object[] {instanceName, Integer.toString(START_TIMEOUT)})); try { synchronized(listener) { while (!listener.isWakeUp() && (System.currentTimeMillis() - start < START_TIMEOUT)) { listener.wait(System.currentTimeMillis() - start); } } } catch (InterruptedException ie) { LOGGER.log(Level.INFO, NbBundle.getMessage(RestartTask.class, "BasicTask.waitShutDown.interruptedException", new Object[] { instance.getName(), ie.getLocalizedMessage()})); } finally { GlassFishStatus.removeListener(instance, listener); } if (!listener.isWakeUp()) { return new StateChange(this, TaskState.FAILED, TaskEvent.CMD_FAILED, "BasicTask.waitShutDown.timeout", new String[] {instanceName, Integer.toString(STOP_TIMEOUT)}); } else { return null; } } /** * Wait for server to shut down. *

* Wait until server stops. Stop server log readers. *

* @return {@see StateChange} request on failure or null on success. */ protected StateChange waitShutDown() { ShutdownStateListener listener = prepareShutdownMonitoring(); if (listener == null) { return new StateChange(this, TaskState.FAILED, TaskEvent.ILLEGAL_STATE, "BasicTask.waitShutDown.listenerError", instanceName); } long start = System.currentTimeMillis(); LOGGER.log(Level.FINEST, NbBundle.getMessage(RestartTask.class, "BasicTask.waitShutDown.waitingTime", new Object[] {instanceName, Integer.toString(STOP_TIMEOUT)})); try { synchronized(listener) { while (!listener.isWakeUp() && (System.currentTimeMillis() - start < STOP_TIMEOUT)) { listener.wait(System.currentTimeMillis() - start); } } } catch (InterruptedException ie) { LOGGER.log(Level.INFO, NbBundle.getMessage(RestartTask.class, "BasicTask.waitShutDown.interruptedException", new Object[] { instance.getName(), ie.getLocalizedMessage()})); } finally { GlassFishStatus.removeListener(instance, listener); } LogViewMgr.removeLog(instance); LogViewMgr logger = LogViewMgr.getInstance( instance.getProperty(GlassfishModule.URL_ATTR)); logger.stopReaders(); if (!listener.isWakeUp()) { return new StateChange(this, TaskState.FAILED, TaskEvent.CMD_FAILED, "BasicTask.waitShutDown.timeout", new String[] {instanceName, Integer.toString(STOP_TIMEOUT)}); } else { return null; } } /** * Call all registered callback listeners to inform about state change. *

* @param stateType New state of current command execution sent * to listeners. This value will be returned by this method. * @param resName Name of the resource to look for message. * @param args Additional arguments passed to message. * @return Passed new state of current command. */ protected final TaskState fireOperationStateChanged( TaskState stateType, TaskEvent te, String resName, String... args) { if(stateListener != null && stateListener.length > 0) { String msg = NbBundle.getMessage(BasicTask.class, resName, args); for(int i = 0; i < stateListener.length; i++) { if(stateListener[i] != null) { stateListener[i].operationStateChanged(stateType, te, msg); } } } return stateType; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy