modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/util/ResponseTimeLogFinder.java
| 73 +++
modules/core/plugin-api/src/test/java/org/rhq/core/pluginapi/util/ResponseTimeLogFinderTest.java
| 149 ++++++
modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ApplicationServerComponent.java
| 34 +
modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/WebApplicationContextDiscoveryComponent.java
| 53 +-
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java
| 9
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/WebRuntimeDiscoveryComponent.java
| 133 ++++++
modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
| 21
modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/WebRuntimeDiscoveryComponentTest.java
| 221 ++++++++++
8 files changed, 668 insertions(+), 25 deletions(-)
New commits:
commit 488e304c2222eeaac300e5efda770531bf2d1a19
Author: Thomas Segismont <tsegismo(a)redhat.com>
Date: Thu Jun 20 10:51:52 2013 +0200
Bug 822247 - Web Application Response Time Log File not being imported
diff --git
a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/util/ResponseTimeLogFinder.java
b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/util/ResponseTimeLogFinder.java
new file mode 100644
index 0000000..ea6551f
--- /dev/null
+++
b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/util/ResponseTimeLogFinder.java
@@ -0,0 +1,73 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2013 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+package org.rhq.core.pluginapi.util;
+
+import java.io.File;
+import java.io.FilenameFilter;
+
+/**
+ * Helps to find a response time filter log file.
+ *
+ * @author Thomas Segismont
+ */
+public class ResponseTimeLogFinder {
+ public static final File FALLBACK_RESPONSE_TIME_LOG_FILE_DIRECTORY = new
File(System.getProperty("java.io.tmpdir")
+ + File.separator + "rhq" + File.separator + "rt");
+
+ private ResponseTimeLogFinder() {
+ // Utility class
+ }
+
+ /**
+ * @param contextPath context path of the monitored web application
+ * @param responseTimeLogFileDirectory Where to search for the response time log file
of the web application.
+ * @return the absolute file path of the response time log file or null if not found
or responseTimeLogFileDirectory
+ * does not exist or is not a directory.
+ * @throws IllegalArgumentException if context path is null or does not start with a
slash, or if
+ * responseTimeLogFileDirectory is null
+ */
+ public static String findResponseTimeLogFileInDirectory(String contextPath, File
responseTimeLogFileDirectory) {
+ if (contextPath == null) {
+ throw new IllegalArgumentException("contextPath is null");
+ }
+ if (!contextPath.startsWith("/")) {
+ throw new IllegalArgumentException("contextPath does not start with
'/': " + contextPath);
+ }
+ if (responseTimeLogFileDirectory == null) {
+ throw new IllegalArgumentException("responseTimeLogFileDirectory is
null");
+ }
+ if (responseTimeLogFileDirectory.exists() &&
responseTimeLogFileDirectory.isDirectory()) {
+ // Handle the root context path
+ // Remove leading slash and convert slashes to underscores
+ final String rtFileSuffix = (contextPath.equals("/") ?
"ROOT" : contextPath).substring(1).replace('/', '_')
+ + "_rt.log";
+ File[] files = responseTimeLogFileDirectory.listFiles(new FilenameFilter() {
+ @Override
+ public boolean accept(File dir, String name) {
+ return name.endsWith(rtFileSuffix);
+ }
+ });
+ if (files != null && files.length == 1) {
+ return files[0].getAbsolutePath();
+ }
+ }
+ return null;
+ }
+}
diff --git
a/modules/core/plugin-api/src/test/java/org/rhq/core/pluginapi/util/ResponseTimeLogFinderTest.java
b/modules/core/plugin-api/src/test/java/org/rhq/core/pluginapi/util/ResponseTimeLogFinderTest.java
new file mode 100644
index 0000000..c64e710
--- /dev/null
+++
b/modules/core/plugin-api/src/test/java/org/rhq/core/pluginapi/util/ResponseTimeLogFinderTest.java
@@ -0,0 +1,149 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2013 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+package org.rhq.core.pluginapi.util;
+
+import static
org.rhq.core.pluginapi.util.ResponseTimeLogFinder.findResponseTimeLogFileInDirectory;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import java.io.File;
+
+import org.testng.annotations.Test;
+
+/**
+ * @author Thomas Segismont
+ */
+public class ResponseTimeLogFinderTest {
+
+ private static final File TMP_DIR = new
File(System.getProperty("java.io.tmpdir"));
+
+ @Test
+ public void shouldThrowIllegalArgumentExceptionForInvalidParameters() {
+ assertThrowsIllegalArgumentException(new Runnable() {
+ @Override
+ public void run() {
+ findResponseTimeLogFileInDirectory(null, null);
+ }
+ }, "Should fail when args are null");
+ assertThrowsIllegalArgumentException(new Runnable() {
+ @Override
+ public void run() {
+ findResponseTimeLogFileInDirectory("/pipo", null);
+ }
+ }, "Should fail when directory arg is null");
+ assertThrowsIllegalArgumentException(new Runnable() {
+ @Override
+ public void run() {
+ findResponseTimeLogFileInDirectory(null, new File(""));
+ }
+ }, "Should fail when context arg is null");
+ assertThrowsIllegalArgumentException(new Runnable() {
+ @Override
+ public void run() {
+ findResponseTimeLogFileInDirectory("pipo", new
File(""));
+ }
+ }, "Should fail when context arg does not start with a slash");
+ }
+
+ private void assertThrowsIllegalArgumentException(Runnable runnable, String
failureMessage) {
+ try {
+ runnable.run();
+ fail(failureMessage);
+ } catch (Exception e) {
+ assertTrue(e instanceof IllegalArgumentException, "Expected instance of
IllegalArgumentException but got "
+ + e.getClass().getSimpleName());
+ }
+ }
+
+ @Test
+ public void shouldReturnNullWhenDirectoryArgDoesNotExist() {
+ File notExistingFile = null;
+ for (int i = 0; i < 2000; i++) {
+ File f = new File(TMP_DIR, "pipo" + i);
+ if (!f.exists()) {
+ notExistingFile = f;
+ break;
+ }
+ }
+ if (notExistingFile == null) {
+ fail("Could not denote a non existing file");
+ }
+ assertNull(findResponseTimeLogFileInDirectory("/pipo",
notExistingFile));
+ }
+
+ @Test
+ public void shouldReturnNullWhenDirectoryArgIsNotADirectory() throws Exception {
+ File tempFile = File.createTempFile("pipo-", ".tmp");
+ tempFile.deleteOnExit();
+ assertNull(findResponseTimeLogFileInDirectory("/pipo", tempFile));
+ }
+
+ @Test
+ public void shouldReturnNullWhenNoFileWasFound() throws Exception {
+ File logFileDir = createLogFileDir();
+ assertNull(findResponseTimeLogFileInDirectory("/pipo", logFileDir));
+ }
+
+ @Test
+ public void shouldReturnFoundFile() throws Exception {
+ File logFileDir = createLogFileDir();
+ File logFile = File.createTempFile("log", "pipo_rt.log",
logFileDir);
+ logFile.deleteOnExit();
+ assertNotNull(findResponseTimeLogFileInDirectory("/pipo",
logFileDir));
+ }
+
+ @Test
+ public void shouldReturnNullIfFoundMoreThanOneFile() throws Exception {
+ File logFileDir = createLogFileDir();
+ File logFile1 = File.createTempFile("log", "pipo_rt.log",
logFileDir);
+ logFile1.deleteOnExit();
+ File logFile2 = File.createTempFile("log", "pipo_rt.log",
logFileDir);
+ logFile2.deleteOnExit();
+ assertNull(findResponseTimeLogFileInDirectory("/pipo", logFileDir));
+ }
+
+ @Test
+ public void shouldReturnFoundFileForRootContext() throws Exception {
+ File logFileDir = createLogFileDir();
+ File logFile = File.createTempFile("log", "ROOT_rt.log",
logFileDir);
+ logFile.deleteOnExit();
+ assertNotNull(findResponseTimeLogFileInDirectory("/", logFileDir));
+ }
+
+ @Test
+ public void shouldReturnFoundFileForSubContexts() throws Exception {
+ File logFileDir = createLogFileDir();
+ File logFile = File.createTempFile("log",
"pipo_molo_molette_rt.log", logFileDir);
+ logFile.deleteOnExit();
+ assertNotNull(findResponseTimeLogFileInDirectory("/pipo/molo/molette",
logFileDir));
+ }
+
+ private static File createLogFileDir() throws Exception {
+ // Java 1.6 has no temp dir creation util
+ File tempDir = File.createTempFile("pipo-", ".tmp");
+ if (tempDir.delete() && tempDir.mkdir()) {
+ tempDir.deleteOnExit();
+ return tempDir;
+ }
+ throw new RuntimeException("Could not create temp directory");
+ }
+}
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 d0839a8..0d45594 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
@@ -1,25 +1,22 @@
/*
- * Jopr Management Platform
- * Copyright (C) 2005-2009 Red Hat, Inc.
+ * RHQ Management Platform
+ * Copyright (C) 2005-2013 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, version 2, as
- * published by the Free Software Foundation, and/or the GNU Lesser
- * General Public License, version 2.1, also as published by the Free
- * Software Foundation.
+ * 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 and the GNU Lesser General Public License
- * for more details.
+ * GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * and the GNU Lesser General Public License along with this program;
- * if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
+
package org.rhq.plugins.jbossas5;
import java.io.File;
@@ -564,4 +561,19 @@ public class ApplicationServerComponent<T extends
ResourceComponent<?>> implemen
return ManagedComponentUtils.getSimplePropertyValue(component, propertyName);
}
+
+ /**
+ * Find the parent {@link ApplicationServerComponent} of the specified {@link
ProfileServiceComponent}.
+ *
+ * @param profileServiceComponent
+ * @return the parent {@link ApplicationServerComponent} or null
+ */
+ public static ApplicationServerComponent<?>
findApplicationServerComponent(ProfileServiceComponent profileServiceComponent) {
+ ProfileServiceComponent component = profileServiceComponent;
+ while (component != null && !(component instanceof
ApplicationServerComponent)) {
+ ResourceComponent parent =
component.getResourceContext().getParentResourceComponent();
+ component = (parent instanceof ProfileServiceComponent) ?
(ProfileServiceComponent) parent : null;
+ }
+ return (ApplicationServerComponent<?>) component;
+ }
}
diff --git
a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/WebApplicationContextDiscoveryComponent.java
b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/WebApplicationContextDiscoveryComponent.java
index 08f750c..ee706f4 100644
---
a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/WebApplicationContextDiscoveryComponent.java
+++
b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/WebApplicationContextDiscoveryComponent.java
@@ -1,27 +1,30 @@
/*
- * Jopr Management Platform
- * Copyright (C) 2005-2009 Red Hat, Inc.
+ * RHQ Management Platform
+ * Copyright (C) 2005-2013 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, version 2, as
- * published by the Free Software Foundation, and/or the GNU Lesser
- * General Public License, version 2.1, also as published by the Free
- * Software Foundation.
+ * 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 and the GNU Lesser General Public License
- * for more details.
+ * GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * and the GNU Lesser General Public License along with this program;
- * if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
+
package org.rhq.plugins.jbossas5;
+import static
org.rhq.core.pluginapi.util.ResponseTimeConfiguration.RESPONSE_TIME_LOG_FILE_CONFIG_PROP;
+import static
org.rhq.core.pluginapi.util.ResponseTimeLogFinder.FALLBACK_RESPONSE_TIME_LOG_FILE_DIRECTORY;
+import static
org.rhq.core.pluginapi.util.ResponseTimeLogFinder.findResponseTimeLogFileInDirectory;
+import static
org.rhq.plugins.jbossas5.ApplicationServerPluginConfigurationProperties.SERVER_HOME_DIR;
+
+import java.io.File;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
@@ -46,6 +49,7 @@ import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+import org.rhq.core.util.StringUtil;
import org.rhq.plugins.jbossas5.helper.MoreKnownComponentTypes;
import org.rhq.plugins.jbossas5.util.ManagedComponentUtils;
import org.rhq.plugins.jbossas5.util.RegularExpressionNameMatcher;
@@ -107,6 +111,8 @@ public class WebApplicationContextDiscoveryComponent implements
pluginConfig.put(new
PropertySimple(ManagedComponentComponent.Config.COMPONENT_NAME,
webApplicationManagerComponentName));
+ discoverResponseTimeLogFile(parentWarComponent, contextPath, pluginConfig);
+
DiscoveredResourceDetails resource = new
DiscoveredResourceDetails(resourceType, resourceKey, resourceName,
resourceVersion, resourceType.getDescription(), pluginConfig, null);
@@ -117,6 +123,29 @@ public class WebApplicationContextDiscoveryComponent implements
return discoveredResources;
}
+ private void discoverResponseTimeLogFile(AbstractManagedDeploymentComponent
parentWarComponent, String contextPath,
+ Configuration pluginConfig) {
+ String rtFilePath = null;
+ // First search in SERVER_HOME_DIR/log/rt directory
+ ApplicationServerComponent applicationServerComponent =
ApplicationServerComponent
+ .findApplicationServerComponent(parentWarComponent);
+ if (applicationServerComponent != null) {
+ String serverHomeDir =
applicationServerComponent.getResourceContext().getPluginConfiguration()
+ .getSimpleValue(SERVER_HOME_DIR);
+ if (StringUtil.isNotBlank(serverHomeDir)) {
+ File rtDirectory = new File(serverHomeDir + File.separator +
"log" + File.separator + "rt");
+ rtFilePath = findResponseTimeLogFileInDirectory(contextPath,
rtDirectory);
+ }
+ }
+ if (rtFilePath == null) {
+ // Search again in FALLBACK_RESPONSE_TIME_LOG_FILE_DIRECTORY
+ rtFilePath = findResponseTimeLogFileInDirectory(contextPath,
FALLBACK_RESPONSE_TIME_LOG_FILE_DIRECTORY);
+ }
+ if (rtFilePath != null) {
+ pluginConfig.setSimpleValue(RESPONSE_TIME_LOG_FILE_CONFIG_PROP, rtFilePath);
+ }
+ }
+
/**
* Returns the parent WAR's context path (e.g. "/jmx-console"), or
<code>null</code> if the WAR is currently
* stopped, since stopped WARs are not associated with any contexts.
@@ -177,4 +206,4 @@ public class WebApplicationContextDiscoveryComponent implements
hostName = hostName.substring(0, hostName.indexOf("/"));
return hostName;
}
-}
\ No newline at end of file
+}
diff --git
a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java
b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java
index 5d540fd..13e1b75 100644
---
a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java
+++
b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java
@@ -411,8 +411,15 @@ public abstract class BaseServerComponent<T extends
ResourceComponent<?>> extend
return operationResult;
}
- private boolean isManuallyAddedServer(OperationResult operationResult, String
operation) {
+ public boolean isManuallyAddedServer() {
if (pluginConfiguration.get("manuallyAdded") != null) {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isManuallyAddedServer(OperationResult operationResult, String
operation) {
+ if (isManuallyAddedServer()) {
operationResult.setErrorMessage(operation + " is not enabled for
manually added servers");
return true;
}
diff --git
a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/WebRuntimeDiscoveryComponent.java
b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/WebRuntimeDiscoveryComponent.java
new file mode 100644
index 0000000..31af277
--- /dev/null
+++
b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/WebRuntimeDiscoveryComponent.java
@@ -0,0 +1,133 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2013 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+package org.rhq.modules.plugins.jbossas7;
+
+import static
org.rhq.core.pluginapi.util.ResponseTimeConfiguration.RESPONSE_TIME_LOG_FILE_CONFIG_PROP;
+import static
org.rhq.core.pluginapi.util.ResponseTimeLogFinder.FALLBACK_RESPONSE_TIME_LOG_FILE_DIRECTORY;
+import static
org.rhq.core.pluginapi.util.ResponseTimeLogFinder.findResponseTimeLogFileInDirectory;
+
+import java.io.File;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+import org.rhq.core.util.StringUtil;
+import org.rhq.modules.plugins.jbossas7.json.Address;
+import org.rhq.modules.plugins.jbossas7.json.ReadAttribute;
+import org.rhq.modules.plugins.jbossas7.json.Result;
+
+/**
+ * @author Thomas Segismont
+ */
+public class WebRuntimeDiscoveryComponent extends SubsystemDiscovery {
+ private static final Log LOG =
LogFactory.getLog(WebRuntimeDiscoveryComponent.class);
+
+ private static final String CONTEXT_ROOT_ATTRIBUTE = "context-root";
+ private static final String PATH_ATTRIBUTE = "path";
+ private static final String PATH_DELIM = ",";
+ private static final String SERVER_PREFIX = "server=";
+
+ @Override
+ public Set<DiscoveredResourceDetails>
discoverResources(ResourceDiscoveryContext<BaseComponent<?>> context)
+ throws Exception {
+ Set<DiscoveredResourceDetails> discoveredResources =
super.discoverResources(context);
+ if (discoveredResources.isEmpty()) {
+ return discoveredResources;
+ }
+ if (discoveredResources.size() != 1) {
+ throw new IllegalStateException("Discovered multiple instances of a
singleton resource type");
+ }
+
+ BaseComponent<?> parentResourceComponent =
context.getParentResourceComponent();
+ BaseServerComponent serverComponent =
parentResourceComponent.getServerComponent();
+ DiscoveredResourceDetails resourceDetails =
discoveredResources.iterator().next();
+ Configuration pluginConfig = resourceDetails.getPluginConfiguration();
+ String nodePath = pluginConfig.getSimpleValue(PATH_ATTRIBUTE);
+ String contextRoot = getContextRootAttribute(new Address(nodePath),
parentResourceComponent.getASConnection());
+
+ discoverResponseTimeLogFile(serverComponent, pluginConfig, nodePath,
contextRoot);
+
+ return discoveredResources;
+ }
+
+ private void discoverResponseTimeLogFile(BaseServerComponent serverComponent,
Configuration pluginConfig,
+ String nodePath, String contextRoot) {
+ if (serverComponent.isManuallyAddedServer()) {
+ return;
+ }
+ String rtFilePath = null;
+ // First search in server log directory
+ if (serverComponent instanceof StandaloneASComponent) {
+ File serverLogDir =
serverComponent.getServerPluginConfiguration().getLogDir();
+ if (serverLogDir != null) {
+ File rtDirectory = new File(serverLogDir, "rt");
+ rtFilePath = findResponseTimeLogFileInDirectory(contextRoot,
rtDirectory);
+ }
+ } else if (serverComponent instanceof HostControllerComponent) {
+ File hostControllerBaseDir =
serverComponent.getServerPluginConfiguration().getBaseDir();
+ String managedServerName = getManagedServerNameFromPathAttribute(nodePath);
+ if (hostControllerBaseDir != null) {
+ File rtDirectory = new File(hostControllerBaseDir, "servers" +
File.separator + managedServerName
+ + File.separator + "log" + File.separator +
"rt");
+ rtFilePath = findResponseTimeLogFileInDirectory(contextRoot,
rtDirectory);
+ }
+ } else {
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("Unknown BaseServerComponent class: " +
serverComponent.getClass().getName());
+ }
+ }
+ if (rtFilePath == null) {
+ // Search again in FALLBACK_RESPONSE_TIME_LOG_FILE_DIRECTORY
+ rtFilePath = findResponseTimeLogFileInDirectory(contextRoot,
FALLBACK_RESPONSE_TIME_LOG_FILE_DIRECTORY);
+ }
+ if (rtFilePath != null) {
+ pluginConfig.setSimpleValue(RESPONSE_TIME_LOG_FILE_CONFIG_PROP, rtFilePath);
+ }
+ }
+
+ private String getContextRootAttribute(Address address, ASConnection asConnection) {
+ ReadAttribute readAttribute = new ReadAttribute(address,
CONTEXT_ROOT_ATTRIBUTE);
+ Result readAttributeResult = asConnection.execute(readAttribute);
+ if (!readAttributeResult.isSuccess()) {
+ throw new RuntimeException("Could not read [" +
CONTEXT_ROOT_ATTRIBUTE + "] attribute of node ["
+ + address.getPath() + "]: " +
readAttributeResult.getFailureDescription());
+ }
+ return (String) readAttributeResult.getResult();
+ }
+
+ private String getManagedServerNameFromPathAttribute(String nodePath) {
+ for (StringTokenizer tokenizer = new StringTokenizer(nodePath, PATH_DELIM);
tokenizer.hasMoreTokens();) {
+ String token = tokenizer.nextToken();
+ if (token.startsWith(SERVER_PREFIX)) {
+ String managedServerName = token.substring(SERVER_PREFIX.length());
+ if (StringUtil.isBlank(managedServerName)) {
+ throw new RuntimeException("Blank managed server name in path
[" + nodePath + "]");
+ }
+ return managedServerName;
+ }
+ }
+ throw new RuntimeException("Could not determine managed server name from
path [" + nodePath + "]");
+ }
+}
diff --git a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
index 6555008..e9449a5 100644
--- a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
@@ -1,5 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ RHQ Management Platform
+ ~ Copyright (C) 2005-2013 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.,
+ ~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ -->
+
<!DOCTYPE plugin [
<!ENTITY pluginName 'JBossAS7'>
@@ -8864,7 +8883,7 @@
<service name="Web Runtime"
class="WebRuntimeComponent"
- discovery="SubsystemDiscovery"
+ discovery="WebRuntimeDiscoveryComponent"
description="Runtime resources exposed by web components in the
deployment."
singleton="true">
diff --git
a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/WebRuntimeDiscoveryComponentTest.java
b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/WebRuntimeDiscoveryComponentTest.java
new file mode 100644
index 0000000..e9f6476
--- /dev/null
+++
b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/WebRuntimeDiscoveryComponentTest.java
@@ -0,0 +1,221 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2013 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+package org.rhq.modules.plugins.jbossas7;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.rhq.modules.plugins.jbossas7.json.Result.SUCCESS;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Set;
+
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+import org.rhq.core.pluginapi.util.ResponseTimeConfiguration;
+import org.rhq.modules.plugins.jbossas7.helper.ServerPluginConfiguration;
+import org.rhq.modules.plugins.jbossas7.json.ReadAttribute;
+import org.rhq.modules.plugins.jbossas7.json.ReadResource;
+import org.rhq.modules.plugins.jbossas7.json.Result;
+
+/**
+ * @author Thomas Segismont
+ */
+public class WebRuntimeDiscoveryComponentTest {
+ private static final String WEBAPP = "coregui";
+ private static final String PATH_ATTRIBUTE = "path";
+ private static final String PARENT_COMPONENT_PATH_IN_STANDALONE_SERVER =
"subdeployment=" + WEBAPP + ".war";
+ private static final String MANAGED_SERVER_NAME = "server-one";
+ private static final String PARENT_COMPONENT_PATH_IN_MANAGED_SERVER =
"server=" + MANAGED_SERVER_NAME
+ + ",subdeployment=" + WEBAPP + ".war";
+ private static final String CONF_PATH = "subsystem=web";
+
+ private WebRuntimeDiscoveryComponent discoveryComponent;
+
+ @Mock
+ private ResourceDiscoveryContext discoveryContext;
+
+ @Mock
+ private BaseComponent parentResourceComponent;
+
+ @Mock
+ private ASConnection asConnection;
+
+ @Mock
+ private ResourceType resourceType;
+
+ @Mock
+ private StandaloneASComponent standaloneASComponent;
+
+ @Mock
+ private HostControllerComponent hostControllerComponent;
+
+ @BeforeMethod(alwaysRun = true)
+ public void setup() throws Exception {
+ discoveryComponent = new WebRuntimeDiscoveryComponent();
+ MockitoAnnotations.initMocks(this);
+
when(discoveryContext.getParentResourceComponent()).thenReturn(parentResourceComponent);
+ when(parentResourceComponent.getASConnection()).thenReturn(asConnection);
+
when(discoveryContext.getDefaultPluginConfiguration()).thenReturn(createDefaultPluginConfig());
+
when(asConnection.execute(any(ReadResource.class))).thenReturn(createReadResourceResult());
+ when(discoveryContext.getResourceType()).thenReturn(resourceType);
+ when(resourceType.getDescription()).thenReturn("Description");
+
when(asConnection.execute(any(ReadAttribute.class))).thenReturn(createReadAttributeResult());
+ }
+
+ private Configuration createDefaultPluginConfig() {
+ Configuration configuration = new Configuration();
+ configuration.setSimpleValue(PATH_ATTRIBUTE, CONF_PATH);
+ return configuration;
+ }
+
+ private Result createReadResourceResult() {
+ Result result = new Result();
+ result.setOutcome(SUCCESS);
+ return result;
+ }
+
+ private Result createReadAttributeResult() {
+ Result result = new Result();
+ result.setOutcome(SUCCESS);
+ result.setResult("/" + WEBAPP);
+ return result;
+ }
+
+ @Test
+ public void shouldFindResponseTimeFilterLogInStandaloneServer() throws Exception {
+
when(parentResourceComponent.getPath()).thenReturn(PARENT_COMPONENT_PATH_IN_STANDALONE_SERVER);
+
when(parentResourceComponent.getServerComponent()).thenReturn(standaloneASComponent);
+ when(standaloneASComponent.isManuallyAddedServer()).thenReturn(Boolean.FALSE);
+ ServerPluginConfiguration standaloneServerPluginConfig =
createStandaloneServerPluginConfig();
+
when(standaloneASComponent.getServerPluginConfiguration()).thenReturn(standaloneServerPluginConfig);
+ File standaloneResponseTimeLogFile =
createStandaloneServerResponseTimeLogFile(standaloneServerPluginConfig);
+
+ Set<DiscoveredResourceDetails> details =
discoveryComponent.discoverResources(discoveryContext);
+ assertNotNull(details);
+ assertEquals(details.size(), 1);
+ DiscoveredResourceDetails discoveredResourceDetails = details.iterator().next();
+ String rtFilePath =
discoveredResourceDetails.getPluginConfiguration().getSimpleValue(
+ ResponseTimeConfiguration.RESPONSE_TIME_LOG_FILE_CONFIG_PROP);
+ assertNotNull(rtFilePath);
+ assertEquals(rtFilePath, standaloneResponseTimeLogFile.getAbsolutePath());
+ }
+
+ private ServerPluginConfiguration createStandaloneServerPluginConfig() throws
Exception {
+ ServerPluginConfiguration mock = mock(ServerPluginConfiguration.class);
+ when(mock.getLogDir()).thenReturn(createTempDir());
+ return mock;
+ }
+
+ private File createStandaloneServerResponseTimeLogFile(ServerPluginConfiguration
standaloneServerPluginConfig)
+ throws IOException {
+ File rtDir = new File(standaloneServerPluginConfig.getLogDir(), "rt");
+ rtDir.mkdir();
+ File logFile = new File(rtDir, WEBAPP + "_rt.log");
+ logFile.createNewFile();
+ return logFile;
+ }
+
+ @Test
+ public void shouldNotFindResponseTimeFilterLogInManuallyAddedStandaloneServer()
throws Exception {
+
when(parentResourceComponent.getPath()).thenReturn(PARENT_COMPONENT_PATH_IN_STANDALONE_SERVER);
+
when(parentResourceComponent.getServerComponent()).thenReturn(standaloneASComponent);
+ when(standaloneASComponent.isManuallyAddedServer()).thenReturn(Boolean.TRUE);
+
+ Set<DiscoveredResourceDetails> details =
discoveryComponent.discoverResources(discoveryContext);
+ assertNotNull(details);
+ assertEquals(details.size(), 1);
+ DiscoveredResourceDetails discoveredResourceDetails = details.iterator().next();
+ String rtFilePath =
discoveredResourceDetails.getPluginConfiguration().getSimpleValue(
+ ResponseTimeConfiguration.RESPONSE_TIME_LOG_FILE_CONFIG_PROP);
+ assertNull(rtFilePath);
+ }
+
+ @Test
+ public void shouldFindResponseTimeFilterLogInManagedServer() throws Exception {
+
when(parentResourceComponent.getPath()).thenReturn(PARENT_COMPONENT_PATH_IN_MANAGED_SERVER);
+
when(parentResourceComponent.getServerComponent()).thenReturn(hostControllerComponent);
+ when(hostControllerComponent.isManuallyAddedServer()).thenReturn(Boolean.FALSE);
+ ServerPluginConfiguration hostControllerServerPluginConfig =
createHostControllerServerPluginConfig();
+
when(hostControllerComponent.getServerPluginConfiguration()).thenReturn(hostControllerServerPluginConfig);
+ File managedServerResponseTimeLogFile =
createManagedServerResponseTimeLogFile(hostControllerServerPluginConfig);
+
+ Set<DiscoveredResourceDetails> details =
discoveryComponent.discoverResources(discoveryContext);
+ assertNotNull(details);
+ assertEquals(details.size(), 1);
+ DiscoveredResourceDetails discoveredResourceDetails = details.iterator().next();
+ String rtFilePath =
discoveredResourceDetails.getPluginConfiguration().getSimpleValue(
+ ResponseTimeConfiguration.RESPONSE_TIME_LOG_FILE_CONFIG_PROP);
+ assertNotNull(rtFilePath);
+ assertEquals(rtFilePath, managedServerResponseTimeLogFile.getAbsolutePath());
+ }
+
+ private ServerPluginConfiguration createHostControllerServerPluginConfig() throws
Exception {
+ ServerPluginConfiguration mock = mock(ServerPluginConfiguration.class);
+ when(mock.getBaseDir()).thenReturn(createTempDir());
+ return mock;
+ }
+
+ private File createManagedServerResponseTimeLogFile(ServerPluginConfiguration
hostControllerServerPluginConfig)
+ throws IOException {
+ File rtDir = new File(hostControllerServerPluginConfig.getBaseDir(),
"servers" + File.separator
+ + MANAGED_SERVER_NAME + File.separator + "log" + File.separator +
"rt");
+ rtDir.mkdirs();
+ File logFile = new File(rtDir, WEBAPP + "_rt.log");
+ logFile.createNewFile();
+ return logFile;
+ }
+
+ @Test
+ public void shouldNotFindResponseTimeFilterLogInManuallyAddedManagedServer() throws
Exception {
+
when(parentResourceComponent.getPath()).thenReturn(PARENT_COMPONENT_PATH_IN_MANAGED_SERVER);
+
when(parentResourceComponent.getServerComponent()).thenReturn(hostControllerComponent);
+ when(hostControllerComponent.isManuallyAddedServer()).thenReturn(Boolean.TRUE);
+
+ Set<DiscoveredResourceDetails> details =
discoveryComponent.discoverResources(discoveryContext);
+ assertNotNull(details);
+ assertEquals(details.size(), 1);
+ DiscoveredResourceDetails discoveredResourceDetails = details.iterator().next();
+ String rtFilePath =
discoveredResourceDetails.getPluginConfiguration().getSimpleValue(
+ ResponseTimeConfiguration.RESPONSE_TIME_LOG_FILE_CONFIG_PROP);
+ assertNull(rtFilePath);
+ }
+
+ private static File createTempDir() throws Exception {
+ // Java 1.6 has no temp dir creation util
+ File tempDir = File.createTempFile("pipo-", ".tmp");
+ if (tempDir.delete() && tempDir.mkdir()) {
+ tempDir.deleteOnExit();
+ return tempDir;
+ }
+ throw new RuntimeException("Could not create temp directory");
+ }
+}