/* * RHQ Management Platform * Copyright (C) 2005-2012 Red Hat, Inc. * All rights reserved. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.common.jbossas.client.controller; import java.io.File; import java.util.List; import java.util.Properties; import org.jboss.as.controller.client.ModelControllerClient; import org.jboss.dmr.ModelNode; import org.jboss.dmr.Property; /** * Provides information to some core services. * * @author John Mazzitelli */ public class CoreJBossASClient extends JBossASClient { public static final String CORE_SERVICE = "core-service"; public static final String SERVER_ENVIRONMENT = "server-environment"; public static final String PLATFORM_MBEAN = "platform-mbean"; public static final String DEPLOYMENT_SCANNER = "deployment-scanner"; public static final String SCANNER = "scanner"; public static final String EXTENSION = "extension"; public static final String MODULE = "module"; public static final String CORE_SERVICE_MGMT = "management"; public static final String MGMT_INTERFACE = "management-interface"; public static final String MGMT_INTERFACE_HTTP = "http-interface"; public CoreJBossASClient(ModelControllerClient client) { super(client); } /** * Allows the caller to turn on or off complete access for the app server's admin console. * * @param enableFlag true if the admin console enabled and visible; false if you want to prohibit all access to the admin console * @throws Exception */ public void setEnableAdminConsole(boolean enableFlag) throws Exception { // /core-service=management/management-interface=http-interface/:write-attribute(name=console-enabled,value=false) final Address address = Address.root() .add(CORE_SERVICE, CORE_SERVICE_MGMT, MGMT_INTERFACE, MGMT_INTERFACE_HTTP); final ModelNode req = createWriteAttributeRequest("console-enabled", Boolean.toString(enableFlag), address); final ModelNode response = execute(req); if (!isSuccess(response)) { throw new FailureException(response); } return; } /** * Given a string with possible ${x} expressions in it, this will resolve that expression * using system property values that are set within the AS JVM itself. If the string * to resolve has no expressions, or has no expressions that are resolveable, the expression * string itself is returned as-is (this includes if <code>expression</code> is <code>null</code>). * * @param expression string containing zero, one or more ${x} expressions to be resolved * @return the expression with the expressions resolved using system properties of the AS JVM * @throws Exception if failed to resolve the expression. */ public String resolveExpression(String expression) throws Exception { if (expression == null || expression.length() == 0) { return expression; } final ModelNode request = createRequest("resolve-expression", Address.root()); request.get("expression").set(expression); final ModelNode response = execute(request); if (!isSuccess(response)) { throw new FailureException(response); } return getResults(response).asString(); } /** * This returns the system properties that are set in the AS JVM. This is not the system properties * in the JVM of this client object - it is actually the system properties in the remote * JVM of the AS instance that the client is talking to. * * @return the AS JVM's system properties * @throws Exception */ public Properties getSystemProperties() throws Exception { final String[] address = { CORE_SERVICE, PLATFORM_MBEAN, "type", "runtime" }; final ModelNode op = createReadAttributeRequest(true, "system-properties", Address.root().add(address)); final ModelNode results = execute(op); if (isSuccess(results)) { // extract the DMR representation into a java Properties object final Properties sysprops = new Properties(); final ModelNode node = getResults(results); final List<Property> propertyList = node.asPropertyList(); for (Property property : propertyList) { final String name = property.getName(); final ModelNode value = property.getValue(); if (name != null) { sysprops.put(name, value != null ? value.asString() : ""); } } return sysprops; } else { throw new FailureException(results, "Failed to get system properties"); } } public String getOperatingSystem() throws Exception { final String[] address = { CORE_SERVICE, PLATFORM_MBEAN, "type", "operating-system" }; final String osName = getStringAttribute("name", Address.root().add(address)); return osName; } public String getAppServerVersion() throws Exception { final String version = getStringAttribute("release-version", Address.root()); return version; } public String getServerProductVersion() throws Exception { final String version = getStringAttribute("product-version", Address.root()); return version; } public String getServerProductName() throws Exception { final String version = getStringAttribute("product-name", Address.root()); return version; } public String getAppServerHomeDir() throws Exception { final String[] address = { CORE_SERVICE, SERVER_ENVIRONMENT }; final String dir = getStringAttribute(true, "home-dir", Address.root().add(address)); return dir; } public String getAppServerDataDir() throws Exception { final String[] address = { CORE_SERVICE, SERVER_ENVIRONMENT }; final String dir = getStringAttribute(true, "data-dir", Address.root().add(address)); return dir; } public String getAppServerBaseDir() throws Exception { final String[] address = { CORE_SERVICE, SERVER_ENVIRONMENT }; final String dir = getStringAttribute(true, "base-dir", Address.root().add(address)); return dir; } public String getAppServerConfigDir() throws Exception { final String[] address = { CORE_SERVICE, SERVER_ENVIRONMENT }; final String dir = getStringAttribute(true, "config-dir", Address.root().add(address)); return dir; } public String getAppServerLogDir() throws Exception { final String[] address = { CORE_SERVICE, SERVER_ENVIRONMENT }; final String dir = getStringAttribute(true, "log-dir", Address.root().add(address)); return dir; } public String getAppServerTmpDir() throws Exception { final String[] address = { CORE_SERVICE, SERVER_ENVIRONMENT }; final String dir = getStringAttribute(true, "temp-dir", Address.root().add(address)); return dir; } /** * Enabled or disables the default deployment scanner. * @param enabled the new status to be set * @throws Exception */ public void setAppServerDefaultDeploymentScanEnabled(boolean enabled) throws Exception { final String[] addressArr = { SUBSYSTEM, DEPLOYMENT_SCANNER, SCANNER, "default" }; final Address address = Address.root().add(addressArr); final ModelNode req = createWriteAttributeRequest("scan-enabled", Boolean.toString(enabled), address); final ModelNode response = execute(req); if (!isSuccess(response)) { throw new FailureException(response); } return; } /** * Returns the location where the default deployment scanner is pointing to. * This is where EARs, WARs and the like are deployed to. * @return the default deployments directory - null if there is no deployment scanner * @throws Exception */ public String getAppServerDefaultDeploymentDir() throws Exception { final String[] addressArr = { SUBSYSTEM, DEPLOYMENT_SCANNER, SCANNER, "default" }; final Address address = Address.root().add(addressArr); final ModelNode resourceAttributes = readResource(address); if (resourceAttributes == null) { return null; // there is no default scanner } final String path = resourceAttributes.get("path").asString(); String relativeTo = null; if (resourceAttributes.hasDefined("relative-to")) { relativeTo = resourceAttributes.get("relative-to").asString(); } // path = the actual filesystem path to be scanned. Treated as an absolute path, // unless 'relative-to' is specified, in which case value is treated as relative to that path. // relative-to = Reference to a filesystem path defined in the "paths" section of the server // configuration, or one of the system properties specified on startup. // NOTE: here we will assume that if specified, it is a system property name. if (relativeTo != null) { String syspropValue = System.getProperty(relativeTo); if (syspropValue == null) { throw new IllegalStateException("Cannot support relative-to that isn't a sysprop: " + relativeTo); } relativeTo = syspropValue; } final File dir = new File(relativeTo, path); return dir.getAbsolutePath(); } /** * Sets the interval of the default deployment scanner. If the value is * less than 1 millisecond, the scanner will scan only one time at server startup. * @param millis number of milliseconds to periodically scan the deployment directory * @throws Exception */ public void setAppServerDefaultDeploymentScanInterval(long millis) throws Exception { final String[] addressArr = { SUBSYSTEM, DEPLOYMENT_SCANNER, SCANNER, "default" }; final Address address = Address.root().add(addressArr); final ModelNode req = createWriteAttributeRequest("scan-interval", Long.toString(millis), address); final ModelNode response = execute(req); if (!isSuccess(response)) { throw new FailureException(response); } return; } /** * Sets the deployment timeout of the default deployment scanner. If a deployment * takes longer than this value, it will fail. * @param secs number of seconds the app server will wait for a deployment to finish * @throws Exception */ public void setAppServerDefaultDeploymentTimeout(long secs) throws Exception { final String[] addressArr = { SUBSYSTEM, DEPLOYMENT_SCANNER, SCANNER, "default" }; final Address address = Address.root().add(addressArr); final ModelNode req = createWriteAttributeRequest("deployment-timeout", Long.toString(secs), address); final ModelNode response = execute(req); if (!isSuccess(response)) { throw new FailureException(response); } return; } /** * Set a runtime system property in the JVM that is managed by JBossAS. * * @param name * @param value * @throws Exception */ public void setSystemProperty(String name, String value) throws Exception { final ModelNode request = createRequest(ADD, Address.root().add(SYSTEM_PROPERTY, name)); request.get(VALUE).set(value); final ModelNode response = execute(request); if (!isSuccess(response)) { throw new FailureException(response, "Failed to set system property [" + name + "]"); } } /** * Adds a new module extension to the core system. * * @param name the name of the new module extension * @throws Exception */ public void addExtension(String name) throws Exception { // /extension=<name>/:add(module=<name>) final ModelNode request = createRequest(ADD, Address.root().add(EXTENSION, name)); request.get(MODULE).set(name); final ModelNode response = execute(request); if (!isSuccess(response)) { throw new FailureException(response, "Failed to add new module extension [" + name + "]"); } return; } /** * Returns true if the given extension is already in existence. * * @param name the name of the extension to check * @return true if the extension already exists; false if not * @throws Exception */ public boolean isExtension(String name) throws Exception { return null != readResource(Address.root().add(EXTENSION, name)); } /** * Adds a new subsystem to the core system. * * @param name the name of the new subsystem * @throws Exception */ public void addSubsystem(String name) throws Exception { addSubsystem(name, null); } /** * Adds a new subsystem (along with some optional settings for that subsystem) to the core system * If settings is null, the subsystem will be created with no additional settings associated with it. * * @param name the name of the new subsystem * @param settings a node with some additional settings used to initialize the subsystem * @throws Exception */ public void addSubsystem(String name, ModelNode settings) throws Exception { // /subsystem=<name>:add() final ModelNode request = createRequest(ADD, Address.root().add(SUBSYSTEM, name), settings); final ModelNode response = execute(request); if (!isSuccess(response)) { throw new FailureException(response, "Failed to add new subsystem [" + name + "]"); } return; } /** * Returns true if the given subsystem is already in existence. * * @param name the name of the subsystem to check * @return true if the subsystem already exists; false if not * @throws Exception */ public boolean isSubsystem(String name) throws Exception { return null != readResource(Address.root().add(SUBSYSTEM, name)); } /** * Invokes the management "reload" operation which will shut down all the app server services and * restart them again. This is required for certain configuration changes to take effect. * This does not shutdown the JVM itself. * * NOTE: once this method returns, the client is probably unusable since the server side * will probably shutdown the connection. You will need to throw away this object and rebuild * another one with a newly reconnected {@link #getModelControllerClient() client}. * * @throws Exception */ public void reload() throws Exception { reload(false); } /** * Invokes the management "reload" operation which will shut down all the app server services and * restart them again potentially in admin-only mode. * This does not shutdown the JVM itself. * * NOTE: once this method returns, the client is probably unusable since the server side * will probably shutdown the connection. You will need to throw away this object and rebuild * another one with a newly reconnected {@link #getModelControllerClient() client}. * * @param adminOnly if <code>true</code>, reloads the server in admin-only mode * * @throws Exception */ public void reload(boolean adminOnly) throws Exception { final ModelNode request = createRequest("reload", Address.root()); request.get("admin-only").set(adminOnly); final ModelNode response = execute(request); if (!isSuccess(response)) { throw new FailureException(response); } return; } /** * Invokes the management "shutdown" operation with the restart option set to true * (see {@link #shutdown(boolean)}). * This means the app server JVM will shutdown but immediately be restarted. * Note that the caller may not be returned to since the JVM in which this call is made * will be killed and if the client is co-located with the server JVM, this client will * also die. * * NOTE: even if this method returns, the client is unusable since the server side * will shutdown the connection. You will need to throw away this object and rebuild * another one with a newly reconnected {@link #getModelControllerClient() client}. * * @throws Exception */ public void restart() throws Exception { shutdown(true); } /** * Invokes the management "shutdown" operation that kills the JVM completely with System.exit. * If restart is set to true, the JVM will immediately be restarted again. If restart is false, * the JVM is killed and will stay down. * Note that in either case, the caller may not be returned to since the JVM in which this call is made * will be killed and if the client is co-located with the server JVM, this client will * also die. * * NOTE: even if this method returns, the client is unusable since the server side * will shutdown the connection. You will need to throw away this object and rebuild * another one with a newly reconnected {@link #getModelControllerClient() client}. * * @param restart if true, the JVM will be restarted * @throws Exception */ public void shutdown(boolean restart) throws Exception { final ModelNode request = createRequest("shutdown", Address.root()); request.get("restart").set(restart); final ModelNode response = execute(request); if (!isSuccess(response)) { throw new FailureException(response); } return; } }