/* * JBoss, Home of Professional Open Source. * Copyright 2010, Red Hat, Inc., 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.as.server; import java.io.File; import java.io.IOException; import java.io.Serializable; import java.net.UnknownHostException; import java.nio.file.Path; import java.util.Arrays; import java.util.HashSet; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.UUID; import java.util.regex.Pattern; import org.jboss.as.controller.OperationFailedException; import org.jboss.as.controller.ProcessType; import org.jboss.as.controller.RunningMode; import org.jboss.as.controller.RunningModeControl; import org.jboss.as.controller.audit.ManagedAuditLogger; import org.jboss.as.controller.audit.ManagedAuditLoggerImpl; import org.jboss.as.controller.interfaces.InetAddressUtil; import org.jboss.as.controller.operations.common.ProcessEnvironment; import org.jboss.as.controller.persistence.ConfigurationFile; import org.jboss.as.network.NetworkUtils; import org.jboss.as.server.logging.ServerLogger; import org.jboss.as.version.ProductConfig; import org.jboss.modules.Module; import org.jboss.modules.ModuleIdentifier; import org.jboss.modules.ModuleLoader; import org.wildfly.common.cpu.ProcessorInfo; import org.wildfly.security.manager.WildFlySecurityManager; /** * Encapsulates the runtime environment for a server. * This is parsed when the server is initially started, a process reload reuses the server environment. * * @author Brian Stansberry * @author Mike M. Clark */ public class ServerEnvironment extends ProcessEnvironment implements Serializable { private static final long serialVersionUID = 1725061010357265545L; /** The manner in which a server can be launched */ public static enum LaunchType { /** Launched by a Host Controller in a managed domain */ DOMAIN(ProcessType.DOMAIN_SERVER), /** Launched from the command line */ STANDALONE(ProcessType.STANDALONE_SERVER), /** Launched by another process in which the server is embedded */ EMBEDDED(ProcessType.EMBEDDED_SERVER), /** Launched as a self-contained (no filesystem) server */ SELF_CONTAINED(ProcessType.SELF_CONTAINED), /** Launched by a Java EE appclient */ APPCLIENT(ProcessType.APPLICATION_CLIENT); private final ProcessType processType; LaunchType(final ProcessType processType) { this.processType = processType; } public ProcessType getProcessType() { return processType; } } // /////////////////////////////////////////////////////////////////////// // Configuration Value Identifiers // // /////////////////////////////////////////////////////////////////////// /** * Constant that holds the name of the system property for specifying the JDK extension directory paths. */ public static final String JAVA_EXT_DIRS = "java.ext.dirs"; /** * Constant that holds the name of the system property for specifying {@link #getHomeDir() the JBoss home directory}. */ public static final String HOME_DIR = "jboss.home.dir"; /** * Constant that holds the name of the system property for specifying the directory returned from * {@link #getModulesDir()}. * * <p> * Defaults to <tt><em>HOME_DIR</em>/modules</tt>/ * </p> * * <strong>This system property has no real meaning and should not be regarded as providing any sort of useful * information.</strong> The "modules" directory is the default location from which JBoss Modules looks to find * modules. However, this behavior is in no way controlled by this system property, nor is it guaranteed that * modules will be loaded from only one directory, nor is it guaranteed that the "modules" directory will be one * of the directories used. Finally, the structure and contents of any directories from which JBoss Modules loads * resources is not something available from this class. Users wishing to interact with the modular classloading * system should use the APIs provided by JBoss Modules * * * @deprecated has no useful meaning */ @Deprecated public static final String MODULES_DIR = "jboss.modules.dir"; /** * Constant that holds the name of the system property for specifying {@link #getBundlesDir() the bundles directory}. * * <p> * Defaults to <tt><em>HOME_DIR</em>/bundles</tt>/ */ public static final String BUNDLES_DIR = "jboss.bundles.dir"; /** * VFS module identifier. */ public static final String VFS_MODULE_IDENTIFIER = "org.jboss.vfs"; /** * Constant that holds the name of the system property for specifying * {@link #getServerBaseDir() the server base directory}. * * <p> * Defaults to <tt><em>HOME_DIR</em>/standalone</tt>. */ public static final String SERVER_BASE_DIR = "jboss.server.base.dir"; /** * Constant that holds the name of the system property for specifying * {@link #getServerConfigurationDir()} () the server configuration directory}. * * <p> * Defaults to <tt><em>SERVER_BASE_DIR</em>/configuration</tt> . */ public static final String SERVER_CONFIG_DIR = "jboss.server.config.dir"; /** * Constant that holds the name of the system property for specifying * {@link #getServerDataDir()} () the server data directory}. * * <p> * Defaults to <tt><em>SERVER_BASE_DIR</em>/data</tt>. */ public static final String SERVER_DATA_DIR = "jboss.server.data.dir"; /** * Constant that holds the name of the system property for specifying * {@link #getServerContentDir() the server managed content repository directory}. * * <p> * Defaults to <tt><em>SERVER_DATA_DIR</em>/content</tt>. */ public static final String SERVER_CONTENT_DIR = "jboss.server.content.dir"; /** * Deprecated variant of {@link #SERVER_CONTENT_DIR}. * * @deprecated use {@link #SERVER_CONTENT_DIR} */ @Deprecated public static final String SERVER_DEPLOY_DIR = "jboss.server.deploy.dir"; /** * Constant that holds the name of the system property for specifying * {@link #getServerLogDir() the server log directory}. * * <p> * Defaults to <tt><em>SERVER_BASE_DIR</em>/<em>log</em></tt>. */ public static final String SERVER_LOG_DIR = "jboss.server.log.dir"; /** * Constant that holds the name of the system property for specifying t * {@link #getServerTempDir() the server temp directory}. * * <p> * Defaults to <tt><em>SERVER_BASE_DIR</em>/tmp</tt> . */ public static final String SERVER_TEMP_DIR = "jboss.server.temp.dir"; /** * Common alias between domain and standalone mode. Equivalent to jboss.domain.temp.dir in a managed domain, * and jboss.server.temp.dir on a standalone server. */ public static final String CONTROLLER_TEMP_DIR = "jboss.controller.temp.dir"; /** * Constant that holds the name of the system property for specifying the node name within a cluster. */ public static final String NODE_NAME = "jboss.node.name"; /** * Constant that holds the name of the system property for specifying the name of this server instance. */ public static final String SERVER_NAME = "jboss.server.name"; /** * Constant that holds the name of the system property for specifying the local part of the name * of the host machine that this server is running on. */ public static final String HOST_NAME = "jboss.host.name"; /** * Constant that holds the name of the system property for specifying the fully-qualified name of the host * machine that this server is running on. */ public static final String QUALIFIED_HOST_NAME = "jboss.qualified.host.name"; /** * Constant that holds the name of the system property for specifying the max threads used by the bootstrap ServiceContainer. */ public static final String BOOTSTRAP_MAX_THREADS = "org.jboss.server.bootstrap.maxThreads"; /** * The default system property used to store bind address information from the command-line (-b). */ public static final String JBOSS_BIND_ADDRESS = "jboss.bind.address"; /** * Prefix for the system property used to store qualified bind address information from the command-line (-bxxx). */ public static final String JBOSS_BIND_ADDRESS_PREFIX = JBOSS_BIND_ADDRESS + "."; /** * The default system property used to store bind address information from the command-line (-b). */ public static final String JBOSS_DEFAULT_MULTICAST_ADDRESS = "jboss.default.multicast.address"; /** * The system property used to store the name of the default server configuration file. If not set, * the default domain configuration file is "standalone.xml". The default domain configuration file is only * relevant if the user does not use the {@code -c} or {@code --server-config} command line switches * to explicitly set the server configuration file. */ public static final String JBOSS_SERVER_DEFAULT_CONFIG = "jboss.server.default.config"; /** * The system property used to set the unique identifier for this server exposed via the * {@code uuid} attribute of the server's root management resource. If the property is not * set any previously persisted UUID will be used; otherwise a random UUID will be generated. */ public static final String JBOSS_SERVER_MANAGEMENT_UUID = "jboss.server.management.uuid"; /** * The system property used to indicate whether the server was configured to persist changes to the configuration * files. * * @deprecated for internal us only, may change or be removed at any time without notice */ @Deprecated public static final String JBOSS_PERSIST_SERVER_CONFIG = "jboss.server.persist.config"; protected static final String DOMAIN_BASE_DIR = "jboss.domain.base.dir"; protected static final String DOMAIN_CONFIG_DIR = "jboss.domain.config.dir"; /** Properties that cannot be set via {@link #systemPropertyUpdated(String, String)} */ private static final Set<String> ILLEGAL_PROPERTIES = new HashSet<String>(Arrays.asList(DOMAIN_BASE_DIR, DOMAIN_CONFIG_DIR, JAVA_EXT_DIRS, HOME_DIR, "modules.path", SERVER_BASE_DIR, SERVER_CONFIG_DIR, SERVER_DATA_DIR, SERVER_DEPLOY_DIR, SERVER_LOG_DIR, BOOTSTRAP_MAX_THREADS, CONTROLLER_TEMP_DIR, JBOSS_SERVER_DEFAULT_CONFIG, JBOSS_PERSIST_SERVER_CONFIG, JBOSS_SERVER_MANAGEMENT_UUID)); /** Properties that can only be set via {@link #systemPropertyUpdated(String, String)} during server boot. */ private static final Set<String> BOOT_PROPERTIES = new HashSet<String>(Arrays.asList(BUNDLES_DIR, SERVER_TEMP_DIR, NODE_NAME, SERVER_NAME, HOST_NAME, QUALIFIED_HOST_NAME)); /** Properties that we care about that were provided to the constructor (i.e. by the user via cmd line) */ private final Properties primordialProperties; /** * Properties that we care about that have been provided by the user either via cmd line or * via {@link #systemPropertyUpdated(String, String)} */ private final Properties providedProperties; /** Whether the server name has been provided via {@link #setProcessName(String)} */ private volatile boolean processNameSet; private final LaunchType launchType; private final String hostControllerName; private volatile String qualifiedHostName; private volatile String hostName; private volatile String serverName; private volatile String nodeName; private final File[] javaExtDirs; private final File homeDir; private final File modulesDir; private final File serverBaseDir; private final File serverConfigurationDir; private final ConfigurationFile serverConfigurationFile; private final File serverLogDir; private final File controllerTempDir; private volatile File serverDataDir; private volatile File serverContentDir; private volatile File serverTempDir; private volatile File bundlesDir; private final File domainBaseDir; private final File domainConfigurationDir; private final boolean standalone; private final boolean allowModelControllerExecutor; private final RunningMode initialRunningMode; private final ProductConfig productConfig; private final RunningModeControl runningModeControl; private final UUID serverUUID; private final long startTime; private final boolean startSuspended; public ServerEnvironment(final String hostControllerName, final Properties props, final Map<String, String> env, final String serverConfig, final ConfigurationFile.InteractionPolicy configInteractionPolicy, final LaunchType launchType, final RunningMode initialRunningMode, ProductConfig productConfig, boolean startSuspended) { this(hostControllerName, props, env, serverConfig, configInteractionPolicy, launchType, initialRunningMode, productConfig, System.currentTimeMillis(), startSuspended); } public ServerEnvironment(final String hostControllerName, final Properties props, final Map<String, String> env, final String serverConfig, final ConfigurationFile.InteractionPolicy configInteractionPolicy, final LaunchType launchType, final RunningMode initialRunningMode, ProductConfig productConfig) { this(hostControllerName, props, env, serverConfig, configInteractionPolicy, launchType, initialRunningMode, productConfig, System.currentTimeMillis(), false); } public ServerEnvironment(final String hostControllerName, final Properties props, final Map<String, String> env, final String serverConfig, final ConfigurationFile.InteractionPolicy configInteractionPolicy, final LaunchType launchType, final RunningMode initialRunningMode, ProductConfig productConfig, long startTime) { this(hostControllerName, props, env, serverConfig, configInteractionPolicy, launchType, initialRunningMode, productConfig, startTime, false); } public ServerEnvironment(final String hostControllerName, final Properties props, final Map<String, String> env, final String serverConfig, final ConfigurationFile.InteractionPolicy configInteractionPolicy, final LaunchType launchType, final RunningMode initialRunningMode, ProductConfig productConfig, long startTime, boolean startSuspended) { this.startSuspended = startSuspended; assert props != null; this.launchType = launchType; this.standalone = launchType != LaunchType.DOMAIN; this.initialRunningMode = initialRunningMode == null ? RunningMode.NORMAL : initialRunningMode; this.runningModeControl = new RunningModeControl(this.initialRunningMode); this.startTime = startTime; this.hostControllerName = hostControllerName; if (standalone && hostControllerName != null) { throw ServerLogger.ROOT_LOGGER.hostControllerNameNonNullInStandalone(); } if (!standalone && hostControllerName == null) { throw ServerLogger.ROOT_LOGGER.hostControllerNameNullInDomain(); } // Calculate qualified and unqualified host names, default server name, cluster node name configureQualifiedHostName(props.getProperty(QUALIFIED_HOST_NAME), props.getProperty(HOST_NAME), props, env); // Java system-wide extension dirs javaExtDirs = getFilesFromProperty(JAVA_EXT_DIRS, props); if ( launchType.equals( LaunchType.SELF_CONTAINED ) ) { homeDir = new File(WildFlySecurityManager.getPropertyPrivileged("user.dir", ".")); serverBaseDir = new File(WildFlySecurityManager.getPropertyPrivileged("user.dir", ".")); serverLogDir = new File(WildFlySecurityManager.getPropertyPrivileged("user.dir", ".")); String serverDirProp = props.getProperty(SERVER_TEMP_DIR); if(null==serverDirProp) { throw ServerLogger.ROOT_LOGGER.requiredSystemPropertyMissing(SERVER_TEMP_DIR); } serverTempDir = new File(serverDirProp); serverDataDir = serverTempDir; modulesDir = null; serverConfigurationDir = null; serverConfigurationFile = null; controllerTempDir = serverTempDir; domainBaseDir = null; domainConfigurationDir = null; WildFlySecurityManager.setPropertyPrivileged(ServerEnvironment.JBOSS_PERSIST_SERVER_CONFIG, "false"); } else { // Must have HOME_DIR homeDir = getFileFromProperty(HOME_DIR, props); if (homeDir == null) { throw ServerLogger.ROOT_LOGGER.missingHomeDirConfiguration(HOME_DIR); } if (!homeDir.exists() || !homeDir.isDirectory()) { throw ServerLogger.ROOT_LOGGER.homeDirectoryDoesNotExist(homeDir); } @SuppressWarnings("deprecation") File tmp = getFileFromProperty(MODULES_DIR, props); if (tmp == null) { tmp = new File(homeDir, "modules"); } else if (!tmp.exists() || !tmp.isDirectory()) { throw ServerLogger.ROOT_LOGGER.modulesDirectoryDoesNotExist(tmp); } modulesDir = tmp; configureBundlesDir(props.getProperty(BUNDLES_DIR), props); tmp = getFileFromProperty(SERVER_BASE_DIR, props); if (tmp == null) { tmp = new File(homeDir, standalone ? "standalone" : "domain/servers/" + serverName); } if (standalone) { if (!tmp.exists()) { throw ServerLogger.ROOT_LOGGER.serverBaseDirectoryDoesNotExist(tmp); } else if (!tmp.isDirectory()) { throw ServerLogger.ROOT_LOGGER.serverBaseDirectoryIsNotADirectory(tmp); } } else { if (tmp.exists()) { if (!tmp.isDirectory()) { throw ServerLogger.ROOT_LOGGER.serverBaseDirectoryIsNotADirectory(tmp); } } else if (!tmp.mkdirs()) { throw ServerLogger.ROOT_LOGGER.couldNotCreateServerBaseDirectory(tmp); } } serverBaseDir = tmp; tmp = getFileFromProperty(SERVER_CONFIG_DIR, props); if (tmp == null) { tmp = new File(serverBaseDir, "configuration"); } serverConfigurationDir = tmp; if (standalone && (!serverConfigurationDir.exists() || !serverConfigurationDir.isDirectory())) { throw ServerLogger.ROOT_LOGGER.configDirectoryDoesNotExist(serverConfigurationDir); } String defaultServerConfig = WildFlySecurityManager.getPropertyPrivileged(JBOSS_SERVER_DEFAULT_CONFIG, "standalone.xml"); serverConfigurationFile = standalone ? new ConfigurationFile(serverConfigurationDir, defaultServerConfig, serverConfig, configInteractionPolicy) : null; // Adds a system property to indicate whether or not the server configuration should be persisted @SuppressWarnings("deprecation") final String propertyKey = JBOSS_PERSIST_SERVER_CONFIG; WildFlySecurityManager.setPropertyPrivileged(propertyKey, Boolean.toString(configInteractionPolicy == null || !configInteractionPolicy.isReadOnly())); tmp = getFileFromProperty(SERVER_DATA_DIR, props); if (tmp == null) { tmp = new File(serverBaseDir, "data"); } serverDataDir = tmp; if (serverDataDir.exists()) { if (!serverDataDir.isDirectory()) { throw ServerLogger.ROOT_LOGGER.serverDataDirectoryIsNotDirectory(serverDataDir); } } else { if (!serverDataDir.mkdirs()) { throw ServerLogger.ROOT_LOGGER.couldNotCreateServerDataDirectory(serverDataDir); } } tmp = getFileFromProperty(SERVER_CONTENT_DIR, props); if (tmp == null) { @SuppressWarnings("deprecation") String deprecatedProp = SERVER_DEPLOY_DIR; tmp = getFileFromProperty(deprecatedProp, props); } if (tmp == null) { tmp = new File(serverDataDir, "content"); } serverContentDir = tmp; if (serverContentDir.exists()) { if (!serverContentDir.isDirectory()) { throw ServerLogger.ROOT_LOGGER.serverContentDirectoryIsNotDirectory(serverContentDir); } } else if (!serverContentDir.mkdirs()) { throw ServerLogger.ROOT_LOGGER.couldNotCreateServerContentDirectory(serverContentDir); } tmp = getFileFromProperty(SERVER_LOG_DIR, props); if (tmp == null) { tmp = new File(serverBaseDir, "log"); } if (tmp.exists()) { if (!tmp.isDirectory()) { throw ServerLogger.ROOT_LOGGER.logDirectoryIsNotADirectory(tmp); } } else if (!tmp.mkdirs()) { throw ServerLogger.ROOT_LOGGER.couldNotCreateLogDirectory(tmp); } serverLogDir = tmp; tmp = configureServerTempDir(props.getProperty(SERVER_TEMP_DIR), props); if (tmp.exists()) { if (!tmp.isDirectory()) { throw ServerLogger.ROOT_LOGGER.serverTempDirectoryIsNotADirectory(tmp); } } else if (!tmp.mkdirs()) { throw ServerLogger.ROOT_LOGGER.couldNotCreateServerTempDirectory(tmp); } tmp = getFileFromProperty(CONTROLLER_TEMP_DIR, props); if (tmp == null) { tmp = serverTempDir; } if (tmp.exists()) { if (!tmp.isDirectory()) { throw ServerLogger.ROOT_LOGGER.controllerTempDirectoryIsNotADirectory(tmp); } } else if (!tmp.mkdirs()) { throw ServerLogger.ROOT_LOGGER.couldNotCreateControllerTempDirectory(tmp); } controllerTempDir = tmp; // Optional paths for the domain mode tmp = getFileFromProperty(DOMAIN_BASE_DIR, props); if (tmp != null) { if (!tmp.exists() || !tmp.isDirectory()) { throw ServerLogger.ROOT_LOGGER.domainBaseDirDoesNotExist(tmp); } this.domainBaseDir = tmp; } else { this.domainBaseDir = null; } tmp = getFileFromProperty(DOMAIN_CONFIG_DIR, props); if (tmp != null) { if (!tmp.exists() || !tmp.isDirectory()) { throw ServerLogger.ROOT_LOGGER.domainConfigDirDoesNotExist(tmp); } this.domainConfigurationDir = tmp; } else { this.domainConfigurationDir = null; } } boolean allowExecutor = true; String maxThreads = WildFlySecurityManager.getPropertyPrivileged(BOOTSTRAP_MAX_THREADS, null); if (maxThreads != null && maxThreads.length() > 0) { try { Integer.decode(maxThreads); // Property was set to a valid value; user wishes to control core service threads allowExecutor = false; } catch(NumberFormatException ex) { ServerLogger.ROOT_LOGGER.failedToParseCommandLineInteger(BOOTSTRAP_MAX_THREADS, maxThreads); } } allowModelControllerExecutor = allowExecutor; final Path filePath = this.serverDataDir.toPath().resolve(KERNEL_DIR).resolve(UUID_FILE); UUID uuid; try { String sysPropUUID = props.getProperty(JBOSS_SERVER_MANAGEMENT_UUID); uuid = obtainProcessUUID(filePath, sysPropUUID); } catch(IOException ex) { throw ServerLogger.ROOT_LOGGER.couldNotObtainServerUuidFile(ex, filePath); } this.serverUUID = uuid; this.productConfig = productConfig; // Keep a copy of the original properties this.primordialProperties = new Properties(); copyProperties(props, primordialProperties); // Create a separate copy for tracking later changes this.providedProperties = new Properties(); copyProperties(primordialProperties, providedProperties); // Provide standard system properties for environment items WildFlySecurityManager.setPropertyPrivileged(QUALIFIED_HOST_NAME, qualifiedHostName); WildFlySecurityManager.setPropertyPrivileged(HOST_NAME, hostName); WildFlySecurityManager.setPropertyPrivileged(SERVER_NAME, serverName); WildFlySecurityManager.setPropertyPrivileged(NODE_NAME, nodeName); setPathProperty(HOME_DIR, homeDir); setPathProperty(MODULES_DIR, modulesDir); setPathProperty(SERVER_BASE_DIR, serverBaseDir); setPathProperty(SERVER_CONFIG_DIR, serverConfigurationDir); setPathProperty(SERVER_DATA_DIR, serverDataDir); setPathProperty(SERVER_DEPLOY_DIR, serverContentDir); setPathProperty(SERVER_LOG_DIR, serverLogDir); setPathProperty(SERVER_TEMP_DIR, serverTempDir); if(launchType.getProcessType() == ProcessType.DOMAIN_SERVER) { if(domainBaseDir != null) { WildFlySecurityManager.setPropertyPrivileged(DOMAIN_BASE_DIR, domainBaseDir.getAbsolutePath()); } if(domainConfigurationDir != null) { WildFlySecurityManager.setPropertyPrivileged(DOMAIN_CONFIG_DIR, domainConfigurationDir.getAbsolutePath()); } } // Register the vfs module as URLStreamHandlerFactory try { ModuleLoader bootLoader = Module.getBootModuleLoader(); Module vfsModule = bootLoader.loadModule(ModuleIdentifier.create(VFS_MODULE_IDENTIFIER)); Module.registerURLStreamHandlerFactoryModule(vfsModule); } catch (Exception ex) { ServerLogger.ROOT_LOGGER.cannotAddURLStreamHandlerFactory(ex, VFS_MODULE_IDENTIFIER); } } private void setPathProperty(String propertyName, File path) { if (this.launchType == LaunchType.SELF_CONTAINED && path == null) { return; } WildFlySecurityManager.setPropertyPrivileged(propertyName, path.getAbsolutePath()); } private static void copyProperties(Properties src, Properties dest) { for (Map.Entry<Object, Object> entry : src.entrySet()) { Object key = entry.getKey(); if (key instanceof String) { Object val = entry.getValue(); if (val == null || val instanceof String) { dest.setProperty((String) key, (String) val); } } } } void resetProvidedProperties() { // We're being reloaded, so restore state to where we were right after constructor was executed providedProperties.clear(); copyProperties(primordialProperties, providedProperties); processNameSet = false; } /** * Get the name of this server's host controller. For domain-mode servers, this is the name given in the domain configuration. For * standalone servers, which do not utilize a host controller, the value should be <code>null</code>. * * @return server's host controller name if the instance is running in domain mode, or <code>null</code> if running in standalone * mode */ @Override public String getHostControllerName() { return hostControllerName; } /** * Get the name of this server instance. For domain-mode servers, this is the name given in the domain configuration. For * standalone servers, this is the name either provided in the server configuration, or, if not given, the name specified * via {@link #SERVER_NAME system property}, or auto-detected based on {@link #getHostName()} host name}. * * @return the server name */ public String getServerName() { return serverName; } private void configureServerName(String serverName, Properties providedProperties) { if (serverName == null) { serverName = hostName; } else { providedProperties.setProperty(SERVER_NAME, serverName); // If necessary, convert jboss.domain.uuid into a UUID serverName = resolveGUID(serverName); } this.serverName = serverName; // Chain down to nodeName as serverName is the default for it configureNodeName(providedProperties.getProperty(NODE_NAME), providedProperties); } /** * Get the fully-qualified host name detected at server startup. * * @return the qualified host name */ @Override public String getQualifiedHostName() { return qualifiedHostName; } private void configureQualifiedHostName(String qualifiedHostName, String providedHostName, Properties providedProperties, Map<String, String> env) { if (qualifiedHostName == null) { // if host name is specified, don't pick a qualified host name that isn't related to it qualifiedHostName = providedHostName; if (qualifiedHostName == null) { // POSIX-like OSes including Mac should have this set qualifiedHostName = env.get("HOSTNAME"); } if (qualifiedHostName == null) { // Certain versions of Windows qualifiedHostName = env.get("COMPUTERNAME"); } if (qualifiedHostName == null) { try { qualifiedHostName = NetworkUtils.canonize(InetAddressUtil.getLocalHost().getHostName()); } catch (UnknownHostException e) { qualifiedHostName = null; } } if (qualifiedHostName != null && qualifiedHostName.matches("^\\d+\\.\\d+\\.\\d+\\.\\d+$|:")) { // IP address is not acceptable qualifiedHostName = null; } if (qualifiedHostName == null) { // Give up qualifiedHostName = "unknown-host.unknown-domain"; } else { qualifiedHostName = qualifiedHostName.trim().toLowerCase(); } } else { providedProperties.setProperty(QUALIFIED_HOST_NAME, qualifiedHostName); } this.qualifiedHostName = qualifiedHostName; // Chain down to hostName as qualifiedHostName is the default for it configureHostName(providedProperties.getProperty(HOST_NAME), providedProperties); } /** * Get the local host name detected at server startup. * * @return the local host name */ @Override public String getHostName() { return hostName; } private void configureHostName(String hostName, Properties providedProperties) { if (hostName == null) { providedProperties.remove(HOST_NAME); // Use the host part of the qualified host name final int idx = qualifiedHostName.indexOf('.'); hostName = idx == -1 ? qualifiedHostName : qualifiedHostName.substring(0, idx); } else { providedProperties.setProperty(HOST_NAME, hostName); } this.hostName = hostName; // Chain down to serverName as hostName is the default for it configureServerName(providedProperties.getProperty(SERVER_NAME), providedProperties); } /** * Get the node name used for clustering purposes. * * @return the node name */ public String getNodeName() { return nodeName; } private void configureNodeName(String nodeName, Properties providedProperties) { if (nodeName == null) { providedProperties.remove(NODE_NAME); nodeName = hostControllerName == null ? serverName : hostControllerName + ":" + serverName; } else { providedProperties.setProperty(NODE_NAME, nodeName); } this.nodeName = nodeName; } /** * Gets any Java extension directories. * * @return the java extension directories. Will not return {@code null}, but may be an empty array */ public File[] getJavaExtDirs() { return javaExtDirs.clone(); } /** * Gets the root directory for this JBoss installation. * * @return the root directory */ public File getHomeDir() { return homeDir; } /** * <strong>A filesystem location that has no real meaning and should not be regarded as providing any sort of useful * information.</strong> The "modules" directory is the default location from which JBoss Modules looks to find * modules. However, this behavior is in no way controlled by the value returned by this method, nor is it guaranteed that * modules will be loaded from only one directory, nor is it guaranteed that the "modules" directory will be one * of the directories used. Finally, the structure and contents of any directories from which JBoss Modules loads * resources is not something available from this class. Users wishing to interact with the modular classloading * system should use the APIs provided by JBoss Modules. * * @return a file * * @deprecated has no reliable meaning */ @Deprecated public File getModulesDir() { return modulesDir; } /** * Gets the directory under which OSGi bundles should be located. * * <p>Defaults to {@link #getHomeDir() homeDir}/bundles</p> * * @return the bundles directory */ public File getBundlesDir() { return bundlesDir; } private void configureBundlesDir(String dirPath, Properties providedProperties) { boolean haveDirProperty = dirPath != null; File tmp = getFileFromPath(dirPath); if (tmp == null) { if (haveDirProperty) { throw ServerLogger.ROOT_LOGGER.bundlesDirectoryDoesNotExist(new File(dirPath).getAbsoluteFile()); } providedProperties.remove(BUNDLES_DIR); tmp = new File(homeDir, "bundles"); } else { providedProperties.setProperty(BUNDLES_DIR, dirPath); } bundlesDir = tmp; } /** * Gets the based directory for this server. * * <p>Defaults to <tt>{@link #getHomeDir() homeDir}/standalone</tt> for a standalone server or * <tt>domain/servers/<server-name></tt> for a managed domain server.</p> * * @return the base directory for the server */ public File getServerBaseDir() { return serverBaseDir; } /** * Gets the directory in which server configuration files are stored. * <p>Defaults to {@link #getServerBaseDir()} serverBaseDir}/configuration</p> * * @return the server configuration directory. */ public File getServerConfigurationDir() { return serverConfigurationDir; } /** * Gets the {@link ConfigurationFile} that manages the server's configuration file. * * @return the configuration file */ public ConfigurationFile getServerConfigurationFile() { return serverConfigurationFile; } /** * Gets the directory in which the server can store private internal state that * should survive a process restart. * <p>Defaults to {@link #getServerBaseDir()} serverBaseDir}/data</p> * * @return the internal state persistent storage directory */ public File getServerDataDir() { return serverDataDir; } /** * Gets the directory in which the server will store server-managed user content (e.g. deployments.) * * <p>Defaults to {@link #getServerDataDir()} serverDataDir}/content</p> * * @return the domain managed content storage directory */ public File getServerContentDir() { return serverContentDir; } /** * Deprecated previous name for {@link #getServerContentDir()}. * @return the server managed content storage directory. * * @deprecated use {@link #getServerContentDir()} */ @Deprecated public File getServerDeployDir() { return serverContentDir; } /** * Gets the directory in which the server can write log files. * <p>Defaults to {@link #getServerBaseDir()} serverBaseDir}/log</p> * * @return the log file directory for the server. */ public File getServerLogDir() { return serverLogDir; } /** * Gets the directory in which athe server can store private internal state that * does not need to survive a process restart. * <p>Defaults to {@link #getServerBaseDir()} serverBaseDir}/tmp</p> * * @return the internal state temporary storage directory for the server. */ public File getServerTempDir() { return serverTempDir; } /** * If this is true then the server will start in suspended mode * * @return <code>true</code> if the server should start in suspended mode */ public boolean isStartSuspended() { return startSuspended; } private File configureServerTempDir(String path, Properties providedProps) { File tmp = getFileFromPath(path); if (tmp == null) { providedProps.remove(SERVER_TEMP_DIR); tmp = new File(serverBaseDir, "tmp"); } else { providedProps.setProperty(SERVER_TEMP_DIR, path); } serverTempDir = tmp; return tmp; } // BES 2012/02/04 made package protected as I cannot find use for it other than to create a PathService // So, the integration hook is the name of the path service, not this method. File getControllerTempDir() { return controllerTempDir; } /** * Gets the base directory in which managed domain files are stored. * <p>Defaults to {@link #getHomeDir() JBOSS_HOME}/domain</p> * * @return the domain base directory, or {@code null} if this server is not running in a managed domain. */ public File getDomainBaseDir() { return domainBaseDir; } /** * Gets the directory in which managed domain configuration files are stored. * <p>Defaults to {@link #getDomainBaseDir()} domainBaseDir}/configuration</p> * * @return the domain configuration directory, or {@code null} if this server is not running in a managed domain. */ public File getDomainConfigurationDir() { return domainConfigurationDir; } /** * Gets the manner in which this server was launched * * @return the launch type */ public LaunchType getLaunchType() { return launchType; } /** * Gets whether this server is an independently managed server, not managed as part of a managed domain. * @return {@code true} if this server is an independently managed server */ public boolean isStandalone() { return standalone; } /** * Gets whether this server is a self-contained (no filesystem layout) or not. * @return {@code true} if this server is self-contained */ public boolean isSelfContained() { return this.launchType == LaunchType.SELF_CONTAINED; } /** * Gets the {@link RunningMode} that was in effect when this server was launched. * * @return the initial running mode */ public RunningMode getInitialRunningMode() { return initialRunningMode; } /** * Get the {@link RunningModeControl} containing the current running mode of the server * * @return the running mode control */ @Override public RunningModeControl getRunningModeControl() { return runningModeControl; } // package protected for now as this is not a stable API boolean isAllowModelControllerExecutor() { return allowModelControllerExecutor; } /** * Gets the {@link ProductConfig} detected at startup. * * @return the product config. Will not be {@code null} */ public ProductConfig getProductConfig() { return productConfig; } @Override public UUID getInstanceUuid() { return this.serverUUID; } /** * Gets the time when this process was started. Note that a process reload does not change this value. * @return the time, in ms since the epoch */ public long getStartTime() { return startTime; } /** * Determine the number of threads to use for the bootstrap service container. This reads * the {@link #BOOTSTRAP_MAX_THREADS} system property and if not set, defaults to 2*cpus. * @see Runtime#availableProcessors() * @return the maximum number of threads to use for the bootstrap service container. */ public static int getBootstrapMaxThreads() { // Base the bootstrap thread on proc count if not specified int cpuCount = ProcessorInfo.availableProcessors(); int defaultThreads = cpuCount * 2; String maxThreads = WildFlySecurityManager.getPropertyPrivileged(BOOTSTRAP_MAX_THREADS, null); if (maxThreads != null && maxThreads.length() > 0) { try { int max = Integer.decode(maxThreads); defaultThreads = Math.max(max, 1); } catch(NumberFormatException ex) { ServerLogger.ROOT_LOGGER.failedToParseCommandLineInteger(BOOTSTRAP_MAX_THREADS, maxThreads); } } return defaultThreads; } @Override protected String getProcessName() { return serverName; } @Override protected void setProcessName(String processName) { if (processName != null) { if (primordialProperties.contains(SERVER_NAME)) { // User specified both -Djboss.server.name and a standalone.xml <server name="xxx"/> value. // Log a WARN String rawServerProp = WildFlySecurityManager.getPropertyPrivileged(SERVER_NAME, serverName); ServerLogger.AS_ROOT_LOGGER.duplicateServerNameConfiguration(SERVER_NAME, rawServerProp, processName); } serverName = processName; WildFlySecurityManager.setPropertyPrivileged(SERVER_NAME, serverName); processNameSet = true; if (!primordialProperties.contains(NODE_NAME)) { nodeName = serverName; WildFlySecurityManager.setPropertyPrivileged(NODE_NAME, nodeName); } } } @Override protected boolean isRuntimeSystemPropertyUpdateAllowed(String propertyName, String propertyValue, boolean bootTime) throws OperationFailedException { if (ILLEGAL_PROPERTIES.contains(propertyName)) { throw ServerLogger.ROOT_LOGGER.systemPropertyNotManageable(propertyName); } if (processNameSet && SERVER_NAME.equals(propertyName)) { throw ServerLogger.ROOT_LOGGER.systemPropertyCannotOverrideServerName(SERVER_NAME); } return bootTime || !BOOT_PROPERTIES.contains(propertyName); } @Override protected void systemPropertyUpdated(String propertyName, String propertyValue) { if (BOOT_PROPERTIES.contains(propertyName)) { if (BUNDLES_DIR.equals(propertyName)) { configureBundlesDir(propertyValue, providedProperties); } else if (SERVER_TEMP_DIR.equals(propertyName)) { configureServerTempDir(propertyValue, providedProperties); } else if (QUALIFIED_HOST_NAME.equals(propertyName)) { configureQualifiedHostName(propertyValue, providedProperties.getProperty(HOST_NAME), providedProperties, WildFlySecurityManager.getSystemEnvironmentPrivileged()); } else if (HOST_NAME.equals(propertyName)) { configureHostName(propertyValue, providedProperties); } else if (SERVER_NAME.equals(propertyName)) { configureServerName(propertyValue, providedProperties); } else if (NODE_NAME.equals(propertyName)) { configureNodeName(propertyValue, providedProperties); } } } /** * Get a File from configuration. * * @param name the name of the property * @param props the set of configuration properties * * @return the CanonicalFile form for the given name. */ private File getFileFromProperty(final String name, final Properties props) { return getFileFromPath(props.getProperty(name)); } /** * Get a File from configuration. * * @param path the file path * * @return the CanonicalFile form for the given name. */ private File getFileFromPath(final String path) { File result = (path != null) ? new File(path) : null; // AS7-1752 see if a non-existent relative path exists relative to the home dir if (result != null && homeDir != null && !result.exists() && !result.isAbsolute()) { File relative = new File(homeDir, path); if (relative.exists()) { result = relative; } } return result; } private static final File[] NO_FILES = new File[0]; /** * Get a File path list from configuration. * * @param name the name of the property * @param props the set of configuration properties * * @return the CanonicalFile form for the given name. */ private File[] getFilesFromProperty(final String name, final Properties props) { String sep = WildFlySecurityManager.getPropertyPrivileged("path.separator", null); String value = props.getProperty(name, null); if (value != null) { final String[] paths = value.split(Pattern.quote(sep)); final int len = paths.length; final File[] files = new File[len]; for (int i = 0; i < len; i++) { files[i] = new File(paths[i]); } return files; } return NO_FILES; } ManagedAuditLogger createAuditLogger() { return new ManagedAuditLoggerImpl(getProductConfig().resolveVersion(), true); } }