[rhq] Branch 'jkremser/separateFromParent' - modules/enterprise
by Jiri Kremser
modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
New commits:
commit 2d498467817aacc76560c7dcbdec5571601ab778
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Thu Feb 21 17:36:02 2013 +0100
making m_agentHomeDirectory field non-static again
diff --git a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
index c48f102..6c01d67 100644
--- a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
+++ b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
@@ -200,7 +200,7 @@ public class AgentMain {
/**
* The directory where this agent is installed.
*/
- private static String m_agentHomeDirectory;
+ private String m_agentHomeDirectory;
/**
* The command line arguments specified by the user.
@@ -526,7 +526,7 @@ public class AgentMain {
*
* @return agent home directory, or empty string if it cannot be determined
*/
- public static String getAgentHomeDirectory() {
+ public String getAgentHomeDirectory() {
if (m_agentHomeDirectory != null) {
return m_agentHomeDirectory;
}
11 years, 3 months
[rhq] modules/core modules/enterprise
by Jay Shaughnessy
modules/core/domain/pom.xml | 26 ++++++++++
modules/core/domain/src/test/resources/arquillian.xml | 4 +
modules/enterprise/server/itests-2/pom.xml | 18 ++++++
modules/enterprise/server/itests-2/src/test/resources/arquillian.xml | 4 +
4 files changed, 52 insertions(+)
New commits:
commit b4522507d1a18a20cabff9cd2097c730c5d5f42e
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Thu Feb 21 11:21:27 2013 -0500
This should allow us to run Arquillian's spawned AS7 instances (for
domain and server jar itests) on non-default ports. This can be helpful
in environments where you want to run multiple AS7 instances at the same
time.
Arquillian will now inspect, through the AS7 management port (assumed to be on
the local machine for now), to find out what ports it needs to deal with.
diff --git a/modules/core/domain/pom.xml b/modules/core/domain/pom.xml
index 3eec8ad..21af6e4 100644
--- a/modules/core/domain/pom.xml
+++ b/modules/core/domain/pom.xml
@@ -235,6 +235,16 @@
<echo>Will now add test configuration to JBossAS config file: ${jboss.conf}</echo>
<replace file="${jboss.conf}">
<replacefilter>
+ <replacetoken></extensions></replacetoken>
+ <replacevalue><![CDATA[
+ </extensions>
+
+ <!-- FOR RHQ TESTING -->
+ <system-properties>
+ <property name="jboss.socket.binding.port-offset" value="${jboss.socket.binding.port-offset}" />
+ </system-properties>]]></replacevalue>
+ </replacefilter>
+ <replacefilter>
<replacetoken></drivers></replacetoken>
<replacevalue><![CDATA[
<!-- FOR RHQ TESTING -->
@@ -681,6 +691,22 @@
<jboss.vm.args.debug>-Xrunjdwp:transport=dt_socket,address=8798,server=y,suspend=y</jboss.vm.args.debug>
</properties>
</profile>
+
+ <!-- These two properties allow Arquillian to inspect AS7 through the mgmt port, to determine the ports it needs to interact
+ with when spawning the AS7 instance. This allows the AS7 to run on non-default ports. If these properties are not set (for
+ example, in settings.xml) then we must set the defaults here. The offset is then provided via the standalone.xml properties -->
+ <profile>
+ <id>arquillian-ports</id>
+ <activation>
+ <property>
+ <name>!jboss.socket.binding.port-offset</name>
+ </property>
+ </activation>
+ <properties>
+ <jboss.socket.binding.port-offset>0</jboss.socket.binding.port-offset>
+ <jboss.management.native.port>9999</jboss.management.native.port>
+ </properties>
+ </profile>
</profiles>
diff --git a/modules/core/domain/src/test/resources/arquillian.xml b/modules/core/domain/src/test/resources/arquillian.xml
index 368ce23..d0744f3 100644
--- a/modules/core/domain/src/test/resources/arquillian.xml
+++ b/modules/core/domain/src/test/resources/arquillian.xml
@@ -21,6 +21,10 @@
<configuration>
<property name="jbossHome">${jboss.unzip.location}</property>
+ <!-- These two properties allow Arquillian to inspect AS7 through the mgmt port, to determine the ports it needs
+ to interact with when spawning the AS7 instance. This allows the AS7 to run on non-default ports. -->
+ <property name="managementAddress">127.0.0.1</property>
+ <property name="managementPort">${jboss.management.native.port}</property>
</configuration>
</container>
diff --git a/modules/enterprise/server/itests-2/pom.xml b/modules/enterprise/server/itests-2/pom.xml
index 5961627..49d79f5 100644
--- a/modules/enterprise/server/itests-2/pom.xml
+++ b/modules/enterprise/server/itests-2/pom.xml
@@ -91,6 +91,7 @@
<system-properties>
<property name="project.version" value="${project.version}"/>
<property name="rhq.server.content.filesystem" value="${jboss.unzip.location}/standalone/data/packagebits" />
+ <property name="jboss.socket.binding.port-offset" value="${jboss.socket.binding.port-offset}" />
</system-properties>]]></replacevalue>
</replacefilter>
@@ -741,5 +742,22 @@
<jboss.vm.args.debug>-Xrunjdwp:transport=dt_socket,address=8798,server=y,suspend=y</jboss.vm.args.debug>
</properties>
</profile>
+
+ <!-- These two properties allow Arquillian to inspect AS7 through the mgmt port, to determine the ports it needs to interact
+ with when spawning the AS7 instance. This allows the AS7 to run on non-default ports. If these properties are not set (for
+ example, in settings.xml) then we must set the defaults here. The offset is then provided via the standalone.xml properties -->
+ <profile>
+ <id>arquillian-ports</id>
+ <activation>
+ <property>
+ <name>!jboss.socket.binding.port-offset</name>
+ </property>
+ </activation>
+ <properties>
+ <jboss.socket.binding.port-offset>0</jboss.socket.binding.port-offset>
+ <jboss.management.native.port>9999</jboss.management.native.port>
+ </properties>
+ </profile>
+
</profiles>
</project>
diff --git a/modules/enterprise/server/itests-2/src/test/resources/arquillian.xml b/modules/enterprise/server/itests-2/src/test/resources/arquillian.xml
index 72f8bdc..ffaa79e 100644
--- a/modules/enterprise/server/itests-2/src/test/resources/arquillian.xml
+++ b/modules/enterprise/server/itests-2/src/test/resources/arquillian.xml
@@ -33,6 +33,10 @@
<configuration>
<property name="jbossHome">${jboss.unzip.location}</property>
<property name="javaVmArguments">${jboss.vm.args} ${jboss.vm.args.debug}</property>
+ <!-- These two properties allow Arquillian to inspect AS7 through the mgmt port, to determine the ports it needs
+ to interact with when spawning the AS7 instance. This allows the AS7 to run on non-default ports. -->
+ <property name="managementAddress">127.0.0.1</property>
+ <property name="managementPort">${jboss.management.native.port}</property>
</configuration>
</container>
</arquillian>
11 years, 3 months
[rhq] modules/enterprise
by mazz
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/AgentManagerLocal.java | 14 ++++++----
1 file changed, 9 insertions(+), 5 deletions(-)
New commits:
commit 93fb46966bfce20ec918191ec78408d20ce6b010
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Thu Feb 21 10:35:59 2013 -0500
don't deprecate these methods - criteria is nice, but these specific methods are very efficient and can be used when we need to eek out as much performance as possible. no need to go through the criteria API just to get a single agent using very targeted WHERE conditions.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/AgentManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/AgentManagerLocal.java
index 842d5d8..7e2c3b9 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/AgentManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/AgentManagerLocal.java
@@ -134,47 +134,51 @@ public interface AgentManagerLocal {
/**
* Given an agent name, this will look up and return the {@link Agent} with that name. If no agent with the given
* name exists, <code>null</code> is returned.
- *
+ * This method is very efficient if you want to find a single agent by its name.
+ * If you need to get more than one agent, you could use <code>findAgentsByCriteria</code>.
+ *
* @param agentName
*
* @return the agent whose name matches the given name; <code>null</code> if there is no agent with the given name
- * @deprecated Use <code>findAgentsByCriteria()</code> instead
*/
Agent getAgentByName(String agentName);
/**
* Given an agent id, this will look up and return the {@link Agent} with that id. If no agent with the given
* name exists, <code>null</code> is returned.
+ * This method is very efficient if you want to find a single agent by its ID.
+ * If you need to get more than one agent, you could use <code>findAgentsByCriteria</code>.
*
* @param agentId
*
* @return the agent whose id matches the given id; <code>null</code> if there is no agent with the given id
- * @deprecated Use <code>findAgentsByCriteria()</code> instead
*/
Agent getAgentByID(int agentId);
/**
* Given an agent token string, this will look up and return the {@link Agent} associated with that token. If the
* given token is invalid, <code>null</code> is returned.
+ * This method is very efficient if you want to find a single agent by its token.
+ * If you need to get more than one agent, you could use <code>findAgentsByCriteria</code>.
*
* @param token the agent token
*
* @return the agent whose agent token matches the given token; <code>null</code> if there is no agent with the
* given token
- * @deprecated Use <code>findAgentsByCriteria()</code> instead
*/
Agent getAgentByAgentToken(String token);
/**
* Given an agent's address and port, this will look up and return the {@link Agent} associated with that address
* and port. If no agent is found, <code>null</code> is returned.
+ * This method is very efficient if you want to find a single agent by its endpoint.
+ * If you need to get more than one agent, you could use <code>findAgentsByCriteria</code>.
*
* @param address the address that the agent is bound to
* @param port the port at the given address that the agent is listening on
*
* @return the agent to be known at the given address and port; <code>null</code> if there is no agent with the
* given token
- * @deprecated Use <code>findAgentsByCriteria()</code> instead
*/
Agent getAgentByAddressAndPort(String address, int port);
11 years, 3 months
[rhq] Branch 'jkremser/separateFromParent' - modules/core modules/enterprise
by Jiri Kremser
modules/core/util/src/main/java/org/rhq/core/util/exec/ProcessExecutor.java | 15 +++++++---
modules/core/util/src/main/java/org/rhq/core/util/exec/ProcessToStart.java | 7 ++++
modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java | 4 +-
3 files changed, 19 insertions(+), 7 deletions(-)
New commits:
commit 1f1b77f0c84681ea4d590b627dad7c6be0e6ca23
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Thu Feb 21 16:32:40 2013 +0100
schell script for running processes in background
Conflicts:
modules/core/util/src/main/java/org/rhq/core/util/exec/ProcessExecutor.java
modules/core/util/src/main/java/org/rhq/core/util/exec/ProcessToStart.java
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java
diff --git a/modules/core/util/src/main/java/org/rhq/core/util/exec/ProcessExecutor.java b/modules/core/util/src/main/java/org/rhq/core/util/exec/ProcessExecutor.java
index 35612a8..6b5f16c 100644
--- a/modules/core/util/src/main/java/org/rhq/core/util/exec/ProcessExecutor.java
+++ b/modules/core/util/src/main/java/org/rhq/core/util/exec/ProcessExecutor.java
@@ -53,7 +53,9 @@ import org.rhq.core.util.UtilI18NResourceKeys;
public class ProcessExecutor {
private static ExecutorService threadPool = Executors.newCachedThreadPool();
- private static String RUN_IN_BACKGROUND_SUFFIX = " & wait $!";
+
+ // HC
+ private static String RUN_IN_BACKGROUND_PREFIX = " /home/jkremser/background.sh";
/**
* This executes any operating system process as described in the given start command. When this method returns, it
@@ -477,10 +479,15 @@ public class ProcessExecutor {
// +1 for the program executable path and possibly +1 for the RUN_IN_BACKGROUND_SUFFIX
String[] retCmdline = new String[numArgs + 1 + (process.isSeparatedFromParent() ? 1 : 0)];
- retCmdline[0] = fullProgramPath;
-
if (numArgs > 0) {
- System.arraycopy(args, 0, retCmdline, 1, numArgs);
+ System.arraycopy(args, 0, retCmdline, (process.isSeparatedFromParent() ? 2 : 1), numArgs);
+ }
+
+ if (process.isSeparatedFromParent()) {
+ retCmdline[0] = RUN_IN_BACKGROUND_PREFIX;
+ retCmdline[1] = fullProgramPath;
+ } else {
+ retCmdline[0] = fullProgramPath;
}
if (process.isSeparatedFromParent()) {
diff --git a/modules/core/util/src/main/java/org/rhq/core/util/exec/ProcessToStart.java b/modules/core/util/src/main/java/org/rhq/core/util/exec/ProcessToStart.java
index af8ca1c..c1ed236 100644
--- a/modules/core/util/src/main/java/org/rhq/core/util/exec/ProcessToStart.java
+++ b/modules/core/util/src/main/java/org/rhq/core/util/exec/ProcessToStart.java
@@ -636,8 +636,13 @@ public class ProcessToStart {
// flag is optional, but non-nullable; remove it if null is passed in
if (value != null) {
map.put(PARAM_SEPARATED_FROM_PARENT, value);
+ String[] envProps = getEnvironment();
+ String[] newEnvProps = new String[envProps.length + 1];
+ System.arraycopy(envProps, 0, newEnvProps, 0, envProps.length);
+ newEnvProps[envProps.length] = "RHQ_CONTROL_WAIT=true";
+ setEnvironment(newEnvProps);
} else {
map.remove(PARAM_SEPARATED_FROM_PARENT);
}
}
-}
\ No newline at end of file
+}
diff --git a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
index 6c01d67..c48f102 100644
--- a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
+++ b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
@@ -200,7 +200,7 @@ public class AgentMain {
/**
* The directory where this agent is installed.
*/
- private String m_agentHomeDirectory;
+ private static String m_agentHomeDirectory;
/**
* The command line arguments specified by the user.
@@ -526,7 +526,7 @@ public class AgentMain {
*
* @return agent home directory, or empty string if it cannot be determined
*/
- public String getAgentHomeDirectory() {
+ public static String getAgentHomeDirectory() {
if (m_agentHomeDirectory != null) {
return m_agentHomeDirectory;
}
11 years, 3 months
[rhq] .classpath modules/core modules/plugins
by Thomas Segismont
.classpath | 36
modules/core/util/src/main/java/org/rhq/core/util/StringUtil.java | 20
modules/plugins/netservices/pom.xml | 468 ++++------
modules/plugins/netservices/src/main/java/org/rhq/plugins/netservices/HTTPNetServiceComponent.java | 214 +++-
modules/plugins/netservices/src/main/java/org/rhq/plugins/netservices/HTTPNetServiceComponentConfiguration.java | 57 +
modules/plugins/netservices/src/main/java/org/rhq/plugins/netservices/HTTPNetServiceDiscoveryComponent.java | 51 -
modules/plugins/netservices/src/main/java/org/rhq/plugins/netservices/PingNetServiceComponent.java | 77 -
modules/plugins/netservices/src/main/java/org/rhq/plugins/netservices/PingNetServiceDiscoveryComponent.java | 41
modules/plugins/netservices/src/main/resources/META-INF/rhq-plugin.xml | 37
modules/plugins/netservices/src/test/java/org/rhq/plugins/netservices/HTTPNetServiceDiscoveryComponentTest.java | 178 +++
modules/plugins/netservices/src/test/java/org/rhq/plugins/netservices/PingNetServiceDiscoveryComponentTest.java | 105 ++
modules/plugins/netservices/src/test/java/org/rhq/plugins/netservices/itest/HTTPNetServiceComponentTest.java | 162 +++
modules/plugins/netservices/src/test/java/org/rhq/plugins/netservices/itest/NetServiceComponentTest.java | 154 +++
modules/plugins/netservices/src/test/java/org/rhq/plugins/netservices/itest/PingNetServiceComponentTest.java | 98 ++
modules/plugins/netservices/src/test/resources/log4j.xml | 32
15 files changed, 1295 insertions(+), 435 deletions(-)
New commits:
commit e0ea2fd840197301df934d34088b419e97279d83
Author: Thomas Segismont <tsegismo(a)redhat.com>
Date: Tue Feb 12 10:23:51 2013 +0100
netservices plugin strengthening
Added Unit tests for HTTPNetServiceDiscoveryComponent
Added HTTPNetServiceComponent itest and verified code coverage
Added Unit tests for PingNetServiceDiscoveryComponent
Added PingNetServiceComponent itest and verified code coverage
Implemented missing parts and cleaned up code
diff --git a/.classpath b/.classpath
index 9af3a50..dd5d354 100644
--- a/.classpath
+++ b/.classpath
@@ -24,9 +24,9 @@
<classpathentry kind="src" path="modules/core/util/src/test/java"/>
<classpathentry kind="src" path="modules/core/dbutils/src/main/java"/>
<classpathentry kind="src" path="modules/core/dbutils/src/test/java"/>
- <classpathentry kind="src" path="modules/core/native-system/src/main/java"/>
- <classpathentry kind="src" path="modules/core/native-system/src/test/java"/>
- <classpathentry kind="src" path="modules/core/native-system/src/test/resources"/>
+ <classpathentry kind="src" path="modules/core/native-system/src/main/java"/>
+ <classpathentry kind="src" path="modules/core/native-system/src/test/java"/>
+ <classpathentry kind="src" path="modules/core/native-system/src/test/resources"/>
<classpathentry kind="src" path="modules/core/domain/src/main/java"/>
<classpathentry kind="src" path="modules/core/domain/src/test/java"/>
<classpathentry kind="src" path="modules/core/plugin-api/src/main/java"/>
@@ -124,6 +124,9 @@
<classpathentry kind="src" path="modules/plugins/apache/src/test/resources"/>
<classpathentry kind="src" path="modules/plugins/script/src/main/java"/>
<classpathentry kind="src" path="modules/plugins/netservices/src/main/java"/>
+ <classpathentry kind="src" path="modules/plugins/netservices/src/main/resources"/>
+ <classpathentry kind="src" path="modules/plugins/netservices/src/test/java"/>
+ <classpathentry kind="src" path="modules/plugins/netservices/src/test/resources"/>
<classpathentry kind="src" path="modules/plugins/ant-bundle/src/main/java"/>
<classpathentry kind="src" path="modules/plugins/ant-bundle/src/test/java"/>
<classpathentry kind="src" path="modules/plugins/ant-bundle/src/test/resources"/>
@@ -178,11 +181,11 @@
<classpathentry kind="src" path="modules/core/arquillian-integration/container/src/test/java"/>
<classpathentry kind="src" path="modules/core/arquillian-integration/container/src/test/resources"/>
<classpathentry kind="src" path="modules/test-utils/src/main/java"/>
- <classpathentry kind="src" path="modules/integration-tests/apache-plugin-test/src/test/java"/>
- <classpathentry kind="src" path="modules/integration-tests/apache-plugin-test/src/test/resources"/>
- <classpathentry kind="src" path="modules/integration-tests/jndi-access/jndi-access-test/src/test/java"/>
- <classpathentry kind="src" path="modules/integration-tests/jndi-access/jndi-access-test/src/test/resources"/>
- <classpathentry kind="src" path="modules/integration-tests/mod_cluster-plugin-test/src/test/java"/>
+ <classpathentry kind="src" path="modules/integration-tests/apache-plugin-test/src/test/java"/>
+ <classpathentry kind="src" path="modules/integration-tests/apache-plugin-test/src/test/resources"/>
+ <classpathentry kind="src" path="modules/integration-tests/jndi-access/jndi-access-test/src/test/java"/>
+ <classpathentry kind="src" path="modules/integration-tests/jndi-access/jndi-access-test/src/test/resources"/>
+ <classpathentry kind="src" path="modules/integration-tests/mod_cluster-plugin-test/src/test/java"/>
<classpathentry kind="src" path="etc/samples/skeleton-plugin/src/main/java"/>
<classpathentry kind="src" path="etc/samples/custom-serverplugin/src/main/java"/>
<classpathentry kind="src" path="etc/samples/simplereport-serverplugin/src/main/java"/>
@@ -336,9 +339,9 @@
<classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/spec/javax/jms/jboss-jms-api_1.1_spec/1.0.0.Final/jboss-jms-api_1.1_spec-1.0.0.Final.jar"/>
<classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/spec/javax/interceptor/jboss-interceptors-api_1.1_spec/1.0.0.Final/jboss-interceptors-api_1.1_spec-1.0.0.Final.jar"/>
<classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/spec/javax/transaction/jboss-transaction-api_1.1_spec/1.0.0.Final/jboss-transaction-api_1.1_spec-1.0.0.Final.jar"/>
- <classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/remotingjmx/remoting-jmx/1.0.2.Final/remoting-jmx-1.0.2.Final.jar"/>
- <classpathentry exported="true" kind="var" path="M2_REPO/javax/enterprise/cdi-api/1.0-SP4/cdi-api-1.0-SP4.jar" sourcepath="M2_REPO/javax/enterprise/cdi-api/1.0-SP4/cdi-api-1.0-SP4-sources.jar"/>
- <classpathentry exported="true" kind="var" path="M2_REPO/javax/inject/javax.inject/1/javax.inject-1.jar" sourcepath="M2_REPO/javax/inject/javax.inject/1/javax.inject-1-sources.jar"/>
+ <classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/remotingjmx/remoting-jmx/1.0.2.Final/remoting-jmx-1.0.2.Final.jar"/>
+ <classpathentry exported="true" kind="var" path="M2_REPO/javax/enterprise/cdi-api/1.0-SP4/cdi-api-1.0-SP4.jar" sourcepath="M2_REPO/javax/enterprise/cdi-api/1.0-SP4/cdi-api-1.0-SP4-sources.jar"/>
+ <classpathentry exported="true" kind="var" path="M2_REPO/javax/inject/javax.inject/1/javax.inject-1.jar" sourcepath="M2_REPO/javax/inject/javax.inject/1/javax.inject-1-sources.jar"/>
<classpathentry exported="true" kind="var" path="M2_REPO/org/mozilla/rhino/1.7R4/rhino-1.7R4.jar"/>
<classpathentry exported="true" kind="var" path="M2_REPO/org/picketbox/picketbox/4.0.7.Final/picketbox-4.0.7.Final.jar"/>
<classpathentry exported="true" kind="var" path="M2_REPO/org/python/jython-standalone/2.5.2/jython-standalone-2.5.2.jar"/>
@@ -346,9 +349,10 @@
<classpathentry exported="true" kind="var" path="M2_REPO/joda-time/joda-time/2.1/joda-time-2.1.jar"/>
<classpathentry exported="true" kind="var" path="M2_REPO/org/apache/cassandra/cassandra-thrift/1.1.5/cassandra-thrift-1.1.5.jar"/>
<classpathentry exported="true" kind="var" path="M2_REPO/org/hectorclient/hector-core/1.1-1/hector-core-1.1-1.jar"/>
- <classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/byteman/byteman-install/1.5.2/byteman-install-1.5.2.jar" sourcepath="M2_REPO/org/jboss/byteman/byteman-install/1.5.2/byteman-install-1.5.2-sources.jar"/>
- <classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/byteman/byteman-submit/1.5.2/byteman-submit-1.5.2.jar" sourcepath="M2_REPO/org/jboss/byteman/byteman-submit/1.5.2/byteman-submit-1.5.2-sources.jar"/>
- <classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/byteman/byteman-bmunit/1.5.2/byteman-bmunit-1.5.2.jar" sourcepath="M2_REPO/org/jboss/byteman/byteman-bmunit/1.5.2/byteman-bmunit-1.5.2-sources.jar"/>
- <classpathentry exported="true" kind="var" path="JDK_HOME/lib/tools.jar"/>
- <classpathentry kind="output" path="eclipse-classes"/>
+ <classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/byteman/byteman-install/1.5.2/byteman-install-1.5.2.jar" sourcepath="M2_REPO/org/jboss/byteman/byteman-install/1.5.2/byteman-install-1.5.2-sources.jar"/>
+ <classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/byteman/byteman-submit/1.5.2/byteman-submit-1.5.2.jar" sourcepath="M2_REPO/org/jboss/byteman/byteman-submit/1.5.2/byteman-submit-1.5.2-sources.jar"/>
+ <classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/byteman/byteman-bmunit/1.5.2/byteman-bmunit-1.5.2.jar" sourcepath="M2_REPO/org/jboss/byteman/byteman-bmunit/1.5.2/byteman-bmunit-1.5.2-sources.jar"/>
+ <classpathentry exported="true" kind="var" path="M2_REPO/org/eclipse/jetty/aggregate/jetty-all/8.1.8.v20121106/jetty-all-8.1.8.v20121106.jar" sourcepath="M2_REPO/org/eclipse/jetty/aggregate/jetty-all/8.1.8.v20121106/jetty-all-8.1.8.v20121106-sources.jar"/>
+ <classpathentry exported="true" kind="var" path="JDK_HOME/lib/tools.jar"/>
+ <classpathentry kind="output" path="eclipse-classes"/>
</classpath>
diff --git a/modules/core/util/src/main/java/org/rhq/core/util/StringUtil.java b/modules/core/util/src/main/java/org/rhq/core/util/StringUtil.java
index 59a09f2..21e81c4 100644
--- a/modules/core/util/src/main/java/org/rhq/core/util/StringUtil.java
+++ b/modules/core/util/src/main/java/org/rhq/core/util/StringUtil.java
@@ -39,6 +39,8 @@ public class StringUtil {
private static final Log log = LogFactory.getLog(StringUtil.class);
+ public static final String EMPTY_STRING = "";
+
/**
* @param source The source string to perform replacements on.
* @param find The substring to find in source.
@@ -119,7 +121,7 @@ public class StringUtil {
*
* @return The Iterator's elements in a user-friendly string format.
*/
- public static String iteratorToString(Iterator i, String delim) {
+ public static String iteratorToString(Iterator<?> i, String delim) {
return iteratorToString(i, delim, "");
}
@@ -132,7 +134,7 @@ public class StringUtil {
*
* @return The Iterator's elements in a user-friendly string format.
*/
- public static String iteratorToString(Iterator i, String delim, String quoteChar) {
+ public static String iteratorToString(Iterator<?> i, String delim, String quoteChar) {
Object elt = null;
StringBuilder rstr = new StringBuilder();
String s;
@@ -166,21 +168,21 @@ public class StringUtil {
*
* @return The List in a user-friendly string format.
*/
- public static String listToString(List list, String delim) {
+ public static String listToString(List<?> list, String delim) {
if (list == null) {
return "NULL";
}
- Iterator i = list.iterator();
+ Iterator<?> i = list.iterator();
return iteratorToString(i, delim, null);
}
- public static String collectionToString(Collection collection, String delim) {
+ public static String collectionToString(Collection<?> collection, String delim) {
if (collection == null) {
return "NULL";
}
- Iterator i = collection.iterator();
+ Iterator<?> i = collection.iterator();
return iteratorToString(i, delim, null);
}
@@ -191,11 +193,11 @@ public class StringUtil {
*
* @return The List in a user-friendly string format.
*/
- public static String listToString(List list) {
+ public static String listToString(List<?> list) {
return listToString(list, ",");
}
- public static String collectionToString(Collection collection) {
+ public static String collectionToString(Collection<?> collection) {
return collectionToString(collection, ",");
}
@@ -278,7 +280,7 @@ public class StringUtil {
*
* @return A string with objects in the list seperated by delim
*/
- public static String implode(List objs, String delim) {
+ public static String implode(List<?> objs, String delim) {
StringBuilder buf = new StringBuilder();
int size = objs.size();
diff --git a/modules/plugins/netservices/pom.xml b/modules/plugins/netservices/pom.xml
index 7805daa..4afa8a5 100644
--- a/modules/plugins/netservices/pom.xml
+++ b/modules/plugins/netservices/pom.xml
@@ -1,240 +1,236 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-plugins-parent</artifactId>
- <version>4.6.0-SNAPSHOT</version>
- </parent>
-
- <groupId>org.rhq</groupId>
- <artifactId>rhq-netservices-plugin</artifactId>
- <packaging>jar</packaging>
-
- <name>RHQ Network Services Plugin</name>
- <description>
- A plugin for monitoring network services.
- </description>
-
- <dependencies>
-
- <dependency>
- <groupId>commons-httpclient</groupId>
- <artifactId>commons-httpclient</artifactId>
- <version>${commons-httpclient.version}</version>
- </dependency>
- <dependency>
- <groupId>commons-codec</groupId>
- <artifactId>commons-codec</artifactId>
- <version>${commons-codec.version}</version>
- </dependency>
-
- </dependencies>
-
- <build>
-
- <plugins>
-
- <plugin>
- <artifactId>maven-dependency-plugin</artifactId>
- <executions>
- <execution>
- <id>copy-dependency-jars</id>
- <phase>process-resources</phase>
- <goals>
- <goal>copy</goal>
- </goals>
- <configuration>
- <artifactItems>
- <artifactItem>
- <groupId>commons-httpclient</groupId>
- <artifactId>commons-httpclient</artifactId>
- <version>${commons-httpclient.version}</version>
- </artifactItem>
- <artifactItem>
- <groupId>commons-codec</groupId>
- <artifactId>commons-codec</artifactId>
- <version>1.2</version>
- </artifactItem>
- </artifactItems>
- <outputDirectory>${project.build.outputDirectory}/lib</outputDirectory>
- </configuration>
- </execution>
- </executions>
- </plugin>
-
- </plugins>
-
- </build>
-
-
- <profiles>
- <profile>
- <id>integration-tests</id>
- <activation>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-plugins-parent</artifactId>
+ <version>4.6.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-netservices-plugin</artifactId>
+ <packaging>jar</packaging>
+
+ <name>RHQ Network Services Plugin</name>
+ <description>A plugin for monitoring network services.</description>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>commons-httpclient</groupId>
+ <artifactId>commons-httpclient</artifactId>
+ <version>${commons-httpclient.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ <version>${commons-codec.version}</version>
+ </dependency>
+
+ <!-- Test dependencies -->
+
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <version>1.9.5</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.jetty.aggregate</groupId>
+ <artifactId>jetty-all</artifactId>
+ <version>8.1.8.v20121106</version>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <exclude>org/rhq/plugins/netservices/itest/**</exclude>
+ </excludes>
+ <properties>
<property>
- <name>maven.test.skip</name>
- <value>!true</value>
+ <name>listener</name>
+ <value>org.rhq.test.testng.StdoutReporter</value>
</property>
- </activation>
-
- <build>
- <plugins>
-
- <!-- Integration testing voodoo to load and test this plugin with its plugin dependencies -->
- <plugin>
- <artifactId>maven-antrun-plugin</artifactId>
- <executions>
- <execution>
- <phase>pre-integration-test</phase>
- <configuration>
- <target>
- <echo>Setting up plugin dependencies for ${project.artifactId}-${project.version}.jar...</echo>
- <property name="settings.localRepository" location="${user.home}/.m2/repository" />
- <mkdir dir="target/itest" />
- <mkdir dir="target/itest/plugins" />
- <mkdir dir="target/itest/lib" />
- <copy toDir="target/itest/plugins" flatten="true">
- <fileset dir="${project.build.directory}">
- <include name="${project.artifactId}-${project.version}.jar" />
- </fileset>
- </copy>
- <unzip dest="target/itest/lib">
- <fileset dir="${settings.localRepository}/org/hyperic/sigar-dist/${sigar.version}" includes="*.zip" />
- <patternset>
- <include name="**/lib/sigar.jar" />
- <include name="**/lib/bcel*.jar" />
- <include name="**/lib/*.so" />
- <include name="**/lib/*.sl" />
- <include name="**/lib/*.dll" />
- <include name="**/lib/*.dylib" />
- </patternset>
- </unzip>
- <move todir="target/itest/lib" flatten="true">
- <fileset dir="target/itest/lib">
- <include name="**/lib/*" />
- </fileset>
- </move>
- <delete dir="target/itest/lib/hyperic-sigar-${sigar.version}" />
- </target>
- </configuration>
- <goals>
- <goal>run</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
-
- <plugin>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <skip>true</skip>
- </configuration>
- <executions>
- <execution>
- <id>surefire-it</id>
- <phase>integration-test</phase>
- <goals>
- <goal>test</goal>
- </goals>
- <configuration>
- <skip>${maven.test.skip}</skip>
- <excludedGroups>${rhq.testng.excludedGroups}</excludedGroups>
- <useSystemClassLoader>false</useSystemClassLoader>
- <argLine>${jacoco.integration-test.args} -Dorg.hyperic.sigar.path=${basedir}/target/itest/lib</argLine>
- <!--<argLine>${jacoco.integration-test.args} -Dorg.hyperic.sigar.path=${basedir}/target/itest/lib -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y</argLine>-->
- <systemProperties>
- <property>
- <name>project.artifactId</name>
- <value>${project.artifactId}</value>
- </property>
- <property>
- <name>project.version</name>
- <value>${project.version}</value>
- </property>
- </systemProperties>
- </configuration>
- </execution>
- </executions>
- </plugin>
-
- </plugins>
- </build>
- </profile>
-
- <profile>
- <id>dev</id>
-
- <properties>
- <rhq.rootDir>../../..</rhq.rootDir>
- <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir>
- <rhq.deploymentDir>${rhq.containerDir}/${rhq.agentPluginDir}</rhq.deploymentDir>
- </properties>
-
- <build>
- <plugins>
-
- <plugin>
- <artifactId>maven-antrun-plugin</artifactId>
- <executions>
-
- <execution>
- <id>deploy</id>
- <phase>compile</phase>
- <configuration>
- <target>
- <mkdir dir="${rhq.deploymentDir}" />
- <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
- <echo>*** Updating ${deployment.file}...</echo>
- <jar destfile="${deployment.file}" basedir="${project.build.outputDirectory}" />
- </target>
- </configuration>
- <goals>
- <goal>run</goal>
- </goals>
- </execution>
-
- <execution>
- <id>deploy-jar-meta-inf</id>
- <phase>package</phase>
- <configuration>
- <target>
- <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
- <echo>*** Updating META-INF dir in ${deployment.file}...</echo>
- <unjar src="${project.build.directory}/${project.build.finalName}.jar" dest="${project.build.outputDirectory}">
- <patternset><include name="META-INF/**" /></patternset>
- </unjar>
- <jar destfile="${deployment.file}" manifest="${project.build.outputDirectory}/META-INF/MANIFEST.MF" update="true">
- </jar>
- </target>
- </configuration>
- <goals>
- <goal>run</goal>
- </goals>
- </execution>
-
- <execution>
- <id>undeploy</id>
- <phase>clean</phase>
- <configuration>
- <target>
- <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
- <echo>*** Deleting ${deployment.file}...</echo>
- <delete file="${deployment.file}" />
- </target>
- </configuration>
- <goals>
- <goal>run</goal>
- </goals>
- </execution>
-
- </executions>
- </plugin>
-
- </plugins>
- </build>
- </profile>
- </profiles>
+ </properties>
+ <useSystemClassLoader>false</useSystemClassLoader>
+ <argLine>${jacoco.unit-test.args}</argLine>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>pre-integration-test</phase>
+ <configuration>
+ <target>
+ <echo>Setting up itest plugin container...</echo>
+ <property name="settings.localRepository" location="${user.home}/.m2/repository" />
+ <mkdir dir="target/itest/plugins" />
+ <copy toDir="target/itest/plugins" flatten="true" verbose="true">
+ <fileset dir="${settings.localRepository}/">
+ <include name="org/rhq/rhq-platform-plugin/${project.version}/rhq-platform-plugin-${project.version}.jar" />
+ </fileset>
+ <fileset dir="${project.build.directory}">
+ <include name="${project.artifactId}-${project.version}.jar" />
+ </fileset>
+ </copy>
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <configuration>
+ <skipTests>false</skipTests>
+ <skipITs>false</skipITs>
+ <includes>
+ <!-- only include integration tests; normal unit tests are handled above by surefire plugin -->
+ <include>org/rhq/plugins/netservices/itest/**/*Test.java</include>
+ </includes>
+ <properties>
+ <property>
+ <name>listener</name>
+ <value>org.rhq.test.testng.StdoutReporter</value>
+ </property>
+ </properties>
+ <useSystemClassLoader>false</useSystemClassLoader>
+ <argLine>${jacoco.integration-test.args}</argLine>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>integration-test</goal>
+ <goal>verify</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy-dependency-jars</id>
+ <phase>process-resources</phase>
+ <goals>
+ <goal>copy</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>commons-httpclient</groupId>
+ <artifactId>commons-httpclient</artifactId>
+ <version>${commons-httpclient.version}</version>
+ </artifactItem>
+ <artifactItem>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ <version>1.2</version>
+ </artifactItem>
+ </artifactItems>
+ <outputDirectory>${project.build.outputDirectory}/lib</outputDirectory>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ </plugins>
+ </build>
+
+ <profiles>
+
+ <profile>
+
+ <id>dev</id>
+
+ <properties>
+ <rhq.rootDir>../../..</rhq.rootDir>
+ <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir>
+ <rhq.deploymentDir>${rhq.containerDir}/${rhq.agentPluginDir}</rhq.deploymentDir>
+ </properties>
+
+ <build>
+ <plugins>
+
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+
+ <execution>
+ <id>deploy</id>
+ <phase>compile</phase>
+ <configuration>
+ <target>
+ <mkdir dir="${rhq.deploymentDir}" />
+ <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
+ <echo>*** Updating ${deployment.file}...</echo>
+ <jar destfile="${deployment.file}" basedir="${project.build.outputDirectory}" />
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ <execution>
+ <id>deploy-jar-meta-inf</id>
+ <phase>package</phase>
+ <configuration>
+ <target>
+ <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
+ <echo>*** Updating META-INF dir in ${deployment.file}...</echo>
+ <unjar src="${project.build.directory}/${project.build.finalName}.jar" dest="${project.build.outputDirectory}">
+ <patternset>
+ <include name="META-INF/**" />
+ </patternset>
+ </unjar>
+ <jar destfile="${deployment.file}" manifest="${project.build.outputDirectory}/META-INF/MANIFEST.MF"
+ update="true">
+ </jar>
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ <execution>
+ <id>undeploy</id>
+ <phase>clean</phase>
+ <configuration>
+ <target>
+ <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
+ <echo>*** Deleting ${deployment.file}...</echo>
+ <delete file="${deployment.file}" />
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ </executions>
+ </plugin>
+
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
</project>
diff --git a/modules/plugins/netservices/src/main/java/org/rhq/plugins/netservices/HTTPNetServiceComponent.java b/modules/plugins/netservices/src/main/java/org/rhq/plugins/netservices/HTTPNetServiceComponent.java
index 54d9256..42cbcee 100644
--- a/modules/plugins/netservices/src/main/java/org/rhq/plugins/netservices/HTTPNetServiceComponent.java
+++ b/modules/plugins/netservices/src/main/java/org/rhq/plugins/netservices/HTTPNetServiceComponent.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2008 Red Hat, Inc.
+ * Copyright (C) 2005-2013 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -19,14 +19,22 @@
package org.rhq.plugins.netservices;
-import java.text.SimpleDateFormat;
+import java.net.MalformedURLException;
+import java.net.URL;
import java.util.Date;
-import java.util.Locale;
import java.util.Set;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpMethodBase;
+import org.apache.commons.httpclient.SimpleHttpConnectionManager;
+import org.apache.commons.httpclient.UsernamePasswordCredentials;
+import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.HeadMethod;
+import org.apache.commons.httpclient.util.DateUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -39,43 +47,114 @@ import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
import org.rhq.core.pluginapi.inventory.ResourceComponent;
import org.rhq.core.pluginapi.inventory.ResourceContext;
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.util.StringUtil;
/**
* Monitoring of HTTP Servers
*
* @author Greg Hinkle
*/
-public class HTTPNetServiceComponent implements ResourceComponent, MeasurementFacet, OperationFacet {
- private final Log log = LogFactory.getLog(this.getClass());
+public class HTTPNetServiceComponent implements ResourceComponent, MeasurementFacet {
- public static final String CONFIG_URL = "url";
- public static final String CONFIG_USER = "user";
- public static final String CONFIG_PASSWORD = "password";
- public static final String CONFIG_REALM = "realm";
+ public static final class ConfigKeys {
- // One of { none, SSL, TLS }
- public static final String CONFIG_SSL_PROTOCOL = "sslProtocol";
+ private ConfigKeys() {
+ // Defensive
+ }
+
+ public static final String URL = "url";
+ public static final String USER = "user";
+ public static final String PASSWORD = "password";
+ public static final String REALM = "realm";
+ public static final String METHOD = "method";
+ public static final String FOLOW_REDIRECTS = "followRedirects";
+ public static final String VALIDATE_RESPONSE_CODE = "validateResponseCode";
+ public static final String VALIDATE_RESPONSE_PATTERN = "validateResponsePattern";
- // One of { HEAD, GET }
- public static final String CONFIG_METHOD = "method";
- public static final String CONFIG_FOLOW_REDIRECTS = "followRedirects";
- public static final String CONFIG_RESPONSE_PATTERN = "responsePattern";
+ }
+
+ public static enum HttpMethod {
+ GET, HEAD
+ }
+
+ private static final Log LOG = LogFactory.getLog(HTTPNetServiceComponent.class);
private ResourceContext resourceContext;
+ private Configuration pluginConfig;
+
+ private HTTPNetServiceComponentConfiguration componentConfig;
+
+ @Override
public void start(ResourceContext resourceContext) throws InvalidPluginConfigurationException, Exception {
this.resourceContext = resourceContext;
- String url = resourceContext.getPluginConfiguration().getSimple(CONFIG_URL).getStringValue();
- if (!url.startsWith("http:") && !url.startsWith("https")) {
- throw new InvalidPluginConfigurationException("Url not valid. Must start with 'http:' or 'https:'");
+ pluginConfig = resourceContext.getPluginConfiguration();
+ componentConfig = createComponentConfiguration(pluginConfig);
+ }
+
+ /**
+ * Create a foram {@link HTTPNetServiceComponentConfiguration} instance with the supplied {@link Configuration}.
+ * May throw {@link InvalidPluginConfigurationException} if:
+ * <ul>
+ * <li>Url is empty, invalid, or pointing an non http/https resource</li>
+ * <li>Http method is not HEAD or GET</li>
+ * <li>If both content validation and HEAD method are configured</li>
+ * <li>If the content validation pattern is invalid</li>
+ * <ul>
+ *
+ * @param pluginConfig
+ * @return
+ * @throws InvalidPluginConfigurationException
+ */
+ static HTTPNetServiceComponentConfiguration createComponentConfiguration(Configuration pluginConfig) {
+
+ URL endPointUrl = null;
+ String configUrl = pluginConfig.getSimpleValue(ConfigKeys.URL, StringUtil.EMPTY_STRING);
+ if (StringUtil.isBlank(configUrl)) {
+ throw new InvalidPluginConfigurationException("Endpoint URL is not defined");
+ }
+ try {
+ endPointUrl = new URL(configUrl);
+ } catch (MalformedURLException e) {
+ throw new InvalidPluginConfigurationException(configUrl + " is not a valid URL");
}
+ String protocol = endPointUrl.getProtocol();
+ if (!protocol.equals("http") && !protocol.equals("https")) {
+ throw new InvalidPluginConfigurationException(configUrl + "does not point to an http(s) resource");
+ }
+
+ HttpMethod httpMethod = null;
+ String configMethod = pluginConfig.getSimpleValue(ConfigKeys.METHOD, StringUtil.EMPTY_STRING);
+ try {
+ httpMethod = HttpMethod.valueOf(configMethod);
+ } catch (IllegalArgumentException e) {
+ throw new InvalidPluginConfigurationException("Invalid http method: " + configMethod);
+ }
+
+ Pattern responseValidationPattern = null;
+ String configValidateResponsePattern = pluginConfig.getSimpleValue(ConfigKeys.VALIDATE_RESPONSE_PATTERN);
+ if (configValidateResponsePattern != null) {
+ if (httpMethod.equals(HttpMethod.HEAD)) {
+ throw new InvalidPluginConfigurationException("Cannot validate response content with HEAD request");
+ }
+ try {
+ responseValidationPattern = Pattern.compile(configValidateResponsePattern);
+ } catch (PatternSyntaxException e) {
+ throw new InvalidPluginConfigurationException("Invalid pattern: " + configValidateResponsePattern);
+ }
+ }
+
+ return new HTTPNetServiceComponentConfiguration(endPointUrl, httpMethod, responseValidationPattern);
}
+ @Override
public void stop() {
+ resourceContext = null;
+ pluginConfig = null;
+ componentConfig = null;
}
+ @Override
public AvailabilityType getAvailability() {
try {
return getValuesOrAvailability(null, null) ? AvailabilityType.UP : AvailabilityType.DOWN;
@@ -84,53 +163,60 @@ public class HTTPNetServiceComponent implements ResourceComponent, MeasurementFa
}
}
+ @Override
public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> metrics) throws Exception {
getValuesOrAvailability(report, metrics);
}
- public boolean getValuesOrAvailability(MeasurementReport report, Set<MeasurementScheduleRequest> metrics)
+ private boolean getValuesOrAvailability(MeasurementReport report, Set<MeasurementScheduleRequest> metrics)
throws Exception {
- try {
-
- Configuration config = resourceContext.getPluginConfiguration();
-
- HttpClient httpClient = new HttpClient();
+ SimpleHttpConnectionManager httpConnectionManager = new SimpleHttpConnectionManager();
+ HttpClient client = new HttpClient(httpConnectionManager);
+
+ String userName = pluginConfig.getSimpleValue(ConfigKeys.USER, StringUtil.EMPTY_STRING);
+ // Set credentials only if a user name is configured
+ if (StringUtil.isNotBlank(userName)) {
+ String password = pluginConfig.getSimpleValue(ConfigKeys.PASSWORD, StringUtil.EMPTY_STRING);
+ String realm = pluginConfig.getSimpleValue(ConfigKeys.REALM, AuthScope.ANY_REALM);
+ client.getState().setCredentials(
+ new AuthScope(componentConfig.getEndPointUrl().getHost(), componentConfig.getEndPointUrl().getPort(),
+ realm), new UsernamePasswordCredentials(userName, password));
+ }
- GetMethod method = new GetMethod(config.getSimple(CONFIG_URL).getStringValue());
+ HttpMethodBase method = null;
+ switch (componentConfig.getHttpMethod()) {
+ case GET:
+ method = new GetMethod(componentConfig.getEndPointUrl().toExternalForm());
+ break;
+ case HEAD:
+ method = new HeadMethod(componentConfig.getEndPointUrl().toExternalForm());
+ break;
+ default:
+ throw new RuntimeException("Unsupported http method: '" + componentConfig.getHttpMethod() + "'");
+ }
+ Boolean followRedirects = pluginConfig.getSimple(ConfigKeys.FOLOW_REDIRECTS).getBooleanValue();
+ method.setFollowRedirects(followRedirects == null ? false : followRedirects.booleanValue());
- method.setFollowRedirects(config.getSimple(CONFIG_FOLOW_REDIRECTS).getBooleanValue());
+ try {
long start = System.currentTimeMillis();
- int responseCode = httpClient.executeMethod(method);
+ int responseCode = client.executeMethod(method);
long connectTime = System.currentTimeMillis() - start;
- boolean success = !config.getSimple("validateResponseCode").getBooleanValue()
+ // Availability may depend on reponse code value
+ boolean success = !pluginConfig.getSimple(ConfigKeys.VALIDATE_RESPONSE_CODE).getBooleanValue()
|| (responseCode >= 200 && responseCode <= 299);
-
- String response = method.getResponseBodyAsString();
+ // Availability may depend on reponse content matching a pattern
+ success = success
+ && (componentConfig.getResponseValidationPattern() == null || componentConfig
+ .getResponseValidationPattern().matcher(method.getResponseBodyAsString()).find());
long readTime = (System.currentTimeMillis() - start);
- // TODO: may need to allow plugin to configure the locale, but for this fixed string, make sure we
- // ignore default locale, this works for english.
- SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss zzz", Locale.ENGLISH);
Header dateHeader = method.getResponseHeader("Date");
- Date contentDate = dateHeader == null ? new Date(System.currentTimeMillis()) : sdf.parse(dateHeader.getValue());
-
- // System.out.println("Success: " + success);
- // System.out.println("Response: " + responseCode);
- // System.out.println("Connect Time: " + connectTime);
- // System.out.println("Read Time: " + readTime);
- // System.out.println("Content Length: " + response.length());
- // System.out.println("Content Date: " + contentDate);
- // System.out.println("Content Charset: " + method.getResponseCharSet());
- // System.out.println("Content Age: " + (System.currentTimeMillis() - contentDate.getTime()));
-
- // System.out.println("-----------------------");
- // for (Header header : method.getResponseHeaders()) {
- // System.out.println(header.getName() + " = " + header.getValue());
- // }
+ Date contentDate = dateHeader == null ? new Date(System.currentTimeMillis()) : DateUtil
+ .parseDate(dateHeader.getValue());
if (metrics != null) {
for (MeasurementScheduleRequest request : metrics) {
@@ -139,7 +225,7 @@ public class HTTPNetServiceComponent implements ResourceComponent, MeasurementFa
} else if (request.getName().equals("readTime")) {
report.addData(new MeasurementDataNumeric(request, (double) readTime));
} else if (request.getName().equals("contentLength")) {
- report.addData(new MeasurementDataNumeric(request, (double) response.length()));
+ report.addData(new MeasurementDataNumeric(request, (double) method.getResponseContentLength()));
} else if (request.getName().equals("contentAge")) {
report.addData(new MeasurementDataNumeric(request,
(double) (System.currentTimeMillis() - contentDate.getTime())));
@@ -150,28 +236,14 @@ public class HTTPNetServiceComponent implements ResourceComponent, MeasurementFa
return success;
} catch (Exception e) {
- // e.printStackTrace();
- log.error(e);
+ LOG.error(e);
+ } finally {
+ // First release connection
+ method.releaseConnection();
+ // Then force close
+ httpConnectionManager.closeIdleConnections(0);
}
return false;
}
- // TODO GH: This really only makes sense to offer to go get the content if we can support long config content for responses bigger than 4k
- public OperationResult invokeOperation(String name, Configuration parameters) throws InterruptedException,
- Exception {
- Configuration config = resourceContext.getPluginConfiguration();
-
- HttpClient httpClient = new HttpClient();
-
- GetMethod method = new GetMethod(config.getSimple(CONFIG_URL).getStringValue());
-
- method.setFollowRedirects(config.getSimple(CONFIG_FOLOW_REDIRECTS).getBooleanValue());
-
- int responseCode = httpClient.executeMethod(method);
-
- String response = method.getResponseBodyAsString();
-
- OperationResult result = new OperationResult(response);
- return result;
- }
}
diff --git a/modules/plugins/netservices/src/main/java/org/rhq/plugins/netservices/HTTPNetServiceComponentConfiguration.java b/modules/plugins/netservices/src/main/java/org/rhq/plugins/netservices/HTTPNetServiceComponentConfiguration.java
new file mode 100644
index 0000000..b28d03f
--- /dev/null
+++ b/modules/plugins/netservices/src/main/java/org/rhq/plugins/netservices/HTTPNetServiceComponentConfiguration.java
@@ -0,0 +1,57 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2013 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.plugins.netservices;
+
+import java.net.URL;
+import java.util.regex.Pattern;
+
+import org.rhq.plugins.netservices.HTTPNetServiceComponent.HttpMethod;
+
+/**
+ * @author Thomas Segismont
+ */
+class HTTPNetServiceComponentConfiguration {
+
+ private URL endPointUrl;
+
+ private HttpMethod httpMethod;
+
+ private Pattern responseValidationPattern;
+
+ public HTTPNetServiceComponentConfiguration(URL endPointUrl, HttpMethod httpMethod,
+ Pattern responseValidationPattern) {
+ this.endPointUrl = endPointUrl;
+ this.httpMethod = httpMethod;
+ this.responseValidationPattern = responseValidationPattern;
+ }
+
+ public URL getEndPointUrl() {
+ return endPointUrl;
+ }
+
+ public HttpMethod getHttpMethod() {
+ return httpMethod;
+ }
+
+ public Pattern getResponseValidationPattern() {
+ return responseValidationPattern;
+ }
+
+}
\ No newline at end of file
diff --git a/modules/plugins/netservices/src/main/java/org/rhq/plugins/netservices/HTTPNetServiceDiscoveryComponent.java b/modules/plugins/netservices/src/main/java/org/rhq/plugins/netservices/HTTPNetServiceDiscoveryComponent.java
index f0d693b..6b259b3 100644
--- a/modules/plugins/netservices/src/main/java/org/rhq/plugins/netservices/HTTPNetServiceDiscoveryComponent.java
+++ b/modules/plugins/netservices/src/main/java/org/rhq/plugins/netservices/HTTPNetServiceDiscoveryComponent.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2008 Red Hat, Inc.
+ * Copyright (C) 2005-2013 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -19,48 +19,37 @@
package org.rhq.plugins.netservices;
-import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
-import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
-import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import java.util.Collections;
+import java.util.Set;
+
+import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
import org.rhq.core.pluginapi.inventory.ManualAddFacet;
-import org.rhq.core.domain.configuration.Configuration;
-
-import java.util.Set;
-import java.util.Collections;
-import java.net.URL;
-import java.net.MalformedURLException;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
/**
* @author Greg Hinkle
*/
public class HTTPNetServiceDiscoveryComponent implements ResourceDiscoveryComponent, ManualAddFacet {
- public Set discoverResources(ResourceDiscoveryContext resourceDiscoveryContext) throws InvalidPluginConfigurationException, Exception {
+
+ @Override
+ public Set discoverResources(ResourceDiscoveryContext resourceDiscoveryContext)
+ throws InvalidPluginConfigurationException, Exception {
// We don't support auto-discovery.
return Collections.emptySet();
}
+ @Override
public DiscoveredResourceDetails discoverResource(Configuration config,
- ResourceDiscoveryContext resourceDiscoveryContext)
- throws InvalidPluginConfigurationException {
- String configURL = config.getSimple(HTTPNetServiceComponent.CONFIG_URL).getStringValue();
- URL url;
- try {
- url = new URL(configURL);
- }
- catch (MalformedURLException e) {
- throw new InvalidPluginConfigurationException("Property '" + HTTPNetServiceComponent.CONFIG_URL
- + "' is not a valid URL.");
- }
- DiscoveredResourceDetails details =
- new DiscoveredResourceDetails(
- resourceDiscoveryContext.getResourceType(),
- url.toExternalForm(),
- url.toExternalForm(),
- null,
- null,
- config,
- null);
+ ResourceDiscoveryContext resourceDiscoveryContext) throws InvalidPluginConfigurationException {
+ // Get the component configuration. This call will also make configuration checks
+ HTTPNetServiceComponentConfiguration componentConfiguration = HTTPNetServiceComponent
+ .createComponentConfiguration(config);
+ String endPointUrl = componentConfiguration.getEndPointUrl().toExternalForm();
+ DiscoveredResourceDetails details = new DiscoveredResourceDetails(resourceDiscoveryContext.getResourceType(),
+ endPointUrl, endPointUrl, null, null, config, null);
return details;
}
}
diff --git a/modules/plugins/netservices/src/main/java/org/rhq/plugins/netservices/PingNetServiceComponent.java b/modules/plugins/netservices/src/main/java/org/rhq/plugins/netservices/PingNetServiceComponent.java
index f219e05..f416140 100644
--- a/modules/plugins/netservices/src/main/java/org/rhq/plugins/netservices/PingNetServiceComponent.java
+++ b/modules/plugins/netservices/src/main/java/org/rhq/plugins/netservices/PingNetServiceComponent.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2008 Red Hat, Inc.
+ * Copyright (C) 2005-2013 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -19,78 +19,93 @@
package org.rhq.plugins.netservices;
-import org.apache.commons.httpclient.Header;
-import org.apache.commons.httpclient.HttpClient;
-import org.apache.commons.httpclient.methods.GetMethod;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.domain.measurement.MeasurementDataNumeric;
+import org.rhq.core.domain.measurement.MeasurementDataTrait;
import org.rhq.core.domain.measurement.MeasurementReport;
import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
-import org.rhq.core.domain.measurement.MeasurementDataTrait;
import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
import org.rhq.core.pluginapi.inventory.ResourceComponent;
import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.core.pluginapi.measurement.MeasurementFacet;
-import org.rhq.core.pluginapi.operation.OperationFacet;
-import org.rhq.core.pluginapi.operation.OperationResult;
-
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Set;
-import java.net.InetAddress;
-import java.net.Inet4Address;
-import java.net.UnknownHostException;
-
+import org.rhq.core.util.StringUtil;
/**
- * Monitoring of HTTP Servers
+ * Monitoring of IP addresses
*
* @author Greg Hinkle
*/
public class PingNetServiceComponent implements ResourceComponent, MeasurementFacet {
- public static final String CONFIG_ADDRESS = "address";
+ public static final class ConfigKeys {
+ private ConfigKeys() {
+ // Defensive
+ }
+
+ public static final String ADDRESS = "address";
+ }
- private ResourceContext resourceContext;
+ private static final Log LOG = LogFactory.getLog(PingNetServiceComponent.class);
- public void start(ResourceContext resourceContext) throws InvalidPluginConfigurationException, Exception {
- this.resourceContext = resourceContext;
- String addressString = resourceContext.getPluginConfiguration().getSimple(CONFIG_ADDRESS).getStringValue();
+ private static final int PING_TIMEOUT = 5000;
+
+ private InetAddress address;
+
+ @Override
+ public void start(@SuppressWarnings("rawtypes")
+ ResourceContext resourceContext) throws InvalidPluginConfigurationException, Exception {
+ address = createComponentConfiguration(resourceContext.getPluginConfiguration());
+ }
+
+ static InetAddress createComponentConfiguration(Configuration pluginConfig)
+ throws InvalidPluginConfigurationException {
+ String addressString = pluginConfig.getSimpleValue(ConfigKeys.ADDRESS, StringUtil.EMPTY_STRING);
+ if (StringUtil.isBlank(addressString)) {
+ throw new InvalidPluginConfigurationException("Address is not defined");
+ }
try {
- InetAddress address = InetAddress.getByName(addressString);
+ return InetAddress.getByName(addressString);
} catch (UnknownHostException uhe) {
throw new InvalidPluginConfigurationException(uhe);
}
}
+ @Override
public void stop() {
+ address = null;
}
+ @Override
public AvailabilityType getAvailability() {
try {
- String addressString = resourceContext.getPluginConfiguration().getSimple(CONFIG_ADDRESS).getStringValue();
- InetAddress address = InetAddress.getByName(addressString);
- return address.isReachable(5000) ? AvailabilityType.UP : AvailabilityType.DOWN;
+ return address.isReachable(PING_TIMEOUT) ? AvailabilityType.UP : AvailabilityType.DOWN;
} catch (Exception e) {
+ if (LOG.isWarnEnabled()) {
+ LOG.warn(address.getHostAddress() + " not reachable", e);
+ }
return AvailabilityType.DOWN;
}
}
-
+ @Override
public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> metrics) throws Exception {
- String addressString = resourceContext.getPluginConfiguration().getSimple(CONFIG_ADDRESS).getStringValue();
- InetAddress address = InetAddress.getByName(addressString);
-
- for (MeasurementScheduleRequest request :metrics) {
+ for (MeasurementScheduleRequest request : metrics) {
if (request.getName().equals("ipAddress")) {
report.addData(new MeasurementDataTrait(request, address.getHostAddress()));
} else if (request.getName().equals("hostName")) {
report.addData(new MeasurementDataTrait(request, address.getCanonicalHostName()));
} else if (request.getName().equals("responseTime")) {
long start = System.currentTimeMillis();
- address.isReachable(5000);
+ address.isReachable(PING_TIMEOUT);
report.addData(new MeasurementDataNumeric(request, (double) (System.currentTimeMillis() - start)));
}
}
diff --git a/modules/plugins/netservices/src/main/java/org/rhq/plugins/netservices/PingNetServiceDiscoveryComponent.java b/modules/plugins/netservices/src/main/java/org/rhq/plugins/netservices/PingNetServiceDiscoveryComponent.java
index 3f41a7e..da87c1b 100644
--- a/modules/plugins/netservices/src/main/java/org/rhq/plugins/netservices/PingNetServiceDiscoveryComponent.java
+++ b/modules/plugins/netservices/src/main/java/org/rhq/plugins/netservices/PingNetServiceDiscoveryComponent.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2008 Red Hat, Inc.
+ * Copyright (C) 2005-2013 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -19,40 +19,37 @@
package org.rhq.plugins.netservices;
-import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
-import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
-import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import java.net.InetAddress;
+import java.util.Collections;
+import java.util.Set;
+
+import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
import org.rhq.core.pluginapi.inventory.ManualAddFacet;
-import org.rhq.core.domain.configuration.Configuration;
-
-import java.util.Set;
-import java.util.Collections;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
/**
* @author Greg Hinkle
*/
public class PingNetServiceDiscoveryComponent implements ResourceDiscoveryComponent, ManualAddFacet {
+
+ private static final String RESOURCE_NAME_PREFIX = "Ping ";
+
+ @Override
public Set discoverResources(ResourceDiscoveryContext resourceDiscoveryContext)
- throws InvalidPluginConfigurationException, Exception {
+ throws InvalidPluginConfigurationException, Exception {
// We don't support auto-discovery.
return Collections.emptySet();
}
+ @Override
public DiscoveredResourceDetails discoverResource(Configuration config,
- ResourceDiscoveryContext resourceDiscoveryContext)
- throws InvalidPluginConfigurationException {
- String address = config.getSimple(PingNetServiceComponent.CONFIG_ADDRESS).getStringValue();
- // TODO: Validate the address is a valid host name or IP address.
- DiscoveredResourceDetails details =
- new DiscoveredResourceDetails(
- resourceDiscoveryContext.getResourceType(),
- address,
- "Ping " + address,
- null,
- null,
- config,
- null);
+ ResourceDiscoveryContext resourceDiscoveryContext) throws InvalidPluginConfigurationException {
+ InetAddress address = PingNetServiceComponent.createComponentConfiguration(config);
+ DiscoveredResourceDetails details = new DiscoveredResourceDetails(resourceDiscoveryContext.getResourceType(),
+ address.getHostAddress(), RESOURCE_NAME_PREFIX + address.getHostAddress(), null, null, config, null);
return details;
}
}
\ No newline at end of file
diff --git a/modules/plugins/netservices/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/netservices/src/main/resources/META-INF/rhq-plugin.xml
index b6b0cd3..16a48d5 100644
--- a/modules/plugins/netservices/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/netservices/src/main/resources/META-INF/rhq-plugin.xml
@@ -11,30 +11,29 @@
<service name="HTTPService"
discovery="HTTPNetServiceDiscoveryComponent"
class="HTTPNetServiceComponent"
- supportsManualAdd="true">
+ supportsManualAdd="true"
+ description="HTTP Endpoint monitoring service">
<plugin-configuration>
- <c:simple-property name="url"/>
- <c:simple-property name="user" required="false"/>
- <c:simple-property name="password" required="false"/>
- <c:simple-property name="realm" required="false"/>
- <c:simple-property name="validateResponseCode" type="boolean" default="false"
- description="Codes in the 200-299 range are considered success"/>
- <c:simple-property name="sslProtocol" default="none">
- <c:property-options>
- <c:option value="none"/>
- <c:option value="SSL"/>
- <c:option value="TLS"/>
- </c:property-options>
- </c:simple-property>
+ <c:simple-property name="url" description="Http URL of the endpoint" />
+ <c:simple-property name="user" required="false"
+ description="User name if http endpoint requires authentication." />
+ <c:simple-property name="password" required="false"
+ description="Password if http endpoint requires authentication." />
+ <c:simple-property name="realm" required="false"
+ description="Authentication Realm. By default user name and password will be used with any realm." />
<c:simple-property name="method" default="GET">
<c:property-options>
<c:option value="HEAD"/>
<c:option value="GET"/>
</c:property-options>
</c:simple-property>
- <c:simple-property name="followRedirects" type="boolean" default="false"/>
- <c:simple-property name="responsePattern" required="false"/>
+ <c:simple-property name="followRedirects" type="boolean" default="false"
+ description="Follow http redirects when contacting endpoints?" />
+ <c:simple-property name="validateResponseCode" type="boolean" default="false"
+ description="Set this to true if response code should determine availability. Codes in the 200-299 range are considered success." />
+ <c:simple-property name="validateResponsePattern" required="false"
+ description="If not empty, availability will depend on http response having content matching this (Java style) regular expression."/>
</plugin-configuration>
<metric property="connectTime" units="milliseconds" displayType="summary"
@@ -46,17 +45,17 @@
<metric property="contentAge" units="milliseconds"
description="The declared age of the requested page"/>
-
</service>
<service name="PingService"
discovery="PingNetServiceDiscoveryComponent"
class="PingNetServiceComponent"
- supportsManualAdd="true">
+ supportsManualAdd="true"
+ description="IP address ping service">
<plugin-configuration>
- <c:simple-property name="address"/>
+ <c:simple-property name="address" description="IP address"/>
</plugin-configuration>
<metric property="ipAddress" displayType="summary" dataType="trait" description="The ip address of the host"/>
diff --git a/modules/plugins/netservices/src/test/java/org/rhq/plugins/netservices/HTTPNetServiceDiscoveryComponentTest.java b/modules/plugins/netservices/src/test/java/org/rhq/plugins/netservices/HTTPNetServiceDiscoveryComponentTest.java
new file mode 100644
index 0000000..0745a34
--- /dev/null
+++ b/modules/plugins/netservices/src/test/java/org/rhq/plugins/netservices/HTTPNetServiceDiscoveryComponentTest.java
@@ -0,0 +1,178 @@
+/*
+ * RHQ Management Platform
+ * Copyright 2013, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * 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.netservices;
+
+import static org.mockito.Mockito.when;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+import org.rhq.plugins.netservices.HTTPNetServiceComponent.ConfigKeys;
+import org.rhq.plugins.netservices.HTTPNetServiceComponent.HttpMethod;
+
+/**
+ * @author Thomas Segismont
+ */
+public class HTTPNetServiceDiscoveryComponentTest {
+
+ private HTTPNetServiceDiscoveryComponent httpNetServiceDiscoveryComponent;
+
+ private Configuration configuration;
+
+ @Mock
+ private ResourceDiscoveryContext<?> resourceDiscoveryContext;
+
+ @Mock
+ private ResourceType resourceType;
+
+ @BeforeMethod(alwaysRun = true)
+ protected void setUp() throws Exception {
+ httpNetServiceDiscoveryComponent = new HTTPNetServiceDiscoveryComponent();
+ configuration = new Configuration();
+ configuration.setSimpleValue(ConfigKeys.URL, "http://www.myhost.com/pipo/molo");
+ configuration.setSimpleValue(ConfigKeys.METHOD, HttpMethod.GET.name());
+ configuration.setSimpleValue(ConfigKeys.VALIDATE_RESPONSE_PATTERN, "(ok|success)");
+ MockitoAnnotations.initMocks(this);
+ when(resourceDiscoveryContext.getResourceType()).thenReturn(resourceType);
+ }
+
+ @Test
+ public void testDiscoverResources() throws Exception {
+ // Manual add only, should always return empty set
+ assertEquals(0, httpNetServiceDiscoveryComponent.discoverResources(null).size());
+ }
+
+ @Test
+ public void testValidComponentConfiguration() {
+ try {
+ DiscoveredResourceDetails resourceDetails = httpNetServiceDiscoveryComponent.discoverResource(
+ configuration, resourceDiscoveryContext);
+ assertEquals(resourceDetails.getResourceType(), resourceType);
+ } catch (InvalidPluginConfigurationException e) {
+ fail("Component configuration should be valid", e);
+ }
+ }
+
+ @Test
+ public void testMissingUrl() {
+ try {
+ configuration.remove(ConfigKeys.URL);
+ httpNetServiceDiscoveryComponent.discoverResource(configuration, resourceDiscoveryContext);
+ fail("Component configuration should be invalid");
+ } catch (InvalidPluginConfigurationException e) {
+ assertEquals(e.getMessage(), "Endpoint URL is not defined");
+ }
+ }
+
+ @Test
+ public void testMalformedUrl() {
+ String configUrl = "pipomolo";
+ try {
+ configuration.setSimpleValue(ConfigKeys.URL, configUrl);
+ httpNetServiceDiscoveryComponent.discoverResource(configuration, resourceDiscoveryContext);
+ fail("Component configuration should be invalid");
+ } catch (InvalidPluginConfigurationException e) {
+ assertEquals(e.getMessage(), configUrl + " is not a valid URL");
+ }
+ }
+
+ @Test
+ public void testNotHttpOrHttpsUrl() {
+ String configUrl = "ftp://pipo.com/molo.zipo";
+ try {
+ configuration.setSimpleValue(ConfigKeys.URL, configUrl);
+ httpNetServiceDiscoveryComponent.discoverResource(configuration, resourceDiscoveryContext);
+ fail("Component configuration should be invalid");
+ } catch (InvalidPluginConfigurationException e) {
+ assertEquals(e.getMessage(), configUrl + "does not point to an http(s) resource");
+ }
+ }
+
+ @Test
+ public void testHttpsUrl() {
+ try {
+ configuration.setSimpleValue(ConfigKeys.URL, "https://www.myhost.com/pipo/molo");
+ DiscoveredResourceDetails resourceDetails = httpNetServiceDiscoveryComponent.discoverResource(
+ configuration, resourceDiscoveryContext);
+ assertEquals(resourceDetails.getResourceType(), resourceType);
+ } catch (InvalidPluginConfigurationException e) {
+ fail("Component configuration should be valid", e);
+ }
+ }
+
+ @Test
+ public void testInvalidHttpMethod() {
+ String configMethod = "DELETE";
+ try {
+ configuration.setSimpleValue(ConfigKeys.METHOD, configMethod);
+ httpNetServiceDiscoveryComponent.discoverResource(configuration, resourceDiscoveryContext);
+ fail("Component configuration should be invalid");
+ } catch (InvalidPluginConfigurationException e) {
+ assertEquals(e.getMessage(), "Invalid http method: " + configMethod);
+ }
+ }
+
+ @Test
+ public void testHeadMethod() {
+ try {
+ configuration.setSimpleValue(ConfigKeys.METHOD, HttpMethod.HEAD.name());
+ configuration.remove(ConfigKeys.VALIDATE_RESPONSE_PATTERN);
+ DiscoveredResourceDetails resourceDetails = httpNetServiceDiscoveryComponent.discoverResource(
+ configuration, resourceDiscoveryContext);
+ assertEquals(resourceDetails.getResourceType(), resourceType);
+ } catch (InvalidPluginConfigurationException e) {
+ fail("Component configuration should be valid", e);
+ }
+ }
+
+ @Test
+ public void testUnableToValidateContentWithHeadRequest() {
+ try {
+ configuration.setSimpleValue(ConfigKeys.METHOD, HttpMethod.HEAD.name());
+ httpNetServiceDiscoveryComponent.discoverResource(configuration, resourceDiscoveryContext);
+ fail("Component configuration should be invalid");
+ } catch (InvalidPluginConfigurationException e) {
+ assertEquals(e.getMessage(), "Cannot validate response content with HEAD request");
+ }
+ }
+
+ @Test
+ public void testInvalidPatternSyntax() {
+ String configValidateResponsePattern = "(pipo";
+ try {
+ configuration.setSimpleValue(ConfigKeys.VALIDATE_RESPONSE_PATTERN, configValidateResponsePattern);
+ httpNetServiceDiscoveryComponent.discoverResource(configuration, resourceDiscoveryContext);
+ fail("Component configuration should be invalid");
+ } catch (InvalidPluginConfigurationException e) {
+ assertEquals(e.getMessage(), "Invalid pattern: " + configValidateResponsePattern);
+ }
+ }
+
+}
diff --git a/modules/plugins/netservices/src/test/java/org/rhq/plugins/netservices/PingNetServiceDiscoveryComponentTest.java b/modules/plugins/netservices/src/test/java/org/rhq/plugins/netservices/PingNetServiceDiscoveryComponentTest.java
new file mode 100644
index 0000000..961a81c
--- /dev/null
+++ b/modules/plugins/netservices/src/test/java/org/rhq/plugins/netservices/PingNetServiceDiscoveryComponentTest.java
@@ -0,0 +1,105 @@
+/*
+ * RHQ Management Platform
+ * Copyright 2013, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * 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.netservices;
+
+import static org.mockito.Mockito.when;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+
+import java.net.UnknownHostException;
+
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+import org.rhq.plugins.netservices.PingNetServiceComponent.ConfigKeys;
+
+/**
+ * @author Thomas Segismont
+ */
+public class PingNetServiceDiscoveryComponentTest {
+
+ private PingNetServiceDiscoveryComponent pingNetServiceDiscoveryComponent;
+
+ private Configuration configuration;
+
+ @Mock
+ private ResourceDiscoveryContext<?> resourceDiscoveryContext;
+
+ @Mock
+ private ResourceType resourceType;
+
+ @BeforeMethod(alwaysRun = true)
+ protected void setUp() throws Exception {
+ pingNetServiceDiscoveryComponent = new PingNetServiceDiscoveryComponent();
+ configuration = new Configuration();
+ configuration.setSimpleValue(ConfigKeys.ADDRESS, "127.0.0.1");
+ MockitoAnnotations.initMocks(this);
+ when(resourceDiscoveryContext.getResourceType()).thenReturn(resourceType);
+ }
+
+ @Test
+ public void testDiscoverResources() throws Exception {
+ // Manual add only, should always return empty set
+ assertEquals(0, pingNetServiceDiscoveryComponent.discoverResources(null).size());
+ }
+
+ @Test
+ public void testValidComponentConfiguration() {
+ try {
+ DiscoveredResourceDetails resourceDetails = pingNetServiceDiscoveryComponent.discoverResource(
+ configuration, resourceDiscoveryContext);
+ assertEquals(resourceDetails.getResourceType(), resourceType);
+ } catch (InvalidPluginConfigurationException e) {
+ fail("Component configuration should be valid", e);
+ }
+ }
+
+ @Test
+ public void testMissingAddress() {
+ try {
+ configuration.remove(ConfigKeys.ADDRESS);
+ pingNetServiceDiscoveryComponent.discoverResource(configuration, resourceDiscoveryContext);
+ fail("Component configuration should be invalid");
+ } catch (InvalidPluginConfigurationException e) {
+ assertEquals(e.getMessage(), "Address is not defined");
+ }
+ }
+
+ @Test
+ public void testMalformedAddress() {
+ String configAddress = "pipomolo";
+ try {
+ configuration.setSimpleValue(ConfigKeys.ADDRESS, configAddress);
+ pingNetServiceDiscoveryComponent.discoverResource(configuration, resourceDiscoveryContext);
+ fail("Component configuration should be invalid");
+ } catch (InvalidPluginConfigurationException e) {
+ assertEquals(e.getCause().getClass(), UnknownHostException.class);
+ }
+ }
+
+}
diff --git a/modules/plugins/netservices/src/test/java/org/rhq/plugins/netservices/itest/HTTPNetServiceComponentTest.java b/modules/plugins/netservices/src/test/java/org/rhq/plugins/netservices/itest/HTTPNetServiceComponentTest.java
new file mode 100644
index 0000000..24b6644
--- /dev/null
+++ b/modules/plugins/netservices/src/test/java/org/rhq/plugins/netservices/itest/HTTPNetServiceComponentTest.java
@@ -0,0 +1,162 @@
+/*
+ * RHQ Management Platform
+ * Copyright 2013, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * 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.netservices.itest;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.discovery.MergeResourceResponse;
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.domain.measurement.DataType;
+import org.rhq.core.domain.measurement.MeasurementData;
+import org.rhq.core.domain.measurement.MeasurementReport;
+import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.plugins.netservices.HTTPNetServiceComponent;
+import org.rhq.plugins.netservices.HTTPNetServiceComponent.ConfigKeys;
+import org.rhq.plugins.netservices.HTTPNetServiceComponent.HttpMethod;
+
+/**
+ * @author Thomas Segismont
+ */
+public class HTTPNetServiceComponentTest extends NetServiceComponentTest {
+
+ private static final Log LOG = LogFactory.getLog(NetServiceComponentTest.class);
+
+ private static final String SERVICE_NAME = "HTTPService";
+
+ private static final String HTTP_HOST = "localhost";
+
+ private static final int HTTP_PORT = 31158;
+
+ private static final int SERVLET_SLEEP = 1000;
+
+ private Server jettyServer;
+
+ private HTTPNetServiceComponent httpNetServiceComponent;
+
+ @BeforeClass
+ public void startJetty() throws Exception {
+ LOG.info("Setting up Jetty test server");
+ jettyServer = new Server(new InetSocketAddress(HTTP_HOST, HTTP_PORT));
+ ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
+ context.setContextPath("/");
+ jettyServer.setHandler(context);
+ @SuppressWarnings("serial")
+ HttpServlet testServlet = new HttpServlet() {
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ resp.getWriter().println("Test servlet request: success view");
+ long start = System.currentTimeMillis();
+ do {
+ try {
+ Thread.sleep(SERVLET_SLEEP);
+ } catch (InterruptedException e) {
+ }
+ } while (System.currentTimeMillis() - start < SERVLET_SLEEP);
+ }
+ };
+ context.addServlet(new ServletHolder(testServlet), "/*");
+ jettyServer.start();
+ }
+
+ @AfterClass
+ public void stopJetty() {
+ LOG.info("Shutting down Jetty test server");
+ try {
+ if (jettyServer != null) {
+ jettyServer.stop();
+ }
+ } catch (Exception ignore) {
+ }
+ }
+
+ @Test(dependsOnMethods = "testPluginLoad")
+ public void testManualAdd() throws Exception {
+ Configuration configuration = new Configuration();
+ configuration.setSimpleValue(ConfigKeys.URL, "http://" + HTTP_HOST + ":" + HTTP_PORT + "/pipo/molo");
+ configuration.setSimpleValue(ConfigKeys.METHOD, HttpMethod.GET.name());
+ configuration.setSimpleValue(ConfigKeys.VALIDATE_RESPONSE_CODE, "true");
+ configuration.setSimpleValue(ConfigKeys.VALIDATE_RESPONSE_PATTERN, "success");
+ MergeResourceResponse response = getInventoryManager().manuallyAddResource(
+ getPluginManager().getMetadataManager().getType(SERVICE_NAME, PLUGIN_NAME), getPlatform().getId(),
+ configuration, -1);
+ assertNotNull(response, "Manual add response is null");
+ @SuppressWarnings("rawtypes")
+ ResourceComponent resourceComponent = getInventoryManager().getResourceContainer(response.getResourceId())
+ .getResourceComponent();
+ assertEquals(resourceComponent.getClass(), HTTPNetServiceComponent.class);
+ httpNetServiceComponent = (HTTPNetServiceComponent) resourceComponent;
+ }
+
+ @Test(dependsOnMethods = "testManualAdd")
+ public void testAvailability() throws Exception {
+ assertEquals(httpNetServiceComponent.getAvailability(), AvailabilityType.UP);
+ }
+
+ @Test(dependsOnMethods = "testAvailability")
+ public void testMeasurement() throws Exception {
+ MeasurementReport report = new MeasurementReport();
+ Set<MeasurementScheduleRequest> metrics = new HashSet<MeasurementScheduleRequest>();
+ int scheduleId = 1;
+ metrics.add(new MeasurementScheduleRequest(scheduleId++, "connectTime", 1000, true, DataType.MEASUREMENT));
+ metrics.add(new MeasurementScheduleRequest(scheduleId++, "readTime", 1000, true, DataType.MEASUREMENT));
+ metrics.add(new MeasurementScheduleRequest(scheduleId++, "contentLength", 1000, true, DataType.MEASUREMENT));
+ metrics.add(new MeasurementScheduleRequest(scheduleId++, "contentAge", 1000, true, DataType.MEASUREMENT));
+ httpNetServiceComponent.getValues(report, metrics);
+ Map<String, Object> datas = new HashMap<String, Object>();
+ for (MeasurementData data : report.getNumericData()) {
+ datas.put(data.getName(), data.getValue());
+ }
+ Double value = getMetric(datas, "connectTime");
+ assertTrue(value > SERVLET_SLEEP);
+ value = getMetric(datas, "readTime");
+ assertTrue(value > SERVLET_SLEEP);
+ value = getMetric(datas, "contentLength");
+ assertTrue(value > 0);
+ value = getMetric(datas, "contentAge");
+ assertTrue(value > 0);
+ }
+
+}
diff --git a/modules/plugins/netservices/src/test/java/org/rhq/plugins/netservices/itest/NetServiceComponentTest.java b/modules/plugins/netservices/src/test/java/org/rhq/plugins/netservices/itest/NetServiceComponentTest.java
new file mode 100644
index 0000000..503e359
--- /dev/null
+++ b/modules/plugins/netservices/src/test/java/org/rhq/plugins/netservices/itest/NetServiceComponentTest.java
@@ -0,0 +1,154 @@
+/*
+ * RHQ Management Platform
+ * Copyright 2013, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * 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.netservices.itest;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.when;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import java.io.File;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.testng.annotations.AfterSuite;
+import org.testng.annotations.BeforeSuite;
+import org.testng.annotations.Test;
+
+import org.rhq.core.clientapi.server.discovery.DiscoveryServerService;
+import org.rhq.core.domain.discovery.MergeResourceResponse;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.pc.PluginContainer;
+import org.rhq.core.pc.PluginContainerConfiguration;
+import org.rhq.core.pc.ServerServices;
+import org.rhq.core.pc.inventory.InventoryManager;
+import org.rhq.core.pc.plugin.FileSystemPluginFinder;
+import org.rhq.core.pc.plugin.PluginEnvironment;
+import org.rhq.core.pc.plugin.PluginManager;
+
+/**
+ * @author Thomas Segismont
+ */
+public abstract class NetServiceComponentTest {
+
+ public static final String PLUGIN_NAME = "NetworkServices";
+
+ private static final Log LOG = LogFactory.getLog(NetServiceComponentTest.class);
+
+ private static final AtomicInteger resourceIdGenerator = new AtomicInteger(Integer.MIN_VALUE / 2);
+
+ private static PluginContainer pluginContainer;
+
+ private static InventoryManager inventoryManager;
+
+ private static Resource platform;
+
+ private static PluginManager pluginManager;
+
+ private static PluginEnvironment pluginEnvironment;
+
+ protected PluginContainer getPluginContainer() {
+ return pluginContainer;
+ }
+
+ protected InventoryManager getInventoryManager() {
+ return inventoryManager;
+ }
+
+ protected Resource getPlatform() {
+ return platform;
+ }
+
+ protected PluginManager getPluginManager() {
+ return pluginManager;
+ }
+
+ protected PluginEnvironment getPluginEnvironment() {
+ return pluginEnvironment;
+ }
+
+ @BeforeSuite
+ public static void startPluginContainer() throws Exception {
+ LOG.info("Setting up plugin container");
+ File pluginDir = new File("target/itest/plugins");
+ PluginContainerConfiguration containerConfig = new PluginContainerConfiguration();
+ containerConfig.setPluginFinder(new FileSystemPluginFinder(pluginDir));
+ containerConfig.setPluginDirectory(pluginDir);
+ containerConfig.setInsideAgent(false);
+ // netservices plugin has resources which can only be manually added so we have to mock server integration.
+ DiscoveryServerService discoveryServerService = Mockito.mock(DiscoveryServerService.class);
+ when(discoveryServerService.addResource(any(Resource.class), anyInt())).thenAnswer(
+ new Answer<MergeResourceResponse>() {
+
+ @Override
+ public MergeResourceResponse answer(InvocationOnMock invocation) throws Throwable {
+ return new MergeResourceResponse(resourceIdGenerator.decrementAndGet(), false);
+ }
+ });
+ ServerServices serverServices = new ServerServices();
+ serverServices.setDiscoveryServerService(discoveryServerService);
+ containerConfig.setServerServices(serverServices);
+ pluginContainer = PluginContainer.getInstance();
+ pluginContainer.setConfiguration(containerConfig);
+ pluginContainer.initialize();
+ inventoryManager = pluginContainer.getInventoryManager();
+ platform = inventoryManager.getPlatform();
+ pluginManager = pluginContainer.getPluginManager();
+ pluginEnvironment = pluginManager.getPlugin(PLUGIN_NAME);
+ }
+
+ @AfterSuite
+ public static void stopPluginContainer() {
+ LOG.info("Shutting down plugin container");
+ try {
+ if (pluginContainer != null) {
+ pluginContainer.shutdown();
+ }
+ } catch (Exception ignore) {
+ }
+ }
+
+ @Test
+ public static void testPluginLoad() {
+ assertNotNull(pluginEnvironment, "Plugin not loaded");
+ assertEquals(pluginEnvironment.getPluginName(), PLUGIN_NAME);
+ }
+
+ public static Double getMetric(Map<String, Object> datas, String metricName) {
+ assertTrue(datas.containsKey(metricName), metricName + " metric not found");
+ assertTrue(datas.get(metricName).getClass().equals(Double.class), metricName + " metric value is not a Double");
+ return (Double) datas.get(metricName);
+ }
+
+ public static String getTrait(Map<String, Object> datas, String traitName) {
+ assertTrue(datas.containsKey(traitName), traitName + " trait not found");
+ assertTrue(datas.get(traitName).getClass().equals(String.class), traitName + " traitName value is not a String");
+ return (String) datas.get(traitName);
+ }
+
+}
diff --git a/modules/plugins/netservices/src/test/java/org/rhq/plugins/netservices/itest/PingNetServiceComponentTest.java b/modules/plugins/netservices/src/test/java/org/rhq/plugins/netservices/itest/PingNetServiceComponentTest.java
new file mode 100644
index 0000000..ea1a374
--- /dev/null
+++ b/modules/plugins/netservices/src/test/java/org/rhq/plugins/netservices/itest/PingNetServiceComponentTest.java
@@ -0,0 +1,98 @@
+/*
+ * RHQ Management Platform
+ * Copyright 2013, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * 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.netservices.itest;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.testng.annotations.Test;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.discovery.MergeResourceResponse;
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.domain.measurement.DataType;
+import org.rhq.core.domain.measurement.MeasurementData;
+import org.rhq.core.domain.measurement.MeasurementReport;
+import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.util.StringUtil;
+import org.rhq.plugins.netservices.PingNetServiceComponent;
+import org.rhq.plugins.netservices.PingNetServiceComponent.ConfigKeys;
+
+/**
+ * @author Thomas Segismont
+ */
+public class PingNetServiceComponentTest extends NetServiceComponentTest {
+
+ private static final String SERVICE_NAME = "PingService";
+
+ private static final String LOOPBACK = "127.0.0.1";
+
+ private PingNetServiceComponent pingNetServiceComponent;
+
+ @Test(dependsOnMethods = "testPluginLoad")
+ public void testManualAdd() throws Exception {
+ Configuration configuration = new Configuration();
+ configuration.setSimpleValue(ConfigKeys.ADDRESS, LOOPBACK);
+ MergeResourceResponse response = getInventoryManager().manuallyAddResource(
+ getPluginManager().getMetadataManager().getType(SERVICE_NAME, PLUGIN_NAME), getPlatform().getId(),
+ configuration, -1);
+ assertNotNull(response, "Manual add response is null");
+ @SuppressWarnings("rawtypes")
+ ResourceComponent resourceComponent = getInventoryManager().getResourceContainer(response.getResourceId())
+ .getResourceComponent();
+ assertEquals(resourceComponent.getClass(), PingNetServiceComponent.class);
+ pingNetServiceComponent = (PingNetServiceComponent) resourceComponent;
+ }
+
+ @Test(dependsOnMethods = "testManualAdd")
+ public void testAvailability() throws Exception {
+ assertEquals(pingNetServiceComponent.getAvailability(), AvailabilityType.UP);
+ }
+
+ @Test(dependsOnMethods = "testAvailability")
+ public void testMeasurement() throws Exception {
+ MeasurementReport report = new MeasurementReport();
+ Set<MeasurementScheduleRequest> metrics = new HashSet<MeasurementScheduleRequest>();
+ int scheduleId = 1;
+ metrics.add(new MeasurementScheduleRequest(scheduleId++, "ipAddress", 1000, true, DataType.TRAIT));
+ metrics.add(new MeasurementScheduleRequest(scheduleId++, "hostName", 1000, true, DataType.TRAIT));
+ metrics.add(new MeasurementScheduleRequest(scheduleId++, "responseTime", 1000, true, DataType.MEASUREMENT));
+ pingNetServiceComponent.getValues(report, metrics);
+ Map<String, Object> datas = new HashMap<String, Object>();
+ for (MeasurementData data : report.getNumericData()) {
+ datas.put(data.getName(), data.getValue());
+ }
+ for (MeasurementData data : report.getTraitData()) {
+ datas.put(data.getName(), data.getValue());
+ }
+ assertEquals(getTrait(datas, "ipAddress"), LOOPBACK);
+ assertTrue(StringUtil.isNotBlank(getTrait(datas, "hostName")));
+ assertTrue(getMetric(datas, "responseTime") >= 0);
+ }
+
+}
diff --git a/modules/plugins/netservices/src/test/resources/log4j.xml b/modules/plugins/netservices/src/test/resources/log4j.xml
new file mode 100644
index 0000000..4815936
--- /dev/null
+++ b/modules/plugins/netservices/src/test/resources/log4j.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<!-- | For more configuration information and examples, see the Jakarta Log4j | website: http://jakarta.apache.org/log4j -->
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+
+ <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
+ <param name="Target" value="System.out" />
+ <param name="Threshold" value="INFO" />
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%-5p %d{dd-MM HH:mm:ss,SSS} (%F:%M:%L) - %m%n" />
+ </layout>
+ </appender>
+
+ <appender name="FILE" class="org.apache.log4j.RollingFileAppender">
+ <param name="File" value="target/test.log" />
+ <param name="Append" value="false" />
+ <param name="Threshold" value="DEBUG" />
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%-5p %d{dd-MM HH:mm:ss,SSS} (%F:%M:%L) - %m%n" />
+ </layout>
+ </appender>
+
+ <root>
+ <level value="DEBUG" />
+ <appender-ref ref="CONSOLE" />
+ <appender-ref ref="FILE" />
+ </root>
+
+</log4j:configuration>
11 years, 3 months
[rhq] Changes to 'tsegismont/netservices'
by Thomas Segismont
New branch 'tsegismont/netservices' available with the following commits:
commit f26fb6165c0bde26a31f9421ef1e31c07c38c5e7
Author: Thomas Segismont <tsegismo(a)redhat.com>
Date: Tue Feb 12 10:23:51 2013 +0100
netservices plugin strengthening
Added Unit tests for HTTPNetServiceDiscoveryComponent
Added HTTPNetServiceComponent itest and verified code coverage
Added Unit tests for PingNetServiceDiscoveryComponent
Added PingNetServiceComponent itest and verified code coverage
Implemented missing parts and cleaned up code
11 years, 3 months