NIHVIVO-336 Improve the function of StartupManager and StartupStatus
This commit is contained in:
parent
65bba272df
commit
0726b3280e
2 changed files with 110 additions and 16 deletions
|
@ -18,7 +18,16 @@ import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO
|
* Instantiate and run the ServletContextListeners for Vitro, while accumulating
|
||||||
|
* messages in StartupStatus.
|
||||||
|
*
|
||||||
|
* The startup listeners are stored in a file with one full-qualified class name
|
||||||
|
* per line. Blank lines and comment lines (starting with '#') are ignored.
|
||||||
|
*
|
||||||
|
* No exception in the listeners should prevent the successful completion.
|
||||||
|
* However, an uncaught exception or a fatal error status will cause the
|
||||||
|
* StartupStatusDisplayFilter to disply the problem instead of showing the home
|
||||||
|
* page (or any other requested page).
|
||||||
*/
|
*/
|
||||||
public class StartupManager implements ServletContextListener {
|
public class StartupManager implements ServletContextListener {
|
||||||
private static final Log log = LogFactory.getLog(StartupManager.class);
|
private static final Log log = LogFactory.getLog(StartupManager.class);
|
||||||
|
@ -175,8 +184,11 @@ public class StartupManager implements ServletContextListener {
|
||||||
try {
|
try {
|
||||||
log.debug("Initializing '" + listener.getClass().getName() + "'");
|
log.debug("Initializing '" + listener.getClass().getName() + "'");
|
||||||
listener.contextInitialized(sce);
|
listener.contextInitialized(sce);
|
||||||
|
ss.listenerExecuted(listener);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
ss.fatal(listener, "Threw unexpected exception", e);
|
ss.fatal(listener, "Threw unexpected exception", e);
|
||||||
|
log.error("Listener threw fatal exception: '"
|
||||||
|
+ listener.getClass().getName() + "'", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.startup;
|
package edu.cornell.mannlib.vitro.webapp.startup;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -10,11 +12,16 @@ import javax.servlet.ServletContext;
|
||||||
import javax.servlet.ServletContextListener;
|
import javax.servlet.ServletContextListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO
|
* Accumulates a list of messages from the StartupManager, and from the context
|
||||||
|
* listeners that the run during startup.
|
||||||
*/
|
*/
|
||||||
public class StartupStatus {
|
public class StartupStatus {
|
||||||
private static final String ATTRIBUTE_NAME = "STARTUP_STATUS";
|
private static final String ATTRIBUTE_NAME = "STARTUP_STATUS";
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// static methods
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
public static StartupStatus getBean(ServletContext ctx) {
|
public static StartupStatus getBean(ServletContext ctx) {
|
||||||
StartupStatus ss;
|
StartupStatus ss;
|
||||||
|
|
||||||
|
@ -29,6 +36,10 @@ public class StartupStatus {
|
||||||
return ss;
|
return ss;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// methods to set status
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
private List<StatusItem> itemList = new ArrayList<StatusItem>();
|
private List<StatusItem> itemList = new ArrayList<StatusItem>();
|
||||||
|
|
||||||
public void info(ServletContextListener listener, String message) {
|
public void info(ServletContextListener listener, String message) {
|
||||||
|
@ -58,21 +69,22 @@ public class StartupStatus {
|
||||||
addItem(StatusItem.Level.FATAL, listener, message, cause);
|
addItem(StatusItem.Level.FATAL, listener, message, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Say that a previous fatal error prevented this listener from running. */
|
||||||
public void listenerNotExecuted(ServletContextListener listener) {
|
public void listenerNotExecuted(ServletContextListener listener) {
|
||||||
addItem(StatusItem.Level.NOT_EXECUTED, listener, "Not executed", null);
|
addItem(StatusItem.Level.NOT_EXECUTED,
|
||||||
|
listener,
|
||||||
|
"Not executed - startup was aborted by a previous fatal error.",
|
||||||
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isStartupAborted() {
|
/** Create a simple item for this listener if no other exists. */
|
||||||
|
public void listenerExecuted(ServletContextListener listener) {
|
||||||
for (StatusItem item : itemList) {
|
for (StatusItem item : itemList) {
|
||||||
if (item.level == StatusItem.Level.FATAL) {
|
if (item.getSourceName().equals(listener.getClass().getName())) {
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
addItem(StatusItem.Level.INFO, listener, "Ran successfully.", null);
|
||||||
}
|
|
||||||
|
|
||||||
public List<StatusItem> getStatusItems() {
|
|
||||||
return Collections.unmodifiableList(itemList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addItem(StatusItem.Level level, ServletContextListener source,
|
private void addItem(StatusItem.Level level, ServletContextListener source,
|
||||||
|
@ -80,22 +92,92 @@ public class StartupStatus {
|
||||||
itemList.add(new StatusItem(level, source, message, cause));
|
itemList.add(new StatusItem(level, source, message, cause));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// methods to query status
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
public boolean allClear() {
|
||||||
|
return getErrorItems().isEmpty() && getWarningItems().isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStartupAborted() {
|
||||||
|
return !getErrorItems().isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<StatusItem> getStatusItems() {
|
||||||
|
return Collections.unmodifiableList(itemList);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<StatusItem> getErrorItems() {
|
||||||
|
List<StatusItem> list = new ArrayList<StartupStatus.StatusItem>();
|
||||||
|
for (StatusItem item : itemList) {
|
||||||
|
if (item.level == StatusItem.Level.FATAL) {
|
||||||
|
list.add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<StatusItem> getWarningItems() {
|
||||||
|
List<StatusItem> list = new ArrayList<StartupStatus.StatusItem>();
|
||||||
|
for (StatusItem item : itemList) {
|
||||||
|
if (item.level == StatusItem.Level.WARNING) {
|
||||||
|
list.add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// helper classes
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
public static class StatusItem {
|
public static class StatusItem {
|
||||||
public enum Level {
|
public enum Level {
|
||||||
INFO, WARNING, FATAL, NOT_EXECUTED
|
INFO, WARNING, FATAL, NOT_EXECUTED
|
||||||
}
|
}
|
||||||
|
|
||||||
final Level level;
|
private final Level level;
|
||||||
final String sourceName;
|
private final String sourceName;
|
||||||
final String message;
|
private final String shortSourceName;
|
||||||
final Throwable cause;
|
private final String message;
|
||||||
|
private final String cause;
|
||||||
|
|
||||||
public StatusItem(Level level, ServletContextListener source,
|
public StatusItem(Level level, ServletContextListener source,
|
||||||
String message, Throwable cause) {
|
String message, Throwable cause) {
|
||||||
this.level = level;
|
this.level = level;
|
||||||
this.sourceName = source.getClass().getName();
|
this.sourceName = source.getClass().getName();
|
||||||
|
this.shortSourceName = source.getClass().getSimpleName();
|
||||||
this.message = message;
|
this.message = message;
|
||||||
this.cause = cause;
|
|
||||||
|
if (cause == null) {
|
||||||
|
this.cause = "";
|
||||||
|
} else {
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
PrintWriter pw = new PrintWriter(sw);
|
||||||
|
cause.printStackTrace(pw);
|
||||||
|
this.cause = sw.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Level getLevel() {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSourceName() {
|
||||||
|
return sourceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getShortSourceName() {
|
||||||
|
return shortSourceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCause() {
|
||||||
|
return cause;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue