modules/integration-tests/apache-plugin-test/src/test/java/org/rhq/plugins/apache/setup/ApacheTestSetup.java | 9
modules/integration-tests/apache-plugin-test/src/test/java/org/rhq/plugins/apache/upgrade/UpgradeTestBase.java | 3
modules/integration-tests/apache-plugin-test/src/test/java/org/rhq/plugins/apache/util/ApacheExecutionUtil.java | 4
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheDirectoryComponent.java | 16
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheIfModuleComponent.java | 17
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheIfModuleDirectoryComponent.java | 9
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerComponent.java | 40 -
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java | 125 ++-
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceComponent.java | 38 -
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceDiscoveryComponent.java | 8
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/parser/ApacheParserImpl.java | 121 ++-
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/RuntimeApacheConfiguration.java | 341 +++++-----
modules/plugins/apache/src/test/java/org/rhq/plugins/apache/RuntimeConfigurationTest.java | 30
modules/plugins/apache/src/test/java/org/rhq/plugins/apache/SnmpMappingTest.java | 13
14 files changed, 511 insertions(+), 263 deletions(-)
New commits:
commit 9e46e174f9c47c49cdfdbbcedc0aafbcfe1c56fa
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Nov 1 16:54:22 2011 +0100
BZ 698474 - Work around the limitations in PIQL so that we don't try to
discover the parent NT service httpd process.
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
index 4fc441c..2a913f9 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
@@ -249,7 +249,9 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
for (ProcessScanResult process : processes) {
try {
DiscoveredResourceDetails apache = discoverSingleProcess(discoveryContext, process);
- discoveredResources.add(apache);
+ if (apache != null) {
+ discoveredResources.add(apache);
+ }
} catch (DiscoveryFailureException e) {
log.warn("Discovery of Apache process [" + process.getProcessInfo() + "] failed: " + e.getMessage());
} catch (Exception e) {
@@ -272,6 +274,11 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
*/
private DiscoveredResourceDetails discoverSingleProcess(ResourceDiscoveryContext<PlatformComponent> discoveryContext,
ProcessScanResult process) throws DiscoveryFailureException, Exception {
+
+ if (isWindowsServiceRootInstance(process)) {
+ return null;
+ }
+
File executablePath = getExecutableAbsolutePath(process);
log.debug("Apache executable path: " + executablePath);
@@ -362,7 +369,7 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
public ResourceUpgradeReport upgrade(ResourceUpgradeContext<PlatformComponent> context) {
String inventoriedResourceKey = context.getResourceKey();
-
+
//check if the inventoried resource has the old format of the resource key.
//the old format was "server-root", while the new format
//is "server-root||httpd-conf". Checking for "||" in the resource key is therefore
@@ -527,7 +534,7 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
return new File(serverConfigFile);
}
- private String getCommandLineOption(String[] cmdLine, String option) {
+ private static String getCommandLineOption(String[] cmdLine, String option) {
String root = null;
for (int i = 1; i < cmdLine.length; i++) {
String arg = cmdLine[i];
@@ -818,4 +825,25 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
default: throw new IllegalStateException("Unknown HttpdAddressUtility instance.");
}
}
+
+ /**
+ * We need this because of PIQL limitations.
+ *
+ * On *nixes we need to match all "root" httpd processes (i.e. with ppid of 1) but on windows
+ * we need to match all child httpd processes (i.e. processes that are spawned from the "root"
+ * httpd process).
+ *
+ * The *nix requirement causes the root httpd process be matched on Windows
+ * as well, which is undesirable but there is no way of telling PIQL
+ * "don't do this on windows" or "match only processes that DO NOT have a -k argument
+ * at all or that have it with a value different from runservice".
+ *
+ * @param process
+ * @return true if the process represents the root httpd instance if run as a windows service
+ */
+ private static boolean isWindowsServiceRootInstance(ProcessScanResult process) {
+ String kArg = getCommandLineOption(process.getProcessInfo().getCommandLine(), "-k");
+
+ return kArg != null && kArg.equalsIgnoreCase("runservice");
+ }
}
commit 4f157acecc7a902bf9ff431c8031314652fdff1f
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Nov 1 16:40:23 2011 +0100
BZ 697585 - A better warning message if an absolute path of httpd
executable can't be established + a little bit of paranoia when trying
to figure out the absolute path.
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
index 9b559cb..4fc441c 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
@@ -89,6 +89,10 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
public DiscoveryFailureException(String message) {
super(message);
}
+
+ public DiscoveryFailureException(String message, Throwable cause) {
+ super(message, cause);
+ }
}
public static final Map<String, String> MODULE_SOURCE_FILE_TO_MODULE_NAME_20;
@@ -268,17 +272,9 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
*/
private DiscoveredResourceDetails discoverSingleProcess(ResourceDiscoveryContext<PlatformComponent> discoveryContext,
ProcessScanResult process) throws DiscoveryFailureException, Exception {
- //String executablePath = process.getProcessInfo().getName();
- String executableName = getExecutableName(process);
- File executablePath = OsProcessUtility.getProcExe(process.getProcessInfo().getPid(), executableName);
- if (executablePath == null) {
- throw new DiscoveryFailureException("Executable path could not be determined.");
- }
- if (!executablePath.isAbsolute()) {
- throw new DiscoveryFailureException("Executable path (" + executablePath + ") is not absolute."
- + "Please restart Apache specifying an absolute path for the executable.");
- }
+ File executablePath = getExecutableAbsolutePath(process);
log.debug("Apache executable path: " + executablePath);
+
ApacheBinaryInfo binaryInfo;
try {
binaryInfo = ApacheBinaryInfo
@@ -563,6 +559,44 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
return executableName;
}
+ private static File getExecutableAbsolutePath(ProcessScanResult process) throws DiscoveryFailureException {
+ //String executablePath = process.getProcessInfo().getName();
+ String executableName = getExecutableName(process);
+ File executablePath = OsProcessUtility.getProcExe(process.getProcessInfo().getPid(), executableName);
+ if (executablePath == null) {
+ throw new DiscoveryFailureException("Executable path could not be determined.");
+ }
+ if (!executablePath.isAbsolute()) {
+ //try to figure out the full path... this might fail due to lack of privs
+ //if the agent is running as a different user than the httpd process
+ String errorMessage = "Executable path (" + executablePath + ") is not absolute. "
+ + "Please restart Apache specifying an absolute path for the executable or "
+ + "make sure that the user running the RHQ agent is able to access the commandline parameters of the " + executableName + " process.";
+ Throwable cause = null;
+ boolean success = false;
+
+ //the OsProcessUtility.getProcExe does an excelent job at figuring the full path and I never saw it fail
+ //when the agent process has enough privs to get at the info at all. Nevertheless, let's be paranoid
+ //and try yet another method..
+ try {
+ String cwd = process.getProcessInfo().getCurrentWorkingDirectory();
+ if (cwd != null) {
+ executablePath = new File(cwd, executablePath.getPath());
+
+ success = executablePath.isAbsolute() && executablePath.isFile();
+ }
+ } catch (Exception e) {
+ cause = e;
+ }
+
+ if (!success) {
+ throw new DiscoveryFailureException(errorMessage, cause);
+ }
+ }
+
+ return executablePath;
+ }
+
private static void validateServerRootAndServerConfigFile(Configuration pluginConfig) {
String serverRoot = pluginConfig.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_SERVER_ROOT)
.getStringValue();
commit 761e4c3202da7faabf9a6a1226a6769496d5dac9
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Oct 31 13:26:22 2011 +0100
BZ 717787 - Making sure augeas is only ever used if the apache resource
is allowed to do so.
Improved the confusing error message when augeas was not enabled that
stated that apache version is not supported or augeas is not available,
when in fact neither could be true.
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheDirectoryComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheDirectoryComponent.java
index e828818..f8ebd79 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheDirectoryComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheDirectoryComponent.java
@@ -70,6 +70,10 @@ public class ApacheDirectoryComponent implements ResourceComponent<ApacheVirtual
}
public Configuration loadResourceConfiguration() throws Exception {
+ if (!isAugeasEnabled()) {
+ throw new IllegalStateException(ApacheServerComponent.CONFIGURATION_NOT_SUPPORTED_ERROR_MESSAGE);
+ }
+
ApacheVirtualHostServiceComponent parentVirtualHost = resourceContext.getParentResourceComponent();
AugeasComponent comp = getAugeas();
@@ -87,7 +91,12 @@ public class ApacheDirectoryComponent implements ResourceComponent<ApacheVirtual
}
public void updateResourceConfiguration(ConfigurationUpdateReport report) {
-
+ if (!isAugeasEnabled()) {
+ report.setStatus(ConfigurationUpdateStatus.FAILURE);
+ report.setErrorMessage(ApacheServerComponent.CONFIGURATION_NOT_SUPPORTED_ERROR_MESSAGE);
+ return;
+ }
+
AugeasComponent comp = getAugeas();
AugeasTree tree = null;
try {
@@ -115,7 +124,12 @@ public class ApacheDirectoryComponent implements ResourceComponent<ApacheVirtual
}
public void deleteResource() throws Exception {
+ if (!isAugeasEnabled()) {
+ throw new IllegalStateException(ApacheServerComponent.CONFIGURATION_NOT_SUPPORTED_ERROR_MESSAGE);
+ }
+
ApacheVirtualHostServiceComponent parentVirtualHost = resourceContext.getParentResourceComponent();
+
AugeasComponent comp = getAugeas();
try {
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheIfModuleComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheIfModuleComponent.java
index bd6b4ee..8554038 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheIfModuleComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheIfModuleComponent.java
@@ -65,6 +65,10 @@ public class ApacheIfModuleComponent implements ResourceComponent<ApacheVirtualH
}
public Configuration loadResourceConfiguration() throws Exception {
+ if (!isAugeasEnabled()) {
+ throw new IllegalStateException(ApacheServerComponent.CONFIGURATION_NOT_SUPPORTED_ERROR_MESSAGE);
+ }
+
AugeasComponent comp = null;
try {
comp = parentComponent.getAugeas();
@@ -81,6 +85,12 @@ public class ApacheIfModuleComponent implements ResourceComponent<ApacheVirtualH
}
public void updateResourceConfiguration(ConfigurationUpdateReport report) {
+ if (!isAugeasEnabled()) {
+ report.setStatus(ConfigurationUpdateStatus.FAILURE);
+ report.setErrorMessage(ApacheServerComponent.CONFIGURATION_NOT_SUPPORTED_ERROR_MESSAGE);
+ return;
+ }
+
AugeasComponent comp = null;
AugeasTree tree = null;
try {
@@ -118,13 +128,6 @@ public class ApacheIfModuleComponent implements ResourceComponent<ApacheVirtualH
return directory;
}
- public void copy(AugeasNode a, AugeasNode b) {
- for (AugeasNode nd : a.getChildNodes()) {
- AugeasNode tempNode = tree.createNode(b, nd.getLabel(), nd.getValue(), nd.getSeq());
- copy(nd, tempNode);
- }
- }
-
public boolean isAugeasEnabled() {
return parentComponent.isAugeasEnabled();
}
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheIfModuleDirectoryComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheIfModuleDirectoryComponent.java
index dedcb3c..c97c28c 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheIfModuleDirectoryComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheIfModuleDirectoryComponent.java
@@ -63,6 +63,10 @@ public class ApacheIfModuleDirectoryComponent implements ResourceComponent<Apach
}
public Configuration loadResourceConfiguration() throws Exception {
+ if (!isAugeasEnabled()) {
+ throw new IllegalStateException(ApacheServerComponent.CONFIGURATION_NOT_SUPPORTED_ERROR_MESSAGE);
+ }
+
ConfigurationDefinition resourceConfigDef = context.getResourceType().getResourceConfigurationDefinition();
AugeasComponent comp = parentComponent.getAugeas();
AugeasTree tree = null;
@@ -78,6 +82,11 @@ public class ApacheIfModuleDirectoryComponent implements ResourceComponent<Apach
}
public void updateResourceConfiguration(ConfigurationUpdateReport report) {
+ if (!isAugeasEnabled()) {
+ report.setStatus(ConfigurationUpdateStatus.FAILURE);
+ report.setErrorMessage(ApacheServerComponent.CONFIGURATION_NOT_SUPPORTED_ERROR_MESSAGE);
+ }
+
AugeasComponent comp = parentComponent.getAugeas();
AugeasTree tree = null;
try {
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerComponent.java
index 04484ce..84f0c99 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerComponent.java
@@ -103,7 +103,10 @@ import org.rhq.rhqtransform.AugeasRHQComponent;
public class ApacheServerComponent implements AugeasRHQComponent, ResourceComponent<PlatformComponent>,
MeasurementFacet, OperationFacet, ConfigurationFacet, CreateChildResourceFacet {
- public static final String CONFIGURATION_NOT_SUPPORTED_ERROR_MESSAGE = "Configuration is supported only for Apache version 2 and up using Augeas. You either have an old version of Apache or Augeas is not installed.";
+ public static final String CONFIGURATION_NOT_SUPPORTED_ERROR_MESSAGE =
+ "Configuration and child resource creation/deletion support for Apache is optional. "
+ + "If you switched it on by enabling Augeas support in the connection settings of the Apache server resource and still get this message, "
+ + "it means that either your Apache version is not supported (only Apache 2.x is supported) or Augeas is not available on your platform.";
private final Log log = LogFactory.getLog(this.getClass());
@@ -338,7 +341,7 @@ public class ApacheServerComponent implements AugeasRHQComponent, ResourceCompon
public Configuration loadResourceConfiguration() throws Exception {
if (!isAugeasEnabled())
- throw new RuntimeException(CONFIGURATION_NOT_SUPPORTED_ERROR_MESSAGE);
+ throw new IllegalStateException(CONFIGURATION_NOT_SUPPORTED_ERROR_MESSAGE);
AugeasComponent comp = getAugeas();
try {
@@ -359,6 +362,7 @@ public class ApacheServerComponent implements AugeasRHQComponent, ResourceCompon
public void updateResourceConfiguration(ConfigurationUpdateReport report) {
if (!isAugeasEnabled()) {
report.setStatus(ConfigurationUpdateStatus.FAILURE);
+ report.setErrorMessage(ApacheServerComponent.CONFIGURATION_NOT_SUPPORTED_ERROR_MESSAGE);
return;
}
@@ -422,9 +426,10 @@ public class ApacheServerComponent implements AugeasRHQComponent, ResourceCompon
public CreateResourceReport createResource(CreateResourceReport report) {
if (!isAugeasEnabled()) {
report.setStatus(CreateResourceStatus.FAILURE);
- report.setErrorMessage("Resources can be created only when augeas is enabled.");
+ report.setErrorMessage(CONFIGURATION_NOT_SUPPORTED_ERROR_MESSAGE);
return report;
}
+
if (ApacheVirtualHostServiceComponent.RESOURCE_TYPE_NAME.equals(report.getResourceType().getName())) {
Configuration vhostResourceConfig = report.getResourceConfiguration();
ConfigurationDefinition vhostResourceConfigDef = report.getResourceType()
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceComponent.java
index 6ec95da..5dd9192 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceComponent.java
@@ -154,9 +154,11 @@ public class ApacheVirtualHostServiceComponent implements ResourceComponent<Apac
}
public Configuration loadResourceConfiguration() throws Exception {
+ if (!isAugeasEnabled()) {
+ throw new IllegalStateException(ApacheServerComponent.CONFIGURATION_NOT_SUPPORTED_ERROR_MESSAGE);
+ }
+
ApacheServerComponent parent = resourceContext.getParentResourceComponent();
- if (!parent.isAugeasEnabled())
- throw new Exception(ApacheServerComponent.CONFIGURATION_NOT_SUPPORTED_ERROR_MESSAGE);
AugeasComponent comp = getAugeas();
try {
@@ -172,6 +174,12 @@ public class ApacheVirtualHostServiceComponent implements ResourceComponent<Apac
}
public void updateResourceConfiguration(ConfigurationUpdateReport report) {
+ if (!isAugeasEnabled()) {
+ report.setStatus(ConfigurationUpdateStatus.FAILURE);
+ report.setErrorMessage(ApacheServerComponent.CONFIGURATION_NOT_SUPPORTED_ERROR_MESSAGE);
+ return;
+ }
+
AugeasComponent comp = getAugeas();
AugeasTree tree = null;
try {
@@ -188,10 +196,14 @@ public class ApacheVirtualHostServiceComponent implements ResourceComponent<Apac
finishConfigurationUpdate(report);
} catch (Exception e) {
- if (tree != null)
- log.error("Augeas failed to save configuration " + tree.summarizeAugeasError());
- else
+ if (tree != null) {
+ String message = "Augeas failed to save configuration " + tree.summarizeAugeasError();
+ report.setErrorMessage(message);
+ log.error(message);
+ } else {
+ report.setErrorMessageFromThrowable(e);
log.error("Augeas failed to save configuration", e);
+ }
report.setStatus(ConfigurationUpdateStatus.FAILURE);
} finally {
comp.close();
@@ -199,9 +211,11 @@ public class ApacheVirtualHostServiceComponent implements ResourceComponent<Apac
}
public void deleteResource() throws Exception {
+ if (!isAugeasEnabled()) {
+ throw new IllegalStateException(ApacheServerComponent.CONFIGURATION_NOT_SUPPORTED_ERROR_MESSAGE);
+ }
+
ApacheServerComponent parent = resourceContext.getParentResourceComponent();
- if (!parent.isAugeasEnabled())
- throw new Exception(ApacheServerComponent.CONFIGURATION_NOT_SUPPORTED_ERROR_MESSAGE);
if (MAIN_SERVER_RESOURCE_KEY.equals(resourceContext.getResourceKey())) {
throw new IllegalArgumentException(
@@ -276,9 +290,10 @@ public class ApacheVirtualHostServiceComponent implements ResourceComponent<Apac
public CreateResourceReport createResource(CreateResourceReport report) {
if (!isAugeasEnabled()) {
report.setStatus(CreateResourceStatus.FAILURE);
- report.setErrorMessage("Resources can be created only when augeas is enabled.");
+ report.setErrorMessage(ApacheServerComponent.CONFIGURATION_NOT_SUPPORTED_ERROR_MESSAGE);
return report;
}
+
ResourceType resourceType = report.getResourceType();
AugeasComponent comp = null;
try {
commit 7a80ae5be67c7ecb5cc68886e130b6baf8553639
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Nov 1 16:56:44 2011 +0100
BZ 687992 - A final touch on making the apache config file parsing
correct. The parser now keeps track of the "current" ServerRoot
(which is defaulted to the value hardcoded in the binary at the start and
then updated each time a ServerRoot directive is encountered during the
config file parsing).
Also made some minor refactoring to consolidate and reuse the runtime
configuration extracting routines.
A final update is to use the runtime configuration to figure out
the paths of the httpd executable as well as control script path (before
we used the full config and so could potentially get wrong results if
ServerRoot was hidden in some conditional blocks).
The runtime config is now also used when figuring out the sample address of
a virtual host during its creation.
diff --git a/modules/integration-tests/apache-plugin-test/src/test/java/org/rhq/plugins/apache/setup/ApacheTestSetup.java b/modules/integration-tests/apache-plugin-test/src/test/java/org/rhq/plugins/apache/setup/ApacheTestSetup.java
index 36ef655..b1abcbe 100644
--- a/modules/integration-tests/apache-plugin-test/src/test/java/org/rhq/plugins/apache/setup/ApacheTestSetup.java
+++ b/modules/integration-tests/apache-plugin-test/src/test/java/org/rhq/plugins/apache/setup/ApacheTestSetup.java
@@ -44,6 +44,8 @@ import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.pc.ServerServices;
import org.rhq.core.pc.upgrade.FakeServerInventory;
+import org.rhq.core.system.SystemInfoFactory;
+import org.rhq.plugins.apache.ApacheServerDiscoveryComponent;
import org.rhq.plugins.apache.ApacheVirtualHostServiceComponent;
import org.rhq.plugins.apache.ApacheVirtualHostServiceDiscoveryComponent;
import org.rhq.plugins.apache.parser.ApacheConfigReader;
@@ -51,6 +53,7 @@ import org.rhq.plugins.apache.parser.ApacheDirectiveTree;
import org.rhq.plugins.apache.parser.ApacheParser;
import org.rhq.plugins.apache.parser.ApacheParserImpl;
import org.rhq.plugins.apache.upgrade.UpgradeTestBase;
+import org.rhq.plugins.apache.util.ApacheBinaryInfo;
import org.rhq.plugins.apache.util.ApacheDeploymentUtil;
import org.rhq.plugins.apache.util.ApacheExecutionUtil;
import org.rhq.plugins.apache.util.HttpdAddressUtility;
@@ -149,10 +152,8 @@ public class ApacheTestSetup {
}
//ok, now try to find the ping URL. The best thing is to actually invoke
- //the same code the apache server discovery does.
- ApacheDirectiveTree tree = new ApacheDirectiveTree();
- ApacheParser parser = new ApacheParserImpl(tree, serverRootDir.getAbsolutePath());
- ApacheConfigReader.buildTree(confFilePath, parser);
+ //the same code the apache server discovery does.
+ ApacheDirectiveTree tree = ApacheServerDiscoveryComponent.parseRuntimeConfiguration(confFilePath, null, ApacheBinaryInfo.getInfo(exePath, SystemInfoFactory.createSystemInfo()));
//XXX this hardcodes apache2 as the only option we have...
HttpdAddressUtility.Address addrToUse = HttpdAddressUtility.APACHE_2_x.getMainServerSampleAddress(tree, null, -1);
diff --git a/modules/integration-tests/apache-plugin-test/src/test/java/org/rhq/plugins/apache/upgrade/UpgradeTestBase.java b/modules/integration-tests/apache-plugin-test/src/test/java/org/rhq/plugins/apache/upgrade/UpgradeTestBase.java
index f86b095..c8952c1 100644
--- a/modules/integration-tests/apache-plugin-test/src/test/java/org/rhq/plugins/apache/upgrade/UpgradeTestBase.java
+++ b/modules/integration-tests/apache-plugin-test/src/test/java/org/rhq/plugins/apache/upgrade/UpgradeTestBase.java
@@ -207,8 +207,7 @@ public class UpgradeTestBase extends PluginContainerTest {
protected void defineRHQ3ResourceKeys(ApacheTestConfiguration testConfig, ApacheTestSetup setup) throws Exception {
setup.withApacheSetup().init();
ApacheServerComponent component = setup.withApacheSetup().getExecutionUtil().getServerComponent();
- ApacheDirectiveTree config = component.loadParser();
- config = RuntimeApacheConfiguration.extract(config, component.getCurrentProcessInfo(), component.getCurrentBinaryInfo(), component.getModuleNames(), false);
+ ApacheDirectiveTree config = component.parseRuntimeConfiguration(false);
DeploymentConfig deployConfig = setup.getDeploymentConfig();
diff --git a/modules/integration-tests/apache-plugin-test/src/test/java/org/rhq/plugins/apache/util/ApacheExecutionUtil.java b/modules/integration-tests/apache-plugin-test/src/test/java/org/rhq/plugins/apache/util/ApacheExecutionUtil.java
index 8dc55ca..ee03318 100644
--- a/modules/integration-tests/apache-plugin-test/src/test/java/org/rhq/plugins/apache/util/ApacheExecutionUtil.java
+++ b/modules/integration-tests/apache-plugin-test/src/test/java/org/rhq/plugins/apache/util/ApacheExecutionUtil.java
@@ -149,9 +149,7 @@ public class ApacheExecutionUtil {
}
public ApacheDirectiveTree getRuntimeConfiguration() {
- ApacheDirectiveTree config = serverComponent.loadParser();
- return RuntimeApacheConfiguration.extract(config, resourceContext.getNativeProcess(), new ApacheBinaryInfo(
- exePath), serverComponent.getModuleNames(), true);
+ return serverComponent.parseRuntimeConfiguration(true);
}
public ApacheServerComponent getServerComponent() {
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerComponent.java
index d180fe6..04484ce 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerComponent.java
@@ -81,11 +81,8 @@ import org.rhq.plugins.apache.augeas.ApacheAugeasNode;
import org.rhq.plugins.apache.augeas.AugeasConfigurationApache;
import org.rhq.plugins.apache.augeas.AugeasTreeBuilderApache;
import org.rhq.plugins.apache.mapping.ApacheAugeasMapping;
-import org.rhq.plugins.apache.parser.ApacheConfigReader;
import org.rhq.plugins.apache.parser.ApacheDirective;
import org.rhq.plugins.apache.parser.ApacheDirectiveTree;
-import org.rhq.plugins.apache.parser.ApacheParser;
-import org.rhq.plugins.apache.parser.ApacheParserImpl;
import org.rhq.plugins.apache.util.ApacheBinaryInfo;
import org.rhq.plugins.apache.util.ConfigurationTimestamp;
import org.rhq.plugins.apache.util.HttpdAddressUtility;
@@ -403,6 +400,7 @@ public class ApacheServerComponent implements AugeasRHQComponent, ResourceCompon
public AugeasComponent getAugeas() throws AugeasTreeException {
return new AugeasComponent() {
+ @Override
public AugeasConfiguration initConfiguration() {
File tempDir = resourceContext.getDataDirectory();
if (!tempDir.exists())
@@ -412,6 +410,7 @@ public class ApacheServerComponent implements AugeasRHQComponent, ResourceCompon
return config;
}
+ @Override
public AugeasTreeBuilder initTreeBuilder() {
AugeasTreeBuilderApache builder = new AugeasTreeBuilderApache();
return builder;
@@ -445,10 +444,7 @@ public class ApacheServerComponent implements AugeasRHQComponent, ResourceCompon
String[] vhostDefs = vhostDef.split(" ");
HttpdAddressUtility.Address addr;
try {
- ApacheDirectiveTree parserTree = new ApacheDirectiveTree();
- ApacheParser parser = new ApacheParserImpl(parserTree, getServerRoot().getAbsolutePath());
-
- ApacheConfigReader.buildTree(getHttpdConfFile().getAbsolutePath(), parser);
+ ApacheDirectiveTree parserTree = parseRuntimeConfiguration(true);
Pattern virtualHostPattern = Pattern.compile(".+:([\\d]+|\\*)");
Matcher matcher = virtualHostPattern.matcher(vhostDefs[0]);
@@ -632,7 +628,7 @@ public class ApacheServerComponent implements AugeasRHQComponent, ResourceCompon
} else {
String serverRoot = null;
- ApacheDirectiveTree tree = loadParser();
+ ApacheDirectiveTree tree = parseRuntimeConfiguration(true);
List<ApacheDirective> directives = tree.search("/ServerRoot");
if (!directives.isEmpty())
if (!directives.get(0).getValues().isEmpty())
@@ -700,7 +696,7 @@ public class ApacheServerComponent implements AugeasRHQComponent, ResourceCompon
// First try server root as base
String serverRoot = null;
try {
- ApacheDirectiveTree tree = loadParser();
+ ApacheDirectiveTree tree = parseRuntimeConfiguration(true);
List<ApacheDirective> directives = tree.search("/ServerRoot");
if (!directives.isEmpty())
if (!directives.get(0).getValues().isEmpty())
@@ -962,13 +958,18 @@ public class ApacheServerComponent implements AugeasRHQComponent, ResourceCompon
}
}
- public ApacheDirectiveTree loadParser() {
- ApacheDirectiveTree tree = new ApacheDirectiveTree();
- ApacheParser parser = new ApacheParserImpl(tree, getServerRoot().getAbsolutePath());
- ApacheConfigReader.buildTree(getHttpdConfFile().getAbsolutePath(), parser);
- return tree;
+ public ApacheDirectiveTree parseFullConfiguration() {
+ String httpdConfPath = getHttpdConfFile().getAbsolutePath();
+ return ApacheServerDiscoveryComponent.parseFullConfiguration(httpdConfPath, binaryInfo.getRoot());
}
+ public ApacheDirectiveTree parseRuntimeConfiguration(boolean suppressUnknownModuleWarnings) {
+ String httpdConfPath = getHttpdConfFile().getAbsolutePath();
+ ProcessInfo processInfo = resourceContext.getNativeProcess();
+
+ return ApacheServerDiscoveryComponent.parseRuntimeConfiguration(httpdConfPath, processInfo, binaryInfo, getModuleNames(), suppressUnknownModuleWarnings);
+ }
+
public boolean isAugeasEnabled() {
Configuration pluginConfig = this.resourceContext.getPluginConfiguration();
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
index 565fd3c..9b559cb 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
@@ -321,10 +321,7 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
pluginConfig.put(new PropertyList(ApacheServerComponent.PLUGIN_CONFIG_CUSTOM_MODULE_NAMES));
- ApacheDirectiveTree serverConfig = loadParser(serverConfigFile.getAbsolutePath(), serverRoot);
-
- //extract the runtime configuration out of declared config
- serverConfig = RuntimeApacheConfiguration.extract(serverConfig, process.getProcessInfo(), binaryInfo, getDefaultModuleNames(binaryInfo.getVersion()), true);
+ ApacheDirectiveTree serverConfig = parseRuntimeConfiguration(serverConfigFile.getAbsolutePath(), process.getProcessInfo(), binaryInfo);
String serverUrl = null;
String vhostsGlobInclude = null;
@@ -334,11 +331,8 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
if (!serverRoots.isEmpty()) {
serverRoot = AugeasNodeValueUtil.unescape(serverRoots.get(0).getValuesAsString());
serverRootProp.setValue(serverRoot);
- //reparse the configuration with the new ServerRoot
- serverConfig = loadParser(serverConfigFile.getAbsolutePath(), serverRoot);
- serverConfig = RuntimeApacheConfiguration.extract(serverConfig, process.getProcessInfo(), binaryInfo, getDefaultModuleNames(binaryInfo.getVersion()), true);
}
-
+
serverUrl = getUrl(serverConfig, binaryInfo.getVersion());
vhostsGlobInclude = scanForGlobInclude(serverConfig);
@@ -597,14 +591,35 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
}
}
- public static ApacheDirectiveTree loadParser(String path, String serverRoot) {
-
+ public static ApacheDirectiveTree parseFullConfiguration(String path, String serverRoot) {
ApacheDirectiveTree tree = new ApacheDirectiveTree();
- ApacheParser parser = new ApacheParserImpl(tree, serverRoot);
+ ApacheParser parser = new ApacheParserImpl(tree, serverRoot, null);
ApacheConfigReader.buildTree(path, parser);
return tree;
}
+ public static ApacheDirectiveTree parseRuntimeConfiguration(String path, ProcessInfo processInfo,
+ ApacheBinaryInfo binaryInfo) {
+
+ String httpdVersion = binaryInfo.getVersion();
+ Map<String, String> defaultModuleNames = getDefaultModuleNames(httpdVersion);
+
+ return parseRuntimeConfiguration(path, processInfo, binaryInfo, defaultModuleNames, true);
+ }
+
+ public static ApacheDirectiveTree parseRuntimeConfiguration(String path, ProcessInfo processInfo, ApacheBinaryInfo binaryInfo, Map<String, String> moduleNames, boolean suppressUnknownModuleWarnings) {
+ String defaultServerRoot = binaryInfo.getRoot();
+
+ RuntimeApacheConfiguration.NodeInspector insp =
+ RuntimeApacheConfiguration.getNodeInspector(processInfo, binaryInfo,
+ moduleNames, suppressUnknownModuleWarnings);
+
+ ApacheDirectiveTree tree = new ApacheDirectiveTree();
+ ApacheParser parser = new ApacheParserImpl(tree, defaultServerRoot, insp);
+ ApacheConfigReader.buildTree(path, parser);
+ return tree;
+ }
+
public static String scanForGlobInclude(ApacheDirectiveTree tree) {
try {
List<ApacheDirective> includes = tree.search("/Include");
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceComponent.java
index c83c665..6ec95da 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceComponent.java
@@ -528,8 +528,7 @@ public class ApacheVirtualHostServiceComponent implements ResourceComponent<Apac
//only look for the vhost entry if the vhost we're looking for isn't the main server
if (!MAIN_SERVER_RESOURCE_KEY.equals(vhostAddressStrings[0])) {
- ApacheDirectiveTree tree = parent.loadParser();
- tree = RuntimeApacheConfiguration.extract(tree, parent.getCurrentProcessInfo(), parent.getCurrentBinaryInfo(), parent.getModuleNames(), false);
+ ApacheDirectiveTree tree = parent.parseRuntimeConfiguration(false);
//find the vhost entry the resource key represents
List<ApacheDirective> vhosts = tree.search("/<VirtualHost");
@@ -603,10 +602,6 @@ public class ApacheVirtualHostServiceComponent implements ResourceComponent<Apac
return resourceContext.getResourceType().getChildResourceTypes().iterator().next();
}
- public ApacheDirectiveTree loadParser() throws Exception {
- return resourceContext.getParentResourceComponent().loadParser();
- }
-
public boolean isAugeasEnabled() {
ApacheServerComponent parent = resourceContext.getParentResourceComponent();
return parent.isAugeasEnabled();
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceDiscoveryComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceDiscoveryComponent.java
index e2c68f3..daf27fd 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceDiscoveryComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceDiscoveryComponent.java
@@ -81,9 +81,7 @@ public class ApacheVirtualHostServiceDiscoveryComponent implements ResourceDisco
Set<DiscoveredResourceDetails> discoveredResources = new LinkedHashSet<DiscoveredResourceDetails>();
ApacheServerComponent serverComponent = context.getParentResourceComponent();
- ApacheDirectiveTree tree = serverComponent.loadParser();
-
- tree = RuntimeApacheConfiguration.extract(tree, serverComponent.getCurrentProcessInfo(), serverComponent.getCurrentBinaryInfo(), serverComponent.getModuleNames(), false);
+ ApacheDirectiveTree tree = serverComponent.parseRuntimeConfiguration(false);
//first define the root server as one virtual host
discoverMainServer(context, tree, discoveredResources);
@@ -164,9 +162,7 @@ public class ApacheVirtualHostServiceDiscoveryComponent implements ResourceDisco
ApacheServerComponent serverComponent = inventoriedResource.getParentResourceComponent();
- ApacheDirectiveTree tree = serverComponent.loadParser();
- tree = RuntimeApacheConfiguration.extract(tree, serverComponent.getCurrentProcessInfo(),
- serverComponent.getCurrentBinaryInfo(), serverComponent.getModuleNames(), false);
+ ApacheDirectiveTree tree = serverComponent.parseRuntimeConfiguration(false);
List<VHostSpec> vhosts = VHostSpec.detect(tree);
VirtualHostLegacyResourceKeyUtil legacyResourceKeyUtil = new VirtualHostLegacyResourceKeyUtil(serverComponent, tree);
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/parser/ApacheParserImpl.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/parser/ApacheParserImpl.java
index f563ccd..bba00bf 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/parser/ApacheParserImpl.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/parser/ApacheParserImpl.java
@@ -22,26 +22,43 @@ import java.io.File;
import java.util.List;
import org.rhq.augeas.util.Glob;
+import org.rhq.plugins.apache.util.AugeasNodeValueUtil;
+import org.rhq.plugins.apache.util.RuntimeApacheConfiguration;
/**
*
* @author Filip Drabek
+ * @author Lukas Krejci
*/
public class ApacheParserImpl implements ApacheParser {
private final static String INCLUDE_DIRECTIVE = "Include";
+ private static final String SERVER_ROOT_DIRECTIVE = "ServerRoot";
private final ApacheDirectiveTree tree;
private ApacheDirectiveStack stack;
private String serverRootPath;
-
- public ApacheParserImpl(ApacheDirectiveTree tree, String serverRootPath) {
+ private RuntimeApacheConfiguration.NodeInspector nodeInspector;
+
+ /**
+ *
+ * @param tree the tree that this parser will fill in
+ * @param initialServerRootPath the initial server root path as detected by other means
+ * @param nodeInspector the node inspector to determine the runtime configuration or null, if full configuration tree is needed
+ */
+ public ApacheParserImpl(ApacheDirectiveTree tree, String initialServerRootPath, RuntimeApacheConfiguration.NodeInspector nodeInspector) {
stack = new ApacheDirectiveStack();
- this.serverRootPath = serverRootPath;
+ this.serverRootPath = initialServerRootPath;
this.tree = tree;
stack.addDirective(this.tree.getRootNode());
+ this.nodeInspector = nodeInspector;
}
public void addDirective(ApacheDirective directive) throws Exception {
+ if (stack.getLastDirective() == null) {
+ //we're ignoring until the end of an ignored nested directive
+ return;
+ }
+
if (directive.getName().equals(INCLUDE_DIRECTIVE)) {
List<File> files = getIncludeFiles(directive.getValuesAsString());
for (File fl : files) {
@@ -49,7 +66,15 @@ public class ApacheParserImpl implements ApacheParser {
ApacheConfigReader.searchFile(fl.getAbsolutePath(), this);
}
}
+ } else if (directive.getName().equals(SERVER_ROOT_DIRECTIVE)) {
+ this.serverRootPath = AugeasNodeValueUtil.unescape(directive.getValuesAsString());
}
+
+ if (nodeInspector != null) {
+ //let the inspector process this directive in case it sees something of interest
+ nodeInspector.inspect(directive.getName(), directive.getValues(), directive.getValuesAsString());
+ }
+
directive.setParentNode(stack.getLastDirective());
stack.getLastDirective().addChildDirective(directive);
}
@@ -59,9 +84,45 @@ public class ApacheParserImpl implements ApacheParser {
}
public void startNestedDirective(ApacheDirective directive) {
- directive.setParentNode(stack.getLastDirective());
- stack.getLastDirective().addChildDirective(directive);
- stack.addDirective(directive);
+ if (nodeInspector != null) {
+ //now we have a node inspector so the tree construction is driven by it - we actually leave out the conditional
+ //directives and replace them with their contents (if they are to be applied of course)...
+
+ RuntimeApacheConfiguration.NodeInspectionResult res = nodeInspector.inspect(directive.getName(), directive.getValues(), directive.getValuesAsString());
+ if (res == null || (res.nodeIsConditional && !res.shouldRecurseIntoConditionalNode)) {
+ //ok, this node should be ignored, mark that fact with a null parent
+ stack.addDirective(null);
+ } else if (res.nodeIsConditional && res.shouldRecurseIntoConditionalNode) {
+ //this is a little tricky..
+ //we need to leave out this directive, because it is conditional and we should be replacing it with its contents
+ //but also we need to keep the stack balanced (i.e. we're going down a nested directive, so we ought to put something
+ //on the stack). By duplicating the last known directive on the stack we actually achieve both of the goals - the
+ //stack remains balanced and the child nodes get added to the parent of this directive (i.e. in the end it is going to
+ //look like we've replaced the directive with its child directives).
+ stack.addDirective(stack.getLastDirective());
+ } else {
+ //ok, a "normal" (non-conditional) nested node
+ //we might be inside an ignored nested directive, so leave all the weaving stuff
+ //out in that case...
+ if (stack.getLastDirective() != null) {
+ directive.setParentNode(stack.getLastDirective());
+ stack.getLastDirective().addChildDirective(directive);
+ }
+ stack.addDirective(directive);
+ }
+ } else {
+ //there is no node inspector, so we have no "guidance" on the tree construction.
+ //Just include all the nested structures so that a full configuration tree is built
+ //with all the directives.
+
+ //we might be inside an ignored nested directive, so leave all the weaving stuff
+ //out in that case...
+ if (stack.getLastDirective() != null) {
+ directive.setParentNode(stack.getLastDirective());
+ stack.getLastDirective().addChildDirective(directive);
+ }
+ stack.addDirective(directive);
+ }
}
private List<File> getIncludeFiles(String foundInclude) {
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/RuntimeApacheConfiguration.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/RuntimeApacheConfiguration.java
index 1f00aec..f8a0bdb 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/RuntimeApacheConfiguration.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/RuntimeApacheConfiguration.java
@@ -59,6 +59,185 @@ public class RuntimeApacheConfiguration {
}
/**
+ * A result of a node inspection using {@link NodeInspector}
+ *
+ *
+ * @author Lukas Krejci
+ */
+ public static class NodeInspectionResult {
+ public boolean nodeIsConditional;
+ public boolean shouldRecurseIntoConditionalNode;
+ }
+
+ /**
+ * Node inspector is used to determine how to proceed with the parsing of the configuration file.
+ *
+ *
+ * @author Lukas Krejci
+ */
+ public static class NodeInspector {
+ private TransformState state;
+
+ private NodeInspector(TransformState state) {
+ this.state = state;
+ }
+
+ /**
+ * Inspects a node.
+ *
+ * @param currentNodeName the name of the node
+ * @param allValues the list of all values specified on the node
+ * @param valueAsString the original value as a string (from which the list of values was somehow produced)
+ * @return the inspection result or null if there was some unexpected event (which has been logged)
+ */
+ public NodeInspectionResult inspect(String currentNodeName, List<String> allValues, String valueAsString) {
+ NodeInspectionResult result = new NodeInspectionResult();
+
+ result.shouldRecurseIntoConditionalNode = true;
+
+ if (currentNodeName.equalsIgnoreCase("LoadModule")) {
+ state.loadedModules.add(allValues.get(0));
+ result.nodeIsConditional = false;
+ } else if (currentNodeName.equalsIgnoreCase("<IfModule")) {
+ String moduleFile = valueAsString;
+ boolean negate = false;
+ if (moduleFile.startsWith("!")) {
+ negate = true;
+ moduleFile = moduleFile.substring(1);
+ }
+
+ boolean moduleLoaded = false;
+
+ switch (isModuleLoaded(moduleFile, state.loadedModules, state.moduleNames, state.moduleFiles)) {
+ case LOADED:
+ moduleLoaded = true;
+ break;
+ case NOT_LOADED:
+ moduleLoaded = false;
+ break;
+ case UNKNOWN:
+ if (state.suppressUnknownModuleWarnings && LOGGED_UNKNOWN_MODULES.contains(moduleFile)) {
+ LOG.debug("Encountered unknown module name in an IfModule directive: " + moduleFile);
+ } else {
+ LOG.warn("Encountered unknown module name in an IfModule directive: "
+ + moduleFile + ". If you are using Apache 2.1 or later, you can try changing the module identifier from the source file to "
+ + "the actual module name as used in the LoadModule directive to get rid of this warning.");
+ }
+ LOGGED_UNKNOWN_MODULES.add(moduleFile);
+ return null;
+ }
+
+ result.shouldRecurseIntoConditionalNode = moduleLoaded != negate;
+
+ result.nodeIsConditional = true;
+ } else if (currentNodeName.equalsIgnoreCase("<IfDefine")) {
+ String define = valueAsString;
+ boolean negate = false;
+ if (define.startsWith("!")) {
+ negate = true;
+ define = define.substring(1);
+ }
+
+ boolean isDefined = state.defines.contains(define);
+
+ result.shouldRecurseIntoConditionalNode = isDefined != negate;
+
+ result.nodeIsConditional = true;
+ } else if (currentNodeName.equalsIgnoreCase("<IfVersion")) {
+ //<IfVersion [[!]operator] version> ... </IfVersion>
+ //operator: =, ==, >, >=, <, <=, ~
+ //version major[.minor[.patch]] or /regex/
+ //if operator is ~, the version is assumed regex
+ //if operator is omitted, = is assumed
+
+ if (isModuleLoaded("mod_version.c", state.loadedModules, state.moduleNames, state.moduleFiles) != ModuleLoadedState.LOADED) {
+ LOG.debug("mod_version not loaded and IfVersion directive encountered. Skipping it.");
+ return null;
+ }
+
+ List<String> values = allValues;
+ String operator = null;
+ String version = null;
+ boolean negate = false;
+ boolean regex = false;
+
+ if (values.size() == 0) {
+ LOG.warn("Invalid IfVersion directive.");
+ return null;
+ }
+
+ if (values.size() == 1) {
+ operator = "=";
+ version = values.get(0);
+ } else if (values.size() == 2) {
+ operator = values.get(0);
+ version = values.get(1);
+ } else {
+ LOG.warn("Too many arguments to a IfVersion directive: " + values);
+ return null;
+ }
+
+ if (operator == null || version == null) {
+ LOG.warn("Invalid IfVersion with parameters: " + values);
+ return null;
+ }
+
+ if (operator.charAt(0) == '!') {
+ negate = true;
+ operator = operator.substring(1);
+ }
+
+ if ("==".equals(operator)) {
+ operator = "=";
+ }
+
+ if (version.charAt(0) == '/') {
+ if ("=".equals(operator) || "~".equals(operator)) {
+ regex = true;
+ version = version.substring(1, version.length() - 1);
+ } else {
+ LOG.warn("Unsupported operator " + operator
+ + " with regex version comparison in IfVersion directive.");
+ return null;
+ }
+ }
+
+ OSGiVersionComparator comp = new OSGiVersionComparator();
+
+ boolean hasVersion = false;
+ if ("=".equals(operator)) {
+ if (regex) {
+ hasVersion = Pattern.matches(version, state.httpdVersion);
+ } else {
+ hasVersion = comp.compare(version, state.httpdVersion) == 0;
+ }
+ } else if ("~".equals(operator)) {
+ hasVersion = Pattern.matches(version, state.httpdVersion);
+ } else if (">".equals(operator)) {
+ hasVersion = comp.compare(state.httpdVersion, version) > 0;
+ } else if (">=".equals(operator)) {
+ hasVersion = comp.compare(state.httpdVersion, version) >= 0;
+ } else if ("<".equals(operator)) {
+ hasVersion = comp.compare(state.httpdVersion, version) < 0;
+ } else if ("<=".equals(operator)) {
+ hasVersion = comp.compare(state.httpdVersion, version) <= 0;
+ } else {
+ LOG.warn("Unknown operator " + operator + " in an IfVersion directive.");
+ return null;
+ }
+
+ result.shouldRecurseIntoConditionalNode = hasVersion != negate;
+
+ result.nodeIsConditional = true;
+ } else {
+ result.nodeIsConditional = false;
+ }
+
+ return result;
+ }
+ }
+
+ /**
* This is a node visitor interface to be implemented by the users of the
* {@link RuntimeApacheConfiguration#walkRuntimeConfig(ApacheAugeasTree, ProcessInfo, ApacheBinaryInfo, Map)}
* or {@link RuntimeApacheConfiguration#walkRuntimeConfig(ApacheDirectiveTree, ProcessInfo, ApacheBinaryInfo, Map)}
@@ -244,6 +423,11 @@ public class RuntimeApacheConfiguration {
}
}
+ public static NodeInspector getNodeInspector(ProcessInfo httpdProcessInfo, ApacheBinaryInfo httpdBinaryInfo, Map<String, String> moduleNames, boolean suppressUnknownModuleWarnings) {
+ return new NodeInspector(new TransformState(httpdProcessInfo, httpdBinaryInfo,
+ moduleNames, suppressUnknownModuleWarnings));
+ }
+
/**
* Given the apache configuration and information about the parameters httpd was executed
* with this method provides the directive tree that corresponds to the actual
@@ -263,7 +447,7 @@ public class RuntimeApacheConfiguration {
public static ApacheDirectiveTree extract(ApacheDirectiveTree tree, ProcessInfo httpdProcessInfo,
ApacheBinaryInfo httpdBinaryInfo, Map<String, String> moduleNames, boolean suppressUnknownModuleWarnings) {
ApacheDirectiveTree ret = tree.clone();
- transform(new TransformingWalker(), ret.getRootNode(), new TransformState(httpdProcessInfo, httpdBinaryInfo,
+ transform(new TransformingWalker(), ret.getRootNode(), getNodeInspector(httpdProcessInfo, httpdBinaryInfo,
moduleNames, suppressUnknownModuleWarnings));
return ret;
@@ -303,7 +487,7 @@ public class RuntimeApacheConfiguration {
}
};
- transform(walker, tree.getRootNode(), new TransformState(httpdProcessInfo, httpdBinaryInfo, moduleNames, suppressUnknownModuleWarnings));
+ transform(walker, tree.getRootNode(), getNodeInspector(httpdProcessInfo, httpdBinaryInfo, moduleNames, suppressUnknownModuleWarnings));
}
public static void walkRuntimeConfig(final NodeVisitor<AugeasNode> visitor, AugeasTree tree,
@@ -350,10 +534,10 @@ public class RuntimeApacheConfiguration {
return node.getLabel();
}
};
- transform(walker, tree.getRootNode(), new TransformState(httpdProcessInfo, httpdBinaryInfo, moduleNames, suppressUnknownModuleWarnings));
+ transform(walker, tree.getRootNode(), getNodeInspector(httpdProcessInfo, httpdBinaryInfo, moduleNames, suppressUnknownModuleWarnings));
}
- private static <T> void transform(TreeWalker<T> walker, T parentNode, TransformState state) {
+ private static <T> void transform(TreeWalker<T> walker, T parentNode, NodeInspector inspector) {
if (walker.getChildren(parentNode).isEmpty()) {
return;
}
@@ -361,148 +545,17 @@ public class RuntimeApacheConfiguration {
walker.onBeforeChildrenScan(parentNode);
for (T node : walker.getChildren(parentNode)) {
- boolean recurseFurther = true;
-
- if (walker.getName(node).equalsIgnoreCase("LoadModule")) {
- state.loadedModules.add(walker.getValues(node).get(0));
+ NodeInspectionResult result = inspector.inspect(walker.getName(node), walker.getValues(node), walker.getValue(node));
+ if (result == null) {
+ continue;
+ }
+ if (!result.nodeIsConditional) {
walker.visitOrdinaryNode(node);
- } else if (walker.getName(node).equalsIgnoreCase("<IfModule")) {
- String moduleFile = walker.getValue(node);
- boolean negate = false;
- if (moduleFile.startsWith("!")) {
- negate = true;
- moduleFile = moduleFile.substring(1);
- }
-
- boolean result = false;
-
- switch (isModuleLoaded(moduleFile, state.loadedModules, state.moduleNames, state.moduleFiles)) {
- case LOADED:
- result = true;
- break;
- case NOT_LOADED:
- result = false;
- break;
- case UNKNOWN:
- if (state.suppressUnknownModuleWarnings && LOGGED_UNKNOWN_MODULES.contains(moduleFile)) {
- LOG.debug("Encountered unknown module name in an IfModule directive: " + moduleFile);
- } else {
- LOG.warn("Encountered unknown module name in an IfModule directive: "
- + moduleFile + ". If you are using Apache 2.1 or later, you can try changing the module identifier from the source file to "
- + "the actual module name as used in the LoadModule directive to get rid of this warning.");
- }
- LOGGED_UNKNOWN_MODULES.add(moduleFile);
- continue;
- }
-
- recurseFurther = result != negate;
-
- walker.visitConditionalNode(node, recurseFurther);
- } else if (walker.getName(node).equalsIgnoreCase("<IfDefine")) {
- String define = walker.getValue(node);
- boolean negate = false;
- if (define.startsWith("!")) {
- negate = true;
- define = define.substring(1);
- }
-
- boolean result = state.defines.contains(define);
-
- recurseFurther = result != negate;
-
- walker.visitConditionalNode(node, recurseFurther);
- } else if (walker.getName(node).equalsIgnoreCase("<IfVersion")) {
- //<IfVersion [[!]operator] version> ... </IfVersion>
- //operator: =, ==, >, >=, <, <=, ~
- //version major[.minor[.patch]] or /regex/
- //if operator is ~, the version is assumed regex
- //if operator is omitted, = is assumed
-
- if (isModuleLoaded("mod_version.c", state.loadedModules, state.moduleNames, state.moduleFiles) != ModuleLoadedState.LOADED) {
- LOG.debug("mod_version not loaded and IfVersion directive encountered. Skipping it.");
- continue;
- }
-
- List<String> values = walker.getValues(node);
- String operator = null;
- String version = null;
- boolean negate = false;
- boolean regex = false;
-
- if (values.size() == 0) {
- LOG.warn("Invalid IfVersion directive.");
- continue;
- }
-
- if (values.size() == 1) {
- operator = "=";
- version = values.get(0);
- } else if (values.size() == 2) {
- operator = values.get(0);
- version = values.get(1);
- } else {
- LOG.warn("Too many arguments to a IfVersion directive: " + values);
- continue;
- }
-
- if (operator == null || version == null) {
- LOG.warn("Invalid IfVersion with parameters: " + values);
- continue;
- }
-
- if (operator.charAt(0) == '!') {
- negate = true;
- operator = operator.substring(1);
- }
-
- if ("==".equals(operator)) {
- operator = "=";
- }
-
- if (version.charAt(0) == '/') {
- if ("=".equals(operator) || "~".equals(operator)) {
- regex = true;
- version = version.substring(1, version.length() - 1);
- } else {
- LOG.warn("Unsupported operator " + operator
- + " with regex version comparison in IfVersion directive.");
- continue;
- }
- }
-
- OSGiVersionComparator comp = new OSGiVersionComparator();
-
- boolean result = false;
- if ("=".equals(operator)) {
- if (regex) {
- result = Pattern.matches(version, state.httpdVersion);
- } else {
- result = comp.compare(version, state.httpdVersion) == 0;
- }
- } else if ("~".equals(operator)) {
- result = Pattern.matches(version, state.httpdVersion);
- } else if (">".equals(operator)) {
- result = comp.compare(state.httpdVersion, version) > 0;
- } else if (">=".equals(operator)) {
- result = comp.compare(state.httpdVersion, version) >= 0;
- } else if ("<".equals(operator)) {
- result = comp.compare(state.httpdVersion, version) < 0;
- } else if ("<=".equals(operator)) {
- result = comp.compare(state.httpdVersion, version) <= 0;
- } else {
- LOG.warn("Unknown operator " + operator + " in an IfVersion directive.");
- continue;
- }
-
- recurseFurther = result != negate;
-
- walker.visitConditionalNode(node, recurseFurther);
} else {
- walker.visitOrdinaryNode(node);
- }
-
- if (recurseFurther) {
- transform(walker, node, state);
+ walker.visitConditionalNode(node, result.shouldRecurseIntoConditionalNode);
+ if (result.shouldRecurseIntoConditionalNode) {
+ transform(walker, node, inspector);
+ }
}
}
walker.onAfterChildrenScan(parentNode);
diff --git a/modules/plugins/apache/src/test/java/org/rhq/plugins/apache/RuntimeConfigurationTest.java b/modules/plugins/apache/src/test/java/org/rhq/plugins/apache/RuntimeConfigurationTest.java
index 4a15b40..74f4e81 100644
--- a/modules/plugins/apache/src/test/java/org/rhq/plugins/apache/RuntimeConfigurationTest.java
+++ b/modules/plugins/apache/src/test/java/org/rhq/plugins/apache/RuntimeConfigurationTest.java
@@ -94,15 +94,14 @@ public class RuntimeConfigurationTest {
public void testConditionalInclusion() {
MockApacheBinaryInfo binfo = new MockApacheBinaryInfo();
binfo.setVersion("2.2.17");
+ binfo.setRoot(new File(tmpDir, "runtime-config/conditional").getAbsolutePath());
MockProcessInfo pinfo = new MockProcessInfo();
- pinfo.setCommandLine(new String[] {"blahblah", "-D", "DEFINED"});
-
- ApacheDirectiveTree tree = new ApacheDirectiveTree();
- ApacheParser parser = new ApacheParserImpl(tree, new File(tmpDir, "runtime-config/conditional").getAbsolutePath());
- ApacheConfigReader.buildTree(new File(tmpDir, "runtime-config/conditional/httpd.conf").getAbsolutePath(), parser);
-
- tree = RuntimeApacheConfiguration.extract(tree, pinfo, binfo, ApacheServerDiscoveryComponent.MODULE_SOURCE_FILE_TO_MODULE_NAME_20, false);
-
+ pinfo.setCommandLine(new String[] { "blahblah", "-D", "DEFINED" });
+
+ ApacheDirectiveTree tree =
+ ApacheServerDiscoveryComponent.parseRuntimeConfiguration(new File(tmpDir,
+ "runtime-config/conditional/httpd.conf").getAbsolutePath(), pinfo, binfo);
+
List<VhostSpec> vhosts = VhostSpec.detect(tree);
List<VhostSpec> expectedVhosts = new ArrayList<VhostSpec>();
@@ -124,15 +123,14 @@ public class RuntimeConfigurationTest {
public void testInclusionOrder() {
MockApacheBinaryInfo binfo = new MockApacheBinaryInfo();
binfo.setVersion("2.2.17");
+ binfo.setRoot(new File(tmpDir, "runtime-config/incl-order").getAbsolutePath());
MockProcessInfo pinfo = new MockProcessInfo();
- pinfo.setCommandLine(new String[] {"blahblah"});
-
- ApacheDirectiveTree tree = new ApacheDirectiveTree();
- ApacheParser parser = new ApacheParserImpl(tree, new File(tmpDir, "runtime-config/incl-order").getAbsolutePath());
- ApacheConfigReader.buildTree(new File(tmpDir, "runtime-config/incl-order/httpd.conf").getAbsolutePath(), parser);
-
- tree = RuntimeApacheConfiguration.extract(tree, pinfo, binfo, ApacheServerDiscoveryComponent.MODULE_SOURCE_FILE_TO_MODULE_NAME_20, false);
-
+ pinfo.setCommandLine(new String[] { "blahblah" });
+
+ ApacheDirectiveTree tree =
+ ApacheServerDiscoveryComponent.parseRuntimeConfiguration(new File(tmpDir,
+ "runtime-config/incl-order/httpd.conf").getAbsolutePath(), pinfo, binfo);
+
List<ApacheDirective> listens = tree.search("/Listen");
assertEquals(listens.size(), 3, "There should be 3 listen directives");
diff --git a/modules/plugins/apache/src/test/java/org/rhq/plugins/apache/SnmpMappingTest.java b/modules/plugins/apache/src/test/java/org/rhq/plugins/apache/SnmpMappingTest.java
index 19fdb67..fd825c1 100644
--- a/modules/plugins/apache/src/test/java/org/rhq/plugins/apache/SnmpMappingTest.java
+++ b/modules/plugins/apache/src/test/java/org/rhq/plugins/apache/SnmpMappingTest.java
@@ -101,13 +101,14 @@ public class SnmpMappingTest {
public void testVhostNames() {
MockApacheBinaryInfo binfo = new MockApacheBinaryInfo();
binfo.setVersion("2.2.17");
+ binfo.setRoot(new File(tmpDir, "snmp-mapping").getAbsolutePath());
MockProcessInfo pinfo = new MockProcessInfo();
- pinfo.setCommandLine(new String[] {"blahblah"});
-
- ApacheDirectiveTree tree = new ApacheDirectiveTree();
- ApacheParser parser = new ApacheParserImpl(tree, new File(tmpDir, "snmp-mapping").getAbsolutePath());
- ApacheConfigReader.buildTree(new File(tmpDir, "snmp-mapping/httpd.conf").getAbsolutePath(), parser);
-
+ pinfo.setCommandLine(new String[] { "blahblah" });
+
+ ApacheDirectiveTree tree =
+ ApacheServerDiscoveryComponent.parseRuntimeConfiguration(
+ new File(tmpDir, "snmp-mapping/httpd.conf").getAbsolutePath(), pinfo, binfo);
+
HttpdAddressUtility addrUtil = HttpdAddressUtility.get("2.2.17");
List<ApacheDirective> vhosts = tree.search("/<VirtualHost");
List<String> snmpNames = new ArrayList<String>(vhosts.size() + 1);
commit 38daab95271e3bd733e8b7909a3cf9c6607408ed
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Oct 26 16:11:16 2011 +0200
Formatting
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/parser/ApacheParserImpl.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/parser/ApacheParserImpl.java
index 8b68052..f563ccd 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/parser/ApacheParserImpl.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/parser/ApacheParserImpl.java
@@ -1,3 +1,21 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 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.apache.parser;
import java.io.File;
@@ -5,24 +23,28 @@ import java.util.List;
import org.rhq.augeas.util.Glob;
-public class ApacheParserImpl implements ApacheParser{
+/**
+ *
+ * @author Filip Drabek
+ */
+public class ApacheParserImpl implements ApacheParser {
private final static String INCLUDE_DIRECTIVE = "Include";
private final ApacheDirectiveTree tree;
private ApacheDirectiveStack stack;
private String serverRootPath;
- public ApacheParserImpl(ApacheDirectiveTree tree,String serverRootPath){
- stack = new ApacheDirectiveStack();
- this.serverRootPath = serverRootPath;
- this.tree = tree;
- stack.addDirective(this.tree.getRootNode());
+ public ApacheParserImpl(ApacheDirectiveTree tree, String serverRootPath) {
+ stack = new ApacheDirectiveStack();
+ this.serverRootPath = serverRootPath;
+ this.tree = tree;
+ stack.addDirective(this.tree.getRootNode());
}
-
- public void addDirective(ApacheDirective directive) throws Exception{
- if (directive.getName().equals(INCLUDE_DIRECTIVE)){
+
+ public void addDirective(ApacheDirective directive) throws Exception {
+ if (directive.getName().equals(INCLUDE_DIRECTIVE)) {
List<File> files = getIncludeFiles(directive.getValuesAsString());
- for (File fl : files){
+ for (File fl : files) {
if (fl.exists() && fl.isFile()) {
ApacheConfigReader.searchFile(fl.getAbsolutePath(), this);
}
@@ -32,20 +54,20 @@ public class ApacheParserImpl implements ApacheParser{
stack.getLastDirective().addChildDirective(directive);
}
- public void endNestedDirective(ApacheDirective directive) {
- stack.removeLastDirective();
+ public void endNestedDirective(ApacheDirective directive) {
+ stack.removeLastDirective();
}
public void startNestedDirective(ApacheDirective directive) {
- directive.setParentNode(stack.getLastDirective());
- stack.getLastDirective().addChildDirective(directive);
- stack.addDirective(directive);
+ directive.setParentNode(stack.getLastDirective());
+ stack.getLastDirective().addChildDirective(directive);
+ stack.addDirective(directive);
}
- private List<File> getIncludeFiles(String foundInclude) {
- File check = new File(foundInclude);
+ private List<File> getIncludeFiles(String foundInclude) {
+ File check = new File(foundInclude);
File root = new File(check.isAbsolute() ? Glob.rootPortion(foundInclude) : serverRootPath);
-
+
return Glob.match(root, foundInclude, Glob.ALPHABETICAL_COMPARATOR);
}
}