modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/util/ServerStartScriptDiscoveryUtility.java | 156 ++++++----
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java | 4
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/HostControllerDiscovery.java | 7
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASDiscovery.java | 6
modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/GenericJBossAS7PluginTest.java | 27 +
5 files changed, 146 insertions(+), 54 deletions(-)
New commits:
commit b6aa68d296a9d27334ba578c8deb9efcbdc1ef9a
Author: Ian Springer <ian.springer(a)redhat.com>
Date: Fri Apr 27 17:48:22 2012 -0400
for a host controller started via domain.sh, the domain.sh process will be the grandparent process, not the parent process (the parent will be the AS7 process controller) - update start script discovery code to recognize this
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java
index 7fe7f5f..7285cec 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java
@@ -240,7 +240,7 @@ public abstract class BaseProcessDiscovery implements ResourceDiscoveryComponent
private void setStartScriptPluginConfigProps(ProcessInfo process, AS7CommandLine commandLine,
Configuration pluginConfig) {
StartScriptConfiguration startScriptConfig = new StartScriptConfiguration(pluginConfig);
- ProcessInfo parentProcess = process.getParentProcess();
+ ProcessInfo parentProcess = getPotentialStartScriptProcess(process);
File startScript = ServerStartScriptDiscoveryUtility.getStartScript(parentProcess);
if (startScript == null) {
@@ -268,6 +268,8 @@ public abstract class BaseProcessDiscovery implements ResourceDiscoveryComponent
startScriptConfig.setStartScriptArgs(startScriptArgs);
}
+ protected abstract ProcessInfo getPotentialStartScriptProcess(ProcessInfo process);
+
private void setUserAndPasswordPluginConfigProps(ServerPluginConfiguration serverPluginConfig, HostConfiguration hostConfig,
File baseDir) {
Properties mgmtUsers = getManagementUsers(hostConfig, getMode(), baseDir);
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/HostControllerDiscovery.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/HostControllerDiscovery.java
index 7886190..455717d 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/HostControllerDiscovery.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/HostControllerDiscovery.java
@@ -114,4 +114,11 @@ public class HostControllerDiscovery extends BaseProcessDiscovery {
return resourceDetails;
}
+ @Override
+ protected ProcessInfo getPotentialStartScriptProcess(ProcessInfo serverProcess) {
+ // If the server was started via domain.sh/bat, its parent process will be the process controller JVM, and the
+ // process controller JVM's parent process will be domain.sh/bat.
+ return serverProcess.getParentProcess().getParentProcess();
+ }
+
}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASDiscovery.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASDiscovery.java
index 136a0af..f23c6e3 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASDiscovery.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASDiscovery.java
@@ -111,4 +111,10 @@ public class StandaloneASDiscovery extends BaseProcessDiscovery {
return resourceDetails;
}
+ @Override
+ protected ProcessInfo getPotentialStartScriptProcess(ProcessInfo process) {
+ // If the server was started via standalone.sh/bat, its parent process will be standalone.sh/bat.
+ return process.getParentProcess();
+ }
+
}
commit 651d54d74878daaba714b3096c6dd8ebf63be436
Author: Ian Springer <ian.springer(a)redhat.com>
Date: Fri Apr 27 17:46:15 2012 -0400
fix a couple bugs, refactor a couple things, and add javadoc
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/util/ServerStartScriptDiscoveryUtility.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/util/ServerStartScriptDiscoveryUtility.java
index 819e1e1..576ae41 100644
--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/util/ServerStartScriptDiscoveryUtility.java
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/util/ServerStartScriptDiscoveryUtility.java
@@ -32,6 +32,8 @@ import java.util.Map;
import java.util.Set;
import org.hyperic.sigar.ProcExe;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.rhq.core.system.ProcessInfo;
@@ -43,15 +45,19 @@ import org.rhq.core.system.ProcessInfo;
*/
public class ServerStartScriptDiscoveryUtility {
+ private static final boolean OS_IS_WINDOWS = (File.separatorChar == '\\');
+ private static final char OPTION_PREFIX = (OS_IS_WINDOWS) ? '/' : '-';
+
// Generic OS-level PATH setting for LINUX. For Windows the PATH must be generated when we have
// the system env vars. It will be of the form %SystemRoot%\\system32;%SystemRoot%;
- private static final String CORE_ENV_VAR_PATH_LINUX = "/bin:/usr/bin";
+ private static final String CORE_ENV_VAR_PATH_UNIX = "/bin:/usr/bin";
// Generic OS-level env vars that should be in every process's environment.
private static final Set<String> CORE_ENV_VAR_NAME_INCLUDES = new HashSet<String>(Arrays.asList("PATH",
"LD_LIBRARY_PATH"));
+
static {
- if (File.separatorChar == '\\') {
+ if (OS_IS_WINDOWS) {
CORE_ENV_VAR_NAME_INCLUDES.add("OS"); // many batch files use this to figure out if the OS type is NT or 9x
CORE_ENV_VAR_NAME_INCLUDES.add("SYSTEMROOT"); // required on Windows to avoid winsock create errors
}
@@ -60,32 +66,32 @@ public class ServerStartScriptDiscoveryUtility {
private ServerStartScriptDiscoveryUtility() {
}
+ /**
+ * If the specified process is a script, return the path to the script - the returned path will be absolute and
+ * canonical if possible, or, if it is not a script, return <code>null</code>.
+ *
+ * @param serverParentProcess the parent process of a server (e.g. JBoss AS) process
+ *
+ * @return if the specified process is a script (the returned path will be absolute and
+ * canonical if possible), the path to the script, otherwise <code>null</code>
+ */
+ @Nullable
public static File getStartScript(ProcessInfo serverParentProcess) {
// e.g. UNIX: "/bin/sh ./standalone.sh --server-config=standalone-full.xml"
// Windows: "cmd.exe [options] standalone.bat --server-config=standalone-full.xml"
- int startScriptIndex = 1;
String[] serverParentProcessCommandLine = serverParentProcess.getCommandLine();
-
- // advance past cmd.exe options. options start with '/'
- if (File.separatorChar == '\\') {
- for (; (startScriptIndex < serverParentProcessCommandLine.length); ++startScriptIndex) {
- if (!serverParentProcessCommandLine[startScriptIndex].startsWith("/")) {
- break;
- }
- }
- }
-
- String startScript = (serverParentProcessCommandLine.length > startScriptIndex) ? serverParentProcessCommandLine[startScriptIndex]
- : null;
+ Integer startScriptIndex = getStartScriptIndex(serverParentProcessCommandLine);
File startScriptFile;
-
- if (isScript(startScript)) {
- // The parent process is a script - excellent!
+ if (startScriptIndex != null) {
+ // The process is a script - excellent!
+ String startScript = (serverParentProcessCommandLine.length > startScriptIndex) ? serverParentProcessCommandLine[startScriptIndex]
+ : null;
startScriptFile = new File(startScript);
if (!startScriptFile.isAbsolute()) {
ProcExe parentProcessExe = serverParentProcess.getExecutable();
if (parentProcessExe == null) {
+ // TODO: This isn't really generic
startScriptFile = new File("bin", startScriptFile.getName());
} else {
String cwd = parentProcessExe.getCwd();
@@ -102,52 +108,79 @@ public class ServerStartScriptDiscoveryUtility {
return startScriptFile;
}
+ /**
+ * Returns the list of arguments that should be passed to the start script for the specified server (e.g. JBoss AS)
+ * process in order to start a functionally equivalent server instance.
+ *
+ * @param serverParentProcess the parent process of a server (e.g. JBoss AS) process
+ * @param serverArgs the subset of arguments from the server (e.g. JBoss AS) process that should be used if the
+ * parent process is not a script
+ * @param optionExcludes options that should be excluded from the returned arguments if the parent process is not a
+ * script
+ *
+ * @return the list of arguments that should be passed to the start script for the specified server (e.g. JBoss AS)
+ * process in order to start a functionally equivalent server instance
+ */
+ @NotNull
public static List<String> getStartScriptArgs(ProcessInfo serverParentProcess, List<String> serverArgs,
Set<CommandLineOption> optionExcludes) {
- // e.g. UNIX: "/bin/sh ./standalone.sh --server-config=standalone-full.xml"
- // Windows: "standalone.bat --server-config=standalone-full.xml"
- int startScriptIndex = (File.separatorChar == '/') ? 1 : 0;
String[] startScriptCommandLine = serverParentProcess.getCommandLine();
- String startScript = (startScriptCommandLine.length > startScriptIndex) ? startScriptCommandLine[startScriptIndex]
- : null;
+ Integer startScriptIndex = getStartScriptIndex(startScriptCommandLine);
List<String> startScriptArgs = new ArrayList<String>();
- if (isScript(startScript)) {
+ if (startScriptIndex != null) {
// Skip past the script to get the arguments that were passed to the script.
for (int i = (startScriptIndex + 1); i < startScriptCommandLine.length; i++) {
startScriptArgs.add(startScriptCommandLine[i]);
}
} else {
- for (int i = 0, serverArgsSize = serverArgs.size(); i < serverArgsSize; i++) {
- String serverArg = serverArgs.get(i);
- // Skip any options that the start script will take care of specifying.
- CommandLineOption option = null;
- for (CommandLineOption optionExclude : optionExcludes) {
- if ((optionExclude.getShortName() != null && (serverArg.equals('-' + optionExclude.getShortName()) || serverArg
- .startsWith('-' + optionExclude.getShortName() + "=")))
- || ((optionExclude.getLongName() != null) && (serverArg.equals("--"
- + optionExclude.getLongName()) || serverArg.startsWith("--" + optionExclude.getLongName()
- + "=")))) {
- option = optionExclude;
- break;
+ if ((optionExcludes != null) && !optionExcludes.isEmpty()) {
+ for (int i = 0, serverArgsSize = serverArgs.size(); i < serverArgsSize; i++) {
+ String serverArg = serverArgs.get(i);
+ // Skip any options that the start script will take care of specifying.
+ CommandLineOption option = null;
+ for (CommandLineOption optionExclude : optionExcludes) {
+ if ((optionExclude.getShortName() != null && (serverArg.equals('-' + optionExclude.getShortName()) || serverArg
+ .startsWith('-' + optionExclude.getShortName() + "=")))
+ || ((optionExclude.getLongName() != null) && (serverArg.equals("--"
+ + optionExclude.getLongName()) || serverArg.startsWith("--" + optionExclude.getLongName()
+ + "=")))) {
+ option = optionExclude;
+ break;
+ }
}
- }
- if (option != null) {
- if (option.isExpectsValue()
- && ((i + 1) < serverArgsSize)
- && (((option.getShortName() != null) && serverArg.equals('-' + option.getShortName())) || (option
- .getLongName() != null) && serverArg.equals("--" + option.getLongName()))) {
- // If the option expects a value and the delimiter is a space, skip the next argument too.
- i++;
+ if (option != null) {
+ if (option.isExpectsValue()
+ && ((i + 1) < serverArgsSize)
+ && (((option.getShortName() != null) && serverArg.equals('-' + option.getShortName())) || (option
+ .getLongName() != null) && serverArg.equals("--" + option.getLongName()))) {
+ // If the option expects a value and the delimiter is a space, skip the next argument too.
+ i++;
+ }
+ } else {
+ startScriptArgs.add(serverArg);
}
- } else {
- startScriptArgs.add(serverArg);
}
+ } else {
+ startScriptArgs.addAll(serverArgs);
}
}
return startScriptArgs;
}
+ /**
+ * Returns the set of environment variables that should be passed to the start script for the specified server
+ * (e.g. JBoss AS) process in order to start a functionally equivalent server instance.
+ *
+ * @param serverProcess a server (e.g. JBoss AS) process
+ * @param serverParentProcess the parent process of the server (e.g. JBoss AS) process
+ * @param envVarNameIncludes the names of the variables that should be included in the returned map, in addition to
+ * a core set of OS-level variables (PATH, LD_LIBRARY_PATH, etc.)
+ *
+ * @return the set of environment variables that should be passed to the start script for the specified server
+ * (e.g. JBoss AS) process
+ */
+ @NotNull
public static Map<String, String> getStartScriptEnv(ProcessInfo serverProcess, ProcessInfo serverParentProcess,
Set<String> envVarNameIncludes) {
Map<String, String> processEnvVars;
@@ -157,7 +190,8 @@ public class ServerStartScriptDiscoveryUtility {
processEnvVars = serverProcess.getEnvironmentVariables();
}
- List<String> fullEnvVarNameIncludes = new ArrayList<String>(envVarNameIncludes);
+ List<String> fullEnvVarNameIncludes = (envVarNameIncludes != null) ?
+ new ArrayList<String>(envVarNameIncludes) : new ArrayList<String>();
// Add the core includes at the end of the list, since end users will probably be more interested in the
// app-specific env vars.
fullEnvVarNameIncludes.addAll(CORE_ENV_VAR_NAME_INCLUDES);
@@ -178,15 +212,37 @@ public class ServerStartScriptDiscoveryUtility {
String path = systemRoot + "\\system32;" + systemRoot;
startScriptEnv.put("PATH", path);
} else {
- startScriptEnv.put("PATH", CORE_ENV_VAR_PATH_LINUX);
+ startScriptEnv.put("PATH", CORE_ENV_VAR_PATH_UNIX);
}
return startScriptEnv;
}
- private static boolean isScript(String startScript) {
+ @Nullable
+ private static Integer getStartScriptIndex(String[] serverParentProcessCommandLine) {
+ // Assuming the specified process actually is a script, it will look something like this:
+ // UNIX: "/bin/sh [options] ./standalone.sh --server-config=standalone-full.xml"
+ // Windows: "cmd.exe [options] standalone.bat --server-config=standalone-full.xml"
+
+ if (serverParentProcessCommandLine.length == 1) {
+ // The command line is an executable with no arguments - there's no way it's a script, so return null.
+ return null;
+ }
+
+ int startScriptIndex;
+ // Advance past any shell (e.g. /bin/sh or cmd.exe) options.
+ for (startScriptIndex = 1; (startScriptIndex < serverParentProcessCommandLine.length); ++startScriptIndex) {
+ if (serverParentProcessCommandLine[startScriptIndex].charAt(0) != OPTION_PREFIX) {
+ break;
+ }
+ }
+ String possibleStartScript = serverParentProcessCommandLine[startScriptIndex];
+ return (isScript(possibleStartScript)) ? startScriptIndex : null;
+ }
+
+ private static boolean isScript(String filePath) {
// TODO: What if CygWin was used to start AS7 on Windows via a shell script?
- return (startScript != null) && (startScript.endsWith(".sh") || startScript.endsWith(".bat"));
+ return (filePath != null) && (filePath.endsWith(".sh") || filePath.matches(".*\\.((bat)|(cmd))$(?i)"));
}
}
commit e69ef1e6945f9ec15f7509d77dd4441b3e1206c5
Author: Ian Springer <ian.springer(a)redhat.com>
Date: Fri Apr 27 17:13:51 2012 -0400
temporarily disable testAllResourceComponentsStarted test until the PC shutdown issue has been fixed
diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/GenericJBossAS7PluginTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/GenericJBossAS7PluginTest.java
index c6cb36a..0f797d8 100644
--- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/GenericJBossAS7PluginTest.java
+++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/GenericJBossAS7PluginTest.java
@@ -1,3 +1,21 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 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.modules.plugins.jbossas7.itest;
import java.util.HashMap;
@@ -6,11 +24,13 @@ import java.util.Map;
import org.testng.annotations.Test;
import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.plugin.testutil.AbstractAgentPluginTest;
import org.rhq.modules.plugins.jbossas7.itest.domain.ManagedServerTest;
import org.rhq.test.arquillian.RunDiscovery;
/**
- * Generic AS7 plugin tests.
+ * AS7 plugin tests that are not specific to particular Resource types. The tests delegate to methods in
+ * {@link AbstractAgentPluginTest}, which provides generic impls of such tests.
*
* @author Ian Springer
*/
@@ -18,15 +38,16 @@ import org.rhq.test.arquillian.RunDiscovery;
public class GenericJBossAS7PluginTest extends AbstractJBossAS7PluginTest {
// ****************************** LIFECYCLE ****************************** //
- @Test(priority = 1)
+ // TODO: Re-enable this once the PC shutdown issue has been fixed.
+ @Test(priority = 1, enabled = false)
@RunDiscovery
public void testAllResourceComponentsStarted() throws Exception {
- Thread.sleep(30*1000L);
assertAllResourceComponentsStarted();
}
// ******************************* METRICS ******************************* //
@Test(priority = 2)
+ @RunDiscovery
public void testAllMetricsHaveNonNullValues() throws Exception {
Map<ResourceType, String[]> excludedMetricNamesByType = new HashMap<ResourceType, String[]>();
// It's normal for the "startTime" trait to be null for a Managed Server that is down/disabled.