/*
* JBoss, Home of Professional Open Source.
* Copyright 2009, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.bootstrap.impl.as.server;
import java.io.File;
import java.net.URL;
import java.util.Collections;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.jboss.bootstrap.api.as.config.JBossASBasedServerConfig;
import org.jboss.bootstrap.api.as.config.JBossASServerConfig;
import org.jboss.bootstrap.api.as.server.JBossASBasedServer;
import org.jboss.bootstrap.api.config.InvalidConfigurationException;
import org.jboss.bootstrap.api.lifecycle.LifecycleEventException;
import org.jboss.bootstrap.api.lifecycle.LifecycleEventHandler;
import org.jboss.bootstrap.api.lifecycle.LifecycleState;
import org.jboss.bootstrap.impl.as.config.JBossASBasedConfigurationValidator;
import org.jboss.bootstrap.impl.as.config.JBossASConfigurationInitializerImpl;
import org.jboss.bootstrap.impl.as.lifecycle.KernelStartEventLifecycleEventHandler;
import org.jboss.bootstrap.impl.as.lifecycle.KernelStopEventLifecycleEventHandler;
import org.jboss.bootstrap.impl.as.lifecycle.VfsInitializingLifecycleEventHandler;
import org.jboss.bootstrap.impl.mc.server.AbstractMCServerBase;
import org.jboss.bootstrap.spi.as.server.JBossASBasedServerProvider;
import org.jboss.kernel.plugins.bootstrap.basic.BasicBootstrap;
import org.jboss.logging.Logger;
import org.jboss.managed.api.annotation.ManagementComponent;
import org.jboss.managed.api.annotation.ManagementObject;
import org.jboss.managed.api.annotation.ManagementProperties;
import org.jboss.managed.api.annotation.ManagementProperty;
/**
* AbstractJBossASServerBase
*
* Base implementation of a JBossAS Server
*
* @author <a href="mailto:andrew.rubinger@jboss.org">ALR</a>
* @version $Revision: $
*/
@ManagementObject(name = AbstractJBossASServerBase.NAME_MANAGEMENT_OBJECT, isRuntime = true, properties = ManagementProperties.EXPLICIT, description = "the MCServer bootstrap view", componentType = @ManagementComponent(type = "MCBean", subtype = "*"))
public abstract class AbstractJBossASServerBase<K extends JBossASBasedServer<K, T>, T extends JBossASBasedServerConfig<T>>
extends
AbstractMCServerBase<K, T> implements JBossASBasedServerProvider<K, T>
{
//-------------------------------------------------------------------------------||
// Class Members ----------------------------------------------------------------||
//-------------------------------------------------------------------------------||
/**
* Logger
*/
private static final Logger log = Logger.getLogger(AbstractJBossASServerBase.class);
/**
* The name of the @ManagementObject for this server
*/
public static final String NAME_MANAGEMENT_OBJECT = "jboss.system:type=MCServer";
/**
* Character denoting that we're referencing an environment variable or some property
*/
private static final char CHAR_ENV_VAR = '$';
/**
* Newline character
*/
private static final char CHAR_NEWLINE = '\n';
/**
* Tab character
*/
private static final char CHAR_TAB = '\t';
//-------------------------------------------------------------------------------||
// Instance Members -------------------------------------------------------------||
//-------------------------------------------------------------------------------||
/**
* Container for version information.
*/
private final ASVersion version = ASVersion.getInstance();
/**
* The date in which the server was started.
* Must not be exported (as it's mutable). Synchronized
* on "this" (as implicit from start() lifecycle) and volatile
* so that we don't need to block in {@link AbstractJBossASServerBase#getStartDate()}
*/
private volatile Date startDate;
/**
* The optional configuration metadata for the server. No sync required as the backing
* instance is final. The mutable state must not be exported.
*/
private final Map<String, Object> metadata = new ConcurrentHashMap<String, Object>();
//-------------------------------------------------------------------------------||
// Constructors -----------------------------------------------------------------||
//-------------------------------------------------------------------------------||
/**
* Constructor
*
* Constructs a new JBossAS Server using a new default configuration,
* which will be automatically created and set
*
* @param actualClass Type of the actual class (used in casting for covarient return)
*/
public AbstractJBossASServerBase(final Class<K> actualClass) throws IllegalArgumentException
{
// Use other ctor
this(actualClass, null);
}
/**
* Constructor
*
* Constructs a new JBossAS Server with the specified underlying configuration
*
* @param actualClass Type of the actual class (used in casting for covarient return)
* @param config
*/
public AbstractJBossASServerBase(final Class<K> actualClass, final T config) throws IllegalArgumentException
{
// Invoke super
super(actualClass, config);
// Set properties
this.setValidator(new JBossASBasedConfigurationValidator<T>());
this.setServerInitializer(new JBossASServerInitializer<K, T>());
this.setConfigInitializer(new JBossASConfigurationInitializerImpl<T>());
}
//-------------------------------------------------------------------------------||
// Required Implementations -----------------------------------------------------||
//-------------------------------------------------------------------------------||
/* (non-Javadoc)
* @see org.jboss.bootstrap.impl.as.server.JBossASServer#getBuildDate()
*/
@ManagementProperty(description = "The server build date", readOnly = true)
public String getBuildDate()
{
return version.getBuildDate();
}
/* (non-Javadoc)
* @see org.jboss.bootstrap.impl.as.server.JBossASServer#getBuildID()
*/
@ManagementProperty(description = "The server build ID", readOnly = true)
public String getBuildID()
{
return version.getBuildID();
}
/* (non-Javadoc)
* @see org.jboss.bootstrap.impl.as.server.JBossASServer#getBuildJVM()
*/
@ManagementProperty(description = "The server build JVM", readOnly = true)
public String getBuildJVM()
{
return version.getBuildJVM();
}
/* (non-Javadoc)
* @see org.jboss.bootstrap.impl.as.server.JBossASServer#getBuildNumber()
*/
@ManagementProperty(description = "The server build number", readOnly = true)
public String getBuildNumber()
{
return version.getBuildNumber();
}
/* (non-Javadoc)
* @see org.jboss.bootstrap.impl.as.server.JBossASServer#getBuildOS()
*/
@ManagementProperty(description = "The server build OS", readOnly = true)
public String getBuildOS()
{
return version.getBuildOS();
}
/* (non-Javadoc)
* @see org.jboss.bootstrap.impl.as.server.JBossASServer#getStartDate()
*/
@ManagementProperty(description = "The server start time", readOnly = true)
public Date getStartDate()
{
// We copy so we don't export the mutable state, JBBOOT-73
final Date copyDate = (Date) startDate.clone();
return copyDate;
}
/* (non-Javadoc)
* @see org.jboss.bootstrap.impl.as.server.JBossASServer#getVersion()
*/
@ManagementProperty(description = "The server version string", readOnly = true)
public String getVersion()
{
return version.toString();
}
/* (non-Javadoc)
* @see org.jboss.bootstrap.impl.as.server.JBossASServer#getVersionName()
*/
@ManagementProperty(description = "The server version name", readOnly = true)
public String getVersionName()
{
return version.getName();
}
/* (non-Javadoc)
* @see org.jboss.bootstrap.impl.as.server.JBossASServer#getVersionNumber()
*/
@ManagementProperty(description = "The server version number string", readOnly = true)
public String getVersionNumber()
{
return version.getVersionNumber();
}
/*
* (non-Javadoc)
* @see org.jboss.bootstrap.spi.as.server.JBossASBasedServerProvider#getMetaData()
*/
public Map<String, Object> getMetaData()
{
return Collections.unmodifiableMap(this.metadata);
}
/* (non-Javadoc)
* @see org.jboss.bootstrap.spi.as.server.JBossASServer#isStarted()
*/
/*
* JBBOOT-80 Remove this when jboss-bootstrap is for AS6 only (no
* more AS5.x support)
*/
@Deprecated
public boolean isStarted()
{
final LifecycleState state = this.getState();
return state.equals(LifecycleState.STARTED);
}
/*
* (non-Javadoc)
* @see org.jboss.bootstrap.impl.base.server.AbstractServer#initialize()
*/
@Override
protected void doInitialize() throws IllegalStateException, InvalidConfigurationException, LifecycleEventException
{
// Call Super
super.doInitialize();
// JBBOOT-68
//TODO Remove once VFS is init'd from something else
// Register an event handler to init VFS alongside server start
@SuppressWarnings("deprecation")
final LifecycleEventHandler initVfsHandler = new VfsInitializingLifecycleEventHandler();
this.registerEventHandler(initVfsHandler, LifecycleState.INITIALIZED);
// Create and Register handlers
final BasicBootstrap bootstrap = this.getBootstrap();
final LifecycleEventHandler startHandler = new KernelStartEventLifecycleEventHandler(bootstrap);
final LifecycleEventHandler stopHandler = new KernelStopEventLifecycleEventHandler(bootstrap);
this.registerEventHandler(startHandler, LifecycleState.STARTED);
this.registerEventHandler(stopHandler, LifecycleState.STOPPING);
// Log the server info
this.logServerInfo();
}
/**
* Logs out information from the underlying server configuration
*/
protected void logServerInfo()
{
// Initialize
final StringBuilder sb = new StringBuilder();
final char newline = CHAR_NEWLINE;
final char tab = CHAR_TAB;
// Get the config
final T config = this.getConfiguration();
if (config.getJBossHome() != null)
{
final String jbossHome = config.getJBossHome().toExternalForm();
sb.append("Server Configuration:");
sb.append(newline).append(newline).append(tab);
sb.append("JBOSS_HOME URL: " + jbossHome);
sb.append(newline).append(tab);
sb.append("Bootstrap: " + getRelativePath(jbossHome, config.getBootstrapUrl()));
sb.append(newline).append(tab);
sb.append("Common Base: " + getRelativePath(jbossHome, config.getCommonBaseLocation()));
sb.append(newline).append(tab);
sb.append("Common Library: " + getRelativePath(jbossHome, config.getCommonLibLocation()));
sb.append(newline).append(tab);
sb.append("Server Name: " + config.getServerName());
sb.append(newline).append(tab);
sb.append("Server Base: " + getRelativePath(jbossHome, config.getServerBaseLocation()));
sb.append(newline).append(tab);
sb.append("Server Library: " + getRelativePath(jbossHome, config.getServerLibLocation()));
sb.append(newline).append(tab);
sb.append("Server Config: " + getRelativePath(jbossHome, config.getServerConfLocation()));
sb.append(newline).append(tab);
sb.append("Server Home: " + getRelativePath(jbossHome, config.getServerHomeLocation()));
sb.append(newline).append(tab);
sb.append("Server Data: " + getRelativePath(jbossHome, config.getServerDataLocation()));
sb.append(newline).append(tab);
sb.append("Server Log: " + getRelativePath(jbossHome, config.getServerLogLocation()));
sb.append(newline).append(tab);
sb.append("Server Temp: " + getRelativePath(jbossHome, config.getServerTempLocation()));
sb.append(newline);
// Log
log.info(sb.toString());
}
}
/**
* Helper method to remove make configuration URLs relative in the logs [JBBOOT-86]
*/
private static String getRelativePath(final String jbossHome, final URL url)
{
if (url == null)
{
return "Not defined";
}
String urlString = url.toExternalForm();
if (urlString.startsWith(jbossHome))
{
urlString = CHAR_ENV_VAR + JBossASServerConfig.ENV_VAR_JBOSSAS_HOME + File.separatorChar
+ urlString.substring(jbossHome.length());
return urlString;
}
return url.toExternalForm();
}
//-------------------------------------------------------------------------------||
// Overridden Implementations ---------------------------------------------------||
//-------------------------------------------------------------------------------||
/* (non-Javadoc)
* @see org.jboss.bootstrap.impl.mc.server.AbstractMCServerBase#doStart()
*/
@Override
protected void doStart() throws Exception
{
// Call super
super.doStart();
// Mark the start date
this.setStartDate(new Date());
}
//-------------------------------------------------------------------------------||
// Accessors / Mutators ---------------------------------------------------------||
//-------------------------------------------------------------------------------||
/**
* @param startDate the startDate to set
*/
protected void setStartDate(final Date startDate)
{
// Clone so we don't give callers access to internal state
this.startDate = (Date) startDate.clone();
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("JBossAS [");
sb.append(this.version.toString());
sb.append("]");
return sb.toString();
}
}