Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@ public AbstractPlugin() {
super();
}

@Override
public boolean validate() {
return true;
}

@Override
public String toString() {
return this.getClass().getSimpleName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,7 @@

public interface OptionalPlugin {

public boolean validate();
default boolean validate() {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ public Builder<T> withPlugins(List<T> plugins_) {
return this;
}

public List<T> getPlugins() {
return plugins;
}

public Builder<T> withPluginsFromClasspath() throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return withPluginsFromClasspath(null);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,49 +18,19 @@
******************************************************************************/
package step.versionmanager;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import step.core.AbstractContext;
import step.core.plugins.Plugin;
import step.framework.server.ServerPlugin;

@Plugin()
public class VersionManagerPlugin<C extends AbstractContext> implements ServerPlugin<C> {

private static final Logger logger = LoggerFactory.getLogger(VersionManagerPlugin.class);

@Override
public void serverStart(C context) throws Exception {
VersionManager versionManager = new VersionManager(context);
public void init(C context) throws Exception {
VersionManager<C> versionManager = new VersionManager<>(context);
context.put(VersionManager.class, versionManager);

versionManager.readLatestControllerLog();
versionManager.insertControllerLog();
}

@Override
public void migrateData(C context) throws Exception {

}

@Override
public void initializeData(C context) throws Exception {

}

@Override
public void afterInitializeData(C context) throws Exception {

}

@Override
public void serverStop(C context) {

}

@Override
public boolean canBeDisabled() {
return true;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -72,19 +72,17 @@ public class ControllerServer {
public static final String UI_CONTEXT_ROOT_DEFAULT_VALUE = "/";
private final String contextRoot;
private final boolean defaultServlet;
private Configuration configuration;
private final Configuration configuration;

private Server server;

private ContextHandlerCollection handlers;

private Integer port;
private final Integer port;

private static final Logger logger = LoggerFactory.getLogger(ControllerServer.class);

private ServerPlugin pluginProxy;

ControllerInitializationPlugin initPluginProxy;
private ServerPlugin<AbstractContext> pluginProxy;

private AbstractContext serverContext;

Expand Down Expand Up @@ -161,10 +159,12 @@ private void stop() {
}
stopping = true;

try {
initPluginProxy.preShutdownHook(serverContext);
} catch (Exception e) {
logger.error("Error while calling plugin pre-shutdown hooks");
if (pluginProxy != null) {
try {
pluginProxy.preShutdownHook(serverContext);
} catch (Exception e) {
logger.error("Error while calling plugin pre-shutdown hooks");
}
}
try {
server.stop();
Expand Down Expand Up @@ -192,10 +192,12 @@ private void stop() {
}
}

try {
initPluginProxy.postShutdownHook(serverContext);
} catch (Exception e) {
logger.error("Error while calling plugin post-shutdown hooks");
if (pluginProxy != null) {
try {
pluginProxy.postShutdownHook();
} catch (Exception e) {
logger.error("Error while calling plugin post-shutdown hooks");
}
}
}

Expand Down Expand Up @@ -303,24 +305,26 @@ protected void configure() {
serverContext.put(ServiceRegistrationCallback.class, serviceRegistrationCallback);
serverContext.put(Configuration.class, configuration);

//Initialization plugins check preconditions and recover
PluginManager<ControllerInitializationPlugin> initPluginManager = (new ServerPluginManager(configuration, null))
.cloneAs(ControllerInitializationPlugin.class);
initPluginProxy = initPluginManager.getProxy();
// Phase 1: scan classpath once with no moduleChecker, run checkPreconditions so that
// the providing plugin can register the ModuleChecker into the context
ServerPluginManager bootstrapManager = new ServerPluginManager(configuration, null);
pluginProxy = bootstrapManager.getProxy();

logger.info("Checking preconditions...");
initPluginProxy.checkPreconditions(serverContext);
pluginProxy.checkPreconditions(serverContext);

//module checker must be created in the checkPreconditions phase of the ControllerInitializationPlugin plugins
// Phase 2: rebuild from the already-scanned plugin list using the now-registered moduleChecker
ModuleChecker moduleChecker = serverContext.get(ModuleChecker.class);
//Create plugins manager for all plugins and add it to context (required for init phases)
ServerPluginManager serverPluginManager = new ServerPluginManager(configuration, moduleChecker);
ServerPluginManager serverPluginManager = moduleChecker != null
? bootstrapManager.rebuild(moduleChecker)
: bootstrapManager;
serverContext.put(ServerPluginManager.class, serverPluginManager);
pluginProxy = serverPluginManager.getProxy();

logger.info("Initializing...");
initPluginProxy.init(serverContext);
pluginProxy.init(serverContext);
logger.info("Recovering controller...");
initPluginProxy.recover(serverContext);
pluginProxy.recover(serverContext);

//start all plugins and init data
logger.info("Starting controller...");
Expand All @@ -333,7 +337,7 @@ protected void configure() {
pluginProxy.afterInitializeData(serverContext);

//Initialization plugins cal final steps
initPluginProxy.finalizeStart(serverContext);
pluginProxy.finalizeStart(serverContext);

//Http session management
SessionHandler s = new SessionHandler();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,117 @@

import step.core.AbstractContext;

/**
* Lifecycle interface for server plugins. Implementations are discovered automatically via
* classpath scanning and invoked by the {@link ServerPluginManager} through a proxy in a
* well-defined startup/shutdown order.
*
* <p>The startup sequence is:
* <ol>
* <li>{@link #checkPreconditions(AbstractContext)} — earliest phase; used to validate
* environment requirements or register infrastructure objects (e.g. a
* {@link step.core.plugins.ModuleChecker}) into the context before the final plugin
* set is determined.</li>
* <li>{@link #init(AbstractContext)} — main initialization phase.</li>
* <li>{@link #recover(AbstractContext)} — recovery phase, e.g. after an unclean shutdown.</li>
* <li>{@link #serverStart(AbstractContext)} — called once the server is ready to start
* accepting work.</li>
* <li>{@link #migrateData(AbstractContext)} — data migration tasks.</li>
* <li>{@link #initializeData(AbstractContext)} — initial data population.</li>
* <li>{@link #afterInitializeData(AbstractContext)} — post data initialization scripts.</li>
* <li>{@link #finalizeStart(AbstractContext)} — final step of the startup sequence.</li>
* </ol>
*
* <p>The shutdown sequence is:
* <ol>
* <li>{@link #preShutdownHook(AbstractContext)} — called before the server begins shutting down.</li>
* <li>{@link #serverStop(AbstractContext)} — called while stopping the server.</li>
* <li>{@link #postShutdownHook()} — called after the server has shut down.</li>
* </ol>
*
* <p>All methods have empty default implementations so that plugins only need to override the
* phases they participate in.
*
* @param <C> the context type passed through the lifecycle
*/
public interface ServerPlugin<C extends AbstractContext> {

public void serverStart(C context) throws Exception;
/**
* Earliest startup phase. Use this to validate preconditions or register infrastructure
* objects into the context (e.g. a {@link step.core.plugins.ModuleChecker}) that must be
* available before the final set of enabled plugins is determined.
*/
default void checkPreconditions(C context) throws Exception {
}

/**
* Main initialization phase, called after preconditions have been checked and the active
* plugin set has been finalized.
*/
default void init(C context) throws Exception {
}

/**
* Recovery phase, called after {@link #init(AbstractContext)}, e.g. to handle state left
* over from an unclean shutdown.
*/
default void recover(C context) throws Exception {
}

/**
* Called once the server is ready to start accepting work.
*/
default void serverStart(C context) throws Exception {
}

/**
* Data migration tasks, executed after {@link #serverStart(AbstractContext)}.
*/
default void migrateData(C context) throws Exception {
}

/**
* Initial data population, executed after {@link #migrateData(AbstractContext)}.
*/
default void initializeData(C context) throws Exception {
}

/**
* Post data initialization scripts, executed after {@link #initializeData(AbstractContext)}.
*/
default void afterInitializeData(C context) throws Exception {
}

public void migrateData(C context) throws Exception;
/**
* Final step of the startup sequence.
*/
default void finalizeStart(C context) throws Exception {
}

public void initializeData(C context) throws Exception;
/**
* Called before the server begins shutting down.
*/
default void preShutdownHook(C context) {
}

public void afterInitializeData(C context) throws Exception;
/**
* Called when stopping the controller
*/
default void serverStop(C context) {
}

public void serverStop(C context);
/**
* Called after the server has shut down.
*/
default void postShutdownHook() {
}

boolean canBeDisabled();
/**
* Returns {@code false} if this plugin is mandatory and must not be disabled via
* configuration or module filtering. Defaults to {@code true}.
*/
default boolean canBeDisabled() {
return true;
}

}
Loading