// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- // package statement // /////////////////////// package com.netscape.cmscore.selftests; /////////////////////// // import statements // /////////////////////// import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.Hashtable; import java.util.ListIterator; import java.util.StringTokenizer; import java.util.Vector; import com.netscape.certsrv.apps.CMS; import com.netscape.certsrv.base.EBaseException; import com.netscape.certsrv.base.EPropertyNotFound; import com.netscape.certsrv.base.IConfigStore; import com.netscape.certsrv.base.ISubsystem; import com.netscape.certsrv.logging.AuditEvent; import com.netscape.certsrv.logging.ELogException; import com.netscape.certsrv.logging.ILogEventListener; import com.netscape.certsrv.logging.ILogger; import com.netscape.certsrv.selftests.EDuplicateSelfTestException; import com.netscape.certsrv.selftests.EInvalidSelfTestException; import com.netscape.certsrv.selftests.EMissingSelfTestException; import com.netscape.certsrv.selftests.ESelfTestException; import com.netscape.certsrv.selftests.ISelfTest; import com.netscape.certsrv.selftests.ISelfTestSubsystem; ////////////////////// // class definition // ////////////////////// /** * This class implements a container for self tests. *
*
* @author mharmsen
* @author thomask
* @version $Revision$, $Date$
*/
public class SelfTestSubsystem
implements ISelfTestSubsystem {
////////////////////////
// default parameters //
////////////////////////
///////////////////////
// helper parameters //
///////////////////////
//////////////////////////////////
// SelfTestSubsystem parameters //
//////////////////////////////////
@SuppressWarnings("unused")
private ISubsystem mOwner;
private IConfigStore mConfig = null;
private ILogEventListener mLogger = null;
private ILogger mErrorLogger = CMS.getLogger();
private ILogger mSignedAuditLogger = CMS.getSignedAuditLogger();
private String mRootPrefix = null;
private String mPrefix = null;
public Hashtable
*
* @param msg signed audit log message
*/
private void audit(String msg) {
// in this case, do NOT strip preceding/trailing whitespace
// from passed-in String parameters
if (mSignedAuditLogger == null) {
return;
}
mSignedAuditLogger.log(ILogger.EV_SIGNED_AUDIT,
null,
ILogger.S_SIGNED_AUDIT,
ILogger.LL_SECURITY,
msg);
}
/**
* This helper method returns the "full" property name (the corresponding
* substore name prepended in front of the plugin/parameter name). This
* method may return null.
*
*
* @param instancePrefix full name of configuration store
* @param instanceName instance name of self test
* @return fullname of this self test plugin
*/
private String getFullName(String instancePrefix,
String instanceName) {
String instanceFullName = null;
// strip preceding/trailing whitespace
// from passed-in String parameters
if (instancePrefix != null) {
instancePrefix = instancePrefix.trim();
}
if (instanceName != null) {
instanceName = instanceName.trim();
}
if ((instancePrefix != null) &&
(instancePrefix != "")) {
if ((instanceName != null) &&
(instanceName != "")) {
instanceFullName = instancePrefix
+ "."
+ instanceName;
}
} else {
instanceFullName = instanceName;
}
return instanceFullName;
}
/**
* This helper method checks to see if an instance name/value
* pair exists for the corresponding ordered list element.
*
*
* @param element owner of this subsystem
* @param instanceName instance name of self test
* @exception EMissingSelfTestException subsystem has missing name/value
*/
private void checkInstance(SelfTestOrderedInstance element)
throws EInvalidSelfTestException, EMissingSelfTestException {
String instanceFullName = null;
String instanceName = null;
String instanceValue = null;
String instancePath = PROP_CONTAINER + "." + PROP_INSTANCE;
IConfigStore instanceConfig = mConfig.getSubStore(instancePath);
instanceName = element.getSelfTestName();
if (instanceName != null) {
instanceName = instanceName.trim();
instanceFullName = getFullName(mPrefix,
instanceName);
} else {
log(mLogger,
CMS.getLogMessage(
"CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
throw new EMissingSelfTestException();
}
try {
// extract the self test plugin value(s)
instanceValue = instanceConfig.getString(instanceName);
if ((instanceValue == null) ||
(instanceValue.equals(""))) {
// self test plugin instance property name exists,
// but it contains no value(s)
log(mLogger,
CMS.getLogMessage(
"CMSCORE_SELFTESTS_PROPERTY_MISSING_VALUES",
instanceFullName));
throw new EMissingSelfTestException(instanceFullName,
instanceValue);
} else {
instanceValue = instanceValue.trim();
}
} catch (EPropertyNotFound e) {
// self test plugin instance property name is not present
log(mLogger,
CMS.getLogMessage(
"CMSCORE_SELFTESTS_PROPERTY_MISSING_NAME",
instanceFullName));
throw new EMissingSelfTestException(instanceFullName);
} catch (EBaseException e) {
// self test plugin instance EBaseException
log(mLogger,
CMS.getLogMessage(
"CMSCORE_SELFTESTS_PROPERTY_THREW_EBASEEXCEPTION",
instanceFullName,
instanceValue));
throw new EInvalidSelfTestException(instanceFullName,
instanceValue);
}
}
///////////////////////////////
// SelfTestSubsystem methods //
///////////////////////////////
//
// methods associated with the list of on demand self tests
//
/**
* List the instance names of all the self tests enabled to run on demand
* (in execution order); may return null.
*
*
* @return list of self test instance names run on demand
*/
public String[] listSelfTestsEnabledOnDemand() {
String[] mList;
int numElements = mOnDemandOrder.size();
if (numElements != 0) {
mList = new String[numElements];
} else {
return null;
}
// loop through all self test plugin instances
// specified to be executed on demand
Enumeration
*
* @param instanceName instance name of self test
* @param isCritical isCritical is either a critical failure (true) or
* a non-critical failure (false)
* @exception EInvalidSelfTestException subsystem has invalid name/value
* @exception EMissingSelfTestException subsystem has missing name/value
*/
public void enableSelfTestOnDemand(String instanceName,
boolean isCritical)
throws EInvalidSelfTestException, EMissingSelfTestException {
// strip preceding/trailing whitespace
// from passed-in String parameters
if (instanceName != null) {
instanceName = instanceName.trim();
} else {
log(mLogger,
CMS.getLogMessage(
"CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
throw new EMissingSelfTestException();
}
// loop through all self test plugin instances
// specified to be executed on demand
Enumeration
*
* @param instanceName instance name of self test
* @exception EMissingSelfTestException subsystem has missing name
*/
public void disableSelfTestOnDemand(String instanceName)
throws EMissingSelfTestException {
String instanceFullName = null;
// strip preceding/trailing whitespace
// from passed-in String parameters
if (instanceName != null) {
instanceName = instanceName.trim();
instanceFullName = getFullName(mPrefix,
instanceName);
} else {
log(mLogger,
CMS.getLogMessage(
"CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
throw new EMissingSelfTestException();
}
// loop through all self test plugin instances
// specified to be executed on demand
Enumeration
*
* @param instanceName instance name of self test
* @return true if the specified self test is enabled on demand
* @exception EMissingSelfTestException subsystem has missing name
*/
public boolean isSelfTestEnabledOnDemand(String instanceName)
throws EMissingSelfTestException {
// strip preceding/trailing whitespace
// from passed-in String parameters
if (instanceName != null) {
instanceName = instanceName.trim();
} else {
log(mLogger,
CMS.getLogMessage(
"CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
throw new EMissingSelfTestException();
}
// loop through all self test plugin instances
// specified to be executed on demand
Enumeration
*
* @param instanceName instance name of self test
* @return true if failure of the specified self test is fatal when
* it is executed on demand
* @exception EMissingSelfTestException subsystem has missing name
*/
public boolean isSelfTestCriticalOnDemand(String instanceName)
throws EMissingSelfTestException {
String instanceFullName = null;
// strip preceding/trailing whitespace
// from passed-in String parameters
if (instanceName != null) {
instanceName = instanceName.trim();
instanceFullName = getFullName(mPrefix,
instanceName);
} else {
log(mLogger,
CMS.getLogMessage(
"CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
throw new EMissingSelfTestException();
}
// loop through all self test plugin instances
// specified to be executed on demand
Enumeration
*
* @exception EMissingSelfTestException subsystem has missing name
* @exception ESelfTestException self test exception
*/
public void runSelfTestsOnDemand()
throws EMissingSelfTestException, ESelfTestException {
if (CMS.debugOn()) {
CMS.debug("SelfTestSubsystem::runSelfTestsOnDemand():"
+ " ENTERING . . .");
}
// loop through all self test plugin instances
// specified to be executed on demand
Enumeration
*
* @return list of self test instance names run at server startup
*/
public String[] listSelfTestsEnabledAtStartup() {
String[] mList;
int numElements = mStartupOrder.size();
if (numElements != 0) {
mList = new String[numElements];
} else {
return null;
}
// loop through all self test plugin instances
// specified to be executed at server startup
Enumeration
*
* @param instanceName instance name of self test
* @param isCritical isCritical is either a critical failure (true) or
* a non-critical failure (false)
* @exception EInvalidSelfTestException subsystem has invalid name/value
* @exception EMissingSelfTestException subsystem has missing name/value
*/
public void enableSelfTestAtStartup(String instanceName,
boolean isCritical)
throws EInvalidSelfTestException, EMissingSelfTestException {
// strip preceding/trailing whitespace
// from passed-in String parameters
if (instanceName != null) {
instanceName = instanceName.trim();
} else {
log(mLogger,
CMS.getLogMessage(
"CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
throw new EMissingSelfTestException();
}
// loop through all self test plugin instances
// specified to be executed at server startup
Enumeration
*
* @param instanceName instance name of self test
* @exception EMissingSelfTestException subsystem has missing name
*/
public void disableSelfTestAtStartup(String instanceName)
throws EMissingSelfTestException {
String instanceFullName = null;
// strip preceding/trailing whitespace
// from passed-in String parameters
if (instanceName != null) {
instanceName = instanceName.trim();
instanceFullName = getFullName(mPrefix,
instanceName);
} else {
log(mLogger,
CMS.getLogMessage(
"CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
throw new EMissingSelfTestException();
}
// loop through all self test plugin instances
// specified to be executed at server startup
Enumeration
*
* @param instanceName instance name of self test
* @return true if the specified self test is executed at server startup
* @exception EMissingSelfTestException subsystem has missing name
*/
public boolean isSelfTestEnabledAtStartup(String instanceName)
throws EMissingSelfTestException {
// strip preceding/trailing whitespace
// from passed-in String parameters
if (instanceName != null) {
instanceName = instanceName.trim();
} else {
log(mLogger,
CMS.getLogMessage(
"CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
throw new EMissingSelfTestException();
}
// loop through all self test plugin instances
// specified to be executed at server startup
Enumeration
*
* @param instanceName instance name of self test
* @return true if failure of the specified self test is fatal to
* server startup
* @exception EMissingSelfTestException subsystem has missing name
*/
public boolean isSelfTestCriticalAtStartup(String instanceName)
throws EMissingSelfTestException {
String instanceFullName = null;
// strip preceding/trailing whitespace
// from passed-in String parameters
if (instanceName != null) {
instanceName = instanceName.trim();
instanceFullName = getFullName(mPrefix,
instanceName);
} else {
log(mLogger,
CMS.getLogMessage(
"CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
throw new EMissingSelfTestException();
}
// loop through all self test plugin instances
// specified to be executed at server startup
Enumeration
*
*
*
* @param instanceName instance name of self test
* @return individual self test
*/
public ISelfTest getSelfTest(String instanceName) {
// strip preceding/trailing whitespace
// from passed-in String parameters
if (instanceName != null) {
instanceName = instanceName.trim();
} else {
return null;
}
// loop through all self test plugin instances
Enumeration
*
* @return ILogEventListener of this subsystem
*/
public ILogEventListener getSelfTestLogger() {
return mLogger;
}
/**
* This method represents the log interface for the self test subsystem.
*
*
* @param logger log event listener
* @param msg self test log message
*/
public void log(ILogEventListener logger, String msg) {
// in this case, do NOT strip preceding/trailing whitespace
// from passed-in String parameters
if (logger != null) {
// log the message to the "selftests.log" log
AuditEvent ev = new AuditEvent(msg);
ev.setSource(ILogger.S_OTHER);
ev.setLevel(ILogger.LL_INFO);
try {
logger.log(ev);
} catch (ELogException le) {
// log the message to the "transactions" log
mErrorLogger.log(ILogger.EV_AUDIT,
null,
ILogger.S_OTHER,
ILogger.LL_INFO,
msg + " - " + le.toString());
}
} else {
// log the message to the "transactions" log
mErrorLogger.log(ILogger.EV_AUDIT,
null,
ILogger.S_OTHER,
ILogger.LL_INFO,
msg);
}
}
/**
* Register an individual self test on the instances list AND
* on the "on demand" list (note that the specified self test
* will be appended to the end of each list).
*
*
* @param instanceName instance name of self test
* @param isCritical isCritical is either a critical failure (true) or
* a non-critical failure (false)
* @param instance individual self test
* @exception EDuplicateSelfTestException subsystem has duplicate name
* @exception EInvalidSelfTestException subsystem has invalid name/value
* @exception EMissingSelfTestException subsystem has missing name/value
*/
public void registerSelfTestOnDemand(String instanceName,
boolean isCritical,
ISelfTest instance)
throws EDuplicateSelfTestException,
EInvalidSelfTestException,
EMissingSelfTestException {
String instanceFullName = null;
// strip preceding/trailing whitespace
// from passed-in String parameters
if (instanceName != null) {
instanceName = instanceName.trim();
instanceFullName = getFullName(mPrefix,
instanceName);
} else {
log(mLogger,
CMS.getLogMessage(
"CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
throw new EMissingSelfTestException();
}
if (mSelfTestInstances.containsKey(instanceName)) {
// self test plugin instance property name is a duplicate
log(mLogger,
CMS.getLogMessage(
"CMSCORE_SELFTESTS_PROPERTY_DUPLICATE_NAME",
instanceFullName));
throw new EDuplicateSelfTestException(instanceFullName);
} else {
// append this self test plugin instance to the end of the list
mSelfTestInstances.put(instanceName, instance);
}
// register the individual self test on the "on demand" list
enableSelfTestOnDemand(instanceName, isCritical);
}
/**
* Deregister an individual self test on the instances list AND
* on the "on demand" list (note that the specified self test
* will be removed from each list).
*
*
* @param instanceName instance name of self test
* @exception EMissingSelfTestException subsystem has missing name
*/
public void deregisterSelfTestOnDemand(String instanceName)
throws EMissingSelfTestException {
String instanceFullName = null;
// strip preceding/trailing whitespace
// from passed-in String parameters
if (instanceName != null) {
instanceName = instanceName.trim();
instanceFullName = getFullName(mPrefix,
instanceName);
} else {
log(mLogger,
CMS.getLogMessage(
"CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
throw new EMissingSelfTestException();
}
// deregister the individual self test from the instances list
ISelfTest test = getSelfTest(instanceName);
if (test == null) {
// self test plugin instance property name is not present
log(mLogger,
CMS.getLogMessage(
"CMSCORE_SELFTESTS_PROPERTY_MISSING_NAME",
instanceFullName));
throw new EMissingSelfTestException(instanceFullName);
} else {
// append this self test plugin instance to the end of the list
mSelfTestInstances.remove(instanceName);
}
// deregister the individual self test from the "on demand" list
disableSelfTestOnDemand(instanceName);
}
/**
* Register an individual self test on the instances list AND
* on the "startup" list (note that the specified self test
* will be appended to the end of each list).
*
*
* @param instanceName instance name of self test
* @param isCritical isCritical is either a critical failure (true) or
* a non-critical failure (false)
* @param instance individual self test
* @exception EDuplicateSelfTestException subsystem has duplicate name
* @exception EInvalidSelfTestException subsystem has invalid name/value
* @exception EMissingSelfTestException subsystem has missing name/value
*/
public void registerSelfTestAtStartup(String instanceName,
boolean isCritical,
ISelfTest instance)
throws EDuplicateSelfTestException,
EInvalidSelfTestException,
EMissingSelfTestException {
String instanceFullName = null;
// strip preceding/trailing whitespace
// from passed-in String parameters
if (instanceName != null) {
instanceName = instanceName.trim();
instanceFullName = getFullName(mPrefix,
instanceName);
} else {
log(mLogger,
CMS.getLogMessage(
"CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
throw new EMissingSelfTestException();
}
if (mSelfTestInstances.containsKey(instanceName)) {
// self test plugin instance property name is a duplicate
log(mLogger,
CMS.getLogMessage(
"CMSCORE_SELFTESTS_PROPERTY_DUPLICATE_NAME",
instanceFullName));
throw new EDuplicateSelfTestException(instanceFullName);
} else {
// append this self test plugin instance to the end of the list
mSelfTestInstances.put(instanceName, instance);
}
// register the individual self test on the "startup" list
enableSelfTestAtStartup(instanceName, isCritical);
}
/**
* Deregister an individual self test on the instances list AND
* on the "startup" list (note that the specified self test
* will be removed from each list).
*
*
* @param instanceName instance name of self test
* @exception EMissingSelfTestException subsystem has missing name
*/
public void deregisterSelfTestAtStartup(String instanceName)
throws EMissingSelfTestException {
String instanceFullName = null;
// strip preceding/trailing whitespace
// from passed-in String parameters
if (instanceName != null) {
instanceName = instanceName.trim();
instanceFullName = getFullName(mPrefix,
instanceName);
} else {
log(mLogger,
CMS.getLogMessage(
"CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
throw new EMissingSelfTestException();
}
// deregister the individual self test from the instances list
ISelfTest test = getSelfTest(instanceName);
if (test == null) {
// self test plugin instance property name is not present
log(mLogger,
CMS.getLogMessage(
"CMSCORE_SELFTESTS_PROPERTY_MISSING_NAME",
instanceFullName));
throw new EMissingSelfTestException(instanceFullName);
} else {
// append this self test plugin instance to the end of the list
mSelfTestInstances.remove(instanceName);
}
// deregister the individual self test from the "startup" list
disableSelfTestAtStartup(instanceName);
}
////////////////////////
// ISubsystem methods //
////////////////////////
/**
* This method retrieves the name of this subsystem. This method
* may return null.
*
*
* @return identification of this subsystem
*/
public String getId() {
return ID;
}
/**
* This method sets information specific to this subsystem.
*
*
* @param id identification of this subsystem
* @exception EBaseException base CMS exception
*/
public void setId(String id)
throws EBaseException {
if (id == null) {
log(mLogger,
CMS.getLogMessage(
"CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
throw new EBaseException("id is null");
}
// nothing needs to be done
}
/**
* This method initializes this subsystem.
*
*
* @param owner owner of this subsystem
* @param config configuration store
* @exception EBaseException base CMS exception
*/
public void init(ISubsystem owner, IConfigStore config)
throws EBaseException {
if (CMS.debugOn()) {
CMS.debug("SelfTestSubsystem::init():"
+ " ENTERING . . .");
}
if (config == null) {
CMS.debug("SelfTestSubsystem::init() - config is null!");
throw new EBaseException("config is null");
}
mOwner = owner;
mConfig = config;
if ((mConfig != null) &&
(mConfig.getName() != null) &&
(mConfig.getName() != "")) {
mRootPrefix = mConfig.getName().trim();
}
int loadStatus = 0;
// NOTE: Obviously, we must load the self test logger parameters
// first, since the "selftests.log" log file does not
// exist until this is accomplished!!!
////////////////////////////////////
// loggerPropertyName=loggerValue //
////////////////////////////////////
if (CMS.debugOn()) {
CMS.debug("SelfTestSubsystem::init():"
+ " loading self test logger parameters");
}
String loggerPrefix = null;
String loggerFullName = null;
String loggerName = PROP_LOGGER_CLASS;
String loggerValue = null;
// compose self test plugins logger property prefix
String loggerPath = PROP_CONTAINER + "." + PROP_LOGGER;
IConfigStore loggerConfig = mConfig.getSubStore(loggerPath);
if ((loggerConfig != null) &&
(loggerConfig.getName() != null) &&
(loggerConfig.getName() != "")) {
loggerPrefix = loggerConfig.getName().trim();
} else {
// NOTE: These messages can only be logged to the "transactions"
// log, since the "selftests.log" will not exist!
log(mLogger,
CMS.getLogMessage(
"CMSCORE_SELFTESTS_INITIALIZATION_NOTIFICATION"));
log(mLogger,
CMS.getLogMessage(
"CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
throw new EMissingSelfTestException();
}
Enumeration
*
* @exception EBaseException base CMS exception
*/
public void startup()
throws EBaseException {
// loop through all self test plugin instances
Enumeration
*/
public void shutdown() {
// reverse order of all self test plugin instances
Collection
*
* @return configuration store of this subsystem
*/
public IConfigStore getConfigStore() {
return mConfig;
}
}
*
*
* @exception EMissingSelfTestException subsystem has missing name
* @exception ESelfTestException self test exception
*/
public void runSelfTestsAtStartup()
throws EMissingSelfTestException, ESelfTestException {
String auditMessage = null;
// ensure that any low-level exceptions are reported
// to the signed audit log and stored as failures
try {
if (CMS.debugOn()) {
CMS.debug("SelfTestSubsystem::runSelfTestsAtStartup():"
+ " ENTERING . . .");
}
// loop through all self test plugin instances
// specified to be executed at server startup
Enumeration