modules/common/jboss-as/pom.xml | 6 modules/common/jboss-as/src/main/java/org/jboss/on/common/jbossas/JmxConnectionHelper.java | 262 +++++++++ modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/inventory/DiscoveredResourceDetails.java | 6 modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java | 7 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/UpdateCollectionIntervalWidget.java | 5 modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ApplicationServerComponent.java | 2 modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ApplicationServerDiscoveryComponent.java | 103 ++- modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ApplicationServerPluginConfigurationProperties.java | 3 modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/JBossProperties.java | 4 modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/JmxConnectionHelper.java | 264 ---------- modules/plugins/jboss-as-5/src/main/resources/META-INF/rhq-plugin.xml | 15 modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/JBossASServerComponent.java | 8 modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/helper/JBossProperties.java | 2 13 files changed, 373 insertions(+), 314 deletions(-)
New commits: commit 19cc4a49d4041a3dcfdf4cb05bff2ab0b56edec1 Author: Ian Springer ian.springer@redhat.com Date: Fri Sep 17 17:40:48 2010 -0400
add support to as5 plugin for managing AS 6.0 M4 and later (https://bugzilla.redhat.com/show_bug.cgi?id=619240); add support to as5 plugin for discovering and managing AS instances with non-standard lib dirs, e.g. jboss.lib.url (https://bugzilla.redhat.com/show_bug.cgi?id=635158); move JmxConnectionHelper to jboss-as-common module
diff --git a/modules/common/jboss-as/pom.xml b/modules/common/jboss-as/pom.xml index d69311c..b60da0b 100644 --- a/modules/common/jboss-as/pom.xml +++ b/modules/common/jboss-as/pom.xml @@ -45,6 +45,12 @@ </dependency>
<dependency> + <groupId>mc4j</groupId> + <artifactId>org-mc4j-ems</artifactId> + <!-- NOTE: The version is defined in the root POM's dependencyManagement section. --> + </dependency> + + <dependency> <groupId>${project.groupId}</groupId> <artifactId>rhq-core-plugin-api</artifactId> <version>${project.version}</version> diff --git a/modules/common/jboss-as/src/main/java/org/jboss/on/common/jbossas/JmxConnectionHelper.java b/modules/common/jboss-as/src/main/java/org/jboss/on/common/jbossas/JmxConnectionHelper.java new file mode 100644 index 0000000..dc57a78 --- /dev/null +++ b/modules/common/jboss-as/src/main/java/org/jboss/on/common/jbossas/JmxConnectionHelper.java @@ -0,0 +1,262 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2009 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.jboss.on.common.jbossas; + +import java.io.File; +import java.util.Properties; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.mc4j.ems.connection.ConnectionFactory; +import org.mc4j.ems.connection.EmsConnection; +import org.mc4j.ems.connection.settings.ConnectionSettings; +import org.mc4j.ems.connection.support.ConnectionProvider; +import org.mc4j.ems.connection.support.metadata.ConnectionTypeDescriptor; +import org.mc4j.ems.connection.support.metadata.InternalVMTypeDescriptor; + +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.PropertySimple; + +/** + * Shared helper class to connect to a remote JMX server. + * + * @author Heiko W. Rupp + */ +public class JmxConnectionHelper { + public static final String CONNECTOR_DESCRIPTOR_TYPE = "connectorDescriptorType"; + public static final String CONNECTOR_ADDRESS = "connectorAddress"; + public static final String CONNECTOR_PRINCIPAL = "connectorPrincipal"; + public static final String CONNECTOR_CREDENTIALS = "connectorCredentials"; + public static final String JBOSS_HOME_DIR = "jbossHomeDir"; + + private static final Log log = LogFactory.getLog(JmxConnectionHelper.class); + + private static EmsConnection connection; + private static Configuration configuration; + + private static final String JNP_DISABLE_DISCOVERY_JNP_INIT_PROP = "jnp.disableDiscovery"; + + /** + * This is the timeout for the initial connection to the MBeanServer that is made by the AS ResourceComponent's + * start method. + */ + private static final int JNP_TIMEOUT = 30 * 1000; // 30 seconds + /** + * This is the timeout for MBean attribute gets/sets and operations invoked on the remote MBeanServer. + * NOTE: This timeout comes into play if the JBossAS instance has gone down since the original JNP connection was made. + */ + private static final int JNP_SO_TIMEOUT = 15 * 1000; // 15 seconds + + /** + * Controls the dampening of connection error stack traces in an attempt to control spam to the log file. Each time + * a connection error is encountered, this will be incremented. When the connection is finally established, this + * will be reset to zero. + */ + private static int consecutiveConnectionErrors; + + private boolean copyConnectionLibraries; + private File tmpDir; + + /** + * Constructs a new connection helper. + * + * @param copyConnectionLibraries whether to copy the libraries need for the connection so that + * the ems classloader doesn't block the application access to them. + * @param tmpDir the temporary directory to use when copying the libraries + */ + public JmxConnectionHelper(boolean copyConnectionLibraries, File tmpDir) { + this.copyConnectionLibraries = copyConnectionLibraries; + this.tmpDir = tmpDir; + } + + /** + * Obtain an EmsConnection for the passed connection properties. The properties will be retained. + * To create a connection with different properties, use this method again with a different set + * of properties. + * @param config Configuration properties for this connection + * @return an EmsConnection or null in case of failure + * @see #getEmsConnection() + */ + public EmsConnection getEmsConnection(Configuration config) { + EmsConnection emsConnection = null; + configuration = config; + + try { + emsConnection = loadConnection(config, copyConnectionLibraries, tmpDir); + } catch (Exception e) { + log.error("Component attempting to access a connection that could not be loaded"); + } + + return emsConnection; + } + + /** + * Obtain an EmsConnection. This will only work if the connection properties have passed + * before via a call to {@link #getEmsConnection(Configuration)} + * @return an EmsConnection or null in case of failure + * @see #getEmsConnection(org.rhq.core.domain.configuration.Configuration) + */ + public EmsConnection getEmsConnection() { + EmsConnection emsConnection = null; + if (configuration == null) { + throw new RuntimeException("No configuration set"); + } + + try { + emsConnection = loadConnection(configuration, copyConnectionLibraries, tmpDir); + } catch (Exception e) { + log.error("Component attempting to access a connection that could not be loaded"); + } + + return emsConnection; + } + + /** + * This is the preferred way to use a connection from within this class; methods should not access the connection + * property directly as it may not have been instantiated if the connection could not be made. + * <p/> + * <p>If the connection has already been established, return the object reference to it. If not, attempt to make a + * live connection to the JMX server.</p> + * <p/> + * <p>If the connection could not be made in the start(org.rhq.core.pluginapi.inventory.ResourceContext) method, + * this method will effectively try to load the connection on each attempt to use it. As such, multiple threads may + * attempt to access the connection through this means at a time. Therefore, the method has been made synchronized + * on instances of the class.</p> + * <p/> + * <p>If any errors are encountered, this method will log the error, taking into account logic to prevent spamming + * the log file. Calling methods should take care to not redundantly log the exception thrown by this method.</p> + * + * @param pluginConfig + * @return live connection to the JMX server; this will not be <code>null</code> + * @throws Exception if there are any issues at all connecting to the server + */ + private static synchronized EmsConnection loadConnection(Configuration pluginConfig, + boolean copyConnectionLibraries, File tmpDir) throws Exception { + if (connection == null) { + try { + //Configuration pluginConfig = this.resourceContext.getPluginConfiguration(); + + ConnectionSettings connectionSettings = new ConnectionSettings(); + + String connectionTypeDescriptorClass = pluginConfig.getSimple(CONNECTOR_DESCRIPTOR_TYPE) + .getStringValue(); + PropertySimple serverUrl = pluginConfig.getSimple(CONNECTOR_ADDRESS); + + connectionSettings.initializeConnectionType((ConnectionTypeDescriptor) Class.forName( + connectionTypeDescriptorClass).newInstance()); + // if not provided use the default serverUrl + if (null != serverUrl) { + connectionSettings.setServerUrl(serverUrl.getStringValue()); + } + + connectionSettings.setPrincipal(pluginConfig.getSimpleValue(CONNECTOR_PRINCIPAL, null)); + connectionSettings.setCredentials(pluginConfig.getSimpleValue(CONNECTOR_CREDENTIALS, null)); + connectionSettings.setLibraryURI(pluginConfig.getSimpleValue(JBOSS_HOME_DIR, null)); + + if (connectionSettings.getAdvancedProperties() == null) { + connectionSettings.setAdvancedProperties(new Properties()); + } + + connectionSettings.getAdvancedProperties().setProperty(ConnectionFactory.USE_CONTEXT_CLASSLOADER, "true"); + connectionSettings.getAdvancedProperties().setProperty(JNP_DISABLE_DISCOVERY_JNP_INIT_PROP, "true"); + + // Make sure the timeout always happens, even if the JBoss server is hung. + connectionSettings.getAdvancedProperties().setProperty("jnp.timeout", String.valueOf(JNP_TIMEOUT)); + connectionSettings.getAdvancedProperties().setProperty("jnp.sotimeout", String.valueOf(JNP_SO_TIMEOUT)); + + // TODO (ips): Remove this? + connectionSettings.getAdvancedProperties().setProperty(ConnectionFactory.USE_CONTEXT_CLASSLOADER, + Boolean.TRUE.toString()); + + if (copyConnectionLibraries) { + // Tell EMS to make copies of jar files so that the ems classloader doesn't lock + // application files (making us unable to update them) Bug: JBNADM-670 + connectionSettings.getControlProperties().setProperty(ConnectionFactory.COPY_JARS_TO_TEMP, + String.valueOf(Boolean.TRUE)); + } + + // Tell EMS to use the plugin's temp dir, so the PC will be able to clean it up and so an access control + // policy can easily be defined for the dir. EMS will use this for connection libraries (i.e. client + // jars) if COPY_JARS control prop is true, but it will also use it for the ems-mpl jar no matter what, + // so we need to always set it. + connectionSettings.getControlProperties().setProperty(ConnectionFactory.JAR_TEMP_DIR, + tmpDir.getAbsolutePath()); + + connectionSettings.getAdvancedProperties().setProperty(InternalVMTypeDescriptor.DEFAULT_DOMAIN_SEARCH, + "jboss"); + + ConnectionFactory connectionFactory = new ConnectionFactory(); + connectionFactory.discoverServerClasses(connectionSettings); + + ConnectionProvider connectionProvider = connectionFactory.getConnectionProvider(connectionSettings); + connection = connectionProvider.connect(); + + connection.loadSynchronous(false); // this loads all the MBeans + + consecutiveConnectionErrors = 0; + + if (log.isDebugEnabled()) + log.debug("Successfully made connection to the remote server instance"); + } catch (Exception e) { + + // The connection will be established even in the case that the principal cannot be authenticated, + // but the connection will not work. That failure seems to come from the call to loadSynchronous after + // the connection is established. If we get to this point that an exception was thrown, close any + // connection that was made and null it out so we can try to establish it again. + if (connection != null) { + if (log.isDebugEnabled()) + log.debug("Connection created but an exception was thrown. Closing the connection.", e); + connection.close(); + connection = null; + } + + // Since the connection is attempted each time it's used, failure to connect could result in log + // file spamming. Log it once for every 10 consecutive times it's encountered. + if (consecutiveConnectionErrors % 10 == 0) { + log.warn("Could not establish connection to the instance [" + (consecutiveConnectionErrors + 1) + + "] times.", e); + } + + if (log.isDebugEnabled()) + log.debug("Could not connect to the instance for resource ", e); + + consecutiveConnectionErrors++; + + throw e; + } + } + + return connection; + } + + /** + * If necessary attempt to close the EMS connection, then set this.connection null. Synchronized ensure we play + * well with loadConnection. + */ + public synchronized void closeConnection() { + if (connection != null) { + try { + connection.close(); + } catch (Exception e) { + log.error("Error closing EMS connection: " + e); + } + connection = null; + } + } +} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java index 720d1ab..361ac15 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java @@ -353,8 +353,13 @@ public class InventoryManager extends AgentService implements ContainerService, parentResourceContext, SystemInfoFactory.createSystemInfo(), null, null, this.configuration .getContainerName(), this.configuration.getPluginContainerDeployment());
+ // Configurations are not immutable, so clone the plugin config, so the plugin will not be able to change the + // actual PC-managed plugin config. + Configuration pluginConfigClone = resource.getPluginConfiguration().deepCopy(false); + // TODO (ips): Clone the ResourceType too for the same reason. + DiscoveredResourceDetails details = new DiscoveredResourceDetails(resourceType, resource.getResourceKey(), - resource.getName(), resource.getVersion(), resource.getDescription(), resource.getPluginConfiguration(), + resource.getName(), resource.getVersion(), resource.getDescription(), pluginConfigClone, null); // TODO: I have a feeling we'll need process info, how to get it??
List<URL> results = proxy.getAdditionalClasspathUrls(discoveryContext, details); diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/UpdateCollectionIntervalWidget.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/UpdateCollectionIntervalWidget.java index bef5806..f8ac5a1 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/UpdateCollectionIntervalWidget.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/UpdateCollectionIntervalWidget.java @@ -75,9 +75,10 @@ public class UpdateCollectionIntervalWidget extends LocatableHLayout implements refresh(UpdateCollectionIntervalWidget.this.schedulesView.getListGrid()); } }); + // Specify a null title so no label is rendered to the left of the combo box. SelectItem unitsItem = new SelectItem("units", null); - unitsItem.setValueMap("seconds", "minutes", "hours"); - unitsItem.setDefaultValue("seconds"); + unitsItem.setValueMap("second(s)", "minute(s)", "hour(s)"); + unitsItem.setDefaultValue("second(s)"); unitsItem.setShowTitle(false); this.form.setFields(intervalItem, unitsItem); addMember(this.form); diff --git a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ApplicationServerComponent.java b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ApplicationServerComponent.java index 6b5dfa4..855791a 100644 --- a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ApplicationServerComponent.java +++ b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ApplicationServerComponent.java @@ -47,6 +47,7 @@ import org.jboss.managed.api.ManagedComponent; import org.jboss.metatype.api.values.SimpleValue; import org.jboss.on.common.jbossas.JBPMWorkflowManager; import org.jboss.on.common.jbossas.JBossASPaths; +import org.jboss.on.common.jbossas.JmxConnectionHelper;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -88,7 +89,6 @@ import org.rhq.plugins.jbossas5.connection.ProfileServiceConnectionProvider; import org.rhq.plugins.jbossas5.connection.RemoteProfileServiceConnectionProvider; import org.rhq.plugins.jbossas5.helper.CreateChildResourceFacetDelegate; import org.rhq.plugins.jbossas5.helper.JBossAS5ConnectionTypeDescriptor; -import org.rhq.plugins.jbossas5.helper.JmxConnectionHelper; import org.rhq.plugins.jbossas5.helper.InPluginControlActionFacade; import org.rhq.plugins.jbossas5.util.ManagedComponentUtils;
diff --git a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ApplicationServerDiscoveryComponent.java b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ApplicationServerDiscoveryComponent.java index 94cad13..1eb9df6 100644 --- a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ApplicationServerDiscoveryComponent.java +++ b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ApplicationServerDiscoveryComponent.java @@ -1,6 +1,6 @@ /* * Jopr Management Platform -* Copyright (C) 2005-2009 Red Hat, Inc. +* Copyright (C) 2005-2010 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify @@ -24,10 +24,11 @@ package org.rhq.plugins.jbossas5;
import java.io.BufferedReader; import java.io.File; -import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; +import java.io.InputStream; import java.net.InetAddress; +import java.net.MalformedURLException; import java.net.URL; import java.net.UnknownHostException; import java.util.ArrayList; @@ -66,9 +67,10 @@ import org.rhq.plugins.jbossas5.helper.JBossInstanceInfo; import org.rhq.plugins.jbossas5.helper.JBossProductType; import org.rhq.plugins.jbossas5.helper.JBossProperties; import org.rhq.plugins.jbossas5.util.JnpConfig; +import org.rhq.plugins.jbossas5.util.ResourceComponentUtils;
/** - * A Resource discovery component for JBoss AS Server Resources, which include the following: + * A Resource discovery component for JBoss application server Resources, which include the following: * * JBoss AS, 5.2.0.Beta1 and later * JBoss EAP, 5.0.0.Beta and later @@ -78,6 +80,7 @@ import org.rhq.plugins.jbossas5.util.JnpConfig; * @author Ian Springer * @author Mark Spritzler */ +@SuppressWarnings({"UnusedDeclaration"}) public class ApplicationServerDiscoveryComponent implements ResourceDiscoveryComponent, ClassLoaderFacet, ManualAddFacet { private static final String CHANGE_ME = "***CHANGE_ME***"; @@ -87,7 +90,8 @@ public class ApplicationServerDiscoveryComponent implements ResourceDiscoveryCom private static final String LOCALHOST = "127.0.0.1"; private static final String JAVA_HOME_ENV_VAR = "JAVA_HOME";
- private static final Map<JBossProductType, ComparableVersion> MINIMUM_PRODUCT_VERSIONS = new HashMap(3); + private static final Map<JBossProductType, ComparableVersion> MINIMUM_PRODUCT_VERSIONS = + new HashMap<JBossProductType, ComparableVersion>(4); static { MINIMUM_PRODUCT_VERSIONS.put(JBossProductType.AS, new ComparableVersion("5.2.0.Beta1")); MINIMUM_PRODUCT_VERSIONS.put(JBossProductType.EAP, new ComparableVersion("5.0.0.Beta")); @@ -95,19 +99,23 @@ public class ApplicationServerDiscoveryComponent implements ResourceDiscoveryCom MINIMUM_PRODUCT_VERSIONS.put(JBossProductType.SOA, new ComparableVersion("5.0.0.Beta")); }
- private static final List<String> CLIENT_JARS = Arrays.asList( + private static final String[] CLIENT_JAR_URLS = new String[] { // NOTE: The jbossall-client.jar aggregates a whole bunch of other jars from the client dir via its // MANIFEST.MF Class-Path. - "client/jbossall-client.jar", "client/trove.jar", "client/javassist.jar", - "common/lib/jboss-security-aspects.jar", "lib/jboss-managed.jar", "lib/jboss-metatype.jar", - "lib/jboss-dependency.jar"); - - private static final List<String> AS6_CLIENT_JARS = new ArrayList<String>(CLIENT_JARS); - static { - // The below jars are required for JBoss AS 6.0 M1, M2, and M3. - AS6_CLIENT_JARS.add("lib/jboss-classpool.jar"); - AS6_CLIENT_JARS.add("lib/jboss-classpool-scoped.jar"); - } + "%clientUrl%/jbossall-client.jar", // + "%clientUrl%/trove.jar", // + "%clientUrl%/javassist.jar", // + "%commonLibUrl%/jboss-security-aspects.jar", // + "%libUrl%/jboss-managed.jar", // + "%libUrl%/jboss-metatype.jar", // + "%libUrl%/jboss-dependency.jar", // + // AS 6.0 M1 and later + "%libUrl%/jboss-classpool.jar", // + "%libUrl%/jboss-classpool-scoped.jar", // + // AS 6.0 M4 and later + "%commonLibUrl%/jboss-as-profileservice.jar", // + "%libUrl%/jboss-profileservice-spi.jar" // + };
private final Log log = LogFactory.getLog(this.getClass());
@@ -149,34 +157,63 @@ public class ApplicationServerDiscoveryComponent implements ResourceDiscoveryCom public List<URL> getAdditionalClasspathUrls(ResourceDiscoveryContext context, DiscoveredResourceDetails details) throws Exception { Configuration pluginConfig = details.getPluginConfiguration(); - String homeDir = pluginConfig.getSimple(ApplicationServerPluginConfigurationProperties.HOME_DIR) - .getStringValue(); + setValuesForUnsetClientJarUrlProperties(pluginConfig); + + List<URL> clientJarUrls = new ArrayList<URL>(); + for (String clientJarUrlString : CLIENT_JAR_URLS) { + // Substitute values in for any templated plugin config props. + clientJarUrlString = ResourceComponentUtils.replacePropertyExpressionsInTemplate(clientJarUrlString, + pluginConfig); + URL clientJarUrl = new URL(clientJarUrlString); + if (isReadable(clientJarUrl)) { + clientJarUrls.add(clientJarUrl); + } else { + log.warn("Client JAR [" + clientJarUrl + "] does not exist or is not readable (note, this JAR " + + " may not be required for some app server versions)."); + } + }
- List<URL> clientJars = new ArrayList<URL>(); + return clientJarUrls; + }
- for (String jarFileName : getClientJars(pluginConfig)) { - File clientJar = new File(homeDir, jarFileName); - if (!clientJar.exists()) { - throw new FileNotFoundException("Cannot find [" + clientJar + "] - unable to manage server."); + private boolean isReadable(URL url) { + try { + InputStream inputStream = url.openStream(); + try { + inputStream.close(); } - if (!clientJar.canRead()) { - throw new IOException("Cannot read [" + clientJar + "] - unable to manage server."); + catch (IOException e) { + log.error("Failed to close input stream for URL [" + url + "].", e); } - clientJars.add(clientJar.toURI().toURL()); + return true; + } + catch (IOException e) { + return false; } - - return clientJars; }
- private List<String> getClientJars(Configuration pluginConfig) throws IOException { - PropertySimple jbossHomeDir = pluginConfig.getSimple("homeDir"); - JBossInstallationInfo installationInfo = new JBossInstallationInfo(new File(jbossHomeDir.getStringValue())); + private void setValuesForUnsetClientJarUrlProperties(Configuration pluginConfig) throws MalformedURLException { + String homeDir = pluginConfig.getSimple(ApplicationServerPluginConfigurationProperties.HOME_DIR) + .getStringValue(); + URL homeUrl = new File(homeDir).toURI().toURL(); + + String clientUrlString = pluginConfig.getSimpleValue(ApplicationServerPluginConfigurationProperties.CLIENT_URL, null); + if (clientUrlString == null) { + URL clientUrl = new URL(homeUrl, "client"); + pluginConfig.put(new PropertySimple(ApplicationServerPluginConfigurationProperties.CLIENT_URL, clientUrl)); + }
- if (installationInfo.getMajorVersion().equals("6")) { - return AS6_CLIENT_JARS; + String libUrlString = pluginConfig.getSimpleValue(ApplicationServerPluginConfigurationProperties.LIB_URL, null); + if (libUrlString == null) { + URL libUrl = new URL(homeUrl, "lib"); + pluginConfig.put(new PropertySimple(ApplicationServerPluginConfigurationProperties.LIB_URL, libUrl)); }
- return CLIENT_JARS; + String commonLibUrlString = pluginConfig.getSimpleValue(ApplicationServerPluginConfigurationProperties.COMMON_LIB_URL, null); + if (commonLibUrlString == null) { + URL commonLibUrl = new URL(homeUrl, "common/lib"); + pluginConfig.put(new PropertySimple(ApplicationServerPluginConfigurationProperties.COMMON_LIB_URL, commonLibUrl)); + } }
private Set<DiscoveredResourceDetails> discoverExternalJBossAsProcesses(ResourceDiscoveryContext discoveryContext) { diff --git a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ApplicationServerPluginConfigurationProperties.java b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ApplicationServerPluginConfigurationProperties.java index c87a82f..3489fd4 100644 --- a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ApplicationServerPluginConfigurationProperties.java +++ b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ApplicationServerPluginConfigurationProperties.java @@ -31,6 +31,9 @@ public class ApplicationServerPluginConfigurationProperties { public static final String PRINCIPAL = "principal"; public static final String CREDENTIALS = "credentials"; public static final String HOME_DIR = "homeDir"; + public static final String CLIENT_URL = "clientUrl"; + public static final String LIB_URL = "libUrl"; + public static final String COMMON_LIB_URL = "commonLibUrl"; public static final String SERVER_HOME_DIR = "serverHomeDir"; public static final String JAVA_HOME = "javaHome"; public static final String BIND_ADDRESS = "bindAddress"; diff --git a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/JBossProperties.java b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/JBossProperties.java index 4c88d99..7fa6360 100644 --- a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/JBossProperties.java +++ b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/JBossProperties.java @@ -23,7 +23,8 @@ package org.rhq.plugins.jbossas5.helper;
/** - * The properties that are used by the JBossAS micro-kernel during bootstrap (see http://wiki.jboss.org/wiki/Wiki.jsp?page=JBossProperties). + * The properties that are used by the JBossAS micro-kernel during bootstrap + * (see http://community.jboss.org/wiki/JBossProperties). * * @author Ian Springer */ @@ -44,6 +45,7 @@ public abstract class JBossProperties { public static final String HOME_URL = "jboss.home.url"; public static final String LIB_URL = "jboss.lib.url"; public static final String PATCH_URL = "jboss.patch.url"; + public static final String COMMON_LIB_URL = "jboss.common.lib.url";
/** * The configuration name of the server - default 'default' for AS, or 'production' for EAP or SOA diff --git a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/JmxConnectionHelper.java b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/JmxConnectionHelper.java deleted file mode 100644 index c07254a..0000000 --- a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/JmxConnectionHelper.java +++ /dev/null @@ -1,264 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 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.plugins.jbossas5.helper; - -import java.io.File; -import java.util.Properties; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.mc4j.ems.connection.ConnectionFactory; -import org.mc4j.ems.connection.EmsConnection; -import org.mc4j.ems.connection.settings.ConnectionSettings; -import org.mc4j.ems.connection.support.ConnectionProvider; -import org.mc4j.ems.connection.support.metadata.ConnectionTypeDescriptor; -import org.mc4j.ems.connection.support.metadata.InternalVMTypeDescriptor; - -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.PropertySimple; - -/** - * Shared helper class to connect to a remote server - * - * @author Heiko W. Rupp - */ -public class JmxConnectionHelper { - - public static final String CONNECTOR_DESCRIPTOR_TYPE = "connectorDescriptorType"; - public static final String CONNECTOR_ADDRESS = "connectorAddress"; - public static final String CONNECTOR_PRINCIPAL = "connectorPrincipal"; - public static final String CONNECTOR_CREDENTIALS = "connectorCredentials"; - public static final String JBOSS_HOME_DIR = "jbossHomeDir"; - - private static final Log log = LogFactory.getLog(JmxConnectionHelper.class); - - private static EmsConnection connection; - private static Configuration configuration; - - private static final String JNP_DISABLE_DISCOVERY_JNP_INIT_PROP = "jnp.disableDiscovery"; - - /** - * This is the timeout for the initial connection to the MBeanServer that is made by - * {@link org.rhq.plugins.jbossas5.ApplicationServerComponent#start(org.rhq.core.pluginapi.inventory.ResourceContext)}. - */ - private static final int JNP_TIMEOUT = 30 * 1000; // 30 seconds - /** - * This is the timeout for MBean attribute gets/sets and operations invoked on the remote MBeanServer. - * NOTE: This timeout comes into play if the JBossAS instance has gone down since the original JNP connection was made. - */ - private static final int JNP_SO_TIMEOUT = 15 * 1000; // 15 seconds - - /** - * Controls the dampening of connection error stack traces in an attempt to control spam to the log file. Each time - * a connection error is encountered, this will be incremented. When the connection is finally established, this - * will be reset to zero. - */ - private static int consecutiveConnectionErrors; - - private boolean copyConnectionLibraries; - private File tmpDir; - - /** - * Constructs a new connection helper. - * - * @param copyConnectionLibraries whether to copy the libraries need for the connection so that - * the ems classloader doesn't block the application access to them. - * @param tmpDir the temporary directory to use when copying the libraries - */ - public JmxConnectionHelper(boolean copyConnectionLibraries, File tmpDir) { - this.copyConnectionLibraries = copyConnectionLibraries; - this.tmpDir = tmpDir; - } - - /** - * Obtain an EmsConnection for the passed connection properties. The properties will be retained. - * To create a connection with different properties, use this method again with a different set - * of properties. - * @param config Configuration properties for this connection - * @return an EmsConnection or null in case of failure - * @see #getEmsConnection() - */ - public EmsConnection getEmsConnection(Configuration config) { - EmsConnection emsConnection = null; - configuration = config; - - try { - emsConnection = loadConnection(config, copyConnectionLibraries, tmpDir); - } catch (Exception e) { - log.error("Component attempting to access a connection that could not be loaded"); - } - - return emsConnection; - } - - /** - * Obtain an EmsConnection. This will only work if the connection properties have passed - * before via a call to {@link #getEmsConnection(Configuration)} - * @return an EmsConnection or null in case of failure - * @see #getEmsConnection(org.rhq.core.domain.configuration.Configuration) - */ - public EmsConnection getEmsConnection() { - EmsConnection emsConnection = null; - if (configuration == null) { - throw new RuntimeException("No configuration set"); - } - - try { - emsConnection = loadConnection(configuration, copyConnectionLibraries, tmpDir); - } catch (Exception e) { - log.error("Component attempting to access a connection that could not be loaded"); - } - - return emsConnection; - } - - /** - * This is the preferred way to use a connection from within this class; methods should not access the connection - * property directly as it may not have been instantiated if the connection could not be made. - * <p/> - * <p>If the connection has already been established, return the object reference to it. If not, attempt to make a - * live connection to the JMX server.</p> - * <p/> - * <p>If the connection could not be made in the start(org.rhq.core.pluginapi.inventory.ResourceContext) method, - * this method will effectively try to load the connection on each attempt to use it. As such, multiple threads may - * attempt to access the connection through this means at a time. Therefore, the method has been made synchronized - * on instances of the class.</p> - * <p/> - * <p>If any errors are encountered, this method will log the error, taking into account logic to prevent spamming - * the log file. Calling methods should take care to not redundantly log the exception thrown by this method.</p> - * - * @param pluginConfig - * @return live connection to the JMX server; this will not be <code>null</code> - * @throws Exception if there are any issues at all connecting to the server - */ - private static synchronized EmsConnection loadConnection(Configuration pluginConfig, - boolean copyConnectionLibraries, File tmpDir) throws Exception { - if (connection == null) { - try { - //Configuration pluginConfig = this.resourceContext.getPluginConfiguration(); - - ConnectionSettings connectionSettings = new ConnectionSettings(); - - String connectionTypeDescriptorClass = pluginConfig.getSimple(CONNECTOR_DESCRIPTOR_TYPE) - .getStringValue(); - PropertySimple serverUrl = pluginConfig.getSimple(CONNECTOR_ADDRESS); - - connectionSettings.initializeConnectionType((ConnectionTypeDescriptor) Class.forName( - connectionTypeDescriptorClass).newInstance()); - // if not provided use the default serverUrl - if (null != serverUrl) { - connectionSettings.setServerUrl(serverUrl.getStringValue()); - } - - connectionSettings.setPrincipal(pluginConfig.getSimpleValue(CONNECTOR_PRINCIPAL, null)); - connectionSettings.setCredentials(pluginConfig.getSimpleValue(CONNECTOR_CREDENTIALS, null)); - connectionSettings.setLibraryURI(pluginConfig.getSimpleValue(JBOSS_HOME_DIR, null)); - - if (connectionSettings.getAdvancedProperties() == null) { - connectionSettings.setAdvancedProperties(new Properties()); - } - - connectionSettings.getAdvancedProperties().setProperty(ConnectionFactory.USE_CONTEXT_CLASSLOADER, "true"); - connectionSettings.getAdvancedProperties().setProperty(JNP_DISABLE_DISCOVERY_JNP_INIT_PROP, "true"); - - // Make sure the timeout always happens, even if the JBoss server is hung. - connectionSettings.getAdvancedProperties().setProperty("jnp.timeout", String.valueOf(JNP_TIMEOUT)); - connectionSettings.getAdvancedProperties().setProperty("jnp.sotimeout", String.valueOf(JNP_SO_TIMEOUT)); - - // TODO (ips): Remove this? - connectionSettings.getAdvancedProperties().setProperty(ConnectionFactory.USE_CONTEXT_CLASSLOADER, - Boolean.TRUE.toString()); - - if (copyConnectionLibraries) { - // Tell EMS to make copies of jar files so that the ems classloader doesn't lock - // application files (making us unable to update them) Bug: JBNADM-670 - connectionSettings.getControlProperties().setProperty(ConnectionFactory.COPY_JARS_TO_TEMP, - String.valueOf(Boolean.TRUE)); - } - - // Tell EMS to use the plugin's temp dir, so the PC will be able to clean it up and so an access control - // policy can easily be defined for the dir. EMS will use this for connection libraries (i.e. client - // jars) if COPY_JARS control prop is true, but it will also use it for the ems-mpl jar no matter what, - // so we need to always set it. - connectionSettings.getControlProperties().setProperty(ConnectionFactory.JAR_TEMP_DIR, - tmpDir.getAbsolutePath()); - - connectionSettings.getAdvancedProperties().setProperty(InternalVMTypeDescriptor.DEFAULT_DOMAIN_SEARCH, - "jboss"); - - ConnectionFactory connectionFactory = new ConnectionFactory(); - connectionFactory.discoverServerClasses(connectionSettings); - - ConnectionProvider connectionProvider = connectionFactory.getConnectionProvider(connectionSettings); - connection = connectionProvider.connect(); - - connection.loadSynchronous(false); // this loads all the MBeans - - consecutiveConnectionErrors = 0; - - if (log.isDebugEnabled()) - log.debug("Successfully made connection to the remote server instance"); - } catch (Exception e) { - - // The connection will be established even in the case that the principal cannot be authenticated, - // but the connection will not work. That failure seems to come from the call to loadSynchronous after - // the connection is established. If we get to this point that an exception was thrown, close any - // connection that was made and null it out so we can try to establish it again. - if (connection != null) { - if (log.isDebugEnabled()) - log.debug("Connection created but an exception was thrown. Closing the connection.", e); - connection.close(); - connection = null; - } - - // Since the connection is attempted each time it's used, failure to connect could result in log - // file spamming. Log it once for every 10 consecutive times it's encountered. - if (consecutiveConnectionErrors % 10 == 0) { - log.warn("Could not establish connection to the instance [" + (consecutiveConnectionErrors + 1) - + "] times.", e); - } - - if (log.isDebugEnabled()) - log.debug("Could not connect to the instance for resource ", e); - - consecutiveConnectionErrors++; - - throw e; - } - } - - return connection; - } - - /** - * If necessary attempt to close the EMS connection, then set this.connection null. Synchronized ensure we play - * well with loadConnection. - */ - public synchronized void closeConnection() { - if (connection != null) { - try { - connection.close(); - } catch (Exception e) { - log.error("Error closing EMS connection: " + e); - } - connection = null; - } - } - -} diff --git a/modules/plugins/jboss-as-5/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/jboss-as-5/src/main/resources/META-INF/rhq-plugin.xml index ea8ff2d..47ca3e0 100644 --- a/modules/plugins/jboss-as-5/src/main/resources/META-INF/rhq-plugin.xml +++ b/modules/plugins/jboss-as-5/src/main/resources/META-INF/rhq-plugin.xml @@ -972,8 +972,17 @@ description="The name of the server configuration (e.g. minimal, default, or all); if not specified, it will default to the last path component of {serverHomeDir}." default="default"/> + <c:simple-property name="clientUrl" required="false" + description="The URL of the server's client JAR library directory; + if not specified, it will default to {homeDir}/client."/> + <c:simple-property name="libUrl" required="false" + description="The URL of the server's main JAR library directory; + if not specified, it will default to {homeDir}/lib."/> + <c:simple-property name="commonLibUrl" required="false" + description="The URL of the server's common JAR library directory; + if not specified, it will default to {homeDir}/common/lib."/> </c:group> - <c:group name="control" displayName="Operations"> + <c:group name="control" displayName="Operations"> <c:simple-property name="scriptPrefix" displayName="Script Prefix" type="string" required="false" description="A prefix applied to script execution commands. Typically a sudo for applicable platforms. The prefix is applied verbatim. As such, a @@ -1011,7 +1020,7 @@ to 'shutdown script'."/> </c:group>
- <c:group name="advanced" displayName="Advanced" hiddenByDefault="true"> + <c:group name="advanced" displayName="Advanced" hiddenByDefault="true"> <c:simple-property name="shutdownMBeanName" displayName="Shutdown MBean Name" default="jboss.system:type=Server" description="Name of the MBean to use when shutting down this server through JMX."/> @@ -1029,7 +1038,7 @@ <c:simple-property name="childJmxServerName" displayName="JBoss AS JVM Name" default="JVM" readOnly="true" required="false" description="The name of the JBoss AS JVM resource."/> - </c:group> + </c:group>
<c:group name="events"> <c:list-property name="logEventSources"> diff --git a/modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/JBossASServerComponent.java b/modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/JBossASServerComponent.java index 5fac37b..8e967ae 100644 --- a/modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/JBossASServerComponent.java +++ b/modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/JBossASServerComponent.java @@ -115,7 +115,7 @@ import org.rhq.plugins.jmx.JMXDiscoveryComponent; import org.rhq.plugins.jmx.ObjectNameQueryUtility;
/** -* Supports JBoss 3.2.3 through 4.2.x +* Resource component for managing JBoss AS 3.2.3 through 4.2.x, and JBoss EAP and SOA-P 4.x. * * @author Greg Hinkle * @author John Mazzitelli @@ -156,10 +156,6 @@ public class JBossASServerComponent implements MeasurementFacet, OperationFacet, private static final String RESOURCE_TYPE_WAR = "Web Application (WAR)"; private static final String RESOURCE_TYPE_SAR = "Service Archive (SAR)"; // Not yet used
- // The following constants reference the exact name of the package types as defined in the plugin descriptor - private static final String PACKAGE_TYPE_PATCH = "cumulativePatch"; - private static final String PACKAGE_TYPE_LIBRARY = "library"; - private static final String JNP_DISABLE_DISCOVERY_JNP_INIT_PROP = "jnp.disableDiscovery";
private static final String DISTRIBUTED_REPLICANT_MANAGER_MBEAN_NAME_TEMPLATE = "jboss:partitionName=%partitionName%,service=DistributedReplicantManager"; @@ -1070,6 +1066,8 @@ public class JBossASServerComponent implements MeasurementFacet, OperationFacet, * * @throws Exception if there are any issues at all connecting to the server */ + // TODO (ips): Refactor this method to use the JmxConnectionHelper class from the jboss-as-common module, which is + // what the jboss-as-5 plugin uses. private synchronized EmsConnection loadConnection() throws Exception { if (this.connection == null) { try { diff --git a/modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/helper/JBossProperties.java b/modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/helper/JBossProperties.java index 7cfb2b2..680898f 100644 --- a/modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/helper/JBossProperties.java +++ b/modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/helper/JBossProperties.java @@ -24,7 +24,7 @@ package org.rhq.plugins.jbossas.helper;
/** * The properties that are used by the JBossAS micro-kernel during bootstrap - * (see http://wiki.jboss.org/wiki/Wiki.jsp?page=JBossProperties). + * (see http://community.jboss.org/wiki/JBossProperties). * * @author Ian Springer */
commit 03d5f59b902515e77f998600875130d476cff61d Author: Ian Springer ian.springer@redhat.com Date: Thu Sep 16 18:42:13 2010 -0400
misc minor
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/inventory/DiscoveredResourceDetails.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/inventory/DiscoveredResourceDetails.java index 4181721..f5350fd 100644 --- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/inventory/DiscoveredResourceDetails.java +++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/inventory/DiscoveredResourceDetails.java @@ -44,13 +44,13 @@ import org.rhq.core.system.ProcessInfo; * @author John Mazzitelli */ public class DiscoveredResourceDetails { - private final Log log = LogFactory.getLog(this.getClass()); - private static final int RESOURCE_KEY_MAX_LENGTH = 500; private static final int RESOURCE_NAME_MAX_LENGTH = 500; private static final int RESOURCE_VERSION_MAX_LENGTH = 100; private static final int RESOURCE_DESCRIPTION_MAX_LENGTH = 1000;
+ private final Log log = LogFactory.getLog(this.getClass()); + private ResourceType resourceType; private String resourceKey; private String resourceName; @@ -289,7 +289,7 @@ public class DiscoveredResourceDetails {
@Override public String toString() { - StringBuffer buf = new StringBuffer(); + StringBuilder buf = new StringBuilder();
buf.append("key="); buf.append(getResourceKey());
rhq-commits@lists.fedorahosted.org