modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/inventory/ResourceContext.java
| 22
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerComponent.java
| 39
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
| 168 +++
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerOperationsDelegate.java
| 72 +
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceComponent.java
| 285 -----
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceDiscoveryComponent.java
| 148 +-
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/augeas/ApacheAugeasNode.java
| 69 -
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/augeas/AugeasConfigurationApache.java
| 6
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/augeas/AugeasTreeBuilderApache.java
| 25
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/parser/ApacheDirective.java
| 21
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/parser/ApacheDirectiveTree.java
| 10
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/parser/ApacheParserImpl.java
| 2
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/ApacheBinaryInfo.java
| 70 +
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/HttpdAddressUtility.java
| 197 ++-
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/RuntimeApacheConfiguration.java
| 519 ++++++++++
modules/plugins/apache/src/main/resources/META-INF/rhq-plugin.xml
| 25
modules/plugins/apache/src/test/java/org/rhq/plugins/apache/RuntimeConfigurationTest.java
| 208 ++++
modules/plugins/apache/src/test/java/org/rhq/plugins/apache/SnmpMappingTest.java
| 140 ++
modules/plugins/apache/src/test/java/org/rhq/plugins/apache/util/MockApacheBinaryInfo.java
| 126 ++
modules/plugins/apache/src/test/java/org/rhq/plugins/apache/util/MockProcessInfo.java
| 51
modules/plugins/apache/src/test/resources/runtime-config/conditional/httpd.conf
| 2
modules/plugins/apache/src/test/resources/runtime-config/conditional/ifdefine-defined.conf
| 5
modules/plugins/apache/src/test/resources/runtime-config/conditional/ifdefine-undefined.conf
| 5
modules/plugins/apache/src/test/resources/runtime-config/conditional/ifmodule-loaded.conf
| 13
modules/plugins/apache/src/test/resources/runtime-config/conditional/ifmodule-not-loaded.conf
| 11
modules/plugins/apache/src/test/resources/runtime-config/conditional/ifversion.conf
| 43
modules/plugins/apache/src/test/resources/runtime-config/conditional/nested-mess.conf
| 51
modules/plugins/apache/src/test/resources/runtime-config/incl-order/a.conf
| 1
modules/plugins/apache/src/test/resources/runtime-config/incl-order/b.conf
| 1
modules/plugins/apache/src/test/resources/runtime-config/incl-order/c.conf
| 1
modules/plugins/apache/src/test/resources/runtime-config/incl-order/httpd.conf
| 1
modules/plugins/apache/src/test/resources/snmp-mapping/httpd.conf
| 5
modules/plugins/apache/src/test/resources/snmp-mapping/vhost-with-servername-by-ip.conf
| 3
modules/plugins/apache/src/test/resources/snmp-mapping/vhost-with-servername-by-unresolvable-hostname.conf
| 3
modules/plugins/apache/src/test/resources/snmp-mapping/vhost-without-servername-resolvable-ip.conf
| 3
modules/plugins/apache/src/test/resources/snmp-mapping/vhost-without-servername-unresolvable-hostname.conf
| 3
modules/plugins/apache/src/test/resources/snmp-mapping/vhost-without-servername-unresolvable-ip.conf
| 3
modules/plugins/augeas/src/main/java/org/rhq/augeas/config/AugeasConfigurationSimple.java
| 2
modules/plugins/augeas/src/main/java/org/rhq/augeas/util/Glob.java
| 48
modules/plugins/augeas/src/main/java/org/rhq/plugins/augeas/AugeasConfigurationComponent.java
| 2
modules/plugins/augeas/src/main/java/org/rhq/plugins/augeas/AugeasConfigurationDiscoveryComponent.java
| 18
modules/plugins/augeas/src/main/java/org/rhq/rhqtransform/impl/PluginDescriptorBasedAugeasConfiguration.java
| 2
42 files changed, 2019 insertions(+), 410 deletions(-)
New commits:
commit 258be003ddf7bf022611ef183ed60a7e7ee7ef18
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed May 4 18:40:08 2011 +0200
BZ 700616 - Augeas tree abstraction now replaces the Include nodes with their contents
instead of just appending their contents to their children list.
This seems to be the original intended behavior of the class according to its
description but actually was not the case.
diff --git
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/augeas/ApacheAugeasNode.java
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/augeas/ApacheAugeasNode.java
index 6cb168e..99cc8cb 100644
---
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/augeas/ApacheAugeasNode.java
+++
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/augeas/ApacheAugeasNode.java
@@ -24,7 +24,10 @@ package org.rhq.plugins.apache.augeas;
import java.io.File;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.rhq.augeas.node.AugeasNode;
import org.rhq.augeas.node.AugeasNodeLazy;
@@ -42,13 +45,14 @@ import org.rhq.augeas.tree.AugeasTreeException;
* and modifies the get* methods to handle these as well.
*
* @author Filip Drabek
+ * @author Lukas Krejci
*/
public class ApacheAugeasNode extends AugeasNodeLazy implements AugeasNode {
/**
* List of included nodes.
*/
- private List<AugeasNode> includedNodes;
+ private Map<Integer, List<AugeasNode>> includedNodes;
public ApacheAugeasNode(String fullPath, AugeasTree tree) {
super(fullPath, tree);
@@ -72,8 +76,22 @@ public class ApacheAugeasNode extends AugeasNodeLazy implements
AugeasNode {
public List<AugeasNode> getChildNodes() {
List<AugeasNode> nodes = null;
nodes = ag.match(getFullPath() + File.separatorChar + "*");
- if (includedNodes != null)
- nodes.addAll(includedNodes);
+
+ if (includedNodes != null) {
+ //to avoid having to recompute indexes to insert the included nodes into the
+ //list of nodes as seen by augeas, let's include them from the biggest
index
+ //to the lowest.
+ List<Integer> includeNodeIndexes = new
ArrayList<Integer>(includedNodes.keySet());
+ Collections.sort(includeNodeIndexes, Collections.reverseOrder());
+
+ for(Integer idx : includeNodeIndexes) {
+ //remove the include node itself
+ nodes.remove(idx);
+
+ //add the included nodes instead of it
+ nodes.addAll(idx, includedNodes.get(idx));
+ }
+ }
return nodes;
}
@@ -83,26 +101,36 @@ public class ApacheAugeasNode extends AugeasNodeLazy implements
AugeasNode {
*
* @param nodes
*/
- public void addIncludeNodes(List<AugeasNode> nodes) {
+ public void addIncludeNodes(AugeasNode includeNode, List<AugeasNode> nodes) {
if (nodes.isEmpty())
return;
if (includedNodes == null)
- includedNodes = new ArrayList<AugeasNode>();
-
- includedNodes.addAll(nodes);
- }
-
- /**
- * Adds the node to the list of the included child nodes.
- *
- * @param node
- */
- public void addIncludeNode(AugeasNode node) {
- if (includedNodes == null)
- includedNodes = new ArrayList<AugeasNode>();
-
- includedNodes.add(node);
+ includedNodes = new HashMap<Integer, List<AugeasNode>>();
+
+ List<AugeasNode> childNodes = super.getChildNodes();
+ int idx = 0;
+ boolean found = false;
+
+ for(AugeasNode child : childNodes) {
+ if (child.getLabel().equals(includeNode.getLabel()) && child.getSeq()
== includeNode.getSeq()) {
+ found = true;
+ break;
+ }
+
+ ++idx;
+ }
+
+ if (found) {
+ List<AugeasNode> alreadyIncluded = includedNodes.get(idx);
+ if (alreadyIncluded == null) {
+ //copy the nodes over to a new list so that we can modify it later
without modifying the original collection
+ //which might be unexpected on the caller site.
+ includedNodes.put(idx, new ArrayList<AugeasNode>(nodes));
+ } else {
+ alreadyIncluded.addAll(nodes);
+ }
+ }
}
public AugeasNode getParentNode() {
@@ -132,7 +160,8 @@ public class ApacheAugeasNode extends AugeasNodeLazy implements
AugeasNode {
//else if this node is included from another file
//and we would destroy that association here.
}
+
public void setParentNode(AugeasNode node){
this.parentNode = node;
- }
+ }
}
diff --git
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/augeas/AugeasConfigurationApache.java
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/augeas/AugeasConfigurationApache.java
index d4f7dd2..a3a715c 100644
---
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/augeas/AugeasConfigurationApache.java
+++
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/augeas/AugeasConfigurationApache.java
@@ -109,7 +109,7 @@ public class AugeasConfigurationApache extends
PluginDescriptorBasedAugeasConfig
File check = new File(expression);
File root = new File(check.isAbsolute() ? Glob.rootPortion(expression) :
serverRootPath);
- files.addAll(Glob.match(root, expression));
+ files.addAll(Glob.match(root, expression, Glob.ALPHABETICAL_COMPARATOR));
for (File fl : files){
if (fl.exists() && fl.isFile()) {
@@ -155,7 +155,7 @@ public class AugeasConfigurationApache extends
PluginDescriptorBasedAugeasConfig
File check = new File(incl);
File root = new File(check.isAbsolute() ? Glob.rootPortion(incl) :
serverRootPath);
- files.addAll(Glob.match(root, incl));
+ files.addAll(Glob.match(root, incl, Glob.ALPHABETICAL_COMPARATOR));
}
if (module.getExcludedGlobs() != null) {
@@ -191,7 +191,7 @@ public class AugeasConfigurationApache extends
PluginDescriptorBasedAugeasConfig
for (String path : foundIncludes) {
File check = new File(path);
File root = new File(check.isAbsolute() ? Glob.rootPortion(path) :
serverRoot);
- for (File f :Glob.match(root, path)){
+ for (File f :Glob.match(root, path, Glob.ALPHABETICAL_COMPARATOR)){
ret.add(f);
}
}
diff --git
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/augeas/AugeasTreeBuilderApache.java
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/augeas/AugeasTreeBuilderApache.java
index e6454b7..fbde74f 100644
---
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/augeas/AugeasTreeBuilderApache.java
+++
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/augeas/AugeasTreeBuilderApache.java
@@ -43,7 +43,6 @@ public class AugeasTreeBuilderApache implements AugeasTreeBuilder {
private Map<String, List<File>> includes;
private Map<AugeasNode, List<String>> incl;
- private static final String[] NESTED_INCLUDE_DIRECTIVES = {
"<VirtualHost", "<Directory" };
private Augeas ag;
public AugeasTreeBuilderApache() {
@@ -78,7 +77,7 @@ public class AugeasTreeBuilderApache implements AugeasTreeBuilder {
File check = new File(inclName);
File root = new File(check.isAbsolute() ? Glob.rootPortion(inclName) :
apacheConfig.getServerRootPath());
- files.addAll(Glob.match(root, inclName));
+ files.addAll(Glob.match(root, inclName, Glob.ALPHABETICAL_COMPARATOR));
if (module.getExcludedGlobs() != null)
Glob.excludeAll(files, module.getExcludedGlobs());
@@ -87,7 +86,7 @@ public class AugeasTreeBuilderApache implements AugeasTreeBuilder {
includes.put(inclName, files);
}
- updateIncludes((ApacheAugeasNode) rootNode, tree, rootPath, false);
+ updateIncludes((ApacheAugeasNode) rootNode, tree, rootPath, null);
//List<String> rootconf = new ArrayList<String>();
// rootconf.add(ApacheAugeasTree.AUGEAS_DATA_PATH + rootPath);
@@ -97,7 +96,7 @@ public class AugeasTreeBuilderApache implements AugeasTreeBuilder {
return tree;
}
- public void updateIncludes(ApacheAugeasNode parentNode, AugeasTree tree, String
fileName, boolean update)
+ public void updateIncludes(ApacheAugeasNode parentNode, AugeasTree tree, String
fileName, AugeasNode includeNode)
throws AugeasRhqException {
List<String> nestedNodes = ag.match(ApacheAugeasTree.AUGEAS_DATA_PATH +
fileName + File.separator + "*");
@@ -111,14 +110,14 @@ public class AugeasTreeBuilderApache implements AugeasTreeBuilder {
createdNodes.add(newNode);
}
- if (update)
- parentNode.addIncludeNodes(createdNodes);
+ if (includeNode != null)
+ parentNode.addIncludeNodes(includeNode, createdNodes);
for (AugeasNode node : createdNodes) {
- if (canContainIncludes(node.getLabel())) {
+ if (canContainNestedNodes(node.getLabel())) {
String labelName = node.getLabel()
+ ((node.getSeq() != 0) ? "[" +
String.valueOf(node.getSeq()) + "]" : "");
- updateIncludes((ApacheAugeasNode) node, tree, fileName + File.separator +
labelName, false);
+ updateIncludes((ApacheAugeasNode) node, tree, fileName + File.separator +
labelName, null);
}
if (node.getLabel().equals("Include")) {
String val = ag.get(node.getFullPath() + File.separator +
"param");
@@ -128,7 +127,7 @@ public class AugeasTreeBuilderApache implements AugeasTreeBuilder {
List<String> names = new ArrayList<String>();
for (File file : files) {
names.add(ApacheAugeasTree.AUGEAS_DATA_PATH +
file.getAbsolutePath());
- updateIncludes((ApacheAugeasNode) node.getParentNode(), tree,
file.getAbsolutePath(), true);
+ updateIncludes((ApacheAugeasNode) node.getParentNode(), tree,
file.getAbsolutePath(), node);
}
if (incl.containsKey(node.getParentNode())) {
List<String> list = incl.get(node.getParentNode());
@@ -140,11 +139,7 @@ public class AugeasTreeBuilderApache implements AugeasTreeBuilder {
}
}
- private boolean canContainIncludes(String name) {
- for (String directive : NESTED_INCLUDE_DIRECTIVES) {
- if (directive.equals(name))
- return true;
- }
- return false;
+ private boolean canContainNestedNodes(String name) {
+ return name.startsWith("<");
}
}
commit 7fa1e7d9ad55391e989e9c4ea4276e5c8a13049e
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue May 3 16:21:25 2011 +0200
Adding tests for the ability to produce the same server and port identifications as
advertised by SNMP module in various scenarios.
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
new file mode 100644
index 0000000..0716ade
--- /dev/null
+++ b/modules/plugins/apache/src/test/java/org/rhq/plugins/apache/SnmpMappingTest.java
@@ -0,0 +1,140 @@
+/*
+ * 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;
+
+import static org.testng.Assert.assertEquals;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import org.rhq.core.pluginapi.util.FileUtils;
+import org.rhq.core.util.file.FileUtil;
+import org.rhq.core.util.stream.StreamUtil;
+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.HttpdAddressUtility;
+import org.rhq.plugins.apache.util.MockApacheBinaryInfo;
+import org.rhq.plugins.apache.util.MockProcessInfo;
+
+/**
+ *
+ *
+ * @author Lukas Krejci
+ */
+@Test
+public class SnmpMappingTest {
+
+ private File tmpDir;
+
+ private static final String[] VHOST_NAMES_CONFIGURATION_TEST_FILES = {
+ "snmp-mapping/httpd.conf",
+ "snmp-mapping/vhost-with-servername-by-ip.conf",
+ "snmp-mapping/vhost-with-servername-by-unresolvable-hostname.conf",
+ "snmp-mapping/vhost-without-servername-resolvable-ip.conf",
+ "snmp-mapping/vhost-without-servername-unresolvable-hostname.conf",
+ "snmp-mapping/vhost-without-servername-unresolvable-ip.conf"
+ };
+
+ private static final String[] EXPECTED_SNMP_NAMES = {
+ "the-main-server-name:42", //httpd.conf
+ "12.34.56.78:0", //vhost-with-servername-by-ip.conf
+ "this-will-never-resolve.weird-server.net:90",
//vhost-with-servername-by-unresolvable-hostname.conf
+ "<<<LOCALHOST>>>:1002",
//vhost-without-servernama-resolvable-ip.conf
+ "bogus_host_without_forward_dns:42",
//vhost-without-servername-unresolvable-hostname.conf
+ "bogus_host_without_reverse_dns:1003"
//vhost-without-servername-unresolvable-ip.conf
+ };
+
+ @BeforeClass
+ public void copyConfigurationFiles() throws Exception {
+ tmpDir = FileUtil.createTempDirectory("apache-runtime-config-tests",
null, null);
+
+ for(String path : VHOST_NAMES_CONFIGURATION_TEST_FILES) {
+ copyResourceToFile(path, new File(tmpDir, path));
+ }
+ }
+
+ @BeforeClass
+ public void initExpectedResults() throws Exception {
+ String localhost = InetAddress.getLocalHost().getHostName();
+ for(int i = 0; i < EXPECTED_SNMP_NAMES.length; ++i) {
+ EXPECTED_SNMP_NAMES[i] =
EXPECTED_SNMP_NAMES[i].replaceAll("<<<LOCALHOST>>>",
localhost);
+ }
+ }
+
+ @AfterClass
+ public void deleteConfigurationFiles() throws IOException {
+ FileUtils.purge(tmpDir, true);
+ }
+
+
+ public void testVhostNames() {
+ MockApacheBinaryInfo binfo = new MockApacheBinaryInfo();
+ binfo.setVersion("2.2.17");
+ 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);
+
+ HttpdAddressUtility addrUtil = HttpdAddressUtility.get("2.2.17");
+ List<ApacheDirective> vhosts = tree.search("/<VirtualHost");
+ List<String> snmpNames = new ArrayList<String>(vhosts.size() + 1);
+
snmpNames.add(addrUtil.getHttpdInternalMainServerAddressRepresentation(tree).toString(false,
false));
+ for(ApacheDirective vhost : vhosts) {
+ String vhostDef = vhost.getValues().get(0);
+ String serverName = null;
+ List<ApacheDirective> serverNames =
vhost.getChildByName("ServerName");
+ if (serverNames.size() > 0) {
+ serverName = serverNames.get(serverNames.size() -
1).getValuesAsString();
+ }
+
+ snmpNames.add(addrUtil.getHttpdInternalVirtualHostAddressRepresentation(tree,
vhostDef, serverName).toString(false, false));
+ }
+
+ assertEquals(snmpNames, Arrays.asList(EXPECTED_SNMP_NAMES));
+ }
+
+
+ private void copyResourceToFile(String resourcePath, File destination) throws
IOException {
+ InputStream input =
getClass().getClassLoader().getResourceAsStream(resourcePath);
+
+ if (input != null) {
+ destination.getParentFile().mkdirs();
+ destination.createNewFile();
+
+ StreamUtil.copy(input, new BufferedOutputStream(new
FileOutputStream(destination)), true);
+ }
+ }
+}
diff --git a/modules/plugins/apache/src/test/resources/snmp-mapping/httpd.conf
b/modules/plugins/apache/src/test/resources/snmp-mapping/httpd.conf
new file mode 100644
index 0000000..29a43eb
--- /dev/null
+++ b/modules/plugins/apache/src/test/resources/snmp-mapping/httpd.conf
@@ -0,0 +1,5 @@
+Listen 80
+Listen 127.0.0.1:90
+ServerName the-main-server-name:42
+
+Include vhost-*.conf
diff --git
a/modules/plugins/apache/src/test/resources/snmp-mapping/vhost-with-servername-by-ip.conf
b/modules/plugins/apache/src/test/resources/snmp-mapping/vhost-with-servername-by-ip.conf
new file mode 100644
index 0000000..978892c
--- /dev/null
+++
b/modules/plugins/apache/src/test/resources/snmp-mapping/vhost-with-servername-by-ip.conf
@@ -0,0 +1,3 @@
+<VirtualHost 127.0.0.1:1000>
+ ServerName 12.34.56.78
+</VirtualHost>
diff --git
a/modules/plugins/apache/src/test/resources/snmp-mapping/vhost-with-servername-by-unresolvable-hostname.conf
b/modules/plugins/apache/src/test/resources/snmp-mapping/vhost-with-servername-by-unresolvable-hostname.conf
new file mode 100644
index 0000000..d38cfc3
--- /dev/null
+++
b/modules/plugins/apache/src/test/resources/snmp-mapping/vhost-with-servername-by-unresolvable-hostname.conf
@@ -0,0 +1,3 @@
+<VirtualHost 127.0.0.1:1001>
+ ServerName this-will-never-resolve.weird-server.net:90
+</VirtualHost>
diff --git
a/modules/plugins/apache/src/test/resources/snmp-mapping/vhost-without-servername-resolvable-ip.conf
b/modules/plugins/apache/src/test/resources/snmp-mapping/vhost-without-servername-resolvable-ip.conf
new file mode 100644
index 0000000..16586d1
--- /dev/null
+++
b/modules/plugins/apache/src/test/resources/snmp-mapping/vhost-without-servername-resolvable-ip.conf
@@ -0,0 +1,3 @@
+<VirtualHost 127.0.0.1:1002>
+
+</VirtualHost>
diff --git
a/modules/plugins/apache/src/test/resources/snmp-mapping/vhost-without-servername-unresolvable-hostname.conf
b/modules/plugins/apache/src/test/resources/snmp-mapping/vhost-without-servername-unresolvable-hostname.conf
new file mode 100644
index 0000000..3ec4c24
--- /dev/null
+++
b/modules/plugins/apache/src/test/resources/snmp-mapping/vhost-without-servername-unresolvable-hostname.conf
@@ -0,0 +1,3 @@
+<VirtualHost unresolvable-hostname.weird-domain.net:1004>
+
+</VirtualHost>
diff --git
a/modules/plugins/apache/src/test/resources/snmp-mapping/vhost-without-servername-unresolvable-ip.conf
b/modules/plugins/apache/src/test/resources/snmp-mapping/vhost-without-servername-unresolvable-ip.conf
new file mode 100644
index 0000000..1637446
--- /dev/null
+++
b/modules/plugins/apache/src/test/resources/snmp-mapping/vhost-without-servername-unresolvable-ip.conf
@@ -0,0 +1,3 @@
+<VirtualHost 12.34.56.78:1003>
+
+</VirtualHost>
commit 08fff40554c621710e947990b80b06734ebced6e
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue May 3 16:18:18 2011 +0200
Adding IfVersion detection tests, removed the vhost-names test that will come in as
standalone test because their not part of the runtime configuration extraction
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 260c4c6..0b7e52e 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
@@ -36,6 +36,7 @@ import org.testng.annotations.Test;
import org.rhq.core.pluginapi.util.FileUtils;
import org.rhq.core.util.file.FileUtil;
+import org.rhq.core.util.stream.StreamUtil;
import org.rhq.plugins.apache.parser.ApacheConfigReader;
import org.rhq.plugins.apache.parser.ApacheDirective;
import org.rhq.plugins.apache.parser.ApacheDirectiveTree;
@@ -61,6 +62,7 @@ public class RuntimeConfigurationTest {
"runtime-config/conditional/ifdefine-undefined.conf",
"runtime-config/conditional/ifmodule-loaded.conf",
"runtime-config/conditional/ifmodule-not-loaded.conf",
+ "runtime-config/conditional/ifversion.conf",
"runtime-config/conditional/nested-mess.conf"
};
@@ -71,29 +73,17 @@ public class RuntimeConfigurationTest {
"runtime-config/incl-order/httpd.conf"
};
- private static final String[] VHOST_NAMES_CONFIGURATION_TEST_FILES = {
- "runtime-config/vhost-names/httpd.conf",
- "runtime-config/vhost-names/vhost-with-servername-by-ip.conf",
-
"runtime-config/vhost-names/vhost-with-servername-by-unresolvable-hostname.conf",
-
"runtime-config/vhost-names/vhost-without-servername-resolvable-ip.conf",
-
"runtime-config/vhost-names/vhost-without-servername-unresolvable-ip.conf"
- };
-
@BeforeClass
public void copyConfigurationFiles() throws Exception {
tmpDir = FileUtil.createTempDirectory("apache-runtime-config-tests",
null, null);
- for(String path : CONDITIONAL_CONFIGURATION_TEST_FILES) {
+ for(String path : CONDITIONAL_CONFIGURATION_TEST_FILES) {
copyResourceToFile(path, new File(tmpDir, path));
}
for(String path : INCLUSION_ORDER_CONFIGURATION_TEST_FILES) {
copyResourceToFile(path, new File(tmpDir, path));
}
-
- for(String path : VHOST_NAMES_CONFIGURATION_TEST_FILES) {
- copyResourceToFile(path, new File(tmpDir, path));
- }
}
@AfterClass
@@ -102,12 +92,10 @@ public class RuntimeConfigurationTest {
}
public void testConditionalInclusion() {
- //TODO add tests for IfVersion!!!
-
MockApacheBinaryInfo binfo = new MockApacheBinaryInfo();
binfo.setVersion("2.2.17");
MockProcessInfo pinfo = new MockProcessInfo();
- pinfo.setCommandLine(new String[] {"/usr/sbin/httpd", "-D",
"DEFINED"});
+ pinfo.setCommandLine(new String[] {"blahblah", "-D",
"DEFINED"});
ApacheDirectiveTree tree = new ApacheDirectiveTree();
ApacheParser parser = new ApacheParserImpl(tree, new File(tmpDir,
"runtime-config/conditional").getAbsolutePath());
@@ -119,11 +107,16 @@ public class RuntimeConfigurationTest {
List<VhostSpec> expectedVhosts = new ArrayList<VhostSpec>();
- expectedVhosts.add(new VhostSpec(Collections.singleton("127.0.0.1:80"),
"ifdefine.defined"));
- expectedVhosts.add(new VhostSpec(Collections.singleton("127.0.0.1:82"),
"ifmodule.loaded.source-file"));
- expectedVhosts.add(new VhostSpec(Collections.singleton("127.0.0.1:83"),
"ifmodule.loaded.module-name"));
- expectedVhosts.add(new VhostSpec(Collections.singleton("127.0.0.1:88"),
"ifdefine.ifmodule.loaded.source-file"));
- expectedVhosts.add(new VhostSpec(Collections.singleton("127.0.0.1:89"),
"ifdefine.ifmodule.loaded.module-name"));
+ expectedVhosts.add(new
VhostSpec(Collections.singleton("127.0.0.1:100"),
"ifdefine.defined"));
+ expectedVhosts.add(new
VhostSpec(Collections.singleton("127.0.0.1:300"),
"ifmodule.loaded.source-file"));
+ expectedVhosts.add(new
VhostSpec(Collections.singleton("127.0.0.1:301"),
"ifmodule.loaded.module-name"));
+ expectedVhosts.add(new
VhostSpec(Collections.singleton("127.0.0.1:501"),
"ifversion.module-loaded.implied-equals"));
+ expectedVhosts.add(new
VhostSpec(Collections.singleton("127.0.0.1:502"),
"ifversion.module-loaded.equals"));
+ expectedVhosts.add(new
VhostSpec(Collections.singleton("127.0.0.1:503"),
"ifversion.module-loaded.not-equals"));
+ expectedVhosts.add(new
VhostSpec(Collections.singleton("127.0.0.1:504"),
"ifversion.module-loaded.regex"));
+ expectedVhosts.add(new
VhostSpec(Collections.singleton("127.0.0.1:505"),
"ifversion.module-loaded.implied-regex"));
+ expectedVhosts.add(new
VhostSpec(Collections.singleton("127.0.0.1:602"),
"ifdefine.ifmodule.loaded.source-file"));
+ expectedVhosts.add(new
VhostSpec(Collections.singleton("127.0.0.1:603"),
"ifdefine.ifmodule.loaded.module-name"));
assertEquals(vhosts, expectedVhosts);
}
@@ -132,7 +125,7 @@ public class RuntimeConfigurationTest {
MockApacheBinaryInfo binfo = new MockApacheBinaryInfo();
binfo.setVersion("2.2.17");
MockProcessInfo pinfo = new MockProcessInfo();
- pinfo.setCommandLine(new String[] {"/usr/sbin/httpd"});
+ pinfo.setCommandLine(new String[] {"blahblah"});
ApacheDirectiveTree tree = new ApacheDirectiveTree();
ApacheParser parser = new ApacheParserImpl(tree, new File(tmpDir,
"runtime-config/incl-order").getAbsolutePath());
@@ -149,39 +142,14 @@ public class RuntimeConfigurationTest {
assertEquals(listens.get(2).getValuesAsString(), "82");
}
- public void testVhostNames() {
- MockApacheBinaryInfo binfo = new MockApacheBinaryInfo();
- binfo.setVersion("2.2.17");
- MockProcessInfo pinfo = new MockProcessInfo();
- pinfo.setCommandLine(new String[] {"/usr/sbin/httpd"});
-
- ApacheDirectiveTree tree = new ApacheDirectiveTree();
- ApacheParser parser = new ApacheParserImpl(tree, new File(tmpDir,
"runtime-config/vhost-names").getAbsolutePath());
- ApacheConfigReader.buildTree(new File(tmpDir,
"runtime-config/vhost-names/httpd.conf").getAbsolutePath(), parser);
-
- tree = RuntimeApacheConfiguration.extract(tree, pinfo, binfo,
ApacheServerDiscoveryComponent.MODULE_SOURCE_FILE_TO_MODULE_NAME_20);
-
- //TODO implement this
- }
-
- private void copyResourceToFile(String resourcePath, File destination) throws
IOException {
+ private void copyResourceToFile(String resourcePath, File destination) throws
IOException {
InputStream input =
getClass().getClassLoader().getResourceAsStream(resourcePath);
if (input != null) {
destination.getParentFile().mkdirs();
destination.createNewFile();
- BufferedOutputStream output = new BufferedOutputStream(new
FileOutputStream(destination));
-
- try {
- int data;
- while((data = input.read()) != -1) {
- output.write(data);
- }
- } finally {
- input.close();
- output.close();
- }
+ StreamUtil.copy(input, new BufferedOutputStream(new
FileOutputStream(destination)), true);
}
}
diff --git
a/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifdefine-defined.conf
b/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifdefine-defined.conf
index 7631a5c..c098499 100644
---
a/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifdefine-defined.conf
+++
b/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifdefine-defined.conf
@@ -1,5 +1,5 @@
<IfDefine DEFINED>
- <VirtualHost 127.0.0.1:80>
+ <VirtualHost 127.0.0.1:100>
ServerName ifdefine.defined
</VirtualHost>
</IfDefine>
diff --git
a/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifdefine-undefined.conf
b/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifdefine-undefined.conf
index 6acd1a5..03d0c07 100644
---
a/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifdefine-undefined.conf
+++
b/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifdefine-undefined.conf
@@ -1,5 +1,5 @@
<IfDefine UNDEFINED>
- <VirtualHost 127.0.0.1:81>
+ <VirtualHost 127.0.0.1:200>
ServerName ifdefine.undefined
</VirtualHost>
</IfDefine>
diff --git
a/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifmodule-loaded.conf
b/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifmodule-loaded.conf
index f9aba0a..a977465 100644
---
a/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifmodule-loaded.conf
+++
b/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifmodule-loaded.conf
@@ -1,13 +1,13 @@
LoadModule alias_module
<IfModule mod_alias.c>
- <VirtualHost 127.0.0.1:82>
+ <VirtualHost 127.0.0.1:300>
ServerName ifmodule.loaded.source-file
</VirtualHost>
</IfModule>
<IfModule alias_module>
- <VirtualHost 127.0.0.1:83>
+ <VirtualHost 127.0.0.1:301>
ServerName ifmodule.loaded.module-name
</VirtualHost>
</IfModule>
diff --git
a/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifmodule-not-loaded.conf
b/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifmodule-not-loaded.conf
index 611ba1a..fffb61d 100644
---
a/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifmodule-not-loaded.conf
+++
b/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifmodule-not-loaded.conf
@@ -1,11 +1,11 @@
<IfModule mod_not_loaded.c>
- <VirtualHost 127.0.0.1:84>
+ <VirtualHost 127.0.0.1:400>
ServerName ifmodule.not-loaded.source-file
</VirtualHost>
</IfModule>
<IfModule not_loaded_module>
- <VirtualHost 127.0.0.1:85>
+ <VirtualHost 127.0.0.1:401>
ServerName ifmodule.not-loaded.module-name
</VirtualHost>
</IfModule>
diff --git
a/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifversion.conf
b/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifversion.conf
new file mode 100644
index 0000000..46413de
--- /dev/null
+++ b/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifversion.conf
@@ -0,0 +1,43 @@
+<IfVersion 2.2.17>
+ <VirtualHost 127.0.0.1:500>
+ ServerName ifversion.module-not-loaded
+ </VirtualHost>
+</IfVersion>
+
+LoadModule version_module
+
+<IfVersion 2.2.17>
+ <VirtualHost 127.0.0.1:501>
+ ServerName ifversion.module-loaded.implied-equals
+ </VirtualHost>
+</IfVersion>
+
+<IfVersion = 2.2.17>
+ <VirtualHost 127.0.0.1:502>
+ ServerName ifversion.module-loaded.equals
+ </VirtualHost>
+</IfVersion>
+
+<IfVersion != 2.2.18>
+ <VirtualHost 127.0.0.1:503>
+ ServerName ifversion.module-loaded.not-equals
+ </VirtualHost>
+</IfVersion>
+
+<IfVersion ~ 2\.2\.1[7-9]>
+ <VirtualHost 127.0.0.1:504>
+ ServerName ifversion.module-loaded.regex
+ </VirtualHost>
+</IfVersion>
+
+<IfVersion /2\.2\.1[7-9]/>
+ <VirtualHost 127.0.0.1:505>
+ ServerName ifversion.module-loaded.implied-regex
+ </VirtualHost>
+</IfVersion>
+
+<IfVersion /2\.2\.1[8-9]/>
+ <VirtualHost 127.0.0.1:506>
+ ServerName ifversion.module-loaded.implied-regex.unmatched
+ </VirtualHost>
+</IfVersion>
\ No newline at end of file
diff --git
a/modules/plugins/apache/src/test/resources/runtime-config/conditional/nested-mess.conf
b/modules/plugins/apache/src/test/resources/runtime-config/conditional/nested-mess.conf
index 5a2ab62..edde513 100644
---
a/modules/plugins/apache/src/test/resources/runtime-config/conditional/nested-mess.conf
+++
b/modules/plugins/apache/src/test/resources/runtime-config/conditional/nested-mess.conf
@@ -1,24 +1,24 @@
<IfDefine DEFINED>
<IfModule mod_not_loaded.c>
- <VirtualHost 127.0.0.1:86>
+ <VirtualHost 127.0.0.1:600>
ServerName ifdefine.ifmodule.not-loaded.source-file
</VirtualHost>
</IfModule>
<IfModule not_loaded_module>
- <VirtualHost 127.0.0.1:87>
+ <VirtualHost 127.0.0.1:601>
ServerName ifdefine.ifmodule.not-loaded.module-name
</VirtualHost>
</IfModule>
<IfModule mod_alias.c>
- <VirtualHost 127.0.0.1:88>
+ <VirtualHost 127.0.0.1:602>
ServerName ifdefine.ifmodule.loaded.source-file
</VirtualHost>
</IfModule>
<IfModule alias_module>
- <VirtualHost 127.0.0.1:89>
+ <VirtualHost 127.0.0.1:603>
ServerName ifdefine.ifmodule.loaded.module-name
</VirtualHost>
</IfModule>
@@ -26,28 +26,26 @@
<IfDefine UNDEFINED>
<IfModule mod_not_loaded.c>
- <VirtualHost 127.0.0.1:90>
+ <VirtualHost 127.0.0.1:604>
ServerName not-ifdefine.ifmodule.not-loaded.source-file
</VirtualHost>
</IfModule>
<IfModule not_loaded_module>
- <VirtualHost 127.0.0.1:91>
+ <VirtualHost 127.0.0.1:605>
ServerName not-ifdefine.ifmodule.not-loaded.module-name
</VirtualHost>
</IfModule>
<IfModule mod_alias.c>
- <VirtualHost 127.0.0.1:92>
+ <VirtualHost 127.0.0.1:606>
ServerName not-ifdefine.ifmodule.loaded.source-file
</VirtualHost>
</IfModule>
<IfModule alias_module>
- <VirtualHost 127.0.0.1:93>
+ <VirtualHost 127.0.0.1:607>
ServerName not-ifdefine.ifmodule.loaded.module-name
</VirtualHost>
</IfModule>
</IfDefine>
-
-
diff --git
a/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/httpd.conf
b/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/httpd.conf
deleted file mode 100644
index 29a43eb..0000000
--- a/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/httpd.conf
+++ /dev/null
@@ -1,5 +0,0 @@
-Listen 80
-Listen 127.0.0.1:90
-ServerName the-main-server-name:42
-
-Include vhost-*.conf
diff --git
a/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/vhost-with-servername-by-ip.conf
b/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/vhost-with-servername-by-ip.conf
deleted file mode 100644
index 978892c..0000000
---
a/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/vhost-with-servername-by-ip.conf
+++ /dev/null
@@ -1,3 +0,0 @@
-<VirtualHost 127.0.0.1:1000>
- ServerName 12.34.56.78
-</VirtualHost>
diff --git
a/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/vhost-with-servername-by-unresolvable-hostname.conf
b/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/vhost-with-servername-by-unresolvable-hostname.conf
deleted file mode 100644
index d38cfc3..0000000
---
a/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/vhost-with-servername-by-unresolvable-hostname.conf
+++ /dev/null
@@ -1,3 +0,0 @@
-<VirtualHost 127.0.0.1:1001>
- ServerName this-will-never-resolve.weird-server.net:90
-</VirtualHost>
diff --git
a/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/vhost-without-servername-resolvable-ip.conf
b/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/vhost-without-servername-resolvable-ip.conf
deleted file mode 100644
index 16586d1..0000000
---
a/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/vhost-without-servername-resolvable-ip.conf
+++ /dev/null
@@ -1,3 +0,0 @@
-<VirtualHost 127.0.0.1:1002>
-
-</VirtualHost>
diff --git
a/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/vhost-without-servername-unresolvable-ip.conf
b/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/vhost-without-servername-unresolvable-ip.conf
deleted file mode 100644
index 1637446..0000000
---
a/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/vhost-without-servername-unresolvable-ip.conf
+++ /dev/null
@@ -1,3 +0,0 @@
-<VirtualHost 12.34.56.78:1003>
-
-</VirtualHost>
commit 7d71991e8df59f75bdfe5c9c2929f8d27956b05c
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue May 3 16:16:22 2011 +0200
BZ 700616 - behave the same as apache when handling the corner case of unresolvable
hostnames in virtual host address definition.
diff --git
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/HttpdAddressUtility.java
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/HttpdAddressUtility.java
index 61fc5b9..ebb315b 100644
---
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/HttpdAddressUtility.java
+++
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/HttpdAddressUtility.java
@@ -410,6 +410,12 @@ public enum HttpdAddressUtility {
}
} catch (UnknownHostException e) {
ret.host = BOGUS_HOST_WITHOUT_FORWARD_DNS;
+
+ //weird, as it seems, apache uses the port of the main server
+ //with the unknown host even if the port was specified in the vhost
+ //definition
+ Address mainAddress =
getHttpdInternalMainServerAddressRepresentation(runtimeConfig);
+ ret.port = mainAddress.port;
}
}
commit 8c7ba989644f307a4a783a31e83f76639ed92a71
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon May 2 17:54:09 2011 +0200
Tests for the inclusion order and IfModule and IfDefine detection.
diff --git
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/ApacheBinaryInfo.java
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/ApacheBinaryInfo.java
index aedb144..724fc19 100644
---
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/ApacheBinaryInfo.java
+++
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/ApacheBinaryInfo.java
@@ -65,7 +65,7 @@ public class ApacheBinaryInfo {
private Set<String> compiledInModules = new HashSet<String>();
private Set<String> compiledInDefines = new HashSet<String>();
- private ApacheBinaryInfo(@NotNull
+ protected ApacheBinaryInfo(@NotNull
String binaryPath) {
this.binaryPath = binaryPath;
}
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
new file mode 100644
index 0000000..260c4c6
--- /dev/null
+++
b/modules/plugins/apache/src/test/java/org/rhq/plugins/apache/RuntimeConfigurationTest.java
@@ -0,0 +1,240 @@
+/*
+ * 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;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import static org.testng.Assert.*;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import org.rhq.core.pluginapi.util.FileUtils;
+import org.rhq.core.util.file.FileUtil;
+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.MockApacheBinaryInfo;
+import org.rhq.plugins.apache.util.MockProcessInfo;
+import org.rhq.plugins.apache.util.RuntimeApacheConfiguration;
+
+/**
+ *
+ *
+ * @author Lukas Krejci
+ */
+@Test
+public class RuntimeConfigurationTest {
+
+ private File tmpDir;
+
+ private static final String[] CONDITIONAL_CONFIGURATION_TEST_FILES = {
+ "runtime-config/conditional/httpd.conf",
+ "runtime-config/conditional/ifdefine-defined.conf",
+ "runtime-config/conditional/ifdefine-undefined.conf",
+ "runtime-config/conditional/ifmodule-loaded.conf",
+ "runtime-config/conditional/ifmodule-not-loaded.conf",
+ "runtime-config/conditional/nested-mess.conf"
+ };
+
+ private static final String[] INCLUSION_ORDER_CONFIGURATION_TEST_FILES = {
+ "runtime-config/incl-order/a.conf",
+ "runtime-config/incl-order/b.conf",
+ "runtime-config/incl-order/c.conf",
+ "runtime-config/incl-order/httpd.conf"
+ };
+
+ private static final String[] VHOST_NAMES_CONFIGURATION_TEST_FILES = {
+ "runtime-config/vhost-names/httpd.conf",
+ "runtime-config/vhost-names/vhost-with-servername-by-ip.conf",
+
"runtime-config/vhost-names/vhost-with-servername-by-unresolvable-hostname.conf",
+
"runtime-config/vhost-names/vhost-without-servername-resolvable-ip.conf",
+
"runtime-config/vhost-names/vhost-without-servername-unresolvable-ip.conf"
+ };
+
+ @BeforeClass
+ public void copyConfigurationFiles() throws Exception {
+ tmpDir = FileUtil.createTempDirectory("apache-runtime-config-tests",
null, null);
+
+ for(String path : CONDITIONAL_CONFIGURATION_TEST_FILES) {
+ copyResourceToFile(path, new File(tmpDir, path));
+ }
+
+ for(String path : INCLUSION_ORDER_CONFIGURATION_TEST_FILES) {
+ copyResourceToFile(path, new File(tmpDir, path));
+ }
+
+ for(String path : VHOST_NAMES_CONFIGURATION_TEST_FILES) {
+ copyResourceToFile(path, new File(tmpDir, path));
+ }
+ }
+
+ @AfterClass
+ public void deleteConfigurationFiles() throws IOException {
+ FileUtils.purge(tmpDir, true);
+ }
+
+ public void testConditionalInclusion() {
+ //TODO add tests for IfVersion!!!
+
+ MockApacheBinaryInfo binfo = new MockApacheBinaryInfo();
+ binfo.setVersion("2.2.17");
+ MockProcessInfo pinfo = new MockProcessInfo();
+ pinfo.setCommandLine(new String[] {"/usr/sbin/httpd", "-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);
+
+ List<VhostSpec> vhosts = VhostSpec.detect(tree);
+
+ List<VhostSpec> expectedVhosts = new ArrayList<VhostSpec>();
+
+ expectedVhosts.add(new VhostSpec(Collections.singleton("127.0.0.1:80"),
"ifdefine.defined"));
+ expectedVhosts.add(new VhostSpec(Collections.singleton("127.0.0.1:82"),
"ifmodule.loaded.source-file"));
+ expectedVhosts.add(new VhostSpec(Collections.singleton("127.0.0.1:83"),
"ifmodule.loaded.module-name"));
+ expectedVhosts.add(new VhostSpec(Collections.singleton("127.0.0.1:88"),
"ifdefine.ifmodule.loaded.source-file"));
+ expectedVhosts.add(new VhostSpec(Collections.singleton("127.0.0.1:89"),
"ifdefine.ifmodule.loaded.module-name"));
+
+ assertEquals(vhosts, expectedVhosts);
+ }
+
+ public void testInclusionOrder() {
+ MockApacheBinaryInfo binfo = new MockApacheBinaryInfo();
+ binfo.setVersion("2.2.17");
+ MockProcessInfo pinfo = new MockProcessInfo();
+ pinfo.setCommandLine(new String[] {"/usr/sbin/httpd"});
+
+ 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);
+
+ List<ApacheDirective> listens = tree.search("/Listen");
+
+ assertEquals(listens.size(), 3, "There should be 3 listen
directives");
+
+ assertEquals(listens.get(0).getValuesAsString(), "80");
+ assertEquals(listens.get(1).getValuesAsString(), "81");
+ assertEquals(listens.get(2).getValuesAsString(), "82");
+ }
+
+ public void testVhostNames() {
+ MockApacheBinaryInfo binfo = new MockApacheBinaryInfo();
+ binfo.setVersion("2.2.17");
+ MockProcessInfo pinfo = new MockProcessInfo();
+ pinfo.setCommandLine(new String[] {"/usr/sbin/httpd"});
+
+ ApacheDirectiveTree tree = new ApacheDirectiveTree();
+ ApacheParser parser = new ApacheParserImpl(tree, new File(tmpDir,
"runtime-config/vhost-names").getAbsolutePath());
+ ApacheConfigReader.buildTree(new File(tmpDir,
"runtime-config/vhost-names/httpd.conf").getAbsolutePath(), parser);
+
+ tree = RuntimeApacheConfiguration.extract(tree, pinfo, binfo,
ApacheServerDiscoveryComponent.MODULE_SOURCE_FILE_TO_MODULE_NAME_20);
+
+ //TODO implement this
+ }
+
+ private void copyResourceToFile(String resourcePath, File destination) throws
IOException {
+ InputStream input =
getClass().getClassLoader().getResourceAsStream(resourcePath);
+
+ if (input != null) {
+ destination.getParentFile().mkdirs();
+ destination.createNewFile();
+
+ BufferedOutputStream output = new BufferedOutputStream(new
FileOutputStream(destination));
+
+ try {
+ int data;
+ while((data = input.read()) != -1) {
+ output.write(data);
+ }
+ } finally {
+ input.close();
+ output.close();
+ }
+ }
+ }
+
+ private static class VhostSpec {
+ public List<String> definition;
+ public String serverName;
+
+ public static List<VhostSpec> detect(ApacheDirectiveTree tree) {
+ List<VhostSpec> ret = new ArrayList<VhostSpec>();
+
+ for(ApacheDirective vhost : tree.search("/<VirtualHost")) {
+ ret.add(new VhostSpec(vhost));
+ }
+
+ return ret;
+ }
+
+ public VhostSpec(ApacheDirective vhost) {
+ definition = vhost.getValues();
+ List<ApacheDirective> serverNames =
vhost.getChildByName("ServerName");
+ if (serverNames.size() > 0) {
+ serverName = serverNames.get(0).getValuesAsString();
+ }
+ }
+
+ public VhostSpec(Collection<String> definition, String serverName) {
+ this.definition = new ArrayList<String>(definition);
+ this.serverName = serverName;
+ }
+
+ @Override
+ public String toString() {
+ return "VhostSpec[serverName='" + serverName + "',
definition=" + definition + "]";
+ }
+
+ @Override
+ public int hashCode() {
+ return serverName.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ if (!(other instanceof VhostSpec)) {
+ return false;
+ }
+
+ VhostSpec o = (VhostSpec) other;
+
+ return serverName.equals(o.serverName) &&
definition.equals(o.definition);
+ }
+ }
+}
diff --git
a/modules/plugins/apache/src/test/java/org/rhq/plugins/apache/util/MockApacheBinaryInfo.java
b/modules/plugins/apache/src/test/java/org/rhq/plugins/apache/util/MockApacheBinaryInfo.java
new file mode 100644
index 0000000..adb5ac8
--- /dev/null
+++
b/modules/plugins/apache/src/test/java/org/rhq/plugins/apache/util/MockApacheBinaryInfo.java
@@ -0,0 +1,126 @@
+/*
+ * 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.util;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Class used to represent the apache binary in the runtime configuration tests.
+ *
+ * @author Lukas Krejci
+ */
+public class MockApacheBinaryInfo extends ApacheBinaryInfo {
+
+ private Set<String> defines = new HashSet<String>();
+ private Set<String> modules = new HashSet<String>();
+ private String configFile;
+ private String binaryPath;
+ private String built;
+ private long lastModified;
+ private String mpm;
+ private String root;
+ private String version;
+
+ public MockApacheBinaryInfo() {
+ super(null);
+ }
+
+ @Override
+ public String getBinaryPath() {
+ return binaryPath;
+ }
+
+ public void setBinaryPath(String path) {
+ this.binaryPath = path;
+ }
+
+ @Override
+ public String getBuilt() {
+ return built;
+ }
+
+ public void setBuilt(String built) {
+ this.built = built;
+ }
+
+ @Override
+ public Set<String> getCompiledInDefines() {
+ return defines;
+ }
+
+ public void setCompiledInDefines(Set<String> defines) {
+ this.defines = defines;
+ }
+
+ @Override
+ public Set<String> getCompiledInModules() {
+ return modules;
+ }
+
+ public void setCompiledInModules(Set<String> modules) {
+ this.modules = modules;
+ }
+
+ @Override
+ public String getCtl() {
+ return configFile;
+ }
+
+ public void setCtl(String ctl) {
+ this.configFile = ctl;
+ }
+
+ @Override
+ public long getLastModified() {
+ return lastModified;
+ }
+
+ public void setLastModified(long lastModified) {
+ this.lastModified = lastModified;
+ }
+
+ @Override
+ public String getMpm() {
+ return mpm;
+ }
+
+ public void setMpm(String mpm) {
+ this.mpm = mpm;
+ }
+
+ @Override
+ public String getRoot() {
+ return root;
+ }
+
+ public void setRoot(String root) {
+ this.root = root;
+ }
+
+ @Override
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+}
diff --git
a/modules/plugins/apache/src/test/java/org/rhq/plugins/apache/util/MockProcessInfo.java
b/modules/plugins/apache/src/test/java/org/rhq/plugins/apache/util/MockProcessInfo.java
new file mode 100644
index 0000000..2832ce2
--- /dev/null
+++
b/modules/plugins/apache/src/test/java/org/rhq/plugins/apache/util/MockProcessInfo.java
@@ -0,0 +1,51 @@
+/*
+ * 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.util;
+
+import org.rhq.core.system.ProcessInfo;
+
+/**
+ * Class used to pretend the apache process info in the runtime configuration tests.
+ *
+ * @author Lukas Krejci
+ */
+public class MockProcessInfo extends ProcessInfo {
+
+ private long pid;
+ private String[] commandLine;
+
+ @Override
+ public long getPid() {
+ return pid;
+ }
+
+ public void setPid(long pid) {
+ this.pid = pid;
+ }
+
+ @Override
+ public String[] getCommandLine() {
+ return commandLine;
+ }
+
+ public void setCommandLine(String[] commandLine) {
+ this.commandLine = commandLine;
+ }
+}
diff --git
a/modules/plugins/apache/src/test/resources/runtime-config/conditional/httpd.conf
b/modules/plugins/apache/src/test/resources/runtime-config/conditional/httpd.conf
new file mode 100644
index 0000000..7325704
--- /dev/null
+++ b/modules/plugins/apache/src/test/resources/runtime-config/conditional/httpd.conf
@@ -0,0 +1,2 @@
+Include if*.conf
+Include nested-mess.conf
diff --git
a/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifdefine-defined.conf
b/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifdefine-defined.conf
new file mode 100644
index 0000000..7631a5c
--- /dev/null
+++
b/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifdefine-defined.conf
@@ -0,0 +1,5 @@
+<IfDefine DEFINED>
+ <VirtualHost 127.0.0.1:80>
+ ServerName ifdefine.defined
+ </VirtualHost>
+</IfDefine>
diff --git
a/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifdefine-undefined.conf
b/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifdefine-undefined.conf
new file mode 100644
index 0000000..6acd1a5
--- /dev/null
+++
b/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifdefine-undefined.conf
@@ -0,0 +1,5 @@
+<IfDefine UNDEFINED>
+ <VirtualHost 127.0.0.1:81>
+ ServerName ifdefine.undefined
+ </VirtualHost>
+</IfDefine>
diff --git
a/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifmodule-loaded.conf
b/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifmodule-loaded.conf
new file mode 100644
index 0000000..f9aba0a
--- /dev/null
+++
b/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifmodule-loaded.conf
@@ -0,0 +1,13 @@
+LoadModule alias_module
+
+<IfModule mod_alias.c>
+ <VirtualHost 127.0.0.1:82>
+ ServerName ifmodule.loaded.source-file
+ </VirtualHost>
+</IfModule>
+
+<IfModule alias_module>
+ <VirtualHost 127.0.0.1:83>
+ ServerName ifmodule.loaded.module-name
+ </VirtualHost>
+</IfModule>
diff --git
a/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifmodule-not-loaded.conf
b/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifmodule-not-loaded.conf
new file mode 100644
index 0000000..611ba1a
--- /dev/null
+++
b/modules/plugins/apache/src/test/resources/runtime-config/conditional/ifmodule-not-loaded.conf
@@ -0,0 +1,11 @@
+<IfModule mod_not_loaded.c>
+ <VirtualHost 127.0.0.1:84>
+ ServerName ifmodule.not-loaded.source-file
+ </VirtualHost>
+</IfModule>
+
+<IfModule not_loaded_module>
+ <VirtualHost 127.0.0.1:85>
+ ServerName ifmodule.not-loaded.module-name
+ </VirtualHost>
+</IfModule>
diff --git
a/modules/plugins/apache/src/test/resources/runtime-config/conditional/nested-mess.conf
b/modules/plugins/apache/src/test/resources/runtime-config/conditional/nested-mess.conf
new file mode 100644
index 0000000..5a2ab62
--- /dev/null
+++
b/modules/plugins/apache/src/test/resources/runtime-config/conditional/nested-mess.conf
@@ -0,0 +1,53 @@
+<IfDefine DEFINED>
+ <IfModule mod_not_loaded.c>
+ <VirtualHost 127.0.0.1:86>
+ ServerName ifdefine.ifmodule.not-loaded.source-file
+ </VirtualHost>
+ </IfModule>
+
+ <IfModule not_loaded_module>
+ <VirtualHost 127.0.0.1:87>
+ ServerName ifdefine.ifmodule.not-loaded.module-name
+ </VirtualHost>
+ </IfModule>
+
+ <IfModule mod_alias.c>
+ <VirtualHost 127.0.0.1:88>
+ ServerName ifdefine.ifmodule.loaded.source-file
+ </VirtualHost>
+ </IfModule>
+
+ <IfModule alias_module>
+ <VirtualHost 127.0.0.1:89>
+ ServerName ifdefine.ifmodule.loaded.module-name
+ </VirtualHost>
+ </IfModule>
+</IfDefine>
+
+<IfDefine UNDEFINED>
+ <IfModule mod_not_loaded.c>
+ <VirtualHost 127.0.0.1:90>
+ ServerName not-ifdefine.ifmodule.not-loaded.source-file
+ </VirtualHost>
+ </IfModule>
+
+ <IfModule not_loaded_module>
+ <VirtualHost 127.0.0.1:91>
+ ServerName not-ifdefine.ifmodule.not-loaded.module-name
+ </VirtualHost>
+ </IfModule>
+
+ <IfModule mod_alias.c>
+ <VirtualHost 127.0.0.1:92>
+ ServerName not-ifdefine.ifmodule.loaded.source-file
+ </VirtualHost>
+ </IfModule>
+
+ <IfModule alias_module>
+ <VirtualHost 127.0.0.1:93>
+ ServerName not-ifdefine.ifmodule.loaded.module-name
+ </VirtualHost>
+ </IfModule>
+</IfDefine>
+
+
diff --git a/modules/plugins/apache/src/test/resources/runtime-config/incl-order/a.conf
b/modules/plugins/apache/src/test/resources/runtime-config/incl-order/a.conf
new file mode 100644
index 0000000..5c1d82b
--- /dev/null
+++ b/modules/plugins/apache/src/test/resources/runtime-config/incl-order/a.conf
@@ -0,0 +1 @@
+Listen 80
diff --git a/modules/plugins/apache/src/test/resources/runtime-config/incl-order/b.conf
b/modules/plugins/apache/src/test/resources/runtime-config/incl-order/b.conf
new file mode 100644
index 0000000..15adf3c
--- /dev/null
+++ b/modules/plugins/apache/src/test/resources/runtime-config/incl-order/b.conf
@@ -0,0 +1 @@
+Listen 81
diff --git a/modules/plugins/apache/src/test/resources/runtime-config/incl-order/c.conf
b/modules/plugins/apache/src/test/resources/runtime-config/incl-order/c.conf
new file mode 100644
index 0000000..dd36fbd
--- /dev/null
+++ b/modules/plugins/apache/src/test/resources/runtime-config/incl-order/c.conf
@@ -0,0 +1 @@
+Listen 82
diff --git
a/modules/plugins/apache/src/test/resources/runtime-config/incl-order/httpd.conf
b/modules/plugins/apache/src/test/resources/runtime-config/incl-order/httpd.conf
new file mode 100644
index 0000000..ee1ee60
--- /dev/null
+++ b/modules/plugins/apache/src/test/resources/runtime-config/incl-order/httpd.conf
@@ -0,0 +1 @@
+Include ?.conf
diff --git
a/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/httpd.conf
b/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/httpd.conf
new file mode 100644
index 0000000..29a43eb
--- /dev/null
+++ b/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/httpd.conf
@@ -0,0 +1,5 @@
+Listen 80
+Listen 127.0.0.1:90
+ServerName the-main-server-name:42
+
+Include vhost-*.conf
diff --git
a/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/vhost-with-servername-by-ip.conf
b/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/vhost-with-servername-by-ip.conf
new file mode 100644
index 0000000..978892c
--- /dev/null
+++
b/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/vhost-with-servername-by-ip.conf
@@ -0,0 +1,3 @@
+<VirtualHost 127.0.0.1:1000>
+ ServerName 12.34.56.78
+</VirtualHost>
diff --git
a/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/vhost-with-servername-by-unresolvable-hostname.conf
b/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/vhost-with-servername-by-unresolvable-hostname.conf
new file mode 100644
index 0000000..d38cfc3
--- /dev/null
+++
b/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/vhost-with-servername-by-unresolvable-hostname.conf
@@ -0,0 +1,3 @@
+<VirtualHost 127.0.0.1:1001>
+ ServerName this-will-never-resolve.weird-server.net:90
+</VirtualHost>
diff --git
a/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/vhost-without-servername-resolvable-ip.conf
b/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/vhost-without-servername-resolvable-ip.conf
new file mode 100644
index 0000000..16586d1
--- /dev/null
+++
b/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/vhost-without-servername-resolvable-ip.conf
@@ -0,0 +1,3 @@
+<VirtualHost 127.0.0.1:1002>
+
+</VirtualHost>
diff --git
a/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/vhost-without-servername-unresolvable-ip.conf
b/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/vhost-without-servername-unresolvable-ip.conf
new file mode 100644
index 0000000..1637446
--- /dev/null
+++
b/modules/plugins/apache/src/test/resources/runtime-config/vhost-names/vhost-without-servername-unresolvable-ip.conf
@@ -0,0 +1,3 @@
+<VirtualHost 12.34.56.78:1003>
+
+</VirtualHost>
commit 2632a30b0bc37eaabbac4e82afc8388411cb34dd
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon May 2 17:51:42 2011 +0200
BZ 700616 - porting over the alphabetic order awareness in glob patterns from master
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 686625e..f0e966f 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
@@ -47,6 +47,6 @@ public class ApacheParserImpl implements ApacheParser{
File check = new File(foundInclude);
File root = new File(check.isAbsolute() ? Glob.rootPortion(foundInclude) :
serverRootPath);
- return Glob.match(root, foundInclude);
+ return Glob.match(root, foundInclude, Glob.ALPHABETICAL_COMPARATOR);
}
}
diff --git
a/modules/plugins/augeas/src/main/java/org/rhq/augeas/config/AugeasConfigurationSimple.java
b/modules/plugins/augeas/src/main/java/org/rhq/augeas/config/AugeasConfigurationSimple.java
index 3ab8e26..0fa093c 100644
---
a/modules/plugins/augeas/src/main/java/org/rhq/augeas/config/AugeasConfigurationSimple.java
+++
b/modules/plugins/augeas/src/main/java/org/rhq/augeas/config/AugeasConfigurationSimple.java
@@ -132,7 +132,7 @@ public class AugeasConfigurationSimple implements AugeasConfiguration
{
throw new IllegalStateException("Expecting at least once inclusion
pattern for configuration files.");
}
- List<File> files = Glob.matchAll(root, includeGlobs);
+ List<File> files = Glob.matchAll(root, includeGlobs,
Glob.ALPHABETICAL_COMPARATOR);
if (module.getExcludedGlobs() != null) {
List<String> excludeGlobs = module.getExcludedGlobs();
diff --git a/modules/plugins/augeas/src/main/java/org/rhq/augeas/util/Glob.java
b/modules/plugins/augeas/src/main/java/org/rhq/augeas/util/Glob.java
index d41d2a2..c61f932 100644
--- a/modules/plugins/augeas/src/main/java/org/rhq/augeas/util/Glob.java
+++ b/modules/plugins/augeas/src/main/java/org/rhq/augeas/util/Glob.java
@@ -27,6 +27,7 @@ import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.logging.Log;
@@ -41,6 +42,16 @@ public class Glob {
private static final Log log = LogFactory.getLog(Glob.class);
+ public static final Comparator<File> ALPHABETICAL_COMPARATOR = new
Comparator<File>() {
+
+ public int compare(File o1, File o2) {
+ String path1 = o1.getAbsolutePath();
+ String path2 = o2.getAbsolutePath();
+
+ return path1.compareTo(path2);
+ }
+ };
+
private Glob() {
}
@@ -79,6 +90,16 @@ public class Glob {
}
/**
+ * This is an overloaded version of the {@link #match(File, String, Comparator)}
method
+ * that passes <code>null</code> as the comparator to use.
+ *
+ * @see #match(File, String, Comparator)
+ */
+ public static List<File> match(File parentPath, String globPattern) {
+ return match(parentPath, globPattern, null);
+ }
+
+ /**
* Returns a fixed size list of matches.
*
* The parent path specifies the "root" from which the glob pattern
applies.
@@ -90,9 +111,10 @@ public class Glob {
*
* @param parentPath the parent path to start the pattern search
* @param globPattern the glob pattern to match against
+ * @param resultComparator the comparator using which to sort the results or null if
no sorting is necessary
* @return the list of matches
*/
- public static List<File> match(File parentPath, String globPattern) {
+ public static List<File> match(File parentPath, String globPattern,
Comparator<? super File> resultComparator) {
if (!parentPath.exists()) {
throw new IllegalArgumentException("Path '" + parentPath +
"' does not exist.");
}
@@ -133,6 +155,11 @@ public class Glob {
log.debug("Could list files in " + parentPath);
return Collections.emptyList();
}
+
+ if (resultComparator != null) {
+ Arrays.sort(files, resultComparator);
+ }
+
return Arrays.asList(files);
}
@@ -141,14 +168,25 @@ public class Glob {
parent = parent + File.separatorChar;
return parent+pattern;
}
- public static List<File> matchAll(File parentPath, String... globPattern) {
- return matchAll(parentPath, Arrays.asList(globPattern));
- }
+ /**
+ * This is an overloaded version of the {@link #matchAll(File, List, Comparator)}
method
+ * that passes <code>null</code> as the comparator to use.
+ *
+ * @see #matchAll(File, List, Comparator)
+ */
public static List<File> matchAll(File parentPath, List<String>
globPatterns) {
+ return matchAll(parentPath, globPatterns, null);
+ }
+
+ public static List<File> matchAll(File parentPath, List<String>
globPatterns, Comparator<? super File> resultComparator) {
ArrayList<File> matches = new ArrayList<File>();
for(String p : globPatterns) {
- matches.addAll(match(parentPath, p));
+ matches.addAll(match(parentPath, p, null));
+ }
+
+ if (resultComparator != null) {
+ Collections.sort(matches, resultComparator);
}
return matches;
diff --git
a/modules/plugins/augeas/src/main/java/org/rhq/plugins/augeas/AugeasConfigurationComponent.java
b/modules/plugins/augeas/src/main/java/org/rhq/plugins/augeas/AugeasConfigurationComponent.java
index 2f500b6..1a37613 100644
---
a/modules/plugins/augeas/src/main/java/org/rhq/plugins/augeas/AugeasConfigurationComponent.java
+++
b/modules/plugins/augeas/src/main/java/org/rhq/plugins/augeas/AugeasConfigurationComponent.java
@@ -312,7 +312,7 @@ public class AugeasConfigurationComponent<T extends
ResourceComponent> implement
}
public List<File> getConfigurationFiles() {
- List<File> files = Glob.matchAll(new File(this.augeasRootPath),
includeGlobs);
+ List<File> files = Glob.matchAll(new File(this.augeasRootPath),
includeGlobs, Glob.ALPHABETICAL_COMPARATOR);
Glob.excludeAll(files, excludeGlobs);
return files;
}
diff --git
a/modules/plugins/augeas/src/main/java/org/rhq/plugins/augeas/AugeasConfigurationDiscoveryComponent.java
b/modules/plugins/augeas/src/main/java/org/rhq/plugins/augeas/AugeasConfigurationDiscoveryComponent.java
index 04d4faf..292e6df 100644
---
a/modules/plugins/augeas/src/main/java/org/rhq/plugins/augeas/AugeasConfigurationDiscoveryComponent.java
+++
b/modules/plugins/augeas/src/main/java/org/rhq/plugins/augeas/AugeasConfigurationDiscoveryComponent.java
@@ -60,12 +60,16 @@ public class AugeasConfigurationDiscoveryComponent<T extends
ResourceComponent>
pluginConfig.put(includeProps);
pluginConfig.put(excludeProps);
- checkFiles(pluginConfig);
-
- DiscoveredResourceDetails resource = createResourceDetails(discoveryContext,
pluginConfig);
- discoveredResources.add(resource);
- log.debug("Discovered " + discoveryContext.getResourceType().getName()
+ " Resource with key ["
- + resource.getResourceKey() + "].");
+ try {
+ checkFiles(pluginConfig);
+
+ DiscoveredResourceDetails resource = createResourceDetails(discoveryContext,
pluginConfig);
+ discoveredResources.add(resource);
+ log.debug("Discovered " +
discoveryContext.getResourceType().getName() + " Resource with key ["
+ + resource.getResourceKey() + "].");
+ } catch (IllegalStateException e) { // Thrown by augeas if it can not read a
file
+ log.warn("Discovery failed: " + e.getMessage());
+ }
return discoveredResources;
}
@@ -127,7 +131,7 @@ public class AugeasConfigurationDiscoveryComponent<T extends
ResourceComponent>
throw new IllegalStateException("Expecting at least one inclusion
pattern for configuration files.");
}
- List<File> files = Glob.matchAll(root, includeGlobs);
+ List<File> files = Glob.matchAll(root, includeGlobs,
Glob.ALPHABETICAL_COMPARATOR);
if (excludeGlobsProp != null) {
List<String> excludeGlobs = getGlobList(excludeGlobsProp);
diff --git
a/modules/plugins/augeas/src/main/java/org/rhq/rhqtransform/impl/PluginDescriptorBasedAugeasConfiguration.java
b/modules/plugins/augeas/src/main/java/org/rhq/rhqtransform/impl/PluginDescriptorBasedAugeasConfiguration.java
index cd15ef2..dd3f497 100644
---
a/modules/plugins/augeas/src/main/java/org/rhq/rhqtransform/impl/PluginDescriptorBasedAugeasConfiguration.java
+++
b/modules/plugins/augeas/src/main/java/org/rhq/rhqtransform/impl/PluginDescriptorBasedAugeasConfiguration.java
@@ -183,7 +183,7 @@ public class PluginDescriptorBasedAugeasConfiguration implements
AugeasConfigura
throw new IllegalStateException("Expecting at least once inclusion
pattern for configuration files.");
}
- List<File> files = Glob.matchAll(root, includeGlobs);
+ List<File> files = Glob.matchAll(root, includeGlobs,
Glob.ALPHABETICAL_COMPARATOR);
if (module.getExcludedGlobs() != null) {
List<String> excludeGlobs = module.getExcludedGlobs();
commit a2c00c6f1da359c6fbd51e391fb4422ada03ac9d
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon May 2 11:04:43 2011 +0200
BZ 700616 - runtime config extracted even in the case server root was redefined in the
config files.
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 9d73da0..56ac57a 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
@@ -322,6 +322,7 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
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()));
}
serverUrl = getUrl(serverConfig, binaryInfo.getVersion());
commit e59a0a42b5447a44b0a89f2a836d5750a39f3b6b
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Apr 29 19:12:27 2011 +0200
BZ 700461 - ResourceContext.getNativeProcess() now always reports the current process
info or null if no process exists for given resource.
diff --git
a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/inventory/ResourceContext.java
b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/inventory/ResourceContext.java
index ca4c6bb..d875f48 100644
---
a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/inventory/ResourceContext.java
+++
b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/inventory/ResourceContext.java
@@ -202,14 +202,28 @@ public class ResourceContext<T extends ResourceComponent> {
* @return information on the resource's process
*/
public ProcessInfo getNativeProcess() {
- if ((this.processInfo == null) || !this.processInfo.isRunning()) {
- // TODO: should we null out processInfo? if it isn't running, the old
processInfo is no longer valid
+ boolean rediscover = this.processInfo == null;
+
+ if (!rediscover) {
+ //if the process info thinks the process is running,
+ //refresh it to check its facts again
+ if (this.processInfo.isRunning()) {
+ this.processInfo.refresh();
+ }
+ rediscover = !this.processInfo.isRunning();
+ }
+
+ if (rediscover) {
+ //This method is documented to return null if the process can no longer be
found.
+ //Let's make sure that's the case and null it out now. The discovery
might or might not
+ //reassign it.
+ this.processInfo = null;
if (this.resourceDiscoveryComponent != null) {
try {
Set<DiscoveredResourceDetails> details;
- ResourceDiscoveryContext context;
+ ResourceDiscoveryContext<ResourceComponent<?>> context;
- context = new ResourceDiscoveryContext(this.resourceType,
this.parentResourceComponent, this,
+ context = new
ResourceDiscoveryContext<ResourceComponent<?>>(this.resourceType,
this.parentResourceComponent, this,
this.systemInformation, getNativeProcessesForType(),
Collections.EMPTY_LIST,
getPluginContainerName(), getPluginContainerDeployment());
commit bd816f6c926b932a2b02349f46b7a00a79c57766
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Apr 29 19:11:08 2011 +0200
BZ 700616 - adding a new operation to apache server resource to detect the SNMP WWW
Service Index values for individual virtual hosts. This is to a) support users when
upgrading from RHQ 3.0.1 vanilla and b) to aid the users with reconfiguring the monitoring
of vhosts after they changed order in the configuration files.
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 f44485e..5822f38 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
@@ -778,6 +778,10 @@ public class ApacheServerComponent implements
AugeasRHQComponent<PlatformCompone
return binaryInfo;
}
+ public String getResourceKey() {
+ return resourceContext.getResourceKey();
+ }
+
// TODO: Move this method to a helper class.
static void addSnmpMetricValueToReport(MeasurementReport report,
MeasurementScheduleRequest schedule,
SNMPValue snmpValue, boolean valueIsTimestamp) throws SNMPException {
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 4cd0184..9d73da0 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
@@ -58,6 +58,7 @@ import org.rhq.plugins.apache.util.AugeasNodeValueUtil;
import org.rhq.plugins.apache.util.HttpdAddressUtility;
import org.rhq.plugins.apache.util.OsProcessUtility;
import org.rhq.plugins.apache.util.HttpdAddressUtility.Address;
+import org.rhq.plugins.apache.util.RuntimeApacheConfiguration;
import org.rhq.plugins.platform.PlatformComponent;
import org.rhq.rhqtransform.impl.PluginDescriptorBasedAugeasConfiguration;
@@ -432,7 +433,7 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
@Nullable
- private String getServerRoot(@NotNull ApacheBinaryInfo binaryInfo, @NotNull
ProcessInfo processInfo) {
+ public static String getServerRoot(@NotNull ApacheBinaryInfo binaryInfo, @NotNull
ProcessInfo processInfo) {
// First see if -d was specified on the httpd command line.
String[] cmdLine = processInfo.getCommandLine();
String root = getCommandLineOption(cmdLine, "-d");
@@ -475,7 +476,7 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
}
@Nullable
- private File getServerConfigFile(ApacheBinaryInfo binaryInfo, ProcessInfo
processInfo, String serverRoot) {
+ public static File getServerConfigFile(ApacheBinaryInfo binaryInfo, ProcessInfo
processInfo, String serverRoot) {
// First see if -f was specified on the httpd command line.
String[] cmdLine = processInfo.getCommandLine();
String serverConfigFile = getCommandLineOption(cmdLine, "-f");
@@ -503,7 +504,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];
diff --git
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerOperationsDelegate.java
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerOperationsDelegate.java
index 8b729ad..f1a1a4b 100644
---
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerOperationsDelegate.java
+++
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerOperationsDelegate.java
@@ -19,9 +19,13 @@
package org.rhq.plugins.apache;
import java.io.File;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.PropertyList;
+import org.rhq.core.domain.configuration.PropertyMap;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.pluginapi.operation.OperationContext;
import org.rhq.core.pluginapi.operation.OperationFacet;
@@ -30,7 +34,18 @@ import org.rhq.core.pluginapi.util.ProcessExecutionUtility;
import org.rhq.core.system.OperatingSystemType;
import org.rhq.core.system.ProcessExecution;
import org.rhq.core.system.ProcessExecutionResults;
+import org.rhq.core.system.ProcessInfo;
import org.rhq.core.system.SystemInfo;
+import org.rhq.core.system.SystemInfoFactory;
+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.HttpdAddressUtility;
+import org.rhq.plugins.apache.util.OsProcessUtility;
+import org.rhq.plugins.apache.util.RuntimeApacheConfiguration;
/**
* Executes operations on an Apache server ({@link ApacheServerComponent} delegates to
this class).
@@ -123,6 +138,10 @@ public class ApacheServerOperationsDelegate implements OperationFacet
{
processExecution.getArguments().add("-t");
break;
}
+
+ case DETECT_SNMP_INDEXES: {
+ return detectSnmpIndexes();
+ }
}
ProcessExecutionResults processExecutionResults =
this.systemInfo.executeProcess(processExecution);
@@ -199,10 +218,61 @@ public class ApacheServerOperationsDelegate implements
OperationFacet {
}
}
+ private OperationResult detectSnmpIndexes() throws Exception {
+ PropertyList vhostList = new
PropertyList("snmpIndexesPerResourceKey");
+
+ ApacheDirectiveTree tree = serverComponent.loadParser();
+ tree = RuntimeApacheConfiguration.extract(tree,
serverComponent.getCurrentProcessInfo(), serverComponent.getCurrentBinaryInfo(),
serverComponent.getModuleNames());
+ ApacheVirtualHostServiceDiscoveryComponent.SnmpWwwServiceIndexes snmpDiscoveries
= ApacheVirtualHostServiceDiscoveryComponent.getSnmpDiscoveries(serverComponent);
+
+ String mainVhostRK =
ApacheVirtualHostServiceDiscoveryComponent.createMainServerResourceKey(serverComponent,
tree, snmpDiscoveries);
+
+ List<ApacheDirective> virtualHosts =
tree.search("/<VirtualHost");
+
+ //the vhosts detected can actually have conflicting resource keys. So before we
build the resulting configuration object
+ //let's pass the results through this map where we can check for those
conflicts more easily.
+ LinkedHashMap<String, Integer> mapping = new LinkedHashMap<String,
Integer>();
+ mapping.put(mainVhostRK, 1);
+
+ int idx = 0;
+ for(ApacheDirective vhost : virtualHosts) {
+ List<String> hosts = vhost.getValues();
+
+ List<ApacheDirective> serverNames =
vhost.getChildByName("ServerName");
+ String serverName = null;
+ if (serverNames.size() > 0) {
+ serverName = serverNames.get(0).getValuesAsString();
+ }
+
+ String resourceKey =
ApacheVirtualHostServiceDiscoveryComponent.createResourceKey(serverName, hosts, tree,
serverComponent, snmpDiscoveries);
+
+ int snmpIdx = virtualHosts.size() - idx + 1;
+
+ if (!mapping.containsKey(resourceKey)) {
+ mapping.put(resourceKey, snmpIdx);
+ }
+
+ ++idx;
+ }
+
+ for (Map.Entry<String, Integer> entry : mapping.entrySet()) {
+ PropertyMap vhostRow = new PropertyMap("snmpIndexForResourceKey");
+ vhostList.add(vhostRow);
+
+ vhostRow.put(new PropertySimple("resourceKey", entry.getKey()));
+ vhostRow.put(new PropertySimple("snmpWwwServiceIndex",
entry.getValue()));
+ }
+
+ OperationResult ret = new OperationResult();
+ ret.getComplexResults().put(vhostList);
+
+ return ret;
+ }
+
/**
* Enumeration of supported operations for an Apache server.
*/
private enum Operation {
- START, STOP, RESTART, START_SSL, GRACEFUL_RESTART, CONFIG_TEST
+ START, STOP, RESTART, START_SSL, GRACEFUL_RESTART, CONFIG_TEST,
DETECT_SNMP_INDEXES
}
}
\ No newline at end of file
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 9da9c31..9abbabe 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
@@ -24,8 +24,10 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
@@ -38,10 +40,17 @@ import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+import org.rhq.core.system.ProcessInfo;
+import org.rhq.core.system.SystemInfoFactory;
+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.HttpdAddressUtility;
import org.rhq.plugins.apache.util.HttpdAddressUtility.Address;
+import org.rhq.plugins.apache.util.ApacheBinaryInfo;
+import org.rhq.plugins.apache.util.OsProcessUtility;
import org.rhq.plugins.apache.util.RuntimeApacheConfiguration;
import org.rhq.plugins.www.snmp.SNMPException;
import org.rhq.plugins.www.snmp.SNMPSession;
@@ -72,7 +81,7 @@ public class ApacheVirtualHostServiceDiscoveryComponent implements
ResourceDisco
//BZ 612189 - prepare for the legacy overrides. We need to revert to the
old-style resource keys until
//resource upgrade functionality is ready.
- SnmpWwwServiceIndexes snmpDiscoveries = getSnmpDiscoveries(context);
+ SnmpWwwServiceIndexes snmpDiscoveries =
getSnmpDiscoveries(context.getParentResourceComponent());
ApacheServerComponent serverComponent = context.getParentResourceComponent();
ApacheDirectiveTree tree = serverComponent.loadParser();
@@ -101,7 +110,7 @@ public class ApacheVirtualHostServiceDiscoveryComponent implements
ResourceDisco
serverName = serverNames.get(0).getValuesAsString();
}
- String resourceKey = createResourceKey(serverName, hosts);
+ String resourceKey = createResourceKey(serverName, hosts, tree,
serverComponent, snmpDiscoveries);
String resourceName = resourceKey; //this'll get overridden below if we
find a better value using the address variable
Configuration pluginConfiguration = context.getDefaultPluginConfiguration();
@@ -146,19 +155,9 @@ public class ApacheVirtualHostServiceDiscoveryComponent implements
ResourceDisco
pluginConfiguration.put(rtLogProp);
//redefine the resourcename using the virtual host sample address
- resourceName = address.toString(false);
+ resourceName = address.toString(false, true);
}
- //BZ 612189 - remove this once we have resource upgrade
- //ok, this is hacky, but...
- //in order not to change the semantics of the resource key creation
- //we use the legacy resource key (i.e. the one based on SNMP) only
- //if SNMP is available, even though we now have algorithm that can
- //determine the SNMP resource key without it being available.
- if (snmpDiscoveries != null) {
- resourceKey =
serverComponent.getAddressUtility().getHttpdInternalVirtualHostAddressRepresentation(tree,
firstAddress, serverName).toString(false);
- }
-
//as the last thing, let's determine the SNMP WWW Service Index of this
vhost
int snmpWwwServiceIndex = virtualHosts.size() - currentVhostIndex + 1;
pluginConfiguration.put(new
PropertySimple(ApacheVirtualHostServiceComponent.SNMP_WWW_SERVICE_INDEX_CONFIG_PROP,
snmpWwwServiceIndex));
@@ -185,7 +184,7 @@ public class ApacheVirtualHostServiceDiscoveryComponent implements
ResourceDisco
String mainServerUrl =
context.getParentResourceContext().getPluginConfiguration().getSimple(
ApacheServerComponent.PLUGIN_CONFIG_PROP_URL).getStringValue();
- String key = null;
+ String key = createMainServerResourceKey(context.getParentResourceComponent(),
runtimeConfig, snmpDiscoveries);
if (mainServerUrl != null && !"null".equals(mainServerUrl)) {
PropertySimple mainServerUrlProp = new
PropertySimple(ApacheVirtualHostServiceComponent.URL_CONFIG_PROP,
@@ -205,30 +204,12 @@ public class ApacheVirtualHostServiceDiscoveryComponent implements
ResourceDisco
PropertySimple rtLogProp = new PropertySimple(
ApacheVirtualHostServiceComponent.RESPONSE_TIME_LOG_FILE_CONFIG_PROP,
rtLogFile.toString());
mainServerPluginConfig.put(rtLogProp);
-
- //BZ 612189 - remove this once we have resource upgrade
- key = host + ":" + port;
}
//the SNMP WWW service index of the main server is always 1
mainServerPluginConfig.put(new PropertySimple(
ApacheVirtualHostServiceComponent.SNMP_WWW_SERVICE_INDEX_CONFIG_PROP, 1));
- //BZ 612189 - this can simply the MAIN_SERVER_RESOURCE_KEY only once we have
resource upgrade
- if (key == null) {
- key = ApacheVirtualHostServiceComponent.MAIN_SERVER_RESOURCE_KEY;
- }
-
- //BZ 612189 - remove this once we have resource upgrade
- //ok, this is hacky, but...
- //in order not to change the semantics of the resource key creation
- //we use the legacy resource key (i.e. the one based on SNMP) only
- //if SNMP is available, even though we now have algorithm that can
- //determine the SNMP resource key without it being available.
- if (snmpDiscoveries != null) {
- key =
context.getParentResourceComponent().getAddressUtility().getHttpdInternalMainServerAddressRepresentation(runtimeConfig).toString(false);
- }
-
DiscoveredResourceDetails mainServer = new
DiscoveredResourceDetails(resourceType,
key, "Main", null, null,
mainServerPluginConfig, null);
@@ -260,7 +241,38 @@ public class ApacheVirtualHostServiceDiscoveryComponent implements
ResourceDisco
// }
// }
- public static String createResourceKey(String serverName, List<String> hosts)
{
+ public static String createMainServerResourceKey(ApacheServerComponent
serverComponent, ApacheDirectiveTree runtimeConfig, SnmpWwwServiceIndexes snmpDiscoveries)
throws Exception {
+ String mainServerUrl = serverComponent.getServerUrl();
+
+ String key = null;
+
+ if (mainServerUrl != null && !"null".equals(mainServerUrl)) {
+ URI mainServerUri = new URI(mainServerUrl);
+ String host = mainServerUri.getHost();
+ int port = mainServerUri.getPort();
+ if (port == -1) {
+ port = 80;
+ }
+
+ key = host + ":" + port;
+ } else {
+ key = ApacheVirtualHostServiceComponent.MAIN_SERVER_RESOURCE_KEY;
+ }
+
+ //BZ 612189 - remove this once we have resource upgrade
+ //ok, this is hacky, but...
+ //in order not to change the semantics of the resource key creation
+ //we use the legacy resource key (i.e. the one based on SNMP) only
+ //if SNMP is available, even though we now have algorithm that can
+ //determine the SNMP resource key without it being available.
+ if (snmpDiscoveries != null) {
+ key =
serverComponent.getAddressUtility().getHttpdInternalMainServerAddressRepresentation(runtimeConfig).toString(false,
false);
+ }
+
+ return key;
+ }
+
+ public static String createResourceKey(String serverName, List<String> hosts,
ApacheDirectiveTree runtimeConfig, ApacheServerComponent serverComponent,
SnmpWwwServiceIndexes snmpDiscoveries) {
//BZ 612189 - swap the impls once resource upgrade is in place
// StringBuilder keyBuilder = new StringBuilder();
// if (serverName != null) {
@@ -275,6 +287,16 @@ public class ApacheVirtualHostServiceDiscoveryComponent implements
ResourceDisco
//
// return keyBuilder.toString();
+ //BZ 612189 - remove this once we have resource upgrade
+ //ok, this is hacky, but...
+ //in order not to change the semantics of the resource key creation
+ //we use the legacy resource key (i.e. the one based on SNMP) only
+ //if SNMP is available, even though we now have algorithm that can
+ //determine the SNMP resource key without it being available.
+ if (snmpDiscoveries != null) {
+ return
serverComponent.getAddressUtility().getHttpdInternalVirtualHostAddressRepresentation(runtimeConfig,
hosts.get(0), serverName).toString(false, false);
+ }
+
//try to derive the same resource key as the SNMP would have... this is to
prevent the duplication of
//vhost resources after the SNMP was configured - how I wish resource upgrade
made it to 3.0 to prevent this
//kind of guessing being necessary.
@@ -302,9 +324,9 @@ public class ApacheVirtualHostServiceDiscoveryComponent implements
ResourceDisco
* @return
*/
@Deprecated
- private SnmpWwwServiceIndexes
getSnmpDiscoveries(ResourceDiscoveryContext<ApacheServerComponent> discoveryContext)
{
+ public static SnmpWwwServiceIndexes getSnmpDiscoveries(ApacheServerComponent
serverComponent) {
try {
- SNMPSession snmpSession =
discoveryContext.getParentResourceComponent().getSNMPSession();
+ SNMPSession snmpSession = serverComponent.getSNMPSession();
List<SNMPValue> nameValues;
List<SNMPValue> portValues;
SNMPValue descValue;
@@ -338,7 +360,7 @@ public class ApacheVirtualHostServiceDiscoveryComponent implements
ResourceDisco
return ret;
} catch (Exception e) {
- log.debug("Error while trying to contact SNMP of the apache server
" + discoveryContext.getParentResourceContext().getResourceKey(), e);
+ log.debug("Error while trying to contact SNMP of the apache server
" + serverComponent.getResourceKey(), e);
return null;
}
}
@@ -349,9 +371,9 @@ public class ApacheVirtualHostServiceDiscoveryComponent implements
ResourceDisco
* @author Lukas Krejci
*/
@Deprecated
- private static class SnmpWwwServiceIndexes {
+ public static class SnmpWwwServiceIndexes {
public List<SNMPValue> names;
public List<SNMPValue> ports;
public SNMPValue desc;
}
-}
\ No newline at end of file
+}
diff --git
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/HttpdAddressUtility.java
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/HttpdAddressUtility.java
index 7c55fb4..61fc5b9 100644
---
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/HttpdAddressUtility.java
+++
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/HttpdAddressUtility.java
@@ -251,10 +251,10 @@ public enum HttpdAddressUtility {
@Override
public String toString() {
- return toString(true);
+ return toString(true, true);
}
- public String toString(boolean includeScheme) {
+ public String toString(boolean includeScheme, boolean interpretWildcardPort) {
StringBuilder bld = new StringBuilder();
if (includeScheme) {
@@ -266,7 +266,7 @@ public enum HttpdAddressUtility {
if (port != NO_PORT_SPECIFIED_VALUE) {
bld.append(":");
- if (port == PORT_WILDCARD_VALUE) {
+ if (port == PORT_WILDCARD_VALUE && interpretWildcardPort) {
bld.append(WILDCARD);
} else {
bld.append(port);
diff --git a/modules/plugins/apache/src/main/resources/META-INF/rhq-plugin.xml
b/modules/plugins/apache/src/main/resources/META-INF/rhq-plugin.xml
index 870eaff..aa97738 100644
--- a/modules/plugins/apache/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/apache/src/main/resources/META-INF/rhq-plugin.xml
@@ -441,6 +441,18 @@
</operation>
+ <operation name="detect_snmp_indexes" displayName="Detect SNMP
WWW Service Index values for Virtual Hosts"
+ description="If the order of the virtual hosts changed in your apache
configuration file, you will need to reconfigure each of the virtual host resources of
this server with the new SNMP WWW Service Index. This value is needed for correct reading
of the configuration as well as monitoring. You will need to manually update each of the
inventoried virtual host resources to correspond to the results of this
operation.">
+ <results>
+ <c:list-property name="snmpIndexesPerResourceKey">
+ <c:map-property name="snmpIndexForResourceKey">
+ <c:simple-property name="resourceKey"
displayName="Virtual Host Resource Key" />
+ <c:simple-property name="snmpWwwServiceIndex"
displayName="SNMP WWW Service Index" type="integer"/>
+ </c:map-property>
+ </c:list-property>
+ </results>
+ </operation>
+
<metric displayName="Number of Concurrent Connections"
property="applInboundAssociations"
destinationType="The number of current connections to this
application"
defaultOn="true" defaultInterval="300000"
displayType="summary" units="none"/>
commit 3e93c6fb5d7dc6b2ab1522d97b845872afbfe1df
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Apr 29 19:08:51 2011 +0200
BZ 700616 - apache vhost resource configuration loading/update converted to take
advantage of the SNMP WWW Service Index property, no imperfect RK matching anymore.
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 b37361c..f122cec 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
@@ -58,11 +58,13 @@ import org.rhq.core.pluginapi.measurement.MeasurementFacet;
import org.rhq.core.pluginapi.util.ResponseTimeConfiguration;
import org.rhq.core.pluginapi.util.ResponseTimeLogParser;
import org.rhq.plugins.apache.mapping.ApacheAugeasMapping;
+import org.rhq.plugins.apache.parser.ApacheDirective;
import org.rhq.plugins.apache.parser.ApacheDirectiveTree;
import org.rhq.plugins.apache.util.AugeasNodeSearch;
import org.rhq.plugins.apache.util.AugeasNodeValueUtil;
import org.rhq.plugins.apache.util.ConfigurationTimestamp;
import org.rhq.plugins.apache.util.HttpdAddressUtility;
+import org.rhq.plugins.apache.util.RuntimeApacheConfiguration;
import org.rhq.plugins.www.snmp.SNMPException;
import org.rhq.plugins.www.snmp.SNMPSession;
import org.rhq.plugins.www.snmp.SNMPValue;
@@ -333,99 +335,51 @@ public class ApacheVirtualHostServiceComponent implements
ResourceComponent<Apac
*/
public AugeasNode getNode(AugeasTree tree) {
String resourceKey = resourceContext.getResourceKey();
-
- if
(ApacheVirtualHostServiceComponent.MAIN_SERVER_RESOURCE_KEY.equals(resourceKey)) {
- return tree.getRootNode();
+ String idxString =
resourceContext.getPluginConfiguration().getSimpleValue(SNMP_WWW_SERVICE_INDEX_CONFIG_PROP,
null);
+
+ ApacheServerComponent server = resourceContext.getParentResourceComponent();
+
+ if (idxString == null || idxString.trim().length() == 0) {
+ throw new IllegalStateException("The SNMP WWW Service Index property has
to be a positive integer. Without it, it is impossible to locate the configuration of the
virtual host with resource key [" + resourceKey + "]");
}
-
- String serverName = null;
- int pipeIdx = resourceKey.indexOf('|');
- if (pipeIdx >= 0) {
- serverName = resourceKey.substring(0, pipeIdx);
+
+ int snmpIdx = Integer.parseInt(idxString);
+
+ if (snmpIdx < 1) {
+ throw new IllegalStateException("The SNMP WWW Service Index property has
to be a positive integer. Without it, it is impossible to locate the configuration of the
virtual host with resource key [" + resourceKey + "]");
+ }
+
+ if (snmpIdx == 1) {
+ return tree.getRootNode();
}
- String[] addrs = resourceKey.substring(pipeIdx + 1).split(" ");
- List<AugeasNode> nodes = tree.matchRelative(tree.getRootNode(),
"<VirtualHost");
- List<AugeasNode> virtualHosts = new ArrayList<AugeasNode>();
- boolean updated = false;
-
-//BZ 612189 - uncomment this algo once the resource upgrade is in place
-// for (AugeasNode node : nodes) {
-// updated = false;
-// List<AugeasNode> serverNameNodes = tree.matchRelative(node,
"ServerName/param");
-// String tempServerName = null;
-//
-// if (!(serverNameNodes.isEmpty())) {
-// tempServerName = serverNameNodes.get(0).getValue();
-// }
-// if (tempServerName == null & serverName == null)
-// updated = true;
-// if (tempServerName != null & serverName != null)
-// if (tempServerName.equals(serverName)){
-// updated = true;
-// }
-//
-//
-// if (updated){
-// updated = false;
-// List<AugeasNode> params =
node.getChildByLabel("param");
-// for (AugeasNode nd : params) {
-// updated = false;
-// for (String adr : addrs) {
-// if (adr.equals(nd.getValue()))
-// updated = true;
-// }
-// if (!updated)
-// break;
-// }
-//
-// if (updated)
-// virtualHosts.add(node);
-// }
-// }
-
- //BZ 612189 - remove this once resource upgrade is in place
- HttpdAddressUtility.Address resourceKeyAddress =
HttpdAddressUtility.Address.parse(resourceKey);
+ final List<AugeasNode> allVhosts = new ArrayList<AugeasNode>();
- AugeasNode bestNode = null;
- int bestMatch = 0;
- for(AugeasNode node : nodes) {
- List<AugeasNode> vhostAddressNodes =
node.getChildByLabel("param");
-
- List<HttpdAddressUtility.Address> vhostAddresses = new
ArrayList<HttpdAddressUtility.Address>();
- for (AugeasNode vhostAddressNode : vhostAddressNodes) {
-
vhostAddresses.add(HttpdAddressUtility.Address.parse(vhostAddressNode.getValue()));
+ RuntimeApacheConfiguration.walkRuntimeConfig(new
RuntimeApacheConfiguration.NodeVisitor<AugeasNode>() {
+ public void visitOrdinaryNode(AugeasNode node) {
+ if ("<VirtualHost".equalsIgnoreCase(node.getLabel())) {
+ allVhosts.add(node);
+ }
}
- int matchRate = matchRate(vhostAddresses, resourceKeyAddress);
- if (bestMatch < matchRate) {
- bestNode = node;
+ public void visitConditionalNode(AugeasNode node, boolean isSatisfied) {
}
- }
-
- if (bestNode != null) {
- return bestNode;
- }
+ }, tree, server.getCurrentProcessInfo(), server.getCurrentBinaryInfo(),
server.getModuleNames());
- //BZ 612189 - remove this once we have resource upgrade
- //ok, one final attempt... the legacy resource key format for the MainServer is
just a host:port as with the rest of the vhosts, let's try that
- try {
- String serverUrl =
resourceContext.getParentResourceComponent().getServerUrl();
- URI serverUri = new URI(serverUrl);
- String expectedResourceKey = serverUri.getHost() + ":" +
serverUri.getPort();
-
- HttpdAddressUtility.Address expectedAddress =
HttpdAddressUtility.Address.parse(expectedResourceKey);
- HttpdAddressUtility.Address actualAddress =
HttpdAddressUtility.Address.parse(resourceKey);
+ //transform the SNMP index into the index of the vhost
+ int idx = allVhosts.size() - snmpIdx + 1;
+
+ AugeasNode vhost = allVhosts.get(idx);
+
+ //now check if there are any If* directives underneath this vhost.
+ //we don't support configuring such beasts.
+ if (vhost.getChildByLabel("<IfDefine").isEmpty() &&
vhost.getChildByLabel("<IfModule").isEmpty()
+ && vhost.getChildByLabel("<IfVersion").isEmpty()) {
- if (matchRate(Collections.singletonList(expectedAddress), actualAddress) >
0) {
- return tree.getRootNode();
- }
- } catch (URISyntaxException e) {
- log.warn("Failed to parse the server URL when trying to match the vhost
with the main server.", e);
+ return vhost;
+ } else {
+ throw new IllegalStateException("Configuration of the virtual host
[" + resourceKey + "] contains conditional blocks. This is not supported by this
plugin.");
}
-
- throw new IllegalStateException("Could not find virtual host configuration
for virtual host resource : "
- + resourceKey + ". Reading and updating configuration of virtual hosts
nested inside If* directives is not supported by this plugin.");
}
/**
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 25f5ad9..a9b411c 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
@@ -19,7 +19,10 @@
package org.rhq.plugins.apache.util;
+import java.util.ArrayDeque;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -30,8 +33,11 @@ import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.rhq.augeas.node.AugeasNode;
+import org.rhq.augeas.tree.AugeasTree;
import org.rhq.core.system.ProcessInfo;
import org.rhq.core.util.OSGiVersionComparator;
+import org.rhq.plugins.apache.augeas.ApacheAugeasTree;
import org.rhq.plugins.apache.parser.ApacheDirective;
import org.rhq.plugins.apache.parser.ApacheDirectiveTree;
@@ -51,6 +57,187 @@ public class RuntimeApacheConfiguration {
}
/**
+ * 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)}
+ * methods.
+ */
+ public interface NodeVisitor<T> {
+
+ /**
+ * This method is called whenever the apache config tree walker encounters one of
the If* directives (IfModule, IfDefine, IfVersion).
+ *
+ * @param node the If* directive
+ * @param isSatisfied true if the directive's condition is satisfied, false
otherwise
+ */
+ void visitConditionalNode(T node, boolean isSatisfied);
+
+ /**
+ * This method is called for all "ordinary" directives that the apache
config tree walker encounters (i.e. all but the ones handled by the {@link
#visitConditionalNode(Object)}
+ * method.
+ *
+ * @param node the directive
+ */
+ void visitOrdinaryNode(T node);
+ }
+
+ /**
+ * Extension of the {@link NodeVisitor} that is used internally to abstract out the
+ * algorithm from the underlying data model.
+ * There's just one transform method that walks any kind of apache config tree
representation
+ * and produces the runtime config. Different impls of this interface can
+ * produce different "side-effects" of that walk.
+ *
+ * @author Lukas Krejci
+ */
+ private interface TreeWalker<T> extends NodeVisitor<T> {
+
+ void onBeforeChildrenScan(T node);
+
+ void onAfterChildrenScan(T node);
+
+ Collection<T> getChildren(T node);
+
+ String getValue(T node);
+
+ List<String> getValues(T node);
+
+ String getName(T node);
+ }
+
+ /**
+ * Impl of {@link TreeWalker} interface that transforms the tree by replacing
+ * the conditional directives that are satisfied with their "contents".
+ *
+ * @author Lukas Krejci
+ */
+ private static class TransformingWalker implements TreeWalker<ApacheDirective>
{
+
+ private static class NodesToModify {
+ ArrayList<ApacheDirective> nodesToRemove = new
ArrayList<ApacheDirective>();
+ ArrayList<ApacheDirective> nodesToPromote = new
ArrayList<ApacheDirective>();
+ }
+
+ private Deque<NodesToModify> currentNodeStack = new
ArrayDeque<NodesToModify>();
+
+ public void visitConditionalNode(ApacheDirective node, boolean isSatisfied) {
+ NodesToModify nodes = currentNodeStack.peek();
+ if (isSatisfied) {
+ nodes.nodesToPromote.add(node);
+ } else {
+ nodes.nodesToRemove.add(node);
+ }
+ }
+
+ public void visitOrdinaryNode(ApacheDirective node) {
+ }
+
+ public void onBeforeChildrenScan(ApacheDirective node) {
+ currentNodeStack.push(new NodesToModify());
+ }
+
+ public void onAfterChildrenScan(ApacheDirective parentNode) {
+ NodesToModify nodes = currentNodeStack.pop();
+
+ for(ApacheDirective node : nodes.nodesToRemove) {
+ parentNode.getChildDirectives().remove(node);
+ }
+
+ //add the children of node as children of parent node at the place node
+ //was declared and remove node ... i.e. make it so as if the child nodes
+ //of node were directly in the parentNode in the place of node
+ for(ApacheDirective node : nodes.nodesToPromote) {
+ int nodeIdx = parentNode.getChildDirectives().indexOf(node);
+
+ List<ApacheDirective> childNodes = node.getChildDirectives();
+ for(int i = childNodes.size() - 1; i >= 0; --i) {
+ ApacheDirective childNode = childNodes.get(i);
+ parentNode.getChildDirectives().add(nodeIdx, childNode);
+ childNode.setParentNode(parentNode);
+ }
+
+ parentNode.getChildDirectives().remove(nodeIdx + childNodes.size());
+ }
+ }
+
+ public Collection<ApacheDirective> getChildren(ApacheDirective node) {
+ return node.getChildDirectives();
+ }
+
+ public String getValue(ApacheDirective node) {
+ return node.getValuesAsString();
+ }
+
+ public List<String> getValues(ApacheDirective node) {
+ return node.getValues();
+ }
+ public String getName(ApacheDirective node) {
+ return node.getName();
+ }
+ }
+
+ /**
+ * This is a "wrapping" class for the number of parameters that are needed
+ * in the transform method.
+ *
+ * @author Lukas Krejci
+ */
+ private static class TransformState {
+ public Set<String> loadedModules;
+ public Set<String> defines;
+ public Map<String, String> moduleNames;
+ public Map<String, String> moduleFiles;
+ public String httpdVersion;
+
+ public TransformState(ProcessInfo httpdProcessInfo, ApacheBinaryInfo
httpdBinaryInfo, Map<String, String> moduleNames) {
+ defines = new HashSet<String>(httpdBinaryInfo.getCompiledInDefines());
+
+ if (httpdProcessInfo != null) {
+ String[] args = httpdProcessInfo.getCommandLine();
+ for(int i = 1; i < args.length; ++i) {
+ String define = null;
+ if (args[i] != null && args[i].startsWith("-D")) {
+ define = args[i].substring(2).trim();
+ }
+
+ if (define != null && define.isEmpty()) {
+ //this means we saw an empty -D arg. This can happen if there is
a space between -D and the value.
+ //That is legal though, so we have to accomodate for that.
+ if (i < args.length - 1) {
+ define = args[i + 1].trim();
+ if (define.startsWith("-")) {
+ //this would be another option
+ define = null;
+ } else {
+ ++i; //we can skip the next arg
+ }
+ } else {
+ define = null; //well -D is the last argument
+ }
+ }
+
+ if (define != null) {
+ defines.add(define);
+ }
+ }
+ }
+
+ loadedModules = new HashSet<String>();
+ loadedModules.addAll(httpdBinaryInfo.getCompiledInModules());
+
+ this.moduleNames = moduleNames;
+
+ //build a map for reverse lookup we might need in the transform method
+ moduleFiles = new HashMap<String, String>(moduleNames.size());
+ for(Map.Entry<String, String> e : moduleNames.entrySet()) {
+ moduleFiles.put(e.getValue(), e.getKey());
+ }
+
+ httpdVersion = httpdBinaryInfo.getVersion();
+ }
+ }
+
+ /**
* Given the apache configuration and information about the parameters httpd was
executed
* with this method provides the directive tree that corresponds to the actual
* runtime configuration as used by httpd.
@@ -67,66 +254,114 @@ public class RuntimeApacheConfiguration {
*/
public static ApacheDirectiveTree extract(ApacheDirectiveTree tree, ProcessInfo
httpdProcessInfo, ApacheBinaryInfo httpdBinaryInfo, Map<String, String> moduleNames)
{
ApacheDirectiveTree ret = tree.clone();
+
+ transform(new TransformingWalker(), ret.getRootNode(), new
TransformState(httpdProcessInfo, httpdBinaryInfo, moduleNames));
+
+ return ret;
+ }
+
+ public static void walkRuntimeConfig(final NodeVisitor<ApacheDirective>
visitor, ApacheDirectiveTree tree, ProcessInfo httpdProcessInfo, ApacheBinaryInfo
httpdBinaryInfo, Map<String, String> moduleNames) {
+ TreeWalker<ApacheDirective> walker = new
TreeWalker<ApacheDirective>() {
+
+ public void visitConditionalNode(ApacheDirective node, boolean isSatisfied)
{
+ visitor.visitConditionalNode(node, isSatisfied);
+ }
+
+ public void visitOrdinaryNode(ApacheDirective node) {
+ visitor.visitOrdinaryNode(node);
+ }
+
+ public void onBeforeChildrenScan(ApacheDirective node) {
+ }
+
+ public void onAfterChildrenScan(ApacheDirective node) {
+ }
+
+ public Collection<ApacheDirective> getChildren(ApacheDirective node) {
+ return node.getChildDirectives();
+ }
+
+ public String getValue(ApacheDirective node) {
+ return node.getValuesAsString();
+ }
+
+ public List<String> getValues(ApacheDirective node) {
+ return node.getValues();
+ }
+
+ public String getName(ApacheDirective node) {
+ return node.getName();
+ }
- List<String> defines = new
ArrayList<String>(httpdBinaryInfo.getCompiledInDefines());
+ };
- if (httpdProcessInfo != null) {
- String[] args = httpdProcessInfo.getCommandLine();
- for(int i = 1; i < args.length; ++i) {
- String define = null;
- if (args[i] != null && args[i].startsWith("-D")) {
- define = args[i].substring(2).trim();
+ transform(walker, tree.getRootNode(), new TransformState(httpdProcessInfo,
httpdBinaryInfo, moduleNames));
+ }
+
+ public static void walkRuntimeConfig(final NodeVisitor<AugeasNode> visitor,
AugeasTree tree, ProcessInfo httpdProcessInfo, ApacheBinaryInfo httpdBinaryInfo,
Map<String, String> moduleNames) {
+ TreeWalker<AugeasNode> walker = new TreeWalker<AugeasNode>() {
+
+ public void visitConditionalNode(AugeasNode node, boolean isSatisfied) {
+ visitor.visitConditionalNode(node, isSatisfied);
+ }
+
+ public void visitOrdinaryNode(AugeasNode node) {
+ visitor.visitOrdinaryNode(node);
+ }
+
+ public void onBeforeChildrenScan(AugeasNode node) {
+ }
+
+ public void onAfterChildrenScan(AugeasNode node) {
+ }
+
+ public Collection<AugeasNode> getChildren(AugeasNode node) {
+ return node.getChildNodes();
+ }
+
+ public String getValue(AugeasNode node) {
+ StringBuilder bld = new StringBuilder();
+ for(String val : getValues(node)) {
+ bld.append(val);
}
+ return bld.toString();
+ }
+
+ public List<String> getValues(AugeasNode node) {
+ ArrayList<String> ret = new ArrayList<String>();
- if (define != null && define.isEmpty()) {
- //this means we saw an empty -D arg. This can happen if there is a
space between -D and the value.
- //That is legal though, so we have to accomodate for that.
- if (i < args.length - 1) {
- define = args[i + 1].trim();
- if (define.startsWith("-")) {
- //this would be another option
- define = null;
- } else {
- ++i; //we can skip the next arg
- }
- } else {
- define = null; //well -D is the last argument
- }
- }
+ List<AugeasNode> params = node.getChildByLabel("param");
- if (define != null) {
- defines.add(define);
+ for(AugeasNode n : params) {
+ ret.add(n.getValue());
}
+
+ return ret;
}
- }
-
- HashSet<String> loadedModules = new HashSet<String>();
- loadedModules.addAll(httpdBinaryInfo.getCompiledInModules());
-
- //build a map for reverse lookup we might need in the transform method
- HashMap<String, String> moduleFiles = new HashMap<String,
String>(moduleNames.size());
- for(Map.Entry<String, String> e : moduleNames.entrySet()) {
- moduleFiles.put(e.getValue(), e.getKey());
- }
-
- transform(ret.getRootNode(), loadedModules, defines, moduleNames, moduleFiles,
httpdBinaryInfo.getVersion());
- return ret;
+ public String getName(AugeasNode node) {
+ return node.getLabel();
+ }
+ };
+
+ transform(walker, tree.getRootNode(), new TransformState(httpdProcessInfo,
httpdBinaryInfo, moduleNames));
}
- private static void transform(ApacheDirective parentNode, Set<String>
currentlyLoadedModules, List<String> defines, Map<String, String> moduleNames,
Map<String, String> moduleFiles, String httpdVersion) {
- if (parentNode.getChildDirectives().isEmpty()) {
+ private static <T> void transform(TreeWalker<T> walker, T parentNode,
TransformState state) {
+ if (walker.getChildren(parentNode).isEmpty()) {
return;
}
- ArrayList<ApacheDirective> nodesToRemove = new
ArrayList<ApacheDirective>();
- ArrayList<ApacheDirective> nodesToPromote = new
ArrayList<ApacheDirective>();
+ walker.onBeforeChildrenScan(parentNode);
- for (ApacheDirective node : parentNode.getChildDirectives()) {
- if (node.getName().equalsIgnoreCase("LoadModule")) {
- currentlyLoadedModules.add(node.getValues().get(0));
- } else if (node.getName().equalsIgnoreCase("<IfModule")) {
- String moduleFile = node.getValuesAsString();
+ for (T node : walker.getChildren(parentNode)) {
+ boolean recurseFurther = true;
+
+ if (walker.getName(node).equalsIgnoreCase("LoadModule")) {
+ state.loadedModules.add(walker.getValue(node));
+ walker.visitOrdinaryNode(node);
+ } else if (walker.getName(node).equalsIgnoreCase("<IfModule"))
{
+ String moduleFile = walker.getValue(node);
boolean negate = false;
if (moduleFile.startsWith("!")) {
negate = true;
@@ -135,7 +370,7 @@ public class RuntimeApacheConfiguration {
boolean result = false;
- switch(isModuleLoaded(moduleFile, currentlyLoadedModules, moduleNames,
moduleFiles)) {
+ switch(isModuleLoaded(moduleFile, state.loadedModules, state.moduleNames,
state.moduleFiles)) {
case LOADED : result = true; break;
case NOT_LOADED : result = false; break;
case UNKNOWN :
@@ -143,39 +378,35 @@ public class RuntimeApacheConfiguration {
continue;
}
- if (result != negate) {
- nodesToPromote.add(node);
- } else {
- nodesToRemove.add(node);
- }
- } else if (node.getName().equalsIgnoreCase("<IfDefine")) {
- String define = node.getValuesAsString();
+ 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 = defines.contains(define);
+ boolean result = state.defines.contains(define);
- if (negate != result) {
- nodesToPromote.add(node);
- } else {
- nodesToRemove.add(node);
- }
- } else if (node.getName().equalsIgnoreCase("<IfVersion")) {
+ 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", currentlyLoadedModules,
moduleNames, moduleFiles) != ModuleLoadedState.LOADED) {
+ 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 = node.getValues();
+ List<String> values = walker.getValues(node);
String operator = null;
String version = null;
boolean negate = false;
@@ -226,54 +457,38 @@ public class RuntimeApacheConfiguration {
boolean result = false;
if ("=".equals(operator)) {
if (regex) {
- result = Pattern.matches(version, httpdVersion);
+ result = Pattern.matches(version, state.httpdVersion);
} else {
- result = comp.compare(version, httpdVersion) == 0;
+ result = comp.compare(version, state.httpdVersion) == 0;
}
} else if ("~".equals(operator)) {
- result = Pattern.matches(version, httpdVersion);
+ result = Pattern.matches(version, state.httpdVersion);
} else if (">".equals(operator)) {
- result = comp.compare(httpdVersion, version) > 0;
+ result = comp.compare(state.httpdVersion, version) > 0;
} else if (">=".equals(operator)) {
- result = comp.compare(httpdVersion, version) >= 0;
+ result = comp.compare(state.httpdVersion, version) >= 0;
} else if ("<".equals(operator)) {
- result = comp.compare(httpdVersion, version) < 0;
+ result = comp.compare(state.httpdVersion, version) < 0;
} else if ("<=".equals(operator)) {
- result = comp.compare(httpdVersion, version) <= 0;
+ result = comp.compare(state.httpdVersion, version) <= 0;
} else {
LOG.warn("Unknown operator " + operator + " in an
IfVersion directive.");
continue;
}
- if (negate != result) {
- nodesToPromote.add(node);
- } else {
- nodesToRemove.add(node);
- }
+ recurseFurther = result != negate;
+
+ walker.visitConditionalNode(node, recurseFurther);
+ } else {
+ walker.visitOrdinaryNode(node);
+ }
+
+ if (recurseFurther) {
+ transform(walker, node, state);
}
-
- transform(node, currentlyLoadedModules, defines, moduleNames, moduleFiles,
httpdVersion);
- }
-
- for(ApacheDirective node : nodesToRemove) {
- parentNode.getChildDirectives().remove(node);
}
- //add the children of node as children of parent node at the place node
- //was declared and remove node ... i.e. make it so as if the child nodes
- //of node were directly in the parentNode in the place of node
- for(ApacheDirective node : nodesToPromote) {
- int nodeIdx = parentNode.getChildDirectives().indexOf(node);
-
- List<ApacheDirective> childNodes = node.getChildDirectives();
- for(int i = childNodes.size() - 1; i >= 0; --i) {
- ApacheDirective childNode = childNodes.get(i);
- parentNode.getChildDirectives().add(nodeIdx, childNode);
- childNode.setParentNode(parentNode);
- }
-
- parentNode.getChildDirectives().remove(nodeIdx + childNodes.size());
- }
+ walker.onAfterChildrenScan(parentNode);
}
private static ModuleLoadedState isModuleLoaded(String moduleIdentifier,
Set<String> currentlyLoadedModules, Map<String, String> moduleNames,
Map<String, String> moduleFiles) {
commit 116411a3e10a5a2e5840d620a14326f5ca9974ce
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Apr 29 19:06:15 2011 +0200
BZ 700616 - apache server discovery component uses runtime discovery as well now
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 17829eb..4cd0184 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
@@ -309,7 +309,8 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
pluginConfig.put(inclusionGlobs);
ApacheDirectiveTree serverConfig = loadParser(serverConfigFile.getAbsolutePath(),
serverRoot);
-
+ serverConfig = RuntimeApacheConfiguration.extract(serverConfig,
process.getProcessInfo(), binaryInfo, getDefaultModuleNames(binaryInfo.getVersion()));
+
String serverUrl = null;
String vhostsGlobInclude = null;
commit 069d5fc2d0e10278277223dd2c04639caa25e3a4
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Apr 29 19:05:26 2011 +0200
BZ 700616 - First pass at converting the discovery to using the runtime
configuration.
Note that THIS DOES NOT COMPILE, but I'm commiting it anyway to logically split
the commits.
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 c4ceb0b..f44485e 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
@@ -416,7 +416,7 @@ public class ApacheServerComponent implements
AugeasRHQComponent<PlatformCompone
if (!matcher.matches())
throw new Exception("Wrong format of virtual host resource
name. The right format is Address:Port.");
- addr = getAddressUtility().getVirtualHostSampleAddress(parserTree,
vhostDefs[0], serverName, false);
+ addr = getAddressUtility().getVirtualHostSampleAddress(parserTree,
vhostDefs[0], serverName);
} catch (Exception e) {
report.setStatus(CreateResourceStatus.FAILURE);
report.setErrorMessage("Wrong format of virtual host resource
name.");
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 fc61097..9da9c31 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
@@ -76,9 +76,11 @@ public class ApacheVirtualHostServiceDiscoveryComponent implements
ResourceDisco
ApacheServerComponent serverComponent = context.getParentResourceComponent();
ApacheDirectiveTree tree = serverComponent.loadParser();
-
+
+ tree = RuntimeApacheConfiguration.extract(tree,
serverComponent.getCurrentProcessInfo(), serverComponent.getCurrentBinaryInfo(),
serverComponent.getModuleNames());
+
//first define the root server as one virtual host
- discoverMainServer(context, discoveredResources, snmpDiscoveries);
+ discoverMainServer(context, discoveredResources, snmpDiscoveries, tree);
ResourceType resourceType = context.getResourceType();
@@ -87,6 +89,8 @@ public class ApacheVirtualHostServiceDiscoveryComponent implements
ResourceDisco
List<ApacheDirective> virtualHosts =
tree.search("/<VirtualHost");
+ int currentVhostIndex = 0;
+
for (ApacheDirective node : virtualHosts) {
List<String> hosts = node.getValues();
String firstAddress = hosts.get(0);
@@ -102,7 +106,7 @@ public class ApacheVirtualHostServiceDiscoveryComponent implements
ResourceDisco
Configuration pluginConfiguration = context.getDefaultPluginConfiguration();
- Address address =
serverComponent.getAddressUtility().getVirtualHostSampleAddress(tree, firstAddress,
serverName, false);
+ Address address =
serverComponent.getAddressUtility().getVirtualHostSampleAddress(tree, firstAddress,
serverName);
if (address != null) {
String scheme = address.scheme;
String hostToPing = address.host;
@@ -146,13 +150,23 @@ public class ApacheVirtualHostServiceDiscoveryComponent implements
ResourceDisco
}
//BZ 612189 - remove this once we have resource upgrade
+ //ok, this is hacky, but...
+ //in order not to change the semantics of the resource key creation
+ //we use the legacy resource key (i.e. the one based on SNMP) only
+ //if SNMP is available, even though we now have algorithm that can
+ //determine the SNMP resource key without it being available.
if (snmpDiscoveries != null) {
- String legacyResourceKey = getLegacyResourceKey(context, resourceKey,
snmpDiscoveries);
- resourceKey = legacyResourceKey != null ? legacyResourceKey :
resourceKey;
+ resourceKey =
serverComponent.getAddressUtility().getHttpdInternalVirtualHostAddressRepresentation(tree,
firstAddress, serverName).toString(false);
}
+ //as the last thing, let's determine the SNMP WWW Service Index of this
vhost
+ int snmpWwwServiceIndex = virtualHosts.size() - currentVhostIndex + 1;
+ pluginConfiguration.put(new
PropertySimple(ApacheVirtualHostServiceComponent.SNMP_WWW_SERVICE_INDEX_CONFIG_PROP,
snmpWwwServiceIndex));
+
discoveredResources.add(new DiscoveredResourceDetails(resourceType,
resourceKey, resourceName, null, null,
pluginConfiguration, null));
+
+ currentVhostIndex++;
}
return discoveredResources;
@@ -160,7 +174,7 @@ public class ApacheVirtualHostServiceDiscoveryComponent implements
ResourceDisco
private void discoverMainServer(ResourceDiscoveryContext<ApacheServerComponent>
context,
- Set<DiscoveredResourceDetails> discoveredResources, SnmpWwwServiceIndexes
snmpDiscoveries) throws Exception {
+ Set<DiscoveredResourceDetails> discoveredResources, SnmpWwwServiceIndexes
snmpDiscoveries, ApacheDirectiveTree runtimeConfig) throws Exception {
ResourceType resourceType = context.getResourceType();
Configuration mainServerPluginConfig = context.getDefaultPluginConfiguration();
@@ -206,9 +220,13 @@ public class ApacheVirtualHostServiceDiscoveryComponent implements
ResourceDisco
}
//BZ 612189 - remove this once we have resource upgrade
+ //ok, this is hacky, but...
+ //in order not to change the semantics of the resource key creation
+ //we use the legacy resource key (i.e. the one based on SNMP) only
+ //if SNMP is available, even though we now have algorithm that can
+ //determine the SNMP resource key without it being available.
if (snmpDiscoveries != null) {
- String legacyKey = getLegacyResourceKey(context, key, snmpDiscoveries);
- key = legacyKey != null ? legacyKey : key;
+ key =
context.getParentResourceComponent().getAddressUtility().getHttpdInternalMainServerAddressRepresentation(runtimeConfig).toString(false);
}
DiscoveredResourceDetails mainServer = new
DiscoveredResourceDetails(resourceType,
@@ -217,30 +235,30 @@ public class ApacheVirtualHostServiceDiscoveryComponent implements
ResourceDisco
discoveredResources.add(mainServer);
}
- /**
- * @deprecated remove this once we have resource upgrade
- * @param discoveryContext
- * @param newStyleResourceKey
- * @param snmpDiscoveries
- * @return
- */
- @Deprecated
- private String
getLegacyResourceKey(ResourceDiscoveryContext<ApacheServerComponent>
discoveryContext, String newStyleResourceKey, SnmpWwwServiceIndexes snmpDiscoveries) {
- int snmpWwwServiceIndex =
ApacheVirtualHostServiceComponent.getMatchingWwwServiceIndex(discoveryContext.getParentResourceComponent(),
newStyleResourceKey, snmpDiscoveries.names, snmpDiscoveries.ports);
-
- if (snmpWwwServiceIndex < 1) {
- return null;
- } else {
- String host = snmpDiscoveries.names.get(snmpWwwServiceIndex - 1).toString();
- String fullPort = snmpDiscoveries.ports.get(snmpWwwServiceIndex -
1).toString();
-
- // The port value will be in the form "1.3.6.1.2.1.6.XXXXX",
- // where "1.3.6.1.2.1.6" represents the TCP protocol ID,
- // and XXXXX is the actual port number
- String port = fullPort.substring(fullPort.lastIndexOf(".") + 1);
- return host + ":" + port;
- }
- }
+// /**
+// * @deprecated remove this once we have resource upgrade
+// * @param discoveryContext
+// * @param newStyleResourceKey
+// * @param snmpDiscoveries
+// * @return
+// */
+// @Deprecated
+// private String
getLegacyResourceKey(ResourceDiscoveryContext<ApacheServerComponent>
discoveryContext, String newStyleResourceKey, SnmpWwwServiceIndexes snmpDiscoveries) {
+// int snmpWwwServiceIndex =
ApacheVirtualHostServiceComponent.getMatchingWwwServiceIndex(discoveryContext.getParentResourceComponent(),
newStyleResourceKey, snmpDiscoveries.names, snmpDiscoveries.ports);
+//
+// if (snmpWwwServiceIndex < 1) {
+// return null;
+// } else {
+// String host = snmpDiscoveries.names.get(snmpWwwServiceIndex -
1).toString();
+// String fullPort = snmpDiscoveries.ports.get(snmpWwwServiceIndex -
1).toString();
+//
+// // The port value will be in the form "1.3.6.1.2.1.6.XXXXX",
+// // where "1.3.6.1.2.1.6" represents the TCP protocol ID,
+// // and XXXXX is the actual port number
+// String port = fullPort.substring(fullPort.lastIndexOf(".") + 1);
+// return host + ":" + port;
+// }
+// }
public static String createResourceKey(String serverName, List<String> hosts)
{
//BZ 612189 - swap the impls once resource upgrade is in place
diff --git
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/HttpdAddressUtility.java
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/HttpdAddressUtility.java
index 0710178..7c55fb4 100644
---
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/HttpdAddressUtility.java
+++
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/HttpdAddressUtility.java
@@ -41,7 +41,8 @@ import org.rhq.plugins.apache.parser.ApacheDirectiveTree;
public enum HttpdAddressUtility {
APACHE_1_3 {
- public Address getMainServerSampleAddress(ApacheDirectiveTree ag, String
limitToHost, int limitToPort) {
+
+ public List<Address> getAllMainServerAddresses(ApacheDirectiveTree ag,
boolean substituteWildcards) {
try {
List<ApacheDirective> ports = ag.search("/Port");
List<ApacheDirective> bindAddresses =
ag.search("/BindAddress");
@@ -50,7 +51,7 @@ public enum HttpdAddressUtility {
String port = "80"; //this is the default in apache 1.3
String bindAddress = null;
- List<Address> addressesToMatch = new ArrayList<Address>();
+ List<Address> addresses = new ArrayList<Address>();
if (ports.size() > 0) {
List<String>values = ports.get(0).getValues();
@@ -67,28 +68,24 @@ public enum HttpdAddressUtility {
//listen directives take precedence over port/bindaddress combo
if (listens.size() > 0) {
for(ApacheDirective l : listens) {
- addressesToMatch.add(parseListen(l.getValues().get(0)));
+ addresses.add(parseListen(l.getValues().get(0)));
}
} else {
- addressesToMatch.add(new Address(bindAddress,
Integer.parseInt(port)));
+ addresses.add(new Address(bindAddress, Integer.parseInt(port)));
}
- for (Address address : addressesToMatch) {
- if (isAddressConforming(address, limitToHost, limitToPort, false)) {
- if (!address.isPortDefined() || address.isPortWildcard()) {
- address.port = 80;
- }
- if (address.host == null || address.isHostDefault() ||
address.isHostWildcard()) {
- address = getLocalhost(address.port);
- }
-
- updateWithServerName(address, ag);
-
- return address;
+ for (Address address : addresses) {
+
+ if (!address.isPortDefined()) {
+ address.port = 80;
+ }
+
+ if (substituteWildcards) {
+ substituteWildcards(ag, address);
}
}
- return null;
+ return addresses;
} catch (Exception e) {
log.warn("Failed to obtain main server address.", e);
@@ -97,23 +94,22 @@ public enum HttpdAddressUtility {
}
},
APACHE_2_x {
- public Address getMainServerSampleAddress(ApacheDirectiveTree ag, String
limitToHost, int limitToPort) {
+
+ public List<Address> getAllMainServerAddresses(ApacheDirectiveTree ag,
boolean substituteWildcards) {
try {
+ List<Address> ret = new ArrayList<Address>();
+
for(ApacheDirective n : ag.search("/Listen")) {
Address addr = parseListen(n.getValues().get(0));
- if (isAddressConforming(addr, limitToHost, limitToPort, false)) {
- if (addr.host == null || addr.isHostDefault() ||
addr.isHostWildcard()) {
- addr = getLocalhost(addr.port);
- }
-
- updateWithServerName(addr, ag);
-
- return addr;
+
+ if (substituteWildcards) {
+ substituteWildcards(ag, addr);
}
+
+ ret.add(addr);
}
- //there has to be at least one Listen directive
- throw new IllegalStateException("Could find a listen address on port
" + limitToPort);
+ return ret;
} catch (Exception e) {
log.warn("Failed to obtain main server address.", e);
@@ -124,6 +120,9 @@ public enum HttpdAddressUtility {
private static final Log log = LogFactory.getLog(HttpdAddressUtility.class);
+ public static final String BOGUS_HOST_WITHOUT_FORWARD_DNS =
"bogus_host_without_forward_dns";
+ public static final String BOGUS_HOST_WITHOUT_REVERSE_DNS =
"bogus_host_without_reverse_dns";
+
public static HttpdAddressUtility get(String version) {
return version.startsWith("1.") ? APACHE_1_3 : APACHE_2_x;
}
@@ -163,8 +162,8 @@ public enum HttpdAddressUtility {
}
int lastColonIdx = address.lastIndexOf(':');
- if (lastColonIdx == NO_PORT_SPECIFIED_VALUE) {
- return new Address(address, -1);
+ if (lastColonIdx == -1) {
+ return new Address(address, NO_PORT_SPECIFIED_VALUE);
} else {
int lastRightBracketPos = address.lastIndexOf(']');
if (lastColonIdx > lastRightBracketPos) {
@@ -283,6 +282,15 @@ public enum HttpdAddressUtility {
}
/**
+ * This returns all the addresses the server listens on.
+ *
+ * @param ag the tree of the httpd configuration
+ * @param substituteWildcards true if wildcard substitution should be made on host
and port specs
+ * @return the addresses or null on failure
+ */
+ public abstract List<Address> getAllMainServerAddresses(ApacheDirectiveTree ag,
boolean substituteWildcards);
+
+ /**
* This just constructs a first available address under which the server or one of
its virtual hosts can be reached.
*
* @param ag the tree of the httpd configuration
@@ -291,7 +299,22 @@ public enum HttpdAddressUtility {
* @param limitToPort if > 0, the sample address is looked for only for the given
port
* @return the address or null on failure
*/
- public abstract Address getMainServerSampleAddress(ApacheDirectiveTree ag, String
limitToHost, int limitToPort);
+ public Address getMainServerSampleAddress(ApacheDirectiveTree ag, String limitToHost,
int limitToPort) {
+ List<Address> addressesToMatch = getAllMainServerAddresses(ag, false);
+
+ if (addressesToMatch == null) {
+ return null;
+ }
+
+ for (Address address : addressesToMatch) {
+ if (isAddressConforming(address, limitToHost, limitToPort, false)) {
+ substituteWildcards(ag, address);
+ return address;
+ }
+ }
+
+ return null;
+ }
/**
* This constructs an address on which given virtual host can be accessed.
@@ -299,20 +322,14 @@ public enum HttpdAddressUtility {
* @param ag the augeas tree of the httpd configuration
* @param virtualHost the port or address:port of the virtual host
* @param serverName the server name for the namebased virtual hosts (or null if the
virtual host is ip based)
- * @param snmpModuleCompatibleMode if true, generates a sample address in the same
way as snmp module. Namely
- * deals with the host name wildcard the same way as snmp module (i.e. by assuming it
means "localhost", even though it doesn't have to).
* @return the address on which the virtual host can be accessed or null on error
*/
- public Address getVirtualHostSampleAddress(ApacheDirectiveTree ag, String
virtualHost, String serverName, boolean snmpModuleCompatibleMode) {
+ public Address getVirtualHostSampleAddress(ApacheDirectiveTree ag, String
virtualHost, String serverName) {
try {
Address addr = Address.parse(virtualHost);
if (addr.isHostDefault() || addr.isHostWildcard()) {
Address serverAddr = null;
- if (snmpModuleCompatibleMode) {
- serverAddr = getLocalhost(addr.port);
- } else {
- serverAddr = getMainServerSampleAddress(ag, null, addr.port);
- }
+ serverAddr = getMainServerSampleAddress(ag, null, addr.port);
if (serverAddr == null)
return null;
addr.host = serverAddr.host;
@@ -329,6 +346,76 @@ public enum HttpdAddressUtility {
}
}
+ public Address getHttpdInternalMainServerAddressRepresentation(ApacheDirectiveTree
runtimeConfig) {
+ Address ret = null;
+
+ List<ApacheDirective> serverNames =
runtimeConfig.search("/ServerName");
+ if (serverNames.size() == 0) {
+ //no servername directive in the apache config
+ ret = new Address(Address.WILDCARD, Address.NO_PORT_SPECIFIED_VALUE);
+ try {
+ ret.host = InetAddress.getLocalHost().getCanonicalHostName();
+ } catch (UnknownHostException e) {
+ ret.host = "127.0.0.1";
+ }
+
+ ret.port = 0;
+ } else {
+ String serverName = serverNames.get(serverNames.size() -
1).getValuesAsString();
+ ret = HttpdAddressUtility.Address.parse(serverName);
+ if (!ret.isPortDefined()) {
+ ret.port = 0;
+ }
+ }
+
+ return ret;
+ }
+
+ public Address getHttpdInternalVirtualHostAddressRepresentation(ApacheDirectiveTree
runtimeConfig, String virtualHost, String serverName) {
+ Address ret = null;
+
+ if (serverName != null) {
+ ret = Address.parse(serverName);
+ if (!ret.isPortDefined()) {
+ ret.port = 0;
+ }
+
+ //servername is taken literally and no reverse dns lookup is made
+ //if the servername host is an IP address. We're done here...
+ } else {
+ ret = Address.parse(virtualHost);
+ if (!ret.isPortDefined() || ret.isPortWildcard() || ret.isHostDefault() ||
ret.isHostWildcard()) {
+ Address mainAddress =
getHttpdInternalMainServerAddressRepresentation(runtimeConfig);
+
+ if (!ret.isPortDefined() || ret.isPortWildcard()) {
+ ret.port = mainAddress.port;
+ }
+
+ if (ret.isHostDefault() || ret.isHostWildcard()) {
+ ret.host = mainAddress.host;
+ }
+ }
+
+ //if the vhost hostname is an IP address, a reverse dns lookup is attempted
+ //to get the actual hostname.
+ //the BOGUS* constants are what the apache actually uses to identify such
+ //"error" conditions.
+ try {
+ InetAddress iAddr = InetAddress.getByName(ret.host);
+ String reverseLookup = iAddr.getHostName();
+ if (iAddr.getHostAddress().equals(reverseLookup)) {
+ ret.host = BOGUS_HOST_WITHOUT_REVERSE_DNS;
+ } else {
+ ret.host = reverseLookup;
+ }
+ } catch (UnknownHostException e) {
+ ret.host = BOGUS_HOST_WITHOUT_FORWARD_DNS;
+ }
+ }
+
+ return ret;
+ }
+
private static Address parseListen(String listenValue) {
Address ret = Address.parse(listenValue);
if (!ret.isPortDefined()) {
@@ -343,6 +430,20 @@ public enum HttpdAddressUtility {
return ret;
}
+ private static void substituteWildcards(ApacheDirectiveTree ag, Address address) {
+ if (address.isPortWildcard()) {
+ address.port = 80;
+ }
+
+ if (address.host == null || address.isHostDefault() || address.isHostWildcard())
{
+ Address localhost = getLocalhost(address.port);
+ address.host = localhost.host;
+ }
+
+ updateWithServerName(address, ag);
+
+ }
+
/**
* Checks that given address represents a possibly wildcarded limitingHost and
limitingPort values.
*
@@ -354,7 +455,7 @@ public enum HttpdAddressUtility {
* If this flag is set to true, this method takes that into account.
* @return
*/
- public static boolean isAddressConforming(Address listen, String limitingHost, int
limitingPort, boolean snmpModuleCompatibleMode) {
+ private static boolean isAddressConforming(Address listen, String limitingHost, int
limitingPort, boolean snmpModuleCompatibleMode) {
if (Address.DEFAULT_HOST.equals(limitingHost) ||
Address.WILDCARD.equals(limitingHost)) {
limitingHost = null;
}
@@ -398,7 +499,7 @@ public enum HttpdAddressUtility {
}
}
- private static void updateWithServerName(Address address, ApacheDirectiveTree config)
throws UnknownHostException {
+ private static void updateWithServerName(Address address, ApacheDirectiveTree config)
{
//check if there is a ServerName directive
List<ApacheDirective> serverNameNodes =
config.search("/ServerName");
@@ -411,7 +512,7 @@ public enum HttpdAddressUtility {
}
}
- private static void updateWithServerName(Address address, String serverName) throws
UnknownHostException {
+ private static void updateWithServerName(Address address, String serverName) {
//the configuration may be invalid and/or the hostname can be unresolvable.
//we try to match the address with the servername first by IP address
//but if that fails (i.e. the hostname couldn't be resolved to an IP)
commit a48c68385ba2fbd226fa62e52b944c2fbcf43515
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Apr 25 17:02:12 2011 +0200
need to update vhost::getNode() to not use the matching. basically I need
to detect, that I'm dealing with only a simple vhost, not nested inside
any if* and not containing and If* that would contain configurable directives.
If that's the case, fail, otherwise we can proceed with the read/update.
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 ee7520f..c4ceb0b 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
@@ -23,7 +23,9 @@ import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -67,6 +69,7 @@ import org.rhq.core.pluginapi.measurement.MeasurementFacet;
import org.rhq.core.pluginapi.operation.OperationFacet;
import org.rhq.core.pluginapi.operation.OperationResult;
import org.rhq.core.system.OperatingSystemType;
+import org.rhq.core.system.ProcessInfo;
import org.rhq.core.system.SystemInfo;
import org.rhq.plugins.apache.augeas.ApacheAugeasNode;
import org.rhq.plugins.apache.augeas.AugeasConfigurationApache;
@@ -145,6 +148,7 @@ public class ApacheServerComponent implements
AugeasRHQComponent<PlatformCompone
private URL url;
private ApacheBinaryInfo binaryInfo;
private long availPingTime = -1;
+ private Map<String, String> moduleNames;
/**
* Delegate instance for handling all calls to invoke operations on this component.
@@ -211,6 +215,9 @@ public class ApacheServerComponent implements
AugeasRHQComponent<PlatformCompone
this.operationsDelegate = new ApacheServerOperationsDelegate(this,
pluginConfig, this.resourceContext
.getSystemInformation());
+ //init the module names with the defaults
+ moduleNames = new HashMap<String,
String>(ApacheServerDiscoveryComponent.getDefaultModuleNames(binaryInfo.getVersion()));
+
startEventPollers();
} catch (Exception e) {
if (this.snmpClient != null) {
@@ -759,6 +766,18 @@ public class ApacheServerComponent implements
AugeasRHQComponent<PlatformCompone
}
}
+ public Map<String, String> getModuleNames() {
+ return moduleNames;
+ }
+
+ public ProcessInfo getCurrentProcessInfo() {
+ return resourceContext.getNativeProcess();
+ }
+
+ public ApacheBinaryInfo getCurrentBinaryInfo() {
+ return binaryInfo;
+ }
+
// TODO: Move this method to a helper class.
static void addSnmpMetricValueToReport(MeasurementReport report,
MeasurementScheduleRequest schedule,
SNMPValue snmpValue, boolean valueIsTimestamp) throws SNMPException {
@@ -924,4 +943,18 @@ public class ApacheServerComponent implements
AugeasRHQComponent<PlatformCompone
return false;
}
}
+
+ private String getVersion() {
+ String ret = resourceContext.getVersion();
+ if (ret == null) {
+ //strange, but this happens sometimes when
+ //the resource is synced with the server for the first
+ //time after data purge on the agent side
+
+ //let's determine the version from the binary info
+ ret = binaryInfo.getVersion();
+ }
+
+ return ret;
+ }
}
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 6ea64f4..17829eb 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
@@ -24,7 +24,9 @@ import java.net.URI;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
@@ -70,6 +72,151 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
private static final Log log =
LogFactory.getLog(ApacheServerDiscoveryComponent.class);
+ public static final Map<String, String> MODULE_SOURCE_FILE_TO_MODULE_NAME_20;
+ public static final Map<String, String> MODULE_SOURCE_FILE_TO_MODULE_NAME_13;
+
+ static {
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20 = new LinkedHashMap<String,
String>();
+
+ //these are extracted from
http://httpd.apache.org/docs/current/mod/
+ //and linked pages
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("beos.c",
"mpm_beos_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("event.c",
"mpm_event_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mpm_netware.c",
"mpm_netware_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mpmt_os2.c",
"mpm_mpmt_os2_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("prefork.c",
"mpm_prefork_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mpm_winnt.c",
"mpm_winnt_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("worker.c",
"mpm_worker_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_actions.c",
"actions_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_alias.c",
"alias_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_asis.c",
"asis_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_auth_basic.c",
"auth_basic_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_auth_digest.c",
"auth_digest_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_authn_alias.c",
"authn_alias_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_authn_anon.c",
"authn_anon_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_authn_dbd.c",
"authn_dbd_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_authn_dbm.c",
"authn_dbm_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_authn_default.c",
"authn_default_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_authn_file.c",
"authn_file_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_authnz_ldap.c",
"authnz_ldap_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_authz_dbm.c",
"authz_dbm_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_authz_default.c",
"authz_default_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_authz_groupfile.c",
"authz_groupfile_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_authz_host.c",
"authz_host_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_authz_owner.c",
"authz_owner_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_authz_user.c",
"authz_user_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_autoindex.c",
"autoindex_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_cache.c",
"cache_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_cern_meta.c",
"cern_meta_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_cgi.c",
"cgi_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_cgid.c",
"cgid_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_charset_lite.c",
"charset_lite_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_dav.c",
"dav_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_dav_fs.c",
"dav_fs_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_dav_lock.c",
"dav_lock_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_dbd.c",
"dbd_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_deflate.c",
"deflate_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_dir.c",
"dir_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_disk_cache.c",
"disk_cache_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_dumpio.c",
"dumpio_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_echo.c",
"echo_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_env.c",
"env_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_example.c",
"example_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_expires.c",
"expires_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_ext_filter.c",
"ext_filter_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_file_cache.c",
"file_cache_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_filter.c",
"filter_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_headers.c",
"headers_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_ident.c",
"ident_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_imagemap.c",
"imagemap_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_include.c",
"include_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_info.c",
"info_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_isapi.c",
"isapi_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("util_ldap.c",
"ldap_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_log_config.c",
"log_config_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_log_forensic.c",
"log_forensic_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_logio.c",
"logio_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_mem_cache.c",
"mem_cache_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_mime.c",
"mime_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_mime_magic.c",
"mime_magic_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_negotiation.c",
"negotiation_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_nw_ssl.c",
"nwssl_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_proxy.c",
"proxy_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_proxy_ajp.c",
"proxy_ajp_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_proxy_balancer.c",
"proxy_balancer_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_proxy_connect.c",
"proxy_connect_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_proxy_ftp.c",
"proxy_ftp_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_proxy_http.c",
"proxy_http_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_proxy_scgi.c",
"proxy_scgi_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_reqtimeout.c",
"reqtimeout_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_rewrite.c",
"rewrite_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_setenvif.c",
"setenvif_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_so.c",
"so_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_speling.c",
"speling_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_ssl.c",
"ssl_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_status.c",
"status_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_substitute.c",
"substitute_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_suexec.c",
"suexec_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_unique_id.c",
"unique_id_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_userdir.c",
"userdir_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_usertrack.c",
"usertrack_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_version.c",
"version_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_vhost_alias.c",
"vhost_alias_module");
+
+ //some hand picked modules
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod_jk.c",
"jk_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod-snmpcommon.c",
"snmpcommon_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("mod-snmpagt.c",
"snmpagt_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_20.put("covalent-snmp-v20.c",
"snmp_agt_module");
+
+ //this list is for apache 1.3
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13 = new LinkedHashMap<String,
String>();
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_access.c",
"access_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_actions.c",
"action_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_alias.c",
"alias_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_asis.c",
"asis_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_auth.c",
"auth_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_auth_anon.c",
"anon_auth_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_auth_db.c",
"db_auth_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_auth_dbm.c",
"dbm_auth_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_auth_digest.c",
"digest_auth_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_autoindex.c",
"autoindex_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_cern_meta.c",
"cern_meta_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_cgi.c",
"cgi_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_digest.c",
"digest_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_dir.c",
"dir_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_env.c",
"env_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_example.c",
"example_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_expires.c",
"expires_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_headers.c",
"headers_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_imap.c",
"imap_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_include.c",
"includes_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_info.c",
"info_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_isapi.c",
"isapi_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_log_agent.c",
"agent_log_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_log_config.c",
"config_log_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_log_forensic.c",
"log_forensic_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_log_referer.c",
"referer_log_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_mime.c",
"mime_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_mime_magic.c",
"mime_magic_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_mmap_static.c",
"mmap_static_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_negotiation.c",
"negotiation_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_proxy.c",
"proxy_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_rewrite.c",
"rewrite_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_setenvif.c",
"setenvif_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_so.c",
"so_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_speling.c",
"speling_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_status.c",
"status_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_unique_id.c",
"unique_id_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_userdir.c",
"userdir_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_usertrack.c",
"usertrack_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_vhost_alias.c",
"vhost_alias_module");
+
+ //and some hand-picks
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("mod_jk.c",
"jk_module");
+ MODULE_SOURCE_FILE_TO_MODULE_NAME_13.put("covalent-snmp-v13.c",
"snmp_agt_module");
+ }
+
private static class DiscoveryFailureException extends Exception {
private static final long serialVersionUID = 1L;
@@ -454,4 +601,14 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
}
return null;
}
+
+ public static Map<String, String> getDefaultModuleNames(String version) {
+ switch (HttpdAddressUtility.get(version)) {
+ case APACHE_1_3 :
+ return MODULE_SOURCE_FILE_TO_MODULE_NAME_13;
+ case APACHE_2_x:
+ return MODULE_SOURCE_FILE_TO_MODULE_NAME_20;
+ default: throw new IllegalStateException("Unknown HttpdAddressUtility
instance.");
+ }
+ }
}
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 c894fa9..b37361c 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
@@ -85,6 +85,8 @@ public class ApacheVirtualHostServiceComponent implements
ResourceComponent<Apac
public static final String SERVER_NAME_CONFIG_PROP = "ServerName";
+ public static final String SNMP_WWW_SERVICE_INDEX_CONFIG_PROP =
"snmpWwwServiceIndex";
+
private static final String RESPONSE_TIME_METRIC = "ResponseTime";
/** Multiply by 1/1000 to convert logged response times, which are in microseconds,
to milliseconds. */
private static final double RESPONSE_TIME_LOG_TIME_MULTIPLIER = 0.001;
@@ -94,7 +96,6 @@ public class ApacheVirtualHostServiceComponent implements
ResourceComponent<Apac
private ResponseTimeLogParser logParser;
private ConfigurationTimestamp lastConfigurationTimeStamp = new
ConfigurationTimestamp();
- private int snmpWwwServiceIndex = -1;
public static final String RESOURCE_TYPE_NAME = "Apache Virtual Host";
@@ -423,8 +424,8 @@ public class ApacheVirtualHostServiceComponent implements
ResourceComponent<Apac
log.warn("Failed to parse the server URL when trying to match the vhost
with the main server.", e);
}
- throw new IllegalStateException("Could not find virtual host configuration
in augeas for virtual host: "
- + resourceKey);
+ throw new IllegalStateException("Could not find virtual host configuration
for virtual host resource : "
+ + resourceKey + ". Reading and updating configuration of virtual hosts
nested inside If* directives is not supported by this plugin.");
}
/**
@@ -508,174 +509,14 @@ public class ApacheVirtualHostServiceComponent implements
ResourceComponent<Apac
return oid;
}
- public static int getMatchingWwwServiceIndex(ApacheServerComponent parent, String
resourceKey, List<SNMPValue> names, List<SNMPValue> ports) {
- int ret = -1;
- Iterator<SNMPValue> namesIterator = names.iterator();
- Iterator<SNMPValue> portsIterator = ports.iterator();
-
- //figure out the servername and addresses of this virtual host
- //from the resource key.
- String vhostServerName = null;
- String[] vhostAddressStrings = null;
- int pipeIdx = resourceKey.indexOf('|');
- if (pipeIdx >= 0) {
- vhostServerName = resourceKey.substring(0, pipeIdx);
- }
- vhostAddressStrings = resourceKey.substring(pipeIdx + 1).split(" ");
-
- ApacheDirectiveTree tree = parent.loadParser();
-
- //convert the vhost addresses into fully qualified ip/port addresses
- List<HttpdAddressUtility.Address> vhostAddresses = new
ArrayList<HttpdAddressUtility.Address>(
- vhostAddressStrings.length);
-
- if (vhostAddressStrings.length == 1 &&
MAIN_SERVER_RESOURCE_KEY.equals(vhostAddressStrings[0])) {
- HttpdAddressUtility.Address serverAddr =
parent.getAddressUtility().getMainServerSampleAddress(tree, null, 0);
- if (serverAddr != null) {
- vhostAddresses.add(serverAddr);
- }
- } else {
- for (int i = 0; i < vhostAddressStrings.length; ++i) {
- HttpdAddressUtility.Address vhostAddr =
parent.getAddressUtility().getVirtualHostSampleAddress(tree, vhostAddressStrings[i],
- vhostServerName, true);
- if (vhostAddr != null) {
- vhostAddresses.add(vhostAddr);
- } else {
- //this is not to choke on the old style resource keys for the main
server. without this, we'd never be able
- //to match the main server with its snmp index below.
- HttpdAddressUtility.Address addr =
HttpdAddressUtility.Address.parse(vhostAddressStrings[i]);
- vhostAddr =
parent.getAddressUtility().getMainServerSampleAddress(tree, addr.host, addr.port);
- if (vhostAddr != null) {
- vhostAddresses.add(vhostAddr);
- }
- }
- }
- }
-
- //finding the snmp index that corresponds to the address(es) of the vhost
isn't that simple
- //because the snmp module in apache always resolves the IPs to hostnames.
- //on the other hand, the resource key tries to be more accurate about what a
- //vhost can actually be represented as. A vhost is represented by at most 1
hostname (i.e. ServerName)
- //and possibly multiple IP addresses.
- SNMPValue bestMatch = null;
- int bestMatchRate = 0;
-
- while (namesIterator.hasNext()) {
- SNMPValue nameValue = namesIterator.next();
- SNMPValue portValue = portsIterator.next();
-
- String snmpHost = nameValue.toString();
- String fullPort = portValue.toString();
-
- int snmpPort =
Integer.parseInt(fullPort.substring(fullPort.lastIndexOf(".") + 1));
-
- HttpdAddressUtility.Address snmpAddress = new
HttpdAddressUtility.Address(snmpHost, snmpPort);
-
- int matchRate = matchRate(vhostAddresses, snmpAddress);
- if (matchRate > bestMatchRate) {
- bestMatch = nameValue;
- bestMatchRate = matchRate;
- }
- }
-
- if (bestMatch != null) {
- String nameOID = bestMatch.getOID();
- ret = Integer.parseInt(nameOID.substring(nameOID.lastIndexOf(".") +
1));
- } else {
- log.warn("Unable to match the Virtual Host [" + resourceKey +
"] with any of the SNMP advertised vhosts: " + names + ". It won't be
possible to monitor the Virtual Host.");
- }
- return ret;
- }
-
/**
* @return the index of the virtual host that identifies it in SNMP
* @throws Exception on SNMP error
*/
private int getWwwServiceIndex() throws Exception {
- ConfigurationTimestamp currentTimestamp =
resourceContext.getParentResourceComponent().getConfigurationTimestamp();
- if (!lastConfigurationTimeStamp.equals(currentTimestamp)) {
- snmpWwwServiceIndex = -1;
- //don't go through this configuration again even if we fail further
below.. we'd fail again.
- lastConfigurationTimeStamp = currentTimestamp;
-
- //configuration has changed. re-read the service index of this virtual host
-
- //we have to scan the SNMP to find the entry corresponding to this vhost.
- SNMPSession snmpSession =
resourceContext.getParentResourceComponent().getSNMPSession();
-
- List<SNMPValue> names;
- List<SNMPValue> ports;
-
- names = snmpSession.getColumn(SNMPConstants.COLUMN_VHOST_NAME);
- ports = snmpSession.getColumn(SNMPConstants.COLUMN_VHOST_PORT);
-
- snmpWwwServiceIndex =
getMatchingWwwServiceIndex(resourceContext.getParentResourceComponent(),
resourceContext.getResourceKey(), names, ports);
- }
- return snmpWwwServiceIndex;
+ return
Integer.parseInt(resourceContext.getPluginConfiguration().getSimpleValue(SNMP_WWW_SERVICE_INDEX_CONFIG_PROP,
"-1"));
}
- private static int matchRate(List<HttpdAddressUtility.Address> addresses,
HttpdAddressUtility.Address addressToCheck) {
- for(HttpdAddressUtility.Address a : addresses) {
- if (HttpdAddressUtility.isAddressConforming(addressToCheck, a.host, a.port,
true)) {
- return 3;
- }
- }
-
- //try to get the IP of the address to check
- InetAddress[] ipAddresses;
- try {
- ipAddresses = InetAddress.getAllByName(addressToCheck.host);
- for(InetAddress ip : ipAddresses) {
- HttpdAddressUtility.Address newCheck = new
HttpdAddressUtility.Address(ip.getHostAddress(), addressToCheck.port);
-
- for(HttpdAddressUtility.Address a : addresses) {
- if (HttpdAddressUtility.isAddressConforming(newCheck, a.host, a.port,
true)) {
- return 2;
- }
- }
- }
- } catch (UnknownHostException e) {
- log.debug("Unknown host encountered in the httpd configuration: " +
addressToCheck.host);
- return 0;
- }
-
- //this stupid 80 = 0 rule is to conform with snmp module
- //the problem is that snmp module represents both 80 and * port defs as 0,
- //so whatever we do, we might mismatch the vhost. But there's no working
around that
- //but to modify the snmp module itself.
-
- int addressPort = addressToCheck.port;
- if (addressPort == 80) {
- addressPort = 0;
- }
-
- //ok, try the hardest...
- for(HttpdAddressUtility.Address listAddress: addresses) {
- int listPort = listAddress.port;
- if (listPort == 80) {
- listPort = 0;
- }
-
- InetAddress[] listAddresses;
- try {
- listAddresses = InetAddress.getAllByName(listAddress.host);
- } catch (UnknownHostException e) {
- log.debug("Unknown host encountered in the httpd configuration:
" + listAddress.host);
- return 0;
- }
-
- for (InetAddress listInetAddr : listAddresses) {
- for (InetAddress ip : ipAddresses) {
- if (ip.equals(listInetAddr) && addressPort == listPort) {
- return 1;
- }
- }
- }
- }
-
- return 0;
- }
-
private ResourceType getDirectoryResourceType() {
return
resourceContext.getResourceType().getChildResourceTypes().iterator().next();
}
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 95edbcf..fc61097 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
@@ -42,6 +42,7 @@ import org.rhq.plugins.apache.parser.ApacheDirective;
import org.rhq.plugins.apache.parser.ApacheDirectiveTree;
import org.rhq.plugins.apache.util.HttpdAddressUtility;
import org.rhq.plugins.apache.util.HttpdAddressUtility.Address;
+import org.rhq.plugins.apache.util.RuntimeApacheConfiguration;
import org.rhq.plugins.www.snmp.SNMPException;
import org.rhq.plugins.www.snmp.SNMPSession;
import org.rhq.plugins.www.snmp.SNMPValue;
@@ -75,6 +76,7 @@ public class ApacheVirtualHostServiceDiscoveryComponent implements
ResourceDisco
ApacheServerComponent serverComponent = context.getParentResourceComponent();
ApacheDirectiveTree tree = serverComponent.loadParser();
+
//first define the root server as one virtual host
discoverMainServer(context, discoveredResources, snmpDiscoveries);
@@ -193,7 +195,11 @@ public class ApacheVirtualHostServiceDiscoveryComponent implements
ResourceDisco
//BZ 612189 - remove this once we have resource upgrade
key = host + ":" + port;
}
-
+
+ //the SNMP WWW service index of the main server is always 1
+ mainServerPluginConfig.put(new PropertySimple(
+ ApacheVirtualHostServiceComponent.SNMP_WWW_SERVICE_INDEX_CONFIG_PROP, 1));
+
//BZ 612189 - this can simply the MAIN_SERVER_RESOURCE_KEY only once we have
resource upgrade
if (key == null) {
key = ApacheVirtualHostServiceComponent.MAIN_SERVER_RESOURCE_KEY;
diff --git
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/parser/ApacheDirective.java
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/parser/ApacheDirective.java
index 53cee70..ae8e23e 100644
---
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/parser/ApacheDirective.java
+++
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/parser/ApacheDirective.java
@@ -5,7 +5,7 @@ import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-public class ApacheDirective {
+public class ApacheDirective implements Cloneable {
private String name;
private List<String> values;
@@ -195,4 +195,23 @@ public class ApacheDirective {
public void addValue(String val){
values.add(val);
}
+
+ @Override
+ public ApacheDirective clone() {
+ try {
+ ApacheDirective copy = (ApacheDirective) super.clone();
+
+ List<ApacheDirective> newChildNodes = new
ArrayList<ApacheDirective>(childNodes.size());
+ for(ApacheDirective child : childNodes) {
+ ApacheDirective childCopy = child.clone();
+ childCopy.parentNode = copy;
+ newChildNodes.add(childCopy);
+ }
+ copy.childNodes = newChildNodes;
+
+ return copy;
+ } catch (CloneNotSupportedException e) {
+ throw new IllegalStateException("ApacheDirective not cloneable even
though it is declared as such.", e);
+ }
+ }
}
diff --git
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/parser/ApacheDirectiveTree.java
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/parser/ApacheDirectiveTree.java
index 4822732..9e0ad8b 100644
---
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/parser/ApacheDirectiveTree.java
+++
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/parser/ApacheDirectiveTree.java
@@ -3,7 +3,7 @@ package org.rhq.plugins.apache.parser;
import java.util.ArrayList;
import java.util.List;
-public class ApacheDirectiveTree {
+public class ApacheDirectiveTree implements Cloneable {
private ApacheDirective rootNode;
@@ -61,4 +61,12 @@ public class ApacheDirectiveTree {
parentNode.addChildDirective(dir);
return dir;
}
+
+ @Override
+ public ApacheDirectiveTree clone() {
+ ApacheDirectiveTree copy = new ApacheDirectiveTree();
+ copy.rootNode = rootNode.clone();
+
+ return copy;
+ }
}
diff --git
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/ApacheBinaryInfo.java
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/ApacheBinaryInfo.java
index 0c41d5c..aedb144 100644
---
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/ApacheBinaryInfo.java
+++
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/ApacheBinaryInfo.java
@@ -23,8 +23,10 @@ import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
+import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -60,7 +62,9 @@ public class ApacheBinaryInfo {
private String built;
private String mpm;
private long lastModified = 0;
-
+ private Set<String> compiledInModules = new HashSet<String>();
+ private Set<String> compiledInDefines = new HashSet<String>();
+
private ApacheBinaryInfo(@NotNull
String binaryPath) {
this.binaryPath = binaryPath;
@@ -133,6 +137,8 @@ public class ApacheBinaryInfo {
BufferedReader is = null;
try {
+ compiledInDefines.clear();
+
ProcessExecution processExecution = new ProcessExecution(binaryPath);
processExecution.setArguments(new String[] { "-V" });
processExecution.setWaitForCompletion(10000L);
@@ -164,7 +170,56 @@ public class ApacheBinaryInfo {
}
this.mpm = line;
+ } else if (line.startsWith("-D")) {
+ String define = line.substring(3);
+ int equalsIdx = define.indexOf('=');
+ if (equalsIdx >= 0) {
+ define = define.substring(0, equalsIdx);
+ }
+
+ compiledInDefines.add(define);
+ }
+ }
+ } catch (Throwable t) {
+ String msg = "Error running binary '" + binaryPath +
"': " + t.getMessage();
+ LOG.error(msg, t);
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+ }
+
+ private void getCompiledInModules(String binaryPath, SystemInfo systemInfo) {
+ BufferedReader is = null;
+
+ try {
+
+ compiledInModules.clear();
+
+ ProcessExecution processExecution = new ProcessExecution(binaryPath);
+ processExecution.setArguments(new String[] { "-l" });
+ processExecution.setWaitForCompletion(10000L);
+ processExecution.setCaptureOutput(true);
+ ProcessExecutionResults results =
systemInfo.executeProcess(processExecution);
+
+ if (results.getError() != null) {
+ throw results.getError();
+ }
+
+ String line;
+ is = new BufferedReader(new StringReader(results.getCapturedOutput()));
+ boolean firstLine = true;
+ while ((line = is.readLine()) != null) {
+ if (firstLine) {
+ firstLine = false;
+ continue;
}
+
+ compiledInModules.add(line.trim());
}
} catch (Throwable t) {
String msg = "Error running binary '" + binaryPath +
"': " + t.getMessage();
@@ -192,7 +247,8 @@ public class ApacheBinaryInfo {
this.lastModified = binaryFile.lastModified();
getVersionCommandInfo(binaryPath, systemInfo);
-
+ getCompiledInModules(binaryPath, systemInfo);
+
File libHttpd = getHttpdSharedLibrary(binaryFile);
this.version = findVersion((libHttpd != null) ? libHttpd.getPath() :
this.binaryPath);
@@ -317,4 +373,12 @@ public class ApacheBinaryInfo {
private static boolean isUnix() {
return File.separatorChar == '/';
}
+
+ public Set<String> getCompiledInModules() {
+ return compiledInModules;
+ }
+
+ public Set<String> getCompiledInDefines() {
+ return compiledInDefines;
+ }
}
\ No newline at end of file
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
new file mode 100644
index 0000000..25f5ad9
--- /dev/null
+++
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/util/RuntimeApacheConfiguration.java
@@ -0,0 +1,304 @@
+/*
+ * 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.util;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.system.ProcessInfo;
+import org.rhq.core.util.OSGiVersionComparator;
+import org.rhq.plugins.apache.parser.ApacheDirective;
+import org.rhq.plugins.apache.parser.ApacheDirectiveTree;
+
+/**
+ * @author Lukas Krejci
+ */
+public class RuntimeApacheConfiguration {
+
+ private static final Log LOG = LogFactory.getLog(RuntimeApacheConfiguration.class);
+
+ private enum ModuleLoadedState {
+ LOADED, NOT_LOADED, UNKNOWN
+ }
+
+ private RuntimeApacheConfiguration() {
+
+ }
+
+ /**
+ * Given the apache configuration and information about the parameters httpd was
executed
+ * with this method provides the directive tree that corresponds to the actual
+ * runtime configuration as used by httpd.
+ * <p>
+ * This enables us to see which directives are actually in effect as opposed to just
+ * declared.
+ *
+ * @param tree
+ * @param httpdProcessInfo
+ * @param httpdBinaryInfo
+ * @param moduleNames the mapping from the module filename to the module name
+ * (i.e. mapping from the name used in IfModule to the name used in LoadModule)
+ * @return a new directive tree that represents the runtime configuration
+ */
+ public static ApacheDirectiveTree extract(ApacheDirectiveTree tree, ProcessInfo
httpdProcessInfo, ApacheBinaryInfo httpdBinaryInfo, Map<String, String> moduleNames)
{
+ ApacheDirectiveTree ret = tree.clone();
+
+ List<String> defines = new
ArrayList<String>(httpdBinaryInfo.getCompiledInDefines());
+
+ if (httpdProcessInfo != null) {
+ String[] args = httpdProcessInfo.getCommandLine();
+ for(int i = 1; i < args.length; ++i) {
+ String define = null;
+ if (args[i] != null && args[i].startsWith("-D")) {
+ define = args[i].substring(2).trim();
+ }
+
+ if (define != null && define.isEmpty()) {
+ //this means we saw an empty -D arg. This can happen if there is a
space between -D and the value.
+ //That is legal though, so we have to accomodate for that.
+ if (i < args.length - 1) {
+ define = args[i + 1].trim();
+ if (define.startsWith("-")) {
+ //this would be another option
+ define = null;
+ } else {
+ ++i; //we can skip the next arg
+ }
+ } else {
+ define = null; //well -D is the last argument
+ }
+ }
+
+ if (define != null) {
+ defines.add(define);
+ }
+ }
+ }
+
+ HashSet<String> loadedModules = new HashSet<String>();
+ loadedModules.addAll(httpdBinaryInfo.getCompiledInModules());
+
+ //build a map for reverse lookup we might need in the transform method
+ HashMap<String, String> moduleFiles = new HashMap<String,
String>(moduleNames.size());
+ for(Map.Entry<String, String> e : moduleNames.entrySet()) {
+ moduleFiles.put(e.getValue(), e.getKey());
+ }
+
+ transform(ret.getRootNode(), loadedModules, defines, moduleNames, moduleFiles,
httpdBinaryInfo.getVersion());
+
+ return ret;
+ }
+
+ private static void transform(ApacheDirective parentNode, Set<String>
currentlyLoadedModules, List<String> defines, Map<String, String> moduleNames,
Map<String, String> moduleFiles, String httpdVersion) {
+ if (parentNode.getChildDirectives().isEmpty()) {
+ return;
+ }
+
+ ArrayList<ApacheDirective> nodesToRemove = new
ArrayList<ApacheDirective>();
+ ArrayList<ApacheDirective> nodesToPromote = new
ArrayList<ApacheDirective>();
+
+ for (ApacheDirective node : parentNode.getChildDirectives()) {
+ if (node.getName().equalsIgnoreCase("LoadModule")) {
+ currentlyLoadedModules.add(node.getValues().get(0));
+ } else if (node.getName().equalsIgnoreCase("<IfModule")) {
+ String moduleFile = node.getValuesAsString();
+ boolean negate = false;
+ if (moduleFile.startsWith("!")) {
+ negate = true;
+ moduleFile = moduleFile.substring(1);
+ }
+
+ boolean result = false;
+
+ switch(isModuleLoaded(moduleFile, currentlyLoadedModules, moduleNames,
moduleFiles)) {
+ case LOADED : result = true; break;
+ case NOT_LOADED : result = false; break;
+ case UNKNOWN :
+ LOG.warn("Encountered unknown module name in an IfModule
directive: " + moduleFile);
+ continue;
+ }
+
+ if (result != negate) {
+ nodesToPromote.add(node);
+ } else {
+ nodesToRemove.add(node);
+ }
+ } else if (node.getName().equalsIgnoreCase("<IfDefine")) {
+ String define = node.getValuesAsString();
+ boolean negate = false;
+ if (define.startsWith("!")) {
+ negate = true;
+ define = define.substring(1);
+ }
+
+ boolean result = defines.contains(define);
+
+ if (negate != result) {
+ nodesToPromote.add(node);
+ } else {
+ nodesToRemove.add(node);
+ }
+ } else if (node.getName().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", currentlyLoadedModules,
moduleNames, moduleFiles) != ModuleLoadedState.LOADED) {
+ LOG.debug("mod_version not loaded and IfVersion directive
encountered. Skipping it.");
+ continue;
+ }
+
+ List<String> values = node.getValues();
+ 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, httpdVersion);
+ } else {
+ result = comp.compare(version, httpdVersion) == 0;
+ }
+ } else if ("~".equals(operator)) {
+ result = Pattern.matches(version, httpdVersion);
+ } else if (">".equals(operator)) {
+ result = comp.compare(httpdVersion, version) > 0;
+ } else if (">=".equals(operator)) {
+ result = comp.compare(httpdVersion, version) >= 0;
+ } else if ("<".equals(operator)) {
+ result = comp.compare(httpdVersion, version) < 0;
+ } else if ("<=".equals(operator)) {
+ result = comp.compare(httpdVersion, version) <= 0;
+ } else {
+ LOG.warn("Unknown operator " + operator + " in an
IfVersion directive.");
+ continue;
+ }
+
+ if (negate != result) {
+ nodesToPromote.add(node);
+ } else {
+ nodesToRemove.add(node);
+ }
+ }
+
+ transform(node, currentlyLoadedModules, defines, moduleNames, moduleFiles,
httpdVersion);
+ }
+
+ for(ApacheDirective node : nodesToRemove) {
+ parentNode.getChildDirectives().remove(node);
+ }
+
+ //add the children of node as children of parent node at the place node
+ //was declared and remove node ... i.e. make it so as if the child nodes
+ //of node were directly in the parentNode in the place of node
+ for(ApacheDirective node : nodesToPromote) {
+ int nodeIdx = parentNode.getChildDirectives().indexOf(node);
+
+ List<ApacheDirective> childNodes = node.getChildDirectives();
+ for(int i = childNodes.size() - 1; i >= 0; --i) {
+ ApacheDirective childNode = childNodes.get(i);
+ parentNode.getChildDirectives().add(nodeIdx, childNode);
+ childNode.setParentNode(parentNode);
+ }
+
+ parentNode.getChildDirectives().remove(nodeIdx + childNodes.size());
+ }
+ }
+
+ private static ModuleLoadedState isModuleLoaded(String moduleIdentifier,
Set<String> currentlyLoadedModules, Map<String, String> moduleNames,
Map<String, String> moduleFiles) {
+ String moduleName = moduleNames.get(moduleIdentifier);
+ if (moduleName == null) {
+ //as of apache 2.1 module files and module names can both be used in
IfModule
+ moduleName = moduleIdentifier;
+ moduleIdentifier = moduleFiles.get(moduleName);
+
+ if (moduleIdentifier == null) {
+ //reverse lookup failed - there is no such module in the mappings
+ //the last attempt is to see if the modulename wasn't used one of the
previous
+ //load module directives
+ if (!currentlyLoadedModules.contains(moduleName)) {
+ return ModuleLoadedState.UNKNOWN;
+ }
+ }
+ }
+
+ //the compiled in modules are being reported by apache using their source file
+ //and the on-demand loaded modules are identified by their
+ //module name - consistent, huh?
+ boolean result = currentlyLoadedModules.contains(moduleIdentifier)
+ || currentlyLoadedModules.contains(moduleName);
+
+ return result ? ModuleLoadedState.LOADED : ModuleLoadedState.NOT_LOADED;
+ }
+}
diff --git a/modules/plugins/apache/src/main/resources/META-INF/rhq-plugin.xml
b/modules/plugins/apache/src/main/resources/META-INF/rhq-plugin.xml
index dc5bb67..870eaff 100644
--- a/modules/plugins/apache/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/apache/src/main/resources/META-INF/rhq-plugin.xml
@@ -497,6 +497,19 @@
description="The http or https URL that will be used
to check availability for this
virtual host. Note that SSL certificate validation is
disabled during availability
checks if this is an HTTPS URL."/>
+ <c:simple-property name="snmpWwwServiceIndex"
displayName="SNMP WWW Service Index" type="integer"
readOnly="false">
+ <c:description>
+ The row index for this virtual host in the MIB table of WWW services
(i.e. virtual hosts).
+ This value can either be read out of the SNMP (using utilities like
snmpwalk) or can be determined
+ by examining the order of the virtual host directives in the Apache
configuration files.
+ The main server always has index 1.
+ If you join all the apache configuration files (i.e. replace all the
Include directives with the contents
+ of the files being included (files determined by a glob pattern in
alphabetical order)), the SNMP WWW Service
+ Index is the reverse order of the corresponding VirtualHost directive
in such joined configuration. I.e.
+ the last virtual host directive has index 2, the second last has 3,
etc.
+ </c:description>
+ <c:constraint><c:integer-constraint minimum="1"
/></c:constraint>
+ </c:simple-property>
<c:group name="ResponseTime">
<c:simple-property name="responseTimeLogFile"
required="false"
description="the full path to the log file
containing response-time stats for this virtual host"/>