[rhq] Branch 'code-smell' - modules/enterprise
by mazz
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/CustomJaasDeploymentService.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 4b3e3a6e01e2f599af8a21a14c37debc92060cc1
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Thu Jul 28 12:37:04 2011 -0400
[coverity] close the context - no need to keep it open since we just create it to see that no exceptions occurred.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/CustomJaasDeploymentService.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/CustomJaasDeploymentService.java
index be7a0ab..a4124ca 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/CustomJaasDeploymentService.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/CustomJaasDeploymentService.java
@@ -209,7 +209,7 @@ public class CustomJaasDeploymentService implements CustomJaasDeploymentServiceM
}
log.debug("Validating LDAP with environment=" + env);
- new InitialLdapContext(env, null);
+ new InitialLdapContext(env, null).close();
return;
}
12 years, 10 months
[rhq] Branch 'code-smell' - modules/core
by mazz
modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryFile.java | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
New commits:
commit 0329aa66eaea0e3a53b4c7682e9e49d3a28d0750
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Thu Jul 28 12:17:21 2011 -0400
[coverity] make sure to close the file
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryFile.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryFile.java
index 7a8e1e5..ea5e7fd 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryFile.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryFile.java
@@ -103,8 +103,9 @@ public class InventoryFile {
* inventory
*/
public void loadInventory() throws PluginContainerException {
+ FileInputStream fis = null;
try {
- FileInputStream fis = new FileInputStream(inventoryFile);
+ fis = new FileInputStream(inventoryFile);
ObjectInputStream ois = new ObjectInputStream(fis);
// this list will contain UUIDs of resources that we should ignore usually due to disabled plugins
@@ -126,6 +127,13 @@ public class InventoryFile {
return;
} catch (Exception e) {
throw new PluginContainerException("Cannot load inventory file: " + inventoryFile, e);
+ } finally {
+ if (fis != null) {
+ try {
+ fis.close();
+ } catch (Exception e) {
+ }
+ }
}
}
12 years, 10 months
[rhq] Branch 'code-smell' - modules/plugins
by mazz
modules/plugins/platform/src/main/java/org/rhq/plugins/platform/content/yum/YumServer.java | 21 +++++-----
1 file changed, 12 insertions(+), 9 deletions(-)
New commits:
commit 203bb4b9b7d4107d7332754709b6bc9ec5851771
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Thu Jul 28 12:12:05 2011 -0400
[coverity] make sure we close the printwriter in finally block
diff --git a/modules/plugins/platform/src/main/java/org/rhq/plugins/platform/content/yum/YumServer.java b/modules/plugins/platform/src/main/java/org/rhq/plugins/platform/content/yum/YumServer.java
index dc92a61..3524b9b 100644
--- a/modules/plugins/platform/src/main/java/org/rhq/plugins/platform/content/yum/YumServer.java
+++ b/modules/plugins/platform/src/main/java/org/rhq/plugins/platform/content/yum/YumServer.java
@@ -178,15 +178,18 @@ public class YumServer {
File file = new File(yumconf);
try {
PrintWriter writer = new PrintWriter(file);
- writer.println("[rhq]");
- writer.println("name=RHQ");
- writer.printf("baseurl=%s\n", context.baseurl());
- writer.printf("metadata_expire=%d\n", context.getMetadataCacheTimeout());
- writer.println("enabled=1");
- writer.println("gpgcheck=0");
- writer.println("keepalive=0");
- writer.println("timeout=90");
- writer.close();
+ try {
+ writer.println("[rhq]");
+ writer.println("name=RHQ");
+ writer.printf("baseurl=%s\n", context.baseurl());
+ writer.printf("metadata_expire=%d\n", context.getMetadataCacheTimeout());
+ writer.println("enabled=1");
+ writer.println("gpgcheck=0");
+ writer.println("keepalive=0");
+ writer.println("timeout=90");
+ } finally {
+ writer.close();
+ }
} catch (Exception e) {
String msg = "The yum repo configuration file '" + file + "' could not be created/updated!";
log.error(msg, e);
12 years, 10 months
[rhq] Branch 'code-smell' - modules/core
by mazz
modules/core/client-api/src/test/java/org/rhq/core/clientapi/agent/metadata/test/ExtensionModelTest.java | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
New commits:
commit 3a558fe5559b55707cb861e72a3d307a6a24b2a6
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Thu Jul 28 11:42:07 2011 -0400
[coverity] this should have been an assert - and if it was, this unit test would have failed only because the casting was incorrect.
the code it was testing actually worked. I'm fixing the test so this actually asserts the correct thing.
diff --git a/modules/core/client-api/src/test/java/org/rhq/core/clientapi/agent/metadata/test/ExtensionModelTest.java b/modules/core/client-api/src/test/java/org/rhq/core/clientapi/agent/metadata/test/ExtensionModelTest.java
index 3d9fb10..06fc087 100644
--- a/modules/core/client-api/src/test/java/org/rhq/core/clientapi/agent/metadata/test/ExtensionModelTest.java
+++ b/modules/core/client-api/src/test/java/org/rhq/core/clientapi/agent/metadata/test/ExtensionModelTest.java
@@ -37,6 +37,7 @@ import org.rhq.core.clientapi.agent.metadata.PluginMetadataManager;
import org.rhq.core.clientapi.descriptor.AgentPluginDescriptorUtil;
import org.rhq.core.clientapi.descriptor.DescriptorPackages;
import org.rhq.core.clientapi.descriptor.plugin.PluginDescriptor;
+import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.domain.configuration.definition.PropertyDefinition;
import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
@@ -130,7 +131,9 @@ public class ExtensionModelTest {
assert !def1.isRequired();
assert def1 instanceof PropertyDefinitionSimple;
assert ((PropertyDefinitionSimple) def1).getType().equals(PropertySimpleType.BOOLEAN);
- def1.getConfigurationDefinition().getDefaultTemplate().getConfiguration().get("force").equals("false");
+ PropertySimple prop = (PropertySimple) def1.getConfigurationDefinition().getDefaultTemplate()
+ .getConfiguration().get("force");
+ assert prop.getBooleanValue().booleanValue() == false;
assert stopOp.getResultsConfigurationDefinition() != null;
ConfigurationDefinition results = stopOp.getResultsConfigurationDefinition();
12 years, 10 months
[rhq] Branch 'code-smell' - modules/enterprise
by mazz
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/SearchBar.java | 31 +++++-----
1 file changed, 17 insertions(+), 14 deletions(-)
New commits:
commit d85516841d7bead784f587535c1364d47185b7a9
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Thu Jul 28 11:23:34 2011 -0400
[coverity] the if-stmt looks bad, but anyway, this handler doesn't do anything anyway, the main code inside it was commented out.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/SearchBar.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/SearchBar.java
index cce560c..007f908 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/SearchBar.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/SearchBar.java
@@ -38,9 +38,6 @@ import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.Event.NativePreviewEvent;
-import com.google.gwt.user.client.Event.NativePreviewHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
@@ -129,17 +126,23 @@ public class SearchBar extends AbstractSearchBar {
String searchButtonId = searchBarElement.getAttribute("searchButtonId");
searchButton = DOM.getElementById(searchButtonId);
- Event.addNativePreviewHandler(new NativePreviewHandler() {
- public void onPreviewNativeEvent(NativePreviewEvent event) {
- if (event.getNativeEvent() != null && event.getNativeEvent().getEventTarget() != null) {
-
- if (event.getNativeEvent().getEventTarget().equals(searchButton)
- && event.getTypeInt() == Event.ONMOUSEDOWN) {
- //prepareSearchExecution();
- }
- }
- }
- });
+ // Don't know what this originally was going to be used for, but if you notice,
+ // after all the if-stmts are evaluated true, the only piece of code to be invoked
+ // (prepareSearchExecution()) has been commented out. So this is a no-op. In addition
+ // the second if-stmt (getEventTarget().equals(searchButton) doesn't look correct and
+ // may not ever evaluate to true anyway. Commenting this out, in case something like this
+ // is needed in the future, but we'll havee to probably fix that if-stmt first.
+
+ // Event.addNativePreviewHandler(new NativePreviewHandler() {
+ // public void onPreviewNativeEvent(NativePreviewEvent event) {
+ // if (event.getNativeEvent() != null && event.getNativeEvent().getEventTarget() != null) {
+ // if (event.getNativeEvent().getEventTarget().equals(searchButton)
+ // && event.getTypeInt() == Event.ONMOUSEDOWN) {
+ // //prepareSearchExecution();
+ // }
+ // }
+ // }
+ // });
String searchSubsystem = searchBarElement.getAttribute("searchSubsystem");
setSearchSubsystem(SearchSubsystem.valueOf(searchSubsystem.toUpperCase()));
12 years, 10 months
[rhq] Branch 'code-smell' - modules/enterprise
by mazz
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/AbstractTwoLevelTabSetView.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
New commits:
commit e7bcd08184a293f0fa745e4fe8a1167dd552bb68
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Thu Jul 28 11:15:21 2011 -0400
[coverity] fix NPE
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/AbstractTwoLevelTabSetView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/AbstractTwoLevelTabSetView.java
index 71f5ec5..047f5af 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/AbstractTwoLevelTabSetView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/AbstractTwoLevelTabSetView.java
@@ -296,7 +296,8 @@ public abstract class AbstractTwoLevelTabSetView<T, U extends Layout> extends Lo
SubTab subTab = tab.getDefaultSubTab();
if (subTab == null || tab.getLayout().isSubTabDisabled(subTab)) {
- CoreGUI.getErrorHandler().handleError(MSG.view_tabs_invalidSubTab(subTab.getName()));
+ CoreGUI.getErrorHandler().handleError(
+ MSG.view_tabs_invalidSubTab((subTab != null ? subTab.getName() : "null")));
subTab = tab.getLayout().getDefaultSubTab();
}
12 years, 10 months
[rhq] 17 commits - modules/enterprise modules/integration-tests modules/plugins
by Heiko W. Rupp
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/PluginConfigurationMetadataManagerBean.java | 10
modules/integration-tests/jboss-as-7-plugin-test/src/test/java/org/rhq/modules/integrationTests/jbossas7plugin/UploadAndDeployTest.java | 85 +++
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/AbstractBaseDiscovery.java | 53 ++
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java | 91 ++--
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java | 111 +++--
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java | 184 ++++++++
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationLoadDelegate.java | 6
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/DomainComponent.java | 72 ---
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/HostControllerComponent.java | 64 ++
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/JmsComponent.java | 3
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASComponent.java | 70 +++
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASDiscovery.java | 9
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ServerGroupComponent.java | 5
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASComponent.java | 38 -
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/json/Address.java | 19
modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml | 222 ++++++----
16 files changed, 794 insertions(+), 248 deletions(-)
New commits:
commit b35ba5b025f995e7658bd1f56a8e002f5b05e84b
Merge: 47451f9 f1b3ecd
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Thu Jul 28 15:48:01 2011 +0200
Merge branch 'as7plugin' of ssh://git.fedorahosted.org/git/rhq/rhq into as7plugin
commit 47451f90a8383fe368a398e45e5e4d75d0efd256
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Thu Jul 28 15:44:35 2011 +0200
BZ 726378 - management port settings on AS7 were not honored.
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
index 322e453..9aa9db0 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
@@ -111,12 +111,15 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
this.context = context;
pluginConfiguration = context.getPluginConfiguration();
- String typeName = context.getResourceType().getName();
- // TODO can we use parent's connection and only set this up for top level base component?
- host = pluginConfiguration.getSimpleValue("hostname", LOCALHOST);
- String portString = pluginConfiguration.getSimpleValue("port", DEFAULT_HTTP_MANAGEMENT_PORT);
- port = Integer.parseInt(portString);
- connection = new ASConnection(host,port);
+ if (!(context.getParentResourceComponent() instanceof BaseComponent)) {
+ host = pluginConfiguration.getSimpleValue("hostname", LOCALHOST);
+ String portString = pluginConfiguration.getSimpleValue("port", DEFAULT_HTTP_MANAGEMENT_PORT);
+ port = Integer.parseInt(portString);
+ connection = new ASConnection(host,port);
+ }
+ else {
+ connection = ((BaseComponent)context.getParentResourceComponent()).getASConnection();
+ }
path = pluginConfiguration.getSimpleValue("path", null);
key = context.getResourceKey();
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java
index 475fd62..471fd42 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java
@@ -79,11 +79,8 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
String psName = psr.getProcessScan().getName();
String description = discoveryContext.getResourceType().getDescription();
String version = null;
- String startScript;
- if (psName.equals("ProcessController")) {
- serverNameFull = "ProcessController";
- serverName = "ProcessController";
- } else if (psName.equals("HostController")) {
+
+ if (psName.equals("HostController")) {
readStandaloneOrHostXml(psr.getProcessInfo(), true);
HostPort hp = getDomainControllerFromHostXml();
if (hp.isLocal) {
@@ -118,11 +115,10 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
tmp = tmp.substring( i + 8);
tmp = tmp.substring(0,tmp.indexOf("/"));
serverNameFull = tmp;
-
- String host = findHost(psr.getProcessInfo(),true);
- config.put(new PropertySimple("domainHost",host));
-
}
+ String host = findHost(psr.getProcessInfo(),true);
+ config.put(new PropertySimple("domainHost",host));
+
config.put(new PropertySimple("baseDir",serverNameFull));
serverName = findHostName();
if (serverName.isEmpty())
@@ -139,6 +135,11 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
}
String logFile = getLogFileFromCommandLine(commandLine);
initLogEventSourcesConfigProp(logFile,config);
+
+ HostPort managmentPort = getManagementPortFromHostXml();
+ config.put(new PropertySimple("hostname",managmentPort.host));
+ config.put(new PropertySimple("port",managmentPort.port));
+
// String javaClazz = psr.getProcessInfo().getName();
commit b160369e4999f327871e961fb75fe74f470d6914
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Thu Jul 28 13:17:00 2011 +0200
Initial support for messaging (JMS)
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
index 776e5ef..322e453 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
@@ -23,6 +23,8 @@ import org.apache.commons.logging.LogFactory;
import org.codehaus.jackson.JsonNode;
import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.Property;
+import org.rhq.core.domain.configuration.PropertyList;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
@@ -480,12 +482,34 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
} else if (what.equals("destination")) {
address.addAll(pathToAddress(getPath()));
String newName = parameters.getSimpleValue("name","");
-// String type = parameters.getSimpleValue("type","Queue").toLowerCase();
-// address.add(new PROPERTY_VALUE(type,newName));
- String queueName = parameters.getSimpleValue("queue-address","");
- Map<String,Object> props = new HashMap<String, Object>();
- props.put("queue-address",queueName);
+ String type = parameters.getSimpleValue("type","jms-queue").toLowerCase();
+ address.add(new PROPERTY_VALUE(type,newName));
+ PropertyList jndiNamesProp = parameters.getList("entries");
+ if (jndiNamesProp==null || jndiNamesProp.getList().isEmpty()) {
+ OperationResult fail = new OperationResult();
+ fail.setErrorMessage("No jndi bindings given");
+ return fail;
+ }
+ List<String> jndiNames = new ArrayList<String>();
+ for (Property p : jndiNamesProp.getList()) {
+ PropertySimple ps = (PropertySimple) p;
+ jndiNames.add(ps.getStringValue());
+ }
+
operation = new Operation(op,address);
+ operation.addAdditionalProperty("entries",jndiNames);
+ if (type.equals("jms-queue")) {
+ PropertySimple ps = (PropertySimple) parameters.get("durable");
+ if (ps!=null) {
+ boolean durable = ps.getBooleanValue();
+ operation.addAdditionalProperty("durable",durable);
+ }
+ String selector = parameters.getSimpleValue("selector","");
+ if (!selector.isEmpty())
+ operation.addAdditionalProperty("selector",selector);
+ }
+
+
} else if (what.equals("managed-server")) {
String chost = parameters.getSimpleValue("hostname","");
String serverName = parameters.getSimpleValue("servername","");
diff --git a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
index 6a8698e..20395e0 100644
--- a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
@@ -444,7 +444,7 @@
<server name="Messaging"
discovery="SubsystemDiscovery"
class="BaseComponent"
- description="The underlying HornetQ based messaging subsystem"
+ description="The HornetQ based messaging subsystem"
singleton="true"
>
<runs-inside>
@@ -459,15 +459,16 @@
<operation name="destination:add" displayName="Add destination" description="Add a Queue or Topic">
<parameters>
<c:simple-property name="name" description="Name of the Destination" required="true"/>
- <c:simple-property name="queue-address" description="The queue address defines what address is used for routing messages." required="true"/>
+ <c:list-property name="entries" description="The JNDI names the destination should be bound to." required="true">
+ <c:simple-property name="entry" description="A single JNDI name. Note, this is relative to java:jboss/jms/"/>
+ </c:list-property>
<c:simple-property name="type" description="Type of Destination to create" default="Queue">
<c:property-options>
- <c:option value="Queue"/>
- <c:option value="Topic"/>
+ <c:option value="jms-queue" name="Queue"/>
+ <c:option value="jms-topic" name="Topic"/>
</c:property-options>
</c:simple-property>
- <c:simple-property name="filter" description="The queue message filter definition."/>
- <c:simple-property name="durable" description="Defines whether the queue is durable." type="boolean" default="false"/>
+ <c:simple-property name="durable" description="Defines whether the queue is durable (for Queues only)." type="boolean" default="false"/>
</parameters>
<results>
<c:simple-property name="operationResult"/>
@@ -487,73 +488,23 @@
<c:simple-property name="journal-type" />
</resource-configuration>
- <!-- this is no child resource TODO
-
- <service name="Acceptor"
- discovery="SubsystemDiscovery"
- class="BaseComponent"
- >
- <plugin-configuration>
- <c:simple-property name="path" readOnly="true" default="acceptor"/>
- </plugin-configuration>
- </service>
- <service name="MessagingConnector"
- discovery="SubsystemDiscovery"
- class="BaseComponent"
- >
- <plugin-configuration>
- <c:simple-property name="path" readOnly="true" default="connector"/>
- </plugin-configuration>
- </service>
- <service name="HQueue"
- discovery="SubsystemDiscovery"
- class="BaseComponent"
- >
- <plugin-configuration>
- <c:simple-property name="path" readOnly="true" default="queue"/>
- </plugin-configuration>
- <resource-configuration>
- <c:simple-property name="queue-address" required="true"/>
- <c:simple-property name="filter" />
- <c:simple-property name="durable" type="boolean"/>
- </resource-configuration>
-
- </service>
--->
- </server>
-
- <server name="JMS"
- discovery="SubsystemDiscovery"
- class="JmsComponent"
- description="The JMS messaging subsystem"
- singleton="true"
- >
- <runs-inside>
- <parent-resource-type name="Profile" plugin="jboss-as-7"/>
- <parent-resource-type name="JBossAS7-Standalone" plugin="jboss-as-7"/>
- </runs-inside>
-
- <plugin-configuration>
- <c:simple-property name="path" readOnly="true" default="subsystem=jms"/>
- </plugin-configuration>
-
- <service name="Queue"
+ <service name="JMS Queue"
discovery="SubsystemDiscovery"
class="JmsComponent"
- createDeletePolicy="both"
+ createDeletePolicy="delete-only"
>
<plugin-configuration>
- <c:simple-property name="path" readOnly="true" default="queue"/>
+ <c:simple-property name="path" readOnly="true" default="jms-queue"/>
</plugin-configuration>
<resource-configuration> <!-- See BZ 705713 TODO -->
- <c:simple-property name="durable" required="false" type="boolean" readOnly="false" default="false"
+ <c:simple-property name="durable" required="false" type="boolean" readOnly="true" default="false"
description="Whether the queue is durable or not."/>
- <c:list-property name="entries" required="false" readOnly="false"
+ <c:list-property name="entries" required="false" readOnly="true"
description="The jndi names the queue will be bound to.">
<c:simple-property name="entries" type="string"/>
</c:list-property>
- <c:simple-property name="selector" required="false" type="string" readOnly="false" description="The queue selector."/>
+ <c:simple-property name="selector" required="false" type="string" readOnly="true" description="The queue selector."/>
<c:template name="add" description="Properties when adding a new queue" >
<c:simple-property name="durable" required="false" type="boolean" default="false"
description="Whether the queue is durable or not."/>
@@ -565,16 +516,16 @@
</c:template>
</resource-configuration>
</service>
- <service name="Topic"
+ <service name="JMS Topic"
discovery="SubsystemDiscovery"
class="JmsComponent"
- createDeletePolicy="both"
+ createDeletePolicy="delete-only"
>
<plugin-configuration>
- <c:simple-property name="path" readOnly="true" default="topic"/>
+ <c:simple-property name="path" readOnly="true" default="jms-topic"/>
</plugin-configuration>
<resource-configuration> <!-- See BZ 705713 TODO -->
- <c:list-property name="entries" required="false" readOnly="false"
+ <c:list-property name="entries" required="false" readOnly="true"
description="The jndi names the queue will be bound to.">
<c:simple-property name="entries" type="string"/>
</c:list-property>
commit d3f942a14e0497b7bcbd6561c495f391513cdb29
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Tue Jul 26 22:29:16 2011 +0200
Add more properties for JBossWeb. Unfortunately they are read-only in AS7
Follow :read-resource output, as the resource description from AS7 is not up to date.
diff --git a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
index d9f79d1..6a8698e 100644
--- a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
@@ -614,6 +614,78 @@
<c:simple-property name="path" readOnly="true" default="subsystem=web"/>
</plugin-configuration>
+ <resource-configuration>
+ <c:simple-property name="default-virtual-server" required="false" type="string" readOnly="true" defaultValue="localhost"
+ description="The web container's default virtual server."/>
+ <c:simple-property name="native" required="false" type="boolean" readOnly="true" defaultValue="true"
+ description="Add the native initialization listener to the web container."/>
+ <c:map-property name="configuration" description="The common web container configuration." >
+ <c:map-property name="static-resources" description="Configuration for static resources" >
+ <c:simple-property name="listings" required="false" type="boolean" readOnly="true" defaultValue="false"
+ description="Enable folder listings."/>
+ <c:simple-property name="sendfile" required="false" type="integer" readOnly="true" defaultValue="49152"
+ description="Enable sendfile if possible, for files bigger than the specified byte size."/>
+ <c:simple-property name="read-only" required="false" type="boolean" readOnly="true" defaultValue="true"
+ description="Allow write HTTP methods (PUT, DELETE)."/>
+ <c:simple-property name="webdav" required="false" type="boolean" readOnly="true" defaultValue="false"
+ description="Enable WebDAV functionality."/>
+ <c:simple-property name="secret" required="false" type="string" readOnly="true" description="Secret for WebDAV locking operations."/>
+ <c:simple-property name="max-depth" required="false" type="integer" readOnly="true" defaultValue="3"
+ description="Maximum recursion for PROPFIND."/>
+ <c:simple-property name="disabled" required="false" type="boolean" readOnly="true" defaultValue="false"
+ description="Enable the JSP container."/>
+ </c:map-property>
+ <c:map-property name="jsp-configuration" description="JSP container configuration">
+ <c:simple-property name="development" required="false" type="boolean" readOnly="true" defaultValue="false"
+ description="Enable the development mode, which gives more information when an error occurs."/>
+ <c:simple-property name="file-encoding" required="false" type="string" readOnly="true" description="Force a file encoding."/>
+ <c:simple-property name="keep-generated" required="false" type="boolean" readOnly="true" defaultValue="true"
+ description="Keep the generated Servlets."/>
+ <c:simple-property name="trim-spaces" required="false" type="boolean" readOnly="true" defaultValue="true"
+ description="Trim some spaces from the generated Servlet."/>
+ <c:simple-property name="tag-pooling" required="false" type="boolean" readOnly="true" defaultValue="true"
+ description="Enable tag pooling."/>
+ <c:simple-property name="mapped-file" required="false" type="boolean" readOnly="true" defaultValue="true"
+ description="Map to the JSP source."/>
+ <c:simple-property name="check-interval" required="false" type="integer" readOnly="true" defaultValue="0"
+ description="Check interval for JSP updates using a background thread."/>
+ <c:simple-property name="modification-test-interval" required="false" type="integer" readOnly="true" defaultValue="4"
+ description="Minimum amount of time between two tests for updates, in seconds."/>
+ <c:simple-property name="recompile-on-fail" required="false" type="boolean" readOnly="true" defaultValue="false"
+ description="Retry failed JSP compilations on each request."/>
+ <c:simple-property name="smap" required="false" type="boolean" readOnly="true" defaultValue="false"
+ description="Enable SMAP."/>
+ <c:simple-property name="dump-smap" required="false" type="boolean" readOnly="true" defaultValue="false"
+ description="Write SMAP data to a file."/>
+ <c:simple-property name="generate-strings-as-char-arrays" required="false" type="boolean" readOnly="true"
+ defaultValue="false"
+ description="Generate String constants as char arrays."/>
+ <c:simple-property name="error-on-use-bean-invalid-class-attribute" required="false" type="boolean" readOnly="true" defaultValue="false"
+ description="Enable errors when using a bad class in useBean."/>
+ <c:simple-property name="scratch-dir" required="false" type="string" readOnly="true" description="Specify a different work directory."/>
+ <c:simple-property name="source-vm" required="false" type="string" readOnly="true" defaultValue="1.5"
+ description="Source VM level for compilation."/>
+ <c:simple-property name="target-vm" required="false" type="string" readOnly="true" defaultValue="1.5"
+ description="Target VM level for compilation."/>
+ <c:simple-property name="java-encoding" required="false" type="string" readOnly="true" defaultValue="UTF-8"
+ description="Specify the encoding used for Java sources."/>
+ <c:simple-property name="x-powered-by" required="false" type="boolean" readOnly="true" defaultValue="true"
+ description="Enable advertising the JSP engine in x-powered-by."/>
+ <c:simple-property name="display-source-fragment" required="false" type="boolean" readOnly="true" defaultValue="true"
+ description="When a runtime error occurs, attempts to display corresponding JSP source fragment."/>
+ </c:map-property>
+ <c:list-property name="mime-mapping" description="A mime-mapping definition." >
+ <c:map-property name="mime-mapping" >
+ <c:simple-property name="name" description="A MIME mapping name"/>
+ <c:simple-property name="value" description="A MIME mapping value"/>
+ </c:map-property>
+ </c:list-property>
+ <c:list-property name="welcome-file" description="A welcome file declaration." >
+ <c:simple-property name="welcome-file" />
+ </c:list-property>
+ </c:map-property>
+ </resource-configuration>
+
<service name="Connector"
discovery="SubsystemDiscovery"
class="BaseComponent"
commit 8cf10dd720219a5b1a03e825eae5ca2ccd978a5f
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Wed Jul 27 09:18:58 2011 +0200
Get rid of the explicit version number and let maven do the magic.
diff --git a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
index 0927693..d9f79d1 100644
--- a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
@@ -48,7 +48,6 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration"
- version="4.0.0-SNAPSHOT"
>
<!-- <depends plugin="JMX" useClasses="true"/> -->
commit 9b8876e0032bf4c94568bd784ac44b38198f4731
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Wed Jul 27 11:18:39 2011 +0200
Log the property being null and don't pollute stdout.
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationLoadDelegate.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationLoadDelegate.java
index e978962..c999be6 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationLoadDelegate.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationLoadDelegate.java
@@ -269,8 +269,10 @@ public class ConfigurationLoadDelegate implements ConfigurationFacet {
if (property!=null)
propertyMap.put(property);
- else
- System.out.println("Property " + key + " was null");
+ else {
+ if (log.isDebugEnabled())
+ log.debug("Property " + key + " was null");
+ }
}
commit 8de2372999f6778ac2c41d7f4d80fcea239e4e2d
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Mon Jul 25 18:00:50 2011 +0200
Provide more connection properties for standalone servers as well as the version. Add start and restart operations for standalone servers.
Read the running instance name (i.e. standalone server name) from standalone.xml
Allow to start a domain/host controller.
Allow to shut down hosts in a domain.
Allow to shut down host controllers. Revert the ability to shutdown hosts - this needs to be done at HC level.
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/AbstractBaseDiscovery.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/AbstractBaseDiscovery.java
index 63a4e45..c089b79 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/AbstractBaseDiscovery.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/AbstractBaseDiscovery.java
@@ -46,9 +46,15 @@ public abstract class AbstractBaseDiscovery<T extends ResourceComponent> impleme
protected Document hostXml;
protected final Log log = LogFactory.getLog(this.getClass());
-// private final Log log = LogFactory.getLog(AbstractBaseDiscovery.class);
- protected void readHostXml(ProcessInfo processInfo,boolean isDomainMode) {
+ /**
+ * Read the host.xml or standalone.xml file depending on isDomainMode. If isDomainMode is true,
+ * host.xml is read, otherwise standalone.xml.
+ * The xml file content is stored in the variable hostXml for future use.
+ * @param processInfo Process info to determine the base file location
+ * @param isDomainMode Indiates if host.xml should be read (true) or standalone.xml (false)
+ */
+ protected void readStandaloneOrHostXml(ProcessInfo processInfo, boolean isDomainMode) {
String hostXmlFile = getHostXmlFileLocation(processInfo,isDomainMode);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
@@ -61,7 +67,11 @@ public abstract class AbstractBaseDiscovery<T extends ResourceComponent> impleme
}
}
-
+ /**
+ * Determine the server home (=base) directory by parsing the passed command line
+ * @param commandLine command line arguments of the process
+ * @return The home dir if found or empty string otherwise
+ */
String getHomeDirFromCommandLine(String[] commandLine) {
for (String line: commandLine) {
if (line.startsWith(DJBOSS_SERVER_HOME_DIR))
@@ -70,6 +80,11 @@ public abstract class AbstractBaseDiscovery<T extends ResourceComponent> impleme
return "";
}
+ /**
+ * Determine the location of the boot log file of the server by parsing the command line
+ * @param commandLine command line arguments of the process
+ * @return The log file location or empty string otherwise
+ */
String getLogFileFromCommandLine(String[] commandLine) {
for (String line: commandLine) {
@@ -79,7 +94,14 @@ public abstract class AbstractBaseDiscovery<T extends ResourceComponent> impleme
return "";
}
+ /**
+ * Try to obtain the management IP and port from the already parsed host.xml or standalone.xml
+ * @return an Object containing host and port
+ * @see #readStandaloneOrHostXml(org.rhq.core.system.ProcessInfo, boolean) on how to obtain the parsed xml
+ */
protected HostPort getManagementPortFromHostXml() {
+ if (hostXml==null)
+ throw new IllegalArgumentException("hostXml is null. You need to call 'readStandaloneOrHostXml' first.");
Element host = hostXml.getDocumentElement();
NodeList interfaceParent = host.getElementsByTagName("management-interfaces");
if (interfaceParent ==null || interfaceParent.getLength()==0) {
@@ -112,7 +134,15 @@ public abstract class AbstractBaseDiscovery<T extends ResourceComponent> impleme
return new HostPort();
}
+ /**
+ * Try to obtain the management interface IP from the host/standalone.xml files
+ * @param nIf Interface to look for
+ * @return IP address to use
+ */
private String getInterface(String nIf) {
+ if (hostXml==null)
+ throw new IllegalArgumentException("hostXml is null. You need to call 'readStandaloneOrHostXml' first.");
+
Element host = hostXml.getDocumentElement();
NodeList interfaceParent = host.getElementsByTagName("interfaces");
if (interfaceParent ==null || interfaceParent.getLength()==0) {
@@ -155,12 +185,26 @@ public abstract class AbstractBaseDiscovery<T extends ResourceComponent> impleme
return null; // TODO: Customise this generated block
}
+ /**
+ * Try to determine the host name - that is the name of a standalone server or a
+ * host in domain mode by looking at the standalone/host.xml files
+ * @return server name
+ */
protected String findHostName() {
+ if (hostXml==null)
+ throw new IllegalArgumentException("hostXml is null. You need to call 'readStandaloneOrHostXml' first.");
+
String hostName = hostXml.getDocumentElement().getAttribute("name");
return hostName;
}
+ /**
+ * Try to obtain the domain controller's location from looking at host.xml
+ * @return host and port of the domain controller
+ */
protected HostPort getDomainControllerFromHostXml() {
+ if (hostXml==null)
+ throw new IllegalArgumentException("hostXml is null. You need to call 'readStandaloneOrHostXml' first.");
Element host = hostXml.getDocumentElement();
NodeList dcParent = host.getElementsByTagName("domain-controller");
@@ -211,6 +255,9 @@ public abstract class AbstractBaseDiscovery<T extends ResourceComponent> impleme
}
+ /**
+ * Helper class that holds information about the host,port tuple
+ */
protected static class HostPort {
String host;
int port;
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
index 8851706..776e5ef 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
@@ -79,7 +79,7 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
final Log log = LogFactory.getLog(this.getClass());
ResourceContext context;
- Configuration conf;
+ Configuration pluginConfiguration;
String myServerName;
ASConnection connection;
String path;
@@ -107,16 +107,16 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
*/
public void start(ResourceContext context) throws InvalidPluginConfigurationException, Exception {
this.context = context;
- conf = context.getPluginConfiguration();
+ pluginConfiguration = context.getPluginConfiguration();
String typeName = context.getResourceType().getName();
// TODO can we use parent's connection and only set this up for top level base component?
- host = conf.getSimpleValue("hostname", LOCALHOST);
- String portString = conf.getSimpleValue("port", DEFAULT_HTTP_MANAGEMENT_PORT);
+ host = pluginConfiguration.getSimpleValue("hostname", LOCALHOST);
+ String portString = pluginConfiguration.getSimpleValue("port", DEFAULT_HTTP_MANAGEMENT_PORT);
port = Integer.parseInt(portString);
connection = new ASConnection(host,port);
- path = conf.getSimpleValue("path", null);
+ path = pluginConfiguration.getSimpleValue("path", null);
key = context.getResourceKey();
myServerName = context.getResourceKey().substring(context.getResourceKey().lastIndexOf("/")+1);
@@ -445,16 +445,15 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
List<PROPERTY_VALUE> address = new ArrayList<PROPERTY_VALUE>();
if (what.equals("server-group")) {
- String groupName = parameters.getSimpleValue("name",null);
+ String groupName = parameters.getSimpleValue("name","");
String profile = parameters.getSimpleValue("profile","default");
address.add(new PROPERTY_VALUE("server-group",groupName));
operation = new Operation(op,address,"profile",profile);
} else if (what.equals("server")) {
-
if (context.getResourceType().getName().equals("JBossAS-Managed")) {
- String host = conf.getSimpleValue("domainHost","local");
+ String host = pluginConfiguration.getSimpleValue("domainHost","local");
address.add(new PROPERTY_VALUE("host",host));
address.add(new PROPERTY_VALUE("server-config",myServerName));
operation = new Operation(op,address);
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java
index 2f71edb..475fd62 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java
@@ -18,8 +18,11 @@
*/
package org.rhq.modules.plugins.jbossas7;
+import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.List;
@@ -30,7 +33,6 @@ import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.mc4j.ems.connection.support.metadata.LocalVMTypeDescriptor;
import org.w3c.dom.Document;
import org.rhq.core.domain.configuration.Configuration;
@@ -43,8 +45,6 @@ import org.rhq.core.pluginapi.inventory.ProcessScanResult;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
import org.rhq.core.system.ProcessInfo;
-import org.rhq.plugins.jmx.JMXDiscoveryComponent;
-
/**
* Discovery class
@@ -53,9 +53,10 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
{
- static final String DJBOSS_SERVER_BASE_DIR = "-Djboss.server.base.dir=";
+ static final String DJBOSS_HOME_DIR = "-Djboss.home.dir=";
static final String DORG_JBOSS_BOOT_LOG_FILE = "-Dorg.jboss.boot.log.file=";
static final String DLOGGING_CONFIGURATION = "-Dlogging.configuration=";
+ static final String DASH_DASH_SERVER_CONFIG = "--server-config=";
private final Log log = LogFactory.getLog(this.getClass());
/**
@@ -77,11 +78,13 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
String serverName;
String psName = psr.getProcessScan().getName();
String description = discoveryContext.getResourceType().getDescription();
+ String version = null;
+ String startScript;
if (psName.equals("ProcessController")) {
serverNameFull = "ProcessController";
serverName = "ProcessController";
} else if (psName.equals("HostController")) {
- readHostXml(psr.getProcessInfo(),true);
+ readStandaloneOrHostXml(psr.getProcessInfo(), true);
HostPort hp = getDomainControllerFromHostXml();
if (hp.isLocal) {
serverName = "DomainController";
@@ -92,11 +95,20 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
serverName = "HostController";
serverNameFull = "HostController";
}
- config.put(new PropertySimple("homedir",getHomeDirFromCommandLine(psr.getProcessInfo().getCommandLine())));
- // TODO add the start script
+ String homeDir = getHomeDirFromCommandLine(psr.getProcessInfo().getCommandLine());
+ config.put(new PropertySimple("baseDir", homeDir));
+ version = homeDir.substring(homeDir.lastIndexOf("-")+1);
+ config.put(new PropertySimple("startScript","bin/domain.sh"));
+ String host = findHost(psr.getProcessInfo(),true);
+ config.put(new PropertySimple("domainHost",host));
+
+ fillUserPassFromFile(config,"domain",homeDir);
+
+ // TODO provide running config
- } else {
- serverNameFull = getBaseDirFromCommandLine(commandLine);
+ } else { // Standalone server
+ serverNameFull = getHomeDirFromCommandLine(commandLine);
+ readStandaloneOrHostXml(psr.getProcessInfo(), false);
if (serverNameFull==null || serverNameFull.isEmpty()) {
// Try to obtain the server name
// -Dorg.jboss.boot.log.file=domain/servers/server-one/log/boot.log
@@ -111,10 +123,19 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
config.put(new PropertySimple("domainHost",host));
}
- serverName = serverNameFull.substring(serverNameFull.lastIndexOf("/")+1);
+ config.put(new PropertySimple("baseDir",serverNameFull));
+ serverName = findHostName();
if (serverName.isEmpty())
serverName = serverNameFull;
+ version = serverName.substring(serverName.lastIndexOf("-")+1);
+
+ String serverConfig = getServerConfigFromCommandLine(commandLine);
+ config.put(new PropertySimple("config",serverConfig));
+ config.put(new PropertySimple("startScript","bin/standalone.sh"));
+
+ fillUserPassFromFile(config,"standalone", serverNameFull);
+
}
String logFile = getLogFileFromCommandLine(commandLine);
initLogEventSourcesConfigProp(logFile,config);
@@ -139,7 +160,7 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
discoveryContext.getResourceType(), // ResourceType
serverNameFull, // key TODO distinguish per domain?
serverName, // Name
- null, // TODO real version ?
+ version, // TODO get via API ?Á
description, // Description
config,
psr.getProcessInfo()
@@ -155,6 +176,48 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
}
+ private void fillUserPassFromFile(Configuration config, String mode, String baseDir) {
+
+ String configDir = baseDir + File.separator + mode + File.separator + "configuration";
+
+ File file = new File(configDir ,"mgmt-users.properties");
+ if (!file.exists() || !file.canRead()) {
+ if (log.isDebugEnabled())
+ log.debug("No console user properties file found at [" + file.getAbsolutePath() + "] or file is not readable");
+ return;
+ }
+ BufferedReader br=null;
+ try {
+ FileReader fileReader = new FileReader(file);
+ br = new BufferedReader(fileReader);
+ String line;
+ while ((line = br.readLine())!=null) {
+ if (line.startsWith("#"))
+ continue;
+ if (line.isEmpty())
+ continue;
+ if (!line.contains("="))
+ continue;
+ // found a candidate
+ String user = line.substring(0,line.indexOf("="));
+ String pass = line.substring(line.indexOf("=")+1);
+ config.put(new PropertySimple("user",user));
+ config.put(new PropertySimple("password",pass));
+
+ }
+ } catch (IOException e) {
+ e.printStackTrace(); // TODO: Customise this generated block
+ } finally {
+ if (br!=null)
+ try {
+ br.close();
+ } catch (IOException e) {
+ // empty
+ }
+ }
+
+ }
+
private String findHost(ProcessInfo processInfo,boolean isDomain) {
String hostXmlFile = getHostXmlFileLocation(processInfo, isDomain);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
@@ -173,12 +236,13 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
return hostName;
}
- String getBaseDirFromCommandLine(String[] commandLine) {
+
+ String getServerConfigFromCommandLine(String[] commandLine) {
for (String line: commandLine) {
- if (line.startsWith(DJBOSS_SERVER_BASE_DIR))
- return line.substring(DJBOSS_SERVER_BASE_DIR.length());
+ if (line.startsWith(DASH_DASH_SERVER_CONFIG))
+ return line.substring(DASH_DASH_SERVER_CONFIG.length());
}
- return "";
+ return "standalone.xml";
}
//-Dorg.jboss.boot.log.file=/devel/jbas7/jboss-as/build/target/jboss-7.0.0.Alpha2/domain/log/server-manager/boot.log
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java
new file mode 100644
index 0000000..c8703a6
--- /dev/null
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java
@@ -0,0 +1,184 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.modules.plugins.jbossas7;
+
+import java.io.File;
+import java.net.ConnectException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.pluginapi.operation.OperationResult;
+import org.rhq.core.pluginapi.util.ProcessExecutionUtility;
+import org.rhq.core.system.ProcessExecution;
+import org.rhq.core.system.ProcessExecutionResults;
+import org.rhq.modules.plugins.jbossas7.json.Result;
+
+/**
+ * Base component for functionality that is common to Standalone AS and HostControllers
+ * @author Heiko W. Rupp
+ */
+public class BaseServerComponent extends BaseComponent {
+
+ private static final String STANDALONE_XML = "standalone.xml";
+ private static final String SEPARATOR = "\n-----------------------\n";
+ final Log log = LogFactory.getLog(BaseServerComponent.class);
+
+ /**
+ * Restart the server by first executing a 'shutdown' operation via its API. Then call
+ * the #startServer method to start it again.
+ *
+ * @param parameters Parameters to pass to the (recursive) invocation of #invokeOperation
+ * @param mode
+ * @return State of execution
+ * @throws Exception If anything goes wrong
+ */
+ protected OperationResult restartServer(Configuration parameters, Mode mode) throws Exception {
+ OperationResult tmp = invokeOperation("shutdown",parameters);
+
+ if (tmp.getErrorMessage()!=null) {
+ tmp.setErrorMessage("Restart failed while failing to shut down: " + tmp.getErrorMessage());
+ return tmp;
+ }
+ Thread.sleep(500); // Wait 0.5s -- this is plenty
+ return startServer(mode);
+ }
+
+ /**
+ * Start the server by calling the start script listed in the plugin configuration. If a different
+ * config is given, this is passed via --server-config
+ * @return State of Execution.
+ * @param mode
+ */
+ protected OperationResult startServer(Mode mode) {
+ OperationResult operationResult = new OperationResult();
+ Configuration conf = context.getPluginConfiguration();
+ String startScript = conf.getSimpleValue("startScript", mode.getStartScript());
+ String baseDir = conf.getSimpleValue("baseDir","");
+ if (baseDir.isEmpty()) {
+ operationResult.setErrorMessage("No base directory provided");
+ return operationResult;
+ }
+ String script = baseDir + File.separator + startScript;
+ String config = conf.getSimpleValue("config", mode.getXmlFile());
+
+ ProcessExecution processExecution;
+ processExecution = ProcessExecutionUtility.createProcessExecution(new File(script));
+ if (!config.equals(mode.getXmlFile())) {
+ processExecution.getArguments().add(mode.getConfigArg());
+ processExecution.getArguments().add(config);
+ }
+ processExecution.setWorkingDirectory(baseDir);
+ processExecution.setCaptureOutput(true);
+ processExecution.setWaitForCompletion(2000L); // 2 seconds // TODO: Should we wait longer than two seconds?
+ processExecution.setKillOnTimeout(false);
+
+
+ long start = System.currentTimeMillis();
+ if (log.isDebugEnabled()) {
+ log.debug("About to execute the following process: [" + processExecution + "]");
+ }
+ ProcessExecutionResults results = context.getSystemInformation().executeProcess(processExecution);
+ logExecutionResults(results);
+ if (results.getError()!=null) {
+ operationResult.setErrorMessage(results.getError().getMessage());
+ } else {
+ operationResult.setSimpleResult("Success");
+ }
+
+ return operationResult;
+
+ }
+
+ private void logExecutionResults(ProcessExecutionResults results) {
+ // Always log the output at info level. On Unix we could switch depending on a exitCode being !=0, but ...
+ log.info("Exit code from process execution: " + results.getExitCode());
+ log.info("Output from process execution: " + SEPARATOR + results.getCapturedOutput() + SEPARATOR);
+ }
+
+ /**
+ * Do some post processing of the Result - especially the 'shutdown' operation needs a special
+ * treatment.
+ * @param name Name of the operation
+ * @param res Result of the operation vs. AS7
+ * @return OperationResult filled in from values of res
+ */
+ protected OperationResult postProcessResult(String name, Result res) {
+ OperationResult operationResult = new OperationResult();
+ if (name.equals("shutdown")) {
+ /*
+ * Shutdown needs a special treatment, because after sending the operation, if shutdown suceeds,
+ * the server connection is closed and we can't read from it. So if we get connection refused for
+ * reading, this is a good sign.
+ */
+ if (!res.isSuccess()) {
+ if (res.getThrowable()!=null && (res.getThrowable() instanceof ConnectException || res.getThrowable().getMessage().equals("Connection refused")))
+ operationResult.setSimpleResult("Success");
+ else
+ operationResult.setErrorMessage(res.getFailureDescription());
+ }
+ }
+ else {
+ if (res.isSuccess()) {
+ if (res.getResult()!=null)
+ operationResult.setSimpleResult(res.getResult().toString());
+ else
+ operationResult.setSimpleResult("-None provided by server-");
+ }
+ else
+ operationResult.setErrorMessage(res.getFailureDescription());
+ }
+ return operationResult;
+ }
+
+ enum Mode {
+ STANDALONE(STANDALONE_XML,"standalone","--server-config","bin/standalone.sh"),
+ DOMAIN("domain.xml","domain", "--domain-config","bin/domain.sh"),
+ HOST("host.xml","domain", "--host-config","bin/domain.sh");
+
+ private String xmlFile;
+ private String baseDir;
+ private String configArg;
+ private String startScript;
+
+ private Mode(String xmlFile, String baseDir, String configArg, String startScript) {
+ this.xmlFile = xmlFile;
+ this.baseDir = baseDir;
+ this.configArg = configArg;
+ this.startScript = startScript;
+ }
+
+ public String getXmlFile() {
+ return xmlFile;
+ }
+
+ public String getBaseDir() {
+ return baseDir;
+ }
+
+ public String getConfigArg() {
+ return configArg;
+ }
+
+ public String getStartScript() {
+ return startScript;
+ }
+ }
+}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/DomainComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/DomainComponent.java
deleted file mode 100644
index c25fe88..0000000
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/DomainComponent.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2011 Red Hat, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-package org.rhq.modules.plugins.jbossas7;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.codehaus.jackson.JsonNode;
-
-import org.rhq.core.domain.configuration.Configuration;
-import org.rhq.core.domain.measurement.AvailabilityType;
-import org.rhq.core.pluginapi.operation.OperationFacet;
-import org.rhq.core.pluginapi.operation.OperationResult;
-import org.rhq.modules.plugins.jbossas7.json.Operation;
-import org.rhq.modules.plugins.jbossas7.json.PROPERTY_VALUE;
-import org.rhq.modules.plugins.jbossas7.json.Result;
-
-/**
- * Common stuff for the Domain
- * @author Heiko W. Rupp
- */
-@SuppressWarnings("unused")
-public class DomainComponent extends BaseComponent implements OperationFacet{
-
- @Override
- public AvailabilityType getAvailability() {
-
- if (context.getResourceType().getName().equals("JBossAS-Managed")) {
- List<PROPERTY_VALUE> address = new ArrayList<PROPERTY_VALUE>(2);
- String host = conf.getSimpleValue("domainHost","local");
- address.add(new PROPERTY_VALUE("host",host));
- address.add(new PROPERTY_VALUE("server-config",myServerName));
- Operation getStatus = new Operation("read-attribute",address,"name","status");
- Result result = null;
- try {
- result = connection.execute(getStatus);
- } catch (Exception e) {
- log.warn(e.getMessage());
- return AvailabilityType.DOWN;
- }
- if (!result.isSuccess())
- return AvailabilityType.DOWN;
-
- String msg = result.getResult().toString();
- if (msg.contains("STARTED"))
- return AvailabilityType.UP;
- else
- return AvailabilityType.DOWN;
- }
-
- return super.getAvailability(); // TODO: Customise this generated block
- }
-
-}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/HostControllerComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/HostControllerComponent.java
new file mode 100644
index 0000000..73eb0bb
--- /dev/null
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/HostControllerComponent.java
@@ -0,0 +1,64 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.modules.plugins.jbossas7;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.pluginapi.operation.OperationFacet;
+import org.rhq.core.pluginapi.operation.OperationResult;
+import org.rhq.modules.plugins.jbossas7.json.Operation;
+import org.rhq.modules.plugins.jbossas7.json.Result;
+
+/**
+ * Component class for host- and domain controller
+ * @author Heiko W. Rupp
+ */
+public class HostControllerComponent extends BaseServerComponent implements OperationFacet {
+
+ private final Log log = LogFactory.getLog(HostControllerComponent.class);
+
+ @Override
+ public OperationResult invokeOperation(String name,
+ Configuration parameters) throws InterruptedException, Exception {
+
+ if (name.equals("start")) {
+ return startServer(Mode.DOMAIN);
+ } else if (name.equals("restart")) {
+ return restartServer(parameters, Mode.DOMAIN);
+
+ } else if (name.equals("shutdown")) {
+ // This is a bit trickier, as it needs to be executed on the level on /host=xx
+ String domainHost = pluginConfiguration.getSimpleValue("domainHost","");
+ if (domainHost.isEmpty()) {
+ OperationResult result = new OperationResult();
+ result.setErrorMessage("No domain host found - can not continue");
+ return result;
+ }
+ Operation op = new Operation("shutdown","host",domainHost);
+ Result res = getASConnection().execute(op);
+
+ postProcessResult(name,res);
+ }
+
+ // Defer other stuff to the base component for now
+ return super.invokeOperation(name, parameters);
+ }
+}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/JmsComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/JmsComponent.java
index d0d3eee..951430c 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/JmsComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/JmsComponent.java
@@ -32,7 +32,6 @@ import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.domain.configuration.definition.PropertyDefinitionList;
import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
-import org.rhq.core.domain.configuration.definition.PropertySimpleType;
import org.rhq.core.domain.resource.CreateResourceStatus;
import org.rhq.core.pluginapi.inventory.CreateResourceReport;
import org.rhq.modules.plugins.jbossas7.json.ComplexResult;
@@ -43,7 +42,7 @@ import org.rhq.modules.plugins.jbossas7.json.PROPERTY_VALUE;
* Component class for the JMS subsystem
* @author Heiko W. Rupp
*/
-public class JmsComponent extends DomainComponent {
+public class JmsComponent extends BaseComponent {
private final Log log = LogFactory.getLog(JmsComponent.class);
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASComponent.java
new file mode 100644
index 0000000..64ac2b6
--- /dev/null
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASComponent.java
@@ -0,0 +1,70 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.modules.plugins.jbossas7;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.modules.plugins.jbossas7.json.Operation;
+import org.rhq.modules.plugins.jbossas7.json.PROPERTY_VALUE;
+import org.rhq.modules.plugins.jbossas7.json.Result;
+
+/**
+ * Common stuff for the Domain
+ * @author Heiko W. Rupp
+ */
+@SuppressWarnings("unused")
+public class ManagedASComponent extends BaseComponent {
+
+ /**
+ * Get the availability of the managed AS server. We can't just check if
+ * a connection succeeds, as the check runs against the API/HostController
+ * and the managed server may still be down even if the connection succeeds.
+ * @return Availability of the managed AS instance.
+ */
+ @Override
+ public AvailabilityType getAvailability() {
+
+ if (context.getResourceType().getName().equals("JBossAS-Managed")) {
+ List<PROPERTY_VALUE> address = new ArrayList<PROPERTY_VALUE>(2);
+ String host = pluginConfiguration.getSimpleValue("domainHost","local");
+ address.add(new PROPERTY_VALUE("host",host));
+ address.add(new PROPERTY_VALUE("server-config",myServerName));
+ Operation getStatus = new Operation("read-attribute",address,"name","status");
+ Result result = null;
+ try {
+ result = connection.execute(getStatus);
+ } catch (Exception e) {
+ log.warn(e.getMessage());
+ return AvailabilityType.DOWN;
+ }
+ if (!result.isSuccess())
+ return AvailabilityType.DOWN;
+
+ String msg = result.getResult().toString();
+ if (msg.contains("STARTED"))
+ return AvailabilityType.UP;
+ else
+ return AvailabilityType.DOWN;
+ }
+
+ return super.getAvailability();
+ }
+}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASDiscovery.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASDiscovery.java
index 3946dbe..fd1b65d 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASDiscovery.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASDiscovery.java
@@ -70,7 +70,7 @@ public class ManagedASDiscovery extends AbstractBaseDiscovery
// Now we have the host controller, lets get the host.xml file
// and obtain the servers from there.
ProcessInfo processInfo = psr.getProcessInfo();
- readHostXml(processInfo,true);
+ readStandaloneOrHostXml(processInfo, true);
String hostName = findHostName();
HostPort managementHostPort = getManagementPortFromHostXml();
@@ -105,13 +105,16 @@ public class ManagedASDiscovery extends AbstractBaseDiscovery
// TODO this fails for the downed servers.
// get from the domain or other place as soon as the domain provides it.
- initLogFile(scans, serverInfo.name, config, getHomeDirFromCommandLine(processInfo.getCommandLine()));
+ String homeDir = getHomeDirFromCommandLine(processInfo.getCommandLine());
+ initLogFile(scans, serverInfo.name, config, homeDir);
+
+ String version = homeDir.substring(homeDir.lastIndexOf("-")+1);
DiscoveredResourceDetails detail = new DiscoveredResourceDetails(
discoveryContext.getResourceType(), // ResourceType
hostName + "/" + serverInfo.name, // key
serverInfo.name, // Name
- null, // TODO real version - get from Domain as soon as it is provided
+ version, // TODO get from Domain as soon as it is provided
"Managed AS 7 instance", // Description
config,
null
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ServerGroupComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ServerGroupComponent.java
index 15cb5d3..ad1109b 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ServerGroupComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ServerGroupComponent.java
@@ -23,7 +23,6 @@ import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -38,12 +37,10 @@ import org.rhq.core.domain.content.transfer.DeployPackageStep;
import org.rhq.core.domain.content.transfer.DeployPackagesResponse;
import org.rhq.core.domain.content.transfer.RemovePackagesResponse;
import org.rhq.core.domain.content.transfer.ResourcePackageDetails;
-import org.rhq.core.domain.resource.CreateResourceStatus;
import org.rhq.core.pluginapi.content.ContentContext;
import org.rhq.core.pluginapi.content.ContentFacet;
import org.rhq.core.pluginapi.content.ContentServices;
import org.rhq.core.pluginapi.inventory.CreateChildResourceFacet;
-import org.rhq.core.pluginapi.inventory.CreateResourceReport;
import org.rhq.modules.plugins.jbossas7.json.CompositeOperation;
import org.rhq.modules.plugins.jbossas7.json.Operation;
import org.rhq.modules.plugins.jbossas7.json.PROPERTY_VALUE;
@@ -55,7 +52,7 @@ import org.rhq.modules.plugins.jbossas7.json.Result;
* @author Heiko W. Rupp
*/
@SuppressWarnings("unused")
-public class ServerGroupComponent extends DomainComponent implements ContentFacet, CreateChildResourceFacet {
+public class ServerGroupComponent extends ManagedASComponent implements ContentFacet, CreateChildResourceFacet {
private static final String SUCCESS = "success";
private static final String OUTCOME = "outcome";
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASComponent.java
index 0281279..ebddf95 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASComponent.java
@@ -31,41 +31,25 @@ import org.rhq.modules.plugins.jbossas7.json.Result;
* Component class for standalone AS7 servers
* @author Heiko W. Rupp
*/
-public class StandaloneASComponent extends BaseComponent implements OperationFacet {
-
+public class StandaloneASComponent extends BaseServerComponent implements OperationFacet {
@Override
public OperationResult invokeOperation(String name,
Configuration parameters) throws Exception {
- // reload, shutdown
+ if (name.equals("start")) {
+ return startServer(Mode.STANDALONE);
+ } else if (name.equals("restart")) {
+ return restartServer(parameters, Mode.STANDALONE);
+
+ }
+
+ // reload, shutdown go to the remote server
Operation op = new Operation(name,new Address());
Result res = getASConnection().execute(op);
- OperationResult operationResult = new OperationResult();
- if (name.equals("shutdown")) {
- /*
- * Shutdown needs a special treatment, because after sending the operation, if shutdown suceeds,
- * the server connection is closed and we can't read from it. So if we get connection refused for
- * reading, this is a good sign.
- */
- if (!res.isSuccess()) {
- if (res.getThrowable() instanceof ConnectException || res.getThrowable().getMessage().equals("Connection refused"))
- operationResult.setSimpleResult("Success");
- else
- operationResult.setErrorMessage(res.getFailureDescription());
- }
- }
- else {
- if (res.isSuccess()) {
- if (res.getResult()!=null)
- operationResult.setSimpleResult(res.getResult().toString());
- else
- operationResult.setSimpleResult("-None provided by server-");
- }
- else
- operationResult.setErrorMessage(res.getFailureDescription());
- }
+ OperationResult operationResult = postProcessResult(name, res);
return operationResult;
}
+
}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/json/Address.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/json/Address.java
index ad91dac..d762485 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/json/Address.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/json/Address.java
@@ -51,6 +51,25 @@ public class Address {
path.addAll(other);
}
+ public Address(String path) {
+ this();
+ String[] components = path.split(",");
+ for (String component : components) {
+ String tmp = component.trim();
+
+ if (tmp.contains("=")) {
+ // strip / from the start of the key if it happens to be there
+ if (tmp.startsWith("/"))
+ tmp = tmp.substring(1);
+
+ String[] pair = tmp.split("=");
+ PROPERTY_VALUE valuePair = new PROPERTY_VALUE(pair[0], pair[1]);
+ this.path.add(valuePair);
+ }
+ }
+
+ }
+
public void add(String key, String value) {
path.add(new PROPERTY_VALUE(key,value));
}
diff --git a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
index c0e364d..0927693 100644
--- a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
@@ -58,6 +58,7 @@
~~ additional 'Personalities' for the kinds of servers (PM, SM, Standalone AS, Managed AS)
-->
+ <!-- TODO do we want to show the process controller at all? We have no benefit from it
<server name="ProcessController"
discovery="BaseProcessDiscovery"
class="BaseComponent"
@@ -68,27 +69,28 @@
<c:simple-property name="hostname" default="localhost" required="true"/>
<c:simple-property name="port" default="9990" type="integer" required="true"/>
- &logSources;
</plugin-configuration>
<process-scan name="ProcessController" query="process|basename|match=^java.*,arg|org.jboss.as.process-controller|match=.*"/>
- <operation name="dummyOperation">
- <!-- TODO supply parameters and return values -->
- </operation>
-
-
</server>
+ -->
<server name="HostController"
discovery="BaseProcessDiscovery"
- class="BaseComponent"
+ class="HostControllerComponent"
description="Domain controller (delegate) for this host"
>
<plugin-configuration>
- <c:simple-property name="hostname" default="localhost" required="true"/>
- <c:simple-property name="port" default="9990" type="integer" required="true"/>
+ <c:simple-property name="hostname" default="localhost" required="true" description="Host name of the domain API"/>
+ <c:simple-property name="port" default="9990" type="integer" required="true" description="Port of the domain API"/>
+ <c:simple-property name="user" type="string" description="Management user for a secured Host controller" required="false"/>
+ <c:simple-property name="password" type="password" description="Password for the management user" required="false"/>
+ <c:simple-property name="config" type="string" default="domain.xml" description="Running configuration" displayName="Configuration"/>
+ <c:simple-property name="baseDir" type="file" description="Base directory of the server installation" displayName="Base directory" readOnly="true" required="false"/>
+ <c:simple-property name="startScript" type="file" default="bin/domain.sh" description="Script used to start the server. If the path is not absolute, it is relative to the base directory"/>
+ <c:simple-property name="domainHost" type="string" readOnly="true" required="false" description="Host name within the AS7 domain"/>
&logSources;
</plugin-configuration>
@@ -96,8 +98,10 @@
<process-scan name="HostController" query="process|basename|match=^java.*,arg|org.jboss.as.host-controller|match=.*"/>
+<!-- Currently not provided by AS7
<operation name="domain:shutdown" displayName="Shutdown Domain" description="Shut this Host-/Domaincontroller down with all managed servers.">
</operation>
+-->
<operation name="server-group:add" displayName="Add ServerGroup" description="Add a server group to the Domain.">
<parameters>
@@ -146,6 +150,17 @@
</operation>
+ <operation name="start" description="Start this Host-/Domaincontroller" displayName="Start this host controller">
+ <results>
+ <c:simple-property name="operationResult" description="Outcome of the start operation"/>
+ </results>
+ </operation>
+ <operation name="shutdown" description="Stop this Host-/Domaincontroller" displayName="Shut down this host controller">
+ <results>
+ <c:simple-property name="operationResult" description="Outcome of the stop operation"/>
+ </results>
+ </operation>
+
<metric property="_internal:mgmtRequests" category="performance" dataType="measurement" defaultInterval="120000"
displayType="summary" measurementType="trendsup" description="Number of requests sent to the controller"
@@ -206,7 +221,7 @@
<resource-configuration>
<c:simple-property name="profile" description="The profile name" required="true"/>
<c:simple-property name="socket-binding-group" readOnly="false" required="true">
- <c:option-source target="resource" expression="type=SocketBindingGroup"/>
+ <c:option-source target="resource" expression="type=SocketBindingGroupDomain"/>
</c:simple-property>
<c:simple-property name="socket-binding-port-offset" required="false" defaultValue="0" type="integer"
description="The default offset to be added to the port values given by the socket binding group."/>
@@ -217,7 +232,7 @@
<server name="Host"
description="Host involved in this domain"
discovery="SubsystemDiscovery"
- class="DomainComponent"
+ class="BaseComponent"
>
<plugin-configuration>
<c:simple-property name="path" default="host" readOnly="true"/>
@@ -287,11 +302,17 @@
<server name="JBossAS7-Standalone"
discovery="BaseProcessDiscovery"
class="StandaloneASComponent"
+ description="Standalone AS7 server"
>
<plugin-configuration>
<c:simple-property name="hostname" default="localhost" required="true"/>
<c:simple-property name="port" default="9990" type="integer" required="true"/>
+ <c:simple-property name="user" type="string" description="Management user for a secured AS" required="false"/>
+ <c:simple-property name="password" type="password" description="Password for the management user" required="false"/>
+ <c:simple-property name="config" type="string" default="standalone.xml" description="Running configuration" displayName="Configuration"/>
+ <c:simple-property name="baseDir" type="file" description="Base directory of the server installation" displayName="Base directory" readOnly="true" required="false"/>
+ <c:simple-property name="startScript" type="file" default="bin/standalone.sh" description="Script used to start the server. If the path is not absolute, it is relative to the base directory"/>
<c:list-property name="system-properties">
<c:map-property name="system-property">
<c:simple-property name="key" readOnly="true"/>
@@ -303,7 +324,18 @@
<process-scan name="StandaloneAS" query="process|basename|match=^java.*,arg|org.jboss.as.standalone|match=.*"/>
- <operation name="reload" description="Make the server load the (changed) configuration." displayName="Reload">
+
+ <operation name="reload" description="Make the server re-load the (changed) configuration. To load a different startup config use 'restart'" displayName="Reload">
+ <results>
+ <c:simple-property name="operationResult"/>
+ </results>
+ </operation>
+ <operation name="start" description="Start the server by invoking its start script">
+ <results>
+ <c:simple-property name="operationResult"/>
+ </results>
+ </operation>
+ <operation name="restart" description="Restart the server by shutting it down and invoking its start script">
<results>
<c:simple-property name="operationResult"/>
</results>
@@ -353,14 +385,14 @@
<server name="JBossAS-Managed"
discovery="ManagedASDiscovery"
- class="DomainComponent"
+ class="ManagedASComponent"
>
<plugin-configuration>
<c:simple-property name="hostname" default="localhost" displayName="Management host" required="true"/>
<c:simple-property name="port" default="9990" type="integer" displayName="Management port" required="true"/>
<c:simple-property name="domainHost" readOnly="true" description="Hostname in the domain"/>
<c:simple-property name="group" readOnly="true" displayName="Server Group" description="Server Group this instance belongs to."/>
- <c:simple-property name="socket-binding-group" readOnly="true" displayName="Socket binding group" description="Socket bindngs to use"/>
+ <c:simple-property name="socket-binding-group" readOnly="true" displayName="Socket binding group" description="Socket bindings to use"/>
<c:simple-property name="socket-binding-port-offset" readOnly="true" displayName="Port Offset" type="integer" default="0" description="Offset to the base ports"/>
<c:simple-property name="path" readOnly="true" />
@@ -412,7 +444,7 @@
<server name="Messaging"
discovery="SubsystemDiscovery"
- class="DomainComponent"
+ class="BaseComponent"
description="The underlying HornetQ based messaging subsystem"
singleton="true"
>
@@ -1792,8 +1824,8 @@ working area for individual server instances</li></ul>"/>
<c:list-property name="includes" required="false">
<c:simple-property name="includes" displayName="Included bindings" description="Other bindings that are included in this one (only needed in Domain Mode)"/>
</c:list-property>
- <c:group name="children:socket.binding">
- <c:list-property name="socket-binding">
+ <c:group name="children:socket-binding:name" displayName="Individual socket bindings">
+ <c:list-property name="*">
<c:map-property name="binding">
<c:simple-property name="name" description="The name of the socket. Services which need to access the socket configuration information will find it using this name." readOnly="true"/>
<c:simple-property name="interface" description="Name of the interface to which the socket should be bound, or, for multicast sockets, the interface on which it should listen. This should be one of the declared interfaces."
commit ae90811cb167e8e8c20cb4677fe1e7580714db51
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Mon Jul 25 17:25:23 2011 +0200
BZ 725417 - if the 'default' attribute is missing on a required property, throw a descriptive exception instead of a NPE.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/PluginConfigurationMetadataManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/PluginConfigurationMetadataManagerBean.java
index 9b2d1db..3963f9d 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/PluginConfigurationMetadataManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/PluginConfigurationMetadataManagerBean.java
@@ -106,8 +106,14 @@ public class PluginConfigurationMetadataManagerBean implements PluginConfigurati
for (PropertyDefinition propertyDef : updateReport.getNewPropertyDefinitions()) {
if (propertyDef.isRequired()) {
Property templateProperty = templateConfiguration.get(propertyDef.getName());
- pluginConfiguration.put(templateProperty.deepCopy(false));
- modified = true;
+ if (templateProperty==null) {
+ throw new IllegalArgumentException("The property [" + propertyDef.getName()
+ + "] marked as required in the configuration definition of [" + propertyDef.getConfigurationDefinition().getName()
+ + "] has no attribute 'default'");
+ } else {
+ pluginConfiguration.put(templateProperty.deepCopy(false));
+ modified = true;
+ }
}
}
commit e194ab53e5b63d1c17e67d370a65c29fb8b17efe
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Mon Jul 25 07:54:06 2011 +0200
Extract the deploy-to-server-magic from createChild() and add tests to use this extracted code to deploy to domain and server-group.
diff --git a/modules/integration-tests/jboss-as-7-plugin-test/src/test/java/org/rhq/modules/integrationTests/jbossas7plugin/UploadAndDeployTest.java b/modules/integration-tests/jboss-as-7-plugin-test/src/test/java/org/rhq/modules/integrationTests/jbossas7plugin/UploadAndDeployTest.java
index 8581ada..2010640 100644
--- a/modules/integration-tests/jboss-as-7-plugin-test/src/test/java/org/rhq/modules/integrationTests/jbossas7plugin/UploadAndDeployTest.java
+++ b/modules/integration-tests/jboss-as-7-plugin-test/src/test/java/org/rhq/modules/integrationTests/jbossas7plugin/UploadAndDeployTest.java
@@ -26,7 +26,17 @@ import java.util.Map;
import org.codehaus.jackson.JsonNode;
import org.testng.annotations.Test;
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.content.PackageDetailsKey;
+import org.rhq.core.domain.content.transfer.ResourcePackageDetails;
+import org.rhq.core.domain.resource.CreateResourceStatus;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.pluginapi.inventory.CreateResourceReport;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.modules.plugins.jbossas7.ASConnection;
+import org.rhq.modules.plugins.jbossas7.BaseComponent;
+import org.rhq.modules.plugins.jbossas7.json.Address;
import org.rhq.modules.plugins.jbossas7.json.CompositeOperation;
import org.rhq.modules.plugins.jbossas7.json.Operation;
import org.rhq.modules.plugins.jbossas7.json.PROPERTY_VALUE;
@@ -292,7 +302,7 @@ public class UploadAndDeployTest extends AbstractIntegrationTest {
/**
* Test uploading to domain only, but not to a server group
- * @throws Exception
+ * @throws Exception if anything goes wrong.
*/
@Test(timeOut = 60*1000L,enabled = isEnabled)
public void testUploadComposite2() throws Exception {
@@ -346,4 +356,77 @@ public class UploadAndDeployTest extends AbstractIntegrationTest {
}
+ /**
+ * Test the real API code for uploading - case 1: just upload to /deployment
+ * @throws Exception if anything goes wrong.
+ */
+ @Test
+ public void testUploadViaCreateChild1() throws Exception {
+
+ BaseComponent bc = new BaseComponent();
+ bc.setConnection(getASConnection());
+ bc.setPath("");
+ ResourceType rt = new ResourceType();
+ rt.setName("Deployment");
+ Resource resource = new Resource("deployment="+TEST_WAR,TEST_WAR,rt); // TODO resource key?
+ ResourceContext context = new ResourceContext(resource,null,null,null,null,null,null,null,null,null,null,null);
+ bc.start(context);
+
+ String bytes_value = uploadToAs(TEST_WAR);
+
+ ResourcePackageDetails details = new ResourcePackageDetails(new PackageDetailsKey(TEST_WAR,"1.0","deployment","all"));
+ CreateResourceReport report = new CreateResourceReport(TEST_WAR,rt,new Configuration(), new Configuration(),details);
+ try {
+ report = bc.runDeploymentMagicOnServer(report,TEST_WAR,TEST_WAR,bytes_value);
+ assert report != null;
+ assert report.getErrorMessage()==null: "Report contained an unexpected error: " + report.getErrorMessage();
+ assert report.getStatus()!=null : "Report did not contain a status";
+ assert report.getStatus()== CreateResourceStatus.SUCCESS : "Status was no success";
+ assert report.getResourceName().equals(TEST_WAR);
+ assert report.getResourceKey().equals("deployment=" + TEST_WAR);
+ } finally {
+ Remove r =new Remove("deployment",TEST_WAR);
+ getASConnection().execute(r);
+ }
+
+ }
+
+ /**
+ * Test the real API code for uploading - case 2: upload to /deployment and a server group
+ * @throws Exception if anything goes wrong.
+ */
+ @Test
+ public void testUploadViaCreateChild2() throws Exception {
+
+ BaseComponent bc = new BaseComponent();
+ bc.setConnection(getASConnection());
+ bc.setPath("server-group=main-server-group");
+ ResourceType rt = new ResourceType();
+ rt.setName("Deployment");
+ Resource resource = new Resource("server-group=main-server-group",TEST_WAR,rt);
+ ResourceContext context = new ResourceContext(resource,null,null,null,null,null,null,null,null,null,null,null);
+ bc.start(context);
+
+ String bytes_value = uploadToAs(TEST_WAR);
+
+ ResourcePackageDetails details = new ResourcePackageDetails(new PackageDetailsKey(TEST_WAR,"1.0","deployment","all"));
+ CreateResourceReport report = new CreateResourceReport(TEST_WAR,rt,new Configuration(), new Configuration(),details);
+ try {
+ report = bc.runDeploymentMagicOnServer(report,TEST_WAR,TEST_WAR,bytes_value);
+ assert report != null;
+ assert report.getErrorMessage()==null: "Report contained an unexpected error: " + report.getErrorMessage();
+ assert report.getStatus()!=null : "Report did not contain a status";
+ assert report.getStatus()== CreateResourceStatus.SUCCESS : "Status was no success";
+ assert report.getResourceName().equals(TEST_WAR);
+ assert report.getResourceKey().equals("server-group=main-server-group,deployment=" + TEST_WAR) : "Resource key was wrong";
+ } finally {
+ Address sgd = new Address("server-group","main-server-group");
+ sgd.add("deployment", TEST_WAR);
+ Remove r =new Remove(sgd);
+ getASConnection().execute(r);
+ r =new Remove("deployment",TEST_WAR);
+ getASConnection().execute(r);
+ }
+
+ }
}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
index 83b221b..8851706 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
@@ -331,18 +331,34 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
fileName=fileName.substring("C:\\fakepath\\".length());
}
- boolean toServerGroup = context.getResourceKey().contains("server-group=");
- log.info("Deploying [" + fileName + "] to domain only= " + !toServerGroup + " ...");
String tmpName = fileName; // TODO figure out the tmp-name biz with the AS guys
JsonNode resultNode = uploadResult.get("result");
String hash = resultNode.get("BYTES_VALUE").getTextValue();
+ return runDeploymentMagicOnServer(report, fileName, tmpName, hash);
+
+ }
+
+ /**
+ * Do the actual fumbling with the domain api to deploy the uploaded content
+ * @param report CreateResourceReport to report the result
+ * @param runtimeName File name to use as runtime name
+ * @param deploymentName Name of the deployment
+ * @param hash Hash of the content bytes
+ * @return the passed report with success or failure settings
+ */
+ public CreateResourceReport runDeploymentMagicOnServer(CreateResourceReport report, String runtimeName,
+ String deploymentName, String hash) {
+
+ boolean toServerGroup = context.getResourceKey().contains("server-group=");
+ log.info("Deploying [" + runtimeName + "] to domain only= " + !toServerGroup + " ...");
+
ASConnection connection = getASConnection();
- Operation step1 = new Operation("add","deployment",tmpName);
+ Operation step1 = new Operation("add","deployment",deploymentName);
// step1.addAdditionalProperty("hash", new PROPERTY_VALUE("BYTES_VALUE", hash));
List<Object> content = new ArrayList<Object>(1);
Map<String,Object> contentValues = new HashMap<String,Object>();
@@ -350,8 +366,8 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
content.add(contentValues);
step1.addAdditionalProperty("content",content);
- step1.addAdditionalProperty("name", tmpName);
- step1.addAdditionalProperty("runtime-name", fileName);
+ step1.addAdditionalProperty("name", deploymentName);
+ step1.addAdditionalProperty("runtime-name", runtimeName);
String resourceKey;
Result result ;
@@ -379,7 +395,7 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
List<PROPERTY_VALUE> serverGroupAddress = new ArrayList<PROPERTY_VALUE>();
serverGroupAddress.addAll(pathToAddress(context.getResourceKey()));
- serverGroupAddress.add(new PROPERTY_VALUE("deployment", tmpName));
+ serverGroupAddress.add(new PROPERTY_VALUE("deployment", deploymentName));
Operation step2 = new Operation("add",serverGroupAddress);
cop.addStep(step2);
@@ -403,13 +419,12 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
}
else {
report.setStatus(CreateResourceStatus.SUCCESS);
- report.setResourceName(fileName);
+ report.setResourceName(runtimeName);
report.setResourceKey(resourceKey);
log.info(" ... with success and key [" + resourceKey + "]" );
}
return report;
-
}
@Override
commit f1b3ecdcd88a1dca8e39236caca260f51a100311
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Thu Jul 28 15:44:35 2011 +0200
BZ 726378 - management port settings on AS7 were not honored.
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
index 322e453..9aa9db0 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
@@ -111,12 +111,15 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
this.context = context;
pluginConfiguration = context.getPluginConfiguration();
- String typeName = context.getResourceType().getName();
- // TODO can we use parent's connection and only set this up for top level base component?
- host = pluginConfiguration.getSimpleValue("hostname", LOCALHOST);
- String portString = pluginConfiguration.getSimpleValue("port", DEFAULT_HTTP_MANAGEMENT_PORT);
- port = Integer.parseInt(portString);
- connection = new ASConnection(host,port);
+ if (!(context.getParentResourceComponent() instanceof BaseComponent)) {
+ host = pluginConfiguration.getSimpleValue("hostname", LOCALHOST);
+ String portString = pluginConfiguration.getSimpleValue("port", DEFAULT_HTTP_MANAGEMENT_PORT);
+ port = Integer.parseInt(portString);
+ connection = new ASConnection(host,port);
+ }
+ else {
+ connection = ((BaseComponent)context.getParentResourceComponent()).getASConnection();
+ }
path = pluginConfiguration.getSimpleValue("path", null);
key = context.getResourceKey();
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java
index 475fd62..471fd42 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java
@@ -79,11 +79,8 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
String psName = psr.getProcessScan().getName();
String description = discoveryContext.getResourceType().getDescription();
String version = null;
- String startScript;
- if (psName.equals("ProcessController")) {
- serverNameFull = "ProcessController";
- serverName = "ProcessController";
- } else if (psName.equals("HostController")) {
+
+ if (psName.equals("HostController")) {
readStandaloneOrHostXml(psr.getProcessInfo(), true);
HostPort hp = getDomainControllerFromHostXml();
if (hp.isLocal) {
@@ -118,11 +115,10 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
tmp = tmp.substring( i + 8);
tmp = tmp.substring(0,tmp.indexOf("/"));
serverNameFull = tmp;
-
- String host = findHost(psr.getProcessInfo(),true);
- config.put(new PropertySimple("domainHost",host));
-
}
+ String host = findHost(psr.getProcessInfo(),true);
+ config.put(new PropertySimple("domainHost",host));
+
config.put(new PropertySimple("baseDir",serverNameFull));
serverName = findHostName();
if (serverName.isEmpty())
@@ -139,6 +135,11 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
}
String logFile = getLogFileFromCommandLine(commandLine);
initLogEventSourcesConfigProp(logFile,config);
+
+ HostPort managmentPort = getManagementPortFromHostXml();
+ config.put(new PropertySimple("hostname",managmentPort.host));
+ config.put(new PropertySimple("port",managmentPort.port));
+
// String javaClazz = psr.getProcessInfo().getName();
commit d46c2fc9b284b6c4d8d1ef50d098f495a4ae9a50
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Thu Jul 28 13:17:00 2011 +0200
Initial support for messaging (JMS)
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
index 776e5ef..322e453 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
@@ -23,6 +23,8 @@ import org.apache.commons.logging.LogFactory;
import org.codehaus.jackson.JsonNode;
import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.Property;
+import org.rhq.core.domain.configuration.PropertyList;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
@@ -480,12 +482,34 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
} else if (what.equals("destination")) {
address.addAll(pathToAddress(getPath()));
String newName = parameters.getSimpleValue("name","");
-// String type = parameters.getSimpleValue("type","Queue").toLowerCase();
-// address.add(new PROPERTY_VALUE(type,newName));
- String queueName = parameters.getSimpleValue("queue-address","");
- Map<String,Object> props = new HashMap<String, Object>();
- props.put("queue-address",queueName);
+ String type = parameters.getSimpleValue("type","jms-queue").toLowerCase();
+ address.add(new PROPERTY_VALUE(type,newName));
+ PropertyList jndiNamesProp = parameters.getList("entries");
+ if (jndiNamesProp==null || jndiNamesProp.getList().isEmpty()) {
+ OperationResult fail = new OperationResult();
+ fail.setErrorMessage("No jndi bindings given");
+ return fail;
+ }
+ List<String> jndiNames = new ArrayList<String>();
+ for (Property p : jndiNamesProp.getList()) {
+ PropertySimple ps = (PropertySimple) p;
+ jndiNames.add(ps.getStringValue());
+ }
+
operation = new Operation(op,address);
+ operation.addAdditionalProperty("entries",jndiNames);
+ if (type.equals("jms-queue")) {
+ PropertySimple ps = (PropertySimple) parameters.get("durable");
+ if (ps!=null) {
+ boolean durable = ps.getBooleanValue();
+ operation.addAdditionalProperty("durable",durable);
+ }
+ String selector = parameters.getSimpleValue("selector","");
+ if (!selector.isEmpty())
+ operation.addAdditionalProperty("selector",selector);
+ }
+
+
} else if (what.equals("managed-server")) {
String chost = parameters.getSimpleValue("hostname","");
String serverName = parameters.getSimpleValue("servername","");
diff --git a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
index 6a8698e..20395e0 100644
--- a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
@@ -444,7 +444,7 @@
<server name="Messaging"
discovery="SubsystemDiscovery"
class="BaseComponent"
- description="The underlying HornetQ based messaging subsystem"
+ description="The HornetQ based messaging subsystem"
singleton="true"
>
<runs-inside>
@@ -459,15 +459,16 @@
<operation name="destination:add" displayName="Add destination" description="Add a Queue or Topic">
<parameters>
<c:simple-property name="name" description="Name of the Destination" required="true"/>
- <c:simple-property name="queue-address" description="The queue address defines what address is used for routing messages." required="true"/>
+ <c:list-property name="entries" description="The JNDI names the destination should be bound to." required="true">
+ <c:simple-property name="entry" description="A single JNDI name. Note, this is relative to java:jboss/jms/"/>
+ </c:list-property>
<c:simple-property name="type" description="Type of Destination to create" default="Queue">
<c:property-options>
- <c:option value="Queue"/>
- <c:option value="Topic"/>
+ <c:option value="jms-queue" name="Queue"/>
+ <c:option value="jms-topic" name="Topic"/>
</c:property-options>
</c:simple-property>
- <c:simple-property name="filter" description="The queue message filter definition."/>
- <c:simple-property name="durable" description="Defines whether the queue is durable." type="boolean" default="false"/>
+ <c:simple-property name="durable" description="Defines whether the queue is durable (for Queues only)." type="boolean" default="false"/>
</parameters>
<results>
<c:simple-property name="operationResult"/>
@@ -487,73 +488,23 @@
<c:simple-property name="journal-type" />
</resource-configuration>
- <!-- this is no child resource TODO
-
- <service name="Acceptor"
- discovery="SubsystemDiscovery"
- class="BaseComponent"
- >
- <plugin-configuration>
- <c:simple-property name="path" readOnly="true" default="acceptor"/>
- </plugin-configuration>
- </service>
- <service name="MessagingConnector"
- discovery="SubsystemDiscovery"
- class="BaseComponent"
- >
- <plugin-configuration>
- <c:simple-property name="path" readOnly="true" default="connector"/>
- </plugin-configuration>
- </service>
- <service name="HQueue"
- discovery="SubsystemDiscovery"
- class="BaseComponent"
- >
- <plugin-configuration>
- <c:simple-property name="path" readOnly="true" default="queue"/>
- </plugin-configuration>
- <resource-configuration>
- <c:simple-property name="queue-address" required="true"/>
- <c:simple-property name="filter" />
- <c:simple-property name="durable" type="boolean"/>
- </resource-configuration>
-
- </service>
--->
- </server>
-
- <server name="JMS"
- discovery="SubsystemDiscovery"
- class="JmsComponent"
- description="The JMS messaging subsystem"
- singleton="true"
- >
- <runs-inside>
- <parent-resource-type name="Profile" plugin="jboss-as-7"/>
- <parent-resource-type name="JBossAS7-Standalone" plugin="jboss-as-7"/>
- </runs-inside>
-
- <plugin-configuration>
- <c:simple-property name="path" readOnly="true" default="subsystem=jms"/>
- </plugin-configuration>
-
- <service name="Queue"
+ <service name="JMS Queue"
discovery="SubsystemDiscovery"
class="JmsComponent"
- createDeletePolicy="both"
+ createDeletePolicy="delete-only"
>
<plugin-configuration>
- <c:simple-property name="path" readOnly="true" default="queue"/>
+ <c:simple-property name="path" readOnly="true" default="jms-queue"/>
</plugin-configuration>
<resource-configuration> <!-- See BZ 705713 TODO -->
- <c:simple-property name="durable" required="false" type="boolean" readOnly="false" default="false"
+ <c:simple-property name="durable" required="false" type="boolean" readOnly="true" default="false"
description="Whether the queue is durable or not."/>
- <c:list-property name="entries" required="false" readOnly="false"
+ <c:list-property name="entries" required="false" readOnly="true"
description="The jndi names the queue will be bound to.">
<c:simple-property name="entries" type="string"/>
</c:list-property>
- <c:simple-property name="selector" required="false" type="string" readOnly="false" description="The queue selector."/>
+ <c:simple-property name="selector" required="false" type="string" readOnly="true" description="The queue selector."/>
<c:template name="add" description="Properties when adding a new queue" >
<c:simple-property name="durable" required="false" type="boolean" default="false"
description="Whether the queue is durable or not."/>
@@ -565,16 +516,16 @@
</c:template>
</resource-configuration>
</service>
- <service name="Topic"
+ <service name="JMS Topic"
discovery="SubsystemDiscovery"
class="JmsComponent"
- createDeletePolicy="both"
+ createDeletePolicy="delete-only"
>
<plugin-configuration>
- <c:simple-property name="path" readOnly="true" default="topic"/>
+ <c:simple-property name="path" readOnly="true" default="jms-topic"/>
</plugin-configuration>
<resource-configuration> <!-- See BZ 705713 TODO -->
- <c:list-property name="entries" required="false" readOnly="false"
+ <c:list-property name="entries" required="false" readOnly="true"
description="The jndi names the queue will be bound to.">
<c:simple-property name="entries" type="string"/>
</c:list-property>
commit 23f8cf9f8417f0780b4019b885f9271288ecda05
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Tue Jul 26 22:29:16 2011 +0200
Add more properties for JBossWeb. Unfortunately they are read-only in AS7
Follow :read-resource output, as the resource description from AS7 is not up to date.
diff --git a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
index d9f79d1..6a8698e 100644
--- a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
@@ -614,6 +614,78 @@
<c:simple-property name="path" readOnly="true" default="subsystem=web"/>
</plugin-configuration>
+ <resource-configuration>
+ <c:simple-property name="default-virtual-server" required="false" type="string" readOnly="true" defaultValue="localhost"
+ description="The web container's default virtual server."/>
+ <c:simple-property name="native" required="false" type="boolean" readOnly="true" defaultValue="true"
+ description="Add the native initialization listener to the web container."/>
+ <c:map-property name="configuration" description="The common web container configuration." >
+ <c:map-property name="static-resources" description="Configuration for static resources" >
+ <c:simple-property name="listings" required="false" type="boolean" readOnly="true" defaultValue="false"
+ description="Enable folder listings."/>
+ <c:simple-property name="sendfile" required="false" type="integer" readOnly="true" defaultValue="49152"
+ description="Enable sendfile if possible, for files bigger than the specified byte size."/>
+ <c:simple-property name="read-only" required="false" type="boolean" readOnly="true" defaultValue="true"
+ description="Allow write HTTP methods (PUT, DELETE)."/>
+ <c:simple-property name="webdav" required="false" type="boolean" readOnly="true" defaultValue="false"
+ description="Enable WebDAV functionality."/>
+ <c:simple-property name="secret" required="false" type="string" readOnly="true" description="Secret for WebDAV locking operations."/>
+ <c:simple-property name="max-depth" required="false" type="integer" readOnly="true" defaultValue="3"
+ description="Maximum recursion for PROPFIND."/>
+ <c:simple-property name="disabled" required="false" type="boolean" readOnly="true" defaultValue="false"
+ description="Enable the JSP container."/>
+ </c:map-property>
+ <c:map-property name="jsp-configuration" description="JSP container configuration">
+ <c:simple-property name="development" required="false" type="boolean" readOnly="true" defaultValue="false"
+ description="Enable the development mode, which gives more information when an error occurs."/>
+ <c:simple-property name="file-encoding" required="false" type="string" readOnly="true" description="Force a file encoding."/>
+ <c:simple-property name="keep-generated" required="false" type="boolean" readOnly="true" defaultValue="true"
+ description="Keep the generated Servlets."/>
+ <c:simple-property name="trim-spaces" required="false" type="boolean" readOnly="true" defaultValue="true"
+ description="Trim some spaces from the generated Servlet."/>
+ <c:simple-property name="tag-pooling" required="false" type="boolean" readOnly="true" defaultValue="true"
+ description="Enable tag pooling."/>
+ <c:simple-property name="mapped-file" required="false" type="boolean" readOnly="true" defaultValue="true"
+ description="Map to the JSP source."/>
+ <c:simple-property name="check-interval" required="false" type="integer" readOnly="true" defaultValue="0"
+ description="Check interval for JSP updates using a background thread."/>
+ <c:simple-property name="modification-test-interval" required="false" type="integer" readOnly="true" defaultValue="4"
+ description="Minimum amount of time between two tests for updates, in seconds."/>
+ <c:simple-property name="recompile-on-fail" required="false" type="boolean" readOnly="true" defaultValue="false"
+ description="Retry failed JSP compilations on each request."/>
+ <c:simple-property name="smap" required="false" type="boolean" readOnly="true" defaultValue="false"
+ description="Enable SMAP."/>
+ <c:simple-property name="dump-smap" required="false" type="boolean" readOnly="true" defaultValue="false"
+ description="Write SMAP data to a file."/>
+ <c:simple-property name="generate-strings-as-char-arrays" required="false" type="boolean" readOnly="true"
+ defaultValue="false"
+ description="Generate String constants as char arrays."/>
+ <c:simple-property name="error-on-use-bean-invalid-class-attribute" required="false" type="boolean" readOnly="true" defaultValue="false"
+ description="Enable errors when using a bad class in useBean."/>
+ <c:simple-property name="scratch-dir" required="false" type="string" readOnly="true" description="Specify a different work directory."/>
+ <c:simple-property name="source-vm" required="false" type="string" readOnly="true" defaultValue="1.5"
+ description="Source VM level for compilation."/>
+ <c:simple-property name="target-vm" required="false" type="string" readOnly="true" defaultValue="1.5"
+ description="Target VM level for compilation."/>
+ <c:simple-property name="java-encoding" required="false" type="string" readOnly="true" defaultValue="UTF-8"
+ description="Specify the encoding used for Java sources."/>
+ <c:simple-property name="x-powered-by" required="false" type="boolean" readOnly="true" defaultValue="true"
+ description="Enable advertising the JSP engine in x-powered-by."/>
+ <c:simple-property name="display-source-fragment" required="false" type="boolean" readOnly="true" defaultValue="true"
+ description="When a runtime error occurs, attempts to display corresponding JSP source fragment."/>
+ </c:map-property>
+ <c:list-property name="mime-mapping" description="A mime-mapping definition." >
+ <c:map-property name="mime-mapping" >
+ <c:simple-property name="name" description="A MIME mapping name"/>
+ <c:simple-property name="value" description="A MIME mapping value"/>
+ </c:map-property>
+ </c:list-property>
+ <c:list-property name="welcome-file" description="A welcome file declaration." >
+ <c:simple-property name="welcome-file" />
+ </c:list-property>
+ </c:map-property>
+ </resource-configuration>
+
<service name="Connector"
discovery="SubsystemDiscovery"
class="BaseComponent"
commit 13e821f0b60a26e6a4ea55cd8bacd523968d90f6
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Wed Jul 27 09:18:58 2011 +0200
Get rid of the explicit version number and let maven do the magic.
diff --git a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
index 0927693..d9f79d1 100644
--- a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
@@ -48,7 +48,6 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration"
- version="4.0.0-SNAPSHOT"
>
<!-- <depends plugin="JMX" useClasses="true"/> -->
commit 0eb50dd5314086d110af46d614e3f607c1c1aac3
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Wed Jul 27 11:18:39 2011 +0200
Log the property being null and don't pollute stdout.
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationLoadDelegate.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationLoadDelegate.java
index e978962..c999be6 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationLoadDelegate.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationLoadDelegate.java
@@ -269,8 +269,10 @@ public class ConfigurationLoadDelegate implements ConfigurationFacet {
if (property!=null)
propertyMap.put(property);
- else
- System.out.println("Property " + key + " was null");
+ else {
+ if (log.isDebugEnabled())
+ log.debug("Property " + key + " was null");
+ }
}
commit 43a1577fe5b8de22132fc2dbe3d2f58fb92a06d2
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Mon Jul 25 18:00:50 2011 +0200
Provide more connection properties for standalone servers as well as the version. Add start and restart operations for standalone servers.
Read the running instance name (i.e. standalone server name) from standalone.xml
Allow to start a domain/host controller.
Allow to shut down hosts in a domain.
Allow to shut down host controllers. Revert the ability to shutdown hosts - this needs to be done at HC level.
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/AbstractBaseDiscovery.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/AbstractBaseDiscovery.java
index 63a4e45..c089b79 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/AbstractBaseDiscovery.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/AbstractBaseDiscovery.java
@@ -46,9 +46,15 @@ public abstract class AbstractBaseDiscovery<T extends ResourceComponent> impleme
protected Document hostXml;
protected final Log log = LogFactory.getLog(this.getClass());
-// private final Log log = LogFactory.getLog(AbstractBaseDiscovery.class);
- protected void readHostXml(ProcessInfo processInfo,boolean isDomainMode) {
+ /**
+ * Read the host.xml or standalone.xml file depending on isDomainMode. If isDomainMode is true,
+ * host.xml is read, otherwise standalone.xml.
+ * The xml file content is stored in the variable hostXml for future use.
+ * @param processInfo Process info to determine the base file location
+ * @param isDomainMode Indiates if host.xml should be read (true) or standalone.xml (false)
+ */
+ protected void readStandaloneOrHostXml(ProcessInfo processInfo, boolean isDomainMode) {
String hostXmlFile = getHostXmlFileLocation(processInfo,isDomainMode);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
@@ -61,7 +67,11 @@ public abstract class AbstractBaseDiscovery<T extends ResourceComponent> impleme
}
}
-
+ /**
+ * Determine the server home (=base) directory by parsing the passed command line
+ * @param commandLine command line arguments of the process
+ * @return The home dir if found or empty string otherwise
+ */
String getHomeDirFromCommandLine(String[] commandLine) {
for (String line: commandLine) {
if (line.startsWith(DJBOSS_SERVER_HOME_DIR))
@@ -70,6 +80,11 @@ public abstract class AbstractBaseDiscovery<T extends ResourceComponent> impleme
return "";
}
+ /**
+ * Determine the location of the boot log file of the server by parsing the command line
+ * @param commandLine command line arguments of the process
+ * @return The log file location or empty string otherwise
+ */
String getLogFileFromCommandLine(String[] commandLine) {
for (String line: commandLine) {
@@ -79,7 +94,14 @@ public abstract class AbstractBaseDiscovery<T extends ResourceComponent> impleme
return "";
}
+ /**
+ * Try to obtain the management IP and port from the already parsed host.xml or standalone.xml
+ * @return an Object containing host and port
+ * @see #readStandaloneOrHostXml(org.rhq.core.system.ProcessInfo, boolean) on how to obtain the parsed xml
+ */
protected HostPort getManagementPortFromHostXml() {
+ if (hostXml==null)
+ throw new IllegalArgumentException("hostXml is null. You need to call 'readStandaloneOrHostXml' first.");
Element host = hostXml.getDocumentElement();
NodeList interfaceParent = host.getElementsByTagName("management-interfaces");
if (interfaceParent ==null || interfaceParent.getLength()==0) {
@@ -112,7 +134,15 @@ public abstract class AbstractBaseDiscovery<T extends ResourceComponent> impleme
return new HostPort();
}
+ /**
+ * Try to obtain the management interface IP from the host/standalone.xml files
+ * @param nIf Interface to look for
+ * @return IP address to use
+ */
private String getInterface(String nIf) {
+ if (hostXml==null)
+ throw new IllegalArgumentException("hostXml is null. You need to call 'readStandaloneOrHostXml' first.");
+
Element host = hostXml.getDocumentElement();
NodeList interfaceParent = host.getElementsByTagName("interfaces");
if (interfaceParent ==null || interfaceParent.getLength()==0) {
@@ -155,12 +185,26 @@ public abstract class AbstractBaseDiscovery<T extends ResourceComponent> impleme
return null; // TODO: Customise this generated block
}
+ /**
+ * Try to determine the host name - that is the name of a standalone server or a
+ * host in domain mode by looking at the standalone/host.xml files
+ * @return server name
+ */
protected String findHostName() {
+ if (hostXml==null)
+ throw new IllegalArgumentException("hostXml is null. You need to call 'readStandaloneOrHostXml' first.");
+
String hostName = hostXml.getDocumentElement().getAttribute("name");
return hostName;
}
+ /**
+ * Try to obtain the domain controller's location from looking at host.xml
+ * @return host and port of the domain controller
+ */
protected HostPort getDomainControllerFromHostXml() {
+ if (hostXml==null)
+ throw new IllegalArgumentException("hostXml is null. You need to call 'readStandaloneOrHostXml' first.");
Element host = hostXml.getDocumentElement();
NodeList dcParent = host.getElementsByTagName("domain-controller");
@@ -211,6 +255,9 @@ public abstract class AbstractBaseDiscovery<T extends ResourceComponent> impleme
}
+ /**
+ * Helper class that holds information about the host,port tuple
+ */
protected static class HostPort {
String host;
int port;
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
index 8851706..776e5ef 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
@@ -79,7 +79,7 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
final Log log = LogFactory.getLog(this.getClass());
ResourceContext context;
- Configuration conf;
+ Configuration pluginConfiguration;
String myServerName;
ASConnection connection;
String path;
@@ -107,16 +107,16 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
*/
public void start(ResourceContext context) throws InvalidPluginConfigurationException, Exception {
this.context = context;
- conf = context.getPluginConfiguration();
+ pluginConfiguration = context.getPluginConfiguration();
String typeName = context.getResourceType().getName();
// TODO can we use parent's connection and only set this up for top level base component?
- host = conf.getSimpleValue("hostname", LOCALHOST);
- String portString = conf.getSimpleValue("port", DEFAULT_HTTP_MANAGEMENT_PORT);
+ host = pluginConfiguration.getSimpleValue("hostname", LOCALHOST);
+ String portString = pluginConfiguration.getSimpleValue("port", DEFAULT_HTTP_MANAGEMENT_PORT);
port = Integer.parseInt(portString);
connection = new ASConnection(host,port);
- path = conf.getSimpleValue("path", null);
+ path = pluginConfiguration.getSimpleValue("path", null);
key = context.getResourceKey();
myServerName = context.getResourceKey().substring(context.getResourceKey().lastIndexOf("/")+1);
@@ -445,16 +445,15 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
List<PROPERTY_VALUE> address = new ArrayList<PROPERTY_VALUE>();
if (what.equals("server-group")) {
- String groupName = parameters.getSimpleValue("name",null);
+ String groupName = parameters.getSimpleValue("name","");
String profile = parameters.getSimpleValue("profile","default");
address.add(new PROPERTY_VALUE("server-group",groupName));
operation = new Operation(op,address,"profile",profile);
} else if (what.equals("server")) {
-
if (context.getResourceType().getName().equals("JBossAS-Managed")) {
- String host = conf.getSimpleValue("domainHost","local");
+ String host = pluginConfiguration.getSimpleValue("domainHost","local");
address.add(new PROPERTY_VALUE("host",host));
address.add(new PROPERTY_VALUE("server-config",myServerName));
operation = new Operation(op,address);
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java
index 2f71edb..475fd62 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java
@@ -18,8 +18,11 @@
*/
package org.rhq.modules.plugins.jbossas7;
+import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.List;
@@ -30,7 +33,6 @@ import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.mc4j.ems.connection.support.metadata.LocalVMTypeDescriptor;
import org.w3c.dom.Document;
import org.rhq.core.domain.configuration.Configuration;
@@ -43,8 +45,6 @@ import org.rhq.core.pluginapi.inventory.ProcessScanResult;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
import org.rhq.core.system.ProcessInfo;
-import org.rhq.plugins.jmx.JMXDiscoveryComponent;
-
/**
* Discovery class
@@ -53,9 +53,10 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
{
- static final String DJBOSS_SERVER_BASE_DIR = "-Djboss.server.base.dir=";
+ static final String DJBOSS_HOME_DIR = "-Djboss.home.dir=";
static final String DORG_JBOSS_BOOT_LOG_FILE = "-Dorg.jboss.boot.log.file=";
static final String DLOGGING_CONFIGURATION = "-Dlogging.configuration=";
+ static final String DASH_DASH_SERVER_CONFIG = "--server-config=";
private final Log log = LogFactory.getLog(this.getClass());
/**
@@ -77,11 +78,13 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
String serverName;
String psName = psr.getProcessScan().getName();
String description = discoveryContext.getResourceType().getDescription();
+ String version = null;
+ String startScript;
if (psName.equals("ProcessController")) {
serverNameFull = "ProcessController";
serverName = "ProcessController";
} else if (psName.equals("HostController")) {
- readHostXml(psr.getProcessInfo(),true);
+ readStandaloneOrHostXml(psr.getProcessInfo(), true);
HostPort hp = getDomainControllerFromHostXml();
if (hp.isLocal) {
serverName = "DomainController";
@@ -92,11 +95,20 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
serverName = "HostController";
serverNameFull = "HostController";
}
- config.put(new PropertySimple("homedir",getHomeDirFromCommandLine(psr.getProcessInfo().getCommandLine())));
- // TODO add the start script
+ String homeDir = getHomeDirFromCommandLine(psr.getProcessInfo().getCommandLine());
+ config.put(new PropertySimple("baseDir", homeDir));
+ version = homeDir.substring(homeDir.lastIndexOf("-")+1);
+ config.put(new PropertySimple("startScript","bin/domain.sh"));
+ String host = findHost(psr.getProcessInfo(),true);
+ config.put(new PropertySimple("domainHost",host));
+
+ fillUserPassFromFile(config,"domain",homeDir);
+
+ // TODO provide running config
- } else {
- serverNameFull = getBaseDirFromCommandLine(commandLine);
+ } else { // Standalone server
+ serverNameFull = getHomeDirFromCommandLine(commandLine);
+ readStandaloneOrHostXml(psr.getProcessInfo(), false);
if (serverNameFull==null || serverNameFull.isEmpty()) {
// Try to obtain the server name
// -Dorg.jboss.boot.log.file=domain/servers/server-one/log/boot.log
@@ -111,10 +123,19 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
config.put(new PropertySimple("domainHost",host));
}
- serverName = serverNameFull.substring(serverNameFull.lastIndexOf("/")+1);
+ config.put(new PropertySimple("baseDir",serverNameFull));
+ serverName = findHostName();
if (serverName.isEmpty())
serverName = serverNameFull;
+ version = serverName.substring(serverName.lastIndexOf("-")+1);
+
+ String serverConfig = getServerConfigFromCommandLine(commandLine);
+ config.put(new PropertySimple("config",serverConfig));
+ config.put(new PropertySimple("startScript","bin/standalone.sh"));
+
+ fillUserPassFromFile(config,"standalone", serverNameFull);
+
}
String logFile = getLogFileFromCommandLine(commandLine);
initLogEventSourcesConfigProp(logFile,config);
@@ -139,7 +160,7 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
discoveryContext.getResourceType(), // ResourceType
serverNameFull, // key TODO distinguish per domain?
serverName, // Name
- null, // TODO real version ?
+ version, // TODO get via API ?Á
description, // Description
config,
psr.getProcessInfo()
@@ -155,6 +176,48 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
}
+ private void fillUserPassFromFile(Configuration config, String mode, String baseDir) {
+
+ String configDir = baseDir + File.separator + mode + File.separator + "configuration";
+
+ File file = new File(configDir ,"mgmt-users.properties");
+ if (!file.exists() || !file.canRead()) {
+ if (log.isDebugEnabled())
+ log.debug("No console user properties file found at [" + file.getAbsolutePath() + "] or file is not readable");
+ return;
+ }
+ BufferedReader br=null;
+ try {
+ FileReader fileReader = new FileReader(file);
+ br = new BufferedReader(fileReader);
+ String line;
+ while ((line = br.readLine())!=null) {
+ if (line.startsWith("#"))
+ continue;
+ if (line.isEmpty())
+ continue;
+ if (!line.contains("="))
+ continue;
+ // found a candidate
+ String user = line.substring(0,line.indexOf("="));
+ String pass = line.substring(line.indexOf("=")+1);
+ config.put(new PropertySimple("user",user));
+ config.put(new PropertySimple("password",pass));
+
+ }
+ } catch (IOException e) {
+ e.printStackTrace(); // TODO: Customise this generated block
+ } finally {
+ if (br!=null)
+ try {
+ br.close();
+ } catch (IOException e) {
+ // empty
+ }
+ }
+
+ }
+
private String findHost(ProcessInfo processInfo,boolean isDomain) {
String hostXmlFile = getHostXmlFileLocation(processInfo, isDomain);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
@@ -173,12 +236,13 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
return hostName;
}
- String getBaseDirFromCommandLine(String[] commandLine) {
+
+ String getServerConfigFromCommandLine(String[] commandLine) {
for (String line: commandLine) {
- if (line.startsWith(DJBOSS_SERVER_BASE_DIR))
- return line.substring(DJBOSS_SERVER_BASE_DIR.length());
+ if (line.startsWith(DASH_DASH_SERVER_CONFIG))
+ return line.substring(DASH_DASH_SERVER_CONFIG.length());
}
- return "";
+ return "standalone.xml";
}
//-Dorg.jboss.boot.log.file=/devel/jbas7/jboss-as/build/target/jboss-7.0.0.Alpha2/domain/log/server-manager/boot.log
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java
new file mode 100644
index 0000000..c8703a6
--- /dev/null
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java
@@ -0,0 +1,184 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.modules.plugins.jbossas7;
+
+import java.io.File;
+import java.net.ConnectException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.pluginapi.operation.OperationResult;
+import org.rhq.core.pluginapi.util.ProcessExecutionUtility;
+import org.rhq.core.system.ProcessExecution;
+import org.rhq.core.system.ProcessExecutionResults;
+import org.rhq.modules.plugins.jbossas7.json.Result;
+
+/**
+ * Base component for functionality that is common to Standalone AS and HostControllers
+ * @author Heiko W. Rupp
+ */
+public class BaseServerComponent extends BaseComponent {
+
+ private static final String STANDALONE_XML = "standalone.xml";
+ private static final String SEPARATOR = "\n-----------------------\n";
+ final Log log = LogFactory.getLog(BaseServerComponent.class);
+
+ /**
+ * Restart the server by first executing a 'shutdown' operation via its API. Then call
+ * the #startServer method to start it again.
+ *
+ * @param parameters Parameters to pass to the (recursive) invocation of #invokeOperation
+ * @param mode
+ * @return State of execution
+ * @throws Exception If anything goes wrong
+ */
+ protected OperationResult restartServer(Configuration parameters, Mode mode) throws Exception {
+ OperationResult tmp = invokeOperation("shutdown",parameters);
+
+ if (tmp.getErrorMessage()!=null) {
+ tmp.setErrorMessage("Restart failed while failing to shut down: " + tmp.getErrorMessage());
+ return tmp;
+ }
+ Thread.sleep(500); // Wait 0.5s -- this is plenty
+ return startServer(mode);
+ }
+
+ /**
+ * Start the server by calling the start script listed in the plugin configuration. If a different
+ * config is given, this is passed via --server-config
+ * @return State of Execution.
+ * @param mode
+ */
+ protected OperationResult startServer(Mode mode) {
+ OperationResult operationResult = new OperationResult();
+ Configuration conf = context.getPluginConfiguration();
+ String startScript = conf.getSimpleValue("startScript", mode.getStartScript());
+ String baseDir = conf.getSimpleValue("baseDir","");
+ if (baseDir.isEmpty()) {
+ operationResult.setErrorMessage("No base directory provided");
+ return operationResult;
+ }
+ String script = baseDir + File.separator + startScript;
+ String config = conf.getSimpleValue("config", mode.getXmlFile());
+
+ ProcessExecution processExecution;
+ processExecution = ProcessExecutionUtility.createProcessExecution(new File(script));
+ if (!config.equals(mode.getXmlFile())) {
+ processExecution.getArguments().add(mode.getConfigArg());
+ processExecution.getArguments().add(config);
+ }
+ processExecution.setWorkingDirectory(baseDir);
+ processExecution.setCaptureOutput(true);
+ processExecution.setWaitForCompletion(2000L); // 2 seconds // TODO: Should we wait longer than two seconds?
+ processExecution.setKillOnTimeout(false);
+
+
+ long start = System.currentTimeMillis();
+ if (log.isDebugEnabled()) {
+ log.debug("About to execute the following process: [" + processExecution + "]");
+ }
+ ProcessExecutionResults results = context.getSystemInformation().executeProcess(processExecution);
+ logExecutionResults(results);
+ if (results.getError()!=null) {
+ operationResult.setErrorMessage(results.getError().getMessage());
+ } else {
+ operationResult.setSimpleResult("Success");
+ }
+
+ return operationResult;
+
+ }
+
+ private void logExecutionResults(ProcessExecutionResults results) {
+ // Always log the output at info level. On Unix we could switch depending on a exitCode being !=0, but ...
+ log.info("Exit code from process execution: " + results.getExitCode());
+ log.info("Output from process execution: " + SEPARATOR + results.getCapturedOutput() + SEPARATOR);
+ }
+
+ /**
+ * Do some post processing of the Result - especially the 'shutdown' operation needs a special
+ * treatment.
+ * @param name Name of the operation
+ * @param res Result of the operation vs. AS7
+ * @return OperationResult filled in from values of res
+ */
+ protected OperationResult postProcessResult(String name, Result res) {
+ OperationResult operationResult = new OperationResult();
+ if (name.equals("shutdown")) {
+ /*
+ * Shutdown needs a special treatment, because after sending the operation, if shutdown suceeds,
+ * the server connection is closed and we can't read from it. So if we get connection refused for
+ * reading, this is a good sign.
+ */
+ if (!res.isSuccess()) {
+ if (res.getThrowable()!=null && (res.getThrowable() instanceof ConnectException || res.getThrowable().getMessage().equals("Connection refused")))
+ operationResult.setSimpleResult("Success");
+ else
+ operationResult.setErrorMessage(res.getFailureDescription());
+ }
+ }
+ else {
+ if (res.isSuccess()) {
+ if (res.getResult()!=null)
+ operationResult.setSimpleResult(res.getResult().toString());
+ else
+ operationResult.setSimpleResult("-None provided by server-");
+ }
+ else
+ operationResult.setErrorMessage(res.getFailureDescription());
+ }
+ return operationResult;
+ }
+
+ enum Mode {
+ STANDALONE(STANDALONE_XML,"standalone","--server-config","bin/standalone.sh"),
+ DOMAIN("domain.xml","domain", "--domain-config","bin/domain.sh"),
+ HOST("host.xml","domain", "--host-config","bin/domain.sh");
+
+ private String xmlFile;
+ private String baseDir;
+ private String configArg;
+ private String startScript;
+
+ private Mode(String xmlFile, String baseDir, String configArg, String startScript) {
+ this.xmlFile = xmlFile;
+ this.baseDir = baseDir;
+ this.configArg = configArg;
+ this.startScript = startScript;
+ }
+
+ public String getXmlFile() {
+ return xmlFile;
+ }
+
+ public String getBaseDir() {
+ return baseDir;
+ }
+
+ public String getConfigArg() {
+ return configArg;
+ }
+
+ public String getStartScript() {
+ return startScript;
+ }
+ }
+}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/DomainComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/DomainComponent.java
deleted file mode 100644
index c25fe88..0000000
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/DomainComponent.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2011 Red Hat, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-package org.rhq.modules.plugins.jbossas7;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.codehaus.jackson.JsonNode;
-
-import org.rhq.core.domain.configuration.Configuration;
-import org.rhq.core.domain.measurement.AvailabilityType;
-import org.rhq.core.pluginapi.operation.OperationFacet;
-import org.rhq.core.pluginapi.operation.OperationResult;
-import org.rhq.modules.plugins.jbossas7.json.Operation;
-import org.rhq.modules.plugins.jbossas7.json.PROPERTY_VALUE;
-import org.rhq.modules.plugins.jbossas7.json.Result;
-
-/**
- * Common stuff for the Domain
- * @author Heiko W. Rupp
- */
-@SuppressWarnings("unused")
-public class DomainComponent extends BaseComponent implements OperationFacet{
-
- @Override
- public AvailabilityType getAvailability() {
-
- if (context.getResourceType().getName().equals("JBossAS-Managed")) {
- List<PROPERTY_VALUE> address = new ArrayList<PROPERTY_VALUE>(2);
- String host = conf.getSimpleValue("domainHost","local");
- address.add(new PROPERTY_VALUE("host",host));
- address.add(new PROPERTY_VALUE("server-config",myServerName));
- Operation getStatus = new Operation("read-attribute",address,"name","status");
- Result result = null;
- try {
- result = connection.execute(getStatus);
- } catch (Exception e) {
- log.warn(e.getMessage());
- return AvailabilityType.DOWN;
- }
- if (!result.isSuccess())
- return AvailabilityType.DOWN;
-
- String msg = result.getResult().toString();
- if (msg.contains("STARTED"))
- return AvailabilityType.UP;
- else
- return AvailabilityType.DOWN;
- }
-
- return super.getAvailability(); // TODO: Customise this generated block
- }
-
-}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/HostControllerComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/HostControllerComponent.java
new file mode 100644
index 0000000..73eb0bb
--- /dev/null
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/HostControllerComponent.java
@@ -0,0 +1,64 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.modules.plugins.jbossas7;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.pluginapi.operation.OperationFacet;
+import org.rhq.core.pluginapi.operation.OperationResult;
+import org.rhq.modules.plugins.jbossas7.json.Operation;
+import org.rhq.modules.plugins.jbossas7.json.Result;
+
+/**
+ * Component class for host- and domain controller
+ * @author Heiko W. Rupp
+ */
+public class HostControllerComponent extends BaseServerComponent implements OperationFacet {
+
+ private final Log log = LogFactory.getLog(HostControllerComponent.class);
+
+ @Override
+ public OperationResult invokeOperation(String name,
+ Configuration parameters) throws InterruptedException, Exception {
+
+ if (name.equals("start")) {
+ return startServer(Mode.DOMAIN);
+ } else if (name.equals("restart")) {
+ return restartServer(parameters, Mode.DOMAIN);
+
+ } else if (name.equals("shutdown")) {
+ // This is a bit trickier, as it needs to be executed on the level on /host=xx
+ String domainHost = pluginConfiguration.getSimpleValue("domainHost","");
+ if (domainHost.isEmpty()) {
+ OperationResult result = new OperationResult();
+ result.setErrorMessage("No domain host found - can not continue");
+ return result;
+ }
+ Operation op = new Operation("shutdown","host",domainHost);
+ Result res = getASConnection().execute(op);
+
+ postProcessResult(name,res);
+ }
+
+ // Defer other stuff to the base component for now
+ return super.invokeOperation(name, parameters);
+ }
+}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/JmsComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/JmsComponent.java
index d0d3eee..951430c 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/JmsComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/JmsComponent.java
@@ -32,7 +32,6 @@ import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.domain.configuration.definition.PropertyDefinitionList;
import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
-import org.rhq.core.domain.configuration.definition.PropertySimpleType;
import org.rhq.core.domain.resource.CreateResourceStatus;
import org.rhq.core.pluginapi.inventory.CreateResourceReport;
import org.rhq.modules.plugins.jbossas7.json.ComplexResult;
@@ -43,7 +42,7 @@ import org.rhq.modules.plugins.jbossas7.json.PROPERTY_VALUE;
* Component class for the JMS subsystem
* @author Heiko W. Rupp
*/
-public class JmsComponent extends DomainComponent {
+public class JmsComponent extends BaseComponent {
private final Log log = LogFactory.getLog(JmsComponent.class);
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASComponent.java
new file mode 100644
index 0000000..64ac2b6
--- /dev/null
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASComponent.java
@@ -0,0 +1,70 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.modules.plugins.jbossas7;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.modules.plugins.jbossas7.json.Operation;
+import org.rhq.modules.plugins.jbossas7.json.PROPERTY_VALUE;
+import org.rhq.modules.plugins.jbossas7.json.Result;
+
+/**
+ * Common stuff for the Domain
+ * @author Heiko W. Rupp
+ */
+@SuppressWarnings("unused")
+public class ManagedASComponent extends BaseComponent {
+
+ /**
+ * Get the availability of the managed AS server. We can't just check if
+ * a connection succeeds, as the check runs against the API/HostController
+ * and the managed server may still be down even if the connection succeeds.
+ * @return Availability of the managed AS instance.
+ */
+ @Override
+ public AvailabilityType getAvailability() {
+
+ if (context.getResourceType().getName().equals("JBossAS-Managed")) {
+ List<PROPERTY_VALUE> address = new ArrayList<PROPERTY_VALUE>(2);
+ String host = pluginConfiguration.getSimpleValue("domainHost","local");
+ address.add(new PROPERTY_VALUE("host",host));
+ address.add(new PROPERTY_VALUE("server-config",myServerName));
+ Operation getStatus = new Operation("read-attribute",address,"name","status");
+ Result result = null;
+ try {
+ result = connection.execute(getStatus);
+ } catch (Exception e) {
+ log.warn(e.getMessage());
+ return AvailabilityType.DOWN;
+ }
+ if (!result.isSuccess())
+ return AvailabilityType.DOWN;
+
+ String msg = result.getResult().toString();
+ if (msg.contains("STARTED"))
+ return AvailabilityType.UP;
+ else
+ return AvailabilityType.DOWN;
+ }
+
+ return super.getAvailability();
+ }
+}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASDiscovery.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASDiscovery.java
index 3946dbe..fd1b65d 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASDiscovery.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASDiscovery.java
@@ -70,7 +70,7 @@ public class ManagedASDiscovery extends AbstractBaseDiscovery
// Now we have the host controller, lets get the host.xml file
// and obtain the servers from there.
ProcessInfo processInfo = psr.getProcessInfo();
- readHostXml(processInfo,true);
+ readStandaloneOrHostXml(processInfo, true);
String hostName = findHostName();
HostPort managementHostPort = getManagementPortFromHostXml();
@@ -105,13 +105,16 @@ public class ManagedASDiscovery extends AbstractBaseDiscovery
// TODO this fails for the downed servers.
// get from the domain or other place as soon as the domain provides it.
- initLogFile(scans, serverInfo.name, config, getHomeDirFromCommandLine(processInfo.getCommandLine()));
+ String homeDir = getHomeDirFromCommandLine(processInfo.getCommandLine());
+ initLogFile(scans, serverInfo.name, config, homeDir);
+
+ String version = homeDir.substring(homeDir.lastIndexOf("-")+1);
DiscoveredResourceDetails detail = new DiscoveredResourceDetails(
discoveryContext.getResourceType(), // ResourceType
hostName + "/" + serverInfo.name, // key
serverInfo.name, // Name
- null, // TODO real version - get from Domain as soon as it is provided
+ version, // TODO get from Domain as soon as it is provided
"Managed AS 7 instance", // Description
config,
null
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ServerGroupComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ServerGroupComponent.java
index 15cb5d3..ad1109b 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ServerGroupComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ServerGroupComponent.java
@@ -23,7 +23,6 @@ import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -38,12 +37,10 @@ import org.rhq.core.domain.content.transfer.DeployPackageStep;
import org.rhq.core.domain.content.transfer.DeployPackagesResponse;
import org.rhq.core.domain.content.transfer.RemovePackagesResponse;
import org.rhq.core.domain.content.transfer.ResourcePackageDetails;
-import org.rhq.core.domain.resource.CreateResourceStatus;
import org.rhq.core.pluginapi.content.ContentContext;
import org.rhq.core.pluginapi.content.ContentFacet;
import org.rhq.core.pluginapi.content.ContentServices;
import org.rhq.core.pluginapi.inventory.CreateChildResourceFacet;
-import org.rhq.core.pluginapi.inventory.CreateResourceReport;
import org.rhq.modules.plugins.jbossas7.json.CompositeOperation;
import org.rhq.modules.plugins.jbossas7.json.Operation;
import org.rhq.modules.plugins.jbossas7.json.PROPERTY_VALUE;
@@ -55,7 +52,7 @@ import org.rhq.modules.plugins.jbossas7.json.Result;
* @author Heiko W. Rupp
*/
@SuppressWarnings("unused")
-public class ServerGroupComponent extends DomainComponent implements ContentFacet, CreateChildResourceFacet {
+public class ServerGroupComponent extends ManagedASComponent implements ContentFacet, CreateChildResourceFacet {
private static final String SUCCESS = "success";
private static final String OUTCOME = "outcome";
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASComponent.java
index 0281279..ebddf95 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASComponent.java
@@ -31,41 +31,25 @@ import org.rhq.modules.plugins.jbossas7.json.Result;
* Component class for standalone AS7 servers
* @author Heiko W. Rupp
*/
-public class StandaloneASComponent extends BaseComponent implements OperationFacet {
-
+public class StandaloneASComponent extends BaseServerComponent implements OperationFacet {
@Override
public OperationResult invokeOperation(String name,
Configuration parameters) throws Exception {
- // reload, shutdown
+ if (name.equals("start")) {
+ return startServer(Mode.STANDALONE);
+ } else if (name.equals("restart")) {
+ return restartServer(parameters, Mode.STANDALONE);
+
+ }
+
+ // reload, shutdown go to the remote server
Operation op = new Operation(name,new Address());
Result res = getASConnection().execute(op);
- OperationResult operationResult = new OperationResult();
- if (name.equals("shutdown")) {
- /*
- * Shutdown needs a special treatment, because after sending the operation, if shutdown suceeds,
- * the server connection is closed and we can't read from it. So if we get connection refused for
- * reading, this is a good sign.
- */
- if (!res.isSuccess()) {
- if (res.getThrowable() instanceof ConnectException || res.getThrowable().getMessage().equals("Connection refused"))
- operationResult.setSimpleResult("Success");
- else
- operationResult.setErrorMessage(res.getFailureDescription());
- }
- }
- else {
- if (res.isSuccess()) {
- if (res.getResult()!=null)
- operationResult.setSimpleResult(res.getResult().toString());
- else
- operationResult.setSimpleResult("-None provided by server-");
- }
- else
- operationResult.setErrorMessage(res.getFailureDescription());
- }
+ OperationResult operationResult = postProcessResult(name, res);
return operationResult;
}
+
}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/json/Address.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/json/Address.java
index ad91dac..d762485 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/json/Address.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/json/Address.java
@@ -51,6 +51,25 @@ public class Address {
path.addAll(other);
}
+ public Address(String path) {
+ this();
+ String[] components = path.split(",");
+ for (String component : components) {
+ String tmp = component.trim();
+
+ if (tmp.contains("=")) {
+ // strip / from the start of the key if it happens to be there
+ if (tmp.startsWith("/"))
+ tmp = tmp.substring(1);
+
+ String[] pair = tmp.split("=");
+ PROPERTY_VALUE valuePair = new PROPERTY_VALUE(pair[0], pair[1]);
+ this.path.add(valuePair);
+ }
+ }
+
+ }
+
public void add(String key, String value) {
path.add(new PROPERTY_VALUE(key,value));
}
diff --git a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
index c0e364d..0927693 100644
--- a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
@@ -58,6 +58,7 @@
~~ additional 'Personalities' for the kinds of servers (PM, SM, Standalone AS, Managed AS)
-->
+ <!-- TODO do we want to show the process controller at all? We have no benefit from it
<server name="ProcessController"
discovery="BaseProcessDiscovery"
class="BaseComponent"
@@ -68,27 +69,28 @@
<c:simple-property name="hostname" default="localhost" required="true"/>
<c:simple-property name="port" default="9990" type="integer" required="true"/>
- &logSources;
</plugin-configuration>
<process-scan name="ProcessController" query="process|basename|match=^java.*,arg|org.jboss.as.process-controller|match=.*"/>
- <operation name="dummyOperation">
- <!-- TODO supply parameters and return values -->
- </operation>
-
-
</server>
+ -->
<server name="HostController"
discovery="BaseProcessDiscovery"
- class="BaseComponent"
+ class="HostControllerComponent"
description="Domain controller (delegate) for this host"
>
<plugin-configuration>
- <c:simple-property name="hostname" default="localhost" required="true"/>
- <c:simple-property name="port" default="9990" type="integer" required="true"/>
+ <c:simple-property name="hostname" default="localhost" required="true" description="Host name of the domain API"/>
+ <c:simple-property name="port" default="9990" type="integer" required="true" description="Port of the domain API"/>
+ <c:simple-property name="user" type="string" description="Management user for a secured Host controller" required="false"/>
+ <c:simple-property name="password" type="password" description="Password for the management user" required="false"/>
+ <c:simple-property name="config" type="string" default="domain.xml" description="Running configuration" displayName="Configuration"/>
+ <c:simple-property name="baseDir" type="file" description="Base directory of the server installation" displayName="Base directory" readOnly="true" required="false"/>
+ <c:simple-property name="startScript" type="file" default="bin/domain.sh" description="Script used to start the server. If the path is not absolute, it is relative to the base directory"/>
+ <c:simple-property name="domainHost" type="string" readOnly="true" required="false" description="Host name within the AS7 domain"/>
&logSources;
</plugin-configuration>
@@ -96,8 +98,10 @@
<process-scan name="HostController" query="process|basename|match=^java.*,arg|org.jboss.as.host-controller|match=.*"/>
+<!-- Currently not provided by AS7
<operation name="domain:shutdown" displayName="Shutdown Domain" description="Shut this Host-/Domaincontroller down with all managed servers.">
</operation>
+-->
<operation name="server-group:add" displayName="Add ServerGroup" description="Add a server group to the Domain.">
<parameters>
@@ -146,6 +150,17 @@
</operation>
+ <operation name="start" description="Start this Host-/Domaincontroller" displayName="Start this host controller">
+ <results>
+ <c:simple-property name="operationResult" description="Outcome of the start operation"/>
+ </results>
+ </operation>
+ <operation name="shutdown" description="Stop this Host-/Domaincontroller" displayName="Shut down this host controller">
+ <results>
+ <c:simple-property name="operationResult" description="Outcome of the stop operation"/>
+ </results>
+ </operation>
+
<metric property="_internal:mgmtRequests" category="performance" dataType="measurement" defaultInterval="120000"
displayType="summary" measurementType="trendsup" description="Number of requests sent to the controller"
@@ -206,7 +221,7 @@
<resource-configuration>
<c:simple-property name="profile" description="The profile name" required="true"/>
<c:simple-property name="socket-binding-group" readOnly="false" required="true">
- <c:option-source target="resource" expression="type=SocketBindingGroup"/>
+ <c:option-source target="resource" expression="type=SocketBindingGroupDomain"/>
</c:simple-property>
<c:simple-property name="socket-binding-port-offset" required="false" defaultValue="0" type="integer"
description="The default offset to be added to the port values given by the socket binding group."/>
@@ -217,7 +232,7 @@
<server name="Host"
description="Host involved in this domain"
discovery="SubsystemDiscovery"
- class="DomainComponent"
+ class="BaseComponent"
>
<plugin-configuration>
<c:simple-property name="path" default="host" readOnly="true"/>
@@ -287,11 +302,17 @@
<server name="JBossAS7-Standalone"
discovery="BaseProcessDiscovery"
class="StandaloneASComponent"
+ description="Standalone AS7 server"
>
<plugin-configuration>
<c:simple-property name="hostname" default="localhost" required="true"/>
<c:simple-property name="port" default="9990" type="integer" required="true"/>
+ <c:simple-property name="user" type="string" description="Management user for a secured AS" required="false"/>
+ <c:simple-property name="password" type="password" description="Password for the management user" required="false"/>
+ <c:simple-property name="config" type="string" default="standalone.xml" description="Running configuration" displayName="Configuration"/>
+ <c:simple-property name="baseDir" type="file" description="Base directory of the server installation" displayName="Base directory" readOnly="true" required="false"/>
+ <c:simple-property name="startScript" type="file" default="bin/standalone.sh" description="Script used to start the server. If the path is not absolute, it is relative to the base directory"/>
<c:list-property name="system-properties">
<c:map-property name="system-property">
<c:simple-property name="key" readOnly="true"/>
@@ -303,7 +324,18 @@
<process-scan name="StandaloneAS" query="process|basename|match=^java.*,arg|org.jboss.as.standalone|match=.*"/>
- <operation name="reload" description="Make the server load the (changed) configuration." displayName="Reload">
+
+ <operation name="reload" description="Make the server re-load the (changed) configuration. To load a different startup config use 'restart'" displayName="Reload">
+ <results>
+ <c:simple-property name="operationResult"/>
+ </results>
+ </operation>
+ <operation name="start" description="Start the server by invoking its start script">
+ <results>
+ <c:simple-property name="operationResult"/>
+ </results>
+ </operation>
+ <operation name="restart" description="Restart the server by shutting it down and invoking its start script">
<results>
<c:simple-property name="operationResult"/>
</results>
@@ -353,14 +385,14 @@
<server name="JBossAS-Managed"
discovery="ManagedASDiscovery"
- class="DomainComponent"
+ class="ManagedASComponent"
>
<plugin-configuration>
<c:simple-property name="hostname" default="localhost" displayName="Management host" required="true"/>
<c:simple-property name="port" default="9990" type="integer" displayName="Management port" required="true"/>
<c:simple-property name="domainHost" readOnly="true" description="Hostname in the domain"/>
<c:simple-property name="group" readOnly="true" displayName="Server Group" description="Server Group this instance belongs to."/>
- <c:simple-property name="socket-binding-group" readOnly="true" displayName="Socket binding group" description="Socket bindngs to use"/>
+ <c:simple-property name="socket-binding-group" readOnly="true" displayName="Socket binding group" description="Socket bindings to use"/>
<c:simple-property name="socket-binding-port-offset" readOnly="true" displayName="Port Offset" type="integer" default="0" description="Offset to the base ports"/>
<c:simple-property name="path" readOnly="true" />
@@ -412,7 +444,7 @@
<server name="Messaging"
discovery="SubsystemDiscovery"
- class="DomainComponent"
+ class="BaseComponent"
description="The underlying HornetQ based messaging subsystem"
singleton="true"
>
@@ -1792,8 +1824,8 @@ working area for individual server instances</li></ul>"/>
<c:list-property name="includes" required="false">
<c:simple-property name="includes" displayName="Included bindings" description="Other bindings that are included in this one (only needed in Domain Mode)"/>
</c:list-property>
- <c:group name="children:socket.binding">
- <c:list-property name="socket-binding">
+ <c:group name="children:socket-binding:name" displayName="Individual socket bindings">
+ <c:list-property name="*">
<c:map-property name="binding">
<c:simple-property name="name" description="The name of the socket. Services which need to access the socket configuration information will find it using this name." readOnly="true"/>
<c:simple-property name="interface" description="Name of the interface to which the socket should be bound, or, for multicast sockets, the interface on which it should listen. This should be one of the declared interfaces."
commit 9933f0e155e2274864458e042614ae8216768f5e
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Mon Jul 25 17:25:23 2011 +0200
BZ 725417 - if the 'default' attribute is missing on a required property, throw a descriptive exception instead of a NPE.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/PluginConfigurationMetadataManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/PluginConfigurationMetadataManagerBean.java
index 9b2d1db..3963f9d 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/PluginConfigurationMetadataManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/PluginConfigurationMetadataManagerBean.java
@@ -106,8 +106,14 @@ public class PluginConfigurationMetadataManagerBean implements PluginConfigurati
for (PropertyDefinition propertyDef : updateReport.getNewPropertyDefinitions()) {
if (propertyDef.isRequired()) {
Property templateProperty = templateConfiguration.get(propertyDef.getName());
- pluginConfiguration.put(templateProperty.deepCopy(false));
- modified = true;
+ if (templateProperty==null) {
+ throw new IllegalArgumentException("The property [" + propertyDef.getName()
+ + "] marked as required in the configuration definition of [" + propertyDef.getConfigurationDefinition().getName()
+ + "] has no attribute 'default'");
+ } else {
+ pluginConfiguration.put(templateProperty.deepCopy(false));
+ modified = true;
+ }
}
}
commit 98365fa7de2d2859473dd0e3bbd68004b837ee57
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Mon Jul 25 07:54:06 2011 +0200
Extract the deploy-to-server-magic from createChild() and add tests to use this extracted code to deploy to domain and server-group.
diff --git a/modules/integration-tests/jboss-as-7-plugin-test/src/test/java/org/rhq/modules/integrationTests/jbossas7plugin/UploadAndDeployTest.java b/modules/integration-tests/jboss-as-7-plugin-test/src/test/java/org/rhq/modules/integrationTests/jbossas7plugin/UploadAndDeployTest.java
index 8581ada..2010640 100644
--- a/modules/integration-tests/jboss-as-7-plugin-test/src/test/java/org/rhq/modules/integrationTests/jbossas7plugin/UploadAndDeployTest.java
+++ b/modules/integration-tests/jboss-as-7-plugin-test/src/test/java/org/rhq/modules/integrationTests/jbossas7plugin/UploadAndDeployTest.java
@@ -26,7 +26,17 @@ import java.util.Map;
import org.codehaus.jackson.JsonNode;
import org.testng.annotations.Test;
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.content.PackageDetailsKey;
+import org.rhq.core.domain.content.transfer.ResourcePackageDetails;
+import org.rhq.core.domain.resource.CreateResourceStatus;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.pluginapi.inventory.CreateResourceReport;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.modules.plugins.jbossas7.ASConnection;
+import org.rhq.modules.plugins.jbossas7.BaseComponent;
+import org.rhq.modules.plugins.jbossas7.json.Address;
import org.rhq.modules.plugins.jbossas7.json.CompositeOperation;
import org.rhq.modules.plugins.jbossas7.json.Operation;
import org.rhq.modules.plugins.jbossas7.json.PROPERTY_VALUE;
@@ -292,7 +302,7 @@ public class UploadAndDeployTest extends AbstractIntegrationTest {
/**
* Test uploading to domain only, but not to a server group
- * @throws Exception
+ * @throws Exception if anything goes wrong.
*/
@Test(timeOut = 60*1000L,enabled = isEnabled)
public void testUploadComposite2() throws Exception {
@@ -346,4 +356,77 @@ public class UploadAndDeployTest extends AbstractIntegrationTest {
}
+ /**
+ * Test the real API code for uploading - case 1: just upload to /deployment
+ * @throws Exception if anything goes wrong.
+ */
+ @Test
+ public void testUploadViaCreateChild1() throws Exception {
+
+ BaseComponent bc = new BaseComponent();
+ bc.setConnection(getASConnection());
+ bc.setPath("");
+ ResourceType rt = new ResourceType();
+ rt.setName("Deployment");
+ Resource resource = new Resource("deployment="+TEST_WAR,TEST_WAR,rt); // TODO resource key?
+ ResourceContext context = new ResourceContext(resource,null,null,null,null,null,null,null,null,null,null,null);
+ bc.start(context);
+
+ String bytes_value = uploadToAs(TEST_WAR);
+
+ ResourcePackageDetails details = new ResourcePackageDetails(new PackageDetailsKey(TEST_WAR,"1.0","deployment","all"));
+ CreateResourceReport report = new CreateResourceReport(TEST_WAR,rt,new Configuration(), new Configuration(),details);
+ try {
+ report = bc.runDeploymentMagicOnServer(report,TEST_WAR,TEST_WAR,bytes_value);
+ assert report != null;
+ assert report.getErrorMessage()==null: "Report contained an unexpected error: " + report.getErrorMessage();
+ assert report.getStatus()!=null : "Report did not contain a status";
+ assert report.getStatus()== CreateResourceStatus.SUCCESS : "Status was no success";
+ assert report.getResourceName().equals(TEST_WAR);
+ assert report.getResourceKey().equals("deployment=" + TEST_WAR);
+ } finally {
+ Remove r =new Remove("deployment",TEST_WAR);
+ getASConnection().execute(r);
+ }
+
+ }
+
+ /**
+ * Test the real API code for uploading - case 2: upload to /deployment and a server group
+ * @throws Exception if anything goes wrong.
+ */
+ @Test
+ public void testUploadViaCreateChild2() throws Exception {
+
+ BaseComponent bc = new BaseComponent();
+ bc.setConnection(getASConnection());
+ bc.setPath("server-group=main-server-group");
+ ResourceType rt = new ResourceType();
+ rt.setName("Deployment");
+ Resource resource = new Resource("server-group=main-server-group",TEST_WAR,rt);
+ ResourceContext context = new ResourceContext(resource,null,null,null,null,null,null,null,null,null,null,null);
+ bc.start(context);
+
+ String bytes_value = uploadToAs(TEST_WAR);
+
+ ResourcePackageDetails details = new ResourcePackageDetails(new PackageDetailsKey(TEST_WAR,"1.0","deployment","all"));
+ CreateResourceReport report = new CreateResourceReport(TEST_WAR,rt,new Configuration(), new Configuration(),details);
+ try {
+ report = bc.runDeploymentMagicOnServer(report,TEST_WAR,TEST_WAR,bytes_value);
+ assert report != null;
+ assert report.getErrorMessage()==null: "Report contained an unexpected error: " + report.getErrorMessage();
+ assert report.getStatus()!=null : "Report did not contain a status";
+ assert report.getStatus()== CreateResourceStatus.SUCCESS : "Status was no success";
+ assert report.getResourceName().equals(TEST_WAR);
+ assert report.getResourceKey().equals("server-group=main-server-group,deployment=" + TEST_WAR) : "Resource key was wrong";
+ } finally {
+ Address sgd = new Address("server-group","main-server-group");
+ sgd.add("deployment", TEST_WAR);
+ Remove r =new Remove(sgd);
+ getASConnection().execute(r);
+ r =new Remove("deployment",TEST_WAR);
+ getASConnection().execute(r);
+ }
+
+ }
}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
index 83b221b..8851706 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
@@ -331,18 +331,34 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
fileName=fileName.substring("C:\\fakepath\\".length());
}
- boolean toServerGroup = context.getResourceKey().contains("server-group=");
- log.info("Deploying [" + fileName + "] to domain only= " + !toServerGroup + " ...");
String tmpName = fileName; // TODO figure out the tmp-name biz with the AS guys
JsonNode resultNode = uploadResult.get("result");
String hash = resultNode.get("BYTES_VALUE").getTextValue();
+ return runDeploymentMagicOnServer(report, fileName, tmpName, hash);
+
+ }
+
+ /**
+ * Do the actual fumbling with the domain api to deploy the uploaded content
+ * @param report CreateResourceReport to report the result
+ * @param runtimeName File name to use as runtime name
+ * @param deploymentName Name of the deployment
+ * @param hash Hash of the content bytes
+ * @return the passed report with success or failure settings
+ */
+ public CreateResourceReport runDeploymentMagicOnServer(CreateResourceReport report, String runtimeName,
+ String deploymentName, String hash) {
+
+ boolean toServerGroup = context.getResourceKey().contains("server-group=");
+ log.info("Deploying [" + runtimeName + "] to domain only= " + !toServerGroup + " ...");
+
ASConnection connection = getASConnection();
- Operation step1 = new Operation("add","deployment",tmpName);
+ Operation step1 = new Operation("add","deployment",deploymentName);
// step1.addAdditionalProperty("hash", new PROPERTY_VALUE("BYTES_VALUE", hash));
List<Object> content = new ArrayList<Object>(1);
Map<String,Object> contentValues = new HashMap<String,Object>();
@@ -350,8 +366,8 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
content.add(contentValues);
step1.addAdditionalProperty("content",content);
- step1.addAdditionalProperty("name", tmpName);
- step1.addAdditionalProperty("runtime-name", fileName);
+ step1.addAdditionalProperty("name", deploymentName);
+ step1.addAdditionalProperty("runtime-name", runtimeName);
String resourceKey;
Result result ;
@@ -379,7 +395,7 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
List<PROPERTY_VALUE> serverGroupAddress = new ArrayList<PROPERTY_VALUE>();
serverGroupAddress.addAll(pathToAddress(context.getResourceKey()));
- serverGroupAddress.add(new PROPERTY_VALUE("deployment", tmpName));
+ serverGroupAddress.add(new PROPERTY_VALUE("deployment", deploymentName));
Operation step2 = new Operation("add",serverGroupAddress);
cop.addStep(step2);
@@ -403,13 +419,12 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
}
else {
report.setStatus(CreateResourceStatus.SUCCESS);
- report.setResourceName(fileName);
+ report.setResourceName(runtimeName);
report.setResourceKey(resourceKey);
log.info(" ... with success and key [" + resourceKey + "]" );
}
return report;
-
}
@Override
12 years, 10 months
[rhq] Branch 'as7plugin' - 92 commits - .classpath modules/core modules/enterprise modules/integration-tests modules/plugins modules/test-utils
by Heiko W. Rupp
.classpath | 2
modules/core/dbutils/pom.xml | 2
modules/core/dbutils/src/main/scripts/dbsetup/sysconfig-data.xml | 6
modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml | 16
modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BaseCriteria.java | 7
modules/core/domain/src/main/java/org/rhq/core/domain/criteria/DriftChangeSetCriteria.java | 18
modules/core/domain/src/main/java/org/rhq/core/domain/criteria/DriftChangeSetJPACriteria.java | 48 +
modules/core/domain/src/main/java/org/rhq/core/domain/drift/DiffReport.java | 38
modules/core/domain/src/main/java/org/rhq/core/domain/drift/Snapshot.java | 68 +
modules/core/domain/src/test/java/org/rhq/core/domain/drift/RhqDriftChangeSetTest.java | 41 -
modules/core/domain/src/test/java/org/rhq/core/domain/drift/SnapshotTest.java | 383 ++++++++++
modules/core/domain/src/test/java/org/rhq/core/domain/test/AbstractEJB3Test.java | 44 -
modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetectionSchedule.java | 13
modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java | 56 -
modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java | 59 +
modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ScheduleQueue.java | 72 +
modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ScheduleQueueImpl.java | 119 +++
modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/ResourceContainer.java | 12
modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftDetectorTest.java | 43 -
modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftTest.java | 9
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/LinkManager.java | 4
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/SystemSettingsView.java | 41 -
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/Table.java | 6
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/AbstractDriftChangeSetsTreeDataSource.java | 266 ++++++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/AbstractDriftChangeSetsTreeView.java | 295 +++++++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftChangeSetsView.java | 78 ++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/ResourceDriftChangeSetsTreeDataSource.java | 51 +
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/ResourceDriftChangeSetsTreeView.java | 56 +
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/ResourceDriftChangeSetsView.java | 40 +
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/DriftGWTService.java | 5
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java | 14
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/DriftGWTServiceImpl.java | 12
modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties | 3
modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties | 3
modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ja.properties | 3
modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_pt.properties | 3
modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_zh.properties | 3
modules/enterprise/gui/coregui/src/main/webapp/images/subsystems/drift/ChangeSet_16.png |binary
modules/enterprise/gui/coregui/src/main/webapp/images/subsystems/drift/ChangeSet_16_open.png |binary
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/RHQConstants.java | 4
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerBean.java | 14
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerLocal.java | 7
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftServerBean.java | 19
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftServerLocal.java | 4
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/Snapshot.java | 38
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java | 90 --
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerLocal.java | 21
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/drift/DriftServerPluginFacet.java | 4
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/drift/DriftServerPluginManager.java | 86 ++
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/drift/SnapshotTest.java | 312 --------
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/metadata/MetadataBeanTest.java | 9
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/AbstractEJB3Test.java | 34
modules/enterprise/server/plugins/drift-rhq/src/main/java/org/rhq/enterprise/server/plugins/drift/DriftServerPluginComponent.java | 7
modules/integration-tests/mod_cluster-plugin-test/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java | 210 +++++
modules/plugins/jmx/src/main/java/org/rhq/plugins/jmx/MBeanResourceComponent.java | 2
modules/plugins/mod-cluster/pom.xml | 271 +++++++
modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java | 102 ++
modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java | 118 +++
modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java | 45 +
modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java | 310 ++++++++
modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml | 132 +++
modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java | 80 ++
modules/plugins/mod-cluster/src/test/resources/log4j.xml | 51 +
modules/plugins/mod-cluster/src/test/resources/proxy_config/proxy_config_1.txt | 13
modules/plugins/mod-cluster/src/test/resources/proxy_config/proxy_config_2.txt | 16
modules/plugins/mod-cluster/src/test/resources/proxy_config/proxy_config_empty.txt | 1
modules/plugins/pom.xml | 3
modules/test-utils/pom.xml | 10
modules/test-utils/src/main/java/org/rhq/test/JPAUtils.java | 207 +++++
modules/test-utils/src/main/java/org/rhq/test/TransactionCallback.java | 7
70 files changed, 3611 insertions(+), 555 deletions(-)
New commits:
commit b35ba5b025f995e7658bd1f56a8e002f5b05e84b
Merge: 47451f9 f1b3ecd
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Thu Jul 28 15:48:01 2011 +0200
Merge branch 'as7plugin' of ssh://git.fedorahosted.org/git/rhq/rhq into as7plugin
commit 47451f90a8383fe368a398e45e5e4d75d0efd256
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Thu Jul 28 15:44:35 2011 +0200
BZ 726378 - management port settings on AS7 were not honored.
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
index 322e453..9aa9db0 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
@@ -111,12 +111,15 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
this.context = context;
pluginConfiguration = context.getPluginConfiguration();
- String typeName = context.getResourceType().getName();
- // TODO can we use parent's connection and only set this up for top level base component?
- host = pluginConfiguration.getSimpleValue("hostname", LOCALHOST);
- String portString = pluginConfiguration.getSimpleValue("port", DEFAULT_HTTP_MANAGEMENT_PORT);
- port = Integer.parseInt(portString);
- connection = new ASConnection(host,port);
+ if (!(context.getParentResourceComponent() instanceof BaseComponent)) {
+ host = pluginConfiguration.getSimpleValue("hostname", LOCALHOST);
+ String portString = pluginConfiguration.getSimpleValue("port", DEFAULT_HTTP_MANAGEMENT_PORT);
+ port = Integer.parseInt(portString);
+ connection = new ASConnection(host,port);
+ }
+ else {
+ connection = ((BaseComponent)context.getParentResourceComponent()).getASConnection();
+ }
path = pluginConfiguration.getSimpleValue("path", null);
key = context.getResourceKey();
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java
index 475fd62..471fd42 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java
@@ -79,11 +79,8 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
String psName = psr.getProcessScan().getName();
String description = discoveryContext.getResourceType().getDescription();
String version = null;
- String startScript;
- if (psName.equals("ProcessController")) {
- serverNameFull = "ProcessController";
- serverName = "ProcessController";
- } else if (psName.equals("HostController")) {
+
+ if (psName.equals("HostController")) {
readStandaloneOrHostXml(psr.getProcessInfo(), true);
HostPort hp = getDomainControllerFromHostXml();
if (hp.isLocal) {
@@ -118,11 +115,10 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
tmp = tmp.substring( i + 8);
tmp = tmp.substring(0,tmp.indexOf("/"));
serverNameFull = tmp;
-
- String host = findHost(psr.getProcessInfo(),true);
- config.put(new PropertySimple("domainHost",host));
-
}
+ String host = findHost(psr.getProcessInfo(),true);
+ config.put(new PropertySimple("domainHost",host));
+
config.put(new PropertySimple("baseDir",serverNameFull));
serverName = findHostName();
if (serverName.isEmpty())
@@ -139,6 +135,11 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
}
String logFile = getLogFileFromCommandLine(commandLine);
initLogEventSourcesConfigProp(logFile,config);
+
+ HostPort managmentPort = getManagementPortFromHostXml();
+ config.put(new PropertySimple("hostname",managmentPort.host));
+ config.put(new PropertySimple("port",managmentPort.port));
+
// String javaClazz = psr.getProcessInfo().getName();
commit b160369e4999f327871e961fb75fe74f470d6914
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Thu Jul 28 13:17:00 2011 +0200
Initial support for messaging (JMS)
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
index 776e5ef..322e453 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
@@ -23,6 +23,8 @@ import org.apache.commons.logging.LogFactory;
import org.codehaus.jackson.JsonNode;
import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.Property;
+import org.rhq.core.domain.configuration.PropertyList;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
@@ -480,12 +482,34 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
} else if (what.equals("destination")) {
address.addAll(pathToAddress(getPath()));
String newName = parameters.getSimpleValue("name","");
-// String type = parameters.getSimpleValue("type","Queue").toLowerCase();
-// address.add(new PROPERTY_VALUE(type,newName));
- String queueName = parameters.getSimpleValue("queue-address","");
- Map<String,Object> props = new HashMap<String, Object>();
- props.put("queue-address",queueName);
+ String type = parameters.getSimpleValue("type","jms-queue").toLowerCase();
+ address.add(new PROPERTY_VALUE(type,newName));
+ PropertyList jndiNamesProp = parameters.getList("entries");
+ if (jndiNamesProp==null || jndiNamesProp.getList().isEmpty()) {
+ OperationResult fail = new OperationResult();
+ fail.setErrorMessage("No jndi bindings given");
+ return fail;
+ }
+ List<String> jndiNames = new ArrayList<String>();
+ for (Property p : jndiNamesProp.getList()) {
+ PropertySimple ps = (PropertySimple) p;
+ jndiNames.add(ps.getStringValue());
+ }
+
operation = new Operation(op,address);
+ operation.addAdditionalProperty("entries",jndiNames);
+ if (type.equals("jms-queue")) {
+ PropertySimple ps = (PropertySimple) parameters.get("durable");
+ if (ps!=null) {
+ boolean durable = ps.getBooleanValue();
+ operation.addAdditionalProperty("durable",durable);
+ }
+ String selector = parameters.getSimpleValue("selector","");
+ if (!selector.isEmpty())
+ operation.addAdditionalProperty("selector",selector);
+ }
+
+
} else if (what.equals("managed-server")) {
String chost = parameters.getSimpleValue("hostname","");
String serverName = parameters.getSimpleValue("servername","");
diff --git a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
index 6a8698e..20395e0 100644
--- a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
@@ -444,7 +444,7 @@
<server name="Messaging"
discovery="SubsystemDiscovery"
class="BaseComponent"
- description="The underlying HornetQ based messaging subsystem"
+ description="The HornetQ based messaging subsystem"
singleton="true"
>
<runs-inside>
@@ -459,15 +459,16 @@
<operation name="destination:add" displayName="Add destination" description="Add a Queue or Topic">
<parameters>
<c:simple-property name="name" description="Name of the Destination" required="true"/>
- <c:simple-property name="queue-address" description="The queue address defines what address is used for routing messages." required="true"/>
+ <c:list-property name="entries" description="The JNDI names the destination should be bound to." required="true">
+ <c:simple-property name="entry" description="A single JNDI name. Note, this is relative to java:jboss/jms/"/>
+ </c:list-property>
<c:simple-property name="type" description="Type of Destination to create" default="Queue">
<c:property-options>
- <c:option value="Queue"/>
- <c:option value="Topic"/>
+ <c:option value="jms-queue" name="Queue"/>
+ <c:option value="jms-topic" name="Topic"/>
</c:property-options>
</c:simple-property>
- <c:simple-property name="filter" description="The queue message filter definition."/>
- <c:simple-property name="durable" description="Defines whether the queue is durable." type="boolean" default="false"/>
+ <c:simple-property name="durable" description="Defines whether the queue is durable (for Queues only)." type="boolean" default="false"/>
</parameters>
<results>
<c:simple-property name="operationResult"/>
@@ -487,73 +488,23 @@
<c:simple-property name="journal-type" />
</resource-configuration>
- <!-- this is no child resource TODO
-
- <service name="Acceptor"
- discovery="SubsystemDiscovery"
- class="BaseComponent"
- >
- <plugin-configuration>
- <c:simple-property name="path" readOnly="true" default="acceptor"/>
- </plugin-configuration>
- </service>
- <service name="MessagingConnector"
- discovery="SubsystemDiscovery"
- class="BaseComponent"
- >
- <plugin-configuration>
- <c:simple-property name="path" readOnly="true" default="connector"/>
- </plugin-configuration>
- </service>
- <service name="HQueue"
- discovery="SubsystemDiscovery"
- class="BaseComponent"
- >
- <plugin-configuration>
- <c:simple-property name="path" readOnly="true" default="queue"/>
- </plugin-configuration>
- <resource-configuration>
- <c:simple-property name="queue-address" required="true"/>
- <c:simple-property name="filter" />
- <c:simple-property name="durable" type="boolean"/>
- </resource-configuration>
-
- </service>
--->
- </server>
-
- <server name="JMS"
- discovery="SubsystemDiscovery"
- class="JmsComponent"
- description="The JMS messaging subsystem"
- singleton="true"
- >
- <runs-inside>
- <parent-resource-type name="Profile" plugin="jboss-as-7"/>
- <parent-resource-type name="JBossAS7-Standalone" plugin="jboss-as-7"/>
- </runs-inside>
-
- <plugin-configuration>
- <c:simple-property name="path" readOnly="true" default="subsystem=jms"/>
- </plugin-configuration>
-
- <service name="Queue"
+ <service name="JMS Queue"
discovery="SubsystemDiscovery"
class="JmsComponent"
- createDeletePolicy="both"
+ createDeletePolicy="delete-only"
>
<plugin-configuration>
- <c:simple-property name="path" readOnly="true" default="queue"/>
+ <c:simple-property name="path" readOnly="true" default="jms-queue"/>
</plugin-configuration>
<resource-configuration> <!-- See BZ 705713 TODO -->
- <c:simple-property name="durable" required="false" type="boolean" readOnly="false" default="false"
+ <c:simple-property name="durable" required="false" type="boolean" readOnly="true" default="false"
description="Whether the queue is durable or not."/>
- <c:list-property name="entries" required="false" readOnly="false"
+ <c:list-property name="entries" required="false" readOnly="true"
description="The jndi names the queue will be bound to.">
<c:simple-property name="entries" type="string"/>
</c:list-property>
- <c:simple-property name="selector" required="false" type="string" readOnly="false" description="The queue selector."/>
+ <c:simple-property name="selector" required="false" type="string" readOnly="true" description="The queue selector."/>
<c:template name="add" description="Properties when adding a new queue" >
<c:simple-property name="durable" required="false" type="boolean" default="false"
description="Whether the queue is durable or not."/>
@@ -565,16 +516,16 @@
</c:template>
</resource-configuration>
</service>
- <service name="Topic"
+ <service name="JMS Topic"
discovery="SubsystemDiscovery"
class="JmsComponent"
- createDeletePolicy="both"
+ createDeletePolicy="delete-only"
>
<plugin-configuration>
- <c:simple-property name="path" readOnly="true" default="topic"/>
+ <c:simple-property name="path" readOnly="true" default="jms-topic"/>
</plugin-configuration>
<resource-configuration> <!-- See BZ 705713 TODO -->
- <c:list-property name="entries" required="false" readOnly="false"
+ <c:list-property name="entries" required="false" readOnly="true"
description="The jndi names the queue will be bound to.">
<c:simple-property name="entries" type="string"/>
</c:list-property>
commit d3f942a14e0497b7bcbd6561c495f391513cdb29
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Tue Jul 26 22:29:16 2011 +0200
Add more properties for JBossWeb. Unfortunately they are read-only in AS7
Follow :read-resource output, as the resource description from AS7 is not up to date.
diff --git a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
index d9f79d1..6a8698e 100644
--- a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
@@ -614,6 +614,78 @@
<c:simple-property name="path" readOnly="true" default="subsystem=web"/>
</plugin-configuration>
+ <resource-configuration>
+ <c:simple-property name="default-virtual-server" required="false" type="string" readOnly="true" defaultValue="localhost"
+ description="The web container's default virtual server."/>
+ <c:simple-property name="native" required="false" type="boolean" readOnly="true" defaultValue="true"
+ description="Add the native initialization listener to the web container."/>
+ <c:map-property name="configuration" description="The common web container configuration." >
+ <c:map-property name="static-resources" description="Configuration for static resources" >
+ <c:simple-property name="listings" required="false" type="boolean" readOnly="true" defaultValue="false"
+ description="Enable folder listings."/>
+ <c:simple-property name="sendfile" required="false" type="integer" readOnly="true" defaultValue="49152"
+ description="Enable sendfile if possible, for files bigger than the specified byte size."/>
+ <c:simple-property name="read-only" required="false" type="boolean" readOnly="true" defaultValue="true"
+ description="Allow write HTTP methods (PUT, DELETE)."/>
+ <c:simple-property name="webdav" required="false" type="boolean" readOnly="true" defaultValue="false"
+ description="Enable WebDAV functionality."/>
+ <c:simple-property name="secret" required="false" type="string" readOnly="true" description="Secret for WebDAV locking operations."/>
+ <c:simple-property name="max-depth" required="false" type="integer" readOnly="true" defaultValue="3"
+ description="Maximum recursion for PROPFIND."/>
+ <c:simple-property name="disabled" required="false" type="boolean" readOnly="true" defaultValue="false"
+ description="Enable the JSP container."/>
+ </c:map-property>
+ <c:map-property name="jsp-configuration" description="JSP container configuration">
+ <c:simple-property name="development" required="false" type="boolean" readOnly="true" defaultValue="false"
+ description="Enable the development mode, which gives more information when an error occurs."/>
+ <c:simple-property name="file-encoding" required="false" type="string" readOnly="true" description="Force a file encoding."/>
+ <c:simple-property name="keep-generated" required="false" type="boolean" readOnly="true" defaultValue="true"
+ description="Keep the generated Servlets."/>
+ <c:simple-property name="trim-spaces" required="false" type="boolean" readOnly="true" defaultValue="true"
+ description="Trim some spaces from the generated Servlet."/>
+ <c:simple-property name="tag-pooling" required="false" type="boolean" readOnly="true" defaultValue="true"
+ description="Enable tag pooling."/>
+ <c:simple-property name="mapped-file" required="false" type="boolean" readOnly="true" defaultValue="true"
+ description="Map to the JSP source."/>
+ <c:simple-property name="check-interval" required="false" type="integer" readOnly="true" defaultValue="0"
+ description="Check interval for JSP updates using a background thread."/>
+ <c:simple-property name="modification-test-interval" required="false" type="integer" readOnly="true" defaultValue="4"
+ description="Minimum amount of time between two tests for updates, in seconds."/>
+ <c:simple-property name="recompile-on-fail" required="false" type="boolean" readOnly="true" defaultValue="false"
+ description="Retry failed JSP compilations on each request."/>
+ <c:simple-property name="smap" required="false" type="boolean" readOnly="true" defaultValue="false"
+ description="Enable SMAP."/>
+ <c:simple-property name="dump-smap" required="false" type="boolean" readOnly="true" defaultValue="false"
+ description="Write SMAP data to a file."/>
+ <c:simple-property name="generate-strings-as-char-arrays" required="false" type="boolean" readOnly="true"
+ defaultValue="false"
+ description="Generate String constants as char arrays."/>
+ <c:simple-property name="error-on-use-bean-invalid-class-attribute" required="false" type="boolean" readOnly="true" defaultValue="false"
+ description="Enable errors when using a bad class in useBean."/>
+ <c:simple-property name="scratch-dir" required="false" type="string" readOnly="true" description="Specify a different work directory."/>
+ <c:simple-property name="source-vm" required="false" type="string" readOnly="true" defaultValue="1.5"
+ description="Source VM level for compilation."/>
+ <c:simple-property name="target-vm" required="false" type="string" readOnly="true" defaultValue="1.5"
+ description="Target VM level for compilation."/>
+ <c:simple-property name="java-encoding" required="false" type="string" readOnly="true" defaultValue="UTF-8"
+ description="Specify the encoding used for Java sources."/>
+ <c:simple-property name="x-powered-by" required="false" type="boolean" readOnly="true" defaultValue="true"
+ description="Enable advertising the JSP engine in x-powered-by."/>
+ <c:simple-property name="display-source-fragment" required="false" type="boolean" readOnly="true" defaultValue="true"
+ description="When a runtime error occurs, attempts to display corresponding JSP source fragment."/>
+ </c:map-property>
+ <c:list-property name="mime-mapping" description="A mime-mapping definition." >
+ <c:map-property name="mime-mapping" >
+ <c:simple-property name="name" description="A MIME mapping name"/>
+ <c:simple-property name="value" description="A MIME mapping value"/>
+ </c:map-property>
+ </c:list-property>
+ <c:list-property name="welcome-file" description="A welcome file declaration." >
+ <c:simple-property name="welcome-file" />
+ </c:list-property>
+ </c:map-property>
+ </resource-configuration>
+
<service name="Connector"
discovery="SubsystemDiscovery"
class="BaseComponent"
commit 8cf10dd720219a5b1a03e825eae5ca2ccd978a5f
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Wed Jul 27 09:18:58 2011 +0200
Get rid of the explicit version number and let maven do the magic.
diff --git a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
index 0927693..d9f79d1 100644
--- a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
@@ -48,7 +48,6 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration"
- version="4.0.0-SNAPSHOT"
>
<!-- <depends plugin="JMX" useClasses="true"/> -->
commit 9b8876e0032bf4c94568bd784ac44b38198f4731
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Wed Jul 27 11:18:39 2011 +0200
Log the property being null and don't pollute stdout.
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationLoadDelegate.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationLoadDelegate.java
index e978962..c999be6 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationLoadDelegate.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationLoadDelegate.java
@@ -269,8 +269,10 @@ public class ConfigurationLoadDelegate implements ConfigurationFacet {
if (property!=null)
propertyMap.put(property);
- else
- System.out.println("Property " + key + " was null");
+ else {
+ if (log.isDebugEnabled())
+ log.debug("Property " + key + " was null");
+ }
}
commit 8de2372999f6778ac2c41d7f4d80fcea239e4e2d
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Mon Jul 25 18:00:50 2011 +0200
Provide more connection properties for standalone servers as well as the version. Add start and restart operations for standalone servers.
Read the running instance name (i.e. standalone server name) from standalone.xml
Allow to start a domain/host controller.
Allow to shut down hosts in a domain.
Allow to shut down host controllers. Revert the ability to shutdown hosts - this needs to be done at HC level.
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/AbstractBaseDiscovery.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/AbstractBaseDiscovery.java
index 63a4e45..c089b79 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/AbstractBaseDiscovery.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/AbstractBaseDiscovery.java
@@ -46,9 +46,15 @@ public abstract class AbstractBaseDiscovery<T extends ResourceComponent> impleme
protected Document hostXml;
protected final Log log = LogFactory.getLog(this.getClass());
-// private final Log log = LogFactory.getLog(AbstractBaseDiscovery.class);
- protected void readHostXml(ProcessInfo processInfo,boolean isDomainMode) {
+ /**
+ * Read the host.xml or standalone.xml file depending on isDomainMode. If isDomainMode is true,
+ * host.xml is read, otherwise standalone.xml.
+ * The xml file content is stored in the variable hostXml for future use.
+ * @param processInfo Process info to determine the base file location
+ * @param isDomainMode Indiates if host.xml should be read (true) or standalone.xml (false)
+ */
+ protected void readStandaloneOrHostXml(ProcessInfo processInfo, boolean isDomainMode) {
String hostXmlFile = getHostXmlFileLocation(processInfo,isDomainMode);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
@@ -61,7 +67,11 @@ public abstract class AbstractBaseDiscovery<T extends ResourceComponent> impleme
}
}
-
+ /**
+ * Determine the server home (=base) directory by parsing the passed command line
+ * @param commandLine command line arguments of the process
+ * @return The home dir if found or empty string otherwise
+ */
String getHomeDirFromCommandLine(String[] commandLine) {
for (String line: commandLine) {
if (line.startsWith(DJBOSS_SERVER_HOME_DIR))
@@ -70,6 +80,11 @@ public abstract class AbstractBaseDiscovery<T extends ResourceComponent> impleme
return "";
}
+ /**
+ * Determine the location of the boot log file of the server by parsing the command line
+ * @param commandLine command line arguments of the process
+ * @return The log file location or empty string otherwise
+ */
String getLogFileFromCommandLine(String[] commandLine) {
for (String line: commandLine) {
@@ -79,7 +94,14 @@ public abstract class AbstractBaseDiscovery<T extends ResourceComponent> impleme
return "";
}
+ /**
+ * Try to obtain the management IP and port from the already parsed host.xml or standalone.xml
+ * @return an Object containing host and port
+ * @see #readStandaloneOrHostXml(org.rhq.core.system.ProcessInfo, boolean) on how to obtain the parsed xml
+ */
protected HostPort getManagementPortFromHostXml() {
+ if (hostXml==null)
+ throw new IllegalArgumentException("hostXml is null. You need to call 'readStandaloneOrHostXml' first.");
Element host = hostXml.getDocumentElement();
NodeList interfaceParent = host.getElementsByTagName("management-interfaces");
if (interfaceParent ==null || interfaceParent.getLength()==0) {
@@ -112,7 +134,15 @@ public abstract class AbstractBaseDiscovery<T extends ResourceComponent> impleme
return new HostPort();
}
+ /**
+ * Try to obtain the management interface IP from the host/standalone.xml files
+ * @param nIf Interface to look for
+ * @return IP address to use
+ */
private String getInterface(String nIf) {
+ if (hostXml==null)
+ throw new IllegalArgumentException("hostXml is null. You need to call 'readStandaloneOrHostXml' first.");
+
Element host = hostXml.getDocumentElement();
NodeList interfaceParent = host.getElementsByTagName("interfaces");
if (interfaceParent ==null || interfaceParent.getLength()==0) {
@@ -155,12 +185,26 @@ public abstract class AbstractBaseDiscovery<T extends ResourceComponent> impleme
return null; // TODO: Customise this generated block
}
+ /**
+ * Try to determine the host name - that is the name of a standalone server or a
+ * host in domain mode by looking at the standalone/host.xml files
+ * @return server name
+ */
protected String findHostName() {
+ if (hostXml==null)
+ throw new IllegalArgumentException("hostXml is null. You need to call 'readStandaloneOrHostXml' first.");
+
String hostName = hostXml.getDocumentElement().getAttribute("name");
return hostName;
}
+ /**
+ * Try to obtain the domain controller's location from looking at host.xml
+ * @return host and port of the domain controller
+ */
protected HostPort getDomainControllerFromHostXml() {
+ if (hostXml==null)
+ throw new IllegalArgumentException("hostXml is null. You need to call 'readStandaloneOrHostXml' first.");
Element host = hostXml.getDocumentElement();
NodeList dcParent = host.getElementsByTagName("domain-controller");
@@ -211,6 +255,9 @@ public abstract class AbstractBaseDiscovery<T extends ResourceComponent> impleme
}
+ /**
+ * Helper class that holds information about the host,port tuple
+ */
protected static class HostPort {
String host;
int port;
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
index 8851706..776e5ef 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
@@ -79,7 +79,7 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
final Log log = LogFactory.getLog(this.getClass());
ResourceContext context;
- Configuration conf;
+ Configuration pluginConfiguration;
String myServerName;
ASConnection connection;
String path;
@@ -107,16 +107,16 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
*/
public void start(ResourceContext context) throws InvalidPluginConfigurationException, Exception {
this.context = context;
- conf = context.getPluginConfiguration();
+ pluginConfiguration = context.getPluginConfiguration();
String typeName = context.getResourceType().getName();
// TODO can we use parent's connection and only set this up for top level base component?
- host = conf.getSimpleValue("hostname", LOCALHOST);
- String portString = conf.getSimpleValue("port", DEFAULT_HTTP_MANAGEMENT_PORT);
+ host = pluginConfiguration.getSimpleValue("hostname", LOCALHOST);
+ String portString = pluginConfiguration.getSimpleValue("port", DEFAULT_HTTP_MANAGEMENT_PORT);
port = Integer.parseInt(portString);
connection = new ASConnection(host,port);
- path = conf.getSimpleValue("path", null);
+ path = pluginConfiguration.getSimpleValue("path", null);
key = context.getResourceKey();
myServerName = context.getResourceKey().substring(context.getResourceKey().lastIndexOf("/")+1);
@@ -445,16 +445,15 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
List<PROPERTY_VALUE> address = new ArrayList<PROPERTY_VALUE>();
if (what.equals("server-group")) {
- String groupName = parameters.getSimpleValue("name",null);
+ String groupName = parameters.getSimpleValue("name","");
String profile = parameters.getSimpleValue("profile","default");
address.add(new PROPERTY_VALUE("server-group",groupName));
operation = new Operation(op,address,"profile",profile);
} else if (what.equals("server")) {
-
if (context.getResourceType().getName().equals("JBossAS-Managed")) {
- String host = conf.getSimpleValue("domainHost","local");
+ String host = pluginConfiguration.getSimpleValue("domainHost","local");
address.add(new PROPERTY_VALUE("host",host));
address.add(new PROPERTY_VALUE("server-config",myServerName));
operation = new Operation(op,address);
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java
index 2f71edb..475fd62 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java
@@ -18,8 +18,11 @@
*/
package org.rhq.modules.plugins.jbossas7;
+import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.List;
@@ -30,7 +33,6 @@ import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.mc4j.ems.connection.support.metadata.LocalVMTypeDescriptor;
import org.w3c.dom.Document;
import org.rhq.core.domain.configuration.Configuration;
@@ -43,8 +45,6 @@ import org.rhq.core.pluginapi.inventory.ProcessScanResult;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
import org.rhq.core.system.ProcessInfo;
-import org.rhq.plugins.jmx.JMXDiscoveryComponent;
-
/**
* Discovery class
@@ -53,9 +53,10 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
{
- static final String DJBOSS_SERVER_BASE_DIR = "-Djboss.server.base.dir=";
+ static final String DJBOSS_HOME_DIR = "-Djboss.home.dir=";
static final String DORG_JBOSS_BOOT_LOG_FILE = "-Dorg.jboss.boot.log.file=";
static final String DLOGGING_CONFIGURATION = "-Dlogging.configuration=";
+ static final String DASH_DASH_SERVER_CONFIG = "--server-config=";
private final Log log = LogFactory.getLog(this.getClass());
/**
@@ -77,11 +78,13 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
String serverName;
String psName = psr.getProcessScan().getName();
String description = discoveryContext.getResourceType().getDescription();
+ String version = null;
+ String startScript;
if (psName.equals("ProcessController")) {
serverNameFull = "ProcessController";
serverName = "ProcessController";
} else if (psName.equals("HostController")) {
- readHostXml(psr.getProcessInfo(),true);
+ readStandaloneOrHostXml(psr.getProcessInfo(), true);
HostPort hp = getDomainControllerFromHostXml();
if (hp.isLocal) {
serverName = "DomainController";
@@ -92,11 +95,20 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
serverName = "HostController";
serverNameFull = "HostController";
}
- config.put(new PropertySimple("homedir",getHomeDirFromCommandLine(psr.getProcessInfo().getCommandLine())));
- // TODO add the start script
+ String homeDir = getHomeDirFromCommandLine(psr.getProcessInfo().getCommandLine());
+ config.put(new PropertySimple("baseDir", homeDir));
+ version = homeDir.substring(homeDir.lastIndexOf("-")+1);
+ config.put(new PropertySimple("startScript","bin/domain.sh"));
+ String host = findHost(psr.getProcessInfo(),true);
+ config.put(new PropertySimple("domainHost",host));
+
+ fillUserPassFromFile(config,"domain",homeDir);
+
+ // TODO provide running config
- } else {
- serverNameFull = getBaseDirFromCommandLine(commandLine);
+ } else { // Standalone server
+ serverNameFull = getHomeDirFromCommandLine(commandLine);
+ readStandaloneOrHostXml(psr.getProcessInfo(), false);
if (serverNameFull==null || serverNameFull.isEmpty()) {
// Try to obtain the server name
// -Dorg.jboss.boot.log.file=domain/servers/server-one/log/boot.log
@@ -111,10 +123,19 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
config.put(new PropertySimple("domainHost",host));
}
- serverName = serverNameFull.substring(serverNameFull.lastIndexOf("/")+1);
+ config.put(new PropertySimple("baseDir",serverNameFull));
+ serverName = findHostName();
if (serverName.isEmpty())
serverName = serverNameFull;
+ version = serverName.substring(serverName.lastIndexOf("-")+1);
+
+ String serverConfig = getServerConfigFromCommandLine(commandLine);
+ config.put(new PropertySimple("config",serverConfig));
+ config.put(new PropertySimple("startScript","bin/standalone.sh"));
+
+ fillUserPassFromFile(config,"standalone", serverNameFull);
+
}
String logFile = getLogFileFromCommandLine(commandLine);
initLogEventSourcesConfigProp(logFile,config);
@@ -139,7 +160,7 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
discoveryContext.getResourceType(), // ResourceType
serverNameFull, // key TODO distinguish per domain?
serverName, // Name
- null, // TODO real version ?
+ version, // TODO get via API ?Á
description, // Description
config,
psr.getProcessInfo()
@@ -155,6 +176,48 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
}
+ private void fillUserPassFromFile(Configuration config, String mode, String baseDir) {
+
+ String configDir = baseDir + File.separator + mode + File.separator + "configuration";
+
+ File file = new File(configDir ,"mgmt-users.properties");
+ if (!file.exists() || !file.canRead()) {
+ if (log.isDebugEnabled())
+ log.debug("No console user properties file found at [" + file.getAbsolutePath() + "] or file is not readable");
+ return;
+ }
+ BufferedReader br=null;
+ try {
+ FileReader fileReader = new FileReader(file);
+ br = new BufferedReader(fileReader);
+ String line;
+ while ((line = br.readLine())!=null) {
+ if (line.startsWith("#"))
+ continue;
+ if (line.isEmpty())
+ continue;
+ if (!line.contains("="))
+ continue;
+ // found a candidate
+ String user = line.substring(0,line.indexOf("="));
+ String pass = line.substring(line.indexOf("=")+1);
+ config.put(new PropertySimple("user",user));
+ config.put(new PropertySimple("password",pass));
+
+ }
+ } catch (IOException e) {
+ e.printStackTrace(); // TODO: Customise this generated block
+ } finally {
+ if (br!=null)
+ try {
+ br.close();
+ } catch (IOException e) {
+ // empty
+ }
+ }
+
+ }
+
private String findHost(ProcessInfo processInfo,boolean isDomain) {
String hostXmlFile = getHostXmlFileLocation(processInfo, isDomain);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
@@ -173,12 +236,13 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
return hostName;
}
- String getBaseDirFromCommandLine(String[] commandLine) {
+
+ String getServerConfigFromCommandLine(String[] commandLine) {
for (String line: commandLine) {
- if (line.startsWith(DJBOSS_SERVER_BASE_DIR))
- return line.substring(DJBOSS_SERVER_BASE_DIR.length());
+ if (line.startsWith(DASH_DASH_SERVER_CONFIG))
+ return line.substring(DASH_DASH_SERVER_CONFIG.length());
}
- return "";
+ return "standalone.xml";
}
//-Dorg.jboss.boot.log.file=/devel/jbas7/jboss-as/build/target/jboss-7.0.0.Alpha2/domain/log/server-manager/boot.log
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java
new file mode 100644
index 0000000..c8703a6
--- /dev/null
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java
@@ -0,0 +1,184 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.modules.plugins.jbossas7;
+
+import java.io.File;
+import java.net.ConnectException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.pluginapi.operation.OperationResult;
+import org.rhq.core.pluginapi.util.ProcessExecutionUtility;
+import org.rhq.core.system.ProcessExecution;
+import org.rhq.core.system.ProcessExecutionResults;
+import org.rhq.modules.plugins.jbossas7.json.Result;
+
+/**
+ * Base component for functionality that is common to Standalone AS and HostControllers
+ * @author Heiko W. Rupp
+ */
+public class BaseServerComponent extends BaseComponent {
+
+ private static final String STANDALONE_XML = "standalone.xml";
+ private static final String SEPARATOR = "\n-----------------------\n";
+ final Log log = LogFactory.getLog(BaseServerComponent.class);
+
+ /**
+ * Restart the server by first executing a 'shutdown' operation via its API. Then call
+ * the #startServer method to start it again.
+ *
+ * @param parameters Parameters to pass to the (recursive) invocation of #invokeOperation
+ * @param mode
+ * @return State of execution
+ * @throws Exception If anything goes wrong
+ */
+ protected OperationResult restartServer(Configuration parameters, Mode mode) throws Exception {
+ OperationResult tmp = invokeOperation("shutdown",parameters);
+
+ if (tmp.getErrorMessage()!=null) {
+ tmp.setErrorMessage("Restart failed while failing to shut down: " + tmp.getErrorMessage());
+ return tmp;
+ }
+ Thread.sleep(500); // Wait 0.5s -- this is plenty
+ return startServer(mode);
+ }
+
+ /**
+ * Start the server by calling the start script listed in the plugin configuration. If a different
+ * config is given, this is passed via --server-config
+ * @return State of Execution.
+ * @param mode
+ */
+ protected OperationResult startServer(Mode mode) {
+ OperationResult operationResult = new OperationResult();
+ Configuration conf = context.getPluginConfiguration();
+ String startScript = conf.getSimpleValue("startScript", mode.getStartScript());
+ String baseDir = conf.getSimpleValue("baseDir","");
+ if (baseDir.isEmpty()) {
+ operationResult.setErrorMessage("No base directory provided");
+ return operationResult;
+ }
+ String script = baseDir + File.separator + startScript;
+ String config = conf.getSimpleValue("config", mode.getXmlFile());
+
+ ProcessExecution processExecution;
+ processExecution = ProcessExecutionUtility.createProcessExecution(new File(script));
+ if (!config.equals(mode.getXmlFile())) {
+ processExecution.getArguments().add(mode.getConfigArg());
+ processExecution.getArguments().add(config);
+ }
+ processExecution.setWorkingDirectory(baseDir);
+ processExecution.setCaptureOutput(true);
+ processExecution.setWaitForCompletion(2000L); // 2 seconds // TODO: Should we wait longer than two seconds?
+ processExecution.setKillOnTimeout(false);
+
+
+ long start = System.currentTimeMillis();
+ if (log.isDebugEnabled()) {
+ log.debug("About to execute the following process: [" + processExecution + "]");
+ }
+ ProcessExecutionResults results = context.getSystemInformation().executeProcess(processExecution);
+ logExecutionResults(results);
+ if (results.getError()!=null) {
+ operationResult.setErrorMessage(results.getError().getMessage());
+ } else {
+ operationResult.setSimpleResult("Success");
+ }
+
+ return operationResult;
+
+ }
+
+ private void logExecutionResults(ProcessExecutionResults results) {
+ // Always log the output at info level. On Unix we could switch depending on a exitCode being !=0, but ...
+ log.info("Exit code from process execution: " + results.getExitCode());
+ log.info("Output from process execution: " + SEPARATOR + results.getCapturedOutput() + SEPARATOR);
+ }
+
+ /**
+ * Do some post processing of the Result - especially the 'shutdown' operation needs a special
+ * treatment.
+ * @param name Name of the operation
+ * @param res Result of the operation vs. AS7
+ * @return OperationResult filled in from values of res
+ */
+ protected OperationResult postProcessResult(String name, Result res) {
+ OperationResult operationResult = new OperationResult();
+ if (name.equals("shutdown")) {
+ /*
+ * Shutdown needs a special treatment, because after sending the operation, if shutdown suceeds,
+ * the server connection is closed and we can't read from it. So if we get connection refused for
+ * reading, this is a good sign.
+ */
+ if (!res.isSuccess()) {
+ if (res.getThrowable()!=null && (res.getThrowable() instanceof ConnectException || res.getThrowable().getMessage().equals("Connection refused")))
+ operationResult.setSimpleResult("Success");
+ else
+ operationResult.setErrorMessage(res.getFailureDescription());
+ }
+ }
+ else {
+ if (res.isSuccess()) {
+ if (res.getResult()!=null)
+ operationResult.setSimpleResult(res.getResult().toString());
+ else
+ operationResult.setSimpleResult("-None provided by server-");
+ }
+ else
+ operationResult.setErrorMessage(res.getFailureDescription());
+ }
+ return operationResult;
+ }
+
+ enum Mode {
+ STANDALONE(STANDALONE_XML,"standalone","--server-config","bin/standalone.sh"),
+ DOMAIN("domain.xml","domain", "--domain-config","bin/domain.sh"),
+ HOST("host.xml","domain", "--host-config","bin/domain.sh");
+
+ private String xmlFile;
+ private String baseDir;
+ private String configArg;
+ private String startScript;
+
+ private Mode(String xmlFile, String baseDir, String configArg, String startScript) {
+ this.xmlFile = xmlFile;
+ this.baseDir = baseDir;
+ this.configArg = configArg;
+ this.startScript = startScript;
+ }
+
+ public String getXmlFile() {
+ return xmlFile;
+ }
+
+ public String getBaseDir() {
+ return baseDir;
+ }
+
+ public String getConfigArg() {
+ return configArg;
+ }
+
+ public String getStartScript() {
+ return startScript;
+ }
+ }
+}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/DomainComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/DomainComponent.java
deleted file mode 100644
index c25fe88..0000000
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/DomainComponent.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2011 Red Hat, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-package org.rhq.modules.plugins.jbossas7;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.codehaus.jackson.JsonNode;
-
-import org.rhq.core.domain.configuration.Configuration;
-import org.rhq.core.domain.measurement.AvailabilityType;
-import org.rhq.core.pluginapi.operation.OperationFacet;
-import org.rhq.core.pluginapi.operation.OperationResult;
-import org.rhq.modules.plugins.jbossas7.json.Operation;
-import org.rhq.modules.plugins.jbossas7.json.PROPERTY_VALUE;
-import org.rhq.modules.plugins.jbossas7.json.Result;
-
-/**
- * Common stuff for the Domain
- * @author Heiko W. Rupp
- */
-@SuppressWarnings("unused")
-public class DomainComponent extends BaseComponent implements OperationFacet{
-
- @Override
- public AvailabilityType getAvailability() {
-
- if (context.getResourceType().getName().equals("JBossAS-Managed")) {
- List<PROPERTY_VALUE> address = new ArrayList<PROPERTY_VALUE>(2);
- String host = conf.getSimpleValue("domainHost","local");
- address.add(new PROPERTY_VALUE("host",host));
- address.add(new PROPERTY_VALUE("server-config",myServerName));
- Operation getStatus = new Operation("read-attribute",address,"name","status");
- Result result = null;
- try {
- result = connection.execute(getStatus);
- } catch (Exception e) {
- log.warn(e.getMessage());
- return AvailabilityType.DOWN;
- }
- if (!result.isSuccess())
- return AvailabilityType.DOWN;
-
- String msg = result.getResult().toString();
- if (msg.contains("STARTED"))
- return AvailabilityType.UP;
- else
- return AvailabilityType.DOWN;
- }
-
- return super.getAvailability(); // TODO: Customise this generated block
- }
-
-}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/HostControllerComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/HostControllerComponent.java
new file mode 100644
index 0000000..73eb0bb
--- /dev/null
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/HostControllerComponent.java
@@ -0,0 +1,64 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.modules.plugins.jbossas7;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.pluginapi.operation.OperationFacet;
+import org.rhq.core.pluginapi.operation.OperationResult;
+import org.rhq.modules.plugins.jbossas7.json.Operation;
+import org.rhq.modules.plugins.jbossas7.json.Result;
+
+/**
+ * Component class for host- and domain controller
+ * @author Heiko W. Rupp
+ */
+public class HostControllerComponent extends BaseServerComponent implements OperationFacet {
+
+ private final Log log = LogFactory.getLog(HostControllerComponent.class);
+
+ @Override
+ public OperationResult invokeOperation(String name,
+ Configuration parameters) throws InterruptedException, Exception {
+
+ if (name.equals("start")) {
+ return startServer(Mode.DOMAIN);
+ } else if (name.equals("restart")) {
+ return restartServer(parameters, Mode.DOMAIN);
+
+ } else if (name.equals("shutdown")) {
+ // This is a bit trickier, as it needs to be executed on the level on /host=xx
+ String domainHost = pluginConfiguration.getSimpleValue("domainHost","");
+ if (domainHost.isEmpty()) {
+ OperationResult result = new OperationResult();
+ result.setErrorMessage("No domain host found - can not continue");
+ return result;
+ }
+ Operation op = new Operation("shutdown","host",domainHost);
+ Result res = getASConnection().execute(op);
+
+ postProcessResult(name,res);
+ }
+
+ // Defer other stuff to the base component for now
+ return super.invokeOperation(name, parameters);
+ }
+}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/JmsComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/JmsComponent.java
index d0d3eee..951430c 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/JmsComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/JmsComponent.java
@@ -32,7 +32,6 @@ import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.domain.configuration.definition.PropertyDefinitionList;
import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
-import org.rhq.core.domain.configuration.definition.PropertySimpleType;
import org.rhq.core.domain.resource.CreateResourceStatus;
import org.rhq.core.pluginapi.inventory.CreateResourceReport;
import org.rhq.modules.plugins.jbossas7.json.ComplexResult;
@@ -43,7 +42,7 @@ import org.rhq.modules.plugins.jbossas7.json.PROPERTY_VALUE;
* Component class for the JMS subsystem
* @author Heiko W. Rupp
*/
-public class JmsComponent extends DomainComponent {
+public class JmsComponent extends BaseComponent {
private final Log log = LogFactory.getLog(JmsComponent.class);
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASComponent.java
new file mode 100644
index 0000000..64ac2b6
--- /dev/null
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASComponent.java
@@ -0,0 +1,70 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.modules.plugins.jbossas7;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.modules.plugins.jbossas7.json.Operation;
+import org.rhq.modules.plugins.jbossas7.json.PROPERTY_VALUE;
+import org.rhq.modules.plugins.jbossas7.json.Result;
+
+/**
+ * Common stuff for the Domain
+ * @author Heiko W. Rupp
+ */
+@SuppressWarnings("unused")
+public class ManagedASComponent extends BaseComponent {
+
+ /**
+ * Get the availability of the managed AS server. We can't just check if
+ * a connection succeeds, as the check runs against the API/HostController
+ * and the managed server may still be down even if the connection succeeds.
+ * @return Availability of the managed AS instance.
+ */
+ @Override
+ public AvailabilityType getAvailability() {
+
+ if (context.getResourceType().getName().equals("JBossAS-Managed")) {
+ List<PROPERTY_VALUE> address = new ArrayList<PROPERTY_VALUE>(2);
+ String host = pluginConfiguration.getSimpleValue("domainHost","local");
+ address.add(new PROPERTY_VALUE("host",host));
+ address.add(new PROPERTY_VALUE("server-config",myServerName));
+ Operation getStatus = new Operation("read-attribute",address,"name","status");
+ Result result = null;
+ try {
+ result = connection.execute(getStatus);
+ } catch (Exception e) {
+ log.warn(e.getMessage());
+ return AvailabilityType.DOWN;
+ }
+ if (!result.isSuccess())
+ return AvailabilityType.DOWN;
+
+ String msg = result.getResult().toString();
+ if (msg.contains("STARTED"))
+ return AvailabilityType.UP;
+ else
+ return AvailabilityType.DOWN;
+ }
+
+ return super.getAvailability();
+ }
+}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASDiscovery.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASDiscovery.java
index 3946dbe..fd1b65d 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASDiscovery.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASDiscovery.java
@@ -70,7 +70,7 @@ public class ManagedASDiscovery extends AbstractBaseDiscovery
// Now we have the host controller, lets get the host.xml file
// and obtain the servers from there.
ProcessInfo processInfo = psr.getProcessInfo();
- readHostXml(processInfo,true);
+ readStandaloneOrHostXml(processInfo, true);
String hostName = findHostName();
HostPort managementHostPort = getManagementPortFromHostXml();
@@ -105,13 +105,16 @@ public class ManagedASDiscovery extends AbstractBaseDiscovery
// TODO this fails for the downed servers.
// get from the domain or other place as soon as the domain provides it.
- initLogFile(scans, serverInfo.name, config, getHomeDirFromCommandLine(processInfo.getCommandLine()));
+ String homeDir = getHomeDirFromCommandLine(processInfo.getCommandLine());
+ initLogFile(scans, serverInfo.name, config, homeDir);
+
+ String version = homeDir.substring(homeDir.lastIndexOf("-")+1);
DiscoveredResourceDetails detail = new DiscoveredResourceDetails(
discoveryContext.getResourceType(), // ResourceType
hostName + "/" + serverInfo.name, // key
serverInfo.name, // Name
- null, // TODO real version - get from Domain as soon as it is provided
+ version, // TODO get from Domain as soon as it is provided
"Managed AS 7 instance", // Description
config,
null
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ServerGroupComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ServerGroupComponent.java
index 15cb5d3..ad1109b 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ServerGroupComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ServerGroupComponent.java
@@ -23,7 +23,6 @@ import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -38,12 +37,10 @@ import org.rhq.core.domain.content.transfer.DeployPackageStep;
import org.rhq.core.domain.content.transfer.DeployPackagesResponse;
import org.rhq.core.domain.content.transfer.RemovePackagesResponse;
import org.rhq.core.domain.content.transfer.ResourcePackageDetails;
-import org.rhq.core.domain.resource.CreateResourceStatus;
import org.rhq.core.pluginapi.content.ContentContext;
import org.rhq.core.pluginapi.content.ContentFacet;
import org.rhq.core.pluginapi.content.ContentServices;
import org.rhq.core.pluginapi.inventory.CreateChildResourceFacet;
-import org.rhq.core.pluginapi.inventory.CreateResourceReport;
import org.rhq.modules.plugins.jbossas7.json.CompositeOperation;
import org.rhq.modules.plugins.jbossas7.json.Operation;
import org.rhq.modules.plugins.jbossas7.json.PROPERTY_VALUE;
@@ -55,7 +52,7 @@ import org.rhq.modules.plugins.jbossas7.json.Result;
* @author Heiko W. Rupp
*/
@SuppressWarnings("unused")
-public class ServerGroupComponent extends DomainComponent implements ContentFacet, CreateChildResourceFacet {
+public class ServerGroupComponent extends ManagedASComponent implements ContentFacet, CreateChildResourceFacet {
private static final String SUCCESS = "success";
private static final String OUTCOME = "outcome";
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASComponent.java
index 0281279..ebddf95 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASComponent.java
@@ -31,41 +31,25 @@ import org.rhq.modules.plugins.jbossas7.json.Result;
* Component class for standalone AS7 servers
* @author Heiko W. Rupp
*/
-public class StandaloneASComponent extends BaseComponent implements OperationFacet {
-
+public class StandaloneASComponent extends BaseServerComponent implements OperationFacet {
@Override
public OperationResult invokeOperation(String name,
Configuration parameters) throws Exception {
- // reload, shutdown
+ if (name.equals("start")) {
+ return startServer(Mode.STANDALONE);
+ } else if (name.equals("restart")) {
+ return restartServer(parameters, Mode.STANDALONE);
+
+ }
+
+ // reload, shutdown go to the remote server
Operation op = new Operation(name,new Address());
Result res = getASConnection().execute(op);
- OperationResult operationResult = new OperationResult();
- if (name.equals("shutdown")) {
- /*
- * Shutdown needs a special treatment, because after sending the operation, if shutdown suceeds,
- * the server connection is closed and we can't read from it. So if we get connection refused for
- * reading, this is a good sign.
- */
- if (!res.isSuccess()) {
- if (res.getThrowable() instanceof ConnectException || res.getThrowable().getMessage().equals("Connection refused"))
- operationResult.setSimpleResult("Success");
- else
- operationResult.setErrorMessage(res.getFailureDescription());
- }
- }
- else {
- if (res.isSuccess()) {
- if (res.getResult()!=null)
- operationResult.setSimpleResult(res.getResult().toString());
- else
- operationResult.setSimpleResult("-None provided by server-");
- }
- else
- operationResult.setErrorMessage(res.getFailureDescription());
- }
+ OperationResult operationResult = postProcessResult(name, res);
return operationResult;
}
+
}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/json/Address.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/json/Address.java
index ad91dac..d762485 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/json/Address.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/json/Address.java
@@ -51,6 +51,25 @@ public class Address {
path.addAll(other);
}
+ public Address(String path) {
+ this();
+ String[] components = path.split(",");
+ for (String component : components) {
+ String tmp = component.trim();
+
+ if (tmp.contains("=")) {
+ // strip / from the start of the key if it happens to be there
+ if (tmp.startsWith("/"))
+ tmp = tmp.substring(1);
+
+ String[] pair = tmp.split("=");
+ PROPERTY_VALUE valuePair = new PROPERTY_VALUE(pair[0], pair[1]);
+ this.path.add(valuePair);
+ }
+ }
+
+ }
+
public void add(String key, String value) {
path.add(new PROPERTY_VALUE(key,value));
}
diff --git a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
index c0e364d..0927693 100644
--- a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
@@ -58,6 +58,7 @@
~~ additional 'Personalities' for the kinds of servers (PM, SM, Standalone AS, Managed AS)
-->
+ <!-- TODO do we want to show the process controller at all? We have no benefit from it
<server name="ProcessController"
discovery="BaseProcessDiscovery"
class="BaseComponent"
@@ -68,27 +69,28 @@
<c:simple-property name="hostname" default="localhost" required="true"/>
<c:simple-property name="port" default="9990" type="integer" required="true"/>
- &logSources;
</plugin-configuration>
<process-scan name="ProcessController" query="process|basename|match=^java.*,arg|org.jboss.as.process-controller|match=.*"/>
- <operation name="dummyOperation">
- <!-- TODO supply parameters and return values -->
- </operation>
-
-
</server>
+ -->
<server name="HostController"
discovery="BaseProcessDiscovery"
- class="BaseComponent"
+ class="HostControllerComponent"
description="Domain controller (delegate) for this host"
>
<plugin-configuration>
- <c:simple-property name="hostname" default="localhost" required="true"/>
- <c:simple-property name="port" default="9990" type="integer" required="true"/>
+ <c:simple-property name="hostname" default="localhost" required="true" description="Host name of the domain API"/>
+ <c:simple-property name="port" default="9990" type="integer" required="true" description="Port of the domain API"/>
+ <c:simple-property name="user" type="string" description="Management user for a secured Host controller" required="false"/>
+ <c:simple-property name="password" type="password" description="Password for the management user" required="false"/>
+ <c:simple-property name="config" type="string" default="domain.xml" description="Running configuration" displayName="Configuration"/>
+ <c:simple-property name="baseDir" type="file" description="Base directory of the server installation" displayName="Base directory" readOnly="true" required="false"/>
+ <c:simple-property name="startScript" type="file" default="bin/domain.sh" description="Script used to start the server. If the path is not absolute, it is relative to the base directory"/>
+ <c:simple-property name="domainHost" type="string" readOnly="true" required="false" description="Host name within the AS7 domain"/>
&logSources;
</plugin-configuration>
@@ -96,8 +98,10 @@
<process-scan name="HostController" query="process|basename|match=^java.*,arg|org.jboss.as.host-controller|match=.*"/>
+<!-- Currently not provided by AS7
<operation name="domain:shutdown" displayName="Shutdown Domain" description="Shut this Host-/Domaincontroller down with all managed servers.">
</operation>
+-->
<operation name="server-group:add" displayName="Add ServerGroup" description="Add a server group to the Domain.">
<parameters>
@@ -146,6 +150,17 @@
</operation>
+ <operation name="start" description="Start this Host-/Domaincontroller" displayName="Start this host controller">
+ <results>
+ <c:simple-property name="operationResult" description="Outcome of the start operation"/>
+ </results>
+ </operation>
+ <operation name="shutdown" description="Stop this Host-/Domaincontroller" displayName="Shut down this host controller">
+ <results>
+ <c:simple-property name="operationResult" description="Outcome of the stop operation"/>
+ </results>
+ </operation>
+
<metric property="_internal:mgmtRequests" category="performance" dataType="measurement" defaultInterval="120000"
displayType="summary" measurementType="trendsup" description="Number of requests sent to the controller"
@@ -206,7 +221,7 @@
<resource-configuration>
<c:simple-property name="profile" description="The profile name" required="true"/>
<c:simple-property name="socket-binding-group" readOnly="false" required="true">
- <c:option-source target="resource" expression="type=SocketBindingGroup"/>
+ <c:option-source target="resource" expression="type=SocketBindingGroupDomain"/>
</c:simple-property>
<c:simple-property name="socket-binding-port-offset" required="false" defaultValue="0" type="integer"
description="The default offset to be added to the port values given by the socket binding group."/>
@@ -217,7 +232,7 @@
<server name="Host"
description="Host involved in this domain"
discovery="SubsystemDiscovery"
- class="DomainComponent"
+ class="BaseComponent"
>
<plugin-configuration>
<c:simple-property name="path" default="host" readOnly="true"/>
@@ -287,11 +302,17 @@
<server name="JBossAS7-Standalone"
discovery="BaseProcessDiscovery"
class="StandaloneASComponent"
+ description="Standalone AS7 server"
>
<plugin-configuration>
<c:simple-property name="hostname" default="localhost" required="true"/>
<c:simple-property name="port" default="9990" type="integer" required="true"/>
+ <c:simple-property name="user" type="string" description="Management user for a secured AS" required="false"/>
+ <c:simple-property name="password" type="password" description="Password for the management user" required="false"/>
+ <c:simple-property name="config" type="string" default="standalone.xml" description="Running configuration" displayName="Configuration"/>
+ <c:simple-property name="baseDir" type="file" description="Base directory of the server installation" displayName="Base directory" readOnly="true" required="false"/>
+ <c:simple-property name="startScript" type="file" default="bin/standalone.sh" description="Script used to start the server. If the path is not absolute, it is relative to the base directory"/>
<c:list-property name="system-properties">
<c:map-property name="system-property">
<c:simple-property name="key" readOnly="true"/>
@@ -303,7 +324,18 @@
<process-scan name="StandaloneAS" query="process|basename|match=^java.*,arg|org.jboss.as.standalone|match=.*"/>
- <operation name="reload" description="Make the server load the (changed) configuration." displayName="Reload">
+
+ <operation name="reload" description="Make the server re-load the (changed) configuration. To load a different startup config use 'restart'" displayName="Reload">
+ <results>
+ <c:simple-property name="operationResult"/>
+ </results>
+ </operation>
+ <operation name="start" description="Start the server by invoking its start script">
+ <results>
+ <c:simple-property name="operationResult"/>
+ </results>
+ </operation>
+ <operation name="restart" description="Restart the server by shutting it down and invoking its start script">
<results>
<c:simple-property name="operationResult"/>
</results>
@@ -353,14 +385,14 @@
<server name="JBossAS-Managed"
discovery="ManagedASDiscovery"
- class="DomainComponent"
+ class="ManagedASComponent"
>
<plugin-configuration>
<c:simple-property name="hostname" default="localhost" displayName="Management host" required="true"/>
<c:simple-property name="port" default="9990" type="integer" displayName="Management port" required="true"/>
<c:simple-property name="domainHost" readOnly="true" description="Hostname in the domain"/>
<c:simple-property name="group" readOnly="true" displayName="Server Group" description="Server Group this instance belongs to."/>
- <c:simple-property name="socket-binding-group" readOnly="true" displayName="Socket binding group" description="Socket bindngs to use"/>
+ <c:simple-property name="socket-binding-group" readOnly="true" displayName="Socket binding group" description="Socket bindings to use"/>
<c:simple-property name="socket-binding-port-offset" readOnly="true" displayName="Port Offset" type="integer" default="0" description="Offset to the base ports"/>
<c:simple-property name="path" readOnly="true" />
@@ -412,7 +444,7 @@
<server name="Messaging"
discovery="SubsystemDiscovery"
- class="DomainComponent"
+ class="BaseComponent"
description="The underlying HornetQ based messaging subsystem"
singleton="true"
>
@@ -1792,8 +1824,8 @@ working area for individual server instances</li></ul>"/>
<c:list-property name="includes" required="false">
<c:simple-property name="includes" displayName="Included bindings" description="Other bindings that are included in this one (only needed in Domain Mode)"/>
</c:list-property>
- <c:group name="children:socket.binding">
- <c:list-property name="socket-binding">
+ <c:group name="children:socket-binding:name" displayName="Individual socket bindings">
+ <c:list-property name="*">
<c:map-property name="binding">
<c:simple-property name="name" description="The name of the socket. Services which need to access the socket configuration information will find it using this name." readOnly="true"/>
<c:simple-property name="interface" description="Name of the interface to which the socket should be bound, or, for multicast sockets, the interface on which it should listen. This should be one of the declared interfaces."
commit ae90811cb167e8e8c20cb4677fe1e7580714db51
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Mon Jul 25 17:25:23 2011 +0200
BZ 725417 - if the 'default' attribute is missing on a required property, throw a descriptive exception instead of a NPE.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/PluginConfigurationMetadataManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/PluginConfigurationMetadataManagerBean.java
index 9b2d1db..3963f9d 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/PluginConfigurationMetadataManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/PluginConfigurationMetadataManagerBean.java
@@ -106,8 +106,14 @@ public class PluginConfigurationMetadataManagerBean implements PluginConfigurati
for (PropertyDefinition propertyDef : updateReport.getNewPropertyDefinitions()) {
if (propertyDef.isRequired()) {
Property templateProperty = templateConfiguration.get(propertyDef.getName());
- pluginConfiguration.put(templateProperty.deepCopy(false));
- modified = true;
+ if (templateProperty==null) {
+ throw new IllegalArgumentException("The property [" + propertyDef.getName()
+ + "] marked as required in the configuration definition of [" + propertyDef.getConfigurationDefinition().getName()
+ + "] has no attribute 'default'");
+ } else {
+ pluginConfiguration.put(templateProperty.deepCopy(false));
+ modified = true;
+ }
}
}
commit e194ab53e5b63d1c17e67d370a65c29fb8b17efe
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Mon Jul 25 07:54:06 2011 +0200
Extract the deploy-to-server-magic from createChild() and add tests to use this extracted code to deploy to domain and server-group.
diff --git a/modules/integration-tests/jboss-as-7-plugin-test/src/test/java/org/rhq/modules/integrationTests/jbossas7plugin/UploadAndDeployTest.java b/modules/integration-tests/jboss-as-7-plugin-test/src/test/java/org/rhq/modules/integrationTests/jbossas7plugin/UploadAndDeployTest.java
index 8581ada..2010640 100644
--- a/modules/integration-tests/jboss-as-7-plugin-test/src/test/java/org/rhq/modules/integrationTests/jbossas7plugin/UploadAndDeployTest.java
+++ b/modules/integration-tests/jboss-as-7-plugin-test/src/test/java/org/rhq/modules/integrationTests/jbossas7plugin/UploadAndDeployTest.java
@@ -26,7 +26,17 @@ import java.util.Map;
import org.codehaus.jackson.JsonNode;
import org.testng.annotations.Test;
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.content.PackageDetailsKey;
+import org.rhq.core.domain.content.transfer.ResourcePackageDetails;
+import org.rhq.core.domain.resource.CreateResourceStatus;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.pluginapi.inventory.CreateResourceReport;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.modules.plugins.jbossas7.ASConnection;
+import org.rhq.modules.plugins.jbossas7.BaseComponent;
+import org.rhq.modules.plugins.jbossas7.json.Address;
import org.rhq.modules.plugins.jbossas7.json.CompositeOperation;
import org.rhq.modules.plugins.jbossas7.json.Operation;
import org.rhq.modules.plugins.jbossas7.json.PROPERTY_VALUE;
@@ -292,7 +302,7 @@ public class UploadAndDeployTest extends AbstractIntegrationTest {
/**
* Test uploading to domain only, but not to a server group
- * @throws Exception
+ * @throws Exception if anything goes wrong.
*/
@Test(timeOut = 60*1000L,enabled = isEnabled)
public void testUploadComposite2() throws Exception {
@@ -346,4 +356,77 @@ public class UploadAndDeployTest extends AbstractIntegrationTest {
}
+ /**
+ * Test the real API code for uploading - case 1: just upload to /deployment
+ * @throws Exception if anything goes wrong.
+ */
+ @Test
+ public void testUploadViaCreateChild1() throws Exception {
+
+ BaseComponent bc = new BaseComponent();
+ bc.setConnection(getASConnection());
+ bc.setPath("");
+ ResourceType rt = new ResourceType();
+ rt.setName("Deployment");
+ Resource resource = new Resource("deployment="+TEST_WAR,TEST_WAR,rt); // TODO resource key?
+ ResourceContext context = new ResourceContext(resource,null,null,null,null,null,null,null,null,null,null,null);
+ bc.start(context);
+
+ String bytes_value = uploadToAs(TEST_WAR);
+
+ ResourcePackageDetails details = new ResourcePackageDetails(new PackageDetailsKey(TEST_WAR,"1.0","deployment","all"));
+ CreateResourceReport report = new CreateResourceReport(TEST_WAR,rt,new Configuration(), new Configuration(),details);
+ try {
+ report = bc.runDeploymentMagicOnServer(report,TEST_WAR,TEST_WAR,bytes_value);
+ assert report != null;
+ assert report.getErrorMessage()==null: "Report contained an unexpected error: " + report.getErrorMessage();
+ assert report.getStatus()!=null : "Report did not contain a status";
+ assert report.getStatus()== CreateResourceStatus.SUCCESS : "Status was no success";
+ assert report.getResourceName().equals(TEST_WAR);
+ assert report.getResourceKey().equals("deployment=" + TEST_WAR);
+ } finally {
+ Remove r =new Remove("deployment",TEST_WAR);
+ getASConnection().execute(r);
+ }
+
+ }
+
+ /**
+ * Test the real API code for uploading - case 2: upload to /deployment and a server group
+ * @throws Exception if anything goes wrong.
+ */
+ @Test
+ public void testUploadViaCreateChild2() throws Exception {
+
+ BaseComponent bc = new BaseComponent();
+ bc.setConnection(getASConnection());
+ bc.setPath("server-group=main-server-group");
+ ResourceType rt = new ResourceType();
+ rt.setName("Deployment");
+ Resource resource = new Resource("server-group=main-server-group",TEST_WAR,rt);
+ ResourceContext context = new ResourceContext(resource,null,null,null,null,null,null,null,null,null,null,null);
+ bc.start(context);
+
+ String bytes_value = uploadToAs(TEST_WAR);
+
+ ResourcePackageDetails details = new ResourcePackageDetails(new PackageDetailsKey(TEST_WAR,"1.0","deployment","all"));
+ CreateResourceReport report = new CreateResourceReport(TEST_WAR,rt,new Configuration(), new Configuration(),details);
+ try {
+ report = bc.runDeploymentMagicOnServer(report,TEST_WAR,TEST_WAR,bytes_value);
+ assert report != null;
+ assert report.getErrorMessage()==null: "Report contained an unexpected error: " + report.getErrorMessage();
+ assert report.getStatus()!=null : "Report did not contain a status";
+ assert report.getStatus()== CreateResourceStatus.SUCCESS : "Status was no success";
+ assert report.getResourceName().equals(TEST_WAR);
+ assert report.getResourceKey().equals("server-group=main-server-group,deployment=" + TEST_WAR) : "Resource key was wrong";
+ } finally {
+ Address sgd = new Address("server-group","main-server-group");
+ sgd.add("deployment", TEST_WAR);
+ Remove r =new Remove(sgd);
+ getASConnection().execute(r);
+ r =new Remove("deployment",TEST_WAR);
+ getASConnection().execute(r);
+ }
+
+ }
}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
index 83b221b..8851706 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
@@ -331,18 +331,34 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
fileName=fileName.substring("C:\\fakepath\\".length());
}
- boolean toServerGroup = context.getResourceKey().contains("server-group=");
- log.info("Deploying [" + fileName + "] to domain only= " + !toServerGroup + " ...");
String tmpName = fileName; // TODO figure out the tmp-name biz with the AS guys
JsonNode resultNode = uploadResult.get("result");
String hash = resultNode.get("BYTES_VALUE").getTextValue();
+ return runDeploymentMagicOnServer(report, fileName, tmpName, hash);
+
+ }
+
+ /**
+ * Do the actual fumbling with the domain api to deploy the uploaded content
+ * @param report CreateResourceReport to report the result
+ * @param runtimeName File name to use as runtime name
+ * @param deploymentName Name of the deployment
+ * @param hash Hash of the content bytes
+ * @return the passed report with success or failure settings
+ */
+ public CreateResourceReport runDeploymentMagicOnServer(CreateResourceReport report, String runtimeName,
+ String deploymentName, String hash) {
+
+ boolean toServerGroup = context.getResourceKey().contains("server-group=");
+ log.info("Deploying [" + runtimeName + "] to domain only= " + !toServerGroup + " ...");
+
ASConnection connection = getASConnection();
- Operation step1 = new Operation("add","deployment",tmpName);
+ Operation step1 = new Operation("add","deployment",deploymentName);
// step1.addAdditionalProperty("hash", new PROPERTY_VALUE("BYTES_VALUE", hash));
List<Object> content = new ArrayList<Object>(1);
Map<String,Object> contentValues = new HashMap<String,Object>();
@@ -350,8 +366,8 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
content.add(contentValues);
step1.addAdditionalProperty("content",content);
- step1.addAdditionalProperty("name", tmpName);
- step1.addAdditionalProperty("runtime-name", fileName);
+ step1.addAdditionalProperty("name", deploymentName);
+ step1.addAdditionalProperty("runtime-name", runtimeName);
String resourceKey;
Result result ;
@@ -379,7 +395,7 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
List<PROPERTY_VALUE> serverGroupAddress = new ArrayList<PROPERTY_VALUE>();
serverGroupAddress.addAll(pathToAddress(context.getResourceKey()));
- serverGroupAddress.add(new PROPERTY_VALUE("deployment", tmpName));
+ serverGroupAddress.add(new PROPERTY_VALUE("deployment", deploymentName));
Operation step2 = new Operation("add",serverGroupAddress);
cop.addStep(step2);
@@ -403,13 +419,12 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
}
else {
report.setStatus(CreateResourceStatus.SUCCESS);
- report.setResourceName(fileName);
+ report.setResourceName(runtimeName);
report.setResourceKey(resourceKey);
log.info(" ... with success and key [" + resourceKey + "]" );
}
return report;
-
}
@Override
commit 60c8260da5440b889746aac23e7bb3c347a09c81
Merge: 0890ce0 462e94c
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Wed Jul 27 23:11:59 2011 -0500
Merge branch 'mod_cluster_plugin'
commit 462e94c290eeb017427f6a1925f254d859d31140
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Wed Jul 27 23:07:42 2011 -0500
Move mod_cluster integration tests in the correct integration folder.
diff --git a/modules/integration-tests/mod_cluster-plugin-test/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java b/modules/integration-tests/mod_cluster-plugin-test/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
new file mode 100644
index 0000000..0f644fc
--- /dev/null
+++ b/modules/integration-tests/mod_cluster-plugin-test/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
@@ -0,0 +1,210 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.modcluster.test;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.testng.annotations.AfterSuite;
+import org.testng.annotations.BeforeSuite;
+import org.testng.annotations.Test;
+
+import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.domain.measurement.MeasurementData;
+import org.rhq.core.domain.measurement.MeasurementDefinition;
+import org.rhq.core.domain.measurement.MeasurementReport;
+import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.pc.PluginContainer;
+import org.rhq.core.pc.PluginContainerConfiguration;
+import org.rhq.core.pc.plugin.FileSystemPluginFinder;
+import org.rhq.core.pc.plugin.PluginEnvironment;
+import org.rhq.core.pc.plugin.PluginManager;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.measurement.MeasurementFacet;
+import org.rhq.core.pluginapi.operation.OperationFacet;
+import org.rhq.core.pluginapi.operation.OperationResult;
+
+/**
+ * @author Stefan Negrea
+ */
+@SuppressWarnings("rawtypes")
+@Test(groups = "modcluster-plugin")
+public class ModclusterPluginTest {
+ private Log log = LogFactory.getLog(this.getClass());
+ private static final String PLUGIN_NAME = "mod_cluster";
+
+ @BeforeSuite
+ public void start() {
+ try {
+ File pluginDir = new File("target/testsetup/plugins");
+ PluginContainerConfiguration pcConfig = new PluginContainerConfiguration();
+ pcConfig.setPluginFinder(new FileSystemPluginFinder(pluginDir));
+ pcConfig.setPluginDirectory(pluginDir);
+
+ pcConfig.setInsideAgent(false);
+ PluginContainer.getInstance().setConfiguration(pcConfig);
+ PluginContainer.getInstance().initialize();
+ log.info("PC started.");
+ for (String plugin : PluginContainer.getInstance().getPluginManager().getMetadataManager().getPluginNames()) {
+ log.info("...Loaded plugin: " + plugin);
+ }
+ } catch (Exception e) {
+ log.info("Error initializing the context", e);
+ }
+ }
+
+ @AfterSuite
+ public void stop() {
+ PluginContainer.getInstance().shutdown();
+ }
+
+ @Test
+ public void testPluginLoad() {
+ PluginManager pluginManager = PluginContainer.getInstance().getPluginManager();
+ PluginEnvironment pluginEnvironment = pluginManager.getPlugin(PLUGIN_NAME);
+ assert (pluginEnvironment != null) : "Null environment, plugin not loaded";
+ assert (pluginEnvironment.getPluginName().equals(PLUGIN_NAME));
+ }
+
+ @Test(dependsOnMethods = "testPluginLoad")
+ public void testDiscovery() throws Exception {
+ InventoryReport report = PluginContainer.getInstance().getInventoryManager().executeServerScanImmediately();
+ assert report != null;
+ log.info("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
+
+ Thread.sleep(1000);
+
+ report = PluginContainer.getInstance().getInventoryManager().executeServiceScanImmediately();
+ assert report != null;
+ log.info("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
+
+ List<String> typeNames = new ArrayList<String>() {
+ private static final long serialVersionUID = 1L;
+
+ {
+ add(PLUGIN_NAME);
+ add(PLUGIN_NAME + " Webapp Context");
+ }
+ };
+
+ Set<Resource> resources = findResource(PluginContainer.getInstance().getInventoryManager().getPlatform(),
+ typeNames);
+ log.info("Found " + resources.size() + " mod_cluster and mod_cluster_context instance(s).");
+
+ assert (resources.size() != 0) : "No mod_cluster or related instances found.";
+
+ if (resources.size() != 0) {
+ for (Object objectResource : resources.toArray()) {
+ Resource resource = (Resource) objectResource;
+ if (resource.getResourceType().getName().equals("mod_cluster")) {
+ testResourceMeasurement(resource);
+ } else {
+ testContextOperations(resource);
+ }
+ }
+ }
+ }
+
+ private void testResourceMeasurement(Resource resource) throws Exception {
+ ResourceComponent resourceComponent = PluginContainer.getInstance().getInventoryManager()
+ .getResourceComponent(resource);
+ if (resourceComponent instanceof MeasurementFacet) {
+ for (MeasurementDefinition def : resource.getResourceType().getMetricDefinitions()) {
+ Set<MeasurementScheduleRequest> metricList = new HashSet<MeasurementScheduleRequest>();
+ metricList.add(new MeasurementScheduleRequest(1, def.getName(), 1000, true, def.getDataType(), null));
+ MeasurementReport report = new MeasurementReport();
+ ((MeasurementFacet) resourceComponent).getValues(report, metricList);
+
+ MeasurementData data = report.getTraitData().iterator().next();
+ assert data != null : "Unable to collect trait [" + def.getName() + "] on " + resource;
+ log.info("Measurement: " + def.getName() + "=" + data.getValue());
+ }
+ }
+
+ if (resourceComponent instanceof OperationFacet) {
+ OperationResult result = ((OperationFacet) resourceComponent).invokeOperation("reset", null);
+ log.info("Result of operation test was: " + result);
+
+ result = ((OperationFacet) resourceComponent).invokeOperation("disable", null);
+ log.info("Result of operation test was: " + result.getSimpleResult());
+ }
+ }
+
+ private void testContextOperations(Resource resource) throws Exception {
+ ResourceComponent resourceComponent = PluginContainer.getInstance().getInventoryManager()
+ .getResourceComponent(resource);
+
+ if (resourceComponent instanceof OperationFacet) {
+ try {
+ OperationResult result = ((OperationFacet) resourceComponent).invokeOperation("enableContext", null);
+ log.info("Result of operation " + "enableContext" + " was: " + result.getSimpleResult());
+
+ Configuration config = new Configuration();
+ config.put(new PropertySimple("timeout", "1000"));
+ config.put(new PropertySimple("unit", java.util.concurrent.TimeUnit.SECONDS));
+ result = ((OperationFacet) resourceComponent).invokeOperation("stopContext", config);
+ log.info("Result of operation stopContext was: " + result.getSimpleResult());
+
+ result = ((OperationFacet) resourceComponent).invokeOperation("enableContext", null);
+ log.info("Result of operation enableContext was: " + result.getSimpleResult());
+
+ result = ((OperationFacet) resourceComponent).invokeOperation("disableContext", null);
+ log.info("Result of operation disableContext was: " + result.getSimpleResult());
+
+ } catch (Exception e) {
+ log.info("Operation failed. ", e);
+ }
+
+ }
+ }
+
+ private Set<Resource> findResource(Resource parent, List<String> typeNames) {
+ Set<Resource> found = new HashSet<Resource>();
+
+ Queue<Resource> discoveryQueue = new LinkedList<Resource>();
+ discoveryQueue.add(parent);
+
+ while (!discoveryQueue.isEmpty()) {
+ Resource currentResource = discoveryQueue.poll();
+
+ log.info("Discovered resource of type: " + currentResource.getResourceType().getName());
+ if (typeNames.contains(currentResource.getResourceType().getName())) {
+ found.add(currentResource);
+ }
+
+ if (currentResource.getChildResources() != null) {
+ for (Resource child : currentResource.getChildResources()) {
+ discoveryQueue.add(child);
+ }
+ }
+ }
+
+ return found;
+ }
+}
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
deleted file mode 100644
index 0f644fc..0000000
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 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.modcluster.test;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Queue;
-import java.util.Set;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.testng.annotations.AfterSuite;
-import org.testng.annotations.BeforeSuite;
-import org.testng.annotations.Test;
-
-import org.rhq.core.clientapi.server.discovery.InventoryReport;
-import org.rhq.core.domain.configuration.Configuration;
-import org.rhq.core.domain.configuration.PropertySimple;
-import org.rhq.core.domain.measurement.MeasurementData;
-import org.rhq.core.domain.measurement.MeasurementDefinition;
-import org.rhq.core.domain.measurement.MeasurementReport;
-import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
-import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.pc.PluginContainer;
-import org.rhq.core.pc.PluginContainerConfiguration;
-import org.rhq.core.pc.plugin.FileSystemPluginFinder;
-import org.rhq.core.pc.plugin.PluginEnvironment;
-import org.rhq.core.pc.plugin.PluginManager;
-import org.rhq.core.pluginapi.inventory.ResourceComponent;
-import org.rhq.core.pluginapi.measurement.MeasurementFacet;
-import org.rhq.core.pluginapi.operation.OperationFacet;
-import org.rhq.core.pluginapi.operation.OperationResult;
-
-/**
- * @author Stefan Negrea
- */
-@SuppressWarnings("rawtypes")
-@Test(groups = "modcluster-plugin")
-public class ModclusterPluginTest {
- private Log log = LogFactory.getLog(this.getClass());
- private static final String PLUGIN_NAME = "mod_cluster";
-
- @BeforeSuite
- public void start() {
- try {
- File pluginDir = new File("target/testsetup/plugins");
- PluginContainerConfiguration pcConfig = new PluginContainerConfiguration();
- pcConfig.setPluginFinder(new FileSystemPluginFinder(pluginDir));
- pcConfig.setPluginDirectory(pluginDir);
-
- pcConfig.setInsideAgent(false);
- PluginContainer.getInstance().setConfiguration(pcConfig);
- PluginContainer.getInstance().initialize();
- log.info("PC started.");
- for (String plugin : PluginContainer.getInstance().getPluginManager().getMetadataManager().getPluginNames()) {
- log.info("...Loaded plugin: " + plugin);
- }
- } catch (Exception e) {
- log.info("Error initializing the context", e);
- }
- }
-
- @AfterSuite
- public void stop() {
- PluginContainer.getInstance().shutdown();
- }
-
- @Test
- public void testPluginLoad() {
- PluginManager pluginManager = PluginContainer.getInstance().getPluginManager();
- PluginEnvironment pluginEnvironment = pluginManager.getPlugin(PLUGIN_NAME);
- assert (pluginEnvironment != null) : "Null environment, plugin not loaded";
- assert (pluginEnvironment.getPluginName().equals(PLUGIN_NAME));
- }
-
- @Test(dependsOnMethods = "testPluginLoad")
- public void testDiscovery() throws Exception {
- InventoryReport report = PluginContainer.getInstance().getInventoryManager().executeServerScanImmediately();
- assert report != null;
- log.info("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
-
- Thread.sleep(1000);
-
- report = PluginContainer.getInstance().getInventoryManager().executeServiceScanImmediately();
- assert report != null;
- log.info("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
-
- List<String> typeNames = new ArrayList<String>() {
- private static final long serialVersionUID = 1L;
-
- {
- add(PLUGIN_NAME);
- add(PLUGIN_NAME + " Webapp Context");
- }
- };
-
- Set<Resource> resources = findResource(PluginContainer.getInstance().getInventoryManager().getPlatform(),
- typeNames);
- log.info("Found " + resources.size() + " mod_cluster and mod_cluster_context instance(s).");
-
- assert (resources.size() != 0) : "No mod_cluster or related instances found.";
-
- if (resources.size() != 0) {
- for (Object objectResource : resources.toArray()) {
- Resource resource = (Resource) objectResource;
- if (resource.getResourceType().getName().equals("mod_cluster")) {
- testResourceMeasurement(resource);
- } else {
- testContextOperations(resource);
- }
- }
- }
- }
-
- private void testResourceMeasurement(Resource resource) throws Exception {
- ResourceComponent resourceComponent = PluginContainer.getInstance().getInventoryManager()
- .getResourceComponent(resource);
- if (resourceComponent instanceof MeasurementFacet) {
- for (MeasurementDefinition def : resource.getResourceType().getMetricDefinitions()) {
- Set<MeasurementScheduleRequest> metricList = new HashSet<MeasurementScheduleRequest>();
- metricList.add(new MeasurementScheduleRequest(1, def.getName(), 1000, true, def.getDataType(), null));
- MeasurementReport report = new MeasurementReport();
- ((MeasurementFacet) resourceComponent).getValues(report, metricList);
-
- MeasurementData data = report.getTraitData().iterator().next();
- assert data != null : "Unable to collect trait [" + def.getName() + "] on " + resource;
- log.info("Measurement: " + def.getName() + "=" + data.getValue());
- }
- }
-
- if (resourceComponent instanceof OperationFacet) {
- OperationResult result = ((OperationFacet) resourceComponent).invokeOperation("reset", null);
- log.info("Result of operation test was: " + result);
-
- result = ((OperationFacet) resourceComponent).invokeOperation("disable", null);
- log.info("Result of operation test was: " + result.getSimpleResult());
- }
- }
-
- private void testContextOperations(Resource resource) throws Exception {
- ResourceComponent resourceComponent = PluginContainer.getInstance().getInventoryManager()
- .getResourceComponent(resource);
-
- if (resourceComponent instanceof OperationFacet) {
- try {
- OperationResult result = ((OperationFacet) resourceComponent).invokeOperation("enableContext", null);
- log.info("Result of operation " + "enableContext" + " was: " + result.getSimpleResult());
-
- Configuration config = new Configuration();
- config.put(new PropertySimple("timeout", "1000"));
- config.put(new PropertySimple("unit", java.util.concurrent.TimeUnit.SECONDS));
- result = ((OperationFacet) resourceComponent).invokeOperation("stopContext", config);
- log.info("Result of operation stopContext was: " + result.getSimpleResult());
-
- result = ((OperationFacet) resourceComponent).invokeOperation("enableContext", null);
- log.info("Result of operation enableContext was: " + result.getSimpleResult());
-
- result = ((OperationFacet) resourceComponent).invokeOperation("disableContext", null);
- log.info("Result of operation disableContext was: " + result.getSimpleResult());
-
- } catch (Exception e) {
- log.info("Operation failed. ", e);
- }
-
- }
- }
-
- private Set<Resource> findResource(Resource parent, List<String> typeNames) {
- Set<Resource> found = new HashSet<Resource>();
-
- Queue<Resource> discoveryQueue = new LinkedList<Resource>();
- discoveryQueue.add(parent);
-
- while (!discoveryQueue.isEmpty()) {
- Resource currentResource = discoveryQueue.poll();
-
- log.info("Discovered resource of type: " + currentResource.getResourceType().getName());
- if (typeNames.contains(currentResource.getResourceType().getName())) {
- found.add(currentResource);
- }
-
- if (currentResource.getChildResources() != null) {
- for (Resource child : currentResource.getChildResources()) {
- discoveryQueue.add(child);
- }
- }
- }
-
- return found;
- }
-}
commit d5d01cb8c70fd39febb46b8418e2e972ae871b60
Merge: aac766a b13a351
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Wed Jul 27 22:46:02 2011 -0500
Merge branch 'mod_cluster_plugin' of ssh://git.fedorahosted.org/git/rhq/rhq into mod_cluster_plugin
commit aac766a243e3aed738184a5563d9ceaeea2f9a38
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Wed Jul 27 22:42:04 2011 -0500
Make the error message useful by adding the name of the attribute that failed to set.
diff --git a/modules/plugins/jmx/src/main/java/org/rhq/plugins/jmx/MBeanResourceComponent.java b/modules/plugins/jmx/src/main/java/org/rhq/plugins/jmx/MBeanResourceComponent.java
index 2e1ae41..cb7f901 100644
--- a/modules/plugins/jmx/src/main/java/org/rhq/plugins/jmx/MBeanResourceComponent.java
+++ b/modules/plugins/jmx/src/main/java/org/rhq/plugins/jmx/MBeanResourceComponent.java
@@ -503,7 +503,7 @@ public class MBeanResourceComponent<T extends JMXComponent> implements Measureme
property.setErrorMessage(ThrowableUtil.getStackAsString(e));
report
.setErrorMessage("Failed setting resource configuration - see property error messages for details");
- log.info("Failure setting MBean Resource configuration value", e);
+ log.info("Failure setting MBean Resource configuration value for " + key, e);
}
}
}
commit 2c7893abae2d8472490f6eb65305ca91e9b61f74
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Wed Jul 27 22:41:13 2011 -0500
Final touches for mod_cluster plugin configuration. Updated a couple of the plugin settings to match mod_cluster specifications.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
index 5c9c3fd..3d03715 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
@@ -42,9 +42,9 @@ import org.rhq.plugins.jmx.MBeanResourceComponent;
@SuppressWarnings("rawtypes")
public class ContextDiscoveryComponent implements ResourceDiscoveryComponent<MBeanResourceComponent> {
- private final String JVM_ROUTE_PROPERTY = "jvmRoute";
- private final String PROXY_INFO_PROPERTY = "proxyInfo";
- private final String ADDITIONAL_CONFIG_BEAN_PROPERTY = "additionalConfigurationObjectName";
+ private static final String JVM_ROUTE_PROPERTY = "jvmRoute";
+ private static final String PROXY_INFO_PROPERTY = "proxyInfo";
+ private static final String ENGINE_OBJECT_NAME = "engineObjectName";
/* (non-Javadoc)
* @see org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent#discoverResources(org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext)
@@ -76,8 +76,8 @@ public class ContextDiscoveryComponent implements ResourceDiscoveryComponent<MBe
*/
private String getJvmRoute(ResourceDiscoveryContext<MBeanResourceComponent> context) {
Configuration pluginConfig = context.getParentResourceComponent().getResourceContext().getPluginConfiguration();
- String objectName = pluginConfig.getSimple(ADDITIONAL_CONFIG_BEAN_PROPERTY).getStringValue();
- EmsBean engineBean = this.loadBean(objectName, context.getParentResourceComponent());
+ String engineObjectName = pluginConfig.getSimple(ENGINE_OBJECT_NAME).getStringValue();
+ EmsBean engineBean = this.loadBean(engineObjectName, context.getParentResourceComponent());
return (String) engineBean.getAttribute(JVM_ROUTE_PROPERTY).refresh().toString();
}
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
index 591fef6..70898ef 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
@@ -25,7 +25,7 @@ import org.rhq.plugins.jmx.MBeanResourceComponent;
* @author Stefan Negrea
*
*/
-@SuppressWarnings("rawtypes")
+@SuppressWarnings({ "rawtypes" })
public class ModclusterServerComponent extends MBeanResourceComponent {
/* (non-Javadoc)
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index 992c5b0..29b334f 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -25,9 +25,7 @@
<plugin-configuration>
<c:simple-property name="objectName" readOnly="true" default="Catalina:type=ModClusterListener,*"/>
- <c:simple-property name="additionalConfigurationObjectName" readOnly="true" default="jboss.web:type=Engine"/>
- <c:simple-property name="jvmRoute" readOnly="false"/>
- <c:simple-property name="nameTemplate" default="mod_cluster"/>
+ <c:simple-property name="engineObjectName" readOnly="true" default="jboss.web:type=Engine"/>
</plugin-configuration>
<operation name="stop" displayName="Stop all webapps" description="Gracefully stops all webapps for all engines.">
@@ -76,12 +74,12 @@
<metric property="proxyConfiguration" displayName="Proxy Configuration" displayType="summary" dataType="trait" />
<metric property="modelerType" displayName="Type of the modeled resource" displayType="summary" dataType="trait" />
<metric property="className" displayName="Fully qualified class name of the managed object" displayType="summary" dataType="trait" />
+ <metric property="advertise" displayName="Enable autodiscovery of httpd servers." displayType="summary" dataType="trait" />
<resource-configuration>
<c:simple-property name="workerTimeout" type="integer" description="Timeout to wait for an available worker (default is no wait)" />
<c:simple-property name="stickySession" type="boolean" description="Enables sticky session for the cluster."/>
<c:simple-property name="stickySessionRemove" type="boolean" description="Remove session when the request cannot be routed to the right node."/>
- <!-- c:simple-property name="advertise" type="boolean" description="Enable autodiscovery of httpd servers."/-->
<c:simple-property name="smax" type="integer" description="Maximum time on seconds for idle connections above smax."/>
<c:simple-property name="maxAttempts" type="integer" description="Maximum number of attempts to send the request to the backend server."/>
<c:simple-property name="advertiseSecurityKey" type="string" required="false" description="Security key for discovery."/>
@@ -89,7 +87,6 @@
<c:simple-property name="balancer" type="string" required="false" description="Name of the balancer."/>
<c:simple-property name="flushPackets" type="boolean" description="Allows controlling flusing of packets."/>
<c:simple-property name="socketTimeout" type="integer" description="Connection timeout for communication with the proxy." />
- <c:simple-property name="domain" type="string" required="false" description="Domain parameter, which allows tying a jvmRoute to a particular domain."/>
<c:simple-property name="advertisePort" type="integer" required="false" description="Multicast port for discovery" />
<c:simple-property name="advertiseGroupAddress" type="string" required="false" description="Multicast address for discovery."/>
<c:simple-property name="flushWait" type="integer" description="Time in ms to wait before flushing packets."/>
commit 34ee85b04b0ad8592caf75511eb7dbc1fec8f857
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Tue Jul 26 16:11:50 2011 -0500
Fully enable jvmRoute for context identification and discovery. Also, addressed all the compiler warnings in the plugin code.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
index 23d7d62..3545fa5 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
@@ -32,6 +32,7 @@ import org.rhq.plugins.jmx.MBeanResourceComponent;
*
* @author Stefan Negrea
*/
+@SuppressWarnings({ "rawtypes", "deprecation" })
public class ContextComponent extends MBeanResourceComponent<MBeanResourceComponent> {
@Override
protected EmsBean loadBean() {
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
index 35ecf30..5c9c3fd 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
@@ -57,10 +57,12 @@ public class ContextDiscoveryComponent implements ResourceDiscoveryComponent<MBe
Set<DiscoveredResourceDetails> entities = new HashSet<DiscoveredResourceDetails>();
for (ProxyInfo.Context availableContext : proxyInfo.getAvailableContexts()) {
- DiscoveredResourceDetails detail = new DiscoveredResourceDetails(context.getResourceType(),
- availableContext.createKey(), availableContext.createName(), null, "mod_cluster Webapp Context", null,
- null);
- entities.add(detail);
+ if (availableContext.getJvmRoute().equals(jvmRoute)) {
+ DiscoveredResourceDetails detail = new DiscoveredResourceDetails(context.getResourceType(),
+ availableContext.createKey(), availableContext.createName(), null, "mod_cluster Webapp Context",
+ null, null);
+ entities.add(detail);
+ }
}
return entities;
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
index 4cca539..8614402 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
@@ -54,9 +54,9 @@ public class ProxyInfo {
identifier = identifier.substring(identifier.indexOf("[") + 1, identifier.indexOf("]"));
String jvmRoute = nodePieces[1];
- jvmRoute = jvmRoute.substring(jvmRoute.indexOf(':')).trim();
+ jvmRoute = jvmRoute.substring(jvmRoute.indexOf(':') + 1).trim();
- availableNodes.put(jvmRoute, new Node(jvmRoute, identifier));
+ availableNodes.put(identifier, new Node(jvmRoute, identifier));
}
}
@@ -90,13 +90,18 @@ public class ProxyInfo {
identifier = identifier.substring(identifier.indexOf("[") + 1, identifier.indexOf("]"));
identifier = identifier.substring(0, identifier.lastIndexOf(":"));
+ String nodeIdentifier = contextPieces[0];
+ nodeIdentifier = nodeIdentifier.substring(nodeIdentifier.indexOf("[") + 1, nodeIdentifier.indexOf("]"));
+ nodeIdentifier = nodeIdentifier.substring(0, nodeIdentifier.indexOf(":"));
+ String jvmRoute = availableNodes.get(nodeIdentifier).getJvmRoute();
+
String rawIsEnabled = contextPieces[2];
rawIsEnabled = rawIsEnabled.substring(rawIsEnabled.indexOf(':') + 1).trim();
boolean isEnabled = rawIsEnabled.equals("ENABLED") ? true : false;
Vhost relatedVhost = availableVhosts.get(identifier);
- availableContexts.add(new Context("", relatedVhost.getHost(), actualContext, isEnabled));
+ availableContexts.add(new Context(jvmRoute, relatedVhost.getHost(), actualContext, isEnabled));
}
}
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index 3c01b30..992c5b0 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -18,12 +18,12 @@
description="mod_cluster plugin"
singleton="true">
- <runs-inside>
+ <runs-inside>
<parent-resource-type name="JBossAS Server" plugin="JBossAS"/>
<parent-resource-type name="JBossAS5 Server" plugin="JBossAS5"/>
</runs-inside>
- <plugin-configuration>
+ <plugin-configuration>
<c:simple-property name="objectName" readOnly="true" default="Catalina:type=ModClusterListener,*"/>
<c:simple-property name="additionalConfigurationObjectName" readOnly="true" default="jboss.web:type=Engine"/>
<c:simple-property name="jvmRoute" readOnly="false"/>
@@ -34,12 +34,14 @@
<parameters>
<c:simple-property required="true" name="timeout" type="string" displayName="Session draining timeout"/>
<c:simple-property required="true" name="unit" default="MILLISECONDS" displayName="Time unit of the timeout parameter">
- <c:property-options allowCustomValue="false">
- <c:option value="MICROSECONDS" name="MICROSECONDS"/>
+ <c:property-options allowCustomValue="false">
+ <c:option value="MICROSECONDS" name="MICROSECONDS"/>
<c:option value="MILLISECONDS" name="MILLISECONDS"/>
<c:option value="NANOSECONDS" name="NANOSECONDS"/>
- <c:option value="SECONDS" name="SECONDS"/>
- </c:property-options>
+ <c:option value="SECONDS" name="SECONDS"/>
+ <c:option value="HOURS" name="HOURS"/>
+ <c:option value="DAYS" name="DAYS"/>
+ </c:property-options>
</c:simple-property>
</parameters>
<results>
@@ -56,7 +58,7 @@
<results>
<c:simple-property name="result" type="boolean" description="The result of the operation" />
</results>
- </operation>
+ </operation>
<operation name="reset" displayName="Reset the node" description="Move the node out of an error state." />
<operation name="disable" displayName="Disable all webpapps" description="Disable all webapps for all engines.">
<results>
@@ -71,7 +73,6 @@
</operation>
<operation name="refresh" displayName="Refresh configuration" description="Refresh configuration" />
-
<metric property="proxyConfiguration" displayName="Proxy Configuration" displayType="summary" dataType="trait" />
<metric property="modelerType" displayName="Type of the modeled resource" displayType="summary" dataType="trait" />
<metric property="className" displayName="Fully qualified class name of the managed object" displayType="summary" dataType="trait" />
@@ -87,7 +88,7 @@
<c:simple-property name="stickySessionForce" type="boolean" description="Return an error when the request cannot be routed to the right node."/>
<c:simple-property name="balancer" type="string" required="false" description="Name of the balancer."/>
<c:simple-property name="flushPackets" type="boolean" description="Allows controlling flusing of packets."/>
- <c:simple-property name="socketTimeout" type="integer" description="Connection timeout for communication with the proxy." />
+ <c:simple-property name="socketTimeout" type="integer" description="Connection timeout for communication with the proxy." />
<c:simple-property name="domain" type="string" required="false" description="Domain parameter, which allows tying a jvmRoute to a particular domain."/>
<c:simple-property name="advertisePort" type="integer" required="false" description="Multicast port for discovery" />
<c:simple-property name="advertiseGroupAddress" type="string" required="false" description="Multicast address for discovery."/>
@@ -130,6 +131,5 @@
</operation>
</service>
-
</service>
</plugin>
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
index 57aed4d..0f644fc 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
@@ -53,6 +53,7 @@ import org.rhq.core.pluginapi.operation.OperationResult;
/**
* @author Stefan Negrea
*/
+@SuppressWarnings("rawtypes")
@Test(groups = "modcluster-plugin")
public class ModclusterPluginTest {
private Log log = LogFactory.getLog(this.getClass());
@@ -104,6 +105,8 @@ public class ModclusterPluginTest {
log.info("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
List<String> typeNames = new ArrayList<String>() {
+ private static final long serialVersionUID = 1L;
+
{
add(PLUGIN_NAME);
add(PLUGIN_NAME + " Webapp Context");
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
index df7d222..625d8d4 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
@@ -21,8 +21,6 @@ package org.rhq.plugins.modcluster.test;
import java.io.IOException;
import java.io.InputStream;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
import org.testng.annotations.Test;
import org.rhq.plugins.modcluster.ProxyInfo;
@@ -32,7 +30,6 @@ import org.rhq.plugins.modcluster.ProxyInfo;
*/
@Test(groups = "modcluster-plugin")
public class ProxyInfoTest {
- private Log log = LogFactory.getLog(this.getClass());
@Test
public void testProxyInfo() throws Exception {
commit d8c6f150e4e80fa19842708e1adf65ddbb9499fa
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Tue Jul 26 15:08:59 2011 -0500
Adding jvmRoute in the mix for webapp context identification. jvmRoute uniquely identifies nodes in a cluster and will be used to decide which contexts run on the node monitored by RHQ.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
index 7cefa46..35ecf30 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
@@ -25,8 +25,10 @@ package org.rhq.plugins.modcluster;
import java.util.HashSet;
import java.util.Set;
+import org.mc4j.ems.connection.EmsConnection;
import org.mc4j.ems.connection.bean.EmsBean;
+import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
@@ -37,26 +39,78 @@ import org.rhq.plugins.jmx.MBeanResourceComponent;
*
* @author Stefan Negrea
*/
+@SuppressWarnings("rawtypes")
public class ContextDiscoveryComponent implements ResourceDiscoveryComponent<MBeanResourceComponent> {
+ private final String JVM_ROUTE_PROPERTY = "jvmRoute";
+ private final String PROXY_INFO_PROPERTY = "proxyInfo";
+ private final String ADDITIONAL_CONFIG_BEAN_PROPERTY = "additionalConfigurationObjectName";
+
/* (non-Javadoc)
* @see org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent#discoverResources(org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext)
*/
public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext<MBeanResourceComponent> context) {
- Set<DiscoveredResourceDetails> entities = new HashSet<DiscoveredResourceDetails>();
+ String jvmRoute = this.getJvmRoute(context);
+ String rawProxyInfo = this.getRawProxyInfo(context);
- EmsBean statsBean = context.getParentResourceComponent().getEmsBean();
-
- String rawProxyInfo = (String) statsBean.getAttribute("proxyInfo").refresh().toString();
ProxyInfo proxyInfo = new ProxyInfo(rawProxyInfo);
+ Set<DiscoveredResourceDetails> entities = new HashSet<DiscoveredResourceDetails>();
for (ProxyInfo.Context availableContext : proxyInfo.getAvailableContexts()) {
DiscoveredResourceDetails detail = new DiscoveredResourceDetails(context.getResourceType(),
- availableContext.toString(), availableContext.toString(), null, "mod_cluster Webapp Context", null,
+ availableContext.createKey(), availableContext.createName(), null, "mod_cluster Webapp Context", null,
null);
entities.add(detail);
}
return entities;
}
+
+ /**
+ * Retrieves the jvm route for the node from the parent context.
+ *
+ * @param context the discovery context
+ * @return node's jvm route
+ */
+ private String getJvmRoute(ResourceDiscoveryContext<MBeanResourceComponent> context) {
+ Configuration pluginConfig = context.getParentResourceComponent().getResourceContext().getPluginConfiguration();
+ String objectName = pluginConfig.getSimple(ADDITIONAL_CONFIG_BEAN_PROPERTY).getStringValue();
+ EmsBean engineBean = this.loadBean(objectName, context.getParentResourceComponent());
+
+ return (String) engineBean.getAttribute(JVM_ROUTE_PROPERTY).refresh().toString();
+ }
+
+ /**
+ * Retrieves raw proxy configuration from the parent context.
+ *
+ * @param context the discovery context
+ * @return raw proxy configuration
+ */
+ private String getRawProxyInfo(ResourceDiscoveryContext<MBeanResourceComponent> context) {
+ EmsBean statsBean = context.getParentResourceComponent().getEmsBean();
+ return (String) statsBean.getAttribute(PROXY_INFO_PROPERTY).refresh().toString();
+ }
+
+ /**
+ * Loads the bean with the given object name.
+ *
+ * Subclasses are free to override this method in order to load the bean.
+ *
+ * @param objectName the name of the bean to load
+ * @return the bean that is loaded
+ */
+ protected EmsBean loadBean(String objectName, MBeanResourceComponent context) {
+ EmsConnection emsConnection = context.getEmsConnection();
+ EmsBean bean = emsConnection.getBean(objectName);
+ if (bean == null) {
+ // In some cases, this resource component may have been discovered by some means other than querying its
+ // parent's EMSConnection (e.g. ApplicationDiscoveryComponent uses a filesystem to discover EARs and
+ // WARs that are not yet deployed). In such cases, getBean() will return null, since EMS won't have the
+ // bean in its cache. To cover such cases, make an attempt to query the underlying MBeanServer for the
+ // bean before giving up.
+ emsConnection.queryBeans(objectName);
+ bean = emsConnection.getBean(objectName);
+ }
+ return bean;
+ }
}
\ No newline at end of file
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
index 52dd287..591fef6 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
@@ -25,6 +25,7 @@ import org.rhq.plugins.jmx.MBeanResourceComponent;
* @author Stefan Negrea
*
*/
+@SuppressWarnings("rawtypes")
public class ModclusterServerComponent extends MBeanResourceComponent {
/* (non-Javadoc)
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
index 36f490d..4cca539 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
@@ -33,11 +33,35 @@ import java.util.regex.Pattern;
*/
public class ProxyInfo {
- private List<Context> availableContexts = new ArrayList<ProxyInfo.Context>();
+ private Map<String, Node> availableNodes = new HashMap<String, Node>();
private Map<String, Vhost> availableVhosts = new HashMap<String, Vhost>();
+ private List<Context> availableContexts = new ArrayList<ProxyInfo.Context>();
public ProxyInfo(String rawProxyInfo) {
- Pattern vhostPattern = Pattern.compile("Vhost.*\n");
+ parseNodes(rawProxyInfo);
+ parseVhosts(rawProxyInfo);
+ parseContexts(rawProxyInfo);
+ }
+
+ private void parseNodes(String rawProxyInfo) {
+ Pattern nodePattern = Pattern.compile("Node:.*\n");
+ Matcher nodeMatcher = nodePattern.matcher(rawProxyInfo);
+ while (nodeMatcher.find()) {
+ String rawNode = nodeMatcher.group();
+ String[] nodePieces = rawNode.split(",");
+
+ String identifier = nodePieces[0];
+ identifier = identifier.substring(identifier.indexOf("[") + 1, identifier.indexOf("]"));
+
+ String jvmRoute = nodePieces[1];
+ jvmRoute = jvmRoute.substring(jvmRoute.indexOf(':')).trim();
+
+ availableNodes.put(jvmRoute, new Node(jvmRoute, identifier));
+ }
+ }
+
+ private void parseVhosts(String rawProxyInfo) {
+ Pattern vhostPattern = Pattern.compile("Vhost:.*\n");
Matcher vhostMatcher = vhostPattern.matcher(rawProxyInfo);
while (vhostMatcher.find()) {
String rawVhost = vhostMatcher.group();
@@ -52,8 +76,10 @@ public class ProxyInfo {
availableVhosts.put(identifier, new Vhost(identifier, host));
}
+ }
- Pattern contextPattern = Pattern.compile("Context.*[\n|}]");
+ private void parseContexts(String rawProxyInfo) {
+ Pattern contextPattern = Pattern.compile("Context:.*[\n|}]");
Matcher contextMatcher = contextPattern.matcher(rawProxyInfo);
while (contextMatcher.find()) {
String rawContext = contextMatcher.group();
@@ -70,7 +96,7 @@ public class ProxyInfo {
Vhost relatedVhost = availableVhosts.get(identifier);
- availableContexts.add(new Context(relatedVhost.getHost(), actualContext, isEnabled));
+ availableContexts.add(new Context("", relatedVhost.getHost(), actualContext, isEnabled));
}
}
@@ -82,7 +108,60 @@ public class ProxyInfo {
return Collections.unmodifiableList(new ArrayList<Vhost>(availableVhosts.values()));
}
- private static class Vhost {
+ public List<Node> getAvailableNodes() {
+ return Collections.unmodifiableList(new ArrayList<Node>(availableNodes.values()));
+ }
+
+ public static class Node {
+ private String jvmRoute;
+ private String nodeId;
+
+ public Node(String jvmRoute, String nodeId) {
+ this.jvmRoute = jvmRoute;
+ this.nodeId = nodeId;
+ }
+
+ public String getNodeId() {
+ return nodeId;
+ }
+
+ public String getJvmRoute() {
+ return jvmRoute;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((jvmRoute == null) ? 0 : jvmRoute.hashCode());
+ result = prime * result + ((nodeId == null) ? 0 : nodeId.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Node other = (Node) obj;
+ if (jvmRoute == null) {
+ if (other.jvmRoute != null)
+ return false;
+ } else if (!jvmRoute.equals(other.jvmRoute))
+ return false;
+ if (nodeId == null) {
+ if (other.nodeId != null)
+ return false;
+ } else if (!nodeId.equals(other.nodeId))
+ return false;
+ return true;
+ }
+ }
+
+ public static class Vhost {
private String identifier;
private String host;
@@ -99,20 +178,52 @@ public class ProxyInfo {
return host;
}
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((host == null) ? 0 : host.hashCode());
+ result = prime * result + ((identifier == null) ? 0 : identifier.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Vhost other = (Vhost) obj;
+ if (host == null) {
+ if (other.host != null)
+ return false;
+ } else if (!host.equals(other.host))
+ return false;
+ if (identifier == null) {
+ if (other.identifier != null)
+ return false;
+ } else if (!identifier.equals(other.identifier))
+ return false;
+ return true;
+ }
}
public static class Context {
private String path;
private String host;
+ private String jvmRoute;
private boolean isEnabled;
- public Context(String host, String path) {
- this(path, host, false);
+ public Context(String jvmRoute, String host, String path) {
+ this(jvmRoute, host, path, false);
}
- public Context(String host, String path, boolean isEnabled) {
- this.path = path;
+ public Context(String jvmRoute, String host, String path, boolean isEnabled) {
+ this.jvmRoute = jvmRoute;
this.host = host;
+ this.path = path;
this.isEnabled = isEnabled;
}
@@ -124,13 +235,25 @@ public class ProxyInfo {
return host;
}
+ public String getJvmRoute() {
+ return jvmRoute;
+ }
+
public boolean isEnabled() {
return isEnabled;
}
+ public String createKey() {
+ return jvmRoute + ":" + host + ":" + path;
+ }
+
+ public String createName() {
+ return host + ":" + path;
+ }
+
@Override
public String toString() {
- return host + ":" + path;
+ return createKey();
}
@Override
@@ -138,6 +261,7 @@ public class ProxyInfo {
final int prime = 31;
int result = 1;
result = prime * result + ((host == null) ? 0 : host.hashCode());
+ result = prime * result + ((jvmRoute == null) ? 0 : jvmRoute.hashCode());
result = prime * result + ((path == null) ? 0 : path.hashCode());
return result;
}
@@ -156,6 +280,11 @@ public class ProxyInfo {
return false;
} else if (!host.equals(other.host))
return false;
+ if (jvmRoute == null) {
+ if (other.jvmRoute != null)
+ return false;
+ } else if (!jvmRoute.equals(other.jvmRoute))
+ return false;
if (path == null) {
if (other.path != null)
return false;
@@ -164,9 +293,13 @@ public class ProxyInfo {
return true;
}
- public static Context fromString(String stringRepresentation) {
- String part[] = stringRepresentation.trim().split(":");
- return new Context(part[1], part[0]);
+ public static Context fromString(String stringRepresentation) throws Exception {
+ String parts[] = stringRepresentation.trim().split(":");
+ if (parts.length < 3) {
+ throw new Exception("Parsing error. Not enough information to create a context.");
+ }
+
+ return new Context(parts[0], parts[1], parts[2]);
}
}
}
\ No newline at end of file
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index b1a0f51..3c01b30 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -25,7 +25,9 @@
<plugin-configuration>
<c:simple-property name="objectName" readOnly="true" default="Catalina:type=ModClusterListener,*"/>
- <c:simple-property name="nameTemplate" default="mod_cluster"/>
+ <c:simple-property name="additionalConfigurationObjectName" readOnly="true" default="jboss.web:type=Engine"/>
+ <c:simple-property name="jvmRoute" readOnly="false"/>
+ <c:simple-property name="nameTemplate" default="mod_cluster"/>
</plugin-configuration>
<operation name="stop" displayName="Stop all webapps" description="Gracefully stops all webapps for all engines.">
@@ -129,6 +131,5 @@
</service>
-
</service>
</plugin>
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
index 8c8c6f4..df7d222 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
@@ -35,7 +35,7 @@ public class ProxyInfoTest {
private Log log = LogFactory.getLog(this.getClass());
@Test
- public void testProxyInfo() throws IOException {
+ public void testProxyInfo() throws Exception {
String[] availableFiles = new String[] { "/proxy_config/proxy_config_1.txt", "/proxy_config/proxy_config_2.txt" };
for (String testConfigurationFile : availableFiles) {
commit 7d68fefbc54053c19fb5b4bc423599fc7f5b3055
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Fri Jul 22 14:31:38 2011 -0500
Added support for stopContext operation for webapp contexts. Updated service description. Added more complex integration tests for webapp context service.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
index 42a1d6e..23d7d62 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
@@ -18,6 +18,8 @@
*/
package org.rhq.plugins.modcluster;
+import java.util.concurrent.TimeUnit;
+
import org.mc4j.ems.connection.bean.EmsBean;
import org.rhq.core.domain.configuration.Configuration;
@@ -75,11 +77,14 @@ public class ContextComponent extends MBeanResourceComponent<MBeanResourceCompon
Object[] configuration = null;
if ("stopContext".equals(name)) {
configuration = new Object[] { context.getHost(), context.getPath(),
- parameters.getSimple("timeout").getLongValue(), parameters.getSimple("unit").getStringValue() };
+ parameters.getSimple("timeout").getLongValue(),
+ TimeUnit.valueOf(parameters.getSimple("unit").getStringValue()) };
} else {
configuration = new Object[] { context.getHost(), context.getPath() };
}
+ log.info(name + " - " + context.getHost() + " " + context.getPath());
+
ClassLoader cl = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(getEmsBean().getClass().getClassLoader());
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
index 4b3adcd..7cefa46 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
@@ -52,7 +52,8 @@ public class ContextDiscoveryComponent implements ResourceDiscoveryComponent<MBe
for (ProxyInfo.Context availableContext : proxyInfo.getAvailableContexts()) {
DiscoveredResourceDetails detail = new DiscoveredResourceDetails(context.getResourceType(),
- availableContext.toString(), availableContext.toString(), null, "mod_cluster Context", null, null);
+ availableContext.toString(), availableContext.toString(), null, "mod_cluster Webapp Context", null,
+ null);
entities.add(detail);
}
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index 70a9f2b..b1a0f51 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -2,6 +2,7 @@
<plugin name="mod_cluster"
displayName="mod_cluster"
+ description="Monitoring and management of mod_cluster plugin."
version="1.0"
package="org.rhq.plugins.modcluster"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
@@ -77,7 +78,7 @@
<c:simple-property name="workerTimeout" type="integer" description="Timeout to wait for an available worker (default is no wait)" />
<c:simple-property name="stickySession" type="boolean" description="Enables sticky session for the cluster."/>
<c:simple-property name="stickySessionRemove" type="boolean" description="Remove session when the request cannot be routed to the right node."/>
- <c:simple-property name="advertise" type="boolean" description="Enable autodiscovery of httpd servers."/>
+ <!-- c:simple-property name="advertise" type="boolean" description="Enable autodiscovery of httpd servers."/-->
<c:simple-property name="smax" type="integer" description="Maximum time on seconds for idle connections above smax."/>
<c:simple-property name="maxAttempts" type="integer" description="Maximum number of attempts to send the request to the backend server."/>
<c:simple-property name="advertiseSecurityKey" type="string" required="false" description="Security key for discovery."/>
@@ -95,7 +96,7 @@
<service name="mod_cluster Webapp Context"
discovery="ContextDiscoveryComponent"
class="ContextComponent"
- description="A mod_cluster context">
+ description="mod_cluster webapp context">
<operation name="disableContext" displayName="Disable webapp" description="Disable this webapp.">
<results>
@@ -110,7 +111,9 @@
<c:option value="MICROSECONDS" name="MICROSECONDS"/>
<c:option value="MILLISECONDS" name="MILLISECONDS"/>
<c:option value="NANOSECONDS" name="NANOSECONDS"/>
- <c:option value="SECONDS" name="SECONDS"/>
+ <c:option value="SECONDS" name="SECONDS"/>
+ <c:option value="HOURS" name="HOURS"/>
+ <c:option value="DAYS" name="DAYS"/>
</c:property-options>
</c:simple-property>
</parameters>
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
index 8bead55..57aed4d 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
@@ -33,6 +33,8 @@ import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Test;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.measurement.MeasurementData;
import org.rhq.core.domain.measurement.MeasurementDefinition;
import org.rhq.core.domain.measurement.MeasurementReport;
@@ -159,11 +161,23 @@ public class ModclusterPluginTest {
try {
OperationResult result = ((OperationFacet) resourceComponent).invokeOperation("enableContext", null);
log.info("Result of operation " + "enableContext" + " was: " + result.getSimpleResult());
+
+ Configuration config = new Configuration();
+ config.put(new PropertySimple("timeout", "1000"));
+ config.put(new PropertySimple("unit", java.util.concurrent.TimeUnit.SECONDS));
+ result = ((OperationFacet) resourceComponent).invokeOperation("stopContext", config);
+ log.info("Result of operation stopContext was: " + result.getSimpleResult());
+
+ result = ((OperationFacet) resourceComponent).invokeOperation("enableContext", null);
+ log.info("Result of operation enableContext was: " + result.getSimpleResult());
+
+ result = ((OperationFacet) resourceComponent).invokeOperation("disableContext", null);
+ log.info("Result of operation disableContext was: " + result.getSimpleResult());
+
} catch (Exception e) {
- log.info("Operation failed");
+ log.info("Operation failed. ", e);
}
- /*result = ((OperationFacet) resourceComponent).invokeOperation("disable", null);
- log.info("Result of operation test was: " + result.getSimpleResult());*/
+
}
}
commit 0963aa55fe898cab3f6a16eb6d595421abe61d76
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Tue Jul 19 23:16:19 2011 -0500
Returning back to simple availability methods (no availability collectors) after getting clarifications from the mod_cluster team with regards to JMX attributes and node refresh operations.
The simple method to get availability now works correctly for mod_cluster resources.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
index 8512ed5..42a1d6e 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
@@ -42,15 +42,19 @@ public class ContextComponent extends MBeanResourceComponent<MBeanResourceCompon
try {
Thread.currentThread().setContextClassLoader(getEmsBean().getClass().getClassLoader());
String rawProxyInfo = (String) getEmsBean().getAttribute("proxyInfo").refresh().toString();
+
ProxyInfo proxyInfo = new ProxyInfo(rawProxyInfo);
ProxyInfo.Context context = ProxyInfo.Context.fromString(resourceContext.getResourceKey());
- ProxyInfo.Context currentContext = proxyInfo.getAvailableContexts().get(
- proxyInfo.getAvailableContexts().indexOf(context));
+ int indexOfCurrentContext = proxyInfo.getAvailableContexts().indexOf(context);
+
+ if (indexOfCurrentContext != -1) {
+ ProxyInfo.Context currentContext = proxyInfo.getAvailableContexts().get(indexOfCurrentContext);
- if (currentContext.isEnabled()) {
- return AvailabilityType.UP;
+ if (currentContext.isEnabled()) {
+ return AvailabilityType.UP;
+ }
}
return AvailabilityType.DOWN;
@@ -68,12 +72,18 @@ public class ContextComponent extends MBeanResourceComponent<MBeanResourceCompon
ProxyInfo.Context context = ProxyInfo.Context.fromString(resourceContext.getResourceKey());
+ Object[] configuration = null;
+ if ("stopContext".equals(name)) {
+ configuration = new Object[] { context.getHost(), context.getPath(),
+ parameters.getSimple("timeout").getLongValue(), parameters.getSimple("unit").getStringValue() };
+ } else {
+ configuration = new Object[] { context.getHost(), context.getPath() };
+ }
+
ClassLoader cl = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(getEmsBean().getClass().getClassLoader());
-
- Object resultObject = getEmsBean().getOperation(name).invoke(
- new Object[] { context.getHost(), context.getPath() });
+ Object resultObject = getEmsBean().getOperation(name).invoke(configuration);
return new OperationResult(String.valueOf(resultObject));
} finally {
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
index e6495a1..52dd287 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
@@ -18,13 +18,7 @@
*/
package org.rhq.plugins.modcluster;
-import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.measurement.AvailabilityType;
-import org.rhq.core.pluginapi.availability.AvailabilityCollectorRunnable;
-import org.rhq.core.pluginapi.availability.AvailabilityFacet;
-import org.rhq.core.pluginapi.inventory.ResourceComponent;
-import org.rhq.core.pluginapi.inventory.ResourceContext;
-import org.rhq.core.pluginapi.operation.OperationResult;
import org.rhq.plugins.jmx.MBeanResourceComponent;
/**
@@ -33,66 +27,18 @@ import org.rhq.plugins.jmx.MBeanResourceComponent;
*/
public class ModclusterServerComponent extends MBeanResourceComponent {
- private AvailabilityCollectorRunnable availabilityCollector;
-
- /* (non-Javadoc)
- * @see org.rhq.plugins.jmx.MBeanResourceComponent#start(org.rhq.core.pluginapi.inventory.ResourceContext)
- */
- @Override
- public void start(ResourceContext context) {
-
- availabilityCollector = context.createAvailabilityCollectorRunnable(new AvailabilityFacet() {
- public AvailabilityType getAvailability() {
- try {
- OperationResult result = ModclusterServerComponent.this.invokeOperation("refresh",
- new Configuration());
-
- int numberOfAttempts = 0;
-
- //The configuration should be loaded in less than 20 attempts.
- //Only in extraneous cases (like network overload or a huge list webapp contexts)
- //it can take more than this.
- while (numberOfAttempts < 20) {
- String rawProxyInfo = (String) getEmsBean().getAttribute("proxyInfo").refresh().toString();
- ProxyInfo proxyInfo = new ProxyInfo(rawProxyInfo);
-
- if (proxyInfo.getAvailableContexts().size() != 0) {
- break;
- }
-
- numberOfAttempts++;
- Thread.sleep(2000);
- }
- } catch (Exception e) {
- log.info("mod_cluster availability update failed. Node configuration could not be refreshed.", e);
- return AvailabilityType.DOWN;
- }
-
- return ModclusterServerComponent.super.getAvailability();
- }
- }, 60000L); // 1 minute - the minimum interval allowed
-
- // Now that you've created your availability collector, you must start it. Once started,
- // it is assigned a thread in a thread pool and begins periodically collecting availability.
- availabilityCollector.start();
-
- super.start(context);
- }
-
- /**
- * Cleans the old resource context and the old MBean.
- * @see ResourceComponent#stop()
- */
- public void stop() {
- availabilityCollector.stop();
- super.stop();
- }
-
/* (non-Javadoc)
* @see org.rhq.plugins.jmx.MBeanResourceComponent#getAvailability()
*/
@Override
public AvailabilityType getAvailability() {
- return availabilityCollector.getLastKnownAvailability();
+ String rawProxyInfo = (String) getEmsBean().getAttribute("proxyInfo").refresh().toString();
+ ProxyInfo proxyInfo = new ProxyInfo(rawProxyInfo);
+
+ if (proxyInfo.getAvailableContexts().size() == 0) {
+ return AvailabilityType.DOWN;
+ }
+
+ return super.getAvailability();
}
}
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
index c517364..36f490d 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
@@ -34,7 +34,7 @@ import java.util.regex.Pattern;
public class ProxyInfo {
private List<Context> availableContexts = new ArrayList<ProxyInfo.Context>();
- private Map<String, Vhost> availableVHosts = new HashMap<String, Vhost>();
+ private Map<String, Vhost> availableVhosts = new HashMap<String, Vhost>();
public ProxyInfo(String rawProxyInfo) {
Pattern vhostPattern = Pattern.compile("Vhost.*\n");
@@ -50,7 +50,7 @@ public class ProxyInfo {
String host = vhostPieces[1].trim();
host = host.substring(host.indexOf(":") + 1).trim();
- availableVHosts.put(identifier, new Vhost(identifier, host));
+ availableVhosts.put(identifier, new Vhost(identifier, host));
}
Pattern contextPattern = Pattern.compile("Context.*[\n|}]");
@@ -68,7 +68,7 @@ public class ProxyInfo {
rawIsEnabled = rawIsEnabled.substring(rawIsEnabled.indexOf(':') + 1).trim();
boolean isEnabled = rawIsEnabled.equals("ENABLED") ? true : false;
- Vhost relatedVhost = availableVHosts.get(identifier);
+ Vhost relatedVhost = availableVhosts.get(identifier);
availableContexts.add(new Context(relatedVhost.getHost(), actualContext, isEnabled));
}
@@ -78,6 +78,10 @@ public class ProxyInfo {
return Collections.unmodifiableList(availableContexts);
}
+ public List<Vhost> getAvailableVhosts() {
+ return Collections.unmodifiableList(new ArrayList<Vhost>(availableVhosts.values()));
+ }
+
private static class Vhost {
private String identifier;
private String host;
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
index b7322bd..8bead55 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
@@ -72,7 +72,7 @@ public class ModclusterPluginTest {
log.info("...Loaded plugin: " + plugin);
}
} catch (Exception e) {
- e.printStackTrace();
+ log.info("Error initializing the context", e);
}
}
@@ -93,19 +93,13 @@ public class ModclusterPluginTest {
public void testDiscovery() throws Exception {
InventoryReport report = PluginContainer.getInstance().getInventoryManager().executeServerScanImmediately();
assert report != null;
- System.out.println("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
+ log.info("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
- Thread.sleep(10000);
+ Thread.sleep(1000);
report = PluginContainer.getInstance().getInventoryManager().executeServiceScanImmediately();
assert report != null;
- System.out.println("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
-
- Thread.sleep(10000);
-
- report = PluginContainer.getInstance().getInventoryManager().executeServiceScanImmediately();
- assert report != null;
- System.out.println("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
+ log.info("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
List<String> typeNames = new ArrayList<String>() {
{
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
index fb1ccba..8c8c6f4 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
@@ -50,10 +50,21 @@ public class ProxyInfoTest {
+ ProxyInfo.Context.class.getCanonicalName();
}
- assert (proxyInfo.getAvailableContexts().size() != 0) : "Raw proxy info parsing failed!";
+ assert (proxyInfo.getAvailableContexts().size() != 0) : "Raw proxy info parsing failed to parse application contexts!";
+ assert (proxyInfo.getAvailableVhosts().size() != 0) : "Raw proxy info parsing failed to parse vhosts!";
}
}
+ @Test
+ public void testProxyInfoWithEmptyConfig() throws IOException {
+ String testConfigurationFile = "/proxy_config/proxy_config_empty.txt";
+ String testConfiguration = readConfigFile(testConfigurationFile);
+ ProxyInfo proxyInfo = new ProxyInfo(testConfiguration);
+
+ assert (proxyInfo.getAvailableContexts().size() == 0) : "Raw proxy info parsing failed to parse an empty proxy config.";
+ assert (proxyInfo.getAvailableVhosts().size() == 0) : "Raw proxy info parsing failed to parse an empty proxy config.";
+ }
+
private String readConfigFile(String filePath) throws IOException {
StringBuffer tempBuffer = new StringBuffer();
byte[] readBuffer = new byte[1024];
commit 3de9b2c6b6d5fd3bb20104221cfb15c31a0c5207
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Fri Jul 15 15:40:54 2011 -0500
Implemented getAvailability using the async collector because there is no guarantee when node full refreshes its configuration. The configuration is read from the httpd proxy and parsed; so network latency and number of loaded contexts influence the reload time.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
index ef13143..e6495a1 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
@@ -20,6 +20,10 @@ package org.rhq.plugins.modcluster;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.pluginapi.availability.AvailabilityCollectorRunnable;
+import org.rhq.core.pluginapi.availability.AvailabilityFacet;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.core.pluginapi.operation.OperationResult;
import org.rhq.plugins.jmx.MBeanResourceComponent;
@@ -29,14 +33,66 @@ import org.rhq.plugins.jmx.MBeanResourceComponent;
*/
public class ModclusterServerComponent extends MBeanResourceComponent {
+ private AvailabilityCollectorRunnable availabilityCollector;
+
+ /* (non-Javadoc)
+ * @see org.rhq.plugins.jmx.MBeanResourceComponent#start(org.rhq.core.pluginapi.inventory.ResourceContext)
+ */
@Override
- public AvailabilityType getAvailability() {
- try {
- OperationResult result = this.invokeOperation("refresh", new Configuration());
- } catch (Exception e) {
- log.info(e);
- }
+ public void start(ResourceContext context) {
+
+ availabilityCollector = context.createAvailabilityCollectorRunnable(new AvailabilityFacet() {
+ public AvailabilityType getAvailability() {
+ try {
+ OperationResult result = ModclusterServerComponent.this.invokeOperation("refresh",
+ new Configuration());
+
+ int numberOfAttempts = 0;
+
+ //The configuration should be loaded in less than 20 attempts.
+ //Only in extraneous cases (like network overload or a huge list webapp contexts)
+ //it can take more than this.
+ while (numberOfAttempts < 20) {
+ String rawProxyInfo = (String) getEmsBean().getAttribute("proxyInfo").refresh().toString();
+ ProxyInfo proxyInfo = new ProxyInfo(rawProxyInfo);
+
+ if (proxyInfo.getAvailableContexts().size() != 0) {
+ break;
+ }
+
+ numberOfAttempts++;
+ Thread.sleep(2000);
+ }
+ } catch (Exception e) {
+ log.info("mod_cluster availability update failed. Node configuration could not be refreshed.", e);
+ return AvailabilityType.DOWN;
+ }
+
+ return ModclusterServerComponent.super.getAvailability();
+ }
+ }, 60000L); // 1 minute - the minimum interval allowed
- return super.getAvailability();
+ // Now that you've created your availability collector, you must start it. Once started,
+ // it is assigned a thread in a thread pool and begins periodically collecting availability.
+ availabilityCollector.start();
+
+ super.start(context);
+ }
+
+ /**
+ * Cleans the old resource context and the old MBean.
+ * @see ResourceComponent#stop()
+ */
+ public void stop() {
+ availabilityCollector.stop();
+ super.stop();
+ }
+
+ /* (non-Javadoc)
+ * @see org.rhq.plugins.jmx.MBeanResourceComponent#getAvailability()
+ */
+ @Override
+ public AvailabilityType getAvailability() {
+ return availabilityCollector.getLastKnownAvailability();
}
}
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
index 874011a..b7322bd 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
@@ -87,7 +87,6 @@ public class ModclusterPluginTest {
PluginEnvironment pluginEnvironment = pluginManager.getPlugin(PLUGIN_NAME);
assert (pluginEnvironment != null) : "Null environment, plugin not loaded";
assert (pluginEnvironment.getPluginName().equals(PLUGIN_NAME));
-
}
@Test(dependsOnMethods = "testPluginLoad")
@@ -96,6 +95,14 @@ public class ModclusterPluginTest {
assert report != null;
System.out.println("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
+ Thread.sleep(10000);
+
+ report = PluginContainer.getInstance().getInventoryManager().executeServiceScanImmediately();
+ assert report != null;
+ System.out.println("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
+
+ Thread.sleep(10000);
+
report = PluginContainer.getInstance().getInventoryManager().executeServiceScanImmediately();
assert report != null;
System.out.println("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
@@ -103,7 +110,7 @@ public class ModclusterPluginTest {
List<String> typeNames = new ArrayList<String>() {
{
add(PLUGIN_NAME);
- add(PLUGIN_NAME + "_context");
+ add(PLUGIN_NAME + " Webapp Context");
}
};
diff --git a/modules/plugins/mod-cluster/src/test/resources/proxy_config/proxy_config_empty.txt b/modules/plugins/mod-cluster/src/test/resources/proxy_config/proxy_config_empty.txt
new file mode 100644
index 0000000..815b8a4
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/test/resources/proxy_config/proxy_config_empty.txt
@@ -0,0 +1 @@
+{192.168.0.101/192.168.0.101:6666=null}
commit c6cf04fe0acc2d3f05a7bc028bae794b6cb34801
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Mon Jul 11 15:33:59 2011 -0500
A couple of small configuration and test corrections.
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index cf12b89..70a9f2b 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -60,7 +60,7 @@
<c:simple-property name="result" type="boolean" description="The result of the operation" />
</results>
</operation>
- <operation name="refreshProxy" displayName="Remove a proxy" description="Remove a proxy.">
+ <operation name="removeProxy" displayName="Remove a proxy" description="Remove a proxy.">
<parameters>
<c:simple-property required="true" name="host" type="string" displayName="Proxy address"/>
<c:simple-property required="true" name="port" type="string" displayName="Proxy port"/>
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
index 41bf26a..fb1ccba 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
@@ -36,7 +36,6 @@ public class ProxyInfoTest {
@Test
public void testProxyInfo() throws IOException {
-
String[] availableFiles = new String[] { "/proxy_config/proxy_config_1.txt", "/proxy_config/proxy_config_2.txt" };
for (String testConfigurationFile : availableFiles) {
@@ -44,10 +43,6 @@ public class ProxyInfoTest {
ProxyInfo proxyInfo = new ProxyInfo(testConfiguration);
for (ProxyInfo.Context context : proxyInfo.getAvailableContexts()) {
- log.info(context.toString() + " - " + context.isEnabled());
-
- log.info(proxyInfo.getAvailableContexts().indexOf(context));
-
assert (proxyInfo.getAvailableContexts().indexOf(context) != -1) : "Equals and hash functions not implemented correctly for "
+ ProxyInfo.Context.class.getCanonicalName();
commit 5c794ba6bc45e518200acc7d78f1fec86869becb
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Mon Jul 11 15:33:39 2011 -0500
The configuration needs to be refreshed before computing availability on all the contexts. Attempt to correctly invoke the operation.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
index 783f579..ef13143 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
@@ -18,6 +18,9 @@
*/
package org.rhq.plugins.modcluster;
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.pluginapi.operation.OperationResult;
import org.rhq.plugins.jmx.MBeanResourceComponent;
/**
@@ -25,4 +28,15 @@ import org.rhq.plugins.jmx.MBeanResourceComponent;
*
*/
public class ModclusterServerComponent extends MBeanResourceComponent {
+
+ @Override
+ public AvailabilityType getAvailability() {
+ try {
+ OperationResult result = this.invokeOperation("refresh", new Configuration());
+ } catch (Exception e) {
+ log.info(e);
+ }
+
+ return super.getAvailability();
+ }
}
commit f4c3e963d2d00b2f02986ba8ea593c1aa2c02893
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Mon Jul 11 13:23:22 2011 -0500
Added availability attribute for contexts. Also improved unit test and coverage.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
index 922197a..8512ed5 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
@@ -21,6 +21,7 @@ package org.rhq.plugins.modcluster;
import org.mc4j.ems.connection.bean.EmsBean;
import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.pluginapi.operation.OperationResult;
import org.rhq.plugins.jmx.MBeanResourceComponent;
@@ -36,18 +37,43 @@ public class ContextComponent extends MBeanResourceComponent<MBeanResourceCompon
}
@Override
+ public AvailabilityType getAvailability() {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ try {
+ Thread.currentThread().setContextClassLoader(getEmsBean().getClass().getClassLoader());
+ String rawProxyInfo = (String) getEmsBean().getAttribute("proxyInfo").refresh().toString();
+ ProxyInfo proxyInfo = new ProxyInfo(rawProxyInfo);
+
+ ProxyInfo.Context context = ProxyInfo.Context.fromString(resourceContext.getResourceKey());
+
+ ProxyInfo.Context currentContext = proxyInfo.getAvailableContexts().get(
+ proxyInfo.getAvailableContexts().indexOf(context));
+
+ if (currentContext.isEnabled()) {
+ return AvailabilityType.UP;
+ }
+
+ return AvailabilityType.DOWN;
+ } catch (Exception e) {
+ log.info(e);
+ return AvailabilityType.DOWN;
+ } finally {
+ Thread.currentThread().setContextClassLoader(cl);
+ }
+ }
+
+ @Override
public OperationResult invokeOperation(String name, Configuration parameters) throws Exception {
if ("enableContext".equals(name) || "disableContext".equals(name) || "stopContext".equals(name)) {
ProxyInfo.Context context = ProxyInfo.Context.fromString(resourceContext.getResourceKey());
- System.out.println(context.toString());
ClassLoader cl = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(getEmsBean().getClass().getClassLoader());
Object resultObject = getEmsBean().getOperation(name).invoke(
- new Object[] { context.host, context.path });
+ new Object[] { context.getHost(), context.getPath() });
return new OperationResult(String.valueOf(resultObject));
} finally {
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
index 40b24f9..c517364 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
@@ -50,9 +50,7 @@ public class ProxyInfo {
String host = vhostPieces[1].trim();
host = host.substring(host.indexOf(":") + 1).trim();
- System.out.println(identifier + "--" + host);
availableVHosts.put(identifier, new Vhost(identifier, host));
-
}
Pattern contextPattern = Pattern.compile("Context.*[\n|}]");
@@ -65,9 +63,14 @@ public class ProxyInfo {
String identifier = contextPieces[0];
identifier = identifier.substring(identifier.indexOf("[") + 1, identifier.indexOf("]"));
identifier = identifier.substring(0, identifier.lastIndexOf(":"));
+
+ String rawIsEnabled = contextPieces[2];
+ rawIsEnabled = rawIsEnabled.substring(rawIsEnabled.indexOf(':') + 1).trim();
+ boolean isEnabled = rawIsEnabled.equals("ENABLED") ? true : false;
+
Vhost relatedVhost = availableVHosts.get(identifier);
- availableContexts.add(new Context(relatedVhost.getHost(), actualContext));
+ availableContexts.add(new Context(relatedVhost.getHost(), actualContext, isEnabled));
}
}
@@ -95,12 +98,18 @@ public class ProxyInfo {
}
public static class Context {
- String path;
- String host;
+ private String path;
+ private String host;
+ private boolean isEnabled;
public Context(String host, String path) {
+ this(path, host, false);
+ }
+
+ public Context(String host, String path, boolean isEnabled) {
this.path = path;
this.host = host;
+ this.isEnabled = isEnabled;
}
public String getPath() {
@@ -111,14 +120,49 @@ public class ProxyInfo {
return host;
}
+ public boolean isEnabled() {
+ return isEnabled;
+ }
+
@Override
public String toString() {
return host + ":" + path;
}
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((host == null) ? 0 : host.hashCode());
+ result = prime * result + ((path == null) ? 0 : path.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Context other = (Context) obj;
+ if (host == null) {
+ if (other.host != null)
+ return false;
+ } else if (!host.equals(other.host))
+ return false;
+ if (path == null) {
+ if (other.path != null)
+ return false;
+ } else if (!path.equals(other.path))
+ return false;
+ return true;
+ }
+
public static Context fromString(String stringRepresentation) {
String part[] = stringRepresentation.trim().split(":");
- return new Context(part[0], part[1]);
+ return new Context(part[1], part[0]);
}
}
}
\ No newline at end of file
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
index be5e987..41bf26a 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
@@ -37,15 +37,26 @@ public class ProxyInfoTest {
@Test
public void testProxyInfo() throws IOException {
- String testConfiguration = readConfigFile("/proxy_config/proxy_config_1.txt");
+ String[] availableFiles = new String[] { "/proxy_config/proxy_config_1.txt", "/proxy_config/proxy_config_2.txt" };
- ProxyInfo proxyInfo = new ProxyInfo(testConfiguration);
+ for (String testConfigurationFile : availableFiles) {
+ String testConfiguration = readConfigFile(testConfigurationFile);
+ ProxyInfo proxyInfo = new ProxyInfo(testConfiguration);
- for (ProxyInfo.Context context : proxyInfo.getAvailableContexts()) {
- log.info(context.toString());
- }
+ for (ProxyInfo.Context context : proxyInfo.getAvailableContexts()) {
+ log.info(context.toString() + " - " + context.isEnabled());
+
+ log.info(proxyInfo.getAvailableContexts().indexOf(context));
+
+ assert (proxyInfo.getAvailableContexts().indexOf(context) != -1) : "Equals and hash functions not implemented correctly for "
+ + ProxyInfo.Context.class.getCanonicalName();
- assert (proxyInfo.getAvailableContexts().size() != 0) : "Raw proxy info parsing failed!";
+ assert (context.equals(ProxyInfo.Context.fromString(context.toString())) == true) : "fromString and toString are not equivalent for:"
+ + ProxyInfo.Context.class.getCanonicalName();
+ }
+
+ assert (proxyInfo.getAvailableContexts().size() != 0) : "Raw proxy info parsing failed!";
+ }
}
private String readConfigFile(String filePath) throws IOException {
diff --git a/modules/plugins/mod-cluster/src/test/resources/proxy_config/proxy_config_2.txt b/modules/plugins/mod-cluster/src/test/resources/proxy_config/proxy_config_2.txt
new file mode 100644
index 0000000..573967a
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/test/resources/proxy_config/proxy_config_2.txt
@@ -0,0 +1,16 @@
+{mobile-work/192.168.1.40:6666=Node: [1],Name: 4e6189af-0502-3305-8ff3-fad7fee8b516,Balancer: mycluster,LBGroup: ,Host: 127.0.0.1,Port: 8009,Type: ajp,Flushpackets: Off,Flushwait: 10,Ping: 10,Smax: 26,Ttl: 60,Elected: 3690,Read: 27864911,Transfered: 0,Connected: 0,Load: 100
+Node: [2],Name: node2,Balancer: mycluster,LBGroup: ,Host: 127.0.0.1,Port: 8009,Type: ajp,Flushpackets: Off,Flushwait: 10,Ping: 10,Smax: 26,Ttl: 60,Elected: 148,Read: 57994,Transfered: 0,Connected: 0,Load: 100
+Vhost: [1:1:1], Alias: test-agent-1
+Vhost: [2:1:2], Alias: remote-agent-2
+Context: [1:1:1], Context: /invoker, Status: DISABLED
+Context: [1:1:2], Context: /loaddemo, Status: DISABLED
+Context: [1:1:3], Context: /jbossws, Status: DISABLED
+Context: [1:1:4], Context: /juddi, Status: DISABLED
+Context: [1:1:5], Context: /jbossmq-httpil, Status: DISABLED
+Context: [1:1:6], Context: /web-console, Status: DISABLED
+Context: [1:1:7], Context: /jmx-console, Status: DISABLED
+Context: [1:1:8], Context: /, Status: DISABLED
+Context: [2:1:9], Context: /, Status: ENABLED
+Context: [2:1:10], Context: /loaddemo, Status: ENABLED
+Context: [2:1:11], Context: /juddi, Status: ENABLED
+Context: [2:1:12], Context: /invoker, Status: ENABLED}
\ No newline at end of file
commit 066d08cc62c780b42ea8650c046eaa30efb6c9a7
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Thu Jul 7 16:37:41 2011 -0500
Created separate unit test suite for proxy info parser. Also, the code now parses the vhost from the actual config property.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
index f2af2bc..40b24f9 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
@@ -20,7 +20,9 @@ package org.rhq.plugins.modcluster;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -32,17 +34,40 @@ import java.util.regex.Pattern;
public class ProxyInfo {
private List<Context> availableContexts = new ArrayList<ProxyInfo.Context>();
+ private Map<String, Vhost> availableVHosts = new HashMap<String, Vhost>();
public ProxyInfo(String rawProxyInfo) {
+ Pattern vhostPattern = Pattern.compile("Vhost.*\n");
+ Matcher vhostMatcher = vhostPattern.matcher(rawProxyInfo);
+ while (vhostMatcher.find()) {
+ String rawVhost = vhostMatcher.group();
+ String[] vhostPieces = rawVhost.split(",");
- Pattern test = Pattern.compile("Context.*\n");
- Matcher m = test.matcher(rawProxyInfo);
- while (m.find()) {
- String rawContext = m.group();
+ String identifier = vhostPieces[0].trim();
+ identifier = identifier.substring(identifier.indexOf("[") + 1, identifier.indexOf("]"));
+ identifier = identifier.substring(0, identifier.lastIndexOf(":"));
+
+ String host = vhostPieces[1].trim();
+ host = host.substring(host.indexOf(":") + 1).trim();
+
+ System.out.println(identifier + "--" + host);
+ availableVHosts.put(identifier, new Vhost(identifier, host));
+
+ }
+
+ Pattern contextPattern = Pattern.compile("Context.*[\n|}]");
+ Matcher contextMatcher = contextPattern.matcher(rawProxyInfo);
+ while (contextMatcher.find()) {
+ String rawContext = contextMatcher.group();
String[] contextPieces = rawContext.split(",");
String actualContext = contextPieces[1].substring(contextPieces[1].indexOf("/")).trim();
- availableContexts.add(new Context("localhost", actualContext));
+ String identifier = contextPieces[0];
+ identifier = identifier.substring(identifier.indexOf("[") + 1, identifier.indexOf("]"));
+ identifier = identifier.substring(0, identifier.lastIndexOf(":"));
+ Vhost relatedVhost = availableVHosts.get(identifier);
+
+ availableContexts.add(new Context(relatedVhost.getHost(), actualContext));
}
}
@@ -50,6 +75,25 @@ public class ProxyInfo {
return Collections.unmodifiableList(availableContexts);
}
+ private static class Vhost {
+ private String identifier;
+ private String host;
+
+ public Vhost(String identifier, String host) {
+ this.identifier = identifier;
+ this.host = host;
+ }
+
+ public String getIdentifier() {
+ return identifier;
+ }
+
+ public String getHost() {
+ return host;
+ }
+
+ }
+
public static class Context {
String path;
String host;
@@ -63,18 +107,10 @@ public class ProxyInfo {
return path;
}
- public void setPath(String path) {
- this.path = path;
- }
-
public String getHost() {
return host;
}
- public void setHost(String host) {
- this.host = host;
- }
-
@Override
public String toString() {
return host + ":" + path;
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
index 0d16e92..874011a 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
@@ -47,10 +47,9 @@ import org.rhq.core.pluginapi.inventory.ResourceComponent;
import org.rhq.core.pluginapi.measurement.MeasurementFacet;
import org.rhq.core.pluginapi.operation.OperationFacet;
import org.rhq.core.pluginapi.operation.OperationResult;
-import org.rhq.plugins.modcluster.ProxyInfo;
/**
- * @author Fady Matar
+ * @author Stefan Negrea
*/
@Test(groups = "modcluster-plugin")
public class ModclusterPluginTest {
@@ -83,31 +82,6 @@ public class ModclusterPluginTest {
}
@Test
- public void testProxyInfo() {
- String test = "{mobile-work/192.168.1.40:6666=Node: [1],Name: 4e6189af-0502-3305-8ff3-fad7fee8b516,Balancer: mycluster,LBGroup: ,Host: 127.0.0.1,Port: 8009,Type: ajp,Flushpackets: Off,Flushwait: 10,Ping: 10,Smax: 26,Ttl: 60,Elected: 3233,Read: 7355619,Transfered: 0,Connected: 0,Load: 100\n"
- + "Node: [2],Name: node2,Balancer: mycluster,LBGroup: ,Host: 127.0.0.1,Port: 8009,Type: ajp,Flushpackets: Off,Flushwait: 10,Ping: 10,Smax: 26,Ttl: 60,Elected: 0,Read: 0,Transfered: 0,Connected: 0,Load: 99\n"
- + "Vhost: [1:1:1], Alias: localhost\n"
- + "Vhost: [2:1:2], Alias: localhost\n"
- + "Context: [1:1:1], Context: /invoker, Status: DISABLED\n"
- + "Context: [1:1:2], Context: /loaddemo, Status: DISABLED\n"
- + "Context: [1:1:3], Context: /jbossws, Status: DISABLED\n"
- + "Context: [1:1:4], Context: /juddi, Status: DISABLED\n"
- + "Context: [1:1:5], Context: /jbossmq-httpil, Status: DISABLED\n"
- + "Context: [1:1:6], Context: /web-console, Status: DISABLED\n"
- + "Context: [1:1:7], Context: /jmx-console, Status: DISABLED\n"
- + "Context: [1:1:8], Context: /, Status: DISABLED\n"
- + "Context: [2:1:9], Context: /loaddemo, Status: ENABLED\n" + "}";
-
- ProxyInfo proxyInfo = new ProxyInfo(test);
-
- for (ProxyInfo.Context context : proxyInfo.getAvailableContexts()) {
- log.info(context.toString());
- }
-
- assert (proxyInfo.getAvailableContexts().size() != 0) : "Raw proxy info parsing failed!";
- }
-
- @Test
public void testPluginLoad() {
PluginManager pluginManager = PluginContainer.getInstance().getPluginManager();
PluginEnvironment pluginEnvironment = pluginManager.getPlugin(PLUGIN_NAME);
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
new file mode 100644
index 0000000..be5e987
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
@@ -0,0 +1,66 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.modcluster.test;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.testng.annotations.Test;
+
+import org.rhq.plugins.modcluster.ProxyInfo;
+
+/**
+ * @author Stefan Negrea
+ */
+@Test(groups = "modcluster-plugin")
+public class ProxyInfoTest {
+ private Log log = LogFactory.getLog(this.getClass());
+
+ @Test
+ public void testProxyInfo() throws IOException {
+
+ String testConfiguration = readConfigFile("/proxy_config/proxy_config_1.txt");
+
+ ProxyInfo proxyInfo = new ProxyInfo(testConfiguration);
+
+ for (ProxyInfo.Context context : proxyInfo.getAvailableContexts()) {
+ log.info(context.toString());
+ }
+
+ assert (proxyInfo.getAvailableContexts().size() != 0) : "Raw proxy info parsing failed!";
+ }
+
+ private String readConfigFile(String filePath) throws IOException {
+ StringBuffer tempBuffer = new StringBuffer();
+ byte[] readBuffer = new byte[1024];
+ int bytesRead = 0;
+
+ InputStream resourceStream = getClass().getResourceAsStream(filePath);
+
+ while ((bytesRead = resourceStream.read(readBuffer)) != -1) {
+ tempBuffer.append(new String(readBuffer, 0, bytesRead));
+ }
+
+ resourceStream.close();
+
+ return tempBuffer.toString();
+ }
+}
\ No newline at end of file
diff --git a/modules/plugins/mod-cluster/src/test/resources/proxy_config/proxy_config_1.txt b/modules/plugins/mod-cluster/src/test/resources/proxy_config/proxy_config_1.txt
new file mode 100644
index 0000000..c99edd3
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/test/resources/proxy_config/proxy_config_1.txt
@@ -0,0 +1,13 @@
+{mobile-work/192.168.1.40:6666=Node: [1],Name: 4e6189af-0502-3305-8ff3-fad7fee8b516,Balancer: mycluster,LBGroup: ,Host: 127.0.0.1,Port: 8009,Type: ajp,Flushpackets: Off,Flushwait: 10,Ping: 10,Smax: 26,Ttl: 60,Elected: 3233,Read: 7355619,Transfered: 0,Connected: 0,Load: 100
+Node: [2],Name: node2,Balancer: mycluster,LBGroup: ,Host: 127.0.0.1,Port: 8009,Type: ajp,Flushpackets: Off,Flushwait: 10,Ping: 10,Smax: 26,Ttl: 60,Elected: 0,Read: 0,Transfered: 0,Connected: 0,Load: 99
+Vhost: [1:1:1], Alias: localhost
+Vhost: [2:1:2], Alias: localhost
+Context: [1:1:1], Context: /invoker, Status: DISABLED
+Context: [1:1:2], Context: /loaddemo, Status: DISABLED
+Context: [1:1:3], Context: /jbossws, Status: DISABLED
+Context: [1:1:4], Context: /juddi, Status: DISABLED
+Context: [1:1:5], Context: /jbossmq-httpil, Status: DISABLED
+Context: [1:1:6], Context: /web-console, Status: DISABLED
+Context: [1:1:7], Context: /jmx-console, Status: DISABLED
+Context: [1:1:8], Context: /, Status: DISABLED
+Context: [2:1:9], Context: /loaddemo, Status: ENABLED}
\ No newline at end of file
commit a6eeb51869e48dc230cd206d7f25eb815538b2bf
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Thu Jul 7 13:27:01 2011 -0600
Fine tunning the plugin based on UI testing.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
index fb72b5f..f2af2bc 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
@@ -77,7 +77,7 @@ public class ProxyInfo {
@Override
public String toString() {
- return path + ":" + host;
+ return host + ":" + path;
}
public static Context fromString(String stringRepresentation) {
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index 88357db..cf12b89 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -80,15 +80,14 @@
<c:simple-property name="advertise" type="boolean" description="Enable autodiscovery of httpd servers."/>
<c:simple-property name="smax" type="integer" description="Maximum time on seconds for idle connections above smax."/>
<c:simple-property name="maxAttempts" type="integer" description="Maximum number of attempts to send the request to the backend server."/>
- <c:simple-property name="advertiseSecurityKey" type="integer" description="Security key for discovery."/>
+ <c:simple-property name="advertiseSecurityKey" type="string" required="false" description="Security key for discovery."/>
<c:simple-property name="stickySessionForce" type="boolean" description="Return an error when the request cannot be routed to the right node."/>
- <c:simple-property name="balancer" type="string" description="Name of the balancer."/>
+ <c:simple-property name="balancer" type="string" required="false" description="Name of the balancer."/>
<c:simple-property name="flushPackets" type="boolean" description="Allows controlling flusing of packets."/>
- <c:simple-property name="socketTimeout" type="integer" description="Connection timeout for communication with the proxy." />
- <c:simple-property name="containerName" type="string" description="Object name of the container."/>
- <c:simple-property name="domain" type="string" description="Domain parameter, which allows tying a jvmRoute to a particular domain."/>
- <c:simple-property name="advertisePort" type="integer" description="Multicast port for discovery" />
- <c:simple-property name="advertiseGroupAddress" type="string" description="Multicast address for discovery."/>
+ <c:simple-property name="socketTimeout" type="integer" description="Connection timeout for communication with the proxy." />
+ <c:simple-property name="domain" type="string" required="false" description="Domain parameter, which allows tying a jvmRoute to a particular domain."/>
+ <c:simple-property name="advertisePort" type="integer" required="false" description="Multicast port for discovery" />
+ <c:simple-property name="advertiseGroupAddress" type="string" required="false" description="Multicast address for discovery."/>
<c:simple-property name="flushWait" type="integer" description="Time in ms to wait before flushing packets."/>
<c:simple-property name="ping" type="integer" description="Time in s to wait for a pong answer to a ping."/>
</resource-configuration>
commit c294e9ec57a4be4d969d8fa453e353f1f39fda8a
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Thu Jul 7 10:38:53 2011 -0600
Changed the name of context objects to the proposed short notation.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
index 9cb6b86..fb72b5f 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
@@ -42,7 +42,7 @@ public class ProxyInfo {
String[] contextPieces = rawContext.split(",");
String actualContext = contextPieces[1].substring(contextPieces[1].indexOf("/")).trim();
- availableContexts.add(new Context(actualContext, "localhost"));
+ availableContexts.add(new Context("localhost", actualContext));
}
}
@@ -54,7 +54,7 @@ public class ProxyInfo {
String path;
String host;
- public Context(String path, String host) {
+ public Context(String host, String path) {
this.path = path;
this.host = host;
}
@@ -77,25 +77,12 @@ public class ProxyInfo {
@Override
public String toString() {
- return "Context [path=" + path + ", host=" + host + "]";
+ return path + ":" + host;
}
public static Context fromString(String stringRepresentation) {
- stringRepresentation = stringRepresentation.substring(stringRepresentation.indexOf('[') + 1);
- stringRepresentation = stringRepresentation.substring(0, stringRepresentation.indexOf(']'));
- stringRepresentation = stringRepresentation.trim();
-
- String host = null;
- String path = null;
- for (String part : stringRepresentation.split(",")) {
- part = part.trim();
- if (part.startsWith("path=")) {
- path = part.substring(5).trim();
- } else if (part.startsWith("host=")) {
- host = part.substring(5).trim();
- }
- }
- return new Context(path, host);
+ String part[] = stringRepresentation.trim().split(":");
+ return new Context(part[0], part[1]);
}
}
}
\ No newline at end of file
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index ad23d34..88357db 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -74,7 +74,7 @@
<metric property="className" displayName="Fully qualified class name of the managed object" displayType="summary" dataType="trait" />
<resource-configuration>
- <c:simple-property name="workerTimeout" type="integer" description="Timeout to wait for an available worker (default is no wait)"
+ <c:simple-property name="workerTimeout" type="integer" description="Timeout to wait for an available worker (default is no wait)" />
<c:simple-property name="stickySession" type="boolean" description="Enables sticky session for the cluster."/>
<c:simple-property name="stickySessionRemove" type="boolean" description="Remove session when the request cannot be routed to the right node."/>
<c:simple-property name="advertise" type="boolean" description="Enable autodiscovery of httpd servers."/>
@@ -83,7 +83,7 @@
<c:simple-property name="advertiseSecurityKey" type="integer" description="Security key for discovery."/>
<c:simple-property name="stickySessionForce" type="boolean" description="Return an error when the request cannot be routed to the right node."/>
<c:simple-property name="balancer" type="string" description="Name of the balancer."/>
- <c:simple-property name="flushPackets" type="boolean" descritpion="Allows controlling flusing of packets."/>
+ <c:simple-property name="flushPackets" type="boolean" description="Allows controlling flusing of packets."/>
<c:simple-property name="socketTimeout" type="integer" description="Connection timeout for communication with the proxy." />
<c:simple-property name="containerName" type="string" description="Object name of the container."/>
<c:simple-property name="domain" type="string" description="Domain parameter, which allows tying a jvmRoute to a particular domain."/>
commit 70f87fe4818e8a4b6dbef2c479aacf992bb71df7
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Thu Jul 7 10:23:06 2011 -0600
Added support for all the mod_cluster available operations.
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index 17a4267..ad23d34 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -27,41 +27,70 @@
<c:simple-property name="nameTemplate" default="mod_cluster"/>
</plugin-configuration>
- <operation name="reset" displayName="Reset the node" description="Move the node out of an error state" />
- <operation name="refresh" displayName="Refresh configuration" description="Refresh configuration" />
- <operation name="enable" displayName="Enable all webapps" description="Enable all webapps for all engines">
+ <operation name="stop" displayName="Stop all webapps" description="Gracefully stops all webapps for all engines.">
+ <parameters>
+ <c:simple-property required="true" name="timeout" type="string" displayName="Session draining timeout"/>
+ <c:simple-property required="true" name="unit" default="MILLISECONDS" displayName="Time unit of the timeout parameter">
+ <c:property-options allowCustomValue="false">
+ <c:option value="MICROSECONDS" name="MICROSECONDS"/>
+ <c:option value="MILLISECONDS" name="MILLISECONDS"/>
+ <c:option value="NANOSECONDS" name="NANOSECONDS"/>
+ <c:option value="SECONDS" name="SECONDS"/>
+ </c:property-options>
+ </c:simple-property>
+ </parameters>
+ <results>
+ <c:simple-property name="result" type="boolean" description="The result of the operation" />
+ </results>
+ </operation>
+ <operation name="addProxy" displayName="Add a proxy" description="Add a proxy.">
+ <parameters>
+ <c:simple-property required="true" name="host" type="string" displayName="Proxy address"/>
+ <c:simple-property required="true" name="port" type="string" displayName="Proxy port"/>
+ </parameters>
+ </operation>
+ <operation name="enable" displayName="Enable all webapps" description="Enable all webapps for all engines">
<results>
<c:simple-property name="result" type="boolean" description="The result of the operation" />
</results>
- </operation>
- <operation name="disable" displayName="Disable all webpapps" description="Disable all webapps for all engines">
+ </operation>
+ <operation name="reset" displayName="Reset the node" description="Move the node out of an error state." />
+ <operation name="disable" displayName="Disable all webpapps" description="Disable all webapps for all engines.">
<results>
<c:simple-property name="result" type="boolean" description="The result of the operation" />
</results>
</operation>
+ <operation name="refreshProxy" displayName="Remove a proxy" description="Remove a proxy.">
+ <parameters>
+ <c:simple-property required="true" name="host" type="string" displayName="Proxy address"/>
+ <c:simple-property required="true" name="port" type="string" displayName="Proxy port"/>
+ </parameters>
+ </operation>
+ <operation name="refresh" displayName="Refresh configuration" description="Refresh configuration" />
+
<metric property="proxyConfiguration" displayName="Proxy Configuration" displayType="summary" dataType="trait" />
<metric property="modelerType" displayName="Type of the modeled resource" displayType="summary" dataType="trait" />
<metric property="className" displayName="Fully qualified class name of the managed object" displayType="summary" dataType="trait" />
<resource-configuration>
- <c:simple-property name="workerTimeout" type="int" description="Timeout to wait for an available worker (default is no wait)"
+ <c:simple-property name="workerTimeout" type="integer" description="Timeout to wait for an available worker (default is no wait)"
<c:simple-property name="stickySession" type="boolean" description="Enables sticky session for the cluster."/>
<c:simple-property name="stickySessionRemove" type="boolean" description="Remove session when the request cannot be routed to the right node."/>
<c:simple-property name="advertise" type="boolean" description="Enable autodiscovery of httpd servers."/>
- <c:simple-property name="smax" type="int" description="Maximum time on seconds for idle connections above smax."/>
- <c:simple-property name="maxAttempts" type="int" description="Maximum number of attempts to send the request to the backend server."/>
- <c:simple-property name="advertiseSecurityKey" type="int" description="Security key for discovery."/>
+ <c:simple-property name="smax" type="integer" description="Maximum time on seconds for idle connections above smax."/>
+ <c:simple-property name="maxAttempts" type="integer" description="Maximum number of attempts to send the request to the backend server."/>
+ <c:simple-property name="advertiseSecurityKey" type="integer" description="Security key for discovery."/>
<c:simple-property name="stickySessionForce" type="boolean" description="Return an error when the request cannot be routed to the right node."/>
<c:simple-property name="balancer" type="string" description="Name of the balancer."/>
<c:simple-property name="flushPackets" type="boolean" descritpion="Allows controlling flusing of packets."/>
- <c:simple-property name="socketTimeout" type="int" description="Connection timeout for communication with the proxy." />
+ <c:simple-property name="socketTimeout" type="integer" description="Connection timeout for communication with the proxy." />
<c:simple-property name="containerName" type="string" description="Object name of the container."/>
<c:simple-property name="domain" type="string" description="Domain parameter, which allows tying a jvmRoute to a particular domain."/>
- <c:simple-property name="advertisePort" type="int" description="Multicast port for discovery" />
+ <c:simple-property name="advertisePort" type="integer" description="Multicast port for discovery" />
<c:simple-property name="advertiseGroupAddress" type="string" description="Multicast address for discovery."/>
- <c:simple-property name="flushWait" type="int" description="Time in ms to wait before flushing packets."/>
- <c:simple-property name="ping" type="int" description="Time in s to wait for a pong answer to a ping"/>
+ <c:simple-property name="flushWait" type="integer" description="Time in ms to wait before flushing packets."/>
+ <c:simple-property name="ping" type="integer" description="Time in s to wait for a pong answer to a ping."/>
</resource-configuration>
<service name="mod_cluster Webapp Context"
@@ -69,19 +98,30 @@
class="ContextComponent"
description="A mod_cluster context">
- <operation name="enableContext" displayName="Enable webapp" description="Enable this webapp">
+ <operation name="disableContext" displayName="Disable webapp" description="Disable this webapp.">
<results>
- <c:simple-property name="result" type="boolean" description="The result of the operation" />
+ <c:simple-property name="result" type="boolean" description="The result of the operation."/>
</results>
</operation>
- <operation name="disableContext" displayName="Disable webapp" description="Disable this webapp">
+ <operation name="stopContext" displayName="Stop webapp" description="Gracefully stops this webapp.">
+ <parameters>
+ <c:simple-property required="true" name="timeout" type="integer" displayName="Session draining timeout"/>
+ <c:simple-property required="true" name="unit" default="MILLISECONDS" displayName="Time unit of the timeout parameter">
+ <c:property-options allowCustomValue="false">
+ <c:option value="MICROSECONDS" name="MICROSECONDS"/>
+ <c:option value="MILLISECONDS" name="MILLISECONDS"/>
+ <c:option value="NANOSECONDS" name="NANOSECONDS"/>
+ <c:option value="SECONDS" name="SECONDS"/>
+ </c:property-options>
+ </c:simple-property>
+ </parameters>
<results>
<c:simple-property name="result" type="boolean" description="The result of the operation" />
</results>
</operation>
- <operation name="stopContext" displayName="Stop webapp" description="Gracefully stops this webapp.">
+ <operation name="enableContext" displayName="Enable webapp" description="Enable this webapp.">
<results>
- <c:simple-property name="result" type="boolean" description="The result of the operation" />
+ <c:simple-property name="result" type="boolean" description="The result of the operation" />
</results>
</operation>
commit 2342ca9a222b3aae20a890d084a7855ce4ff02fd
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Thu Jul 7 09:49:10 2011 -0600
Added all the properties available through the JMX interface to the plugin configuration.
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index b2179c3..17a4267 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -45,9 +45,23 @@
<metric property="className" displayName="Fully qualified class name of the managed object" displayType="summary" dataType="trait" />
<resource-configuration>
- <c:simple-property name="stickySessions" type="boolean" description="Enables sticky sessions."/>
+ <c:simple-property name="workerTimeout" type="int" description="Timeout to wait for an available worker (default is no wait)"
+ <c:simple-property name="stickySession" type="boolean" description="Enables sticky session for the cluster."/>
<c:simple-property name="stickySessionRemove" type="boolean" description="Remove session when the request cannot be routed to the right node."/>
<c:simple-property name="advertise" type="boolean" description="Enable autodiscovery of httpd servers."/>
+ <c:simple-property name="smax" type="int" description="Maximum time on seconds for idle connections above smax."/>
+ <c:simple-property name="maxAttempts" type="int" description="Maximum number of attempts to send the request to the backend server."/>
+ <c:simple-property name="advertiseSecurityKey" type="int" description="Security key for discovery."/>
+ <c:simple-property name="stickySessionForce" type="boolean" description="Return an error when the request cannot be routed to the right node."/>
+ <c:simple-property name="balancer" type="string" description="Name of the balancer."/>
+ <c:simple-property name="flushPackets" type="boolean" descritpion="Allows controlling flusing of packets."/>
+ <c:simple-property name="socketTimeout" type="int" description="Connection timeout for communication with the proxy." />
+ <c:simple-property name="containerName" type="string" description="Object name of the container."/>
+ <c:simple-property name="domain" type="string" description="Domain parameter, which allows tying a jvmRoute to a particular domain."/>
+ <c:simple-property name="advertisePort" type="int" description="Multicast port for discovery" />
+ <c:simple-property name="advertiseGroupAddress" type="string" description="Multicast address for discovery."/>
+ <c:simple-property name="flushWait" type="int" description="Time in ms to wait before flushing packets."/>
+ <c:simple-property name="ping" type="int" description="Time in s to wait for a pong answer to a ping"/>
</resource-configuration>
<service name="mod_cluster Webapp Context"
@@ -55,17 +69,17 @@
class="ContextComponent"
description="A mod_cluster context">
- <operation name="enableContext" displayName="Enable webapp" description="Enable the webapp">
+ <operation name="enableContext" displayName="Enable webapp" description="Enable this webapp">
<results>
<c:simple-property name="result" type="boolean" description="The result of the operation" />
</results>
</operation>
- <operation name="disableContext" displayName="Disable webpapp" description="Disable the webapp">
+ <operation name="disableContext" displayName="Disable webapp" description="Disable this webapp">
<results>
<c:simple-property name="result" type="boolean" description="The result of the operation" />
</results>
</operation>
- <operation name="stopContext" displayName="Stop webpapp" description="Gracefully stops the webapp">
+ <operation name="stopContext" displayName="Stop webapp" description="Gracefully stops this webapp.">
<results>
<c:simple-property name="result" type="boolean" description="The result of the operation" />
</results>
commit 526d7241227292380f1ccd644d5f3e0b41eda7d3
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Wed Jul 6 15:28:48 2011 -0500
A couple more tweaks to make the user interface for mod_cluster display correct and proper text.
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index cdfa7fb..b2179c3 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -24,7 +24,7 @@
<plugin-configuration>
<c:simple-property name="objectName" readOnly="true" default="Catalina:type=ModClusterListener,*"/>
- <c:simple-property name="nameTemplate" default="{application}"/>
+ <c:simple-property name="nameTemplate" default="mod_cluster"/>
</plugin-configuration>
<operation name="reset" displayName="Reset the node" description="Move the node out of an error state" />
@@ -50,22 +50,22 @@
<c:simple-property name="advertise" type="boolean" description="Enable autodiscovery of httpd servers."/>
</resource-configuration>
- <service name="mod_cluster_context"
+ <service name="mod_cluster Webapp Context"
discovery="ContextDiscoveryComponent"
class="ContextComponent"
description="A mod_cluster context">
- <operation name="enableContext" displayName="Enable webapp" description="Enable a single webapp">
+ <operation name="enableContext" displayName="Enable webapp" description="Enable the webapp">
<results>
<c:simple-property name="result" type="boolean" description="The result of the operation" />
</results>
</operation>
- <operation name="disableContext" displayName="Disable webpapp" description="Disable a single webapp">
+ <operation name="disableContext" displayName="Disable webpapp" description="Disable the webapp">
<results>
<c:simple-property name="result" type="boolean" description="The result of the operation" />
</results>
</operation>
- <operation name="stopContext" displayName="Stop webpapp" description="Gracefully stops a single webapp">
+ <operation name="stopContext" displayName="Stop webpapp" description="Gracefully stops the webapp">
<results>
<c:simple-property name="result" type="boolean" description="The result of the operation" />
</results>
commit 4a6bb37c939ba001b3be6774cf89d1ec409f2827
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Wed Jul 6 13:19:07 2011 -0500
Fine tuning the plugin configuration based other plugin configuration and test deployment issues.
diff --git a/modules/plugins/mod-cluster/pom.xml b/modules/plugins/mod-cluster/pom.xml
index 74defeb..4536125 100644
--- a/modules/plugins/mod-cluster/pom.xml
+++ b/modules/plugins/mod-cluster/pom.xml
@@ -12,7 +12,7 @@
<artifactId>modcluster-plugin</artifactId>
<packaging>jar</packaging>
- <name>mod_cluster RHQ Plugin</name>
+ <name>RHQ mod_cluster Plugin</name>
<description>mod_cluster RHQ Agent plugin</description>
<dependencies>
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index be4b25b..cdfa7fb 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -14,11 +14,12 @@
discovery="org.rhq.plugins.jmx.MBeanResourceDiscoveryComponent"
class="ModclusterServerComponent"
supportsManualAdd="true"
- description="mod_cluster plugin">
+ description="mod_cluster plugin"
+ singleton="true">
<runs-inside>
<parent-resource-type name="JBossAS Server" plugin="JBossAS"/>
- <parent-resource-type name="JBossAS Server" plugin="JBossAS5"/>
+ <parent-resource-type name="JBossAS5 Server" plugin="JBossAS5"/>
</runs-inside>
<plugin-configuration>
diff --git a/modules/plugins/pom.xml b/modules/plugins/pom.xml
index 02f6584..f32159e 100644
--- a/modules/plugins/pom.xml
+++ b/modules/plugins/pom.xml
@@ -125,10 +125,11 @@
<module>augeas</module>
<module>apache</module>
<module>tomcat</module>
- <module>jboss-as</module>
<module>hibernate</module>
+ <module>mod-cluster</module>
<module>rhq-server</module>
<module>jboss-cache</module>
+ <module>jboss-as</module>
<module>jboss-as-5</module>
<module>jboss-as-7</module>
<module>jboss-cache-v3</module>
commit 20f0f36e49fa935deafed1fc2ac057f7e480dd9a
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Wed Jul 6 10:00:21 2011 -0500
Added dev profile for plugin deployment in the local plugin repo.
diff --git a/modules/plugins/mod-cluster/pom.xml b/modules/plugins/mod-cluster/pom.xml
index a19dfc0..74defeb 100644
--- a/modules/plugins/mod-cluster/pom.xml
+++ b/modules/plugins/mod-cluster/pom.xml
@@ -190,6 +190,82 @@
</plugins>
</build>
</profile>
+
+
+ <profile>
+ <id>dev</id>
+
+ <properties>
+ <rhq.rootDir>../../..</rhq.rootDir>
+ <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir>
+ <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/rhq-downloads/rhq-plugins</rhq.deploymentDir>
+ </properties>
+
+ <build>
+ <plugins>
+
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.1</version>
+ <executions>
+
+ <execution>
+ <id>deploy</id>
+ <phase>compile</phase>
+ <configuration>
+ <tasks>
+ <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}" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ <execution>
+ <id>deploy-jar-meta-inf</id>
+ <phase>package</phase>
+ <configuration>
+ <tasks>
+ <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>
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ <execution>
+ <id>undeploy</id>
+ <phase>clean</phase>
+ <configuration>
+ <tasks>
+ <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
+ <echo>*** Deleting ${deployment.file}...</echo>
+ <delete file="${deployment.file}" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ </executions>
+ </plugin>
+
+ </plugins>
+ </build>
+ </profile>
+
</profiles>
</project>
commit 4ee3094d6e29330d68730729edaa04e4a85cc81d
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Tue Jul 5 23:31:24 2011 -0500
All the context dependent operations are now passed for execution to the parent MBean. The operation arguments are parsed from the proxyInfo MBean property.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
index f73a151..922197a 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
@@ -1,24 +1,20 @@
/*
- * Jopr Management Platform
+ * RHQ Management Platform
* Copyright (C) 2005-2008 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation, and/or the GNU Lesser
- * General Public License, version 2.1, also as published by the Free
- * Software Foundation.
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License and the GNU Lesser General Public License
- * for more details.
+ * GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * and the GNU Lesser General Public License along with this program;
- * if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.rhq.plugins.modcluster;
@@ -29,10 +25,9 @@ import org.rhq.core.pluginapi.operation.OperationResult;
import org.rhq.plugins.jmx.MBeanResourceComponent;
/**
- * Manages a Hibernate Entity.
+ * Manages a mod_cluster context entity.
*
- * @author Greg Hinkle
- * @author John Mazzitelli
+ * @author Stefan Negrea
*/
public class ContextComponent extends MBeanResourceComponent<MBeanResourceComponent> {
@Override
@@ -42,46 +37,24 @@ public class ContextComponent extends MBeanResourceComponent<MBeanResourceCompon
@Override
public OperationResult invokeOperation(String name, Configuration parameters) throws Exception {
- if ("enableContext".equals(name)) {
- //String[] queryStrings = (String[]) getEmsBean().getAttribute("Queries").refresh();
- OperationResult result = new OperationResult();
- result.setSimpleResult("This works!");
- /*PropertyList queries = new PropertyList("queries");
- result.getComplexResults().put(queries);*/
+ if ("enableContext".equals(name) || "disableContext".equals(name) || "stopContext".equals(name)) {
+
+ ProxyInfo.Context context = ProxyInfo.Context.fromString(resourceContext.getResourceKey());
+ System.out.println(context.toString());
ClassLoader cl = Thread.currentThread().getContextClassLoader();
try {
- /*Thread.currentThread().setContextClassLoader(getEmsBean().getClass().getClassLoader());
- for (String queryString : queryStrings) {
- Object queryStatistics = getEmsBean().getOperation("getQueryStatistics").invoke(
- new Object[] { queryString });
-
- Long executionCount = (Long) queryStatistics.getClass().getMethod("getExecutionCount")
- .invoke(queryStatistics);
- Long executionRowCount = (Long) queryStatistics.getClass().getMethod("getExecutionRowCount")
- .invoke(queryStatistics);
- Long executionMinTime = (Long) queryStatistics.getClass().getMethod("getExecutionMinTime")
- .invoke(queryStatistics);
- Long executionMaxTime = (Long) queryStatistics.getClass().getMethod("getExecutionMaxTime")
- .invoke(queryStatistics);
- Long executionAvgTime = (Long) queryStatistics.getClass().getMethod("getExecutionAvgTime")
- .invoke(queryStatistics);
-
- PropertyMap query = new PropertyMap("query", new PropertySimple("query", queryString),
- new PropertySimple("executionCount", executionCount), new PropertySimple("executionRowCount",
- executionRowCount), new PropertySimple("executionMinTime", executionMinTime),
- new PropertySimple("executionMaxTime", executionMaxTime), new PropertySimple(
- "executionAvgTime", executionAvgTime));
+ Thread.currentThread().setContextClassLoader(getEmsBean().getClass().getClassLoader());
- queries.add(query);
- }*/
+ Object resultObject = getEmsBean().getOperation(name).invoke(
+ new Object[] { context.host, context.path });
- return result;
+ return new OperationResult(String.valueOf(resultObject));
} finally {
Thread.currentThread().setContextClassLoader(cl);
}
}
- return super.invokeOperation(name, parameters);
+ throw new Exception("Operation " + name + " not available mod_cluster_context service");
}
}
\ No newline at end of file
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
index 90e5c6b..4b3adcd 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
@@ -33,11 +33,15 @@ import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
import org.rhq.plugins.jmx.MBeanResourceComponent;
/**
- * Discovers hibernate entities from a hibernate stats mbean
+ * Discovers mod_cluster contexts from the proxyInfo mbean property.
*
- * @author Greg Hinkle
+ * @author Stefan Negrea
*/
public class ContextDiscoveryComponent implements ResourceDiscoveryComponent<MBeanResourceComponent> {
+
+ /* (non-Javadoc)
+ * @see org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent#discoverResources(org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext)
+ */
public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext<MBeanResourceComponent> context) {
Set<DiscoveredResourceDetails> entities = new HashSet<DiscoveredResourceDetails>();
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
index 15a9a68..9cb6b86 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
@@ -16,7 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
package org.rhq.plugins.modcluster;
import java.util.ArrayList;
@@ -25,16 +24,17 @@ import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+/**
+ * Simple parser for the raw proxy information provided by mod_cluster.
+ *
+ * @author Stefan Negrea
+ */
public class ProxyInfo {
private List<Context> availableContexts = new ArrayList<ProxyInfo.Context>();
public ProxyInfo(String rawProxyInfo) {
- System.out.println("--------------------------------------");
- System.out.println(rawProxyInfo);
- System.out.println("--------------------------------------");
-
Pattern test = Pattern.compile("Context.*\n");
Matcher m = test.matcher(rawProxyInfo);
while (m.find()) {
@@ -42,7 +42,7 @@ public class ProxyInfo {
String[] contextPieces = rawContext.split(",");
String actualContext = contextPieces[1].substring(contextPieces[1].indexOf("/")).trim();
- availableContexts.add(new Context(actualContext, "localHost"));
+ availableContexts.add(new Context(actualContext, "localhost"));
}
}
@@ -50,12 +50,11 @@ public class ProxyInfo {
return Collections.unmodifiableList(availableContexts);
}
- public class Context {
+ public static class Context {
String path;
String host;
public Context(String path, String host) {
- super();
this.path = path;
this.host = host;
}
@@ -80,5 +79,23 @@ public class ProxyInfo {
public String toString() {
return "Context [path=" + path + ", host=" + host + "]";
}
+
+ public static Context fromString(String stringRepresentation) {
+ stringRepresentation = stringRepresentation.substring(stringRepresentation.indexOf('[') + 1);
+ stringRepresentation = stringRepresentation.substring(0, stringRepresentation.indexOf(']'));
+ stringRepresentation = stringRepresentation.trim();
+
+ String host = null;
+ String path = null;
+ for (String part : stringRepresentation.split(",")) {
+ part = part.trim();
+ if (part.startsWith("path=")) {
+ path = part.substring(5).trim();
+ } else if (part.startsWith("host=")) {
+ host = part.substring(5).trim();
+ }
+ }
+ return new Context(path, host);
+ }
}
}
\ No newline at end of file
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index 084165e..be4b25b 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -45,6 +45,8 @@
<resource-configuration>
<c:simple-property name="stickySessions" type="boolean" description="Enables sticky sessions."/>
+ <c:simple-property name="stickySessionRemove" type="boolean" description="Remove session when the request cannot be routed to the right node."/>
+ <c:simple-property name="advertise" type="boolean" description="Enable autodiscovery of httpd servers."/>
</resource-configuration>
<service name="mod_cluster_context"
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
index deceb70..0d16e92 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
@@ -140,8 +140,14 @@ public class ModclusterPluginTest {
assert (resources.size() != 0) : "No mod_cluster or related instances found.";
if (resources.size() != 0) {
- testResourceMeasurement((Resource) resources.toArray()[0]);
- testContextOperations((Resource) resources.toArray()[1]);
+ for (Object objectResource : resources.toArray()) {
+ Resource resource = (Resource) objectResource;
+ if (resource.getResourceType().getName().equals("mod_cluster")) {
+ testResourceMeasurement(resource);
+ } else {
+ testContextOperations(resource);
+ }
+ }
}
}
@@ -175,9 +181,12 @@ public class ModclusterPluginTest {
.getResourceComponent(resource);
if (resourceComponent instanceof OperationFacet) {
- OperationResult result = ((OperationFacet) resourceComponent).invokeOperation("enableContext", null);
- log.info("Result of operation " + "enableContext" + " was: " + result.getSimpleResult());
-
+ try {
+ OperationResult result = ((OperationFacet) resourceComponent).invokeOperation("enableContext", null);
+ log.info("Result of operation " + "enableContext" + " was: " + result.getSimpleResult());
+ } catch (Exception e) {
+ log.info("Operation failed");
+ }
/*result = ((OperationFacet) resourceComponent).invokeOperation("disable", null);
log.info("Result of operation test was: " + result.getSimpleResult());*/
}
commit 821df1aa30368c6d97eacad1401a52295e6d2181
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Tue Jul 5 18:43:06 2011 -0500
Added individual contexts as sub services to mod_cluster service.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
new file mode 100644
index 0000000..f73a151
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
@@ -0,0 +1,87 @@
+/*
+ * Jopr Management Platform
+ * Copyright (C) 2005-2008 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.rhq.plugins.modcluster;
+
+import org.mc4j.ems.connection.bean.EmsBean;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.pluginapi.operation.OperationResult;
+import org.rhq.plugins.jmx.MBeanResourceComponent;
+
+/**
+ * Manages a Hibernate Entity.
+ *
+ * @author Greg Hinkle
+ * @author John Mazzitelli
+ */
+public class ContextComponent extends MBeanResourceComponent<MBeanResourceComponent> {
+ @Override
+ protected EmsBean loadBean() {
+ return getResourceContext().getParentResourceComponent().getEmsBean();
+ }
+
+ @Override
+ public OperationResult invokeOperation(String name, Configuration parameters) throws Exception {
+ if ("enableContext".equals(name)) {
+ //String[] queryStrings = (String[]) getEmsBean().getAttribute("Queries").refresh();
+ OperationResult result = new OperationResult();
+ result.setSimpleResult("This works!");
+ /*PropertyList queries = new PropertyList("queries");
+ result.getComplexResults().put(queries);*/
+
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ try {
+ /*Thread.currentThread().setContextClassLoader(getEmsBean().getClass().getClassLoader());
+ for (String queryString : queryStrings) {
+ Object queryStatistics = getEmsBean().getOperation("getQueryStatistics").invoke(
+ new Object[] { queryString });
+
+ Long executionCount = (Long) queryStatistics.getClass().getMethod("getExecutionCount")
+ .invoke(queryStatistics);
+ Long executionRowCount = (Long) queryStatistics.getClass().getMethod("getExecutionRowCount")
+ .invoke(queryStatistics);
+ Long executionMinTime = (Long) queryStatistics.getClass().getMethod("getExecutionMinTime")
+ .invoke(queryStatistics);
+ Long executionMaxTime = (Long) queryStatistics.getClass().getMethod("getExecutionMaxTime")
+ .invoke(queryStatistics);
+ Long executionAvgTime = (Long) queryStatistics.getClass().getMethod("getExecutionAvgTime")
+ .invoke(queryStatistics);
+
+ PropertyMap query = new PropertyMap("query", new PropertySimple("query", queryString),
+ new PropertySimple("executionCount", executionCount), new PropertySimple("executionRowCount",
+ executionRowCount), new PropertySimple("executionMinTime", executionMinTime),
+ new PropertySimple("executionMaxTime", executionMaxTime), new PropertySimple(
+ "executionAvgTime", executionAvgTime));
+
+ queries.add(query);
+ }*/
+
+ return result;
+ } finally {
+ Thread.currentThread().setContextClassLoader(cl);
+ }
+ }
+
+ return super.invokeOperation(name, parameters);
+ }
+}
\ No newline at end of file
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
new file mode 100644
index 0000000..90e5c6b
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
@@ -0,0 +1,57 @@
+/*
+ * Jopr Management Platform
+ * Copyright (C) 2005-2008 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.rhq.plugins.modcluster;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.mc4j.ems.connection.bean.EmsBean;
+
+import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+import org.rhq.plugins.jmx.MBeanResourceComponent;
+
+/**
+ * Discovers hibernate entities from a hibernate stats mbean
+ *
+ * @author Greg Hinkle
+ */
+public class ContextDiscoveryComponent implements ResourceDiscoveryComponent<MBeanResourceComponent> {
+ public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext<MBeanResourceComponent> context) {
+ Set<DiscoveredResourceDetails> entities = new HashSet<DiscoveredResourceDetails>();
+
+ EmsBean statsBean = context.getParentResourceComponent().getEmsBean();
+
+ String rawProxyInfo = (String) statsBean.getAttribute("proxyInfo").refresh().toString();
+ ProxyInfo proxyInfo = new ProxyInfo(rawProxyInfo);
+
+ for (ProxyInfo.Context availableContext : proxyInfo.getAvailableContexts()) {
+ DiscoveredResourceDetails detail = new DiscoveredResourceDetails(context.getResourceType(),
+ availableContext.toString(), availableContext.toString(), null, "mod_cluster Context", null, null);
+ entities.add(detail);
+ }
+
+ return entities;
+ }
+}
\ No newline at end of file
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
index a98792e..783f579 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
@@ -18,9 +18,6 @@
*/
package org.rhq.plugins.modcluster;
-import org.rhq.core.domain.operation.OperationDefinition;
-import org.rhq.core.pluginapi.inventory.ResourceComponent;
-import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.plugins.jmx.MBeanResourceComponent;
/**
@@ -28,16 +25,4 @@ import org.rhq.plugins.jmx.MBeanResourceComponent;
*
*/
public class ModclusterServerComponent extends MBeanResourceComponent {
-
- /**
- * Stores the context and loads the MBean.
- * @see ResourceComponent#start(ResourceContext)
- */
- @Override
- public void start(ResourceContext context) {
- super.start(context);
-
- OperationDefinition test = new OperationDefinition(context.getResourceType(), "Text");
- context.getResourceType().addOperationDefinition(test);
- }
}
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
new file mode 100644
index 0000000..15a9a68
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
@@ -0,0 +1,84 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.modcluster;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class ProxyInfo {
+
+ private List<Context> availableContexts = new ArrayList<ProxyInfo.Context>();
+
+ public ProxyInfo(String rawProxyInfo) {
+
+ System.out.println("--------------------------------------");
+ System.out.println(rawProxyInfo);
+ System.out.println("--------------------------------------");
+
+ Pattern test = Pattern.compile("Context.*\n");
+ Matcher m = test.matcher(rawProxyInfo);
+ while (m.find()) {
+ String rawContext = m.group();
+ String[] contextPieces = rawContext.split(",");
+ String actualContext = contextPieces[1].substring(contextPieces[1].indexOf("/")).trim();
+
+ availableContexts.add(new Context(actualContext, "localHost"));
+ }
+ }
+
+ public List<Context> getAvailableContexts() {
+ return Collections.unmodifiableList(availableContexts);
+ }
+
+ public class Context {
+ String path;
+ String host;
+
+ public Context(String path, String host) {
+ super();
+ this.path = path;
+ this.host = host;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public void setPath(String path) {
+ this.path = path;
+ }
+
+ public String getHost() {
+ return host;
+ }
+
+ public void setHost(String host) {
+ this.host = host;
+ }
+
+ @Override
+ public String toString() {
+ return "Context [path=" + path + ", host=" + host + "]";
+ }
+ }
+}
\ No newline at end of file
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index b8d7249..084165e 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -47,5 +47,29 @@
<c:simple-property name="stickySessions" type="boolean" description="Enables sticky sessions."/>
</resource-configuration>
+ <service name="mod_cluster_context"
+ discovery="ContextDiscoveryComponent"
+ class="ContextComponent"
+ description="A mod_cluster context">
+
+ <operation name="enableContext" displayName="Enable webapp" description="Enable a single webapp">
+ <results>
+ <c:simple-property name="result" type="boolean" description="The result of the operation" />
+ </results>
+ </operation>
+ <operation name="disableContext" displayName="Disable webpapp" description="Disable a single webapp">
+ <results>
+ <c:simple-property name="result" type="boolean" description="The result of the operation" />
+ </results>
+ </operation>
+ <operation name="stopContext" displayName="Stop webpapp" description="Gracefully stops a single webapp">
+ <results>
+ <c:simple-property name="result" type="boolean" description="The result of the operation" />
+ </results>
+ </operation>
+
+ </service>
+
+
</service>
</plugin>
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
index da0303e..deceb70 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
@@ -19,8 +19,10 @@
package org.rhq.plugins.modcluster.test;
import java.io.File;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
+import java.util.List;
import java.util.Queue;
import java.util.Set;
@@ -45,6 +47,7 @@ import org.rhq.core.pluginapi.inventory.ResourceComponent;
import org.rhq.core.pluginapi.measurement.MeasurementFacet;
import org.rhq.core.pluginapi.operation.OperationFacet;
import org.rhq.core.pluginapi.operation.OperationResult;
+import org.rhq.plugins.modcluster.ProxyInfo;
/**
* @author Fady Matar
@@ -80,6 +83,31 @@ public class ModclusterPluginTest {
}
@Test
+ public void testProxyInfo() {
+ String test = "{mobile-work/192.168.1.40:6666=Node: [1],Name: 4e6189af-0502-3305-8ff3-fad7fee8b516,Balancer: mycluster,LBGroup: ,Host: 127.0.0.1,Port: 8009,Type: ajp,Flushpackets: Off,Flushwait: 10,Ping: 10,Smax: 26,Ttl: 60,Elected: 3233,Read: 7355619,Transfered: 0,Connected: 0,Load: 100\n"
+ + "Node: [2],Name: node2,Balancer: mycluster,LBGroup: ,Host: 127.0.0.1,Port: 8009,Type: ajp,Flushpackets: Off,Flushwait: 10,Ping: 10,Smax: 26,Ttl: 60,Elected: 0,Read: 0,Transfered: 0,Connected: 0,Load: 99\n"
+ + "Vhost: [1:1:1], Alias: localhost\n"
+ + "Vhost: [2:1:2], Alias: localhost\n"
+ + "Context: [1:1:1], Context: /invoker, Status: DISABLED\n"
+ + "Context: [1:1:2], Context: /loaddemo, Status: DISABLED\n"
+ + "Context: [1:1:3], Context: /jbossws, Status: DISABLED\n"
+ + "Context: [1:1:4], Context: /juddi, Status: DISABLED\n"
+ + "Context: [1:1:5], Context: /jbossmq-httpil, Status: DISABLED\n"
+ + "Context: [1:1:6], Context: /web-console, Status: DISABLED\n"
+ + "Context: [1:1:7], Context: /jmx-console, Status: DISABLED\n"
+ + "Context: [1:1:8], Context: /, Status: DISABLED\n"
+ + "Context: [2:1:9], Context: /loaddemo, Status: ENABLED\n" + "}";
+
+ ProxyInfo proxyInfo = new ProxyInfo(test);
+
+ for (ProxyInfo.Context context : proxyInfo.getAvailableContexts()) {
+ log.info(context.toString());
+ }
+
+ assert (proxyInfo.getAvailableContexts().size() != 0) : "Raw proxy info parsing failed!";
+ }
+
+ @Test
public void testPluginLoad() {
PluginManager pluginManager = PluginContainer.getInstance().getPluginManager();
PluginEnvironment pluginEnvironment = pluginManager.getPlugin(PLUGIN_NAME);
@@ -98,12 +126,22 @@ public class ModclusterPluginTest {
assert report != null;
System.out.println("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
+ List<String> typeNames = new ArrayList<String>() {
+ {
+ add(PLUGIN_NAME);
+ add(PLUGIN_NAME + "_context");
+ }
+ };
+
Set<Resource> resources = findResource(PluginContainer.getInstance().getInventoryManager().getPlatform(),
- PLUGIN_NAME);
- log.info("Found " + resources.size() + " mod_cluster instance(s).");
+ typeNames);
+ log.info("Found " + resources.size() + " mod_cluster and mod_cluster_context instance(s).");
+
+ assert (resources.size() != 0) : "No mod_cluster or related instances found.";
if (resources.size() != 0) {
testResourceMeasurement((Resource) resources.toArray()[0]);
+ testContextOperations((Resource) resources.toArray()[1]);
}
}
@@ -132,7 +170,20 @@ public class ModclusterPluginTest {
}
}
- private Set<Resource> findResource(Resource parent, String typeName) {
+ private void testContextOperations(Resource resource) throws Exception {
+ ResourceComponent resourceComponent = PluginContainer.getInstance().getInventoryManager()
+ .getResourceComponent(resource);
+
+ if (resourceComponent instanceof OperationFacet) {
+ OperationResult result = ((OperationFacet) resourceComponent).invokeOperation("enableContext", null);
+ log.info("Result of operation " + "enableContext" + " was: " + result.getSimpleResult());
+
+ /*result = ((OperationFacet) resourceComponent).invokeOperation("disable", null);
+ log.info("Result of operation test was: " + result.getSimpleResult());*/
+ }
+ }
+
+ private Set<Resource> findResource(Resource parent, List<String> typeNames) {
Set<Resource> found = new HashSet<Resource>();
Queue<Resource> discoveryQueue = new LinkedList<Resource>();
@@ -142,7 +193,7 @@ public class ModclusterPluginTest {
Resource currentResource = discoveryQueue.poll();
log.info("Discovered resource of type: " + currentResource.getResourceType().getName());
- if (currentResource.getResourceType().getName().equals(typeName)) {
+ if (typeNames.contains(currentResource.getResourceType().getName())) {
found.add(currentResource);
}
commit d2b8d0f801936bfc318be141737aa237bc7d7b74
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Tue Jul 5 15:46:03 2011 -0500
Attempt to manually manipulate the operations list for mod_cluster to dynamically load the contexts.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
index c70f53b..a98792e 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
@@ -18,6 +18,9 @@
*/
package org.rhq.plugins.modcluster;
+import org.rhq.core.domain.operation.OperationDefinition;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.plugins.jmx.MBeanResourceComponent;
/**
@@ -26,4 +29,15 @@ import org.rhq.plugins.jmx.MBeanResourceComponent;
*/
public class ModclusterServerComponent extends MBeanResourceComponent {
+ /**
+ * Stores the context and loads the MBean.
+ * @see ResourceComponent#start(ResourceContext)
+ */
+ @Override
+ public void start(ResourceContext context) {
+ super.start(context);
+
+ OperationDefinition test = new OperationDefinition(context.getResourceType(), "Text");
+ context.getResourceType().addOperationDefinition(test);
+ }
}
commit 384ac9ada9f59a2f2f1cbd52088c81044ba2038c
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Tue Jul 5 15:45:23 2011 -0500
Added simple operations to the list of operations supported by the plugin. Complex operations to follow....
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterDiscoveryComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterDiscoveryComponent.java
deleted file mode 100644
index fa807a3..0000000
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterDiscoveryComponent.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 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.modcluster;
-
-import java.util.HashSet;
-import java.util.List;
-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.pluginapi.inventory.DiscoveredResourceDetails;
-import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
-import org.rhq.core.pluginapi.inventory.ManualAddFacet;
-import org.rhq.core.pluginapi.inventory.ProcessScanResult;
-import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
-import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
-
-/**
- * This can be the start of your own custom plugin's discovery component. Review the javadoc for
- * {@link ResourceDiscoveryComponent}.
- *
- * @author John Mazzitelli
- */
-@SuppressWarnings("unchecked")
-public class ModclusterDiscoveryComponent implements ResourceDiscoveryComponent, ManualAddFacet {
- private final Log log = LogFactory.getLog(ModclusterDiscoveryComponent.class);
-
- /**
- * This discovery method is the way the plugin supports "manual-add" capability. The plugin
- * descriptor must specify supportsManualAdd="true" to allow the resource to be manually added.
- * If that attribute is false, this method will never be used since it will not be possible to manually
- * add an instance of the resource.
- *
- * Review the javadoc for both {@link ManualAddFacet} and {@link ResourceDiscoveryContext} to learn what
- * you need to do in this method.
- *
- * @see ManualAddFacet#discoverResource(Configuration, ResourceDiscoveryContext)
- */
- @Override
- public DiscoveredResourceDetails discoverResource(Configuration pluginConfiguration,
- ResourceDiscoveryContext context) throws InvalidPluginConfigurationException {
-
- // pluginConfiguration contains information on a resource that was manually added by the user.
- // take it and build a details object that represents that resource.
-
- // key = this must be a unique string across all of your resources - see docs for uniqueness rules
- // name = this is the name you give the new resource; it does not necessarily have to be unique
- // version = this is any string that corresponds to the resource's version
- // description = this is any string that you want to assign as the default description for your resource
- String key = "My Manually Added Resource Key";
- String name = "My Resource";
- String version = "1.0";
- String description = "This describes My Resource";
-
- DiscoveredResourceDetails resource = new DiscoveredResourceDetails(context.getResourceType(), key, name,
- version, description, pluginConfiguration, null);
-
- return resource;
- }
-
- /**
- * Review the javadoc for both {@link ResourceDiscoveryComponent} and {@link ResourceDiscoveryContext} to learn what
- * you need to do in this method.
- *
- * @see ResourceDiscoveryComponent#discoverResources(ResourceDiscoveryContext)
- */
- @Override
- public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext context) {
- log.info("Discovering my custom plugin's resources");
-
- // if your plugin descriptor defined one or more <process-scan>s, then see if the plugin container
- // auto-discovered processes using those process scan definitions. Process all those that were found.
- List<ProcessScanResult> autoDiscoveryResults = context.getAutoDiscoveredProcesses();
- for (ProcessScanResult autoDiscoveryResult : autoDiscoveryResults) {
- // determine if you want to include the result in this method's returned set of discovered resources
- }
-
- // now perform your own discovery mechanism, if you have one. For each resource discovered, you need to
- // create a details object that describe the resource that you discovered.
- HashSet<DiscoveredResourceDetails> set = new HashSet<DiscoveredResourceDetails>();
-
- // key = this must be a unique string across all of your resources - see docs for uniqueness rules
- // name = this is the name you give the new resource; it does not necessarily have to be unique
- // version = this is any string that corresponds to the resource's version
- // description = this is any string that you want to assign as the default description for your resource
- String key = "My Resource Key";
- String name = "My Resource";
- String version = "1.0";
- String description = "This describes My Resource";
-
- DiscoveredResourceDetails resource = new DiscoveredResourceDetails(context.getResourceType(), key, name,
- version, description, null, null);
-
- set.add(resource);
-
- return set;
- }
-}
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index c924753..b8d7249 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -27,10 +27,25 @@
</plugin-configuration>
<operation name="reset" displayName="Reset the node" description="Move the node out of an error state" />
+ <operation name="refresh" displayName="Refresh configuration" description="Refresh configuration" />
+ <operation name="enable" displayName="Enable all webapps" description="Enable all webapps for all engines">
+ <results>
+ <c:simple-property name="result" type="boolean" description="The result of the operation" />
+ </results>
+ </operation>
+ <operation name="disable" displayName="Disable all webpapps" description="Disable all webapps for all engines">
+ <results>
+ <c:simple-property name="result" type="boolean" description="The result of the operation" />
+ </results>
+ </operation>
<metric property="proxyConfiguration" displayName="Proxy Configuration" displayType="summary" dataType="trait" />
<metric property="modelerType" displayName="Type of the modeled resource" displayType="summary" dataType="trait" />
<metric property="className" displayName="Fully qualified class name of the managed object" displayType="summary" dataType="trait" />
+ <resource-configuration>
+ <c:simple-property name="stickySessions" type="boolean" description="Enables sticky sessions."/>
+ </resource-configuration>
+
</service>
</plugin>
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
index 5f68989..da0303e 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
@@ -43,6 +43,8 @@ import org.rhq.core.pc.plugin.PluginEnvironment;
import org.rhq.core.pc.plugin.PluginManager;
import org.rhq.core.pluginapi.inventory.ResourceComponent;
import org.rhq.core.pluginapi.measurement.MeasurementFacet;
+import org.rhq.core.pluginapi.operation.OperationFacet;
+import org.rhq.core.pluginapi.operation.OperationResult;
/**
* @author Fady Matar
@@ -115,13 +117,19 @@ public class ModclusterPluginTest {
MeasurementReport report = new MeasurementReport();
((MeasurementFacet) resourceComponent).getValues(report, metricList);
- /*assert report.getNumericData().size() > 0 : "Measurement " + def.getName() + " not collected from "
- + resource;*/
MeasurementData data = report.getTraitData().iterator().next();
assert data != null : "Unable to collect trait [" + def.getName() + "] on " + resource;
log.info("Measurement: " + def.getName() + "=" + data.getValue());
}
}
+
+ if (resourceComponent instanceof OperationFacet) {
+ OperationResult result = ((OperationFacet) resourceComponent).invokeOperation("reset", null);
+ log.info("Result of operation test was: " + result);
+
+ result = ((OperationFacet) resourceComponent).invokeOperation("disable", null);
+ log.info("Result of operation test was: " + result.getSimpleResult());
+ }
}
private Set<Resource> findResource(Resource parent, String typeName) {
commit 53efc864c9d00bae1a7c8ed66ea0f25baed05b65
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Fri Jul 1 16:12:13 2011 -0500
Remove unused file.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/LoadMetric.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/LoadMetric.java
deleted file mode 100644
index 1223508..0000000
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/LoadMetric.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2009 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.modcluster;
-
-import org.rhq.plugins.jmx.MBeanResourceComponent;
-
-/**
- * @author Stefan Negrea
- *
- */
-public class LoadMetric extends MBeanResourceComponent {
-
-}
commit 30737d3a2d1e3fc85111416203cafdf4d47b70a2
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Fri Jul 1 15:11:36 2011 -0600
Added all the metrics proposed in the design document to the plugin with complete unit tests.
Also, corrected the cumbersome find resource code. No reason to have recursion when a simple queue can do the job more efficiently.
diff --git a/modules/plugins/mod-cluster/pom.xml b/modules/plugins/mod-cluster/pom.xml
index 869a25e..a19dfc0 100644
--- a/modules/plugins/mod-cluster/pom.xml
+++ b/modules/plugins/mod-cluster/pom.xml
@@ -69,6 +69,8 @@
<fileset dir="${settings.localRepository}/">
<include name="org/rhq/rhq-platform-plugin/${project.version}/rhq-platform-plugin-${project.version}.jar" />
<include name="org/rhq/rhq-jmx-plugin/${project.version}/rhq-jmx-plugin-${project.version}.jar" />
+ <include name="org/jboss/on/jopr-jboss-as-plugin/${project.version}/jopr-jboss-as-plugin-${project.version}.jar" />
+ <include name="org/jboss/on/jopr-jboss-as-5-plugin/${project.version}/jopr-jboss-as-5-plugin-${project.version}.jar" />
</fileset>
<fileset dir="${rhq.deploymentDir}">
<include name="${project.artifactId}-${project.version}.jar" />
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
index 6d6998a..c70f53b 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2008 Red Hat, Inc.
+ * Copyright (C) 2005-2009 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -18,151 +18,12 @@
*/
package org.rhq.plugins.modcluster;
-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.configuration.ConfigurationUpdateStatus;
-import org.rhq.core.domain.measurement.AvailabilityType;
-import org.rhq.core.domain.measurement.MeasurementDataNumeric;
-import org.rhq.core.domain.measurement.MeasurementReport;
-import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
-import org.rhq.core.pluginapi.configuration.ConfigurationFacet;
-import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport;
-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.plugins.jmx.MBeanResourceComponent;
/**
- * This can be the start of your own custom plugin's server component. Review the javadoc for {@link ResourceComponent}
- * and all the facet interfaces to learn what you can do in your resource component. This component has a lot of methods
- * in it because it implements all possible facets. If your resource does not support, for example, configuration, you
- * can remove the {@link ConfigurationFacet} from the <code>implements</code> clause and remove all method
- * implementations that that facet required.
- *
- * <p>You should not only read the javadoc in each of this class' methods, but you should also read the javadocs linked
- * by their "see" javadoc tags since those additional javadocs will contain a good deal of additional information you
- * will need to know.</p>
+ * @author Stefan Negrea
*
- * @author John Mazzitelli
*/
-public class ModclusterServerComponent implements ResourceComponent, MeasurementFacet, OperationFacet,
- ConfigurationFacet {
- private final Log log = LogFactory.getLog(ModclusterServerComponent.class);
-
- /**
- * Represents the resource configuration of the custom product being managed.
- */
- private Configuration resourceConfiguration;
-
- /**
- * All AMPS plugins are stateful - this context contains information that your resource component can use when
- * performing its processing.
- */
- private ResourceContext resourceContext;
-
- /**
- * This is called when your component has been started with the given context. You normally initialize some internal
- * state of your component as well as attempt to make a stateful connection to your managed resource.
- *
- * @see ResourceComponent#start(ResourceContext)
- */
- public void start(ResourceContext context) {
- resourceContext = context;
- }
-
- /**
- * This is called when the component is being stopped, usually due to the plugin container shutting down. You can
- * perform some cleanup here; though normally not much needs to be done here.
- *
- * @see ResourceComponent#stop()
- */
- public void stop() {
- }
-
- /**
- * All resource components must be able to tell the plugin container if the managed resource is available or not.
- * This method is called by the plugin container when it needs to know if the managed resource is actually up and
- * available.
- *
- * @see ResourceComponent#getAvailability()
- */
- public AvailabilityType getAvailability() {
- // TODO: here you normally make some type of connection attempt to the managed resource
- // to determine if it is really up and running.
- return AvailabilityType.UP;
- }
-
- /**
- * The plugin container will call this method when your resource component has been scheduled to collect some
- * measurements now. It is within this method that you actually talk to the managed resource and collect the
- * measurement data that is has emitted.
- *
- * @see MeasurementFacet#getValues(MeasurementReport, Set)
- */
- public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> requests) {
- for (MeasurementScheduleRequest request : requests) {
- String name = request.getName();
-
- // TODO: based on the request information, you must collect the requested measurement(s)
- // you can use the name of the measurement to determine what you actually need to collect
- try {
- Number value = new Integer(1); // dummy measurement value - this should come from the managed resource
- report.addData(new MeasurementDataNumeric(request, value.doubleValue()));
- } catch (Exception e) {
- log.error("Failed to obtain measurement [" + name + "]. Cause: " + e);
- }
- }
-
- return;
- }
-
- /**
- * The plugin container will call this method when it wants to invoke an operation on your managed resource. Your
- * plugin will connect to the managed resource and invoke the analogous operation in your own custom way.
- *
- * @see OperationFacet#invokeOperation(String, Configuration)
- */
- public OperationResult invokeOperation(String name, Configuration configuration) {
- return null;
- }
-
- /**
- * The plugin container will call this method and it needs to obtain the current configuration of the managed
- * resource. Your plugin will obtain the managed resource's configuration in your own custom way and populate the
- * returned Configuration object with the managed resource's configuration property values.
- *
- * @see ConfigurationFacet#loadResourceConfiguration()
- */
- public Configuration loadResourceConfiguration() {
- // here we simulate the loading of the managed resource's configuration
-
- if (resourceConfiguration == null) {
- // for this example, we will create a simple dummy configuration to start with.
- // note that it is empty, so we're assuming there are no required configs in the plugin descriptor.
- resourceConfiguration = new Configuration();
- }
-
- Configuration config = resourceConfiguration;
-
- return config;
- }
-
- /**
- * The plugin container will call this method when it has a new configuration for your managed resource. Your plugin
- * will re-configure the managed resource in your own custom way, setting its configuration based on the new values
- * of the given configuration.
- *
- * @see ConfigurationFacet#updateResourceConfiguration(ConfigurationUpdateReport)
- */
- public void updateResourceConfiguration(ConfigurationUpdateReport report) {
- // this simulates the plugin taking the new configuration and reconfiguring the managed resource
- resourceConfiguration = report.getConfiguration().deepCopy();
+public class ModclusterServerComponent extends MBeanResourceComponent {
- report.setStatus(ConfigurationUpdateStatus.SUCCESS);
- }
}
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index fe6d1b3..c924753 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -12,21 +12,25 @@
<service name="mod_cluster"
discovery="org.rhq.plugins.jmx.MBeanResourceDiscoveryComponent"
- class="LoadMetric"
+ class="ModclusterServerComponent"
supportsManualAdd="true"
description="mod_cluster plugin">
- <!-- runs-inside>
- <parent-resource-type name="JMX Server" plugin="JMX"/>
- </runs-inside-->
- <runs-inside>
- <parent-resource-type name="JMX Server" plugin="JMX"/>
- </runs-inside>
+ <runs-inside>
+ <parent-resource-type name="JBossAS Server" plugin="JBossAS"/>
+ <parent-resource-type name="JBossAS Server" plugin="JBossAS5"/>
+ </runs-inside>
- <plugin-configuration>
- <c:simple-property name="connectorAddress" default="http://192.168.1.56:6666"/>
- <c:simple-property name="objectName" readOnly="true" default="ModClusterServiceMBean"/>
+ <plugin-configuration>
+ <c:simple-property name="objectName" readOnly="true" default="Catalina:type=ModClusterListener,*"/>
+ <c:simple-property name="nameTemplate" default="{application}"/>
</plugin-configuration>
-
+
+ <operation name="reset" displayName="Reset the node" description="Move the node out of an error state" />
+
+ <metric property="proxyConfiguration" displayName="Proxy Configuration" displayType="summary" dataType="trait" />
+ <metric property="modelerType" displayName="Type of the modeled resource" displayType="summary" dataType="trait" />
+ <metric property="className" displayName="Fully qualified class name of the managed object" displayType="summary" dataType="trait" />
+
</service>
</plugin>
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
index 971ccb1..5f68989 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
@@ -20,6 +20,8 @@ package org.rhq.plugins.modcluster.test;
import java.io.File;
import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Queue;
import java.util.Set;
import org.apache.commons.logging.Log;
@@ -29,12 +31,18 @@ import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Test;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.domain.measurement.MeasurementData;
+import org.rhq.core.domain.measurement.MeasurementDefinition;
+import org.rhq.core.domain.measurement.MeasurementReport;
+import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.pc.PluginContainer;
import org.rhq.core.pc.PluginContainerConfiguration;
import org.rhq.core.pc.plugin.FileSystemPluginFinder;
import org.rhq.core.pc.plugin.PluginEnvironment;
import org.rhq.core.pc.plugin.PluginManager;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.measurement.MeasurementFacet;
/**
* @author Fady Matar
@@ -90,23 +98,53 @@ public class ModclusterPluginTest {
Set<Resource> resources = findResource(PluginContainer.getInstance().getInventoryManager().getPlatform(),
PLUGIN_NAME);
- log.info("Found " + resources.size() + "mod_cluster instance(s).");
+ log.info("Found " + resources.size() + " mod_cluster instance(s).");
+
+ if (resources.size() != 0) {
+ testResourceMeasurement((Resource) resources.toArray()[0]);
+ }
+ }
+
+ private void testResourceMeasurement(Resource resource) throws Exception {
+ ResourceComponent resourceComponent = PluginContainer.getInstance().getInventoryManager()
+ .getResourceComponent(resource);
+ if (resourceComponent instanceof MeasurementFacet) {
+ for (MeasurementDefinition def : resource.getResourceType().getMetricDefinitions()) {
+ Set<MeasurementScheduleRequest> metricList = new HashSet<MeasurementScheduleRequest>();
+ metricList.add(new MeasurementScheduleRequest(1, def.getName(), 1000, true, def.getDataType(), null));
+ MeasurementReport report = new MeasurementReport();
+ ((MeasurementFacet) resourceComponent).getValues(report, metricList);
+
+ /*assert report.getNumericData().size() > 0 : "Measurement " + def.getName() + " not collected from "
+ + resource;*/
+ MeasurementData data = report.getTraitData().iterator().next();
+ assert data != null : "Unable to collect trait [" + def.getName() + "] on " + resource;
+ log.info("Measurement: " + def.getName() + "=" + data.getValue());
+ }
+ }
}
private Set<Resource> findResource(Resource parent, String typeName) {
Set<Resource> found = new HashSet<Resource>();
- Resource platform = parent;
- for (Resource resource : platform.getChildResources()) {
- log.info("Discovered resource of type: " + resource.getResourceType().getName());
- if (resource.getResourceType().getName().equals(typeName)) {
- found.add(resource);
+
+ Queue<Resource> discoveryQueue = new LinkedList<Resource>();
+ discoveryQueue.add(parent);
+
+ while (!discoveryQueue.isEmpty()) {
+ Resource currentResource = discoveryQueue.poll();
+
+ log.info("Discovered resource of type: " + currentResource.getResourceType().getName());
+ if (currentResource.getResourceType().getName().equals(typeName)) {
+ found.add(currentResource);
}
- if (resource.getChildResources() != null) {
- for (Resource child : found) {
- found.addAll(findResource(child, typeName));
+
+ if (currentResource.getChildResources() != null) {
+ for (Resource child : currentResource.getChildResources()) {
+ discoveryQueue.add(child);
}
}
}
+
return found;
}
}
commit e12cc04174250dcabd6dd81ca7f97e998ca801fb
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Tue Jun 28 09:21:49 2011 -0500
Attempts to make mod_cluster a simple derivation from JMX plugin.
diff --git a/.classpath b/.classpath
index d5bec34..c215ebf 100644
--- a/.classpath
+++ b/.classpath
@@ -271,5 +271,7 @@
<classpathentry excluding="**" kind="src" path="modules/enterprise/comm/src/test/resources"/>
<classpathentry excluding="**" kind="src" path="modules/enterprise/agent/src/main/resources"/>
<classpathentry excluding="**" kind="src" path="modules/enterprise/agent/src/test/resources"/>
+ <classpathentry kind="src" path="modules/plugins/mod-cluster/src/main/java"/>
+ <classpathentry kind="src" path="modules/plugins/mod-cluster/src/test/java"/>
<classpathentry kind="output" path="eclipse-classes"/>
</classpath>
diff --git a/modules/plugins/mod-cluster/pom.xml b/modules/plugins/mod-cluster/pom.xml
index e22efc7..869a25e 100644
--- a/modules/plugins/mod-cluster/pom.xml
+++ b/modules/plugins/mod-cluster/pom.xml
@@ -1,5 +1,3 @@
-<?xml version="1.0"?>
-
<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>
@@ -12,16 +10,11 @@
<groupId>org.rhq.plugins.modcluster</groupId>
<artifactId>modcluster-plugin</artifactId>
- <version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>mod_cluster RHQ Plugin</name>
<description>mod_cluster RHQ Agent plugin</description>
- <!--properties>
- <rhq.version>4.1.0-SNAPSHOT</rhq.version>
- </properties-->
-
<dependencies>
<dependency>
@@ -31,220 +24,170 @@
<scope>provided</scope>
</dependency>
- <!-- Below are the core modules that are required dependencies of all plugins -->
- <dependency>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-core-domain</artifactId>
- <version>${rhq.version}</version>
- <scope>provided</scope> <!-- provided by the agent/plugin-container -->
- </dependency>
-
- <dependency>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-core-plugin-api</artifactId>
- <version>${rhq.version}</version>
- <scope>provided</scope> <!-- provided by the agent/plugin-container -->
- </dependency>
-
- <dependency>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-core-native-system</artifactId>
- <version>${rhq.version}</version>
- <scope>provided</scope> <!-- provided by the agent/plugin-container -->
- </dependency>
-
- <!-- Fix for the Javac bug requiring annotations to be available when compiling classes. (fixed in JDK 6) -->
- <dependency>
- <groupId>javax.persistence</groupId>
- <artifactId>persistence-api</artifactId>
- <version>1.0</version>
- <scope>provided</scope> <!-- provided by the agent/plugin-container -->
- </dependency>
-
- <!-- Fix for the Javac bug requiring annotations to be available when compiling classes. (fixed in JDK 6) -->
- <dependency>
- <groupId>hibernate-annotations</groupId>
- <artifactId>hibernate-annotations</artifactId>
- <version>3.2.1.GA</version>
- <scope>provided</scope> <!-- provided by the agent/plugin-container -->
- </dependency>
-
- <!-- Fix for the Javac bug requiring annotations to be available when compiling classes. (fixed in JDK 6) -->
- <dependency>
- <groupId>javax.xml.bind</groupId>
- <artifactId>jaxb-api</artifactId>
- <version>2.1</version>
- <scope>provided</scope> <!-- provided by the agent/plugin-container -->
- </dependency>
-
- <!--
- Uncomment the one of the three logging systems your plugin uses: log4j, commons-logging or i18nlog
- All three are provided to your plugin by the agent/plugin-container.
- -->
- <dependency>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- <version>1.1</version>
- <scope>provided</scope>
- </dependency>
-
-
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
<scope>provided</scope>
</dependency>
-
- <!--
- <dependency>
- <groupId>i18nlog</groupId>
- <artifactId>i18nlog</artifactId>
- <version>1.0.9</version>
- <scope>provided</scope>
- </dependency>
- -->
-
- <!-- Define any third-party dependencies your plugin has here. -->
- <!--
- <dependency>
- <groupId>group-id-of-dependency-goes-here</groupId>
- <artifactId>artifact-id-of-dependency-goes-here</artifactId>
- <version>version-of-dependency-goes-here</version>
- </dependency>
- -->
</dependencies>
- <build>
- <plugins>
-
- <plugin>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <source>1.5</source>
- <target>1.5</target>
- </configuration>
- </plugin>
-
- <!--
- If your plugin has third-party jar dependencies that are not already available when deployed in the plugin
- container, you can package these jars in your plugin. They go in your plugin jar's "lib" directory.
- Uncomment the maven plugin definition below and define one or more jar files (aka "artifactItem" elements)
- that you want to include in your plugin jar.
- -->
- <!--
- <plugin>
- <artifactId>maven-dependency-plugin</artifactId>
- <executions>
- <execution>
- <id>copy-dependencies</id>
- <phase>process-resources</phase>
- <goals>
- <goal>copy</goal>
- </goals>
- <configuration>
- <artifactItems>
- <artifactItem>
- <groupId>your-third-party-dep-group</groupId>
- <artifactId>your-third-party-dep-artifact</artifactId>
- <version>your-third-party-dep-version</version>
- </artifactItem>
- </artifactItems>
- <outputDirectory>${project.build.outputDirectory}/lib</outputDirectory>
- </configuration>
- </execution>
- </executions>
- </plugin>
- -->
-
- </plugins>
- </build>
-
<profiles>
+
<profile>
- <id>dev</id>
+ <id>integration-tests</id>
+ <activation>
+ <property>
+ <name>maven.test.skip</name>
+ <value>!true</value>
+ </property>
+ </activation>
+
<properties>
- <!-- define the location of your RHQ root directory - typically rhq.rootDir is overridden in Maven's settings.xml -->
- <rhq.rootDir>/rhq/trunk</rhq.rootDir>
- <rhq.defaultDevContainerPath>dev-container</rhq.defaultDevContainerPath>
+ <rhq.rootDir>../../..</rhq.rootDir>
<rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir>
- <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/rhq.ear/rhq-downloads/rhq-plugins</rhq.deploymentDir>
+ <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/rhq-downloads/rhq-plugins</rhq.deploymentDir>
</properties>
+
<build>
<plugins>
+
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
- <version>1.1</version>
<executions>
<execution>
- <id>deploy</id>
- <phase>compile</phase>
+ <phase>process-test-resources</phase>
<configuration>
<tasks>
- <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}" />
+ <echo>Setting up plugin dependencies...</echo>
+ <property name="settings.localRepository" location="${user.home}/.m2/repository" />
+ <mkdir dir="target/testsetup" />
+
+ <mkdir dir="target/testsetup/plugins" />
+ <copy toDir="target/testsetup/plugins" flatten="true">
+ <fileset dir="${settings.localRepository}/">
+ <include name="org/rhq/rhq-platform-plugin/${project.version}/rhq-platform-plugin-${project.version}.jar" />
+ <include name="org/rhq/rhq-jmx-plugin/${project.version}/rhq-jmx-plugin-${project.version}.jar" />
+ </fileset>
+ <fileset dir="${rhq.deploymentDir}">
+ <include name="${project.artifactId}-${project.version}.jar" />
+ </fileset>
+ </copy>
+
+ <mkdir dir="target/testsetup/lib" />
+ <unzip dest="target/testsetup/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/testsetup/lib" flatten="true">
+ <fileset dir="target/testsetup/lib">
+ <include name="**/lib/*" />
+ </fileset>
+ </move>
+ <delete dir="target/testsetup/lib/hyperic-sigar-${sigar.version}" />
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
+
+ <execution>
+ <id>deploy</id>
+ <phase>compile</phase>
+ <configuration>
+ <tasks>
+ <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}" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
<execution>
<id>deploy-jar-meta-inf</id>
<phase>package</phase>
<configuration>
- <tasks>
- <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>
- </tasks>
+ <tasks>
+ <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>
+ </tasks>
</configuration>
<goals>
- <goal>run</goal>
+ <goal>run</goal>
</goals>
</execution>
+
<execution>
<id>undeploy</id>
<phase>clean</phase>
<configuration>
- <tasks>
- <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
- <echo>*** Deleting ${deployment.file}...</echo>
- <delete file="${deployment.file}" />
- </tasks>
+ <tasks>
+ <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
+ <echo>*** Deleting ${deployment.file}...</echo>
+ <delete file="${deployment.file}" />
+ </tasks>
</configuration>
<goals>
- <goal>run</goal>
+ <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>-Dorg.hyperic.sigar.path=${basedir}/target/testsetup/lib</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>
</profiles>
- <repositories>
- <repository>
- <id>jboss-public-repository-group</id>
- <name>JBoss Public Maven Repository Group</name>
- <url>https://repository.jboss.org/nexus/content/groups/public/</url>
- <snapshots>
- <enabled>false</enabled>
- </snapshots>
- </repository>
- </repositories>
-
</project>
-
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/LoadMetric.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/LoadMetric.java
new file mode 100644
index 0000000..1223508
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/LoadMetric.java
@@ -0,0 +1,29 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2009 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.modcluster;
+
+import org.rhq.plugins.jmx.MBeanResourceComponent;
+
+/**
+ * @author Stefan Negrea
+ *
+ */
+public class LoadMetric extends MBeanResourceComponent {
+
+}
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterDiscoveryComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterDiscoveryComponent.java
new file mode 100644
index 0000000..fa807a3
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterDiscoveryComponent.java
@@ -0,0 +1,116 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.modcluster;
+
+import java.util.HashSet;
+import java.util.List;
+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.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ManualAddFacet;
+import org.rhq.core.pluginapi.inventory.ProcessScanResult;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+
+/**
+ * This can be the start of your own custom plugin's discovery component. Review the javadoc for
+ * {@link ResourceDiscoveryComponent}.
+ *
+ * @author John Mazzitelli
+ */
+@SuppressWarnings("unchecked")
+public class ModclusterDiscoveryComponent implements ResourceDiscoveryComponent, ManualAddFacet {
+ private final Log log = LogFactory.getLog(ModclusterDiscoveryComponent.class);
+
+ /**
+ * This discovery method is the way the plugin supports "manual-add" capability. The plugin
+ * descriptor must specify supportsManualAdd="true" to allow the resource to be manually added.
+ * If that attribute is false, this method will never be used since it will not be possible to manually
+ * add an instance of the resource.
+ *
+ * Review the javadoc for both {@link ManualAddFacet} and {@link ResourceDiscoveryContext} to learn what
+ * you need to do in this method.
+ *
+ * @see ManualAddFacet#discoverResource(Configuration, ResourceDiscoveryContext)
+ */
+ @Override
+ public DiscoveredResourceDetails discoverResource(Configuration pluginConfiguration,
+ ResourceDiscoveryContext context) throws InvalidPluginConfigurationException {
+
+ // pluginConfiguration contains information on a resource that was manually added by the user.
+ // take it and build a details object that represents that resource.
+
+ // key = this must be a unique string across all of your resources - see docs for uniqueness rules
+ // name = this is the name you give the new resource; it does not necessarily have to be unique
+ // version = this is any string that corresponds to the resource's version
+ // description = this is any string that you want to assign as the default description for your resource
+ String key = "My Manually Added Resource Key";
+ String name = "My Resource";
+ String version = "1.0";
+ String description = "This describes My Resource";
+
+ DiscoveredResourceDetails resource = new DiscoveredResourceDetails(context.getResourceType(), key, name,
+ version, description, pluginConfiguration, null);
+
+ return resource;
+ }
+
+ /**
+ * Review the javadoc for both {@link ResourceDiscoveryComponent} and {@link ResourceDiscoveryContext} to learn what
+ * you need to do in this method.
+ *
+ * @see ResourceDiscoveryComponent#discoverResources(ResourceDiscoveryContext)
+ */
+ @Override
+ public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext context) {
+ log.info("Discovering my custom plugin's resources");
+
+ // if your plugin descriptor defined one or more <process-scan>s, then see if the plugin container
+ // auto-discovered processes using those process scan definitions. Process all those that were found.
+ List<ProcessScanResult> autoDiscoveryResults = context.getAutoDiscoveredProcesses();
+ for (ProcessScanResult autoDiscoveryResult : autoDiscoveryResults) {
+ // determine if you want to include the result in this method's returned set of discovered resources
+ }
+
+ // now perform your own discovery mechanism, if you have one. For each resource discovered, you need to
+ // create a details object that describe the resource that you discovered.
+ HashSet<DiscoveredResourceDetails> set = new HashSet<DiscoveredResourceDetails>();
+
+ // key = this must be a unique string across all of your resources - see docs for uniqueness rules
+ // name = this is the name you give the new resource; it does not necessarily have to be unique
+ // version = this is any string that corresponds to the resource's version
+ // description = this is any string that you want to assign as the default description for your resource
+ String key = "My Resource Key";
+ String name = "My Resource";
+ String version = "1.0";
+ String description = "This describes My Resource";
+
+ DiscoveredResourceDetails resource = new DiscoveredResourceDetails(context.getResourceType(), key, name,
+ version, description, null, null);
+
+ set.add(resource);
+
+ return set;
+ }
+}
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
new file mode 100644
index 0000000..6d6998a
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
@@ -0,0 +1,168 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.modcluster;
+
+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.configuration.ConfigurationUpdateStatus;
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.domain.measurement.MeasurementDataNumeric;
+import org.rhq.core.domain.measurement.MeasurementReport;
+import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
+import org.rhq.core.pluginapi.configuration.ConfigurationFacet;
+import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport;
+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;
+
+/**
+ * This can be the start of your own custom plugin's server component. Review the javadoc for {@link ResourceComponent}
+ * and all the facet interfaces to learn what you can do in your resource component. This component has a lot of methods
+ * in it because it implements all possible facets. If your resource does not support, for example, configuration, you
+ * can remove the {@link ConfigurationFacet} from the <code>implements</code> clause and remove all method
+ * implementations that that facet required.
+ *
+ * <p>You should not only read the javadoc in each of this class' methods, but you should also read the javadocs linked
+ * by their "see" javadoc tags since those additional javadocs will contain a good deal of additional information you
+ * will need to know.</p>
+ *
+ * @author John Mazzitelli
+ */
+public class ModclusterServerComponent implements ResourceComponent, MeasurementFacet, OperationFacet,
+ ConfigurationFacet {
+ private final Log log = LogFactory.getLog(ModclusterServerComponent.class);
+
+ /**
+ * Represents the resource configuration of the custom product being managed.
+ */
+ private Configuration resourceConfiguration;
+
+ /**
+ * All AMPS plugins are stateful - this context contains information that your resource component can use when
+ * performing its processing.
+ */
+ private ResourceContext resourceContext;
+
+ /**
+ * This is called when your component has been started with the given context. You normally initialize some internal
+ * state of your component as well as attempt to make a stateful connection to your managed resource.
+ *
+ * @see ResourceComponent#start(ResourceContext)
+ */
+ public void start(ResourceContext context) {
+ resourceContext = context;
+ }
+
+ /**
+ * This is called when the component is being stopped, usually due to the plugin container shutting down. You can
+ * perform some cleanup here; though normally not much needs to be done here.
+ *
+ * @see ResourceComponent#stop()
+ */
+ public void stop() {
+ }
+
+ /**
+ * All resource components must be able to tell the plugin container if the managed resource is available or not.
+ * This method is called by the plugin container when it needs to know if the managed resource is actually up and
+ * available.
+ *
+ * @see ResourceComponent#getAvailability()
+ */
+ public AvailabilityType getAvailability() {
+ // TODO: here you normally make some type of connection attempt to the managed resource
+ // to determine if it is really up and running.
+ return AvailabilityType.UP;
+ }
+
+ /**
+ * The plugin container will call this method when your resource component has been scheduled to collect some
+ * measurements now. It is within this method that you actually talk to the managed resource and collect the
+ * measurement data that is has emitted.
+ *
+ * @see MeasurementFacet#getValues(MeasurementReport, Set)
+ */
+ public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> requests) {
+ for (MeasurementScheduleRequest request : requests) {
+ String name = request.getName();
+
+ // TODO: based on the request information, you must collect the requested measurement(s)
+ // you can use the name of the measurement to determine what you actually need to collect
+ try {
+ Number value = new Integer(1); // dummy measurement value - this should come from the managed resource
+ report.addData(new MeasurementDataNumeric(request, value.doubleValue()));
+ } catch (Exception e) {
+ log.error("Failed to obtain measurement [" + name + "]. Cause: " + e);
+ }
+ }
+
+ return;
+ }
+
+ /**
+ * The plugin container will call this method when it wants to invoke an operation on your managed resource. Your
+ * plugin will connect to the managed resource and invoke the analogous operation in your own custom way.
+ *
+ * @see OperationFacet#invokeOperation(String, Configuration)
+ */
+ public OperationResult invokeOperation(String name, Configuration configuration) {
+ return null;
+ }
+
+ /**
+ * The plugin container will call this method and it needs to obtain the current configuration of the managed
+ * resource. Your plugin will obtain the managed resource's configuration in your own custom way and populate the
+ * returned Configuration object with the managed resource's configuration property values.
+ *
+ * @see ConfigurationFacet#loadResourceConfiguration()
+ */
+ public Configuration loadResourceConfiguration() {
+ // here we simulate the loading of the managed resource's configuration
+
+ if (resourceConfiguration == null) {
+ // for this example, we will create a simple dummy configuration to start with.
+ // note that it is empty, so we're assuming there are no required configs in the plugin descriptor.
+ resourceConfiguration = new Configuration();
+ }
+
+ Configuration config = resourceConfiguration;
+
+ return config;
+ }
+
+ /**
+ * The plugin container will call this method when it has a new configuration for your managed resource. Your plugin
+ * will re-configure the managed resource in your own custom way, setting its configuration based on the new values
+ * of the given configuration.
+ *
+ * @see ConfigurationFacet#updateResourceConfiguration(ConfigurationUpdateReport)
+ */
+ public void updateResourceConfiguration(ConfigurationUpdateReport report) {
+ // this simulates the plugin taking the new configuration and reconfiguring the managed resource
+ resourceConfiguration = report.getConfiguration().deepCopy();
+
+ report.setStatus(ConfigurationUpdateStatus.SUCCESS);
+ }
+}
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginDiscoveryComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginDiscoveryComponent.java
deleted file mode 100644
index 2abd0ea..0000000
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginDiscoveryComponent.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 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.modcluster;
-
-import java.util.HashSet;
-import java.util.List;
-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.pluginapi.inventory.DiscoveredResourceDetails;
-import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
-import org.rhq.core.pluginapi.inventory.ManualAddFacet;
-import org.rhq.core.pluginapi.inventory.ProcessScanResult;
-import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
-import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
-
-/**
- * This can be the start of your own custom plugin's discovery component. Review the javadoc for
- * {@link ResourceDiscoveryComponent}.
- *
- * @author John Mazzitelli
- */
-@SuppressWarnings("unchecked")
-public class SamplePluginDiscoveryComponent implements ResourceDiscoveryComponent, ManualAddFacet {
- private final Log log = LogFactory.getLog(SamplePluginDiscoveryComponent.class);
-
- /**
- * This discovery method is the way the plugin supports "manual-add" capability. The plugin
- * descriptor must specify supportsManualAdd="true" to allow the resource to be manually added.
- * If that attribute is false, this method will never be used since it will not be possible to manually
- * add an instance of the resource.
- *
- * Review the javadoc for both {@link ManualAddFacet} and {@link ResourceDiscoveryContext} to learn what
- * you need to do in this method.
- *
- * @see ManualAddFacet#discoverResource(Configuration, ResourceDiscoveryContext)
- */
- @Override
- public DiscoveredResourceDetails discoverResource(Configuration pluginConfiguration,
- ResourceDiscoveryContext context) throws InvalidPluginConfigurationException {
-
- // pluginConfiguration contains information on a resource that was manually added by the user.
- // take it and build a details object that represents that resource.
-
- // key = this must be a unique string across all of your resources - see docs for uniqueness rules
- // name = this is the name you give the new resource; it does not necessarily have to be unique
- // version = this is any string that corresponds to the resource's version
- // description = this is any string that you want to assign as the default description for your resource
- String key = "My Manually Added Resource Key";
- String name = "My Resource";
- String version = "1.0";
- String description = "This describes My Resource";
-
- DiscoveredResourceDetails resource = new DiscoveredResourceDetails(context.getResourceType(), key, name,
- version, description, pluginConfiguration, null);
-
- return resource;
- }
-
- /**
- * Review the javadoc for both {@link ResourceDiscoveryComponent} and {@link ResourceDiscoveryContext} to learn what
- * you need to do in this method.
- *
- * @see ResourceDiscoveryComponent#discoverResources(ResourceDiscoveryContext)
- */
- @Override
- public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext context) {
- log.info("Discovering my custom plugin's resources");
-
- // if your plugin descriptor defined one or more <process-scan>s, then see if the plugin container
- // auto-discovered processes using those process scan definitions. Process all those that were found.
- List<ProcessScanResult> autoDiscoveryResults = context.getAutoDiscoveredProcesses();
- for (ProcessScanResult autoDiscoveryResult : autoDiscoveryResults) {
- // determine if you want to include the result in this method's returned set of discovered resources
- }
-
- // now perform your own discovery mechanism, if you have one. For each resource discovered, you need to
- // create a details object that describe the resource that you discovered.
- HashSet<DiscoveredResourceDetails> set = new HashSet<DiscoveredResourceDetails>();
-
- // key = this must be a unique string across all of your resources - see docs for uniqueness rules
- // name = this is the name you give the new resource; it does not necessarily have to be unique
- // version = this is any string that corresponds to the resource's version
- // description = this is any string that you want to assign as the default description for your resource
- String key = "My Resource Key";
- String name = "My Resource";
- String version = "1.0";
- String description = "This describes My Resource";
-
- DiscoveredResourceDetails resource = new DiscoveredResourceDetails(context.getResourceType(), key, name,
- version, description, null, null);
-
- set.add(resource);
-
- return set;
- }
-}
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginServerComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginServerComponent.java
deleted file mode 100644
index 0236532..0000000
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginServerComponent.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 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.modcluster;
-
-import java.io.InputStream;
-import java.util.List;
-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.configuration.ConfigurationUpdateStatus;
-import org.rhq.core.domain.content.PackageType;
-import org.rhq.core.domain.content.transfer.DeployPackageStep;
-import org.rhq.core.domain.content.transfer.DeployPackagesResponse;
-import org.rhq.core.domain.content.transfer.RemovePackagesResponse;
-import org.rhq.core.domain.content.transfer.ResourcePackageDetails;
-import org.rhq.core.domain.measurement.AvailabilityType;
-import org.rhq.core.domain.measurement.MeasurementDataNumeric;
-import org.rhq.core.domain.measurement.MeasurementReport;
-import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
-import org.rhq.core.pluginapi.configuration.ConfigurationFacet;
-import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport;
-import org.rhq.core.pluginapi.content.ContentFacet;
-import org.rhq.core.pluginapi.content.ContentServices;
-import org.rhq.core.pluginapi.inventory.CreateChildResourceFacet;
-import org.rhq.core.pluginapi.inventory.CreateResourceReport;
-import org.rhq.core.pluginapi.inventory.DeleteResourceFacet;
-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;
-
-/**
- * This can be the start of your own custom plugin's server component. Review the javadoc for {@link ResourceComponent}
- * and all the facet interfaces to learn what you can do in your resource component. This component has a lot of methods
- * in it because it implements all possible facets. If your resource does not support, for example, configuration, you
- * can remove the {@link ConfigurationFacet} from the <code>implements</code> clause and remove all method
- * implementations that that facet required.
- *
- * <p>You should not only read the javadoc in each of this class' methods, but you should also read the javadocs linked
- * by their "see" javadoc tags since those additional javadocs will contain a good deal of additional information you
- * will need to know.</p>
- *
- * @author John Mazzitelli
- */
-public class SamplePluginServerComponent implements ResourceComponent, MeasurementFacet, OperationFacet,
- ConfigurationFacet, ContentFacet, DeleteResourceFacet, CreateChildResourceFacet {
- private final Log log = LogFactory.getLog(SamplePluginServerComponent.class);
-
- /**
- * Represents the resource configuration of the custom product being managed.
- */
- private Configuration resourceConfiguration;
-
- /**
- * All AMPS plugins are stateful - this context contains information that your resource component can use when
- * performing its processing.
- */
- private ResourceContext resourceContext;
-
- /**
- * This is called when your component has been started with the given context. You normally initialize some internal
- * state of your component as well as attempt to make a stateful connection to your managed resource.
- *
- * @see ResourceComponent#start(ResourceContext)
- */
- public void start(ResourceContext context) {
- resourceContext = context;
- }
-
- /**
- * This is called when the component is being stopped, usually due to the plugin container shutting down. You can
- * perform some cleanup here; though normally not much needs to be done here.
- *
- * @see ResourceComponent#stop()
- */
- public void stop() {
- }
-
- /**
- * All resource components must be able to tell the plugin container if the managed resource is available or not.
- * This method is called by the plugin container when it needs to know if the managed resource is actually up and
- * available.
- *
- * @see ResourceComponent#getAvailability()
- */
- public AvailabilityType getAvailability() {
- // TODO: here you normally make some type of connection attempt to the managed resource
- // to determine if it is really up and running.
- return AvailabilityType.UP;
- }
-
- /**
- * The plugin container will call this method when your resource component has been scheduled to collect some
- * measurements now. It is within this method that you actually talk to the managed resource and collect the
- * measurement data that is has emitted.
- *
- * @see MeasurementFacet#getValues(MeasurementReport, Set)
- */
- public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> requests) {
- for (MeasurementScheduleRequest request : requests) {
- String name = request.getName();
-
- // TODO: based on the request information, you must collect the requested measurement(s)
- // you can use the name of the measurement to determine what you actually need to collect
- try {
- Number value = new Integer(1); // dummy measurement value - this should come from the managed resource
- report.addData(new MeasurementDataNumeric(request, value.doubleValue()));
- } catch (Exception e) {
- log.error("Failed to obtain measurement [" + name + "]. Cause: " + e);
- }
- }
-
- return;
- }
-
- /**
- * The plugin container will call this method when it wants to invoke an operation on your managed resource. Your
- * plugin will connect to the managed resource and invoke the analogous operation in your own custom way.
- *
- * @see OperationFacet#invokeOperation(String, Configuration)
- */
- public OperationResult invokeOperation(String name, Configuration configuration) {
- return null;
- }
-
- /**
- * The plugin container will call this method and it needs to obtain the current configuration of the managed
- * resource. Your plugin will obtain the managed resource's configuration in your own custom way and populate the
- * returned Configuration object with the managed resource's configuration property values.
- *
- * @see ConfigurationFacet#loadResourceConfiguration()
- */
- public Configuration loadResourceConfiguration() {
- // here we simulate the loading of the managed resource's configuration
-
- if (resourceConfiguration == null) {
- // for this example, we will create a simple dummy configuration to start with.
- // note that it is empty, so we're assuming there are no required configs in the plugin descriptor.
- resourceConfiguration = new Configuration();
- }
-
- Configuration config = resourceConfiguration;
-
- return config;
- }
-
- /**
- * The plugin container will call this method when it has a new configuration for your managed resource. Your plugin
- * will re-configure the managed resource in your own custom way, setting its configuration based on the new values
- * of the given configuration.
- *
- * @see ConfigurationFacet#updateResourceConfiguration(ConfigurationUpdateReport)
- */
- public void updateResourceConfiguration(ConfigurationUpdateReport report) {
- // this simulates the plugin taking the new configuration and reconfiguring the managed resource
- resourceConfiguration = report.getConfiguration().deepCopy();
-
- report.setStatus(ConfigurationUpdateStatus.SUCCESS);
- }
-
- /**
- * When this is called, the plugin is responsible for scanning its managed resource and look for content that need
- * to be managed for that resource. This method should only discover packages of the given package type.
- *
- * @see ContentFacet#discoverDeployedPackages(PackageType)
- */
- public Set<ResourcePackageDetails> discoverDeployedPackages(PackageType type) {
- return null;
- }
-
- /**
- * The plugin container calls this method when new packages need to be deployed/installed on resources.
- *
- * @see ContentFacet#deployPackages(Set, ContentServices)
- */
- public DeployPackagesResponse deployPackages(Set<ResourcePackageDetails> packages, ContentServices contentServices) {
- return null;
- }
-
- /**
- * When a remote client wants to see the actual data content for an installed package, this method will be called.
- * This method must return a stream of data containing the full content of the package.
- *
- * @see ContentFacet#retrievePackageBits(ResourcePackageDetails)
- */
- public InputStream retrievePackageBits(ResourcePackageDetails packageDetails) {
- return null;
- }
-
- /**
- * This is the method that is used when the component has to create the installation steps and their results.
- *
- * @see ContentFacet#generateInstallationSteps(ResourcePackageDetails)
- */
- public List<DeployPackageStep> generateInstallationSteps(ResourcePackageDetails packageDetails) {
- return null;
- }
-
- /**
- * This is called when the actual content of packages should be deleted from the managed resource.
- *
- * @see ContentFacet#removePackages(Set)
- */
- public RemovePackagesResponse removePackages(Set<ResourcePackageDetails> packages) {
- return null;
- }
-
- /**
- * When called, the plugin container is asking the plugin to create a new managed resource. The new resource's
- * details need to be added to the given report.
- *
- * @see CreateChildResourceFacet#createResource(CreateResourceReport)
- */
- public CreateResourceReport createResource(CreateResourceReport report) {
- return null;
- }
-
- /**
- * When called, the plugin container is asking the plugin to delete a managed resource.
- *
- * @see DeleteResourceFacet#deleteResource()
- */
- public void deleteResource() {
- }
-}
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index 1a99bf7..fe6d1b3 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -10,97 +10,23 @@
<depends plugin="JMX" />
- <!--
- CHANGE: The following is a sample server resource type. This entry is here to serve as a model and should
- be removed prior to deploying the plugin. Multiple resource types (either server or service) may be
- defined at this level.
- -->
- <server name="mod_cluster"
- discovery="SamplePluginDiscoveryComponent"
- class="SamplePluginServerComponent"
+ <service name="mod_cluster"
+ discovery="org.rhq.plugins.jmx.MBeanResourceDiscoveryComponent"
+ class="LoadMetric"
supportsManualAdd="true"
description="mod_cluster plugin">
-
- <!--
- CHANGE: Categories are optional; this entire section may be removed if there is no need to further group
- related child resources. Categories defined at this level can carry metadata on the category itself,
- such as a display name and description.
- -->
- <subcategories>
- <subcategory name="Category1" displayName="Sample Category 1"
- description="This is a sample category that should be removed."/>
- <subcategory name="Category2" >
- <subcategory name="ChildCategory2a" />
- </subcategory>
- </subcategories>
-
- <!--
- CHANGE: The entire plugin configuration is optional. If there are properties specific to handling how the
- resource component will connect to the resource, they should be added here. If the plugin-configuration
- entity is specified, at least one property must be provided.
- -->
- <plugin-configuration>
- <c:simple-property name="SamplePluginProperty" displayName="Sample Plugin Property" default="Value" />
+
+ <!-- runs-inside>
+ <parent-resource-type name="JMX Server" plugin="JMX"/>
+ </runs-inside-->
+ <runs-inside>
+ <parent-resource-type name="JMX Server" plugin="JMX"/>
+ </runs-inside>
+
+ <plugin-configuration>
+ <c:simple-property name="connectorAddress" default="http://192.168.1.56:6666"/>
+ <c:simple-property name="objectName" readOnly="true" default="ModClusterServiceMBean"/>
</plugin-configuration>
- <!--
- CHANGE: The process-scan element requests the plugin container provide the discovery component for
- this resource type with the results of scanning the machine for running processes. If there is
- no use for this in a given resource type, this entry may be omitted.
- -->
- <process-scan name="ScanIdentifier" query="process|basename|match=^java.*,arg|org.jboss.Main|match=.*"/>
-
- <!--
- CHANGE: An operation element is added for each operation that may be executed against resources of this type.
- The parameters element is optional; properties defined within will be displayed to the user when
- invoking the operation. If the resource has no applicable operations, these elements may be omitted.
-
- REQUIRED INTERFACE: The resource component for this resource type must implement the OperationFacet interface
- if any operations are specified.
- -->
- <operation name="testSimple"
- description="Test simple-property configuration element for a resource operation">
- <parameters>
- <c:group name="required" displayName="Required Parameters" hiddenByDefault="false">
- <c:description>All of these properties are required</c:description>
- <c:simple-property name="aNumber" type="integer" required="true" default="42" displayName="A Number" description="A number between 1 and 100, inclusive">
- <c:constraint>
- <c:integer-constraint minimum="1" maximum="100"/>
- </c:constraint>
- </c:simple-property>
- </c:group>
- </parameters>
- <results>
- <c:simple-property name="results" />
- </results>
- </operation>
-
- <!--
- CHANGE: For each measurement that should be collected for resources of this type, a metric element is added.
- In addition to identifying the metric, a default collection interval and whether or not the
- metric is even collected by default are indicated. If the resource has no measurements to be
- collected, these elements may be omitted.
-
- REQUIRED INTERFACE: The resource component for this resource type must implement the MeasurementFacet interface
- if any metrics are specified.
- -->
- <metric property="MeasurementName"
- displayName="The Measurement Name"
- description="Describes what this measurement is actually telling you"
- defaultOn="true"
- defaultInterval="300000"
- category="performance" />
-
- <!--
- CHANGE: Resource configuration properties are used to configure resources themselves, as compared to the plugin
- configuration which refers to the connection to a resource. If the resource-configuration
- entity is specified, at least one property must be provided.
-
- REQUIRED INTERFACE: The resource component for this resource type must implement the ConfigurationFacet
- interface if a resource-configuration element is supplied.
- -->
- <resource-configuration>
- <c:simple-property name="port" type="integer" displayName="Port on which to listen" />
- </resource-configuration>
- </server>
+ </service>
</plugin>
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
index bada521..971ccb1 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
@@ -24,6 +24,9 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.testng.annotations.AfterSuite;
+import org.testng.annotations.BeforeSuite;
+import org.testng.annotations.Test;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
import org.rhq.core.domain.resource.Resource;
@@ -32,22 +35,19 @@ import org.rhq.core.pc.PluginContainerConfiguration;
import org.rhq.core.pc.plugin.FileSystemPluginFinder;
import org.rhq.core.pc.plugin.PluginEnvironment;
import org.rhq.core.pc.plugin.PluginManager;
-import org.testng.annotations.AfterSuite;
-import org.testng.annotations.BeforeSuite;
-import org.testng.annotations.Test;
/**
* @author Fady Matar
*/
-@Test(groups = "tomcat-plugin")
+@Test(groups = "modcluster-plugin")
public class ModclusterPluginTest {
private Log log = LogFactory.getLog(this.getClass());
- private static final String PLUGIN_NAME = "Tomcat";
+ private static final String PLUGIN_NAME = "mod_cluster";
@BeforeSuite
public void start() {
try {
- File pluginDir = new File("target/itest/plugins");
+ File pluginDir = new File("target/testsetup/plugins");
PluginContainerConfiguration pcConfig = new PluginContainerConfiguration();
pcConfig.setPluginFinder(new FileSystemPluginFinder(pluginDir));
pcConfig.setPluginDirectory(pluginDir);
@@ -75,16 +75,22 @@ public class ModclusterPluginTest {
PluginEnvironment pluginEnvironment = pluginManager.getPlugin(PLUGIN_NAME);
assert (pluginEnvironment != null) : "Null environment, plugin not loaded";
assert (pluginEnvironment.getPluginName().equals(PLUGIN_NAME));
+
}
@Test(dependsOnMethods = "testPluginLoad")
public void testDiscovery() throws Exception {
InventoryReport report = PluginContainer.getInstance().getInventoryManager().executeServerScanImmediately();
assert report != null;
- log.info("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
+ System.out.println("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
+
+ report = PluginContainer.getInstance().getInventoryManager().executeServiceScanImmediately();
+ assert report != null;
+ System.out.println("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
+
Set<Resource> resources = findResource(PluginContainer.getInstance().getInventoryManager().getPlatform(),
- "Tomcat");
- log.info("Found " + resources.size() + " ews / apache tomcat instance(s).");
+ PLUGIN_NAME);
+ log.info("Found " + resources.size() + "mod_cluster instance(s).");
}
private Set<Resource> findResource(Resource parent, String typeName) {
commit 288af403c3c181cb3915b2fbe067bb23937f1e39
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Thu Jun 23 11:09:56 2011 -0500
A couple of updates to modcluster plugin based on tomcat plugin (modified the initial template commit).
diff --git a/modules/plugins/mod-cluster/pom.xml b/modules/plugins/mod-cluster/pom.xml
index b72c93d..e22efc7 100644
--- a/modules/plugins/mod-cluster/pom.xml
+++ b/modules/plugins/mod-cluster/pom.xml
@@ -1,25 +1,36 @@
<?xml version="1.0"?>
-<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">
+<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>
- <groupId>org.rhq.sample.skeletonplugin</groupId>
- <artifactId>skeleton-plugin</artifactId>
+ <parent>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-plugins-parent</artifactId>
+ <version>4.1.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.rhq.plugins.modcluster</groupId>
+ <artifactId>modcluster-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
- <name>Skeleton RHQ Plugin Template</name>
- <description>A template for building a custom RHQ Agent plugin</description>
+ <name>mod_cluster RHQ Plugin</name>
+ <description>mod_cluster RHQ Agent plugin</description>
- <properties>
+ <!--properties>
<rhq.version>4.1.0-SNAPSHOT</rhq.version>
- </properties>
+ </properties-->
<dependencies>
+ <dependency>
+ <groupId>${rhq.groupId}</groupId>
+ <artifactId>rhq-jmx-plugin</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
<!-- Below are the core modules that are required dependencies of all plugins -->
<dependency>
<groupId>org.rhq</groupId>
@@ -77,15 +88,14 @@
<scope>provided</scope>
</dependency>
- <!--
+
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
<scope>provided</scope>
</dependency>
- -->
-
+
<!--
<dependency>
<groupId>i18nlog</groupId>
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginDiscoveryComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginDiscoveryComponent.java
index 2bb46e6..2abd0ea 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginDiscoveryComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginDiscoveryComponent.java
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-package org.rhq.sample.skeletonplugin;
+package org.rhq.plugins.modcluster;
import java.util.HashSet;
import java.util.List;
@@ -113,4 +113,4 @@ public class SamplePluginDiscoveryComponent implements ResourceDiscoveryComponen
return set;
}
-}
\ No newline at end of file
+}
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginServerComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginServerComponent.java
index 701afb0..0236532 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginServerComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginServerComponent.java
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-package org.rhq.sample.skeletonplugin;
+package org.rhq.plugins.modcluster;
import java.io.InputStream;
import java.util.List;
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index 2547af7..1a99bf7 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -1,36 +1,25 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<!--
- See the rhq-plugin.xsd file for detailed documentatoin on the schema. The notes in this file are to
- facilitate using this file as a base plugin descriptor.
--->
-
-<!--
- CHANGE: The name (and optional displayName) should be changed to reflect the plugin being developed. Keep in mind
- the value for name must be unique across all other plugins that are deployed.
-
- The package attribute should be changed to reflect the package in which all of the component classes
- are built.
--->
-<plugin name="SkeletonPlugin"
- displayName="Skeleton Plugin"
+<plugin name="mod_cluster"
+ displayName="mod_cluster"
version="1.0"
- package="org.rhq.sample.skeletonplugin"
+ package="org.rhq.plugins.modcluster"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
+ <depends plugin="JMX" />
- <!--
+ <!--
CHANGE: The following is a sample server resource type. This entry is here to serve as a model and should
be removed prior to deploying the plugin. Multiple resource types (either server or service) may be
defined at this level.
-->
- <server name="Sample Plugin Server"
+ <server name="mod_cluster"
discovery="SamplePluginDiscoveryComponent"
class="SamplePluginServerComponent"
supportsManualAdd="true"
- description="This is a sample resource type and should be removed.">
+ description="mod_cluster plugin">
<!--
CHANGE: Categories are optional; this entire section may be removed if there is no need to further group
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
new file mode 100644
index 0000000..bada521
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
@@ -0,0 +1,106 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.modcluster.test;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.pc.PluginContainer;
+import org.rhq.core.pc.PluginContainerConfiguration;
+import org.rhq.core.pc.plugin.FileSystemPluginFinder;
+import org.rhq.core.pc.plugin.PluginEnvironment;
+import org.rhq.core.pc.plugin.PluginManager;
+import org.testng.annotations.AfterSuite;
+import org.testng.annotations.BeforeSuite;
+import org.testng.annotations.Test;
+
+/**
+ * @author Fady Matar
+ */
+@Test(groups = "tomcat-plugin")
+public class ModclusterPluginTest {
+ private Log log = LogFactory.getLog(this.getClass());
+ private static final String PLUGIN_NAME = "Tomcat";
+
+ @BeforeSuite
+ public void start() {
+ try {
+ File pluginDir = new File("target/itest/plugins");
+ PluginContainerConfiguration pcConfig = new PluginContainerConfiguration();
+ pcConfig.setPluginFinder(new FileSystemPluginFinder(pluginDir));
+ pcConfig.setPluginDirectory(pluginDir);
+
+ pcConfig.setInsideAgent(false);
+ PluginContainer.getInstance().setConfiguration(pcConfig);
+ PluginContainer.getInstance().initialize();
+ log.info("PC started.");
+ for (String plugin : PluginContainer.getInstance().getPluginManager().getMetadataManager().getPluginNames()) {
+ log.info("...Loaded plugin: " + plugin);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @AfterSuite
+ public void stop() {
+ PluginContainer.getInstance().shutdown();
+ }
+
+ @Test
+ public void testPluginLoad() {
+ PluginManager pluginManager = PluginContainer.getInstance().getPluginManager();
+ PluginEnvironment pluginEnvironment = pluginManager.getPlugin(PLUGIN_NAME);
+ assert (pluginEnvironment != null) : "Null environment, plugin not loaded";
+ assert (pluginEnvironment.getPluginName().equals(PLUGIN_NAME));
+ }
+
+ @Test(dependsOnMethods = "testPluginLoad")
+ public void testDiscovery() throws Exception {
+ InventoryReport report = PluginContainer.getInstance().getInventoryManager().executeServerScanImmediately();
+ assert report != null;
+ log.info("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
+ Set<Resource> resources = findResource(PluginContainer.getInstance().getInventoryManager().getPlatform(),
+ "Tomcat");
+ log.info("Found " + resources.size() + " ews / apache tomcat instance(s).");
+ }
+
+ private Set<Resource> findResource(Resource parent, String typeName) {
+ Set<Resource> found = new HashSet<Resource>();
+ Resource platform = parent;
+ for (Resource resource : platform.getChildResources()) {
+ log.info("Discovered resource of type: " + resource.getResourceType().getName());
+ if (resource.getResourceType().getName().equals(typeName)) {
+ found.add(resource);
+ }
+ if (resource.getChildResources() != null) {
+ for (Resource child : found) {
+ found.addAll(findResource(child, typeName));
+ }
+ }
+ }
+ return found;
+ }
+}
diff --git a/modules/plugins/mod-cluster/src/test/resources/log4j.xml b/modules/plugins/mod-cluster/src/test/resources/log4j.xml
new file mode 100644
index 0000000..9ac1be8
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/test/resources/log4j.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<!-- ===================================================================== -->
+<!-- -->
+<!-- Log4j Configuration -->
+<!-- -->
+<!-- ===================================================================== -->
+
+<!-- $Id: log4j.xml 9973 2008-05-08 00:57:31Z ispringer $ -->
+
+<!--
+ | For more configuration infromation and examples see the Jakarta Log4j
+ | owebsite: http://jakarta.apache.org/log4j
+ -->
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="true">
+
+ <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">
+ <!-- The default pattern: Date Priority [Category] Messagen -->
+
+ <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n"/>
+
+ <!--<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="Threshold" value="DEBUG"/>
+ <param name="Append" value="false"/>
+
+ <layout class="org.apache.log4j.PatternLayout">
+ <!-- The default pattern: Date Priority [Category] Messagen -->
+ <!--
+ <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n"/>
+ -->
+ <param name="ConversionPattern" value="%-5p %d{dd-MM HH:mm:ss,SSS} (%F:%M:%L) -%m%n"/>
+ </layout>
+ </appender>
+
+ <root>
+ <appender-ref ref="CONSOLE"/>
+ <appender-ref ref="FILE"/>
+ </root>
+
+</log4j:configuration>
commit f5d95830a0ef0c23f58af2f60e34375a2b9273b9
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Wed Jun 22 15:52:27 2011 -0500
Start for mod_cluster plugin from skeleton-plugin template.
diff --git a/modules/plugins/mod-cluster/pom.xml b/modules/plugins/mod-cluster/pom.xml
new file mode 100644
index 0000000..b72c93d
--- /dev/null
+++ b/modules/plugins/mod-cluster/pom.xml
@@ -0,0 +1,240 @@
+<?xml version="1.0"?>
+
+<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>
+
+ <groupId>org.rhq.sample.skeletonplugin</groupId>
+ <artifactId>skeleton-plugin</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <name>Skeleton RHQ Plugin Template</name>
+ <description>A template for building a custom RHQ Agent plugin</description>
+
+ <properties>
+ <rhq.version>4.1.0-SNAPSHOT</rhq.version>
+ </properties>
+
+ <dependencies>
+
+ <!-- Below are the core modules that are required dependencies of all plugins -->
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-domain</artifactId>
+ <version>${rhq.version}</version>
+ <scope>provided</scope> <!-- provided by the agent/plugin-container -->
+ </dependency>
+
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-plugin-api</artifactId>
+ <version>${rhq.version}</version>
+ <scope>provided</scope> <!-- provided by the agent/plugin-container -->
+ </dependency>
+
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-native-system</artifactId>
+ <version>${rhq.version}</version>
+ <scope>provided</scope> <!-- provided by the agent/plugin-container -->
+ </dependency>
+
+ <!-- Fix for the Javac bug requiring annotations to be available when compiling classes. (fixed in JDK 6) -->
+ <dependency>
+ <groupId>javax.persistence</groupId>
+ <artifactId>persistence-api</artifactId>
+ <version>1.0</version>
+ <scope>provided</scope> <!-- provided by the agent/plugin-container -->
+ </dependency>
+
+ <!-- Fix for the Javac bug requiring annotations to be available when compiling classes. (fixed in JDK 6) -->
+ <dependency>
+ <groupId>hibernate-annotations</groupId>
+ <artifactId>hibernate-annotations</artifactId>
+ <version>3.2.1.GA</version>
+ <scope>provided</scope> <!-- provided by the agent/plugin-container -->
+ </dependency>
+
+ <!-- Fix for the Javac bug requiring annotations to be available when compiling classes. (fixed in JDK 6) -->
+ <dependency>
+ <groupId>javax.xml.bind</groupId>
+ <artifactId>jaxb-api</artifactId>
+ <version>2.1</version>
+ <scope>provided</scope> <!-- provided by the agent/plugin-container -->
+ </dependency>
+
+ <!--
+ Uncomment the one of the three logging systems your plugin uses: log4j, commons-logging or i18nlog
+ All three are provided to your plugin by the agent/plugin-container.
+ -->
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <version>1.1</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <!--
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>1.2.14</version>
+ <scope>provided</scope>
+ </dependency>
+ -->
+
+ <!--
+ <dependency>
+ <groupId>i18nlog</groupId>
+ <artifactId>i18nlog</artifactId>
+ <version>1.0.9</version>
+ <scope>provided</scope>
+ </dependency>
+ -->
+
+ <!-- Define any third-party dependencies your plugin has here. -->
+ <!--
+ <dependency>
+ <groupId>group-id-of-dependency-goes-here</groupId>
+ <artifactId>artifact-id-of-dependency-goes-here</artifactId>
+ <version>version-of-dependency-goes-here</version>
+ </dependency>
+ -->
+
+ </dependencies>
+
+ <build>
+ <plugins>
+
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+
+ <!--
+ If your plugin has third-party jar dependencies that are not already available when deployed in the plugin
+ container, you can package these jars in your plugin. They go in your plugin jar's "lib" directory.
+ Uncomment the maven plugin definition below and define one or more jar files (aka "artifactItem" elements)
+ that you want to include in your plugin jar.
+ -->
+ <!--
+ <plugin>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy-dependencies</id>
+ <phase>process-resources</phase>
+ <goals>
+ <goal>copy</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>your-third-party-dep-group</groupId>
+ <artifactId>your-third-party-dep-artifact</artifactId>
+ <version>your-third-party-dep-version</version>
+ </artifactItem>
+ </artifactItems>
+ <outputDirectory>${project.build.outputDirectory}/lib</outputDirectory>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ -->
+
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>dev</id>
+ <properties>
+ <!-- define the location of your RHQ root directory - typically rhq.rootDir is overridden in Maven's settings.xml -->
+ <rhq.rootDir>/rhq/trunk</rhq.rootDir>
+ <rhq.defaultDevContainerPath>dev-container</rhq.defaultDevContainerPath>
+ <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir>
+ <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/rhq.ear/rhq-downloads/rhq-plugins</rhq.deploymentDir>
+ </properties>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.1</version>
+ <executions>
+ <execution>
+ <id>deploy</id>
+ <phase>compile</phase>
+ <configuration>
+ <tasks>
+ <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}" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>deploy-jar-meta-inf</id>
+ <phase>package</phase>
+ <configuration>
+ <tasks>
+ <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>
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>undeploy</id>
+ <phase>clean</phase>
+ <configuration>
+ <tasks>
+ <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
+ <echo>*** Deleting ${deployment.file}...</echo>
+ <delete file="${deployment.file}" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+ <repositories>
+ <repository>
+ <id>jboss-public-repository-group</id>
+ <name>JBoss Public Maven Repository Group</name>
+ <url>https://repository.jboss.org/nexus/content/groups/public/</url>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+
+</project>
+
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginDiscoveryComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginDiscoveryComponent.java
new file mode 100644
index 0000000..2bb46e6
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginDiscoveryComponent.java
@@ -0,0 +1,116 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.sample.skeletonplugin;
+
+import java.util.HashSet;
+import java.util.List;
+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.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ManualAddFacet;
+import org.rhq.core.pluginapi.inventory.ProcessScanResult;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+
+/**
+ * This can be the start of your own custom plugin's discovery component. Review the javadoc for
+ * {@link ResourceDiscoveryComponent}.
+ *
+ * @author John Mazzitelli
+ */
+@SuppressWarnings("unchecked")
+public class SamplePluginDiscoveryComponent implements ResourceDiscoveryComponent, ManualAddFacet {
+ private final Log log = LogFactory.getLog(SamplePluginDiscoveryComponent.class);
+
+ /**
+ * This discovery method is the way the plugin supports "manual-add" capability. The plugin
+ * descriptor must specify supportsManualAdd="true" to allow the resource to be manually added.
+ * If that attribute is false, this method will never be used since it will not be possible to manually
+ * add an instance of the resource.
+ *
+ * Review the javadoc for both {@link ManualAddFacet} and {@link ResourceDiscoveryContext} to learn what
+ * you need to do in this method.
+ *
+ * @see ManualAddFacet#discoverResource(Configuration, ResourceDiscoveryContext)
+ */
+ @Override
+ public DiscoveredResourceDetails discoverResource(Configuration pluginConfiguration,
+ ResourceDiscoveryContext context) throws InvalidPluginConfigurationException {
+
+ // pluginConfiguration contains information on a resource that was manually added by the user.
+ // take it and build a details object that represents that resource.
+
+ // key = this must be a unique string across all of your resources - see docs for uniqueness rules
+ // name = this is the name you give the new resource; it does not necessarily have to be unique
+ // version = this is any string that corresponds to the resource's version
+ // description = this is any string that you want to assign as the default description for your resource
+ String key = "My Manually Added Resource Key";
+ String name = "My Resource";
+ String version = "1.0";
+ String description = "This describes My Resource";
+
+ DiscoveredResourceDetails resource = new DiscoveredResourceDetails(context.getResourceType(), key, name,
+ version, description, pluginConfiguration, null);
+
+ return resource;
+ }
+
+ /**
+ * Review the javadoc for both {@link ResourceDiscoveryComponent} and {@link ResourceDiscoveryContext} to learn what
+ * you need to do in this method.
+ *
+ * @see ResourceDiscoveryComponent#discoverResources(ResourceDiscoveryContext)
+ */
+ @Override
+ public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext context) {
+ log.info("Discovering my custom plugin's resources");
+
+ // if your plugin descriptor defined one or more <process-scan>s, then see if the plugin container
+ // auto-discovered processes using those process scan definitions. Process all those that were found.
+ List<ProcessScanResult> autoDiscoveryResults = context.getAutoDiscoveredProcesses();
+ for (ProcessScanResult autoDiscoveryResult : autoDiscoveryResults) {
+ // determine if you want to include the result in this method's returned set of discovered resources
+ }
+
+ // now perform your own discovery mechanism, if you have one. For each resource discovered, you need to
+ // create a details object that describe the resource that you discovered.
+ HashSet<DiscoveredResourceDetails> set = new HashSet<DiscoveredResourceDetails>();
+
+ // key = this must be a unique string across all of your resources - see docs for uniqueness rules
+ // name = this is the name you give the new resource; it does not necessarily have to be unique
+ // version = this is any string that corresponds to the resource's version
+ // description = this is any string that you want to assign as the default description for your resource
+ String key = "My Resource Key";
+ String name = "My Resource";
+ String version = "1.0";
+ String description = "This describes My Resource";
+
+ DiscoveredResourceDetails resource = new DiscoveredResourceDetails(context.getResourceType(), key, name,
+ version, description, null, null);
+
+ set.add(resource);
+
+ return set;
+ }
+}
\ No newline at end of file
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginServerComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginServerComponent.java
new file mode 100644
index 0000000..701afb0
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginServerComponent.java
@@ -0,0 +1,245 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.sample.skeletonplugin;
+
+import java.io.InputStream;
+import java.util.List;
+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.configuration.ConfigurationUpdateStatus;
+import org.rhq.core.domain.content.PackageType;
+import org.rhq.core.domain.content.transfer.DeployPackageStep;
+import org.rhq.core.domain.content.transfer.DeployPackagesResponse;
+import org.rhq.core.domain.content.transfer.RemovePackagesResponse;
+import org.rhq.core.domain.content.transfer.ResourcePackageDetails;
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.domain.measurement.MeasurementDataNumeric;
+import org.rhq.core.domain.measurement.MeasurementReport;
+import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
+import org.rhq.core.pluginapi.configuration.ConfigurationFacet;
+import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport;
+import org.rhq.core.pluginapi.content.ContentFacet;
+import org.rhq.core.pluginapi.content.ContentServices;
+import org.rhq.core.pluginapi.inventory.CreateChildResourceFacet;
+import org.rhq.core.pluginapi.inventory.CreateResourceReport;
+import org.rhq.core.pluginapi.inventory.DeleteResourceFacet;
+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;
+
+/**
+ * This can be the start of your own custom plugin's server component. Review the javadoc for {@link ResourceComponent}
+ * and all the facet interfaces to learn what you can do in your resource component. This component has a lot of methods
+ * in it because it implements all possible facets. If your resource does not support, for example, configuration, you
+ * can remove the {@link ConfigurationFacet} from the <code>implements</code> clause and remove all method
+ * implementations that that facet required.
+ *
+ * <p>You should not only read the javadoc in each of this class' methods, but you should also read the javadocs linked
+ * by their "see" javadoc tags since those additional javadocs will contain a good deal of additional information you
+ * will need to know.</p>
+ *
+ * @author John Mazzitelli
+ */
+public class SamplePluginServerComponent implements ResourceComponent, MeasurementFacet, OperationFacet,
+ ConfigurationFacet, ContentFacet, DeleteResourceFacet, CreateChildResourceFacet {
+ private final Log log = LogFactory.getLog(SamplePluginServerComponent.class);
+
+ /**
+ * Represents the resource configuration of the custom product being managed.
+ */
+ private Configuration resourceConfiguration;
+
+ /**
+ * All AMPS plugins are stateful - this context contains information that your resource component can use when
+ * performing its processing.
+ */
+ private ResourceContext resourceContext;
+
+ /**
+ * This is called when your component has been started with the given context. You normally initialize some internal
+ * state of your component as well as attempt to make a stateful connection to your managed resource.
+ *
+ * @see ResourceComponent#start(ResourceContext)
+ */
+ public void start(ResourceContext context) {
+ resourceContext = context;
+ }
+
+ /**
+ * This is called when the component is being stopped, usually due to the plugin container shutting down. You can
+ * perform some cleanup here; though normally not much needs to be done here.
+ *
+ * @see ResourceComponent#stop()
+ */
+ public void stop() {
+ }
+
+ /**
+ * All resource components must be able to tell the plugin container if the managed resource is available or not.
+ * This method is called by the plugin container when it needs to know if the managed resource is actually up and
+ * available.
+ *
+ * @see ResourceComponent#getAvailability()
+ */
+ public AvailabilityType getAvailability() {
+ // TODO: here you normally make some type of connection attempt to the managed resource
+ // to determine if it is really up and running.
+ return AvailabilityType.UP;
+ }
+
+ /**
+ * The plugin container will call this method when your resource component has been scheduled to collect some
+ * measurements now. It is within this method that you actually talk to the managed resource and collect the
+ * measurement data that is has emitted.
+ *
+ * @see MeasurementFacet#getValues(MeasurementReport, Set)
+ */
+ public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> requests) {
+ for (MeasurementScheduleRequest request : requests) {
+ String name = request.getName();
+
+ // TODO: based on the request information, you must collect the requested measurement(s)
+ // you can use the name of the measurement to determine what you actually need to collect
+ try {
+ Number value = new Integer(1); // dummy measurement value - this should come from the managed resource
+ report.addData(new MeasurementDataNumeric(request, value.doubleValue()));
+ } catch (Exception e) {
+ log.error("Failed to obtain measurement [" + name + "]. Cause: " + e);
+ }
+ }
+
+ return;
+ }
+
+ /**
+ * The plugin container will call this method when it wants to invoke an operation on your managed resource. Your
+ * plugin will connect to the managed resource and invoke the analogous operation in your own custom way.
+ *
+ * @see OperationFacet#invokeOperation(String, Configuration)
+ */
+ public OperationResult invokeOperation(String name, Configuration configuration) {
+ return null;
+ }
+
+ /**
+ * The plugin container will call this method and it needs to obtain the current configuration of the managed
+ * resource. Your plugin will obtain the managed resource's configuration in your own custom way and populate the
+ * returned Configuration object with the managed resource's configuration property values.
+ *
+ * @see ConfigurationFacet#loadResourceConfiguration()
+ */
+ public Configuration loadResourceConfiguration() {
+ // here we simulate the loading of the managed resource's configuration
+
+ if (resourceConfiguration == null) {
+ // for this example, we will create a simple dummy configuration to start with.
+ // note that it is empty, so we're assuming there are no required configs in the plugin descriptor.
+ resourceConfiguration = new Configuration();
+ }
+
+ Configuration config = resourceConfiguration;
+
+ return config;
+ }
+
+ /**
+ * The plugin container will call this method when it has a new configuration for your managed resource. Your plugin
+ * will re-configure the managed resource in your own custom way, setting its configuration based on the new values
+ * of the given configuration.
+ *
+ * @see ConfigurationFacet#updateResourceConfiguration(ConfigurationUpdateReport)
+ */
+ public void updateResourceConfiguration(ConfigurationUpdateReport report) {
+ // this simulates the plugin taking the new configuration and reconfiguring the managed resource
+ resourceConfiguration = report.getConfiguration().deepCopy();
+
+ report.setStatus(ConfigurationUpdateStatus.SUCCESS);
+ }
+
+ /**
+ * When this is called, the plugin is responsible for scanning its managed resource and look for content that need
+ * to be managed for that resource. This method should only discover packages of the given package type.
+ *
+ * @see ContentFacet#discoverDeployedPackages(PackageType)
+ */
+ public Set<ResourcePackageDetails> discoverDeployedPackages(PackageType type) {
+ return null;
+ }
+
+ /**
+ * The plugin container calls this method when new packages need to be deployed/installed on resources.
+ *
+ * @see ContentFacet#deployPackages(Set, ContentServices)
+ */
+ public DeployPackagesResponse deployPackages(Set<ResourcePackageDetails> packages, ContentServices contentServices) {
+ return null;
+ }
+
+ /**
+ * When a remote client wants to see the actual data content for an installed package, this method will be called.
+ * This method must return a stream of data containing the full content of the package.
+ *
+ * @see ContentFacet#retrievePackageBits(ResourcePackageDetails)
+ */
+ public InputStream retrievePackageBits(ResourcePackageDetails packageDetails) {
+ return null;
+ }
+
+ /**
+ * This is the method that is used when the component has to create the installation steps and their results.
+ *
+ * @see ContentFacet#generateInstallationSteps(ResourcePackageDetails)
+ */
+ public List<DeployPackageStep> generateInstallationSteps(ResourcePackageDetails packageDetails) {
+ return null;
+ }
+
+ /**
+ * This is called when the actual content of packages should be deleted from the managed resource.
+ *
+ * @see ContentFacet#removePackages(Set)
+ */
+ public RemovePackagesResponse removePackages(Set<ResourcePackageDetails> packages) {
+ return null;
+ }
+
+ /**
+ * When called, the plugin container is asking the plugin to create a new managed resource. The new resource's
+ * details need to be added to the given report.
+ *
+ * @see CreateChildResourceFacet#createResource(CreateResourceReport)
+ */
+ public CreateResourceReport createResource(CreateResourceReport report) {
+ return null;
+ }
+
+ /**
+ * When called, the plugin container is asking the plugin to delete a managed resource.
+ *
+ * @see DeleteResourceFacet#deleteResource()
+ */
+ public void deleteResource() {
+ }
+}
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
new file mode 100644
index 0000000..2547af7
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+ See the rhq-plugin.xsd file for detailed documentatoin on the schema. The notes in this file are to
+ facilitate using this file as a base plugin descriptor.
+-->
+
+<!--
+ CHANGE: The name (and optional displayName) should be changed to reflect the plugin being developed. Keep in mind
+ the value for name must be unique across all other plugins that are deployed.
+
+ The package attribute should be changed to reflect the package in which all of the component classes
+ are built.
+-->
+<plugin name="SkeletonPlugin"
+ displayName="Skeleton Plugin"
+ version="1.0"
+ package="org.rhq.sample.skeletonplugin"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+
+ <!--
+ CHANGE: The following is a sample server resource type. This entry is here to serve as a model and should
+ be removed prior to deploying the plugin. Multiple resource types (either server or service) may be
+ defined at this level.
+ -->
+ <server name="Sample Plugin Server"
+ discovery="SamplePluginDiscoveryComponent"
+ class="SamplePluginServerComponent"
+ supportsManualAdd="true"
+ description="This is a sample resource type and should be removed.">
+
+ <!--
+ CHANGE: Categories are optional; this entire section may be removed if there is no need to further group
+ related child resources. Categories defined at this level can carry metadata on the category itself,
+ such as a display name and description.
+ -->
+ <subcategories>
+ <subcategory name="Category1" displayName="Sample Category 1"
+ description="This is a sample category that should be removed."/>
+ <subcategory name="Category2" >
+ <subcategory name="ChildCategory2a" />
+ </subcategory>
+ </subcategories>
+
+ <!--
+ CHANGE: The entire plugin configuration is optional. If there are properties specific to handling how the
+ resource component will connect to the resource, they should be added here. If the plugin-configuration
+ entity is specified, at least one property must be provided.
+ -->
+ <plugin-configuration>
+ <c:simple-property name="SamplePluginProperty" displayName="Sample Plugin Property" default="Value" />
+ </plugin-configuration>
+
+ <!--
+ CHANGE: The process-scan element requests the plugin container provide the discovery component for
+ this resource type with the results of scanning the machine for running processes. If there is
+ no use for this in a given resource type, this entry may be omitted.
+ -->
+ <process-scan name="ScanIdentifier" query="process|basename|match=^java.*,arg|org.jboss.Main|match=.*"/>
+
+ <!--
+ CHANGE: An operation element is added for each operation that may be executed against resources of this type.
+ The parameters element is optional; properties defined within will be displayed to the user when
+ invoking the operation. If the resource has no applicable operations, these elements may be omitted.
+
+ REQUIRED INTERFACE: The resource component for this resource type must implement the OperationFacet interface
+ if any operations are specified.
+ -->
+ <operation name="testSimple"
+ description="Test simple-property configuration element for a resource operation">
+ <parameters>
+ <c:group name="required" displayName="Required Parameters" hiddenByDefault="false">
+ <c:description>All of these properties are required</c:description>
+ <c:simple-property name="aNumber" type="integer" required="true" default="42" displayName="A Number" description="A number between 1 and 100, inclusive">
+ <c:constraint>
+ <c:integer-constraint minimum="1" maximum="100"/>
+ </c:constraint>
+ </c:simple-property>
+ </c:group>
+ </parameters>
+ <results>
+ <c:simple-property name="results" />
+ </results>
+ </operation>
+
+ <!--
+ CHANGE: For each measurement that should be collected for resources of this type, a metric element is added.
+ In addition to identifying the metric, a default collection interval and whether or not the
+ metric is even collected by default are indicated. If the resource has no measurements to be
+ collected, these elements may be omitted.
+
+ REQUIRED INTERFACE: The resource component for this resource type must implement the MeasurementFacet interface
+ if any metrics are specified.
+ -->
+ <metric property="MeasurementName"
+ displayName="The Measurement Name"
+ description="Describes what this measurement is actually telling you"
+ defaultOn="true"
+ defaultInterval="300000"
+ category="performance" />
+
+ <!--
+ CHANGE: Resource configuration properties are used to configure resources themselves, as compared to the plugin
+ configuration which refers to the connection to a resource. If the resource-configuration
+ entity is specified, at least one property must be provided.
+
+ REQUIRED INTERFACE: The resource component for this resource type must implement the ConfigurationFacet
+ interface if a resource-configuration element is supplied.
+ -->
+ <resource-configuration>
+ <c:simple-property name="port" type="integer" displayName="Port on which to listen" />
+ </resource-configuration>
+ </server>
+</plugin>
commit b13a3515a996de937f8345fa287f044f90454d41
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Wed Jul 27 22:42:04 2011 -0500
Make the error message useful by adding the name of the attribute that failed to set.
diff --git a/modules/plugins/jmx/src/main/java/org/rhq/plugins/jmx/MBeanResourceComponent.java b/modules/plugins/jmx/src/main/java/org/rhq/plugins/jmx/MBeanResourceComponent.java
index 2e1ae41..cb7f901 100644
--- a/modules/plugins/jmx/src/main/java/org/rhq/plugins/jmx/MBeanResourceComponent.java
+++ b/modules/plugins/jmx/src/main/java/org/rhq/plugins/jmx/MBeanResourceComponent.java
@@ -503,7 +503,7 @@ public class MBeanResourceComponent<T extends JMXComponent> implements Measureme
property.setErrorMessage(ThrowableUtil.getStackAsString(e));
report
.setErrorMessage("Failed setting resource configuration - see property error messages for details");
- log.info("Failure setting MBean Resource configuration value", e);
+ log.info("Failure setting MBean Resource configuration value for " + key, e);
}
}
}
commit 7e0f49de3b2da3b4b4d1987eb3fe53e42abbbf68
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Wed Jul 27 22:41:13 2011 -0500
Final touches for mod_cluster plugin configuration. Updated a couple of the plugin settings to match mod_cluster specifications.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
index 5c9c3fd..3d03715 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
@@ -42,9 +42,9 @@ import org.rhq.plugins.jmx.MBeanResourceComponent;
@SuppressWarnings("rawtypes")
public class ContextDiscoveryComponent implements ResourceDiscoveryComponent<MBeanResourceComponent> {
- private final String JVM_ROUTE_PROPERTY = "jvmRoute";
- private final String PROXY_INFO_PROPERTY = "proxyInfo";
- private final String ADDITIONAL_CONFIG_BEAN_PROPERTY = "additionalConfigurationObjectName";
+ private static final String JVM_ROUTE_PROPERTY = "jvmRoute";
+ private static final String PROXY_INFO_PROPERTY = "proxyInfo";
+ private static final String ENGINE_OBJECT_NAME = "engineObjectName";
/* (non-Javadoc)
* @see org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent#discoverResources(org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext)
@@ -76,8 +76,8 @@ public class ContextDiscoveryComponent implements ResourceDiscoveryComponent<MBe
*/
private String getJvmRoute(ResourceDiscoveryContext<MBeanResourceComponent> context) {
Configuration pluginConfig = context.getParentResourceComponent().getResourceContext().getPluginConfiguration();
- String objectName = pluginConfig.getSimple(ADDITIONAL_CONFIG_BEAN_PROPERTY).getStringValue();
- EmsBean engineBean = this.loadBean(objectName, context.getParentResourceComponent());
+ String engineObjectName = pluginConfig.getSimple(ENGINE_OBJECT_NAME).getStringValue();
+ EmsBean engineBean = this.loadBean(engineObjectName, context.getParentResourceComponent());
return (String) engineBean.getAttribute(JVM_ROUTE_PROPERTY).refresh().toString();
}
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
index 591fef6..70898ef 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
@@ -25,7 +25,7 @@ import org.rhq.plugins.jmx.MBeanResourceComponent;
* @author Stefan Negrea
*
*/
-@SuppressWarnings("rawtypes")
+@SuppressWarnings({ "rawtypes" })
public class ModclusterServerComponent extends MBeanResourceComponent {
/* (non-Javadoc)
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index 992c5b0..29b334f 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -25,9 +25,7 @@
<plugin-configuration>
<c:simple-property name="objectName" readOnly="true" default="Catalina:type=ModClusterListener,*"/>
- <c:simple-property name="additionalConfigurationObjectName" readOnly="true" default="jboss.web:type=Engine"/>
- <c:simple-property name="jvmRoute" readOnly="false"/>
- <c:simple-property name="nameTemplate" default="mod_cluster"/>
+ <c:simple-property name="engineObjectName" readOnly="true" default="jboss.web:type=Engine"/>
</plugin-configuration>
<operation name="stop" displayName="Stop all webapps" description="Gracefully stops all webapps for all engines.">
@@ -76,12 +74,12 @@
<metric property="proxyConfiguration" displayName="Proxy Configuration" displayType="summary" dataType="trait" />
<metric property="modelerType" displayName="Type of the modeled resource" displayType="summary" dataType="trait" />
<metric property="className" displayName="Fully qualified class name of the managed object" displayType="summary" dataType="trait" />
+ <metric property="advertise" displayName="Enable autodiscovery of httpd servers." displayType="summary" dataType="trait" />
<resource-configuration>
<c:simple-property name="workerTimeout" type="integer" description="Timeout to wait for an available worker (default is no wait)" />
<c:simple-property name="stickySession" type="boolean" description="Enables sticky session for the cluster."/>
<c:simple-property name="stickySessionRemove" type="boolean" description="Remove session when the request cannot be routed to the right node."/>
- <!-- c:simple-property name="advertise" type="boolean" description="Enable autodiscovery of httpd servers."/-->
<c:simple-property name="smax" type="integer" description="Maximum time on seconds for idle connections above smax."/>
<c:simple-property name="maxAttempts" type="integer" description="Maximum number of attempts to send the request to the backend server."/>
<c:simple-property name="advertiseSecurityKey" type="string" required="false" description="Security key for discovery."/>
@@ -89,7 +87,6 @@
<c:simple-property name="balancer" type="string" required="false" description="Name of the balancer."/>
<c:simple-property name="flushPackets" type="boolean" description="Allows controlling flusing of packets."/>
<c:simple-property name="socketTimeout" type="integer" description="Connection timeout for communication with the proxy." />
- <c:simple-property name="domain" type="string" required="false" description="Domain parameter, which allows tying a jvmRoute to a particular domain."/>
<c:simple-property name="advertisePort" type="integer" required="false" description="Multicast port for discovery" />
<c:simple-property name="advertiseGroupAddress" type="string" required="false" description="Multicast address for discovery."/>
<c:simple-property name="flushWait" type="integer" description="Time in ms to wait before flushing packets."/>
commit 0890ce0e4f2e6331d3bcca15c799eecba8a15f38
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Jul 27 16:10:09 2011 -0400
[BZ-726202 - alerts not firing despite valid baseline values and alert conditions templates for some agents]
The issue here was that user created baseline did not properly trigger a
measurement condition cache reload for the affected agent. This was due
to the new Baseline not committed/visible to the trans executing the
agent status update.
- also, removed unused findBaselineForResourceAndMeasurementDefinition as
opposed to changing it for this fix.
- made a local public method private and removed some dead commented code
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java
index 282ae1a..286a75e 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java
@@ -355,9 +355,25 @@ public class MeasurementBaselineManagerBean implements MeasurementBaselineManage
return baseline;
}
+ @TransactionAttribute(TransactionAttributeType.NEVER)
public MeasurementBaseline calculateAutoBaseline(Subject subject, Integer measurementScheduleId, long startDate,
long endDate, boolean save) throws BaselineCreationException, MeasurementNotFoundException {
+ MeasurementBaseline result = measurementBaselineManager.calculateAutoBaselineInNewTransaction(subject,
+ measurementScheduleId, startDate, endDate, save);
+
+ if (save) {
+ // note, this executes in a new transaction so the baseline must already be committed to the database
+ agentStatusManager.updateByMeasurementBaseline(result.getId());
+ }
+
+ return result;
+ }
+
+ @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
+ public MeasurementBaseline calculateAutoBaselineInNewTransaction(Subject subject, Integer measurementScheduleId,
+ long startDate, long endDate, boolean save) throws BaselineCreationException, MeasurementNotFoundException {
+
MeasurementBaseline baseline;
MeasurementSchedule sched = entityManager.find(MeasurementSchedule.class, measurementScheduleId);
@@ -391,13 +407,26 @@ public class MeasurementBaselineManagerBean implements MeasurementBaselineManage
return baseline;
}
- //calculateAutoBaseline(LookupUtil.getSubjectManager().getOverlord(),
- //chartForm.getGroupId(), chartForm.getM()[0], chartForm.getStartDate().getTime(), chartForm
- //.getEndDate().getTime(), false);
-
+ @TransactionAttribute(TransactionAttributeType.NEVER)
public MeasurementBaseline calculateAutoBaseline(Subject subject, int groupId, int definitionId, long startDate,
long endDate, boolean save) throws BaselineCreationException, MeasurementNotFoundException {
+ MeasurementBaseline result = measurementBaselineManager.calculateAutoBaselineForGroupInNewTransaction(subject,
+ groupId, definitionId, startDate, endDate, save);
+
+ if (save) {
+ // note, this executes in a new transaction so the baseline must already be committed to the database
+ agentStatusManager.updateByMeasurementBaseline(result.getId());
+ }
+
+ return result;
+ }
+
+ @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
+ public MeasurementBaseline calculateAutoBaselineForGroupInNewTransaction(Subject subject, int groupId,
+ int definitionId, long startDate, long endDate, boolean save) throws BaselineCreationException,
+ MeasurementNotFoundException {
+
if (save && !authorizationManager.hasGroupPermission(subject, Permission.MANAGE_MEASUREMENTS, groupId)) {
throw new PermissionException("User[" + subject.getName()
+ "] does not have permission to calculate and set baselines for group[id=" + groupId + "]");
@@ -405,7 +434,7 @@ public class MeasurementBaselineManagerBean implements MeasurementBaselineManage
MeasurementBaseline baseline;
try {
- baseline = calculateBaseline(groupId, definitionId, true, startDate, endDate, save);
+ baseline = calculateBaselineForGroup(groupId, definitionId, true, startDate, endDate, save);
if (save) {
// We have changed the baseline information for the schedule, so remove the now outdated OOB info.
oobManager.removeOOBsForGroupAndDefinition(subject, groupId, definitionId);
@@ -435,43 +464,6 @@ public class MeasurementBaselineManagerBean implements MeasurementBaselineManage
}
}
- public MeasurementBaseline findBaselineForResourceAndMeasurementDefinition(Subject subject, Integer resourceId,
- Integer measurementDefinitionId) {
- if (!authorizationManager.canViewResource(subject, resourceId)) {
- throw new PermissionException("Cannot view the baseline for resourceId=" + resourceId
- + "] - you do not have permission");
- }
-
- List<MeasurementBaseline> baselines = getBaselinesForResourcesAndDefinitionIds(new Integer[] { resourceId },
- new Integer[] { measurementDefinitionId });
- if ((baselines != null) && (baselines.size() > 0)) {
- return baselines.get(0);
- }
-
- Subject overlord = subjectManager.getOverlord();
- try {
- MeasurementSchedule schedule = measurementScheduleManager.getSchedule(overlord, resourceId,
- measurementDefinitionId, true);
-
- /*
- * Use all available data from the epoch until now to calculate the baseline (we don't need to start from
- * the epoch, because the baseline should have been auto-calculated after a few days, but it's a catch-all)
- */
- MeasurementBaseline baseline = calculateAutoBaseline(overlord, schedule.getId(), 0, System
- .currentTimeMillis(), true);
-
- return baseline;
- } catch (MeasurementNotFoundException mnfe) {
- log.error("Could not find measurement schedule for " + "resourceId=" + resourceId + ", "
- + "measurementDefinitionId=" + measurementDefinitionId, mnfe);
- } catch (BaselineCreationException bce) {
- log.error("Could not calculate baseline for " + "resourceId=" + resourceId + ", "
- + "measurementDefinitionId=" + measurementDefinitionId, bce);
- }
-
- return null;
- }
-
@SuppressWarnings("unchecked")
private List<MeasurementBaseline> getBaselinesForResourcesAndDefinitionIds(Integer[] resourceIds,
Integer[] definitionIds) {
@@ -531,15 +523,13 @@ public class MeasurementBaselineManagerBean implements MeasurementBaselineManage
if (save) {
entityManager.persist(baseline);
entityManager.merge(schedule);
-
- notifyAlertConditionCacheManager("calculateBaseline", baseline);
}
return baseline;
}
- public MeasurementBaseline calculateBaseline(int groupId, int definitionId, boolean userEntered, long startDate,
- long endDate, boolean save) throws DataNotAvailableException, BaselineCreationException {
+ private MeasurementBaseline calculateBaselineForGroup(int groupId, int definitionId, boolean userEntered,
+ long startDate, long endDate, boolean save) throws DataNotAvailableException, BaselineCreationException {
MeasurementAggregate agg = dataManager.getAggregate(subjectManager.getOverlord(), groupId, definitionId,
startDate, endDate);
@@ -583,8 +573,6 @@ public class MeasurementBaselineManagerBean implements MeasurementBaselineManage
if (save) {
entityManager.persist(baseline);
entityManager.merge(schedule);
-
- notifyAlertConditionCacheManager("calculateBaseline", baseline);
}
}
@@ -592,12 +580,6 @@ public class MeasurementBaselineManagerBean implements MeasurementBaselineManage
return baseline;
}
- private void notifyAlertConditionCacheManager(String callingMethod, MeasurementBaseline baseline) {
- agentStatusManager.updateByMeasurementBaseline(baseline.getId());
-
- log.debug("Invoking... " + callingMethod);
- }
-
@SuppressWarnings("unchecked")
public List<MeasurementBaseline> findBaselinesForResource(Subject subject, int resourceId) {
if (authorizationManager.canViewResource(subject, resourceId) == false) {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerLocal.java
index 88d8e94..7f7655a 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerLocal.java
@@ -92,9 +92,17 @@ public interface MeasurementBaselineManagerLocal {
MeasurementBaseline calculateAutoBaseline(Subject subject, Integer measurementScheduleId, long startDate,
long endDate, boolean save) throws BaselineCreationException, MeasurementNotFoundException;
+ // internal use only for transactioning reasons
+ MeasurementBaseline calculateAutoBaselineInNewTransaction(Subject subject, Integer measurementScheduleId,
+ long startDate, long endDate, boolean save) throws BaselineCreationException, MeasurementNotFoundException;
+
MeasurementBaseline calculateAutoBaseline(Subject subject, int groupId, int definitionId, long startDate,
long endDate, boolean save) throws BaselineCreationException, MeasurementNotFoundException;
+ // internal use only for transactioning reasons
+ MeasurementBaseline calculateAutoBaselineForGroupInNewTransaction(Subject subject, int groupId, int definitionId,
+ long startDate, long endDate, boolean save) throws BaselineCreationException, MeasurementNotFoundException;
+
/**
* Unset the {@link MeasurementBaseline#setUserEntered(boolean) user-entered} property in baselines so that we can
* do autobaselines on it again.
@@ -105,19 +113,6 @@ public interface MeasurementBaselineManagerLocal {
*/
void enableAutoBaselineCalculation(Subject subject, Integer[] resourceIds, Integer[] definitionIds);
- /**
- * Returns the baseline for a measurement identified by its measurement definition and the resource whose
- * measurement it is.
- *
- * @param subject
- * @param resource
- * @param measurementDefinitionId
- *
- * @return baseline of the resource's measurement with the given definition
- */
- MeasurementBaseline findBaselineForResourceAndMeasurementDefinition(Subject subject, Integer resource,
- Integer measurementDefinitionId);
-
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
// The following are shared with the Remote Interface
commit 85e65e6a60f04e58e33d1cd32ebaee32a9610b7b
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Wed Jul 27 15:17:52 2011 -0400
context menu on change set node
multiple select tree nodes
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/AbstractDriftChangeSetsTreeView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/AbstractDriftChangeSetsTreeView.java
index 6085af1..8203361 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/AbstractDriftChangeSetsTreeView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/AbstractDriftChangeSetsTreeView.java
@@ -47,7 +47,6 @@ import org.rhq.enterprise.gui.coregui.client.ImageManager;
import org.rhq.enterprise.gui.coregui.client.ViewId;
import org.rhq.enterprise.gui.coregui.client.ViewPath;
import org.rhq.enterprise.gui.coregui.client.components.table.TimestampCellFormatter;
-import org.rhq.enterprise.gui.coregui.client.util.message.Message;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableTreeGrid;
/**
@@ -67,7 +66,7 @@ public abstract class AbstractDriftChangeSetsTreeView extends LocatableTreeGrid
// fetch the top nodes at the inital onDraw()
setAutoFetchData(true);
setAnimateFolders(false);
- setSelectionType(SelectionStyle.SINGLE);
+ setSelectionType(SelectionStyle.MULTIPLE);
setShowRollOver(false);
setShowHeader(false);
setSortField(AbstractDriftChangeSetsTreeDataSource.ATTR_NAME);
@@ -96,9 +95,10 @@ public abstract class AbstractDriftChangeSetsTreeView extends LocatableTreeGrid
TreeNode eventNode = event.getNode();
if (eventNode instanceof ChangeSetTreeNode) {
- CoreGUI.getMessageCenter().notify(new Message("TODO [this will popup the changeset menu]"));
+ Menu menu = buildChangeSetTreeNodeContextMenu((ChangeSetTreeNode) eventNode);
+ menu.showContextMenu();
} else if (eventNode instanceof DriftTreeNode) {
- Menu menu = buildContextMenu((DriftTreeNode) eventNode);
+ Menu menu = buildDriftTreeNodeContextMenu((DriftTreeNode) eventNode);
menu.showContextMenu();
}
}
@@ -171,12 +171,12 @@ public abstract class AbstractDriftChangeSetsTreeView extends LocatableTreeGrid
* @param node the drift node whose menu is to be displayed
* @return the context menu to display
*/
- protected Menu buildContextMenu(final DriftTreeNode node) {
+ protected Menu buildDriftTreeNodeContextMenu(final DriftTreeNode node) {
Menu contextMenu = new Menu();
// title
- String titleName = node.getName();
+ String titleName = node.getTitle();
if (titleName.length() > 50) {
// make sure the title isn't really long so the menu is not abnormally wide
titleName = "..." + titleName.substring(titleName.length() - 50);
@@ -204,6 +204,36 @@ public abstract class AbstractDriftChangeSetsTreeView extends LocatableTreeGrid
}
/**
+ * Builds the right-mouse-click context menu for the given change set node
+ * @param node the change set node whose menu is to be displayed
+ * @return the context menu to display
+ */
+ protected Menu buildChangeSetTreeNodeContextMenu(final ChangeSetTreeNode node) {
+
+ Menu contextMenu = new Menu();
+
+ // title
+ String titleName = node.getTitle();
+ MenuItem titleItem = new MenuItem(titleName);
+ titleItem.setEnabled(false);
+ contextMenu.setItems(titleItem);
+
+ // separator
+ contextMenu.addItem(new MenuItemSeparator());
+
+ // item that links to the history details
+ MenuItem deleteItem = new MenuItem(MSG.common_button_delete());
+ deleteItem.addClickHandler(new ClickHandler() {
+ public void onClick(MenuItemClickEvent event) {
+ // TODO: delete the change set
+ }
+ });
+ contextMenu.addItem(deleteItem);
+
+ return contextMenu;
+ }
+
+ /**
* We override this because we know all of our nodes will have titles. Without this,
* I could not get the title of change set nodes to show - it always fell back to using
* the name. This way is at least faster, since we don't do any conditional checking,
commit 19cf0266ba2d7b78c07c584512c1b0bb7813f3a7
Author: John Sanda <jsanda(a)redhat.com>
Date: Wed Jul 27 14:50:44 2011 -0400
Making the active drift server plugin configurable via system settings
When a drift serer plugin is loaded or unloaded, it is added to or
removed from the systems settings. When the DriftServerBean (SLSB
layers) asks for the drift plugin, the DriftServerPlugin queries the
system settings to find the active drift server plugin. The drift-rhq
plugin is active by default.
diff --git a/modules/core/dbutils/pom.xml b/modules/core/dbutils/pom.xml
index 39f0798..e2a599d 100644
--- a/modules/core/dbutils/pom.xml
+++ b/modules/core/dbutils/pom.xml
@@ -22,7 +22,7 @@
<properties>
<scm.module.path>modules/core/dbutils/</scm.module.path>
- <db.schema.version>2.111</db.schema.version>
+ <db.schema.version>2.112</db.schema.version>
</properties>
<dependencies>
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/sysconfig-data.xml b/modules/core/dbutils/src/main/scripts/dbsetup/sysconfig-data.xml
index 121e971..6d0e80a 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup/sysconfig-data.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/sysconfig-data.xml
@@ -125,6 +125,12 @@
<data ID="56" PROPERTY_KEY="RESOURCE_GENERIC_PROPERTIES_UPGRADE" PROPERTY_VALUE="false"
DEFAULT_PROPERTY_VALUE="false" FREAD_ONLY="FALSE"/>
+ <!-- default drift server plugin settings -->
+ <data ID="57" PROPERTY_KEY="ACTIVE_DRIFT_PLUGIN" PROPERTY_VALUE="[drift-rhq$$Drift:RHQ]"
+ DEFAULT_PROPERTY_VALUE="[drift-rhq$$Drift:RHQ]" FREAD_ONLY="FALSE"/>
+ <data ID="58" PROPERTY_KEY="DRIFT_PLUGINS" PROPERTY_VALUE="" DEFAULT_PROPERTY_VALUE="[drift-rhq$$Drift:RHQ]"
+ FREAD_ONLY="FALSE"/>
+
</table>
</dbsetup>
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
index 7e38d96..2b1097d 100644
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@ -3586,6 +3586,22 @@
</schema-directSQL>
</schemaSpec>
+ <schemaSpec version="2.112">
+ <schema-directSQL>
+ <statement desc="Adding drift server plugin active plugin system configuration property">
+ INSERT INTO rhq_system_config (id, property_key, property_value, default_property_value)
+ VALUES (57, 'ACTIVE_DRIFT_PLUGIN', '[drift-rhq$$Drift:RHQ]', '[drift-rhq$$Drift:RHQ]')
+ </statement>
+ </schema-directSQL>
+
+ <schema-directSQL>
+ <statement desc="Adding drift server plugin plugins system configuration property">
+ INSERT INTO rhq_system_config (id, property_key, property_value, default_property_value)
+ VALUES (58, 'DRIFT_PLUGINS', '', '[drift-rhq$$Drift:RHQ]')
+ </statement>
+ </schema-directSQL>
+ </schemaSpec>
+
</dbupgrade>
</target>
</project>
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/SystemSettingsView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/SystemSettingsView.java
index 5e83850..ac861b0 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/SystemSettingsView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/SystemSettingsView.java
@@ -19,8 +19,10 @@
package org.rhq.enterprise.gui.coregui.client.admin;
+import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import com.google.gwt.user.client.rpc.AsyncCallback;
@@ -38,6 +40,7 @@ import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.domain.configuration.definition.PropertyDefinition;
+import org.rhq.core.domain.configuration.definition.PropertyDefinitionEnumeration;
import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
import org.rhq.core.domain.configuration.definition.PropertyGroupDefinition;
import org.rhq.core.domain.configuration.definition.PropertySimpleType;
@@ -99,6 +102,9 @@ public class SystemSettingsView extends LocatableVLayout implements PropertyValu
String LDAPBaseDN = "CAM_LDAP_BASE_DN";
String LDAPBindDN = "CAM_LDAP_BIND_DN";
String LDAPBindPW = "CAM_LDAP_BIND_PW";
+
+ String ACTIVE_DRIFT_PLUGIN = "ACTIVE_DRIFT_PLUGIN";
+ String DRIFT_PLUGINS = "DRIFT_PLUGINS";
}
public SystemSettingsView(String locatorId) {
@@ -128,6 +134,7 @@ public class SystemSettingsView extends LocatableVLayout implements PropertyValu
canvas.addMember(getServerDetails());
Configuration config = new Configuration();
+ String[] driftPlugins = null;
for (Map.Entry<String, String> entry : result.entrySet()) {
String name = entry.getKey();
String value = (entry.getValue() == null) ? "" : entry.getValue();
@@ -166,6 +173,9 @@ public class SystemSettingsView extends LocatableVLayout implements PropertyValu
if (value.trim().length() == 0) {
value = "true";
}
+ } else if (Constant.DRIFT_PLUGINS.equals(name)) {
+ driftPlugins = value.split(",");
+ continue;
}
PropertySimple prop = new PropertySimple(name, value);
@@ -173,8 +183,8 @@ public class SystemSettingsView extends LocatableVLayout implements PropertyValu
}
// build our config definition and populate our config editor
- editor = new ConfigurationEditor(extendLocatorId("configEditor"), getSystemSettingsDefinition(config),
- config);
+ editor = new ConfigurationEditor(extendLocatorId("configEditor"), getSystemSettingsDefinition(config,
+ driftPlugins), config);
editor.addPropertyValueChangeListener(SystemSettingsView.this);
canvas.addMember(editor);
@@ -305,7 +315,7 @@ public class SystemSettingsView extends LocatableVLayout implements PropertyValu
*
* @return system settings config def
*/
- private ConfigurationDefinition getSystemSettingsDefinition(Configuration config) {
+ private ConfigurationDefinition getSystemSettingsDefinition(Configuration config, String[] driftPlugins) {
ConfigurationDefinition def = new ConfigurationDefinition("sysset", MSG.view_adminConfig_systemSettings());
///////////////////////////////////
@@ -519,6 +529,31 @@ public class SystemSettingsView extends LocatableVLayout implements PropertyValu
ldapBindPW.setDefaultValue("");
def.put(ldapBindPW);
+ ///////////////////////////////////////////
+ // Drift Server Configuration Properties //
+ ///////////////////////////////////////////
+ PropertyGroupDefinition driftGroup = new PropertyGroupDefinition("drift server");
+ driftGroup.setDisplayName("Drift Server Configuration Settings");
+ driftGroup.setOrder(4);
+ driftGroup.setDefaultHidden(false);
+
+ PropertyDefinitionSimple activeDriftServer = new PropertyDefinitionSimple("ACTIVE_DRIFT_PLUGIN",
+ "The drift server plugin that manages the persistence of drift-related entities and content", true,
+ PropertySimpleType.STRING);
+ activeDriftServer.setDisplayName("Active Drift Server Plugin");
+ activeDriftServer.setPropertyGroupDefinition(driftGroup);
+
+ List<PropertyDefinitionEnumeration> options = new ArrayList<PropertyDefinitionEnumeration>();
+ for (String plugin : driftPlugins) {
+ // plugin is of the form, [plugin_name$$plugin_display_name]]
+ String pluginName = plugin.substring(1, plugin.indexOf("$$"));
+ String pluginDisplayName = plugin.substring(pluginName.length() + 3, plugin.indexOf("]"));
+ options.add(new PropertyDefinitionEnumeration(pluginDisplayName, plugin));
+ }
+ activeDriftServer.setEnumeratedValues(options, false);
+
+ def.put(activeDriftServer);
+
//
// if the config is missing any properties for which we have defaults, set them to their defaults
//
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/RHQConstants.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/RHQConstants.java
index e992271..63037c1 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/RHQConstants.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/RHQConstants.java
@@ -49,6 +49,10 @@ public class RHQConstants {
public static final String LDAPBindDN = "CAM_LDAP_BIND_DN";
public static final String LDAPBindPW = "CAM_LDAP_BIND_PW";
+ // DRIFT Server properties
+ public static final String ACTIVE_DRIFT_PLUGIN = "ACTIVE_DRIFT_PLUGIN";
+ public static final String DRIFT_PLUGINS = "DRIFT_PLUGINS";
+
// Base URL for the application - (i think this is only used for alert emails)
public static final String BaseURL = "CAM_BASE_URL";
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/drift/DriftServerPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/drift/DriftServerPluginManager.java
index 8e00b0c..9e405ec 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/drift/DriftServerPluginManager.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/drift/DriftServerPluginManager.java
@@ -18,11 +18,23 @@
*/
package org.rhq.enterprise.server.plugin.pc.drift;
+import java.util.List;
+import java.util.Properties;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.rhq.enterprise.server.auth.SubjectManagerLocal;
import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment;
import org.rhq.enterprise.server.plugin.pc.ServerPluginManager;
+import org.rhq.enterprise.server.system.SystemManagerLocal;
+import org.rhq.enterprise.server.util.LookupUtil;
+import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType;
+
+import static org.rhq.core.domain.util.StringUtils.getListAsString;
+import static org.rhq.core.domain.util.StringUtils.getStringAsList;
+import static org.rhq.enterprise.server.RHQConstants.ACTIVE_DRIFT_PLUGIN;
+import static org.rhq.enterprise.server.RHQConstants.DRIFT_PLUGINS;
/**
* This loads in all drift server plugins that can be found. You can obtain a loaded plugin's
@@ -32,6 +44,7 @@ import org.rhq.enterprise.server.plugin.pc.ServerPluginManager;
* @author John Sanda
*/
public class DriftServerPluginManager extends ServerPluginManager {
+
private final Log log = LogFactory.getLog(this.getClass());
public DriftServerPluginManager(DriftServerPluginContainer pc) {
@@ -39,7 +52,76 @@ public class DriftServerPluginManager extends ServerPluginManager {
}
public DriftServerPluginFacet getDriftServerPluginComponent() {
- // TODO The name of the drift server plugin probably will need to be obtained from the system config
- return (DriftServerPluginFacet) getServerPluginComponent("drift-rhq");
+ Properties sysConfig = getSysConfig();
+ String value = sysConfig.getProperty(ACTIVE_DRIFT_PLUGIN);
+
+ if (value == null) {
+ throw new RuntimeException(ACTIVE_DRIFT_PLUGIN + " system configuration property is not set.");
+ }
+
+ return (DriftServerPluginFacet) getServerPluginComponent(value.substring(1, value.indexOf("$$")));
+ }
+
+ @Override
+ protected void loadPlugin(ServerPluginEnvironment env, boolean enabled) throws Exception {
+ super.loadPlugin(env, enabled);
+
+ String pluginName = env.getPluginKey().getPluginName();
+ List<String> plugins = getDriftPlugins();
+
+ int index = findPluginIndex(plugins, pluginName);
+ if (index == -1) {
+ plugins.add("[" + pluginName + "$$" + env.getPluginDescriptor().getDisplayName() + "]");
+ saveDriftPlugins(plugins);
+ }
+
+ }
+
+ @Override
+ protected void unloadPlugin(String pluginName) throws Exception {
+ super.unloadPlugin(pluginName);
+
+ List<String> plugins = getDriftPlugins();
+ int index = findPluginIndex(plugins, pluginName);
+
+ if (index != -1) {
+ plugins.remove(index);
+ saveDriftPlugins(plugins);
+ }
+ }
+
+ private List<String> getDriftPlugins() {
+ Properties sysConfig = getSysConfig();
+ return getStringAsList(sysConfig.getProperty(DRIFT_PLUGINS, ""), ",", true);
}
+
+ private void saveDriftPlugins(List<String> plugins) throws Exception {
+ SubjectManagerLocal subjectMgr = LookupUtil.getSubjectManager();
+ SystemManagerLocal systemMgr = LookupUtil.getSystemManager();
+
+ Properties sysConfig = systemMgr.getSystemConfiguration(subjectMgr.getOverlord());
+ sysConfig.put(DRIFT_PLUGINS, getListAsString(plugins, ","));
+ systemMgr.setSystemConfiguration(subjectMgr.getOverlord(), sysConfig, false);
+ }
+
+ private Properties getSysConfig() {
+ SubjectManagerLocal subjectMgr = LookupUtil.getSubjectManager();
+ SystemManagerLocal systemMgr = LookupUtil.getSystemManager();
+
+ return systemMgr.getSystemConfiguration(subjectMgr.getOverlord());
+ }
+
+ private int findPluginIndex(List<String> plugins, String name) {
+ int i = 0;
+ for (String value : plugins) {
+ // value is of the form, [plugin_name$$plugin_display_name]
+ if (name.equals(value.substring(1, value.indexOf("$$")))) {
+ return i;
+ }
+ ++i;
+ }
+ return -1;
+ }
+
+
}
\ No newline at end of file
diff --git a/modules/test-utils/src/main/java/org/rhq/test/JPAUtils.java b/modules/test-utils/src/main/java/org/rhq/test/JPAUtils.java
index 349b84c..b385473 100644
--- a/modules/test-utils/src/main/java/org/rhq/test/JPAUtils.java
+++ b/modules/test-utils/src/main/java/org/rhq/test/JPAUtils.java
@@ -143,7 +143,7 @@ public class JPAUtils {
em.createNativeQuery("delete from rhq_measurement_sched");
em.createNativeQuery("delete from rhq_measurement_def");
em.createNativeQuery("delete from rhq_plugin");
- em.createNativeQuery("delete from rhq_system_config where id not in (1, 2, 3, 4, 9, 10, 32, 34, 35, 36, 51, 52, 53, 54, 55, 56)");
+ em.createNativeQuery("delete from rhq_system_config where id not in (1, 2, 3, 4, 9, 10, 32, 34, 35, 36, 51, 52, 53, 54, 55, 56, 57, 58)");
em.createNativeQuery("delete from rhq_alert_notification");
em.createNativeQuery("delete from rhq_alert_condition_log");
em.createNativeQuery("delete from rhq_alert");
commit d064e0516c87a1aa44d1f9f2231907279e9582dd
Author: John Sanda <jsanda(a)redhat.com>
Date: Tue Jul 26 21:22:19 2011 -0400
Persist drift detection schedule across agent restarts
This commit add functionality for persisting drift detection schedules
across restarts. When the agent is shutting down and the inventory is
persisted to disk, the schedules are now written out to disk along with
the rest of the inventory.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetectionSchedule.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetectionSchedule.java
index fe42744..ab5bac3 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetectionSchedule.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetectionSchedule.java
@@ -1,8 +1,12 @@
package org.rhq.core.pc.drift;
+import java.io.Serializable;
+
import org.rhq.core.domain.drift.DriftConfiguration;
-public class DriftDetectionSchedule implements Comparable<DriftDetectionSchedule> {
+public class DriftDetectionSchedule implements Comparable<DriftDetectionSchedule>, Serializable {
+
+ private static final long serialVersionUID = 1L;
private int resourceId;
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java
index f499697..879ceca 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java
@@ -67,11 +67,36 @@ public class DriftManager extends AgentService implements DriftAgentService, Dri
driftDetector.setChangeSetManager(changeSetMgr);
driftDetector.setDriftClient(this);
+ InventoryManager inventoryMgr = PluginContainer.getInstance().getInventoryManager();
+ initSchedules(inventoryMgr.getPlatform(), inventoryMgr);
+
driftThreadPool = new ScheduledThreadPoolExecutor(5);
// TODO Make the drift detection rate configurable
driftThreadPool.scheduleAtFixedRate(driftDetector, 30, 60, TimeUnit.SECONDS);
}
+ private void initSchedules(Resource r, InventoryManager inventoryMgr) {
+ if (r.getId() == 0) {
+ log.debug("Will not reschedule drift detection schedules for " + r + ". It is not sync'ed yet.");
+ return;
+ }
+
+ ResourceContainer container = inventoryMgr.getResourceContainer(r.getId());
+ if (container == null) {
+ log.debug("No resource container found for " + r + ". Unable to reschedule drift detection schedules.");
+ return;
+ }
+
+ log.debug("Rescheduling drift detection schedules for " + r);
+ for (DriftDetectionSchedule schedule : container.getDriftSchedules()) {
+ schedulesQueue.addSchedule(schedule);
+ }
+
+ for (Resource child : r.getChildResources()) {
+ initSchedules(child, inventoryMgr);
+ }
+ }
+
@Override
public void shutdown() {
driftThreadPool.shutdown();
@@ -164,8 +189,8 @@ public class DriftManager extends AgentService implements DriftAgentService, Dri
}
@Override
- public boolean update(int resourceId, DriftConfiguration config) {
- return false;
+ public DriftDetectionSchedule update(int resourceId, DriftConfiguration config) {
+ return schedule;
}
@Override
@@ -208,9 +233,16 @@ public class DriftManager extends AgentService implements DriftAgentService, Dri
@Override
public void updateDriftDetection(int resourceId, DriftConfiguration driftConfiguration) {
- boolean updated = schedulesQueue.update(resourceId, driftConfiguration);
- if (!updated) {
- schedulesQueue.addSchedule(new DriftDetectionSchedule(resourceId, driftConfiguration));
+ DriftDetectionSchedule updatedSchedule = schedulesQueue.update(resourceId, driftConfiguration);
+ if (updatedSchedule == null) {
+ updatedSchedule = new DriftDetectionSchedule(resourceId, driftConfiguration);
+ schedulesQueue.addSchedule(updatedSchedule);
+ }
+
+ InventoryManager inventoryMgr = PluginContainer.getInstance().getInventoryManager();
+ ResourceContainer container = inventoryMgr.getResourceContainer(resourceId);
+ if (container != null) {
+ container.getDriftSchedules().add(updatedSchedule);
}
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ScheduleQueue.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ScheduleQueue.java
index ca7edc5..374e27e 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ScheduleQueue.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ScheduleQueue.java
@@ -38,7 +38,7 @@ public interface ScheduleQueue {
* Adds a schedule to the queue for processing by the drift detector
*
* @param schedule A {@link DriftDetectionSchedule} object
- * @return true if the schedule is added, falsed otherwise
+ * @return true if the schedule is added, false otherwise
*/
boolean addSchedule(DriftDetectionSchedule schedule);
@@ -52,9 +52,9 @@ public interface ScheduleQueue {
*
* @param resourceId The resource id
* @param config A {@link DriftConfiguration} belonging the resource with the specified id
- * @return true if the schedule is updated, false otherwise.
+ * @return A copy of the updated schedule or null if no update was performed
*/
- boolean update(int resourceId, DriftConfiguration config);
+ DriftDetectionSchedule update(int resourceId, DriftConfiguration config);
/**
* Removes the schedule identified by the resource id and the drift configuration. More
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ScheduleQueueImpl.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ScheduleQueueImpl.java
index 499ad91..b4a2f00 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ScheduleQueueImpl.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ScheduleQueueImpl.java
@@ -112,20 +112,26 @@ public class ScheduleQueueImpl implements ScheduleQueue {
}
@Override
- public boolean update(int resourceId, DriftConfiguration config) {
+ public DriftDetectionSchedule update(int resourceId, DriftConfiguration config) {
try {
lock.writeLock().lock();
if (isActiveSchedule(resourceId, config)) {
update(activeSchedule, config);
- } else {
- DriftDetectionSchedule schedule = remove(resourceId, config);
- if (schedule == null) {
- return false;
- }
- update(schedule, config);
- queue.offer(schedule);
+ return activeSchedule.copy();
+ }
+
+ DriftDetectionSchedule schedule = remove(resourceId, config);
+ if (schedule == null) {
+ return null;
}
- return true;
+
+ update(schedule, config);
+
+ if (queue.offer(schedule)) {
+ return schedule.copy();
+ }
+
+ return null;
} finally {
lock.writeLock().unlock();
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/ResourceContainer.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/ResourceContainer.java
index ab8d30e..fcf1aea 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/ResourceContainer.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/ResourceContainer.java
@@ -52,6 +52,7 @@ import org.rhq.core.domain.measurement.Availability;
import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.pc.drift.DriftDetectionSchedule;
import org.rhq.core.pc.util.FacetLockType;
import org.rhq.core.pc.util.LoggingThreadFactory;
import org.rhq.core.pluginapi.inventory.ResourceComponent;
@@ -88,6 +89,7 @@ public class ResourceContainer implements Serializable {
private SynchronizationState synchronizationState = SynchronizationState.NEW;
private Set<MeasurementScheduleRequest> measurementSchedule = new HashSet<MeasurementScheduleRequest>();
private Set<ResourcePackageDetails> installedPackages = new HashSet<ResourcePackageDetails>();
+ private Set<DriftDetectionSchedule> driftSchedules = new HashSet<DriftDetectionSchedule>();
// transient fields
private transient ResourceComponent resourceComponent;
@@ -242,6 +244,16 @@ public class ResourceContainer implements Serializable {
}
}
+ public Set<DriftDetectionSchedule> getDriftSchedules() {
+ synchronized (this) {
+ return driftSchedules;
+ }
+ }
+
+ public void setDriftSchedules(Set<DriftDetectionSchedule> schedules) {
+ driftSchedules = schedules;
+ }
+
public ResourceComponentState getResourceComponentState() {
synchronized (this) {
return this.resourceComponentState;
commit d6e42c6a12a2a630a37fd3151fadb64848c24a30
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Jul 26 18:31:39 2011 -0400
tweek folder icons for drift
diff --git a/modules/enterprise/gui/coregui/src/main/webapp/images/subsystems/drift/ChangeSet_16.png b/modules/enterprise/gui/coregui/src/main/webapp/images/subsystems/drift/ChangeSet_16.png
index fdda214..e728bc8 100644
Binary files a/modules/enterprise/gui/coregui/src/main/webapp/images/subsystems/drift/ChangeSet_16.png and b/modules/enterprise/gui/coregui/src/main/webapp/images/subsystems/drift/ChangeSet_16.png differ
diff --git a/modules/enterprise/gui/coregui/src/main/webapp/images/subsystems/drift/ChangeSet_16_open.png b/modules/enterprise/gui/coregui/src/main/webapp/images/subsystems/drift/ChangeSet_16_open.png
index 358cf61..1ca204f 100644
Binary files a/modules/enterprise/gui/coregui/src/main/webapp/images/subsystems/drift/ChangeSet_16_open.png and b/modules/enterprise/gui/coregui/src/main/webapp/images/subsystems/drift/ChangeSet_16_open.png differ
commit 5024b757bdcf0b842d4c49fe58ca45890450e670
Author: John Sanda <jsanda(a)redhat.com>
Date: Tue Jul 26 16:14:26 2011 -0400
Adding support for updating drift configs
When the server sends a request to the agent to update a drift
configuration, that config is attached to a schedule which is in one of
two places. It is either on the schedule queue or it is "active"
schedule currently being processed by the drift detector. The config
update will be applied such that the next time the drift detector
processes the schedule the update will take effect.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetectionSchedule.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetectionSchedule.java
index a767b99..fe42744 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetectionSchedule.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetectionSchedule.java
@@ -32,6 +32,13 @@ public class DriftDetectionSchedule implements Comparable<DriftDetectionSchedule
nextScan = System.currentTimeMillis() + (driftConfig.getInterval() * 1000);
}
+ public DriftDetectionSchedule copy() {
+ DriftDetectionSchedule copy = new DriftDetectionSchedule(resourceId,
+ new DriftConfiguration(driftConfig.getConfiguration().deepCopyWithoutProxies()));
+ copy.nextScan = nextScan;
+ return copy;
+ }
+
@Override
public int compareTo(DriftDetectionSchedule other) {
if (this.nextScan < other.nextScan) {
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
index b92dd7c..153e5a9 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
@@ -47,52 +47,44 @@ public class DriftDetector implements Runnable {
@Override
public void run() {
- DriftDetectionSchedule schedule = scheduleQueue.dequeue();
+ DriftDetectionSchedule schedule = scheduleQueue.getNextSchedule();
if (schedule == null) {
return;
}
- if (schedule.getNextScan() > (System.currentTimeMillis() + 100L)) {
- scheduleQueue.enqueue(schedule);
- // TODO should we grab the schedule from the queue?
- // Maybe we should continue pulling schedules off the queue until
- // we find one that is ready to be processed.
- return;
- }
-
- if (!schedule.getDriftConfiguration().getEnabled()) {
- schedule.updateShedule();
- scheduleQueue.enqueue(schedule);
- // TODO should we grab the schedule from the queue?
- // Maybe we should continue pulling schedules off the queue until
- // we find one that is ready to be processed.
- return;
- }
-
- DriftConfiguration driftConfig = schedule.getDriftConfiguration();
- int resourceId = schedule.getResourceId();
- DriftChangeSetCategory changeSetType = null;
- int changes = 0;
-
try {
- if (changeSetMgr.changeSetExists(schedule.getResourceId(), new Headers(driftConfig.getName(),
- basedir(resourceId, driftConfig), COVERAGE))) {
- changeSetType = DRIFT;
- changes = generateDriftChangeSet(schedule);
- } else {
- changeSetType = COVERAGE;
- generateCoverageChangeSet(schedule);
+ if (schedule.getNextScan() > (System.currentTimeMillis() + 100L)) {
+ return;
}
- } catch (IOException e) {
- // TODO Call ChangeSetManager here to rollback any thing that was written to disk.
- log.error("An error occurred while scanning for drift", e);
- }
- schedule.updateShedule();
- scheduleQueue.enqueue(schedule);
+ if (!schedule.getDriftConfiguration().getEnabled()) {
+ return;
+ }
- if (changeSetType == COVERAGE || changes > 0) {
- driftClient.sendChangeSetToServer(schedule.getResourceId(), driftConfig, changeSetType);
+ DriftConfiguration driftConfig = schedule.getDriftConfiguration();
+ int resourceId = schedule.getResourceId();
+ DriftChangeSetCategory changeSetType = null;
+ int changes = 0;
+
+ try {
+ if (changeSetMgr.changeSetExists(schedule.getResourceId(), new Headers(driftConfig.getName(),
+ basedir(resourceId, driftConfig), COVERAGE))) {
+ changeSetType = DRIFT;
+ changes = generateDriftChangeSet(schedule);
+ } else {
+ changeSetType = COVERAGE;
+ generateCoverageChangeSet(schedule);
+ }
+ } catch (IOException e) {
+ // TODO Call ChangeSetManager here to rollback any thing that was written to disk.
+ log.error("An error occurred while scanning for drift", e);
+ }
+
+ if (changeSetType == COVERAGE || changes > 0) {
+ driftClient.sendChangeSetToServer(schedule.getResourceId(), driftConfig, changeSetType);
+ }
+ } finally {
+ scheduleQueue.deactivateSchedule();
}
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java
index b688154..f499697 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java
@@ -141,14 +141,14 @@ public class DriftManager extends AgentService implements DriftAgentService, Dri
DriftDetectionSchedule schedule;
@Override
- public DriftDetectionSchedule dequeue() {
+ public DriftDetectionSchedule getNextSchedule() {
DriftDetectionSchedule removedSchedule = schedule;
schedule = null;
return removedSchedule;
}
@Override
- public boolean enqueue(DriftDetectionSchedule schedule) {
+ public boolean addSchedule(DriftDetectionSchedule schedule) {
this.schedule = schedule;
return true;
}
@@ -157,8 +157,23 @@ public class DriftManager extends AgentService implements DriftAgentService, Dri
public void clear() {
schedule = null;
}
+
+ @Override
+ public void deactivateSchedule() {
+ schedule = null;
+ }
+
+ @Override
+ public boolean update(int resourceId, DriftConfiguration config) {
+ return false;
+ }
+
+ @Override
+ public DriftDetectionSchedule remove(int resourceId, DriftConfiguration config) {
+ return null;
+ }
};
- queue.enqueue(new DriftDetectionSchedule(resourceId, driftConfiguration));
+ queue.addSchedule(new DriftDetectionSchedule(resourceId, driftConfiguration));
DriftDetector driftDetector = new DriftDetector();
driftDetector.setChangeSetManager(changeSetMgr);
@@ -170,7 +185,7 @@ public class DriftManager extends AgentService implements DriftAgentService, Dri
@Override
public void scheduleDriftDetection(int resourceId, DriftConfiguration driftConfiguration) {
- schedulesQueue.enqueue(new DriftDetectionSchedule(resourceId, driftConfiguration));
+ schedulesQueue.addSchedule(new DriftDetectionSchedule(resourceId, driftConfiguration));
}
@Override
@@ -193,6 +208,10 @@ public class DriftManager extends AgentService implements DriftAgentService, Dri
@Override
public void updateDriftDetection(int resourceId, DriftConfiguration driftConfiguration) {
+ boolean updated = schedulesQueue.update(resourceId, driftConfiguration);
+ if (!updated) {
+ schedulesQueue.addSchedule(new DriftDetectionSchedule(resourceId, driftConfiguration));
+ }
}
/**
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ScheduleQueue.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ScheduleQueue.java
index 09b0aa5..ca7edc5 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ScheduleQueue.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ScheduleQueue.java
@@ -1,11 +1,79 @@
package org.rhq.core.pc.drift;
+import org.rhq.core.domain.drift.DriftConfiguration;
+
+/**
+ * Manages the drift detection schedules that are processed by the drift detector. The
+ * queue has a concept of the currently "active" schedule. This is identified simply as
+ * the schedule returned from {@link #getNextSchedule()} which is the previous head of the
+ * queue. A reference to the active schedule needs to be maintained because at any point in
+ * time the server can send a request to update the drift configuration that is attached to
+ * a schedule. That schedule will either be on the queue waiting to be processed or in the
+ * "active" state meaning it is currently being processed by the drift detector.
+ */
public interface ScheduleQueue {
- DriftDetectionSchedule dequeue();
+ /**
+ * Removes the head of the queue and returns a copy of the schedule that was removed.
+ * That schedule is also marked as the active schedule.
+ *
+ * @return A copy of the schedule that is removed from the head of the queue.
+ *
+ * @see DriftDetectionSchedule
+ *
+ * @throws IllegalStateException if there is already an active schedule. The active
+ * schedule must be deactivated before getting the next schedule.
+ */
+ DriftDetectionSchedule getNextSchedule();
+
+ /**
+ * This method does two things. First it updates the active schedule's nextScan
+ * property. Then it adds the schedule back onto the queue, allowing the next schedule
+ * at the head of the queue to become active. If there is no active schedule this
+ * method simply does nothing and returns.
+ */
+ void deactivateSchedule();
+
+ /**
+ * Adds a schedule to the queue for processing by the drift detector
+ *
+ * @param schedule A {@link DriftDetectionSchedule} object
+ * @return true if the schedule is added, falsed otherwise
+ */
+ boolean addSchedule(DriftDetectionSchedule schedule);
+
+ /**
+ * This method attempts to update the schedule identified by the resource id the and
+ * the drift configuration. More specifically, the schedule is identified by a
+ * combination of resource id and drift configuraiton name. If the schedule to be
+ * updated is the active schedule, it is immediately updated and then placed back on
+ * the queue the next time {@link #deactivateSchedule()} is called. If the schedule
+ * is on the queue, it is removed, updated, and then added back onto the queue.
+ *
+ * @param resourceId The resource id
+ * @param config A {@link DriftConfiguration} belonging the resource with the specified id
+ * @return true if the schedule is updated, false otherwise.
+ */
+ boolean update(int resourceId, DriftConfiguration config);
- boolean enqueue(DriftDetectionSchedule schedule);
+ /**
+ * Removes the schedule identified by the resource id and the drift configuration. More
+ * specifically, the schedule is identified by a combination of resource id drift
+ * configuration name. This method can remove either the active schedule or a schedule
+ * on the queue.
+ *
+ * @param resourceId The resource id
+ *
+ * @param config A {@link DriftConfiguration} belonging the resource with the specified id
+ *
+ * @return The {@link DriftDetectionSchedule} that is removed or null if no matching
+ * schedule is found.
+ */
+ DriftDetectionSchedule remove(int resourceId, DriftConfiguration config);
+ /**
+ * Removes all elements from the queue and deactivates the active schedule.
+ */
void clear();
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ScheduleQueueImpl.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ScheduleQueueImpl.java
index 7934c2d..499ad91 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ScheduleQueueImpl.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ScheduleQueueImpl.java
@@ -3,24 +3,54 @@ package org.rhq.core.pc.drift;
import java.util.PriorityQueue;
import java.util.concurrent.locks.ReentrantReadWriteLock;
+import org.rhq.core.domain.drift.DriftConfiguration;
+
public class ScheduleQueueImpl implements ScheduleQueue {
private PriorityQueue<DriftDetectionSchedule> queue = new PriorityQueue<DriftDetectionSchedule>();
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+ private DriftDetectionSchedule activeSchedule;
+
@Override
- public DriftDetectionSchedule dequeue() {
+ public DriftDetectionSchedule getNextSchedule() {
try {
lock.writeLock().lock();
- return queue.poll();
+ if (activeSchedule != null) {
+ throw new IllegalStateException("There is already an active schedule that must be deactivated " +
+ "before getting the next schedule.");
+ }
+ activeSchedule = queue.poll();
+ return activeSchedule == null ? null : activeSchedule.copy();
} finally {
lock.writeLock().unlock();
}
}
+ private boolean isActiveSchedule(int resourceId, DriftConfiguration config) {
+ return activeSchedule != null && activeSchedule.getResourceId() == resourceId &&
+ activeSchedule.getDriftConfiguration().getName().equals(config.getName());
+
+ }
+
@Override
- public boolean enqueue(DriftDetectionSchedule schedule) {
+ public void deactivateSchedule() {
+ try {
+ lock.writeLock().lock();
+ if (activeSchedule == null) {
+ return;
+ }
+ activeSchedule.updateShedule();
+ queue.offer(activeSchedule);
+ activeSchedule = null;
+ } finally {
+ lock.writeLock().unlock();
+ }
+ }
+
+ @Override
+ public boolean addSchedule(DriftDetectionSchedule schedule) {
boolean inserted = false;
try {
lock.writeLock().lock();
@@ -32,9 +62,85 @@ public class ScheduleQueueImpl implements ScheduleQueue {
}
@Override
+ public DriftDetectionSchedule remove(int resourceId, DriftConfiguration config) {
+ DriftDetectionSchedule scheduleToRemove = null;
+ try {
+ lock.readLock().lock();
+ if (isActiveSchedule(resourceId, config)) {
+ // The schedule to be removed is the currently active schedule so "upgrade"
+ // to the write lock and return the schedule while removing it from the queue
+ // at the same time.
+ try {
+ lock.writeLock().lock();
+ DriftDetectionSchedule removedSchedule = activeSchedule;
+ activeSchedule = null;
+ return removedSchedule;
+ } finally {
+ lock.writeLock().unlock();
+ }
+ }
+
+ for (DriftDetectionSchedule s : queue) {
+ if (s.getResourceId() == resourceId &&
+ s.getDriftConfiguration().getName().equals(config.getName())) {
+ scheduleToRemove = s;
+ break;
+ }
+ }
+
+ // The schedule was not found in the queue so we can simply return null without
+ // any additional processing.
+ if (scheduleToRemove == null) {
+ return null;
+ }
+
+ boolean removed = false;
+ // At this point, we found the target schedule in the queue. We "upgrade" to
+ // the write lock and remove it from the queue. If the schedule was successfully
+ // removed we return it; otherwise, return null.
+ try {
+ lock.writeLock().lock();
+ removed = queue.remove(scheduleToRemove);
+ } finally {
+ lock.writeLock().unlock();
+ }
+
+ return removed ? scheduleToRemove : null;
+ } finally {
+ lock.readLock().unlock();
+ }
+ }
+
+ @Override
+ public boolean update(int resourceId, DriftConfiguration config) {
+ try {
+ lock.writeLock().lock();
+ if (isActiveSchedule(resourceId, config)) {
+ update(activeSchedule, config);
+ } else {
+ DriftDetectionSchedule schedule = remove(resourceId, config);
+ if (schedule == null) {
+ return false;
+ }
+ update(schedule, config);
+ queue.offer(schedule);
+ }
+ return true;
+ } finally {
+ lock.writeLock().unlock();
+ }
+ }
+
+ private void update(DriftDetectionSchedule schedule, DriftConfiguration config) {
+ schedule.getDriftConfiguration().setEnabled(config.getEnabled());
+ schedule.getDriftConfiguration().setInterval(config.getInterval());
+ }
+
+ @Override
public void clear() {
try {
lock.writeLock().lock();
+ activeSchedule = null;
queue.clear();
} finally {
lock.writeLock().unlock();
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftDetectorTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftDetectorTest.java
index 9b62422..49dab54 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftDetectorTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftDetectorTest.java
@@ -58,7 +58,7 @@ public class DriftDetectorTest extends DriftTest {
DriftConfiguration driftConfig = driftConfiguration("coverage-test", resourceDir.getAbsolutePath());
- scheduleQueue.enqueue(new DriftDetectionSchedule(resourceId(), driftConfig));
+ scheduleQueue.addSchedule(new DriftDetectionSchedule(resourceId(), driftConfig));
detector.run();
File changeSet = changeSet(driftConfig.getName(), COVERAGE);
@@ -77,12 +77,12 @@ public class DriftDetectorTest extends DriftTest {
DriftConfiguration driftConfig = driftConfiguration("basedir-entry-test", resourceDir.getAbsolutePath());
- scheduleQueue.enqueue(new DriftDetectionSchedule(resourceId(), driftConfig));
+ scheduleQueue.addSchedule(new DriftDetectionSchedule(resourceId(), driftConfig));
detector.run();
DriftDetectionSchedule schedule = new DriftDetectionSchedule(resourceId(), driftConfig);
- scheduleQueue.enqueue(schedule);
+ scheduleQueue.addSchedule(schedule);
detector.run();
assertChangeSetContainsDirEntry(changeSet(driftConfig.getName(), COVERAGE),
@@ -102,7 +102,7 @@ public class DriftDetectorTest extends DriftTest {
DriftConfiguration config = driftConfiguration("multiple-files-test", resourceDir.getAbsolutePath());
- scheduleQueue.enqueue(new DriftDetectionSchedule(resourceId(), config));
+ scheduleQueue.addSchedule(new DriftDetectionSchedule(resourceId(), config));
detector.run();
File changeSet = changeSet(config.getName(), COVERAGE);
@@ -127,7 +127,7 @@ public class DriftDetectorTest extends DriftTest {
DriftConfiguration config = driftConfiguration("sibling-dirs-test", resourceDir.getAbsolutePath());
- scheduleQueue.enqueue(new DriftDetectionSchedule(resourceId(), config));
+ scheduleQueue.addSchedule(new DriftDetectionSchedule(resourceId(), config));
detector.run();
File changeSet = changeSet(config.getName(), COVERAGE);
@@ -153,7 +153,7 @@ public class DriftDetectorTest extends DriftTest {
DriftConfiguration config = driftConfiguration("nested-dirs-test", resourceDir.getAbsolutePath());
- scheduleQueue.enqueue(new DriftDetectionSchedule(resourceId(), config));
+ scheduleQueue.addSchedule(new DriftDetectionSchedule(resourceId(), config));
detector.run();
File changeSet = changeSet(config.getName(), COVERAGE);
@@ -188,7 +188,7 @@ public class DriftDetectorTest extends DriftTest {
File server1Conf = new File(confDir, "server-1.conf");
touch(server1Conf);
- scheduleQueue.enqueue(new DriftDetectionSchedule(resourceId(), config));
+ scheduleQueue.addSchedule(new DriftDetectionSchedule(resourceId(), config));
detector.run();
}
@@ -217,7 +217,7 @@ public class DriftDetectorTest extends DriftTest {
File server2Conf = new File(confDir, "server-2.conf");
touch(server2Conf);
- scheduleQueue.enqueue(new DriftDetectionSchedule(resourceId(), config));
+ scheduleQueue.addSchedule(new DriftDetectionSchedule(resourceId(), config));
detector.run();
File driftChangeSet = changeSet(config.getName(), DRIFT);
@@ -266,7 +266,7 @@ public class DriftDetectorTest extends DriftTest {
// create some drift
server2Conf.delete();
- scheduleQueue.enqueue(new DriftDetectionSchedule(resourceId(), config));
+ scheduleQueue.addSchedule(new DriftDetectionSchedule(resourceId(), config));
detector.run();
File driftChangeSet = changeSet(config.getName(), DRIFT);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftServerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftServerBean.java
index 276c8b9..9de0966 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftServerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftServerBean.java
@@ -145,7 +145,7 @@ public class DriftServerBean implements DriftServerLocal {
AgentClient agentClient = agentMgr.getAgentClient(subjectMgr.getOverlord(), resourceId);
DriftAgentService service = agentClient.getDriftAgentService();
try {
- service.scheduleDriftDetection(resourceId, driftConfig);
+ service.updateDriftDetection(resourceId, driftConfig);
} catch (Exception e) {
log.warn(" Unable to inform agent of unscheduled drift detection [" + driftConfig + "]", e);
}
commit f0ae8b1ff4a879e22116df404f51a526d0ca7583
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Jul 26 16:05:42 2011 -0400
add sort direction
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/AbstractDriftChangeSetsTreeView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/AbstractDriftChangeSetsTreeView.java
index 2d7205d..6085af1 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/AbstractDriftChangeSetsTreeView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/AbstractDriftChangeSetsTreeView.java
@@ -26,6 +26,7 @@ import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.RunAsyncCallback;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.types.SelectionStyle;
+import com.smartgwt.client.types.SortDirection;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.events.DataArrivedEvent;
import com.smartgwt.client.widgets.grid.events.DataArrivedHandler;
@@ -70,6 +71,7 @@ public abstract class AbstractDriftChangeSetsTreeView extends LocatableTreeGrid
setShowRollOver(false);
setShowHeader(false);
setSortField(AbstractDriftChangeSetsTreeDataSource.ATTR_NAME);
+ setSortDirection(SortDirection.DESCENDING);
}
@Override
commit 061059a61f26ba172a6c5c0df837e8850ab1bf39
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Jul 26 15:58:32 2011 -0400
sort the tree and provide a refresh button
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/AbstractDriftChangeSetsTreeView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/AbstractDriftChangeSetsTreeView.java
index 7778084..2d7205d 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/AbstractDriftChangeSetsTreeView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/AbstractDriftChangeSetsTreeView.java
@@ -24,7 +24,9 @@ package org.rhq.enterprise.gui.coregui.client.drift;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.RunAsyncCallback;
+import com.smartgwt.client.data.Record;
import com.smartgwt.client.types.SelectionStyle;
+import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.events.DataArrivedEvent;
import com.smartgwt.client.widgets.grid.events.DataArrivedHandler;
import com.smartgwt.client.widgets.menu.Menu;
@@ -67,6 +69,7 @@ public abstract class AbstractDriftChangeSetsTreeView extends LocatableTreeGrid
setSelectionType(SelectionStyle.SINGLE);
setShowRollOver(false);
setShowHeader(false);
+ setSortField(AbstractDriftChangeSetsTreeDataSource.ATTR_NAME);
}
@Override
@@ -198,6 +201,17 @@ public abstract class AbstractDriftChangeSetsTreeView extends LocatableTreeGrid
return contextMenu;
}
+ /**
+ * We override this because we know all of our nodes will have titles. Without this,
+ * I could not get the title of change set nodes to show - it always fell back to using
+ * the name. This way is at least faster, since we don't do any conditional checking,
+ * we always immediately use the getTitle results.
+ */
+ @Override
+ protected String getNodeTitle(Record node, int recordNum, ListGridField field) {
+ return ((TreeNode) node).getTitle();
+ }
+
@SuppressWarnings("unchecked")
static class ChangeSetTreeNode extends TreeNode {
public ChangeSetTreeNode(DriftChangeSet changeset) {
@@ -205,7 +219,8 @@ public abstract class AbstractDriftChangeSetsTreeView extends LocatableTreeGrid
setIcon("subsystems/drift/ChangeSet_16.png");
setShowOpenIcon(true);
setID(changeset.getId());
- setName(buildDriftChangeSetNodeName(changeset));
+ setName(padWithZeroes(changeset.getVersion())); // we sort on this column, hence we make sure the version # is padded
+ setTitle(buildDriftChangeSetNodeName(changeset));
}
private String buildDriftChangeSetNodeName(DriftChangeSet changeset) {
@@ -219,6 +234,14 @@ public abstract class AbstractDriftChangeSetsTreeView extends LocatableTreeGrid
str.append(')');
return str.toString();
}
+
+ private String padWithZeroes(int numberToPad) {
+ String stringToPad = String.valueOf(numberToPad);
+ char[] zeroes = new char[10 - stringToPad.length()];
+ for (int i = 0; i < zeroes.length; i++)
+ zeroes[i] = '0';
+ return new String(zeroes) + stringToPad;
+ }
}
@SuppressWarnings("unchecked")
@@ -229,7 +252,12 @@ public abstract class AbstractDriftChangeSetsTreeView extends LocatableTreeGrid
String parentID = drift.getChangeSet().getId();
setParentID(parentID);
setID(parentID + '_' + drift.getId());
- setName(drift.getPath());
+ setName(drift.getPath()); // we sort on this column
+ }
+
+ @Override
+ public String getTitle() {
+ return super.getName();
}
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftChangeSetsView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftChangeSetsView.java
index 48f5bc8..56b4aa2 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftChangeSetsView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftChangeSetsView.java
@@ -19,7 +19,14 @@
*/
package org.rhq.enterprise.gui.coregui.client.drift;
+import com.smartgwt.client.widgets.IButton;
+import com.smartgwt.client.widgets.events.ClickEvent;
+import com.smartgwt.client.widgets.events.ClickHandler;
+import com.smartgwt.client.widgets.toolbar.ToolStrip;
+
import org.rhq.core.domain.common.EntityContext;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableIButton;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableToolStrip;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
/**
@@ -42,7 +49,23 @@ public class DriftChangeSetsView extends LocatableVLayout {
protected void onDraw() {
super.onDraw();
- addMember(new ResourceDriftChangeSetsTreeView(extendLocatorId("Tree"), this.hasWriteAccess, this.context));
+ final ResourceDriftChangeSetsTreeView tree = new ResourceDriftChangeSetsTreeView(extendLocatorId("Tree"),
+ this.hasWriteAccess, this.context);
+ addMember(tree);
+
+ ToolStrip toolStrip = new LocatableToolStrip(extendLocatorId("toolstrip"));
+ toolStrip.setBackgroundImage(null);
+ toolStrip.setWidth100();
+ toolStrip.setMembersMargin(3);
+ toolStrip.setPadding(3);
+ IButton refreshButton = new LocatableIButton(extendLocatorId("refreshButton"), MSG.common_button_refresh());
+ refreshButton.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ tree.refresh();
+ }
+ });
+ toolStrip.addMember(refreshButton);
+ addMember(toolStrip);
}
public EntityContext getContext() {
commit c09f53eb056db2db67bbac77138806e3240aea3a
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Jul 26 13:34:42 2011 -0400
refactor so we can later put in group classes but still support indiv resources
fix query so we filter on resource ID for resource view
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/AbstractDriftChangeSetsTreeDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/AbstractDriftChangeSetsTreeDataSource.java
new file mode 100644
index 0000000..50b4634
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/AbstractDriftChangeSetsTreeDataSource.java
@@ -0,0 +1,266 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.enterprise.gui.coregui.client.drift;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.data.DSRequest;
+import com.smartgwt.client.data.DSResponse;
+import com.smartgwt.client.data.DataSourceField;
+import com.smartgwt.client.data.Record;
+import com.smartgwt.client.data.fields.DataSourceTextField;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+import com.smartgwt.client.widgets.tree.TreeNode;
+
+import org.rhq.core.domain.criteria.BaseCriteria;
+import org.rhq.core.domain.criteria.DriftChangeSetCriteria;
+import org.rhq.core.domain.criteria.DriftChangeSetJPACriteria;
+import org.rhq.core.domain.criteria.DriftCriteria;
+import org.rhq.core.domain.criteria.DriftJPACriteria;
+import org.rhq.core.domain.drift.Drift;
+import org.rhq.core.domain.drift.DriftChangeSet;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.core.domain.util.PageOrdering;
+import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.gwt.DriftGWTServiceAsync;
+import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
+
+/**
+ * @author John Mazzitelli
+ */
+@SuppressWarnings("unchecked")
+public abstract class AbstractDriftChangeSetsTreeDataSource extends RPCDataSource<Object, BaseCriteria> {
+
+ public static final String ATTR_PARENT_ID = "parentId";
+ public static final String ATTR_ID = "id";
+ public static final String ATTR_NAME = "name";
+
+ private DriftGWTServiceAsync driftService = GWTServiceLookup.getDriftService();
+ private final boolean canManageDrift;
+
+ public AbstractDriftChangeSetsTreeDataSource(boolean canManageDrift) {
+ super();
+ this.canManageDrift = canManageDrift;
+ List<DataSourceField> fields = addDataSourceFields();
+ addFields(fields);
+ }
+
+ @Override
+ protected List<DataSourceField> addDataSourceFields() {
+ List<DataSourceField> fields = super.addDataSourceFields();
+
+ DataSourceField idDataField = new DataSourceTextField(ATTR_ID, MSG.common_title_id());
+ idDataField.setPrimaryKey(true);
+ fields.add(idDataField);
+
+ DataSourceTextField nameDataField = new DataSourceTextField(ATTR_NAME, MSG.common_title_name());
+ nameDataField.setCanEdit(false);
+ fields.add(nameDataField);
+
+ DataSourceTextField parentIdField = new DataSourceTextField(ATTR_PARENT_ID, MSG.common_title_id_parent());
+ parentIdField.setForeignKey(ATTR_ID);
+ fields.add(parentIdField);
+
+ return fields;
+ }
+
+ @Override
+ protected void executeFetch(final DSRequest request, final DSResponse response, final BaseCriteria unused) {
+
+ String parentId = request.getCriteria().getAttribute(ATTR_PARENT_ID);
+
+ if (parentId == null) {
+
+ // There is no parent - we are at the root of the tree.
+ // Get the top nodes (the change sets) but to be as fast as possible don't load their drifts.
+ // We will lazily load drifts when the these changeset tree nodes are opened
+ DriftChangeSetCriteria criteria = getDriftChangeSetCriteria(request);
+
+ driftService.findDriftChangeSetsByCriteria(criteria, new AsyncCallback<PageList<DriftChangeSet>>() {
+ public void onSuccess(PageList<DriftChangeSet> result) {
+ response.setData(buildRecords(result));
+ response.setTotalRows(result.getTotalSize());
+ processResponse(request.getRequestId(), response);
+ }
+
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError(MSG.view_drift_changeset_tree_loadFailure(), caught);
+ response.setStatus(DSResponse.STATUS_FAILURE);
+ processResponse(request.getRequestId(), response);
+ }
+ });
+ } else {
+ String changesetId = parentId;
+ DriftCriteria criteria = new DriftJPACriteria();
+ criteria.addFilterChangeSetId(changesetId);
+
+ driftService.findDriftsByCriteria(criteria, new AsyncCallback<PageList<Drift>>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError(MSG.view_drift_changeset_tree_loadFailure(), caught);
+ response.setStatus(DSResponse.STATUS_FAILURE);
+ processResponse(request.getRequestId(), response);
+ }
+
+ public void onSuccess(PageList<Drift> result) {
+ response.setData(buildRecords(result));
+ response.setTotalRows(result.getTotalSize());
+ processResponse(request.getRequestId(), response);
+ }
+ });
+
+ /*
+ * I am leaving this code commented for future reference. Because today the drit change set tree only
+ * shows simple changeset->drift tree, we don't need this. But if we need to have
+ * multiple types of child nodes, we'll need something like below to query
+ * for the different child node data. For example, we'd need this if we have a tree like:
+ * ChangeSet
+ * |____Resources
+ * | |____ My resource 1
+ * | |____ ...
+ * |_____Drifts
+ * |___ Drift #1
+ * |___ Drift #2
+ * |___ ...
+ * Today we only have Drifts child nodes, so we don't need to have that intermediate
+ * "Drifts" node. If we later want to introduce different node types (like Resources)
+ * we need additional code like below.
+ *
+
+ // we are at an inner node, being asked to get the children of it
+ if (p.endsWith("_drifts")) {
+ // ...load drift items like above in the real code...
+ } else if (p.endsWith("_resources")) {
+ // ...load resource items and put those nodes in the tree...
+ } else {
+ // This is an unknown type of node, so just log an error.
+ // Note that if, in the future, we have other types of nodes (like maybe resource nodes for group change sets?)
+ // we'll add more if-else statements above to process those different nodes.
+ CoreGUI.getErrorHandler().handleError(MSG.view_drift_changeset_tree_loadFailure());
+ }
+
+ *
+ */
+ }
+
+ return;
+ }
+
+ /**
+ * Returns a criteria that will be used to obtain the root nodes for the tree - that is,
+ * the top level change set entries.
+ *
+ * Subclasses can override this method, or modify the returned criteria to further
+ * filter the change sets that are to be returned.
+ *
+ * @param request the request being made of the tree
+ *
+ * @return the criteria to use when querying for change setss
+ */
+ protected DriftChangeSetCriteria getDriftChangeSetCriteria(final DSRequest request) {
+ DriftChangeSetCriteria criteria = new DriftChangeSetJPACriteria();
+ criteria.addSortVersion(PageOrdering.DESC);
+ criteria.setPageControl(getPageControl(request));
+ return criteria;
+ }
+
+ @Override
+ protected BaseCriteria getFetchCriteria(DSRequest request) {
+ // our executeFetch will determine on its own what criteria to use based on what is to be fetched
+ // thus we don't return anything here and let the executeFetch do everything
+ return null;
+ }
+
+ @Override
+ public Object copyValues(Record from) {
+ return null; // don't need this method.
+ }
+
+ @Override
+ public ListGridRecord[] buildRecords(Collection dataObjects) {
+ return buildRecordsForKnownChangeSets(dataObjects, null);
+ }
+
+ public ListGridRecord[] buildRecordsForKnownChangeSets(Collection dataObjects, Integer changeSetId) {
+ if (dataObjects == null) {
+ return null;
+ }
+
+ final List<ListGridRecord> records = new ArrayList<ListGridRecord>();
+
+ for (Object item : dataObjects) {
+
+ // the resultant item is a direct node to build
+ records.add(copyValues(item));
+
+ // now build the children of the node
+ /*
+ * We do not have the need for building any intermeidate nodes today.
+ * There is nothing to do, but if in the future we have differnet node types,
+ * we'll probably want intermediate nodes that we create here. See BundleTreeDataSource
+ * for an example of where this is already done. Commenting this out just as an
+ * example of how this can be done.
+
+ if (item instanceof DriftChangeSet) {
+ DriftChangeSet changeset = (DriftChangeSet) item;
+
+ // each bundle has two direct children - the versions and destinations folders
+ TreeNode versionNode = new TreeNode(MSG.view_drift());
+ versionNode.setID(changeset.getId() + "_drifts");
+ versionNode.setParentID(changeset.getId());
+ versionNode.setName(MSG.view_drift());
+ versionNode.setAttribute("name", MSG.view_drift());
+ records.add(versionNode);
+ } else if (item instanceof Drift) {
+ if (canManageDrift) {
+ records.add(copyValuesForKnownDriftChangeSet(driftItem, changeSetId));
+ }
+ }
+
+ *
+ */
+ }
+
+ return records.toArray(new ListGridRecord[records.size()]);
+ }
+
+ @Override
+ public ListGridRecord copyValues(Object from) {
+ return copyValuesForKnownDriftChangeSet(from, null);
+ }
+
+ public ListGridRecord copyValuesForKnownDriftChangeSet(Object from, Integer changeSetId) {
+ TreeNode node;
+ if (from instanceof DriftChangeSet) {
+ DriftChangeSet changeset = (DriftChangeSet) from;
+ node = new AbstractDriftChangeSetsTreeView.ChangeSetTreeNode(changeset);
+ } else if (from instanceof Drift) {
+ Drift drift = (Drift) from;
+ node = new AbstractDriftChangeSetsTreeView.DriftTreeNode(drift);
+ } else {
+ throw new IllegalArgumentException("please report this bug - bad value: " + from);
+ }
+ // if, in the future, we add more node types, we'll add more else-if statements here
+
+ return node;
+ }
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/AbstractDriftChangeSetsTreeView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/AbstractDriftChangeSetsTreeView.java
index 50d787d..7778084 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/AbstractDriftChangeSetsTreeView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/AbstractDriftChangeSetsTreeView.java
@@ -67,8 +67,6 @@ public abstract class AbstractDriftChangeSetsTreeView extends LocatableTreeGrid
setSelectionType(SelectionStyle.SINGLE);
setShowRollOver(false);
setShowHeader(false);
-
- setDataSource(new DriftChangeSetsTreeDataSource(canManageDrift));
}
@Override
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftChangeSetsTreeDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftChangeSetsTreeDataSource.java
deleted file mode 100644
index c6e9e65..0000000
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftChangeSetsTreeDataSource.java
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2011 Red Hat, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-package org.rhq.enterprise.gui.coregui.client.drift;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.smartgwt.client.data.DSRequest;
-import com.smartgwt.client.data.DSResponse;
-import com.smartgwt.client.data.DataSourceField;
-import com.smartgwt.client.data.Record;
-import com.smartgwt.client.data.fields.DataSourceTextField;
-import com.smartgwt.client.widgets.grid.ListGridRecord;
-import com.smartgwt.client.widgets.tree.TreeNode;
-
-import org.rhq.core.domain.criteria.BaseCriteria;
-import org.rhq.core.domain.criteria.DriftChangeSetCriteria;
-import org.rhq.core.domain.criteria.DriftChangeSetJPACriteria;
-import org.rhq.core.domain.criteria.DriftCriteria;
-import org.rhq.core.domain.criteria.DriftJPACriteria;
-import org.rhq.core.domain.drift.Drift;
-import org.rhq.core.domain.drift.DriftChangeSet;
-import org.rhq.core.domain.util.PageList;
-import org.rhq.core.domain.util.PageOrdering;
-import org.rhq.enterprise.gui.coregui.client.CoreGUI;
-import org.rhq.enterprise.gui.coregui.client.gwt.DriftGWTServiceAsync;
-import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
-import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
-
-/**
- * @author John Mazzitelli
- */
-@SuppressWarnings("unchecked")
-public class DriftChangeSetsTreeDataSource extends RPCDataSource<Object, BaseCriteria> {
-
- private static final String ATTR_PARENT_ID = "parentId";
- public static final String ATTR_ID = "id";
- public static final String ATTR_NAME = "name";
-
- private DriftGWTServiceAsync driftService = GWTServiceLookup.getDriftService();
- private final boolean canManageDrift;
-
- public DriftChangeSetsTreeDataSource(boolean canManageDrift) {
- super();
- this.canManageDrift = canManageDrift;
- List<DataSourceField> fields = addDataSourceFields();
- addFields(fields);
- }
-
- @Override
- protected List<DataSourceField> addDataSourceFields() {
- List<DataSourceField> fields = super.addDataSourceFields();
-
- DataSourceField idDataField = new DataSourceTextField(ATTR_ID, MSG.common_title_id());
- idDataField.setPrimaryKey(true);
- fields.add(idDataField);
-
- DataSourceTextField nameDataField = new DataSourceTextField(ATTR_NAME, MSG.common_title_name());
- nameDataField.setCanEdit(false);
- fields.add(nameDataField);
-
- DataSourceTextField parentIdField = new DataSourceTextField(ATTR_PARENT_ID, MSG.common_title_id_parent());
- parentIdField.setForeignKey(ATTR_ID);
- fields.add(parentIdField);
-
- return fields;
- }
-
- @Override
- protected void executeFetch(final DSRequest request, final DSResponse response, final BaseCriteria unused) {
-
- String parentId = request.getCriteria().getAttribute(ATTR_PARENT_ID);
-
- if (parentId == null) {
-
- // There is no parent - we are at the root of the tree.
- // Get the top nodes (the change sets) but to be as fast as possible don't load their drifts.
- // We will lazily load drifts when the these changeset tree nodes are opened
- DriftChangeSetCriteria criteria = new DriftChangeSetJPACriteria();
- criteria.addSortVersion(PageOrdering.DESC);
- criteria.setPageControl(getPageControl(request));
-
- driftService.findDriftChangeSetsByCriteria(criteria, new AsyncCallback<PageList<DriftChangeSet>>() {
- public void onSuccess(PageList<DriftChangeSet> result) {
- response.setData(buildRecords(result));
- response.setTotalRows(result.getTotalSize());
- processResponse(request.getRequestId(), response);
- }
-
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError(MSG.view_drift_changeset_tree_loadFailure(), caught);
- response.setStatus(DSResponse.STATUS_FAILURE);
- processResponse(request.getRequestId(), response);
- }
- });
- } else {
- String changesetId = parentId;
- DriftCriteria criteria = new DriftJPACriteria();
- criteria.addFilterChangeSetId(changesetId);
-
- driftService.findDriftsByCriteria(criteria, new AsyncCallback<PageList<Drift>>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError(MSG.view_drift_changeset_tree_loadFailure(), caught);
- response.setStatus(DSResponse.STATUS_FAILURE);
- processResponse(request.getRequestId(), response);
- }
-
- public void onSuccess(PageList<Drift> result) {
- response.setData(buildRecords(result));
- response.setTotalRows(result.getTotalSize());
- processResponse(request.getRequestId(), response);
- }
- });
-
- /*
- * I am leaving this code commented for future reference. Because today the drit change set tree only
- * shows simple changeset->drift tree, we don't need this. But if we need to have
- * multiple types of child nodes, we'll need something like below to query
- * for the different child node data. For example, we'd need this if we have a tree like:
- * ChangeSet
- * |____Resources
- * | |____ My resource 1
- * | |____ ...
- * |_____Drifts
- * |___ Drift #1
- * |___ Drift #2
- * |___ ...
- * Today we only have Drifts child nodes, so we don't need to have that intermediate
- * "Drifts" node. If we later want to introduce different node types (like Resources)
- * we need additional code like below.
- *
-
- // we are at an inner node, being asked to get the children of it
- if (p.endsWith("_drifts")) {
- // ...load drift items like above in the real code...
- } else if (p.endsWith("_resources")) {
- // ...load resource items and put those nodes in the tree...
- } else {
- // This is an unknown type of node, so just log an error.
- // Note that if, in the future, we have other types of nodes (like maybe resource nodes for group change sets?)
- // we'll add more if-else statements above to process those different nodes.
- CoreGUI.getErrorHandler().handleError(MSG.view_drift_changeset_tree_loadFailure());
- }
-
- *
- */
- }
-
- return;
- }
-
- @Override
- protected BaseCriteria getFetchCriteria(DSRequest request) {
- // our executeFetch will determine on its own what criteria to use based on what is to be fetched
- // thus we don't return anything here and let the executeFetch do everything
- return null;
- }
-
- @Override
- public Object copyValues(Record from) {
- return null; // don't need this method.
- }
-
- @Override
- public ListGridRecord[] buildRecords(Collection dataObjects) {
- return buildRecordsForKnownChangeSets(dataObjects, null);
- }
-
- public ListGridRecord[] buildRecordsForKnownChangeSets(Collection dataObjects, Integer changeSetId) {
- if (dataObjects == null) {
- return null;
- }
-
- final List<ListGridRecord> records = new ArrayList<ListGridRecord>();
-
- for (Object item : dataObjects) {
-
- // the resultant item is a direct node to build
- records.add(copyValues(item));
-
- // now build the children of the node
- /*
- * We do not have the need for building any intermeidate nodes today.
- * There is nothing to do, but if in the future we have differnet node types,
- * we'll probably want intermediate nodes that we create here. See BundleTreeDataSource
- * for an example of where this is already done. Commenting this out just as an
- * example of how this can be done.
-
- if (item instanceof DriftChangeSet) {
- DriftChangeSet changeset = (DriftChangeSet) item;
-
- // each bundle has two direct children - the versions and destinations folders
- TreeNode versionNode = new TreeNode(MSG.view_drift());
- versionNode.setID(changeset.getId() + "_drifts");
- versionNode.setParentID(changeset.getId());
- versionNode.setName(MSG.view_drift());
- versionNode.setAttribute("name", MSG.view_drift());
- records.add(versionNode);
- } else if (item instanceof Drift) {
- if (canManageDrift) {
- records.add(copyValuesForKnownDriftChangeSet(driftItem, changeSetId));
- }
- }
-
- *
- */
- }
-
- return records.toArray(new ListGridRecord[records.size()]);
- }
-
- @Override
- public ListGridRecord copyValues(Object from) {
- return copyValuesForKnownDriftChangeSet(from, null);
- }
-
- public ListGridRecord copyValuesForKnownDriftChangeSet(Object from, Integer changeSetId) {
- TreeNode node;
- if (from instanceof DriftChangeSet) {
- DriftChangeSet changeset = (DriftChangeSet) from;
- node = new AbstractDriftChangeSetsTreeView.ChangeSetTreeNode(changeset);
- } else if (from instanceof Drift) {
- Drift drift = (Drift) from;
- node = new AbstractDriftChangeSetsTreeView.DriftTreeNode(drift);
- } else {
- throw new IllegalArgumentException("please report this bug - bad value: " + from);
- }
- // if, in the future, we add more node types, we'll add more else-if statements here
-
- return node;
- }
-}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/ResourceDriftChangeSetsTreeDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/ResourceDriftChangeSetsTreeDataSource.java
new file mode 100644
index 0000000..f5341e2
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/ResourceDriftChangeSetsTreeDataSource.java
@@ -0,0 +1,51 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.enterprise.gui.coregui.client.drift;
+
+import com.smartgwt.client.data.DSRequest;
+
+import org.rhq.core.domain.common.EntityContext;
+import org.rhq.core.domain.criteria.DriftChangeSetCriteria;
+
+/**
+ * @author John Mazzitelli
+ */
+public class ResourceDriftChangeSetsTreeDataSource extends AbstractDriftChangeSetsTreeDataSource {
+
+ private final EntityContext context;
+
+ public ResourceDriftChangeSetsTreeDataSource(boolean canManageDrift, EntityContext context) {
+ super(canManageDrift);
+
+ if (context.type != EntityContext.Type.Resource) {
+ throw new IllegalArgumentException("wrong context: " + context);
+ }
+
+ this.context = context;
+ }
+
+ @Override
+ protected DriftChangeSetCriteria getDriftChangeSetCriteria(final DSRequest request) {
+ DriftChangeSetCriteria criteria = super.getDriftChangeSetCriteria(request);
+ criteria.addFilterResourceId(this.context.resourceId);
+ return criteria;
+ }
+
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/ResourceDriftChangeSetsTreeView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/ResourceDriftChangeSetsTreeView.java
index 3e368d5..3ee0b5f 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/ResourceDriftChangeSetsTreeView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/ResourceDriftChangeSetsTreeView.java
@@ -40,11 +40,13 @@ public class ResourceDriftChangeSetsTreeView extends AbstractDriftChangeSetsTree
}
this.context = context;
+
+ setDataSource(new ResourceDriftChangeSetsTreeDataSource(canManageDrift, context));
}
protected String getNodeTargetLink(TreeNode node) {
if (node instanceof DriftTreeNode) {
- String driftIdStr = node.getAttribute(DriftChangeSetsTreeDataSource.ATTR_ID).split("_")[1];
+ String driftIdStr = node.getAttribute(AbstractDriftChangeSetsTreeDataSource.ATTR_ID).split("_")[1];
String path = LinkManager.getDriftHistoryLink(this.context.resourceId, Integer.valueOf(driftIdStr));
return path;
}
commit 3796f35c8250ffc3b798ff7cb3dcd5b2f4204596
Author: John Sanda <jsanda(a)redhat.com>
Date: Tue Jul 26 09:22:15 2011 -0400
Adding logic to check the enabled flag during drift detection
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
index f2883b9..b92dd7c 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
@@ -54,6 +54,18 @@ public class DriftDetector implements Runnable {
if (schedule.getNextScan() > (System.currentTimeMillis() + 100L)) {
scheduleQueue.enqueue(schedule);
+ // TODO should we grab the schedule from the queue?
+ // Maybe we should continue pulling schedules off the queue until
+ // we find one that is ready to be processed.
+ return;
+ }
+
+ if (!schedule.getDriftConfiguration().getEnabled()) {
+ schedule.updateShedule();
+ scheduleQueue.enqueue(schedule);
+ // TODO should we grab the schedule from the queue?
+ // Maybe we should continue pulling schedules off the queue until
+ // we find one that is ready to be processed.
return;
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ScheduleQueueImpl.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ScheduleQueueImpl.java
index fe15677..7934c2d 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ScheduleQueueImpl.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/ScheduleQueueImpl.java
@@ -1,7 +1,6 @@
package org.rhq.core.pc.drift;
import java.util.PriorityQueue;
-import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ScheduleQueueImpl implements ScheduleQueue {
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftDetectorTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftDetectorTest.java
index 4f27974..9b62422 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftDetectorTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftDetectorTest.java
@@ -16,6 +16,7 @@ import org.rhq.common.drift.ChangeSetReaderImpl;
import org.rhq.common.drift.DirectoryEntry;
import org.rhq.common.drift.FileEntry;
import org.rhq.common.drift.Headers;
+import org.rhq.core.domain.drift.DriftChangeSetCategory;
import org.rhq.core.domain.drift.DriftConfiguration;
import static org.apache.commons.io.FileUtils.touch;
@@ -167,6 +168,32 @@ public class DriftDetectorTest extends DriftTest {
@SuppressWarnings("unchecked")
@Test
+ public void skipScheduledThatHasConfigDisabled() throws Exception {
+ detector.setDriftClient(new DriftClientTestStub() {
+ {
+ setBaseDir(resourceDir);
+ }
+
+ @Override
+ public void sendChangeSetToServer(int resourceId, DriftConfiguration driftConfiguration,
+ DriftChangeSetCategory type) {
+ throw new RuntimeException("Should not invoke drift client when drift configuration is disabled");
+ }
+ });
+
+ DriftConfiguration config = driftConfiguration("disabled-config-test", resourceDir.getAbsolutePath());
+ config.setEnabled(false);
+
+ File confDir = mkdir(resourceDir, "conf");
+ File server1Conf = new File(confDir, "server-1.conf");
+ touch(server1Conf);
+
+ scheduleQueue.enqueue(new DriftDetectionSchedule(resourceId(), config));
+ detector.run();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
public void includeAddedFileInDriftChangeSet() throws Exception {
DriftConfiguration config = driftConfiguration("file-added-drift-test", resourceDir.getAbsolutePath());
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftTest.java
index 97bfa45..98c421e 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftTest.java
@@ -81,6 +81,12 @@ public class DriftTest {
*/
protected File resourceDir;
+ /**
+ * The default interval assigned to drift configurations created using
+ * {@link #driftConfiguration(String, String)}
+ */
+ protected long defaultInterval = 1800L; // 30 minutes;
+
private MessageDigestGenerator digestGenerator;
/**
@@ -180,6 +186,7 @@ public class DriftTest {
/**
* Creates a {@link DriftConfiguration} with the specified basedir. The file system is
* used as the context for the basedir which means the path specified is used as is.
+ * The interval property is set to {@link #defaultInterval}.
*
* @param name The configuration name
* @param basedir An absolute path of the base directory
@@ -189,6 +196,8 @@ public class DriftTest {
DriftConfiguration config = new DriftConfiguration(new Configuration());
config.setName(name);
config.setBasedir(new DriftConfiguration.BaseDirectory(fileSystem, basedir));
+ config.setEnabled(true);
+ config.setInterval(defaultInterval);
return config;
}
commit 70fbc22e07246b5dd161c32877cfaf0cea4458ff
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Mon Jul 25 17:53:45 2011 -0400
sort the query in desc order, though the tree currently ignores this and has its own sorting.
need to fix that later
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftChangeSetsTreeDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftChangeSetsTreeDataSource.java
index fe8586a..c6e9e65 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftChangeSetsTreeDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftChangeSetsTreeDataSource.java
@@ -95,7 +95,7 @@ public class DriftChangeSetsTreeDataSource extends RPCDataSource<Object, BaseCri
// Get the top nodes (the change sets) but to be as fast as possible don't load their drifts.
// We will lazily load drifts when the these changeset tree nodes are opened
DriftChangeSetCriteria criteria = new DriftChangeSetJPACriteria();
- criteria.addSortVersion(PageOrdering.ASC);
+ criteria.addSortVersion(PageOrdering.DESC);
criteria.setPageControl(getPageControl(request));
driftService.findDriftChangeSetsByCriteria(criteria, new AsyncCallback<PageList<DriftChangeSet>>() {
commit ce318c437ea1a985679610191a0ceb6d3ebe5195
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Mon Jul 25 17:53:03 2011 -0400
default subtab view for drift is the change set tree
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java
index 4efc189..0e63d8e 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java
@@ -243,13 +243,13 @@ public class ResourceDetailView extends AbstractTwoLevelTabSetView<ResourceCompo
driftTab = new TwoLevelTab(getTabSet().extendLocatorId(Tab.DRIFT), new ViewName(Tab.DRIFT, MSG
.view_tabs_common_drift()), "subsystems/drift/Drift_16.png");
- this.driftHistory = new SubTab(driftTab.extendLocatorId(DriftSubTab.HISTORY), new ViewName(DriftSubTab.HISTORY,
- MSG.view_tabs_common_history()), null);
this.driftChangeSets = new SubTab(driftTab.extendLocatorId(DriftSubTab.CHANGE_SETS), new ViewName(
DriftSubTab.CHANGE_SETS, MSG.view_drift_changeSets()), null);
+ this.driftHistory = new SubTab(driftTab.extendLocatorId(DriftSubTab.HISTORY), new ViewName(DriftSubTab.HISTORY,
+ MSG.view_tabs_common_history()), null);
this.driftConfig = new SubTab(driftTab.extendLocatorId(DriftSubTab.CONFIGURATION), new ViewName(
DriftSubTab.CONFIGURATION, MSG.view_tabs_common_configuration()), null);
- driftTab.registerSubTabs(driftHistory, driftChangeSets, driftConfig);
+ driftTab.registerSubTabs(driftChangeSets, driftHistory, driftConfig);
tabs.add(driftTab);
contentTab = new TwoLevelTab(getTabSet().extendLocatorId("Content"), new ViewName("Content", MSG
@@ -519,17 +519,17 @@ public class ResourceDetailView extends AbstractTwoLevelTabSetView<ResourceCompo
ResourcePermission resourcePermissions, Set<ResourceTypeFacet> facets) {
if (updateTab(this.driftTab, facets.contains(ResourceTypeFacet.DRIFT), resourcePermissions.isDrift())) {
- updateSubTab(this.driftTab, this.driftHistory, true, true, new ViewFactory() {
+ updateSubTab(this.driftTab, this.driftChangeSets, true, true, new ViewFactory() {
@Override
public Canvas createView() {
- return ResourceDriftHistoryView.get(driftHistory.extendLocatorId("View"), resourceComposite);
+ return ResourceDriftChangeSetsView.get(driftChangeSets.extendLocatorId("View"), resourceComposite);
}
});
- updateSubTab(this.driftTab, this.driftChangeSets, true, true, new ViewFactory() {
+ updateSubTab(this.driftTab, this.driftHistory, true, true, new ViewFactory() {
@Override
public Canvas createView() {
- return ResourceDriftChangeSetsView.get(driftChangeSets.extendLocatorId("View"), resourceComposite);
+ return ResourceDriftHistoryView.get(driftHistory.extendLocatorId("View"), resourceComposite);
}
});
commit 14da4c241edb1bb8116eaf1657ddda6746f258fb
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Mon Jul 25 17:49:19 2011 -0400
initial start of the context menu for the change set tree
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/AbstractDriftChangeSetsTreeView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/AbstractDriftChangeSetsTreeView.java
index 521d7b2..50d787d 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/AbstractDriftChangeSetsTreeView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/AbstractDriftChangeSetsTreeView.java
@@ -27,14 +27,24 @@ import com.google.gwt.core.client.RunAsyncCallback;
import com.smartgwt.client.types.SelectionStyle;
import com.smartgwt.client.widgets.grid.events.DataArrivedEvent;
import com.smartgwt.client.widgets.grid.events.DataArrivedHandler;
+import com.smartgwt.client.widgets.menu.Menu;
+import com.smartgwt.client.widgets.menu.MenuItem;
+import com.smartgwt.client.widgets.menu.MenuItemSeparator;
+import com.smartgwt.client.widgets.menu.events.ClickHandler;
+import com.smartgwt.client.widgets.menu.events.MenuItemClickEvent;
import com.smartgwt.client.widgets.tree.Tree;
import com.smartgwt.client.widgets.tree.TreeNode;
-import com.smartgwt.client.widgets.tree.events.NodeClickEvent;
-import com.smartgwt.client.widgets.tree.events.NodeClickHandler;
+import com.smartgwt.client.widgets.tree.events.NodeContextClickEvent;
+import com.smartgwt.client.widgets.tree.events.NodeContextClickHandler;
+import org.rhq.core.domain.drift.Drift;
+import org.rhq.core.domain.drift.DriftChangeSet;
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.ImageManager;
import org.rhq.enterprise.gui.coregui.client.ViewId;
import org.rhq.enterprise.gui.coregui.client.ViewPath;
+import org.rhq.enterprise.gui.coregui.client.components.table.TimestampCellFormatter;
+import org.rhq.enterprise.gui.coregui.client.util.message.Message;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableTreeGrid;
/**
@@ -56,18 +66,9 @@ public abstract class AbstractDriftChangeSetsTreeView extends LocatableTreeGrid
setAnimateFolders(false);
setSelectionType(SelectionStyle.SINGLE);
setShowRollOver(false);
- setSortField(DriftChangeSetsTreeDataSource.ATTR_NAME);
setShowHeader(false);
setDataSource(new DriftChangeSetsTreeDataSource(canManageDrift));
-
- addNodeClickHandler(new NodeClickHandler() {
- public void onNodeClick(NodeClickEvent event) {
- TreeNode node = event.getNode();
- String link = getNodeTargetLink(node);
- CoreGUI.goToView(link);
- }
- });
}
@Override
@@ -76,13 +77,30 @@ public abstract class AbstractDriftChangeSetsTreeView extends LocatableTreeGrid
// We may need to wait for tree data to be fetched before we can complete processing the selected path.
// When the datasource pulls data keep processing the selectedPath if necessary.
- this.addDataArrivedHandler(new DataArrivedHandler() {
+ addDataArrivedHandler(new DataArrivedHandler() {
public void onDataArrived(DataArrivedEvent dataArrivedEvent) {
if (null != pendingPath) {
selectPath(pendingPath);
}
}
});
+
+ addNodeContextClickHandler(new NodeContextClickHandler() {
+ public void onNodeContextClick(final NodeContextClickEvent event) {
+ // stop the browser right-click menu
+ event.cancel();
+
+ TreeNode eventNode = event.getNode();
+
+ if (eventNode instanceof ChangeSetTreeNode) {
+ CoreGUI.getMessageCenter().notify(new Message("TODO [this will popup the changeset menu]"));
+ } else if (eventNode instanceof DriftTreeNode) {
+ Menu menu = buildContextMenu((DriftTreeNode) eventNode);
+ menu.showContextMenu();
+ }
+ }
+ });
+
}
public void selectPath(ViewPath viewPath) {
@@ -144,4 +162,76 @@ public abstract class AbstractDriftChangeSetsTreeView extends LocatableTreeGrid
* @return the node's link
*/
protected abstract String getNodeTargetLink(TreeNode node);
+
+ /**
+ * Builds the right-mouse-click context menu for the given drift node
+ * @param node the drift node whose menu is to be displayed
+ * @return the context menu to display
+ */
+ protected Menu buildContextMenu(final DriftTreeNode node) {
+
+ Menu contextMenu = new Menu();
+
+ // title
+ String titleName = node.getName();
+ if (titleName.length() > 50) {
+ // make sure the title isn't really long so the menu is not abnormally wide
+ titleName = "..." + titleName.substring(titleName.length() - 50);
+ }
+ MenuItem titleItem = new MenuItem(titleName);
+ titleItem.setEnabled(false);
+ contextMenu.setItems(titleItem);
+
+ // separator
+ contextMenu.addItem(new MenuItemSeparator());
+
+ // item that links to the history details
+ MenuItem detailsItem = new MenuItem(MSG.common_title_details());
+ detailsItem.addClickHandler(new ClickHandler() {
+ public void onClick(MenuItemClickEvent event) {
+ String link = getNodeTargetLink(node);
+ if (link != null) {
+ CoreGUI.goToView(link);
+ }
+ }
+ });
+ contextMenu.addItem(detailsItem);
+
+ return contextMenu;
+ }
+
+ @SuppressWarnings("unchecked")
+ static class ChangeSetTreeNode extends TreeNode {
+ public ChangeSetTreeNode(DriftChangeSet changeset) {
+ setIsFolder(true);
+ setIcon("subsystems/drift/ChangeSet_16.png");
+ setShowOpenIcon(true);
+ setID(changeset.getId());
+ setName(buildDriftChangeSetNodeName(changeset));
+ }
+
+ private String buildDriftChangeSetNodeName(DriftChangeSet changeset) {
+ StringBuilder str = new StringBuilder();
+ str.append(MSG.common_title_version());
+ str.append(' ');
+ str.append(changeset.getVersion());
+ str.append(" (");
+ str.append(TimestampCellFormatter.format(changeset.getCtime(),
+ TimestampCellFormatter.DATE_TIME_FORMAT_SHORT));
+ str.append(')');
+ return str.toString();
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ static class DriftTreeNode extends TreeNode {
+ public DriftTreeNode(Drift drift) {
+ setIsFolder(false);
+ setIcon(ImageManager.getDriftCategoryIcon(drift.getCategory()));
+ String parentID = drift.getChangeSet().getId();
+ setParentID(parentID);
+ setID(parentID + '_' + drift.getId());
+ setName(drift.getPath());
+ }
+ }
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftChangeSetsTreeDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftChangeSetsTreeDataSource.java
index c609a1e..fe8586a 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftChangeSetsTreeDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftChangeSetsTreeDataSource.java
@@ -39,9 +39,8 @@ import org.rhq.core.domain.criteria.DriftJPACriteria;
import org.rhq.core.domain.drift.Drift;
import org.rhq.core.domain.drift.DriftChangeSet;
import org.rhq.core.domain.util.PageList;
+import org.rhq.core.domain.util.PageOrdering;
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
-import org.rhq.enterprise.gui.coregui.client.ImageManager;
-import org.rhq.enterprise.gui.coregui.client.components.table.TimestampCellFormatter;
import org.rhq.enterprise.gui.coregui.client.gwt.DriftGWTServiceAsync;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
@@ -96,6 +95,7 @@ public class DriftChangeSetsTreeDataSource extends RPCDataSource<Object, BaseCri
// Get the top nodes (the change sets) but to be as fast as possible don't load their drifts.
// We will lazily load drifts when the these changeset tree nodes are opened
DriftChangeSetCriteria criteria = new DriftChangeSetJPACriteria();
+ criteria.addSortVersion(PageOrdering.ASC);
criteria.setPageControl(getPageControl(request));
driftService.findDriftChangeSetsByCriteria(criteria, new AsyncCallback<PageList<DriftChangeSet>>() {
@@ -233,38 +233,18 @@ public class DriftChangeSetsTreeDataSource extends RPCDataSource<Object, BaseCri
}
public ListGridRecord copyValuesForKnownDriftChangeSet(Object from, Integer changeSetId) {
- String parentID;
- TreeNode node = new TreeNode();
+ TreeNode node;
if (from instanceof DriftChangeSet) {
DriftChangeSet changeset = (DriftChangeSet) from;
- node.setIsFolder(true);
- node.setIcon("subsystems/drift/ChangeSet_16.png");
- node.setShowOpenIcon(true);
- node.setID(changeset.getId());
- node.setName(buildDriftChangeSetNodeName(changeset));
-
+ node = new AbstractDriftChangeSetsTreeView.ChangeSetTreeNode(changeset);
} else if (from instanceof Drift) {
Drift drift = (Drift) from;
- node.setIsFolder(false);
- node.setIcon(ImageManager.getDriftCategoryIcon(drift.getCategory()));
- parentID = drift.getChangeSet().getId();
- node.setParentID(parentID);
- node.setID(parentID + '_' + drift.getId());
- node.setName(drift.getPath());
+ node = new AbstractDriftChangeSetsTreeView.DriftTreeNode(drift);
+ } else {
+ throw new IllegalArgumentException("please report this bug - bad value: " + from);
}
// if, in the future, we add more node types, we'll add more else-if statements here
return node;
}
-
- private String buildDriftChangeSetNodeName(DriftChangeSet changeset) {
- StringBuilder str = new StringBuilder();
- str.append(MSG.common_title_version());
- str.append(' ');
- str.append(changeset.getVersion());
- str.append(" (");
- str.append(TimestampCellFormatter.format(changeset.getCtime(), TimestampCellFormatter.DATE_TIME_FORMAT_SHORT));
- str.append(')');
- return str.toString();
- }
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/ResourceDriftChangeSetsTreeView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/ResourceDriftChangeSetsTreeView.java
index dc2a22d..3e368d5 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/ResourceDriftChangeSetsTreeView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/ResourceDriftChangeSetsTreeView.java
@@ -43,9 +43,12 @@ public class ResourceDriftChangeSetsTreeView extends AbstractDriftChangeSetsTree
}
protected String getNodeTargetLink(TreeNode node) {
- String driftIdStr = node.getAttribute(DriftChangeSetsTreeDataSource.ATTR_ID).split("_")[1];
- String path = LinkManager.getDriftHistoryLink(this.context.resourceId, Integer.valueOf(driftIdStr));
- return path;
+ if (node instanceof DriftTreeNode) {
+ String driftIdStr = node.getAttribute(DriftChangeSetsTreeDataSource.ATTR_ID).split("_")[1];
+ String path = LinkManager.getDriftHistoryLink(this.context.resourceId, Integer.valueOf(driftIdStr));
+ return path;
+ }
+ return null;
}
}
commit 50215a85fb2c91627be9fb8c350c5222c3d57350
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Mon Jul 25 16:37:56 2011 -0400
the initial start of the drift change set tree view
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/LinkManager.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/LinkManager.java
index 30523b3..10c15e4 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/LinkManager.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/LinkManager.java
@@ -458,4 +458,8 @@ public class LinkManager {
public static String getBundleDeploymentLink(int bundleId, int bundleDeploymentId) {
return "#Bundles/Bundle/" + bundleId + "/deployments/" + bundleDeploymentId;
}
+
+ public static String getDriftHistoryLink(int resourceId, int driftId) {
+ return "#Resource/" + resourceId + "/Drift/History/" + driftId;
+ }
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/AbstractDriftChangeSetsTreeView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/AbstractDriftChangeSetsTreeView.java
new file mode 100644
index 0000000..521d7b2
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/AbstractDriftChangeSetsTreeView.java
@@ -0,0 +1,147 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.rhq.enterprise.gui.coregui.client.drift;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.RunAsyncCallback;
+import com.smartgwt.client.types.SelectionStyle;
+import com.smartgwt.client.widgets.grid.events.DataArrivedEvent;
+import com.smartgwt.client.widgets.grid.events.DataArrivedHandler;
+import com.smartgwt.client.widgets.tree.Tree;
+import com.smartgwt.client.widgets.tree.TreeNode;
+import com.smartgwt.client.widgets.tree.events.NodeClickEvent;
+import com.smartgwt.client.widgets.tree.events.NodeClickHandler;
+
+import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.ViewId;
+import org.rhq.enterprise.gui.coregui.client.ViewPath;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableTreeGrid;
+
+/**
+ * @author John Mazzitelli
+ */
+public abstract class AbstractDriftChangeSetsTreeView extends LocatableTreeGrid {
+
+ // We may need to wait for tree data to be fetched before we can complete processing the selected path.
+ // If so, hold it here and retry after the datasource pulls the data.
+ private ViewPath pendingPath = null;
+
+ public AbstractDriftChangeSetsTreeView(String locatorId, boolean canManageDrift) {
+ super(locatorId);
+ setWidth100();
+ setHeight100();
+ setLeaveScrollbarGap(false);
+ // fetch the top nodes at the inital onDraw()
+ setAutoFetchData(true);
+ setAnimateFolders(false);
+ setSelectionType(SelectionStyle.SINGLE);
+ setShowRollOver(false);
+ setSortField(DriftChangeSetsTreeDataSource.ATTR_NAME);
+ setShowHeader(false);
+
+ setDataSource(new DriftChangeSetsTreeDataSource(canManageDrift));
+
+ addNodeClickHandler(new NodeClickHandler() {
+ public void onNodeClick(NodeClickEvent event) {
+ TreeNode node = event.getNode();
+ String link = getNodeTargetLink(node);
+ CoreGUI.goToView(link);
+ }
+ });
+ }
+
+ @Override
+ protected void onInit() {
+ super.onInit();
+
+ // We may need to wait for tree data to be fetched before we can complete processing the selected path.
+ // When the datasource pulls data keep processing the selectedPath if necessary.
+ this.addDataArrivedHandler(new DataArrivedHandler() {
+ public void onDataArrived(DataArrivedEvent dataArrivedEvent) {
+ if (null != pendingPath) {
+ selectPath(pendingPath);
+ }
+ }
+ });
+ }
+
+ public void selectPath(ViewPath viewPath) {
+ Tree theTree = getTree();
+
+ if (viewPath.viewsLeft() > 0) {
+ String key = "";
+ for (ViewId view : viewPath.getViewPath().subList(2, viewPath.getViewPath().size())) {
+ if (key.length() > 0) {
+ key += "_";
+ }
+
+ key += view.getPath();
+
+ TreeNode node = theTree.findById(key);
+
+ if (node != null) {
+ // open the node, this will force a fetch of child data if necessary
+ theTree.openFolder(node);
+ } else {
+ // wait for data to get loaded...
+ pendingPath = new ViewPath(viewPath.toString());
+ return;
+ }
+ }
+
+ // we found the node, so keep going
+ pendingPath = null;
+
+ final String finalKey = key;
+ GWT.runAsync(new RunAsyncCallback() {
+ public void onFailure(Throwable reason) {
+ }
+
+ public void onSuccess() {
+ TreeNode node = getTree().findById(finalKey);
+ if (node != null) {
+ deselectAllRecords();
+ selectRecord(node);
+ }
+ }
+ });
+ } else {
+ deselectAllRecords();
+ if (getTotalRows() > 0)
+ selectRecord(0);
+ }
+ }
+
+ public void refresh() {
+ invalidateCache();
+ }
+
+ /**
+ * Returns the link (as a string) that the client should be redirected to
+ * if the given node is clicked.
+ *
+ * @param node the node whose target link is to be returned
+ * @return the node's link
+ */
+ protected abstract String getNodeTargetLink(TreeNode node);
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftChangeSetsTreeDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftChangeSetsTreeDataSource.java
new file mode 100644
index 0000000..c609a1e
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftChangeSetsTreeDataSource.java
@@ -0,0 +1,270 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.enterprise.gui.coregui.client.drift;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.data.DSRequest;
+import com.smartgwt.client.data.DSResponse;
+import com.smartgwt.client.data.DataSourceField;
+import com.smartgwt.client.data.Record;
+import com.smartgwt.client.data.fields.DataSourceTextField;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+import com.smartgwt.client.widgets.tree.TreeNode;
+
+import org.rhq.core.domain.criteria.BaseCriteria;
+import org.rhq.core.domain.criteria.DriftChangeSetCriteria;
+import org.rhq.core.domain.criteria.DriftChangeSetJPACriteria;
+import org.rhq.core.domain.criteria.DriftCriteria;
+import org.rhq.core.domain.criteria.DriftJPACriteria;
+import org.rhq.core.domain.drift.Drift;
+import org.rhq.core.domain.drift.DriftChangeSet;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.ImageManager;
+import org.rhq.enterprise.gui.coregui.client.components.table.TimestampCellFormatter;
+import org.rhq.enterprise.gui.coregui.client.gwt.DriftGWTServiceAsync;
+import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
+
+/**
+ * @author John Mazzitelli
+ */
+@SuppressWarnings("unchecked")
+public class DriftChangeSetsTreeDataSource extends RPCDataSource<Object, BaseCriteria> {
+
+ private static final String ATTR_PARENT_ID = "parentId";
+ public static final String ATTR_ID = "id";
+ public static final String ATTR_NAME = "name";
+
+ private DriftGWTServiceAsync driftService = GWTServiceLookup.getDriftService();
+ private final boolean canManageDrift;
+
+ public DriftChangeSetsTreeDataSource(boolean canManageDrift) {
+ super();
+ this.canManageDrift = canManageDrift;
+ List<DataSourceField> fields = addDataSourceFields();
+ addFields(fields);
+ }
+
+ @Override
+ protected List<DataSourceField> addDataSourceFields() {
+ List<DataSourceField> fields = super.addDataSourceFields();
+
+ DataSourceField idDataField = new DataSourceTextField(ATTR_ID, MSG.common_title_id());
+ idDataField.setPrimaryKey(true);
+ fields.add(idDataField);
+
+ DataSourceTextField nameDataField = new DataSourceTextField(ATTR_NAME, MSG.common_title_name());
+ nameDataField.setCanEdit(false);
+ fields.add(nameDataField);
+
+ DataSourceTextField parentIdField = new DataSourceTextField(ATTR_PARENT_ID, MSG.common_title_id_parent());
+ parentIdField.setForeignKey(ATTR_ID);
+ fields.add(parentIdField);
+
+ return fields;
+ }
+
+ @Override
+ protected void executeFetch(final DSRequest request, final DSResponse response, final BaseCriteria unused) {
+
+ String parentId = request.getCriteria().getAttribute(ATTR_PARENT_ID);
+
+ if (parentId == null) {
+
+ // There is no parent - we are at the root of the tree.
+ // Get the top nodes (the change sets) but to be as fast as possible don't load their drifts.
+ // We will lazily load drifts when the these changeset tree nodes are opened
+ DriftChangeSetCriteria criteria = new DriftChangeSetJPACriteria();
+ criteria.setPageControl(getPageControl(request));
+
+ driftService.findDriftChangeSetsByCriteria(criteria, new AsyncCallback<PageList<DriftChangeSet>>() {
+ public void onSuccess(PageList<DriftChangeSet> result) {
+ response.setData(buildRecords(result));
+ response.setTotalRows(result.getTotalSize());
+ processResponse(request.getRequestId(), response);
+ }
+
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError(MSG.view_drift_changeset_tree_loadFailure(), caught);
+ response.setStatus(DSResponse.STATUS_FAILURE);
+ processResponse(request.getRequestId(), response);
+ }
+ });
+ } else {
+ String changesetId = parentId;
+ DriftCriteria criteria = new DriftJPACriteria();
+ criteria.addFilterChangeSetId(changesetId);
+
+ driftService.findDriftsByCriteria(criteria, new AsyncCallback<PageList<Drift>>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError(MSG.view_drift_changeset_tree_loadFailure(), caught);
+ response.setStatus(DSResponse.STATUS_FAILURE);
+ processResponse(request.getRequestId(), response);
+ }
+
+ public void onSuccess(PageList<Drift> result) {
+ response.setData(buildRecords(result));
+ response.setTotalRows(result.getTotalSize());
+ processResponse(request.getRequestId(), response);
+ }
+ });
+
+ /*
+ * I am leaving this code commented for future reference. Because today the drit change set tree only
+ * shows simple changeset->drift tree, we don't need this. But if we need to have
+ * multiple types of child nodes, we'll need something like below to query
+ * for the different child node data. For example, we'd need this if we have a tree like:
+ * ChangeSet
+ * |____Resources
+ * | |____ My resource 1
+ * | |____ ...
+ * |_____Drifts
+ * |___ Drift #1
+ * |___ Drift #2
+ * |___ ...
+ * Today we only have Drifts child nodes, so we don't need to have that intermediate
+ * "Drifts" node. If we later want to introduce different node types (like Resources)
+ * we need additional code like below.
+ *
+
+ // we are at an inner node, being asked to get the children of it
+ if (p.endsWith("_drifts")) {
+ // ...load drift items like above in the real code...
+ } else if (p.endsWith("_resources")) {
+ // ...load resource items and put those nodes in the tree...
+ } else {
+ // This is an unknown type of node, so just log an error.
+ // Note that if, in the future, we have other types of nodes (like maybe resource nodes for group change sets?)
+ // we'll add more if-else statements above to process those different nodes.
+ CoreGUI.getErrorHandler().handleError(MSG.view_drift_changeset_tree_loadFailure());
+ }
+
+ *
+ */
+ }
+
+ return;
+ }
+
+ @Override
+ protected BaseCriteria getFetchCriteria(DSRequest request) {
+ // our executeFetch will determine on its own what criteria to use based on what is to be fetched
+ // thus we don't return anything here and let the executeFetch do everything
+ return null;
+ }
+
+ @Override
+ public Object copyValues(Record from) {
+ return null; // don't need this method.
+ }
+
+ @Override
+ public ListGridRecord[] buildRecords(Collection dataObjects) {
+ return buildRecordsForKnownChangeSets(dataObjects, null);
+ }
+
+ public ListGridRecord[] buildRecordsForKnownChangeSets(Collection dataObjects, Integer changeSetId) {
+ if (dataObjects == null) {
+ return null;
+ }
+
+ final List<ListGridRecord> records = new ArrayList<ListGridRecord>();
+
+ for (Object item : dataObjects) {
+
+ // the resultant item is a direct node to build
+ records.add(copyValues(item));
+
+ // now build the children of the node
+ /*
+ * We do not have the need for building any intermeidate nodes today.
+ * There is nothing to do, but if in the future we have differnet node types,
+ * we'll probably want intermediate nodes that we create here. See BundleTreeDataSource
+ * for an example of where this is already done. Commenting this out just as an
+ * example of how this can be done.
+
+ if (item instanceof DriftChangeSet) {
+ DriftChangeSet changeset = (DriftChangeSet) item;
+
+ // each bundle has two direct children - the versions and destinations folders
+ TreeNode versionNode = new TreeNode(MSG.view_drift());
+ versionNode.setID(changeset.getId() + "_drifts");
+ versionNode.setParentID(changeset.getId());
+ versionNode.setName(MSG.view_drift());
+ versionNode.setAttribute("name", MSG.view_drift());
+ records.add(versionNode);
+ } else if (item instanceof Drift) {
+ if (canManageDrift) {
+ records.add(copyValuesForKnownDriftChangeSet(driftItem, changeSetId));
+ }
+ }
+
+ *
+ */
+ }
+
+ return records.toArray(new ListGridRecord[records.size()]);
+ }
+
+ @Override
+ public ListGridRecord copyValues(Object from) {
+ return copyValuesForKnownDriftChangeSet(from, null);
+ }
+
+ public ListGridRecord copyValuesForKnownDriftChangeSet(Object from, Integer changeSetId) {
+ String parentID;
+ TreeNode node = new TreeNode();
+ if (from instanceof DriftChangeSet) {
+ DriftChangeSet changeset = (DriftChangeSet) from;
+ node.setIsFolder(true);
+ node.setIcon("subsystems/drift/ChangeSet_16.png");
+ node.setShowOpenIcon(true);
+ node.setID(changeset.getId());
+ node.setName(buildDriftChangeSetNodeName(changeset));
+
+ } else if (from instanceof Drift) {
+ Drift drift = (Drift) from;
+ node.setIsFolder(false);
+ node.setIcon(ImageManager.getDriftCategoryIcon(drift.getCategory()));
+ parentID = drift.getChangeSet().getId();
+ node.setParentID(parentID);
+ node.setID(parentID + '_' + drift.getId());
+ node.setName(drift.getPath());
+ }
+ // if, in the future, we add more node types, we'll add more else-if statements here
+
+ return node;
+ }
+
+ private String buildDriftChangeSetNodeName(DriftChangeSet changeset) {
+ StringBuilder str = new StringBuilder();
+ str.append(MSG.common_title_version());
+ str.append(' ');
+ str.append(changeset.getVersion());
+ str.append(" (");
+ str.append(TimestampCellFormatter.format(changeset.getCtime(), TimestampCellFormatter.DATE_TIME_FORMAT_SHORT));
+ str.append(')');
+ return str.toString();
+ }
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftChangeSetsView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftChangeSetsView.java
index f610b8b..48f5bc8 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftChangeSetsView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftChangeSetsView.java
@@ -38,6 +38,13 @@ public class DriftChangeSetsView extends LocatableVLayout {
this.hasWriteAccess = hasWriteAccess;
}
+ @Override
+ protected void onDraw() {
+ super.onDraw();
+
+ addMember(new ResourceDriftChangeSetsTreeView(extendLocatorId("Tree"), this.hasWriteAccess, this.context));
+ }
+
public EntityContext getContext() {
return context;
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/ResourceDriftChangeSetsTreeView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/ResourceDriftChangeSetsTreeView.java
new file mode 100644
index 0000000..dc2a22d
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/ResourceDriftChangeSetsTreeView.java
@@ -0,0 +1,51 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.enterprise.gui.coregui.client.drift;
+
+import com.smartgwt.client.widgets.tree.TreeNode;
+
+import org.rhq.core.domain.common.EntityContext;
+import org.rhq.enterprise.gui.coregui.client.LinkManager;
+
+/**
+ * @author John Mazzitelli
+ */
+public class ResourceDriftChangeSetsTreeView extends AbstractDriftChangeSetsTreeView {
+
+ private final EntityContext context;
+
+ public ResourceDriftChangeSetsTreeView(String locatorId, boolean canManageDrift, EntityContext context) {
+
+ super(locatorId, canManageDrift);
+
+ if (context.type != EntityContext.Type.Resource) {
+ throw new IllegalArgumentException("wrong context: " + context);
+ }
+
+ this.context = context;
+ }
+
+ protected String getNodeTargetLink(TreeNode node) {
+ String driftIdStr = node.getAttribute(DriftChangeSetsTreeDataSource.ATTR_ID).split("_")[1];
+ String path = LinkManager.getDriftHistoryLink(this.context.resourceId, Integer.valueOf(driftIdStr));
+ return path;
+ }
+
+}
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties
index c7d6f91..ea8c956 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties
@@ -1123,6 +1123,7 @@ view_drift_category_fileChanged = File Changed
view_drift_category_fileRemoved = File Removed
view_drift_changeSets = Change Sets
view_drift_changeSets_resourceViewTitle = Resource Drift Change Sets
+view_drift_changeset_tree_loadFailure = Failed to load drift change set tree.
view_drift_delete_confirm = Delete the selected drift(s)?
view_drift_delete_confirmAll = Delete all drifts from this source?
view_drift_failure_delete = Failed to delete drift targets with id''s: {0}
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties
index 5fe14aa..a07568a 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties
@@ -941,6 +941,7 @@ view_dashboards_title = Dashboard
##view_drift_category_fileRemoved = File Removed
##view_drift_changeSets = Change Sets
##view_drift_changeSets_resourceViewTitle = Resource Drift Change Sets
+##view_drift_changeset_tree_loadFailure = Failed to load drift change set tree.
##view_drift_delete_confirm = Delete the selected drift(s)?
##view_drift_delete_confirmAll = Delete all drifts from this source?
##view_drift_failure_delete = Failed to delete drift targets with id''s: {0}
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ja.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ja.properties
index 6bce847..6e68cff 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ja.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ja.properties
@@ -1106,6 +1106,7 @@ view_dashboards_title = ããã·ã¥ããŒã
##view_drift = Drift
##view_drift_changeSets = Change Sets
##view_drift_changeSets_resourceViewTitle = Resource Drift Change Sets
+##view_drift_changeset_tree_loadFailure = Failed to load drift change set tree.
##view_drift_table_baseDir = Base Directory
##view_drift_table_changeSet = Change Set
##view_drift_table_newFile = New File
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_pt.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_pt.properties
index bd2b6fb..fa86006 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_pt.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_pt.properties
@@ -1141,6 +1141,7 @@ view_dashboards_title = Dashboard~
##view_drift_category_fileRemoved = File Removed
##view_drift_changeSets = Change Sets
##view_drift_changeSets_resourceViewTitle = Resource Drift Change Sets
+##view_drift_changeset_tree_loadFailure = Failed to load drift change set tree.
##view_drift_delete_confirm = Delete the selected drift(s)?
##view_drift_delete_confirmAll = Delete all drifts from this source?
##view_drift_failure_delete = Failed to delete drift targets with id''s: {0}
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_zh.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_zh.properties
index 9fa9115..79816c5 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_zh.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_zh.properties
@@ -1115,6 +1115,7 @@ view_dashboards_title = \u7edf\u8ba1\u8868\u76d8
##view_drift = Drift
##view_drift_changeSets = Change Sets
##view_drift_changeSets_resourceViewTitle = Resource Drift Change Sets
+##view_drift_changeset_tree_loadFailure = Failed to load drift change set tree.
##view_drift_table_baseDir = Base Directory
##view_drift_table_changeSet = Change Set
##view_drift_table_newFile = New File
diff --git a/modules/enterprise/gui/coregui/src/main/webapp/images/subsystems/drift/ChangeSet_16.png b/modules/enterprise/gui/coregui/src/main/webapp/images/subsystems/drift/ChangeSet_16.png
new file mode 100644
index 0000000..fdda214
Binary files /dev/null and b/modules/enterprise/gui/coregui/src/main/webapp/images/subsystems/drift/ChangeSet_16.png differ
diff --git a/modules/enterprise/gui/coregui/src/main/webapp/images/subsystems/drift/ChangeSet_16_open.png b/modules/enterprise/gui/coregui/src/main/webapp/images/subsystems/drift/ChangeSet_16_open.png
new file mode 100644
index 0000000..358cf61
Binary files /dev/null and b/modules/enterprise/gui/coregui/src/main/webapp/images/subsystems/drift/ChangeSet_16_open.png differ
commit abb0a2caa37e9258b97957f4ac2acd78a6c13638
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Mon Jul 25 12:12:31 2011 -0400
drift change set criteria needs to support paging like everyone else.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BaseCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BaseCriteria.java
index edc436b..f377ade 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BaseCriteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BaseCriteria.java
@@ -3,8 +3,11 @@ package org.rhq.core.domain.criteria;
import org.rhq.core.domain.util.PageControl;
/**
- * Created by IntelliJ IDEA. User: jsanda Date: 7/19/11 Time: 5:30 PM To change this template use File | Settings | File
- * Templates.
+ * All criteria, regardless of the backend storage that will be queried with this criteria, needs
+ * to support certain base functionality (like paging).
+ * This base interface provides that common API.
+ *
+ * @author John Sanda
*/
public interface BaseCriteria {
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/DriftChangeSetCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/DriftChangeSetCriteria.java
index 1b3effc..b5f71b2 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/DriftChangeSetCriteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/DriftChangeSetCriteria.java
@@ -5,7 +5,7 @@ import java.io.Serializable;
import org.rhq.core.domain.drift.DriftChangeSetCategory;
import org.rhq.core.domain.util.PageOrdering;
-public interface DriftChangeSetCriteria extends Serializable {
+public interface DriftChangeSetCriteria extends BaseCriteria, Serializable {
void addFilterId(String filterId);
commit bd1fd799e79a43d006f82d6e7ad5817a42486b8f
Author: John Sanda <jsanda(a)redhat.com>
Date: Sun Jul 24 21:13:24 2011 -0400
Adding createSnapshot method to drift server api
Also moving Snapshot and DiffReport classes to core/domain to make them
accessible to coregui.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/drift/DiffReport.java b/modules/core/domain/src/main/java/org/rhq/core/domain/drift/DiffReport.java
new file mode 100644
index 0000000..e0659d9
--- /dev/null
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/drift/DiffReport.java
@@ -0,0 +1,38 @@
+package org.rhq.core.domain.drift;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class DiffReport<T> {
+
+ private List<T> notInLeft = new ArrayList<T>();
+
+ private List<T> notInRight = new ArrayList<T>();
+
+ private List<T> conflicts = new ArrayList<T>();
+
+ public List<T> getElementsNotInLeft() {
+ return notInLeft;
+ }
+
+ public void elementNotInLeft(T element) {
+ notInLeft.add(element);
+ }
+
+ public List<T> getElementsNotInRight() {
+ return notInRight;
+ }
+
+ public void elementNotInRight(T element) {
+ notInRight.add(element);
+ }
+
+ public List<T> getElementsInConflict() {
+ return conflicts;
+ }
+
+ public void elementInConflict(T element) {
+ conflicts.add(element);
+ }
+
+}
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/drift/Snapshot.java b/modules/core/domain/src/main/java/org/rhq/core/domain/drift/Snapshot.java
new file mode 100644
index 0000000..91e5f50
--- /dev/null
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/drift/Snapshot.java
@@ -0,0 +1,68 @@
+package org.rhq.core.domain.drift;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Map;
+import java.util.TreeMap;
+
+import static org.rhq.core.domain.drift.DriftCategory.FILE_REMOVED;
+
+public class Snapshot implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private int version;
+
+ private Map<String, Drift> entries = new TreeMap<String, Drift>();
+
+ public int getVersion() {
+ return version;
+ }
+
+ public Collection<Drift> getEntries() {
+ return entries.values();
+ }
+
+ public <D extends Drift> Snapshot add(DriftChangeSet<D> changeSet) {
+ for (Drift entry : changeSet.getDrifts()) {
+ entries.remove(entry.getPath());
+ if (entry.getCategory() != FILE_REMOVED) {
+ entries.put(entry.getPath(), entry);
+ }
+ }
+ version = changeSet.getVersion();
+ return this;
+ }
+
+ public DiffReport diff(Snapshot right) {
+ Snapshot left = this;
+ DiffReport<Drift> diff = new DiffReport<Drift>();
+
+ for (Map.Entry<String, Drift> entry : left.entries.entrySet()) {
+ if (!right.entries.containsKey(entry.getKey())) {
+ diff.elementNotInRight(entry.getValue());
+ }
+ }
+
+ for (Map.Entry<String, Drift> entry : right.entries.entrySet()) {
+ if (!left.entries.containsKey(entry.getKey())) {
+ diff.elementNotInLeft(entry.getValue());
+ }
+ }
+
+ for (Map.Entry<String, Drift> entry : left.entries.entrySet()) {
+ Drift rightDrift = right.entries.get(entry.getKey());
+ if (rightDrift != null) {
+ DriftFile leftFile = entry.getValue().getNewDriftFile();
+ DriftFile rightFile = rightDrift.getNewDriftFile();
+
+ if (!leftFile.getHashId().equals(rightFile.getHashId())) {
+ diff.elementInConflict(entry.getValue());
+ }
+ }
+ }
+
+ return diff;
+ }
+
+}
diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/drift/SnapshotTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/drift/SnapshotTest.java
new file mode 100644
index 0000000..93653b3
--- /dev/null
+++ b/modules/core/domain/src/test/java/org/rhq/core/domain/drift/SnapshotTest.java
@@ -0,0 +1,383 @@
+package org.rhq.core.domain.drift;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.testng.annotations.Test;
+
+import static java.util.Arrays.asList;
+import static org.rhq.core.domain.drift.DriftCategory.FILE_ADDED;
+import static org.rhq.core.domain.drift.DriftCategory.FILE_CHANGED;
+import static org.rhq.core.domain.drift.DriftCategory.FILE_REMOVED;
+import static org.rhq.core.domain.drift.DriftChangeSetCategory.COVERAGE;
+import static org.rhq.core.domain.drift.DriftChangeSetCategory.DRIFT;
+import static org.rhq.core.domain.drift.DriftFileStatus.LOADED;
+import static org.rhq.test.AssertUtils.assertCollectionMatchesNoOrder;
+import static org.testng.Assert.assertEquals;
+
+public class SnapshotTest {
+
+ @Test
+ public void addChangeSetWithAddedFile() {
+ int configId = 1;
+
+ FakeDriftChangeSet changeSet = new FakeDriftChangeSet(0, COVERAGE, configId)
+ .add(new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a1b2c3", 1024, LOADED), "/drift/1.txt"));
+
+ Snapshot snapshot = new Snapshot().add(changeSet);
+
+ assertCollectionMatchesNoOrder(changeSet.getDrifts(), snapshot.getEntries(), "Failed to build " +
+ "a snapshot that contains a single change set");
+ assertEquals(snapshot.getVersion(), changeSet.getVersion(), "Snapshot version is wrong");
+ }
+
+ @Test
+ public void addChangeSetsWithAddedFiles() {
+ int configId = 1;
+
+ Drift entry1 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a1b2c3", 1024, LOADED), "/drift/1.txt");
+ FakeDriftChangeSet changeSet1 = new FakeDriftChangeSet(0, COVERAGE, configId).add(entry1);
+
+ Drift entry2 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("4a5b6c", 1024, LOADED), "/drift/2.txt");
+ FakeDriftChangeSet changeSet2 = new FakeDriftChangeSet(1, DRIFT, configId).add(entry2);
+
+ Snapshot snapshot = new Snapshot().add(changeSet1).add(changeSet2);
+
+ assertCollectionMatchesNoOrder(asSet(entry1, entry2), snapshot.getEntries(), "Failed to build snapshot " +
+ "with two change sets and file added in second change set");
+ assertEquals(snapshot.getVersion(), changeSet2.getVersion(), "Snapshot version is wrong");
+ }
+
+ @Test
+ public void replaceFileWithChangedVersion() {
+ int configId = 1;
+
+ Drift entry1 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a1b2c3", 1024, LOADED), "/drift/1.txt");
+ FakeDriftChangeSet changeSet1 = new FakeDriftChangeSet(0, COVERAGE, configId).add(entry1);
+
+ Drift entry2 = new FakeDrift(FILE_CHANGED, new FakeDriftFile("a1b2c3", 1024, LOADED),
+ new FakeDriftFile("4d5e6f", 1024, LOADED), "/drift/1.txt");
+ FakeDriftChangeSet changeSet2 = new FakeDriftChangeSet(1, DRIFT, configId).add(entry2);
+
+ Snapshot snapshot = new Snapshot().add(changeSet1).add(changeSet2);
+
+ assertCollectionMatchesNoOrder(asSet(entry2), snapshot.getEntries(),
+ "Failed to build snapshot with file changed");
+ }
+
+ @Test
+ public void deleteFileThatHasBeenRemoved() {
+ int configId = 1;
+
+ Drift entry1 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a1b2c3", 1024, LOADED), "/drift/1.txt");
+ Drift entry2 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("d1f2a3", 1024, LOADED), "/drift/2.txt");
+ FakeDriftChangeSet changeSet1 = new FakeDriftChangeSet(0, COVERAGE, configId).add(entry1).add(entry2);
+
+ Drift entry3 = new FakeDrift(FILE_REMOVED, new FakeDriftFile("a1b2c3", 1024, LOADED), null, "/drift/1.txt");
+ FakeDriftChangeSet changeSet2 = new FakeDriftChangeSet(1, DRIFT, configId).add(entry3);
+
+ Snapshot snapshot = new Snapshot().add(changeSet1).add(changeSet2);
+
+ assertCollectionMatchesNoOrder(asSet(entry2), snapshot.getEntries(),
+ "Failed to build snapshot with a file " +
+ "removed.");
+ }
+
+ @Test
+ public void diffShowsEntriesInLeftAndNotInRight() {
+ int configId = 1;
+
+ Drift entry1 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a1b2c3", 1024, LOADED), "/drift/1.txt");
+ FakeDriftChangeSet changeSet1 = new FakeDriftChangeSet(0, COVERAGE, configId).add(entry1);
+ Snapshot right = new Snapshot().add(changeSet1);
+
+ Drift entry2 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a3b6c9", 1024, LOADED), "/drift/2.txt");
+ FakeDriftChangeSet changeSet2 = new FakeDriftChangeSet(0, COVERAGE, configId).add(entry1).add(entry2);
+ Snapshot left = new Snapshot().add(changeSet1).add(changeSet2);
+
+ DiffReport diff = left.diff(right);
+
+ assertCollectionMatchesNoOrder(asList(entry2), diff.getElementsNotInRight(),
+ "Diff report does not contain " +
+ "elements that are in the left but not in the right.");
+ }
+
+ @Test
+ public void diffShowsEntriesInRightAndNotInLeft() {
+ int configId = 1;
+
+ Drift entry1 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a1b2c3", 1024, LOADED), "/drift/1.txt");
+ FakeDriftChangeSet changeSet1 = new FakeDriftChangeSet(0, COVERAGE, configId).add(entry1);
+ Snapshot right = new Snapshot().add(changeSet1);
+
+ Drift entry2 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a3b6c9", 1024, LOADED), "/drift/2.txt");
+ FakeDriftChangeSet changeSet2 = new FakeDriftChangeSet(0, COVERAGE, configId).add(entry2);
+ Snapshot left = new Snapshot().add(changeSet2);
+
+ DiffReport diff = left.diff(right);
+
+ assertCollectionMatchesNoOrder(asList(entry1), diff.getElementsNotInLeft(),
+ "Diff report does not contain " +
+ "elements that are in the left but not in the right");
+ }
+
+ @Test
+ public void diffShowsEntriesInLeftAndRightThatAreInConflict() {
+ int configId = 1;
+
+ Drift entry1 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a1b2c3", 1024, LOADED), "/drfit/1.txt");
+ FakeDriftChangeSet changeSet1 = new FakeDriftChangeSet(0, COVERAGE, configId).add(entry1);
+ Snapshot right = new Snapshot().add(changeSet1);
+
+ Drift entry2 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("c3b2a1", 1024, LOADED), "/drfit/1.txt");
+ FakeDriftChangeSet changeSet2 = new FakeDriftChangeSet(1, DRIFT, configId).add(entry2);
+ Snapshot left = new Snapshot().add(changeSet2);
+
+ DiffReport diff = left.diff(right);
+
+ assertCollectionMatchesNoOrder(asList(entry2), diff.getElementsInConflict(),
+ "Diff report does not contain " +
+ "element that are in both left and right and are in conflict");
+ }
+
+ <E> Set<E> asSet(E... elements) {
+ HashSet<E> set = new HashSet<E>();
+ for (E element : elements) {
+ set.add(element);
+ }
+ return set;
+ }
+
+ static class FakeDriftChangeSet implements DriftChangeSet {
+
+ private String id;
+ private int version;
+ private DriftChangeSetCategory category;
+ private int configId;
+ private Set<Drift> drifts = new HashSet<Drift>();
+ private long ctime = System.currentTimeMillis();
+
+ public FakeDriftChangeSet() {
+ }
+
+ public FakeDriftChangeSet(int version, DriftChangeSetCategory category, int configId) {
+ this.version = version;
+ this.category = category;
+ this.configId = configId;
+ }
+
+ @Override
+ public String getId() {
+ return id;
+ }
+
+ @Override
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ @Override
+ public Long getCtime() {
+ return ctime;
+ }
+
+ @Override
+ public int getVersion() {
+ return version;
+ }
+
+ @Override
+ public void setVersion(int version) {
+ this.version = version;
+ }
+
+ @Override
+ public DriftChangeSetCategory getCategory() {
+ return category;
+ }
+
+ @Override
+ public void setCategory(DriftChangeSetCategory category) {
+ this.category = category;
+ }
+
+ @Override
+ public int getDriftConfigurationId() {
+ return configId;
+ }
+
+ @Override
+ public void setDriftConfigurationId(int id) {
+ configId = id;
+ }
+
+ @Override
+ public int getResourceId() {
+ return 0;
+ }
+
+ @Override
+ public Set getDrifts() {
+ return drifts;
+ }
+
+ @Override
+ public void setDrifts(Set drifts) {
+ this.drifts = drifts;
+ }
+
+ public FakeDriftChangeSet add(Drift drift) {
+ drifts.add(drift);
+ return this;
+ }
+ }
+
+ static class FakeDrift implements Drift {
+
+ private String id;
+ private DriftCategory category;
+ private String path;
+ private DriftFile oldFile;
+ private DriftFile newFile;
+ private long ctime = System.currentTimeMillis();
+
+ public FakeDrift() {
+ }
+
+ public FakeDrift(DriftCategory category, DriftFile oldFile, DriftFile newFile, String path) {
+ this.category = category;
+ this.oldFile = oldFile;
+ this.newFile = newFile;
+ this.path = path;
+ }
+
+ @Override
+ public String getId() {
+ return id;
+ }
+
+ @Override
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ @Override
+ public Long getCtime() {
+ return ctime;
+ }
+
+ @Override
+ public DriftChangeSet getChangeSet() {
+ return null;
+ }
+
+ @Override
+ public void setChangeSet(DriftChangeSet changeSet) {
+
+ }
+
+ @Override
+ public DriftCategory getCategory() {
+ return category;
+ }
+
+ @Override
+ public void setCategory(DriftCategory category) {
+ this.category = category;
+ }
+
+ @Override
+ public String getPath() {
+ return path;
+ }
+
+ @Override
+ public void setPath(String path) {
+ this.path = path;
+ }
+
+ @Override
+ public DriftFile getOldDriftFile() {
+ return oldFile;
+ }
+
+ @Override
+ public void setOldDriftFile(DriftFile oldDriftFile) {
+ this.oldFile = oldDriftFile;
+ }
+
+ @Override
+ public DriftFile getNewDriftFile() {
+ return newFile;
+ }
+
+ @Override
+ public void setNewDriftFile(DriftFile newDriftFile) {
+ newFile = newDriftFile;
+ }
+
+ @Override
+ public String toString() {
+ return "Drift[category: " + category.code() + ", oldFile: " + oldFile + ", newFile: " + newFile +
+ ", path: " + path + "]";
+ }
+ }
+
+ static class FakeDriftFile implements DriftFile {
+
+ private String hash;
+ private long size;
+ private DriftFileStatus status;
+ private long ctime = System.currentTimeMillis();
+
+ public FakeDriftFile() {
+ }
+
+ public FakeDriftFile(String hash, long size, DriftFileStatus status) {
+ this.hash = hash;
+ this.size = size;
+ this.status = status;
+ }
+
+ @Override
+ public String getHashId() {
+ return hash;
+ }
+
+ @Override
+ public void setHashId(String hashId) {
+ hash = hashId;
+ }
+
+ @Override
+ public Long getCtime() {
+ return ctime;
+ }
+
+ @Override
+ public Long getDataSize() {
+ return size;
+ }
+
+ @Override
+ public void setDataSize(Long size) {
+ this.size = size;
+ }
+
+ @Override
+ public DriftFileStatus getStatus() {
+ return status;
+ }
+
+ @Override
+ public void setStatus(DriftFileStatus status) {
+ this.status = status;
+ }
+
+ @Override
+ public String toString() {
+ return "DriftFile[hashId: " + hash + ", dataSize: " + size + ", status: " + status.ordinal() + "]";
+ }
+ }
+
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/DriftGWTService.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/DriftGWTService.java
index f69195d..10f72f5 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/DriftGWTService.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/DriftGWTService.java
@@ -20,13 +20,16 @@ package org.rhq.enterprise.gui.coregui.client.gwt;
import com.google.gwt.user.client.rpc.RemoteService;
+import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.common.EntityContext;
import org.rhq.core.domain.criteria.DriftChangeSetCriteria;
+import org.rhq.core.domain.criteria.DriftChangeSetJPACriteria;
import org.rhq.core.domain.criteria.DriftCriteria;
import org.rhq.core.domain.drift.Drift;
import org.rhq.core.domain.drift.DriftChangeSet;
import org.rhq.core.domain.drift.DriftComposite;
import org.rhq.core.domain.drift.DriftConfiguration;
+import org.rhq.core.domain.drift.Snapshot;
import org.rhq.core.domain.util.PageList;
/**
@@ -115,6 +118,8 @@ public interface DriftGWTService extends RemoteService {
PageList<DriftComposite> findDriftCompositesByCriteria(DriftCriteria criteria);
+ Snapshot createSnapshot(Subject subject, DriftChangeSetJPACriteria criteria);
+
/**
* Get the specified drift configuration for the specified context.
*
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/DriftGWTServiceImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/DriftGWTServiceImpl.java
index 8d5beb9..b440ffd 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/DriftGWTServiceImpl.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/DriftGWTServiceImpl.java
@@ -18,13 +18,16 @@
*/
package org.rhq.enterprise.gui.coregui.server.gwt;
+import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.common.EntityContext;
import org.rhq.core.domain.criteria.DriftChangeSetCriteria;
+import org.rhq.core.domain.criteria.DriftChangeSetJPACriteria;
import org.rhq.core.domain.criteria.DriftCriteria;
import org.rhq.core.domain.drift.Drift;
import org.rhq.core.domain.drift.DriftChangeSet;
import org.rhq.core.domain.drift.DriftComposite;
import org.rhq.core.domain.drift.DriftConfiguration;
+import org.rhq.core.domain.drift.Snapshot;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.gui.coregui.client.gwt.DriftGWTService;
import org.rhq.enterprise.gui.coregui.server.util.SerialUtility;
@@ -122,6 +125,15 @@ public class DriftGWTServiceImpl extends AbstractGWTServiceImpl implements Drift
}
@Override
+ public Snapshot createSnapshot(Subject subject, DriftChangeSetJPACriteria criteria) {
+ try {
+ return driftServer.createSnapshot(subject, criteria);
+ } catch (Throwable t) {
+ throw getExceptionToThrowToClient(t);
+ }
+ }
+
+ @Override
public DriftConfiguration getDriftConfiguration(EntityContext entityContext, int driftConfigId)
throws RuntimeException {
try {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DiffReport.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DiffReport.java
deleted file mode 100644
index 89f3286..0000000
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DiffReport.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.rhq.enterprise.server.drift;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class DiffReport<T> {
-
- private List<T> notInLeft = new ArrayList<T>();
-
- private List<T> notInRight = new ArrayList<T>();
-
- private List<T> conflicts = new ArrayList<T>();
-
- public List<T> getElementsNotInLeft() {
- return notInLeft;
- }
-
- public void elementNotInLeft(T element) {
- notInLeft.add(element);
- }
-
- public List<T> getElementsNotInRight() {
- return notInRight;
- }
-
- public void elementNotInRight(T element) {
- notInRight.add(element);
- }
-
- public List<T> getElementsInConflict() {
- return conflicts;
- }
-
- public void elementInConflict(T element) {
- conflicts.add(element);
- }
-
-}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerBean.java
index 4c669e7..54eda95 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerBean.java
@@ -71,6 +71,7 @@ import org.rhq.core.domain.drift.DriftFileBits;
import org.rhq.core.domain.drift.DriftFileStatus;
import org.rhq.core.domain.drift.RhqDrift;
import org.rhq.core.domain.drift.RhqDriftChangeSet;
+import org.rhq.core.domain.drift.Snapshot;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.util.ZipUtil;
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerLocal.java
index 0fb077d..6939c7c 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerLocal.java
@@ -33,6 +33,7 @@ import org.rhq.core.domain.drift.DriftConfiguration;
import org.rhq.core.domain.drift.RhqDrift;
import org.rhq.core.domain.drift.RhqDriftChangeSet;
import org.rhq.core.domain.drift.RhqDriftFile;
+import org.rhq.core.domain.drift.Snapshot;
import org.rhq.core.domain.util.PageList;
@Local
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftServerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftServerBean.java
index 0dd2aa8..276c8b9 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftServerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftServerBean.java
@@ -19,11 +19,13 @@ import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.common.EntityContext;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.criteria.DriftChangeSetCriteria;
+import org.rhq.core.domain.criteria.DriftChangeSetJPACriteria;
import org.rhq.core.domain.criteria.DriftCriteria;
import org.rhq.core.domain.drift.Drift;
import org.rhq.core.domain.drift.DriftChangeSet;
import org.rhq.core.domain.drift.DriftComposite;
import org.rhq.core.domain.drift.DriftConfiguration;
+import org.rhq.core.domain.drift.Snapshot;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.RHQConstants;
@@ -41,6 +43,13 @@ import static javax.ejb.TransactionAttributeType.NOT_SUPPORTED;
@Stateless
public class DriftServerBean implements DriftServerLocal {
+ // TODO Should security checks be handled here instead of delegating to the drift plugin?
+ // Currently any security checks that need to be performed are delegated to the plugin.
+ // This is fine *so far* since the only plugin is the default which is our existing SLSB
+ // layer backed by the RHQ database. If the plugins are only supposed to be responsible
+ // for persistence management of drift entities and content, then they should not be
+ // responsible for other concerns like security.
+
private Log log = LogFactory.getLog(DriftServerBean.class);
@PersistenceContext(unitName = RHQConstants.PERSISTENCE_UNIT_NAME)
@@ -87,6 +96,13 @@ public class DriftServerBean implements DriftServerLocal {
driftServerPlugin.saveChangeSetFiles(changeSetFilesZip);
}
+ @Override
+ @TransactionAttribute(NOT_SUPPORTED)
+ public Snapshot createSnapshot(Subject subject, DriftChangeSetJPACriteria criteria) {
+ DriftServerPluginFacet driftServerPlugin = getServerPlugin();
+ return driftServerPlugin.createSnapshot(subject, criteria);
+ }
+
DriftServerPluginFacet getServerPlugin() {
MasterServerPluginContainer masterPC = LookupUtil.getServerPluginService().getMasterPluginContainer();
if (masterPC == null) {
@@ -201,4 +217,5 @@ public class DriftServerBean implements DriftServerLocal {
throw new IllegalArgumentException("Entity Context Type not supported [" + context + "]");
}
}
+
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftServerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftServerLocal.java
index 756f135..5046e83 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftServerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftServerLocal.java
@@ -7,11 +7,13 @@ import javax.ejb.Local;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.common.EntityContext;
import org.rhq.core.domain.criteria.DriftChangeSetCriteria;
+import org.rhq.core.domain.criteria.DriftChangeSetJPACriteria;
import org.rhq.core.domain.criteria.DriftCriteria;
import org.rhq.core.domain.drift.Drift;
import org.rhq.core.domain.drift.DriftChangeSet;
import org.rhq.core.domain.drift.DriftComposite;
import org.rhq.core.domain.drift.DriftConfiguration;
+import org.rhq.core.domain.drift.Snapshot;
import org.rhq.core.domain.util.PageList;
@Local
@@ -33,4 +35,6 @@ public interface DriftServerLocal {
PageList<DriftComposite> findDriftCompositesByCriteria(Subject subject, DriftCriteria criteria);
+ Snapshot createSnapshot(Subject subject, DriftChangeSetJPACriteria criteria);
+
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/Snapshot.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/Snapshot.java
deleted file mode 100644
index 5dc18fa..0000000
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/Snapshot.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package org.rhq.enterprise.server.drift;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.Map;
-import java.util.TreeMap;
-
-import org.rhq.core.domain.drift.Drift;
-import org.rhq.core.domain.drift.DriftChangeSet;
-import org.rhq.core.domain.drift.DriftFile;
-
-import static org.rhq.core.domain.drift.DriftCategory.FILE_REMOVED;
-
-public class Snapshot implements Serializable {
-
- private static final long serialVersionUID = 1L;
-
- private int version;
-
- private Map<String, Drift> entries = new TreeMap<String, Drift>();
-
- public int getVersion() {
- return version;
- }
-
- public Collection<Drift> getEntries() {
- return entries.values();
- }
-
- public <D extends Drift> Snapshot add(DriftChangeSet<D> changeSet) {
- for (Drift entry : changeSet.getDrifts()) {
- entries.remove(entry.getPath());
- if (entry.getCategory() != FILE_REMOVED) {
- entries.put(entry.getPath(), entry);
- }
- }
- version = changeSet.getVersion();
- return this;
- }
-
- public DiffReport diff(Snapshot right) {
- Snapshot left = this;
- DiffReport<Drift> diff = new DiffReport<Drift>();
-
- for (Map.Entry<String, Drift> entry : left.entries.entrySet()) {
- if (!right.entries.containsKey(entry.getKey())) {
- diff.elementNotInRight(entry.getValue());
- }
- }
-
- for (Map.Entry<String, Drift> entry : right.entries.entrySet()) {
- if (!left.entries.containsKey(entry.getKey())) {
- diff.elementNotInLeft(entry.getValue());
- }
- }
-
- for (Map.Entry<String, Drift> entry : left.entries.entrySet()) {
- Drift rightDrift = right.entries.get(entry.getKey());
- if (rightDrift != null) {
- DriftFile leftFile = entry.getValue().getNewDriftFile();
- DriftFile rightFile = rightDrift.getNewDriftFile();
-
- if (!leftFile.getHashId().equals(rightFile.getHashId())) {
- diff.elementInConflict(entry.getValue());
- }
- }
- }
-
- return diff;
- }
-
-}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/drift/DriftServerPluginFacet.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/drift/DriftServerPluginFacet.java
index 890d2d8..867464d 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/drift/DriftServerPluginFacet.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/drift/DriftServerPluginFacet.java
@@ -23,10 +23,12 @@ import java.io.File;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.criteria.DriftChangeSetCriteria;
+import org.rhq.core.domain.criteria.DriftChangeSetJPACriteria;
import org.rhq.core.domain.criteria.DriftCriteria;
import org.rhq.core.domain.drift.Drift;
import org.rhq.core.domain.drift.DriftChangeSet;
import org.rhq.core.domain.drift.DriftComposite;
+import org.rhq.core.domain.drift.Snapshot;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent;
@@ -47,4 +49,6 @@ public interface DriftServerPluginFacet extends ServerPluginComponent {
void saveChangeSet(int resourceId, File changeSetZip) throws Exception;
void saveChangeSetFiles(File changeSetFilesZip) throws Exception;
+
+ Snapshot createSnapshot(Subject subject, DriftChangeSetJPACriteria criteria);
}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/drift/SnapshotTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/drift/SnapshotTest.java
deleted file mode 100644
index 47dbb73..0000000
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/drift/SnapshotTest.java
+++ /dev/null
@@ -1,385 +0,0 @@
-package org.rhq.enterprise.server.drift;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import org.testng.annotations.Test;
-
-import org.rhq.core.domain.drift.Drift;
-import org.rhq.core.domain.drift.DriftCategory;
-import org.rhq.core.domain.drift.DriftChangeSet;
-import org.rhq.core.domain.drift.DriftChangeSetCategory;
-import org.rhq.core.domain.drift.DriftFile;
-import org.rhq.core.domain.drift.DriftFileStatus;
-
-import static java.util.Arrays.asList;
-import static org.rhq.core.domain.drift.DriftCategory.FILE_ADDED;
-import static org.rhq.core.domain.drift.DriftCategory.FILE_CHANGED;
-import static org.rhq.core.domain.drift.DriftCategory.FILE_REMOVED;
-import static org.rhq.core.domain.drift.DriftChangeSetCategory.COVERAGE;
-import static org.rhq.core.domain.drift.DriftChangeSetCategory.DRIFT;
-import static org.rhq.core.domain.drift.DriftFileStatus.LOADED;
-import static org.rhq.test.AssertUtils.assertCollectionMatchesNoOrder;
-import static org.testng.Assert.assertEquals;
-
-public class SnapshotTest {
-
- @Test
- public void addChangeSetWithAddedFile() {
- int configId = 1;
-
- FakeDriftChangeSet changeSet = new FakeDriftChangeSet(0, COVERAGE, configId)
- .add(new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a1b2c3", 1024, LOADED), "/drift/1.txt"));
-
- Snapshot snapshot = new Snapshot().add(changeSet);
-
- assertCollectionMatchesNoOrder(changeSet.getDrifts(), snapshot.getEntries(), "Failed to build " +
- "a snapshot that contains a single change set");
- assertEquals(snapshot.getVersion(), changeSet.getVersion(), "Snapshot version is wrong");
- }
-
- @Test
- public void addChangeSetsWithAddedFiles() {
- int configId = 1;
-
- Drift entry1 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a1b2c3", 1024, LOADED), "/drift/1.txt");
- FakeDriftChangeSet changeSet1 = new FakeDriftChangeSet(0, COVERAGE, configId).add(entry1);
-
- Drift entry2 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("4a5b6c", 1024, LOADED), "/drift/2.txt");
- FakeDriftChangeSet changeSet2 = new FakeDriftChangeSet(1, DRIFT, configId).add(entry2);
-
- Snapshot snapshot = new Snapshot().add(changeSet1).add(changeSet2);
-
- assertCollectionMatchesNoOrder(asSet(entry1, entry2), snapshot.getEntries(), "Failed to build snapshot " +
- "with two change sets and file added in second change set");
- assertEquals(snapshot.getVersion(), changeSet2.getVersion(), "Snapshot version is wrong");
- }
-
- @Test
- public void replaceFileWithChangedVersion() {
- int configId = 1;
-
- Drift entry1 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a1b2c3", 1024, LOADED), "/drift/1.txt");
- FakeDriftChangeSet changeSet1 = new FakeDriftChangeSet(0, COVERAGE, configId).add(entry1);
-
- Drift entry2 = new FakeDrift(FILE_CHANGED, new FakeDriftFile("a1b2c3", 1024, LOADED),
- new FakeDriftFile("4d5e6f", 1024, LOADED), "/drift/1.txt");
- FakeDriftChangeSet changeSet2 = new FakeDriftChangeSet(1, DRIFT, configId).add(entry2);
-
- Snapshot snapshot = new Snapshot().add(changeSet1).add(changeSet2);
-
- assertCollectionMatchesNoOrder(asSet(entry2), snapshot.getEntries(), "Failed to build snapshot with file changed");
- }
-
- @Test
- public void deleteFileThatHasBeenRemoved() {
- int configId = 1;
-
- Drift entry1 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a1b2c3", 1024, LOADED), "/drift/1.txt");
- Drift entry2 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("d1f2a3", 1024, LOADED), "/drift/2.txt");
- FakeDriftChangeSet changeSet1 = new FakeDriftChangeSet(0, COVERAGE, configId).add(entry1).add(entry2);
-
- Drift entry3 = new FakeDrift(FILE_REMOVED, new FakeDriftFile("a1b2c3", 1024, LOADED), null, "/drift/1.txt");
- FakeDriftChangeSet changeSet2 = new FakeDriftChangeSet(1, DRIFT, configId).add(entry3);
-
- Snapshot snapshot = new Snapshot().add(changeSet1).add(changeSet2);
-
- assertCollectionMatchesNoOrder(asSet(entry2), snapshot.getEntries(), "Failed to build snapshot with a file " +
- "removed.");
- }
-
- @Test
- public void diffShowsEntriesInLeftAndNotInRight() {
- int configId = 1;
-
- Drift entry1 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a1b2c3", 1024, LOADED), "/drift/1.txt");
- FakeDriftChangeSet changeSet1 = new FakeDriftChangeSet(0, COVERAGE, configId).add(entry1);
- Snapshot right = new Snapshot().add(changeSet1);
-
- Drift entry2 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a3b6c9", 1024, LOADED), "/drift/2.txt");
- FakeDriftChangeSet changeSet2 = new FakeDriftChangeSet(0, COVERAGE, configId).add(entry1).add(entry2);
- Snapshot left = new Snapshot().add(changeSet1).add(changeSet2);
-
- DiffReport diff = left.diff(right);
-
- assertCollectionMatchesNoOrder(asList(entry2), diff.getElementsNotInRight(), "Diff report does not contain " +
- "elements that are in the left but not in the right.");
- }
-
- @Test
- public void diffShowsEntriesInRightAndNotInLeft() {
- int configId = 1;
-
- Drift entry1 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a1b2c3", 1024, LOADED), "/drift/1.txt");
- FakeDriftChangeSet changeSet1 = new FakeDriftChangeSet(0, COVERAGE, configId).add(entry1);
- Snapshot right = new Snapshot().add(changeSet1);
-
- Drift entry2 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a3b6c9", 1024, LOADED), "/drift/2.txt");
- FakeDriftChangeSet changeSet2 = new FakeDriftChangeSet(0, COVERAGE, configId).add(entry2);
- Snapshot left = new Snapshot().add(changeSet2);
-
- DiffReport diff = left.diff(right);
-
- assertCollectionMatchesNoOrder(asList(entry1), diff.getElementsNotInLeft(), "Diff report does not contain " +
- "elements that are in the left but not in the right");
- }
-
- @Test
- public void diffShowsEntriesInLeftAndRightThatAreInConflict() {
- int configId = 1;
-
- Drift entry1 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a1b2c3", 1024, LOADED), "/drfit/1.txt");
- FakeDriftChangeSet changeSet1 = new FakeDriftChangeSet(0, COVERAGE, configId).add(entry1);
- Snapshot right = new Snapshot().add(changeSet1);
-
- Drift entry2 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("c3b2a1", 1024, LOADED), "/drfit/1.txt");
- FakeDriftChangeSet changeSet2 = new FakeDriftChangeSet(1, DRIFT, configId).add(entry2);
- Snapshot left = new Snapshot().add(changeSet2);
-
- DiffReport diff = left.diff(right);
-
- assertCollectionMatchesNoOrder(asList(entry2), diff.getElementsInConflict(), "Diff report does not contain " +
- "element that are in both left and right and are in conflict");
- }
-
- <E> Set<E> asSet(E... elements) {
- HashSet<E> set = new HashSet<E>();
- for (E element : elements) {
- set.add(element);
- }
- return set;
- }
-
- static class FakeDriftChangeSet implements DriftChangeSet {
-
- private String id;
- private int version;
- private DriftChangeSetCategory category;
- private int configId;
- private Set<Drift> drifts = new HashSet<Drift>();
- private long ctime = System.currentTimeMillis();
-
- public FakeDriftChangeSet() {
- }
-
- public FakeDriftChangeSet(int version, DriftChangeSetCategory category, int configId) {
- this.version = version;
- this.category = category;
- this.configId = configId;
- }
-
- @Override
- public String getId() {
- return id;
- }
-
- @Override
- public void setId(String id) {
- this.id = id;
- }
-
- @Override
- public Long getCtime() {
- return ctime;
- }
-
- @Override
- public int getVersion() {
- return version;
- }
-
- @Override
- public void setVersion(int version) {
- this.version = version;
- }
-
- @Override
- public DriftChangeSetCategory getCategory() {
- return category;
- }
-
- @Override
- public void setCategory(DriftChangeSetCategory category) {
- this.category = category;
- }
-
- @Override
- public int getDriftConfigurationId() {
- return configId;
- }
-
- @Override
- public void setDriftConfigurationId(int id) {
- configId = id;
- }
-
- @Override
- public int getResourceId() {
- return 0;
- }
-
- @Override
- public Set getDrifts() {
- return drifts;
- }
-
- @Override
- public void setDrifts(Set drifts) {
- this.drifts = drifts;
- }
-
- public FakeDriftChangeSet add(Drift drift) {
- drifts.add(drift);
- return this;
- }
- }
-
- static class FakeDrift implements Drift {
-
- private String id;
- private DriftCategory category;
- private String path;
- private DriftFile oldFile;
- private DriftFile newFile;
- private long ctime = System.currentTimeMillis();
-
- public FakeDrift() {
- }
-
- public FakeDrift(DriftCategory category, DriftFile oldFile, DriftFile newFile, String path) {
- this.category = category;
- this.oldFile = oldFile;
- this.newFile = newFile;
- this.path = path;
- }
-
- @Override
- public String getId() {
- return id;
- }
-
- @Override
- public void setId(String id) {
- this.id = id;
- }
-
- @Override
- public Long getCtime() {
- return ctime;
- }
-
- @Override
- public DriftChangeSet getChangeSet() {
- return null;
- }
-
- @Override
- public void setChangeSet(DriftChangeSet changeSet) {
-
- }
-
- @Override
- public DriftCategory getCategory() {
- return category;
- }
-
- @Override
- public void setCategory(DriftCategory category) {
- this.category = category;
- }
-
- @Override
- public String getPath() {
- return path;
- }
-
- @Override
- public void setPath(String path) {
- this.path = path;
- }
-
- @Override
- public DriftFile getOldDriftFile() {
- return oldFile;
- }
-
- @Override
- public void setOldDriftFile(DriftFile oldDriftFile) {
- this.oldFile = oldDriftFile;
- }
-
- @Override
- public DriftFile getNewDriftFile() {
- return newFile;
- }
-
- @Override
- public void setNewDriftFile(DriftFile newDriftFile) {
- newFile = newDriftFile;
- }
-
- @Override
- public String toString() {
- return "Drift[category: " + category.code() + ", oldFile: " + oldFile + ", newFile: " + newFile +
- ", path: " + path + "]";
- }
- }
-
- static class FakeDriftFile implements DriftFile {
-
- private String hash;
- private long size;
- private DriftFileStatus status;
- private long ctime = System.currentTimeMillis();
-
- public FakeDriftFile() {
- }
-
- public FakeDriftFile(String hash, long size, DriftFileStatus status) {
- this.hash = hash;
- this.size = size;
- this.status = status;
- }
-
- @Override
- public String getHashId() {
- return hash;
- }
-
- @Override
- public void setHashId(String hashId) {
- hash = hashId;
- }
-
- @Override
- public Long getCtime() {
- return ctime;
- }
-
- @Override
- public Long getDataSize() {
- return size;
- }
-
- @Override
- public void setDataSize(Long size) {
- this.size = size;
- }
-
- @Override
- public DriftFileStatus getStatus() {
- return status;
- }
-
- @Override
- public void setStatus(DriftFileStatus status) {
- this.status = status;
- }
-
- @Override
- public String toString() {
- return "DriftFile[hashId: " + hash + ", dataSize: " + size + ", status: " + status.ordinal() + "]";
- }
- }
-
-}
diff --git a/modules/enterprise/server/plugins/drift-rhq/src/main/java/org/rhq/enterprise/server/plugins/drift/DriftServerPluginComponent.java b/modules/enterprise/server/plugins/drift-rhq/src/main/java/org/rhq/enterprise/server/plugins/drift/DriftServerPluginComponent.java
index 456c4a5..8d4cae4 100644
--- a/modules/enterprise/server/plugins/drift-rhq/src/main/java/org/rhq/enterprise/server/plugins/drift/DriftServerPluginComponent.java
+++ b/modules/enterprise/server/plugins/drift-rhq/src/main/java/org/rhq/enterprise/server/plugins/drift/DriftServerPluginComponent.java
@@ -33,6 +33,7 @@ import org.rhq.core.domain.drift.Drift;
import org.rhq.core.domain.drift.DriftCategory;
import org.rhq.core.domain.drift.DriftChangeSet;
import org.rhq.core.domain.drift.DriftComposite;
+import org.rhq.core.domain.drift.Snapshot;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.drift.DriftManagerLocal;
import org.rhq.enterprise.server.plugin.pc.ServerPluginContext;
@@ -107,6 +108,12 @@ public class DriftServerPluginComponent implements DriftServerPluginFacet {
driftMgr.storeFiles(changeSetFilesZip);
}
+ @Override
+ public Snapshot createSnapshot(Subject subject, DriftChangeSetJPACriteria criteria) {
+ DriftManagerLocal driftMgr = getDriftManager();
+ return driftMgr.createSnapshot(subject, criteria);
+ }
+
private DriftJPACriteria toJPACriteria(DriftCriteria criteria) {
DriftJPACriteria jpaCriteria = new DriftJPACriteria();
jpaCriteria.addFilterId(criteria.getFilterId());
commit e0cdb9af1df636bcf0949da9a7a3eace650f7cb3
Author: John Sanda <jsanda(a)redhat.com>
Date: Sat Jul 23 22:57:09 2011 -0400
First cut at createSnapshot method in DriftManagerBean
Also refactoring tests in server/jar to use the JPAUtils class for
resetting the db.
diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/drift/RhqDriftChangeSetTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/drift/RhqDriftChangeSetTest.java
index c03e3e6..bc8d26a 100644
--- a/modules/core/domain/src/test/java/org/rhq/core/domain/drift/RhqDriftChangeSetTest.java
+++ b/modules/core/domain/src/test/java/org/rhq/core/domain/drift/RhqDriftChangeSetTest.java
@@ -38,24 +38,6 @@ public class RhqDriftChangeSetTest extends AbstractEJB3Test {
resource.setDriftConfigurations(driftConfigs);
-// executeInTransaction(new TransactionCallback() {
-// @Override
-// public void execute() throws Exception {
-// getEntityManager().createQuery("delete from RhqDriftChangeSet").executeUpdate();
-//
-// // Cascading deletes for Resource.driftConfigurations does not work, nor does it
-// // appear the orphan deletes work either. I came across https://hibernate.onjira.com/browse/HHH-1917
-// // and https://hibernate.onjira.com/browse/HHH-1917 which led me to using
-// // native SQL to perform the delete on the join table rhq_drift_config_map.
-// //
-// // jsanda
-// getEntityManager().createNativeQuery("delete from rhq_drift_config_map").executeUpdate();
-//
-// getEntityManager().createQuery("delete from Resource").executeUpdate();
-// getEntityManager().createQuery("delete from ResourceType").executeUpdate();
-// }
-// });
-
executeInTransaction(new TransactionCallback() {
@Override
public void execute() throws Exception {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerBean.java
index 65a6a55..4c669e7 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerBean.java
@@ -581,4 +581,17 @@ public class DriftManagerBean implements DriftManagerLocal, DriftManagerRemote {
throw new IllegalArgumentException("Entity Context Type not supported [" + context + "]");
}
}
+
+ @Override
+ public Snapshot createSnapshot(Subject subject, DriftChangeSetJPACriteria criteria) {
+ // TODO security checks
+ Snapshot snapshot = new Snapshot();
+ PageList<RhqDriftChangeSet> changeSets = findDriftChangeSetsByCriteria(subject, criteria);
+
+ for (RhqDriftChangeSet changeSet : changeSets) {
+ snapshot.add(changeSet);
+ }
+
+ return snapshot;
+ }
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerLocal.java
index 4a30952..0fb077d 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerLocal.java
@@ -177,7 +177,7 @@ public interface DriftManagerLocal extends DriftManagerRemote {
* @return
* @throws Exception
*/
- public RhqDriftFile persistDriftFile(RhqDriftFile driftFile) throws Exception;
+ RhqDriftFile persistDriftFile(RhqDriftFile driftFile) throws Exception;
/**
* SUPPORTS DRIFT RHQ SERVER PLUGIN
@@ -185,6 +185,8 @@ public interface DriftManagerLocal extends DriftManagerRemote {
* @param data
* @throws Exception
*/
- public void persistDriftFileData(RhqDriftFile driftFile, InputStream data) throws Exception;
+ void persistDriftFileData(RhqDriftFile driftFile, InputStream data) throws Exception;
+
+ Snapshot createSnapshot(Subject subject, DriftChangeSetJPACriteria criteria);
}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/metadata/MetadataBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/metadata/MetadataBeanTest.java
index f1934d7..7ffacbf 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/metadata/MetadataBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/metadata/MetadataBeanTest.java
@@ -1,7 +1,5 @@
package org.rhq.enterprise.server.resource.metadata;
-import static org.rhq.core.clientapi.shared.PluginDescriptorUtil.loadPluginDescriptor;
-
import java.io.File;
import java.net.URL;
import java.sql.Connection;
@@ -39,10 +37,17 @@ import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal;
import org.rhq.enterprise.server.test.AbstractEJB3Test;
import org.rhq.enterprise.server.util.LookupUtil;
+import static org.rhq.core.clientapi.shared.PluginDescriptorUtil.loadPluginDescriptor;
+
public class MetadataBeanTest extends AbstractEJB3Test {
private static List<String> plugins = new ArrayList<String>();
+ @Override
+ protected boolean isDBResetNeeded() {
+ return false;
+ }
+
@BeforeGroups(groups = { "plugin.metadata" }, dependsOnGroups = { "integration.ejb3" })
public void startMBeanServer() throws Exception {
setupDB();
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/AbstractEJB3Test.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/AbstractEJB3Test.java
index ee2a45f..5ed329f 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/AbstractEJB3Test.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/AbstractEJB3Test.java
@@ -28,7 +28,6 @@ import javax.management.MBeanServerFactory;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
import javax.transaction.TransactionManager;
import org.hibernate.SessionFactory;
@@ -36,6 +35,7 @@ import org.hibernate.stat.Statistics;
import org.testng.AssertJUnit;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterSuite;
+import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeSuite;
@@ -57,12 +57,28 @@ import org.rhq.enterprise.server.scheduler.SchedulerService;
import org.rhq.enterprise.server.scheduler.SchedulerServiceMBean;
import org.rhq.enterprise.server.util.LookupUtil;
+import static org.rhq.test.JPAUtils.clearDB;
+import static org.rhq.test.JPAUtils.lookupEntityManager;
+import static org.rhq.test.JPAUtils.lookupTransactionManager;
+
/**
* This is the abstract test base for server jar tests.
*
* @author Greg Hinkle
*/
public abstract class AbstractEJB3Test extends AssertJUnit {
+
+ @BeforeClass
+ public void resetDB() throws Exception {
+ if (isDBResetNeeded()) {
+ clearDB();
+ }
+ }
+
+ protected boolean isDBResetNeeded() {
+ return true;
+ }
+
//@BeforeSuite(groups = {"integration.ejb3","PERF"}) // TODO investigate again
@BeforeSuite(alwaysRun = true)
public static void startupEmbeddedJboss() throws Exception {
@@ -165,23 +181,11 @@ public abstract class AbstractEJB3Test extends AssertJUnit {
private static Statistics stats;
public TransactionManager getTransactionManager() {
- try {
- tm = (TransactionManager) getInitialContext().lookup("java:/TransactionManager");
- return tm;
- } catch (NamingException e) {
- e.printStackTrace();
- throw new RuntimeException("Failed to load transaction manager", e);
- }
+ return lookupTransactionManager();
}
public static EntityManager getEntityManager() {
- try {
- return ((EntityManagerFactory) getInitialContext().lookup(RHQConstants.ENTITY_MANAGER_JNDI_NAME))
- .createEntityManager();
- } catch (NamingException e) {
- e.printStackTrace();
- throw new RuntimeException("Failed to load entity manager", e);
- }
+ return lookupEntityManager();
}
public static InitialContext getInitialContext() {
commit 20105a1abca72db2ef548f9b0a0e6a097a73024e
Author: John Sanda <jsanda(a)redhat.com>
Date: Sat Jul 23 21:38:07 2011 -0400
Initial commit for JPAUtils
Refactoring some methods in AbstractEJB3Test to delegate to JPAUtils
with the intent to eliminate duplicate code in core/domain and
server/jar tests. Most importantly though, the method clearDB is now
part of JPAUtils making it accessible to any test. This provides a much
more robust way of resetting the entire database to a known, consistent
state.
diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/drift/RhqDriftChangeSetTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/drift/RhqDriftChangeSetTest.java
index c9e61ef..c03e3e6 100644
--- a/modules/core/domain/src/test/java/org/rhq/core/domain/drift/RhqDriftChangeSetTest.java
+++ b/modules/core/domain/src/test/java/org/rhq/core/domain/drift/RhqDriftChangeSetTest.java
@@ -3,10 +3,6 @@ package org.rhq.core.domain.drift;
import java.util.HashSet;
import java.util.Set;
-import javax.persistence.EntityManager;
-import javax.transaction.SystemException;
-
-import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@@ -16,6 +12,7 @@ import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.shared.ResourceBuilder;
import org.rhq.core.domain.test.AbstractEJB3Test;
+import org.rhq.test.TransactionCallback;
import static org.rhq.core.domain.drift.DriftChangeSetCategory.COVERAGE;
diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/test/AbstractEJB3Test.java b/modules/core/domain/src/test/java/org/rhq/core/domain/test/AbstractEJB3Test.java
index aa6e0e0..dc5319a 100644
--- a/modules/core/domain/src/test/java/org/rhq/core/domain/test/AbstractEJB3Test.java
+++ b/modules/core/domain/src/test/java/org/rhq/core/domain/test/AbstractEJB3Test.java
@@ -30,8 +30,6 @@ import java.util.Hashtable;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import javax.transaction.SystemException;
import javax.transaction.TransactionManager;
import org.testng.AssertJUnit;
@@ -42,6 +40,13 @@ import org.testng.annotations.BeforeSuite;
import org.jboss.ejb3.embedded.EJB3StandaloneBootstrap;
import org.jboss.ejb3.embedded.EJB3StandaloneDeployer;
+import org.rhq.test.JPAUtils;
+import org.rhq.test.TransactionCallback;
+
+import static org.rhq.test.JPAUtils.clearDB;
+import static org.rhq.test.JPAUtils.lookupEntityManager;
+import static org.rhq.test.JPAUtils.lookupTransactionManager;
+
public abstract class AbstractEJB3Test extends AssertJUnit {
@BeforeClass
@@ -96,26 +101,12 @@ public abstract class AbstractEJB3Test extends AssertJUnit {
EJB3StandaloneBootstrap.shutdown();
}
- private TransactionManager tm;
-
public TransactionManager getTransactionManager() {
- try {
- tm = (TransactionManager) getInitialContext().lookup("java:/TransactionManager");
- return tm;
- } catch (NamingException e) {
- e.printStackTrace();
- throw new RuntimeException("Failed to load transaction manager", e);
- }
+ return lookupTransactionManager();
}
public EntityManager getEntityManager() {
- try {
- return ((EntityManagerFactory) getInitialContext().lookup("java:/RHQEntityManagerFactory"))
- .createEntityManager();
- } catch (NamingException e) {
- e.printStackTrace();
- throw new RuntimeException("Failed to load entity manager", e);
- }
+ return lookupEntityManager();
}
public boolean isPostgres(EntityManager em) throws Exception {
@@ -148,171 +139,7 @@ public abstract class AbstractEJB3Test extends AssertJUnit {
}
protected void executeInTransaction(TransactionCallback callback) {
- try {
- getTransactionManager().begin();
- callback.execute();
- getTransactionManager().commit();
- } catch (Throwable t) {
- try {
- getTransactionManager().rollback();
- } catch (SystemException e) {
- throw new RuntimeException("Failed to rollback transaction", e);
- }
- throw new RuntimeException(t.getCause());
- }
+ JPAUtils.executeInTransaction(callback);
}
- void clearDB() throws Exception {
- executeInTransaction(new TransactionCallback() {
- @Override
- public void execute() throws Exception {
- EntityManager em = getEntityManager();
-
- em.createNativeQuery("delete from jms_subscriptions");
- em.createNativeQuery("delete from jms_roles");
- em.createNativeQuery("delete from jms_users");
- em.createNativeQuery("delete from jms_transactions");
- em.createNativeQuery("delete from jms_messages");
- em.createNativeQuery("delete from rhq_drift_config_map");
- em.createNativeQuery("delete from rhq_drift_template_map");
- em.createNativeQuery("delete from rhq_delete_res_hist");
- em.createNativeQuery("delete from rhq_create_res_hist");
- em.createNativeQuery("delete from rhq_tagging_bundle_dest_map");
- em.createNativeQuery("delete from rhq_tagging_bundle_deploy_map");
- em.createNativeQuery("delete from rhq_tagging_bundle_version_map");
- em.createNativeQuery("delete from rhq_tagging_bundle_map");
- em.createNativeQuery("delete from rhq_bundle_res_dep_hist");
- em.createNativeQuery("delete from rhq_bundle_res_deploy");
- em.createNativeQuery("delete from rhq_bundle_deployment");
- em.createNativeQuery("delete from rhq_bundle_destination");
- em.createNativeQuery("delete from rhq_bundle_file");
- em.createNativeQuery("delete from rhq_bundle_version_repo");
- em.createNativeQuery("delete from rhq_bundle_version");
- em.createNativeQuery("delete from rhq_bundle");
- em.createNativeQuery("delete from rhq_bundle_type");
- em.createNativeQuery("delete from rhq_repo_advisory");
- em.createNativeQuery("delete from rhq_advisory_buglist");
- em.createNativeQuery("delete from rhq_advisory_cve");
- em.createNativeQuery("delete from rhq_cve");
- em.createNativeQuery("delete from rhq_advisory_package");
- em.createNativeQuery("delete from rhq_advisory");
- em.createNativeQuery("delete from rhq_distribution_file");
- em.createNativeQuery("delete from rhq_repo_distribution");
- em.createNativeQuery("delete from rhq_distribution where id not in (1, 2)");
- em.createNativeQuery("delete from rhq_pkg_prd_map");
- em.createNativeQuery("delete from rhq_pkg_ver_content_src_map");
- em.createNativeQuery("delete from rhq_repo_pkg_version_map");
- em.createNativeQuery("delete from rhq_repo_repo_relation_map");
- em.createNativeQuery("delete from rhq_repo_repo_group_map");
- em.createNativeQuery("delete from rhq_repo_content_src_map");
- em.createNativeQuery("delete from rhq_repo_resource_map");
- em.createNativeQuery("delete from rhq_package_inst_step");
- em.createNativeQuery("delete from rhq_repo_sync");
- em.createNativeQuery("delete from rhq_content_src_sync");
- em.createNativeQuery("delete from rhq_installed_pkg_hist");
- em.createNativeQuery("delete from rhq_installed_package");
- em.createNativeQuery("delete from rhq_content_req");
- em.createNativeQuery("delete from rhq_package_version");
- em.createNativeQuery("delete from rhq_package_bits");
- em.createNativeQuery("delete from rhq_package");
- em.createNativeQuery("delete from rhq_package_type");
- em.createNativeQuery("delete from rhq_repo_relation");
- em.createNativeQuery("delete from rhq_repo_relation_type where id not in (1, 2)");
- em.createNativeQuery("delete from rhq_repo");
- em.createNativeQuery("delete from rhq_repo_group");
- em.createNativeQuery("delete from rhq_repo_group_type where id <> 1");
- em.createNativeQuery("delete from rhq_archirtecture where id < 1 and id > 38");
- em.createNativeQuery("delete from rhq_meas_data_num_r14");
- em.createNativeQuery("delete from rhq_meas_data_num_r13");
- em.createNativeQuery("delete from rhq_meas_data_num_r12");
- em.createNativeQuery("delete from rhq_meas_data_num_r11");
- em.createNativeQuery("delete from rhq_meas_data_num_r10");
- em.createNativeQuery("delete from rhq_meas_data_num_r09");
- em.createNativeQuery("delete from rhq_meas_data_num_r08");
- em.createNativeQuery("delete from rhq_meas_data_num_r07");
- em.createNativeQuery("delete from rhq_meas_data_num_r06");
- em.createNativeQuery("delete from rhq_meas_data_num_r05");
- em.createNativeQuery("delete from rhq_meas_data_num_r04");
- em.createNativeQuery("delete from rhq_meas_data_num_r03");
- em.createNativeQuery("delete from rhq_meas_data_num_r02");
- em.createNativeQuery("delete from rhq_meas_data_num_r01");
- em.createNativeQuery("delete from rhq_meas_data_num_r00");
- em.createNativeQuery("delete from rhq_measurement_oob_tmp");
- em.createNativeQuery("delete rhq_measurement_oob");
- em.createNativeQuery("delete rhq_resource_avail");
- em.createNativeQuery("delete from rhq_availability");
- em.createNativeQuery("delete from rhq_calltime_data_value");
- em.createNativeQuery("delete from rhq_calltime_data_key");
- em.createNativeQuery("delete from rhq_measurement_data_trait");
- em.createNativeQuery("delete from rhq_measurement_data_num_1d");
- em.createNativeQuery("delete from rhq_measurement_data_num_6h");
- em.createNativeQuery("delete from rhq_measurement_data_num_1h");
- em.createNativeQuery("delete from rhq_measurement_bline");
- em.createNativeQuery("delete from rhq_measurement_sched");
- em.createNativeQuery("delete from rhq_measurement_def");
- em.createNativeQuery("delete from rhq_plugin");
- em.createNativeQuery("delete from rhq_system_config where id not in (1, 2, 3, 4, 9, 10, 32, 34, 35, 36, 51, 52, 53, 54, 55, 56)");
- em.createNativeQuery("delete from rhq_alert_notification");
- em.createNativeQuery("delete from rhq_alert_condition_log");
- em.createNativeQuery("delete from rhq_alert");
- em.createNativeQuery("delete from rhq_alert_condition");
- em.createNativeQuery("delete from rhq_alert_dampen_event");
- em.createNativeQuery("delete from rhq_alert_definition");
- em.createNativeQuery("delete from rhq_event");
- em.createNativeQuery("delete from rhq_event_source");
- em.createNativeQuery("delete from rhq_event_def");
- em.createNativeQuery("delete from rhq_operation_schedule");
- em.createNativeQuery("delete from rhq_operation_history");
- em.createNativeQuery("delete from rhq_operation_def");
- em.createNativeQuery("delete from rhq_dashboard_portlet");
- em.createNativeQuery("delete from rhq_dashboard");
- em.createNativeQuery("delete from rhq_saved_search");
- em.createNativeQuery("delete from rhq_subject_role_ldap_map");
- em.createNativeQuery("delete from rhq_subject_role_map where id not in (1, 2)");
- em.createNativeQuery("delete from rhq_permission where role_id not in (1, 2)");
- em.createNativeQuery("delete from rhq_role_ldap_group");
- em.createNativeQuery("delete from rhq_role_resource_group_map");
- em.createNativeQuery("delete from rhq_role where id not in (1, 2)");
- em.createNativeQuery("delete from rhq_tagging_res_group_map");
- em.createNativeQuery("delete from rhq_tagging_resource_map");
- em.createNativeQuery("delete from rhq_tagging");
- em.createNativeQuery("delete from rhq_config_update");
- em.createNativeQuery("delete from rhq_config_group_update");
- em.createNativeQuery("delete from rhq_resource_group_res_exp_map");
- em.createNativeQuery("delete from rhq_resource_group_res_imp_map");
- em.createNativeQuery("delete from rhq_resource_group");
- em.createNativeQuery("delete from rhq_group_def");
- em.createNativeQuery("delete from rhq_resource_error");
- em.createNativeQuery("delete from rhq_resource");
- em.createNativeQuery("delete from rhq_prd_ver");
- em.createNativeQuery("delete from rhq_process_scan");
- em.createNativeQuery("delete from rhq_resource_type_parents");
- em.createNativeQuery("delete from rhq_resource_subcat");
- em.createNativeQuery("delete from rhq_resource_type");
- em.createNativeQuery("delete from rhq_subject where id not in (1, 2)");
- em.createNativeQuery("delete from rhq_principal where id <> 2");
- em.createNativeQuery("delete from rhq_failover_details");
- em.createNativeQuery("delete from rhq_failover_list");
- em.createNativeQuery("delete from rhq_partition_details");
- em.createNativeQuery("delete from rhq_partition_event");
- em.createNativeQuery("delete from rhq_agent");
- em.createNativeQuery("delete from rhq_server");
- em.createNativeQuery("delete from rhq_affinity_group");
- em.createNativeQuery("delete from rhq_raw_config");
- em.createNativeQuery("delete from rhq_config_template");
- em.createNativeQuery("delete from rhq_config_property");
- em.createNativeQuery("delete from rhq_config");
- em.createNativeQuery("delete from rhq_config_prop_constr");
- em.createNativeQuery("delete from rhq_conf_prop_def_enum");
- em.createNativeQuery("delete from rhq_config_pd_osrc");
- em.createNativeQuery("delete from rhq_config_prop_def");
- em.createNativeQuery("delete from rhq_config_prop_grp_def");
- em.createNativeQuery("delete from rhq_config_def");
- }
- });
- }
-
- public static interface TransactionCallback {
- void execute() throws Exception;
- }
}
\ No newline at end of file
diff --git a/modules/test-utils/pom.xml b/modules/test-utils/pom.xml
index 3ed6856..5c6e85c 100644
--- a/modules/test-utils/pom.xml
+++ b/modules/test-utils/pom.xml
@@ -15,6 +15,16 @@
<dependencies>
<dependency>
+ <groupId>javax.persistence</groupId>
+ <artifactId>persistence-api</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.transaction</groupId>
+ <artifactId>jta</artifactId>
+ <version>1.1</version>
+ </dependency>
+ <dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>${testng.version}</version>
diff --git a/modules/test-utils/src/main/java/org/rhq/test/JPAUtils.java b/modules/test-utils/src/main/java/org/rhq/test/JPAUtils.java
new file mode 100644
index 0000000..349b84c
--- /dev/null
+++ b/modules/test-utils/src/main/java/org/rhq/test/JPAUtils.java
@@ -0,0 +1,207 @@
+package org.rhq.test;
+
+import java.util.Hashtable;
+
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.transaction.SystemException;
+import javax.transaction.TransactionManager;
+
+public class JPAUtils {
+
+ public static InitialContext getInitialContext() {
+ Hashtable<String, String> env = new Hashtable<String, String>();
+ env.put("java.naming.factory.initial", "org.jnp.interfaces.LocalOnlyContextFactory");
+ env.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
+ try {
+ return new InitialContext(env);
+ } catch (NamingException e) {
+ throw new RuntimeException("Failed to load initial context", e);
+ }
+ }
+
+ public static EntityManager lookupEntityManager() {
+ try {
+ return ((EntityManagerFactory) getInitialContext().lookup("java:/RHQEntityManagerFactory"))
+ .createEntityManager();
+ } catch (NamingException e) {
+ throw new RuntimeException("Failed to load entity manager", e);
+ }
+ }
+
+ public static TransactionManager lookupTransactionManager() {
+ try {
+ return (TransactionManager) getInitialContext().lookup("java:/TransactionManager");
+ } catch (NamingException e) {
+ throw new RuntimeException("Failed to load transaction manager", e);
+ }
+ }
+
+ public static void executeInTransaction(TransactionCallback callback) {
+ try {
+ lookupTransactionManager().begin();
+ callback.execute();
+ lookupTransactionManager().commit();
+ } catch (Throwable t) {
+ try {
+ lookupTransactionManager().rollback();
+ } catch (SystemException e) {
+ throw new RuntimeException("Failed to rollback transaction", e);
+ }
+ throw new RuntimeException(t.getCause());
+ }
+ }
+
+ public static void clearDB() {
+ executeInTransaction(new TransactionCallback() {
+ @Override
+ public void execute() throws Exception {
+ EntityManager em = lookupEntityManager();
+
+ em.createNativeQuery("delete from jms_subscriptions");
+ em.createNativeQuery("delete from jms_roles");
+ em.createNativeQuery("delete from jms_users");
+ em.createNativeQuery("delete from jms_transactions");
+ em.createNativeQuery("delete from jms_messages");
+ em.createNativeQuery("delete from rhq_drift_config_map");
+ em.createNativeQuery("delete from rhq_drift_template_map");
+ em.createNativeQuery("delete from rhq_delete_res_hist");
+ em.createNativeQuery("delete from rhq_create_res_hist");
+ em.createNativeQuery("delete from rhq_tagging_bundle_dest_map");
+ em.createNativeQuery("delete from rhq_tagging_bundle_deploy_map");
+ em.createNativeQuery("delete from rhq_tagging_bundle_version_map");
+ em.createNativeQuery("delete from rhq_tagging_bundle_map");
+ em.createNativeQuery("delete from rhq_bundle_res_dep_hist");
+ em.createNativeQuery("delete from rhq_bundle_res_deploy");
+ em.createNativeQuery("delete from rhq_bundle_deployment");
+ em.createNativeQuery("delete from rhq_bundle_destination");
+ em.createNativeQuery("delete from rhq_bundle_file");
+ em.createNativeQuery("delete from rhq_bundle_version_repo");
+ em.createNativeQuery("delete from rhq_bundle_version");
+ em.createNativeQuery("delete from rhq_bundle");
+ em.createNativeQuery("delete from rhq_bundle_type");
+ em.createNativeQuery("delete from rhq_repo_advisory");
+ em.createNativeQuery("delete from rhq_advisory_buglist");
+ em.createNativeQuery("delete from rhq_advisory_cve");
+ em.createNativeQuery("delete from rhq_cve");
+ em.createNativeQuery("delete from rhq_advisory_package");
+ em.createNativeQuery("delete from rhq_advisory");
+ em.createNativeQuery("delete from rhq_distribution_file");
+ em.createNativeQuery("delete from rhq_repo_distribution");
+ em.createNativeQuery("delete from rhq_distribution where id not in (1, 2)");
+ em.createNativeQuery("delete from rhq_pkg_prd_map");
+ em.createNativeQuery("delete from rhq_pkg_ver_content_src_map");
+ em.createNativeQuery("delete from rhq_repo_pkg_version_map");
+ em.createNativeQuery("delete from rhq_repo_repo_relation_map");
+ em.createNativeQuery("delete from rhq_repo_repo_group_map");
+ em.createNativeQuery("delete from rhq_repo_content_src_map");
+ em.createNativeQuery("delete from rhq_repo_resource_map");
+ em.createNativeQuery("delete from rhq_package_inst_step");
+ em.createNativeQuery("delete from rhq_repo_sync");
+ em.createNativeQuery("delete from rhq_content_src_sync");
+ em.createNativeQuery("delete from rhq_installed_pkg_hist");
+ em.createNativeQuery("delete from rhq_installed_package");
+ em.createNativeQuery("delete from rhq_content_req");
+ em.createNativeQuery("delete from rhq_package_version");
+ em.createNativeQuery("delete from rhq_package_bits");
+ em.createNativeQuery("delete from rhq_package");
+ em.createNativeQuery("delete from rhq_package_type");
+ em.createNativeQuery("delete from rhq_repo_relation");
+ em.createNativeQuery("delete from rhq_repo_relation_type where id not in (1, 2)");
+ em.createNativeQuery("delete from rhq_repo");
+ em.createNativeQuery("delete from rhq_repo_group");
+ em.createNativeQuery("delete from rhq_repo_group_type where id <> 1");
+ em.createNativeQuery("delete from rhq_archirtecture where id < 1 and id > 38");
+ em.createNativeQuery("delete from rhq_meas_data_num_r14");
+ em.createNativeQuery("delete from rhq_meas_data_num_r13");
+ em.createNativeQuery("delete from rhq_meas_data_num_r12");
+ em.createNativeQuery("delete from rhq_meas_data_num_r11");
+ em.createNativeQuery("delete from rhq_meas_data_num_r10");
+ em.createNativeQuery("delete from rhq_meas_data_num_r09");
+ em.createNativeQuery("delete from rhq_meas_data_num_r08");
+ em.createNativeQuery("delete from rhq_meas_data_num_r07");
+ em.createNativeQuery("delete from rhq_meas_data_num_r06");
+ em.createNativeQuery("delete from rhq_meas_data_num_r05");
+ em.createNativeQuery("delete from rhq_meas_data_num_r04");
+ em.createNativeQuery("delete from rhq_meas_data_num_r03");
+ em.createNativeQuery("delete from rhq_meas_data_num_r02");
+ em.createNativeQuery("delete from rhq_meas_data_num_r01");
+ em.createNativeQuery("delete from rhq_meas_data_num_r00");
+ em.createNativeQuery("delete from rhq_measurement_oob_tmp");
+ em.createNativeQuery("delete rhq_measurement_oob");
+ em.createNativeQuery("delete rhq_resource_avail");
+ em.createNativeQuery("delete from rhq_availability");
+ em.createNativeQuery("delete from rhq_calltime_data_value");
+ em.createNativeQuery("delete from rhq_calltime_data_key");
+ em.createNativeQuery("delete from rhq_measurement_data_trait");
+ em.createNativeQuery("delete from rhq_measurement_data_num_1d");
+ em.createNativeQuery("delete from rhq_measurement_data_num_6h");
+ em.createNativeQuery("delete from rhq_measurement_data_num_1h");
+ em.createNativeQuery("delete from rhq_measurement_bline");
+ em.createNativeQuery("delete from rhq_measurement_sched");
+ em.createNativeQuery("delete from rhq_measurement_def");
+ em.createNativeQuery("delete from rhq_plugin");
+ em.createNativeQuery("delete from rhq_system_config where id not in (1, 2, 3, 4, 9, 10, 32, 34, 35, 36, 51, 52, 53, 54, 55, 56)");
+ em.createNativeQuery("delete from rhq_alert_notification");
+ em.createNativeQuery("delete from rhq_alert_condition_log");
+ em.createNativeQuery("delete from rhq_alert");
+ em.createNativeQuery("delete from rhq_alert_condition");
+ em.createNativeQuery("delete from rhq_alert_dampen_event");
+ em.createNativeQuery("delete from rhq_alert_definition");
+ em.createNativeQuery("delete from rhq_event");
+ em.createNativeQuery("delete from rhq_event_source");
+ em.createNativeQuery("delete from rhq_event_def");
+ em.createNativeQuery("delete from rhq_operation_schedule");
+ em.createNativeQuery("delete from rhq_operation_history");
+ em.createNativeQuery("delete from rhq_operation_def");
+ em.createNativeQuery("delete from rhq_dashboard_portlet");
+ em.createNativeQuery("delete from rhq_dashboard");
+ em.createNativeQuery("delete from rhq_saved_search");
+ em.createNativeQuery("delete from rhq_subject_role_ldap_map");
+ em.createNativeQuery("delete from rhq_subject_role_map where id not in (1, 2)");
+ em.createNativeQuery("delete from rhq_permission where role_id not in (1, 2)");
+ em.createNativeQuery("delete from rhq_role_ldap_group");
+ em.createNativeQuery("delete from rhq_role_resource_group_map");
+ em.createNativeQuery("delete from rhq_role where id not in (1, 2)");
+ em.createNativeQuery("delete from rhq_tagging_res_group_map");
+ em.createNativeQuery("delete from rhq_tagging_resource_map");
+ em.createNativeQuery("delete from rhq_tagging");
+ em.createNativeQuery("delete from rhq_config_update");
+ em.createNativeQuery("delete from rhq_config_group_update");
+ em.createNativeQuery("delete from rhq_resource_group_res_exp_map");
+ em.createNativeQuery("delete from rhq_resource_group_res_imp_map");
+ em.createNativeQuery("delete from rhq_resource_group");
+ em.createNativeQuery("delete from rhq_group_def");
+ em.createNativeQuery("delete from rhq_resource_error");
+ em.createNativeQuery("delete from rhq_resource");
+ em.createNativeQuery("delete from rhq_prd_ver");
+ em.createNativeQuery("delete from rhq_process_scan");
+ em.createNativeQuery("delete from rhq_resource_type_parents");
+ em.createNativeQuery("delete from rhq_resource_subcat");
+ em.createNativeQuery("delete from rhq_resource_type");
+ em.createNativeQuery("delete from rhq_subject where id not in (1, 2)");
+ em.createNativeQuery("delete from rhq_principal where id <> 2");
+ em.createNativeQuery("delete from rhq_failover_details");
+ em.createNativeQuery("delete from rhq_failover_list");
+ em.createNativeQuery("delete from rhq_partition_details");
+ em.createNativeQuery("delete from rhq_partition_event");
+ em.createNativeQuery("delete from rhq_agent");
+ em.createNativeQuery("delete from rhq_server");
+ em.createNativeQuery("delete from rhq_affinity_group");
+ em.createNativeQuery("delete from rhq_raw_config");
+ em.createNativeQuery("delete from rhq_config_template");
+ em.createNativeQuery("delete from rhq_config_property");
+ em.createNativeQuery("delete from rhq_config");
+ em.createNativeQuery("delete from rhq_config_prop_constr");
+ em.createNativeQuery("delete from rhq_conf_prop_def_enum");
+ em.createNativeQuery("delete from rhq_config_pd_osrc");
+ em.createNativeQuery("delete from rhq_config_prop_def");
+ em.createNativeQuery("delete from rhq_config_prop_grp_def");
+ em.createNativeQuery("delete from rhq_config_def");
+ }
+ });
+ }
+
+}
diff --git a/modules/test-utils/src/main/java/org/rhq/test/TransactionCallback.java b/modules/test-utils/src/main/java/org/rhq/test/TransactionCallback.java
new file mode 100644
index 0000000..711df43
--- /dev/null
+++ b/modules/test-utils/src/main/java/org/rhq/test/TransactionCallback.java
@@ -0,0 +1,7 @@
+package org.rhq.test;
+
+public interface TransactionCallback {
+
+ void execute() throws Exception;
+
+}
commit b8cf92971d297313e8853a73aa537fddf6742e57
Author: John Sanda <jsanda(a)redhat.com>
Date: Sat Jul 23 07:09:35 2011 -0400
Adding support for version and date ranges in DriftChangeSetCriteria
Version and/or date ranges are needed in order to fetch multiple change
sets to build a snapshot. This commit also includes new set up code in
the base test class AbstractEJB3Test. It clears all database tables
which should be more robust than the approach taken with dbunit.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/DriftChangeSetCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/DriftChangeSetCriteria.java
index 6ba63df..1b3effc 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/DriftChangeSetCriteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/DriftChangeSetCriteria.java
@@ -15,6 +15,22 @@ public interface DriftChangeSetCriteria extends Serializable {
String getFilterVersion();
+ void addFilterStartVersion(String filterStartVersion);
+
+ String getFilterStartVersion();
+
+ void addFilterEndVersion(String filterEndVersion);
+
+ String getFilterEndVersion();
+
+ void addFilterCreatedAfter(Long filterCreatedAfter);
+
+ Long getFilterCreatedAfter();
+
+ void addFilterCreatedBefore(Long filterCreatedBefore);
+
+ Long getFilterCreatedBefore();
+
void addFilterResourceId(Integer filterResourceId);
Integer getFilterResourceId();
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/DriftChangeSetJPACriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/DriftChangeSetJPACriteria.java
index 9b39cc3..6c17877 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/DriftChangeSetJPACriteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/DriftChangeSetJPACriteria.java
@@ -40,6 +40,10 @@ public class DriftChangeSetJPACriteria extends Criteria implements DriftChangeSe
private Integer filterInitial; // needs override
private Integer filterResourceId; // needs override
private String filterVersion;
+ private String filterStartVersion;
+ private String filterEndVersion;
+ private Long filterCreatedAfter;
+ private Long filterCreatedBefore;
private DriftChangeSetCategory filterCategory;
private boolean fetchDrifts;
@@ -48,6 +52,10 @@ public class DriftChangeSetJPACriteria extends Criteria implements DriftChangeSe
public DriftChangeSetJPACriteria() {
filterOverrides.put("initial", "version = 0");
filterOverrides.put("resourceId", "resource.id = ?");
+ filterOverrides.put("filterStartVersion", "version >= ?");
+ filterOverrides.put("filterEndVersion", "version <= ?");
+ filterOverrides.put("filterCreatedAfter", "ctime >= ?");
+ filterOverrides.put("filterCreatedBefore", "ctime <= ?");
}
@Override
@@ -75,6 +83,46 @@ public class DriftChangeSetJPACriteria extends Criteria implements DriftChangeSe
return filterVersion;
}
+ @Override
+ public void addFilterStartVersion(String filterStartVersion) {
+ this.filterStartVersion = filterStartVersion;
+ }
+
+ @Override
+ public String getFilterStartVersion() {
+ return filterStartVersion;
+ }
+
+ @Override
+ public void addFilterEndVersion(String filterEndVersion) {
+ this.filterEndVersion = filterEndVersion;
+ }
+
+ @Override
+ public String getFilterEndVersion() {
+ return filterEndVersion;
+ }
+
+ @Override
+ public void addFilterCreatedAfter(Long filterCreatedAfter) {
+ this.filterCreatedAfter = filterCreatedAfter;
+ }
+
+ @Override
+ public Long getFilterCreatedAfter() {
+ return filterCreatedAfter;
+ }
+
+ @Override
+ public void addFilterCreatedBefore(Long filterCreatedBefore) {
+ this.filterCreatedBefore = filterCreatedBefore;
+ }
+
+ @Override
+ public Long getFilterCreatedBefore() {
+ return filterCreatedBefore;
+ }
+
public void addFilterResourceId(Integer filterResourceId) {
this.filterResourceId = filterResourceId;
}
diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/drift/RhqDriftChangeSetTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/drift/RhqDriftChangeSetTest.java
index abc300d..c9e61ef 100644
--- a/modules/core/domain/src/test/java/org/rhq/core/domain/drift/RhqDriftChangeSetTest.java
+++ b/modules/core/domain/src/test/java/org/rhq/core/domain/drift/RhqDriftChangeSetTest.java
@@ -1,11 +1,12 @@
package org.rhq.core.domain.drift;
import java.util.HashSet;
-import java.util.List;
import java.util.Set;
+import javax.persistence.EntityManager;
import javax.transaction.SystemException;
+import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@@ -20,10 +21,6 @@ import static org.rhq.core.domain.drift.DriftChangeSetCategory.COVERAGE;
public class RhqDriftChangeSetTest extends AbstractEJB3Test {
- static interface TransactionCallback {
- void execute() throws Exception;
- }
-
Resource resource;
DriftConfiguration driftConfig;
@@ -44,23 +41,23 @@ public class RhqDriftChangeSetTest extends AbstractEJB3Test {
resource.setDriftConfigurations(driftConfigs);
- executeInTransaction(new TransactionCallback() {
- @Override
- public void execute() throws Exception {
- getEntityManager().createQuery("delete from RhqDriftChangeSet").executeUpdate();
-
- // Cascading deletes for Resource.driftConfigurations does not work, nor does it
- // appear the orphan deletes work either. I came across https://hibernate.onjira.com/browse/HHH-1917
- // and https://hibernate.onjira.com/browse/HHH-1917 which led me to using
- // native SQL to perform the delete on the join table rhq_drift_config_map.
- //
- // jsanda
- getEntityManager().createNativeQuery("delete from rhq_drift_config_map").executeUpdate();
-
- getEntityManager().createQuery("delete from Resource").executeUpdate();
- getEntityManager().createQuery("delete from ResourceType").executeUpdate();
- }
- });
+// executeInTransaction(new TransactionCallback() {
+// @Override
+// public void execute() throws Exception {
+// getEntityManager().createQuery("delete from RhqDriftChangeSet").executeUpdate();
+//
+// // Cascading deletes for Resource.driftConfigurations does not work, nor does it
+// // appear the orphan deletes work either. I came across https://hibernate.onjira.com/browse/HHH-1917
+// // and https://hibernate.onjira.com/browse/HHH-1917 which led me to using
+// // native SQL to perform the delete on the join table rhq_drift_config_map.
+// //
+// // jsanda
+// getEntityManager().createNativeQuery("delete from rhq_drift_config_map").executeUpdate();
+//
+// getEntityManager().createQuery("delete from Resource").executeUpdate();
+// getEntityManager().createQuery("delete from ResourceType").executeUpdate();
+// }
+// });
executeInTransaction(new TransactionCallback() {
@Override
@@ -115,19 +112,4 @@ public class RhqDriftChangeSetTest extends AbstractEJB3Test {
});
}
- void executeInTransaction(TransactionCallback callback) {
- try {
- getTransactionManager().begin();
- callback.execute();
- getTransactionManager().commit();
- } catch (Throwable t) {
- try {
- getTransactionManager().rollback();
- } catch (SystemException e) {
- throw new RuntimeException("Failed to rollback transaction", e);
- }
- throw new RuntimeException(t.getCause());
- }
- }
-
}
diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/test/AbstractEJB3Test.java b/modules/core/domain/src/test/java/org/rhq/core/domain/test/AbstractEJB3Test.java
index 57ec318..aa6e0e0 100644
--- a/modules/core/domain/src/test/java/org/rhq/core/domain/test/AbstractEJB3Test.java
+++ b/modules/core/domain/src/test/java/org/rhq/core/domain/test/AbstractEJB3Test.java
@@ -31,20 +31,26 @@ import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
+import javax.transaction.SystemException;
import javax.transaction.TransactionManager;
import org.testng.AssertJUnit;
import org.testng.annotations.AfterGroups;
-import org.testng.annotations.AfterSuite;
-import org.testng.annotations.BeforeGroups;
+import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeSuite;
import org.jboss.ejb3.embedded.EJB3StandaloneBootstrap;
import org.jboss.ejb3.embedded.EJB3StandaloneDeployer;
public abstract class AbstractEJB3Test extends AssertJUnit {
-// @BeforeSuite(groups = "integration.ejb3")
- @BeforeGroups(groups = "integration.ejb3")
+
+ @BeforeClass
+ public void resetDB() throws Exception {
+ clearDB();
+ }
+
+ @BeforeSuite(groups = "integration.ejb3")
+ //@BeforeGroups(groups = "integration.ejb3")
public static void startupEmbeddedJboss() {
System.out.println("Starting ejb3...");
String classesDir = System.getProperty("ejbjarDirectory", "target/classes");
@@ -140,4 +146,173 @@ public abstract class AbstractEJB3Test extends AssertJUnit {
referenceTime += offset;
return new Date(referenceTime);
}
+
+ protected void executeInTransaction(TransactionCallback callback) {
+ try {
+ getTransactionManager().begin();
+ callback.execute();
+ getTransactionManager().commit();
+ } catch (Throwable t) {
+ try {
+ getTransactionManager().rollback();
+ } catch (SystemException e) {
+ throw new RuntimeException("Failed to rollback transaction", e);
+ }
+ throw new RuntimeException(t.getCause());
+ }
+ }
+
+ void clearDB() throws Exception {
+ executeInTransaction(new TransactionCallback() {
+ @Override
+ public void execute() throws Exception {
+ EntityManager em = getEntityManager();
+
+ em.createNativeQuery("delete from jms_subscriptions");
+ em.createNativeQuery("delete from jms_roles");
+ em.createNativeQuery("delete from jms_users");
+ em.createNativeQuery("delete from jms_transactions");
+ em.createNativeQuery("delete from jms_messages");
+ em.createNativeQuery("delete from rhq_drift_config_map");
+ em.createNativeQuery("delete from rhq_drift_template_map");
+ em.createNativeQuery("delete from rhq_delete_res_hist");
+ em.createNativeQuery("delete from rhq_create_res_hist");
+ em.createNativeQuery("delete from rhq_tagging_bundle_dest_map");
+ em.createNativeQuery("delete from rhq_tagging_bundle_deploy_map");
+ em.createNativeQuery("delete from rhq_tagging_bundle_version_map");
+ em.createNativeQuery("delete from rhq_tagging_bundle_map");
+ em.createNativeQuery("delete from rhq_bundle_res_dep_hist");
+ em.createNativeQuery("delete from rhq_bundle_res_deploy");
+ em.createNativeQuery("delete from rhq_bundle_deployment");
+ em.createNativeQuery("delete from rhq_bundle_destination");
+ em.createNativeQuery("delete from rhq_bundle_file");
+ em.createNativeQuery("delete from rhq_bundle_version_repo");
+ em.createNativeQuery("delete from rhq_bundle_version");
+ em.createNativeQuery("delete from rhq_bundle");
+ em.createNativeQuery("delete from rhq_bundle_type");
+ em.createNativeQuery("delete from rhq_repo_advisory");
+ em.createNativeQuery("delete from rhq_advisory_buglist");
+ em.createNativeQuery("delete from rhq_advisory_cve");
+ em.createNativeQuery("delete from rhq_cve");
+ em.createNativeQuery("delete from rhq_advisory_package");
+ em.createNativeQuery("delete from rhq_advisory");
+ em.createNativeQuery("delete from rhq_distribution_file");
+ em.createNativeQuery("delete from rhq_repo_distribution");
+ em.createNativeQuery("delete from rhq_distribution where id not in (1, 2)");
+ em.createNativeQuery("delete from rhq_pkg_prd_map");
+ em.createNativeQuery("delete from rhq_pkg_ver_content_src_map");
+ em.createNativeQuery("delete from rhq_repo_pkg_version_map");
+ em.createNativeQuery("delete from rhq_repo_repo_relation_map");
+ em.createNativeQuery("delete from rhq_repo_repo_group_map");
+ em.createNativeQuery("delete from rhq_repo_content_src_map");
+ em.createNativeQuery("delete from rhq_repo_resource_map");
+ em.createNativeQuery("delete from rhq_package_inst_step");
+ em.createNativeQuery("delete from rhq_repo_sync");
+ em.createNativeQuery("delete from rhq_content_src_sync");
+ em.createNativeQuery("delete from rhq_installed_pkg_hist");
+ em.createNativeQuery("delete from rhq_installed_package");
+ em.createNativeQuery("delete from rhq_content_req");
+ em.createNativeQuery("delete from rhq_package_version");
+ em.createNativeQuery("delete from rhq_package_bits");
+ em.createNativeQuery("delete from rhq_package");
+ em.createNativeQuery("delete from rhq_package_type");
+ em.createNativeQuery("delete from rhq_repo_relation");
+ em.createNativeQuery("delete from rhq_repo_relation_type where id not in (1, 2)");
+ em.createNativeQuery("delete from rhq_repo");
+ em.createNativeQuery("delete from rhq_repo_group");
+ em.createNativeQuery("delete from rhq_repo_group_type where id <> 1");
+ em.createNativeQuery("delete from rhq_archirtecture where id < 1 and id > 38");
+ em.createNativeQuery("delete from rhq_meas_data_num_r14");
+ em.createNativeQuery("delete from rhq_meas_data_num_r13");
+ em.createNativeQuery("delete from rhq_meas_data_num_r12");
+ em.createNativeQuery("delete from rhq_meas_data_num_r11");
+ em.createNativeQuery("delete from rhq_meas_data_num_r10");
+ em.createNativeQuery("delete from rhq_meas_data_num_r09");
+ em.createNativeQuery("delete from rhq_meas_data_num_r08");
+ em.createNativeQuery("delete from rhq_meas_data_num_r07");
+ em.createNativeQuery("delete from rhq_meas_data_num_r06");
+ em.createNativeQuery("delete from rhq_meas_data_num_r05");
+ em.createNativeQuery("delete from rhq_meas_data_num_r04");
+ em.createNativeQuery("delete from rhq_meas_data_num_r03");
+ em.createNativeQuery("delete from rhq_meas_data_num_r02");
+ em.createNativeQuery("delete from rhq_meas_data_num_r01");
+ em.createNativeQuery("delete from rhq_meas_data_num_r00");
+ em.createNativeQuery("delete from rhq_measurement_oob_tmp");
+ em.createNativeQuery("delete rhq_measurement_oob");
+ em.createNativeQuery("delete rhq_resource_avail");
+ em.createNativeQuery("delete from rhq_availability");
+ em.createNativeQuery("delete from rhq_calltime_data_value");
+ em.createNativeQuery("delete from rhq_calltime_data_key");
+ em.createNativeQuery("delete from rhq_measurement_data_trait");
+ em.createNativeQuery("delete from rhq_measurement_data_num_1d");
+ em.createNativeQuery("delete from rhq_measurement_data_num_6h");
+ em.createNativeQuery("delete from rhq_measurement_data_num_1h");
+ em.createNativeQuery("delete from rhq_measurement_bline");
+ em.createNativeQuery("delete from rhq_measurement_sched");
+ em.createNativeQuery("delete from rhq_measurement_def");
+ em.createNativeQuery("delete from rhq_plugin");
+ em.createNativeQuery("delete from rhq_system_config where id not in (1, 2, 3, 4, 9, 10, 32, 34, 35, 36, 51, 52, 53, 54, 55, 56)");
+ em.createNativeQuery("delete from rhq_alert_notification");
+ em.createNativeQuery("delete from rhq_alert_condition_log");
+ em.createNativeQuery("delete from rhq_alert");
+ em.createNativeQuery("delete from rhq_alert_condition");
+ em.createNativeQuery("delete from rhq_alert_dampen_event");
+ em.createNativeQuery("delete from rhq_alert_definition");
+ em.createNativeQuery("delete from rhq_event");
+ em.createNativeQuery("delete from rhq_event_source");
+ em.createNativeQuery("delete from rhq_event_def");
+ em.createNativeQuery("delete from rhq_operation_schedule");
+ em.createNativeQuery("delete from rhq_operation_history");
+ em.createNativeQuery("delete from rhq_operation_def");
+ em.createNativeQuery("delete from rhq_dashboard_portlet");
+ em.createNativeQuery("delete from rhq_dashboard");
+ em.createNativeQuery("delete from rhq_saved_search");
+ em.createNativeQuery("delete from rhq_subject_role_ldap_map");
+ em.createNativeQuery("delete from rhq_subject_role_map where id not in (1, 2)");
+ em.createNativeQuery("delete from rhq_permission where role_id not in (1, 2)");
+ em.createNativeQuery("delete from rhq_role_ldap_group");
+ em.createNativeQuery("delete from rhq_role_resource_group_map");
+ em.createNativeQuery("delete from rhq_role where id not in (1, 2)");
+ em.createNativeQuery("delete from rhq_tagging_res_group_map");
+ em.createNativeQuery("delete from rhq_tagging_resource_map");
+ em.createNativeQuery("delete from rhq_tagging");
+ em.createNativeQuery("delete from rhq_config_update");
+ em.createNativeQuery("delete from rhq_config_group_update");
+ em.createNativeQuery("delete from rhq_resource_group_res_exp_map");
+ em.createNativeQuery("delete from rhq_resource_group_res_imp_map");
+ em.createNativeQuery("delete from rhq_resource_group");
+ em.createNativeQuery("delete from rhq_group_def");
+ em.createNativeQuery("delete from rhq_resource_error");
+ em.createNativeQuery("delete from rhq_resource");
+ em.createNativeQuery("delete from rhq_prd_ver");
+ em.createNativeQuery("delete from rhq_process_scan");
+ em.createNativeQuery("delete from rhq_resource_type_parents");
+ em.createNativeQuery("delete from rhq_resource_subcat");
+ em.createNativeQuery("delete from rhq_resource_type");
+ em.createNativeQuery("delete from rhq_subject where id not in (1, 2)");
+ em.createNativeQuery("delete from rhq_principal where id <> 2");
+ em.createNativeQuery("delete from rhq_failover_details");
+ em.createNativeQuery("delete from rhq_failover_list");
+ em.createNativeQuery("delete from rhq_partition_details");
+ em.createNativeQuery("delete from rhq_partition_event");
+ em.createNativeQuery("delete from rhq_agent");
+ em.createNativeQuery("delete from rhq_server");
+ em.createNativeQuery("delete from rhq_affinity_group");
+ em.createNativeQuery("delete from rhq_raw_config");
+ em.createNativeQuery("delete from rhq_config_template");
+ em.createNativeQuery("delete from rhq_config_property");
+ em.createNativeQuery("delete from rhq_config");
+ em.createNativeQuery("delete from rhq_config_prop_constr");
+ em.createNativeQuery("delete from rhq_conf_prop_def_enum");
+ em.createNativeQuery("delete from rhq_config_pd_osrc");
+ em.createNativeQuery("delete from rhq_config_prop_def");
+ em.createNativeQuery("delete from rhq_config_prop_grp_def");
+ em.createNativeQuery("delete from rhq_config_def");
+ }
+ });
+ }
+
+ public static interface TransactionCallback {
+ void execute() throws Exception;
+ }
}
\ No newline at end of file
commit ae72c575c529a40462ccb7495252c7a5cff6dbb8
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Jul 22 16:09:08 2011 -0400
stub out the new drift change sets subtab
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftChangeSetsView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftChangeSetsView.java
new file mode 100644
index 0000000..f610b8b
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftChangeSetsView.java
@@ -0,0 +1,48 @@
+/*
+ * RHQ Management Platform
+ * Copyright 2011, 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.enterprise.gui.coregui.client.drift;
+
+import org.rhq.core.domain.common.EntityContext;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
+
+/**
+ * A view that displays a tree of all change sets and their related drift trails.
+ *
+ * @author John Mazzitelli
+ */
+public class DriftChangeSetsView extends LocatableVLayout {
+
+ private EntityContext context;
+ private boolean hasWriteAccess;
+
+ protected DriftChangeSetsView(String locatorId, String tableTitle, EntityContext context, boolean hasWriteAccess) {
+ super(locatorId);
+ this.context = context;
+ this.hasWriteAccess = hasWriteAccess;
+ }
+
+ public EntityContext getContext() {
+ return context;
+ }
+
+ protected boolean hasWriteAccess() {
+ return this.hasWriteAccess;
+ }
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/ResourceDriftChangeSetsView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/ResourceDriftChangeSetsView.java
new file mode 100644
index 0000000..ab54e88
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/ResourceDriftChangeSetsView.java
@@ -0,0 +1,40 @@
+/*
+ * RHQ Management Platform
+ * Copyright 2011, 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.enterprise.gui.coregui.client.drift;
+
+import org.rhq.core.domain.common.EntityContext;
+import org.rhq.core.domain.resource.composite.ResourceComposite;
+
+/**
+ * @author John Mazzitelli
+ */
+public class ResourceDriftChangeSetsView extends DriftChangeSetsView {
+ public static ResourceDriftChangeSetsView get(String locatorId, ResourceComposite composite) {
+ String tableTitle = MSG.view_drift_changeSets_resourceViewTitle();
+ EntityContext context = EntityContext.forResource(composite.getResource().getId());
+ boolean hasWriteAccess = composite.getResourcePermission().isDrift();
+ return new ResourceDriftChangeSetsView(locatorId, tableTitle, context, hasWriteAccess);
+ }
+
+ private ResourceDriftChangeSetsView(String locatorId, String tableTitle, EntityContext context,
+ boolean hasWriteAccess) {
+ super(locatorId, tableTitle, context, hasWriteAccess);
+ }
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java
index b8031ea..4efc189 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java
@@ -50,6 +50,7 @@ import org.rhq.enterprise.gui.coregui.client.components.tab.SubTab;
import org.rhq.enterprise.gui.coregui.client.components.tab.TwoLevelTab;
import org.rhq.enterprise.gui.coregui.client.components.view.ViewFactory;
import org.rhq.enterprise.gui.coregui.client.components.view.ViewName;
+import org.rhq.enterprise.gui.coregui.client.drift.ResourceDriftChangeSetsView;
import org.rhq.enterprise.gui.coregui.client.drift.ResourceDriftConfigurationView;
import org.rhq.enterprise.gui.coregui.client.drift.ResourceDriftHistoryView;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
@@ -98,6 +99,7 @@ public class ResourceDetailView extends AbstractTwoLevelTabSetView<ResourceCompo
public static class DriftSubTab {
public static final String CONFIGURATION = "Configuration";
public static final String HISTORY = "History";
+ public static final String CHANGE_SETS = "ChangeSets";
}
public static class OperationsSubTab {
@@ -143,6 +145,7 @@ public class ResourceDetailView extends AbstractTwoLevelTabSetView<ResourceCompo
private SubTab configHistory;
private SubTab eventHistory;
private SubTab driftHistory;
+ private SubTab driftChangeSets;
private SubTab driftConfig;
private SubTab contentDeployed;
private SubTab contentNew;
@@ -242,9 +245,11 @@ public class ResourceDetailView extends AbstractTwoLevelTabSetView<ResourceCompo
.view_tabs_common_drift()), "subsystems/drift/Drift_16.png");
this.driftHistory = new SubTab(driftTab.extendLocatorId(DriftSubTab.HISTORY), new ViewName(DriftSubTab.HISTORY,
MSG.view_tabs_common_history()), null);
+ this.driftChangeSets = new SubTab(driftTab.extendLocatorId(DriftSubTab.CHANGE_SETS), new ViewName(
+ DriftSubTab.CHANGE_SETS, MSG.view_drift_changeSets()), null);
this.driftConfig = new SubTab(driftTab.extendLocatorId(DriftSubTab.CONFIGURATION), new ViewName(
DriftSubTab.CONFIGURATION, MSG.view_tabs_common_configuration()), null);
- driftTab.registerSubTabs(driftHistory, driftConfig);
+ driftTab.registerSubTabs(driftHistory, driftChangeSets, driftConfig);
tabs.add(driftTab);
contentTab = new TwoLevelTab(getTabSet().extendLocatorId("Content"), new ViewName("Content", MSG
@@ -521,6 +526,13 @@ public class ResourceDetailView extends AbstractTwoLevelTabSetView<ResourceCompo
}
});
+ updateSubTab(this.driftTab, this.driftChangeSets, true, true, new ViewFactory() {
+ @Override
+ public Canvas createView() {
+ return ResourceDriftChangeSetsView.get(driftChangeSets.extendLocatorId("View"), resourceComposite);
+ }
+ });
+
updateSubTab(this.driftTab, this.driftConfig, true, true, new ViewFactory() {
@Override
public Canvas createView() {
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties
index 354e504..c7d6f91 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties
@@ -1121,6 +1121,8 @@ view_drift_button_detectNow = Detect Now
view_drift_category_fileAdded = File Added
view_drift_category_fileChanged = File Changed
view_drift_category_fileRemoved = File Removed
+view_drift_changeSets = Change Sets
+view_drift_changeSets_resourceViewTitle = Resource Drift Change Sets
view_drift_delete_confirm = Delete the selected drift(s)?
view_drift_delete_confirmAll = Delete all drifts from this source?
view_drift_failure_delete = Failed to delete drift targets with id''s: {0}
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties
index f117bdf..5fe14aa 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties
@@ -939,6 +939,8 @@ view_dashboards_title = Dashboard
##view_drift_category_fileAdded = File Added
##view_drift_category_fileChanged = File Changed
##view_drift_category_fileRemoved = File Removed
+##view_drift_changeSets = Change Sets
+##view_drift_changeSets_resourceViewTitle = Resource Drift Change Sets
##view_drift_delete_confirm = Delete the selected drift(s)?
##view_drift_delete_confirmAll = Delete all drifts from this source?
##view_drift_failure_delete = Failed to delete drift targets with id''s: {0}
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ja.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ja.properties
index f343153..6bce847 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ja.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ja.properties
@@ -1104,6 +1104,8 @@ view_dashboards_portlets_refresh_success1 = ããŒãã¬ããã®èªåãªãã¬
view_dashboards_portlets_refresh_success2 = èªåãªãã¬ãã·ã¥ããããŒãã¬ããã®ãªããŒããåæ¢ããŠããŸã
view_dashboards_title = ããã·ã¥ããŒã
##view_drift = Drift
+##view_drift_changeSets = Change Sets
+##view_drift_changeSets_resourceViewTitle = Resource Drift Change Sets
##view_drift_table_baseDir = Base Directory
##view_drift_table_changeSet = Change Set
##view_drift_table_newFile = New File
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_pt.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_pt.properties
index 516f235..bd2b6fb 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_pt.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_pt.properties
@@ -1139,6 +1139,8 @@ view_dashboards_title = Dashboard~
##view_drift_category_fileAdded = File Added
##view_drift_category_fileChanged = File Changed
##view_drift_category_fileRemoved = File Removed
+##view_drift_changeSets = Change Sets
+##view_drift_changeSets_resourceViewTitle = Resource Drift Change Sets
##view_drift_delete_confirm = Delete the selected drift(s)?
##view_drift_delete_confirmAll = Delete all drifts from this source?
##view_drift_failure_delete = Failed to delete drift targets with id''s: {0}
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_zh.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_zh.properties
index bcac425..9fa9115 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_zh.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_zh.properties
@@ -1113,6 +1113,8 @@ view_dashboards_portlets_refresh_success1 = \u6210\u529f\u4fee\u6539portlets\u81
view_dashboards_portlets_refresh_success2 = \u6210\u529f\u505c\u7528portlets\u81ea\u52a8\u5237\u65b0\u7684\u91cd\u8f7d
view_dashboards_title = \u7edf\u8ba1\u8868\u76d8
##view_drift = Drift
+##view_drift_changeSets = Change Sets
+##view_drift_changeSets_resourceViewTitle = Resource Drift Change Sets
##view_drift_table_baseDir = Base Directory
##view_drift_table_changeSet = Change Set
##view_drift_table_newFile = New File
commit 606ae34fc2e8d3ee88db8ae6904ef4a9cc914053
Author: John Sanda <jsanda(a)redhat.com>
Date: Fri Jul 22 13:22:56 2011 -0400
Adding support for generating snapshot diffs
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DiffReport.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DiffReport.java
new file mode 100644
index 0000000..89f3286
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DiffReport.java
@@ -0,0 +1,38 @@
+package org.rhq.enterprise.server.drift;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class DiffReport<T> {
+
+ private List<T> notInLeft = new ArrayList<T>();
+
+ private List<T> notInRight = new ArrayList<T>();
+
+ private List<T> conflicts = new ArrayList<T>();
+
+ public List<T> getElementsNotInLeft() {
+ return notInLeft;
+ }
+
+ public void elementNotInLeft(T element) {
+ notInLeft.add(element);
+ }
+
+ public List<T> getElementsNotInRight() {
+ return notInRight;
+ }
+
+ public void elementNotInRight(T element) {
+ notInRight.add(element);
+ }
+
+ public List<T> getElementsInConflict() {
+ return conflicts;
+ }
+
+ public void elementInConflict(T element) {
+ conflicts.add(element);
+ }
+
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/Snapshot.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/Snapshot.java
index 2efc8d8..5dc18fa 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/Snapshot.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/Snapshot.java
@@ -1,12 +1,13 @@
package org.rhq.enterprise.server.drift;
import java.io.Serializable;
-import java.util.Comparator;
-import java.util.Set;
-import java.util.TreeSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.TreeMap;
import org.rhq.core.domain.drift.Drift;
import org.rhq.core.domain.drift.DriftChangeSet;
+import org.rhq.core.domain.drift.DriftFile;
import static org.rhq.core.domain.drift.DriftCategory.FILE_REMOVED;
@@ -16,30 +17,56 @@ public class Snapshot implements Serializable {
private int version;
- private Set<Drift> entries = new TreeSet<Drift>(new Comparator<Drift>() {
- @Override
- public int compare(Drift d1, Drift d2) {
- return d1.getPath().compareTo(d2.getPath());
- }
- });
+ private Map<String, Drift> entries = new TreeMap<String, Drift>();
public int getVersion() {
return version;
}
- public Set<Drift> getEntries() {
- return entries;
+ public Collection<Drift> getEntries() {
+ return entries.values();
}
public <D extends Drift> Snapshot add(DriftChangeSet<D> changeSet) {
for (Drift entry : changeSet.getDrifts()) {
- entries.remove(entry);
+ entries.remove(entry.getPath());
if (entry.getCategory() != FILE_REMOVED) {
- entries.add(entry);
+ entries.put(entry.getPath(), entry);
}
}
version = changeSet.getVersion();
return this;
}
+ public DiffReport diff(Snapshot right) {
+ Snapshot left = this;
+ DiffReport<Drift> diff = new DiffReport<Drift>();
+
+ for (Map.Entry<String, Drift> entry : left.entries.entrySet()) {
+ if (!right.entries.containsKey(entry.getKey())) {
+ diff.elementNotInRight(entry.getValue());
+ }
+ }
+
+ for (Map.Entry<String, Drift> entry : right.entries.entrySet()) {
+ if (!left.entries.containsKey(entry.getKey())) {
+ diff.elementNotInLeft(entry.getValue());
+ }
+ }
+
+ for (Map.Entry<String, Drift> entry : left.entries.entrySet()) {
+ Drift rightDrift = right.entries.get(entry.getKey());
+ if (rightDrift != null) {
+ DriftFile leftFile = entry.getValue().getNewDriftFile();
+ DriftFile rightFile = rightDrift.getNewDriftFile();
+
+ if (!leftFile.getHashId().equals(rightFile.getHashId())) {
+ diff.elementInConflict(entry.getValue());
+ }
+ }
+ }
+
+ return diff;
+ }
+
}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/drift/SnapshotTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/drift/SnapshotTest.java
index b646b19..47dbb73 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/drift/SnapshotTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/drift/SnapshotTest.java
@@ -12,6 +12,7 @@ import org.rhq.core.domain.drift.DriftChangeSetCategory;
import org.rhq.core.domain.drift.DriftFile;
import org.rhq.core.domain.drift.DriftFileStatus;
+import static java.util.Arrays.asList;
import static org.rhq.core.domain.drift.DriftCategory.FILE_ADDED;
import static org.rhq.core.domain.drift.DriftCategory.FILE_CHANGED;
import static org.rhq.core.domain.drift.DriftCategory.FILE_REMOVED;
@@ -87,6 +88,60 @@ public class SnapshotTest {
"removed.");
}
+ @Test
+ public void diffShowsEntriesInLeftAndNotInRight() {
+ int configId = 1;
+
+ Drift entry1 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a1b2c3", 1024, LOADED), "/drift/1.txt");
+ FakeDriftChangeSet changeSet1 = new FakeDriftChangeSet(0, COVERAGE, configId).add(entry1);
+ Snapshot right = new Snapshot().add(changeSet1);
+
+ Drift entry2 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a3b6c9", 1024, LOADED), "/drift/2.txt");
+ FakeDriftChangeSet changeSet2 = new FakeDriftChangeSet(0, COVERAGE, configId).add(entry1).add(entry2);
+ Snapshot left = new Snapshot().add(changeSet1).add(changeSet2);
+
+ DiffReport diff = left.diff(right);
+
+ assertCollectionMatchesNoOrder(asList(entry2), diff.getElementsNotInRight(), "Diff report does not contain " +
+ "elements that are in the left but not in the right.");
+ }
+
+ @Test
+ public void diffShowsEntriesInRightAndNotInLeft() {
+ int configId = 1;
+
+ Drift entry1 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a1b2c3", 1024, LOADED), "/drift/1.txt");
+ FakeDriftChangeSet changeSet1 = new FakeDriftChangeSet(0, COVERAGE, configId).add(entry1);
+ Snapshot right = new Snapshot().add(changeSet1);
+
+ Drift entry2 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a3b6c9", 1024, LOADED), "/drift/2.txt");
+ FakeDriftChangeSet changeSet2 = new FakeDriftChangeSet(0, COVERAGE, configId).add(entry2);
+ Snapshot left = new Snapshot().add(changeSet2);
+
+ DiffReport diff = left.diff(right);
+
+ assertCollectionMatchesNoOrder(asList(entry1), diff.getElementsNotInLeft(), "Diff report does not contain " +
+ "elements that are in the left but not in the right");
+ }
+
+ @Test
+ public void diffShowsEntriesInLeftAndRightThatAreInConflict() {
+ int configId = 1;
+
+ Drift entry1 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a1b2c3", 1024, LOADED), "/drfit/1.txt");
+ FakeDriftChangeSet changeSet1 = new FakeDriftChangeSet(0, COVERAGE, configId).add(entry1);
+ Snapshot right = new Snapshot().add(changeSet1);
+
+ Drift entry2 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("c3b2a1", 1024, LOADED), "/drfit/1.txt");
+ FakeDriftChangeSet changeSet2 = new FakeDriftChangeSet(1, DRIFT, configId).add(entry2);
+ Snapshot left = new Snapshot().add(changeSet2);
+
+ DiffReport diff = left.diff(right);
+
+ assertCollectionMatchesNoOrder(asList(entry2), diff.getElementsInConflict(), "Diff report does not contain " +
+ "element that are in both left and right and are in conflict");
+ }
+
<E> Set<E> asSet(E... elements) {
HashSet<E> set = new HashSet<E>();
for (E element : elements) {
commit 8736df77b8eb3ff47484c6b0ca17a9a52aca8fb6
Author: John Sanda <jsanda(a)redhat.com>
Date: Thu Jul 21 22:03:41 2011 -0400
Adding logic for removing files from a snapshot
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/Snapshot.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/Snapshot.java
index 35a4669..2efc8d8 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/Snapshot.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/Snapshot.java
@@ -1,5 +1,6 @@
package org.rhq.enterprise.server.drift;
+import java.io.Serializable;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
@@ -7,7 +8,11 @@ import java.util.TreeSet;
import org.rhq.core.domain.drift.Drift;
import org.rhq.core.domain.drift.DriftChangeSet;
-public class Snapshot {
+import static org.rhq.core.domain.drift.DriftCategory.FILE_REMOVED;
+
+public class Snapshot implements Serializable {
+
+ private static final long serialVersionUID = 1L;
private int version;
@@ -29,7 +34,9 @@ public class Snapshot {
public <D extends Drift> Snapshot add(DriftChangeSet<D> changeSet) {
for (Drift entry : changeSet.getDrifts()) {
entries.remove(entry);
- entries.add(entry);
+ if (entry.getCategory() != FILE_REMOVED) {
+ entries.add(entry);
+ }
}
version = changeSet.getVersion();
return this;
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/drift/SnapshotTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/drift/SnapshotTest.java
index 627bc2c..b646b19 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/drift/SnapshotTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/drift/SnapshotTest.java
@@ -14,6 +14,7 @@ import org.rhq.core.domain.drift.DriftFileStatus;
import static org.rhq.core.domain.drift.DriftCategory.FILE_ADDED;
import static org.rhq.core.domain.drift.DriftCategory.FILE_CHANGED;
+import static org.rhq.core.domain.drift.DriftCategory.FILE_REMOVED;
import static org.rhq.core.domain.drift.DriftChangeSetCategory.COVERAGE;
import static org.rhq.core.domain.drift.DriftChangeSetCategory.DRIFT;
import static org.rhq.core.domain.drift.DriftFileStatus.LOADED;
@@ -23,7 +24,7 @@ import static org.testng.Assert.assertEquals;
public class SnapshotTest {
@Test
- public void generateSnapshotForOneChangeSet() throws Exception {
+ public void addChangeSetWithAddedFile() {
int configId = 1;
FakeDriftChangeSet changeSet = new FakeDriftChangeSet(0, COVERAGE, configId)
@@ -37,7 +38,7 @@ public class SnapshotTest {
}
@Test
- public void generateSnapshotWithTwoChangeSetsAndFileAdded() {
+ public void addChangeSetsWithAddedFiles() {
int configId = 1;
Drift entry1 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a1b2c3", 1024, LOADED), "/drift/1.txt");
@@ -54,7 +55,7 @@ public class SnapshotTest {
}
@Test
- public void generateSnapshotWithFileChanged() {
+ public void replaceFileWithChangedVersion() {
int configId = 1;
Drift entry1 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a1b2c3", 1024, LOADED), "/drift/1.txt");
@@ -66,7 +67,24 @@ public class SnapshotTest {
Snapshot snapshot = new Snapshot().add(changeSet1).add(changeSet2);
- assertCollectionMatchesNoOrder(asSet(entry2), snapshot.getEntries(), "Failed build snapshot with file changed");
+ assertCollectionMatchesNoOrder(asSet(entry2), snapshot.getEntries(), "Failed to build snapshot with file changed");
+ }
+
+ @Test
+ public void deleteFileThatHasBeenRemoved() {
+ int configId = 1;
+
+ Drift entry1 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("a1b2c3", 1024, LOADED), "/drift/1.txt");
+ Drift entry2 = new FakeDrift(FILE_ADDED, null, new FakeDriftFile("d1f2a3", 1024, LOADED), "/drift/2.txt");
+ FakeDriftChangeSet changeSet1 = new FakeDriftChangeSet(0, COVERAGE, configId).add(entry1).add(entry2);
+
+ Drift entry3 = new FakeDrift(FILE_REMOVED, new FakeDriftFile("a1b2c3", 1024, LOADED), null, "/drift/1.txt");
+ FakeDriftChangeSet changeSet2 = new FakeDriftChangeSet(1, DRIFT, configId).add(entry3);
+
+ Snapshot snapshot = new Snapshot().add(changeSet1).add(changeSet2);
+
+ assertCollectionMatchesNoOrder(asSet(entry2), snapshot.getEntries(), "Failed to build snapshot with a file " +
+ "removed.");
}
<E> Set<E> asSet(E... elements) {
commit 609a2aa1c541eb8f38b98c725d3e513c364653dc
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Wed Jul 27 10:03:45 2011 -0400
add peer-review warning
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/Table.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/Table.java
index ea2e29d..b1d0bb1 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/Table.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/Table.java
@@ -91,6 +91,12 @@ import org.rhq.enterprise.gui.coregui.client.util.selenium.SeleniumUtility;
/**
* A tabular view of set of data records from an {@link RPCDataSource}.
*
+ * WARNING! If you make _any_ changes to this class, no matter how seemingly
+ * trivial, you must get it peer reviewed. Send out your proposed changes
+ * to the dev mailing list and ask for comments. Any problems introduced to
+ * this class are magnified because it is used in so many UI views and problems
+ * are hard to detect due to the varies ways it is used.
+ *
* @author Greg Hinkle
* @author Ian Springer
*/
commit 668586aa9445d9aee9f63fc8991da4477bb4031d
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Tue Jul 26 16:11:50 2011 -0500
Fully enable jvmRoute for context identification and discovery. Also, addressed all the compiler warnings in the plugin code.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
index 23d7d62..3545fa5 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
@@ -32,6 +32,7 @@ import org.rhq.plugins.jmx.MBeanResourceComponent;
*
* @author Stefan Negrea
*/
+@SuppressWarnings({ "rawtypes", "deprecation" })
public class ContextComponent extends MBeanResourceComponent<MBeanResourceComponent> {
@Override
protected EmsBean loadBean() {
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
index 35ecf30..5c9c3fd 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
@@ -57,10 +57,12 @@ public class ContextDiscoveryComponent implements ResourceDiscoveryComponent<MBe
Set<DiscoveredResourceDetails> entities = new HashSet<DiscoveredResourceDetails>();
for (ProxyInfo.Context availableContext : proxyInfo.getAvailableContexts()) {
- DiscoveredResourceDetails detail = new DiscoveredResourceDetails(context.getResourceType(),
- availableContext.createKey(), availableContext.createName(), null, "mod_cluster Webapp Context", null,
- null);
- entities.add(detail);
+ if (availableContext.getJvmRoute().equals(jvmRoute)) {
+ DiscoveredResourceDetails detail = new DiscoveredResourceDetails(context.getResourceType(),
+ availableContext.createKey(), availableContext.createName(), null, "mod_cluster Webapp Context",
+ null, null);
+ entities.add(detail);
+ }
}
return entities;
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
index 4cca539..8614402 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
@@ -54,9 +54,9 @@ public class ProxyInfo {
identifier = identifier.substring(identifier.indexOf("[") + 1, identifier.indexOf("]"));
String jvmRoute = nodePieces[1];
- jvmRoute = jvmRoute.substring(jvmRoute.indexOf(':')).trim();
+ jvmRoute = jvmRoute.substring(jvmRoute.indexOf(':') + 1).trim();
- availableNodes.put(jvmRoute, new Node(jvmRoute, identifier));
+ availableNodes.put(identifier, new Node(jvmRoute, identifier));
}
}
@@ -90,13 +90,18 @@ public class ProxyInfo {
identifier = identifier.substring(identifier.indexOf("[") + 1, identifier.indexOf("]"));
identifier = identifier.substring(0, identifier.lastIndexOf(":"));
+ String nodeIdentifier = contextPieces[0];
+ nodeIdentifier = nodeIdentifier.substring(nodeIdentifier.indexOf("[") + 1, nodeIdentifier.indexOf("]"));
+ nodeIdentifier = nodeIdentifier.substring(0, nodeIdentifier.indexOf(":"));
+ String jvmRoute = availableNodes.get(nodeIdentifier).getJvmRoute();
+
String rawIsEnabled = contextPieces[2];
rawIsEnabled = rawIsEnabled.substring(rawIsEnabled.indexOf(':') + 1).trim();
boolean isEnabled = rawIsEnabled.equals("ENABLED") ? true : false;
Vhost relatedVhost = availableVhosts.get(identifier);
- availableContexts.add(new Context("", relatedVhost.getHost(), actualContext, isEnabled));
+ availableContexts.add(new Context(jvmRoute, relatedVhost.getHost(), actualContext, isEnabled));
}
}
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index 3c01b30..992c5b0 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -18,12 +18,12 @@
description="mod_cluster plugin"
singleton="true">
- <runs-inside>
+ <runs-inside>
<parent-resource-type name="JBossAS Server" plugin="JBossAS"/>
<parent-resource-type name="JBossAS5 Server" plugin="JBossAS5"/>
</runs-inside>
- <plugin-configuration>
+ <plugin-configuration>
<c:simple-property name="objectName" readOnly="true" default="Catalina:type=ModClusterListener,*"/>
<c:simple-property name="additionalConfigurationObjectName" readOnly="true" default="jboss.web:type=Engine"/>
<c:simple-property name="jvmRoute" readOnly="false"/>
@@ -34,12 +34,14 @@
<parameters>
<c:simple-property required="true" name="timeout" type="string" displayName="Session draining timeout"/>
<c:simple-property required="true" name="unit" default="MILLISECONDS" displayName="Time unit of the timeout parameter">
- <c:property-options allowCustomValue="false">
- <c:option value="MICROSECONDS" name="MICROSECONDS"/>
+ <c:property-options allowCustomValue="false">
+ <c:option value="MICROSECONDS" name="MICROSECONDS"/>
<c:option value="MILLISECONDS" name="MILLISECONDS"/>
<c:option value="NANOSECONDS" name="NANOSECONDS"/>
- <c:option value="SECONDS" name="SECONDS"/>
- </c:property-options>
+ <c:option value="SECONDS" name="SECONDS"/>
+ <c:option value="HOURS" name="HOURS"/>
+ <c:option value="DAYS" name="DAYS"/>
+ </c:property-options>
</c:simple-property>
</parameters>
<results>
@@ -56,7 +58,7 @@
<results>
<c:simple-property name="result" type="boolean" description="The result of the operation" />
</results>
- </operation>
+ </operation>
<operation name="reset" displayName="Reset the node" description="Move the node out of an error state." />
<operation name="disable" displayName="Disable all webpapps" description="Disable all webapps for all engines.">
<results>
@@ -71,7 +73,6 @@
</operation>
<operation name="refresh" displayName="Refresh configuration" description="Refresh configuration" />
-
<metric property="proxyConfiguration" displayName="Proxy Configuration" displayType="summary" dataType="trait" />
<metric property="modelerType" displayName="Type of the modeled resource" displayType="summary" dataType="trait" />
<metric property="className" displayName="Fully qualified class name of the managed object" displayType="summary" dataType="trait" />
@@ -87,7 +88,7 @@
<c:simple-property name="stickySessionForce" type="boolean" description="Return an error when the request cannot be routed to the right node."/>
<c:simple-property name="balancer" type="string" required="false" description="Name of the balancer."/>
<c:simple-property name="flushPackets" type="boolean" description="Allows controlling flusing of packets."/>
- <c:simple-property name="socketTimeout" type="integer" description="Connection timeout for communication with the proxy." />
+ <c:simple-property name="socketTimeout" type="integer" description="Connection timeout for communication with the proxy." />
<c:simple-property name="domain" type="string" required="false" description="Domain parameter, which allows tying a jvmRoute to a particular domain."/>
<c:simple-property name="advertisePort" type="integer" required="false" description="Multicast port for discovery" />
<c:simple-property name="advertiseGroupAddress" type="string" required="false" description="Multicast address for discovery."/>
@@ -130,6 +131,5 @@
</operation>
</service>
-
</service>
</plugin>
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
index 57aed4d..0f644fc 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
@@ -53,6 +53,7 @@ import org.rhq.core.pluginapi.operation.OperationResult;
/**
* @author Stefan Negrea
*/
+@SuppressWarnings("rawtypes")
@Test(groups = "modcluster-plugin")
public class ModclusterPluginTest {
private Log log = LogFactory.getLog(this.getClass());
@@ -104,6 +105,8 @@ public class ModclusterPluginTest {
log.info("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
List<String> typeNames = new ArrayList<String>() {
+ private static final long serialVersionUID = 1L;
+
{
add(PLUGIN_NAME);
add(PLUGIN_NAME + " Webapp Context");
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
index df7d222..625d8d4 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
@@ -21,8 +21,6 @@ package org.rhq.plugins.modcluster.test;
import java.io.IOException;
import java.io.InputStream;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
import org.testng.annotations.Test;
import org.rhq.plugins.modcluster.ProxyInfo;
@@ -32,7 +30,6 @@ import org.rhq.plugins.modcluster.ProxyInfo;
*/
@Test(groups = "modcluster-plugin")
public class ProxyInfoTest {
- private Log log = LogFactory.getLog(this.getClass());
@Test
public void testProxyInfo() throws Exception {
commit d1fe493616de40914e8708fa7497bcfac5b32498
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Tue Jul 26 15:08:59 2011 -0500
Adding jvmRoute in the mix for webapp context identification. jvmRoute uniquely identifies nodes in a cluster and will be used to decide which contexts run on the node monitored by RHQ.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
index 7cefa46..35ecf30 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
@@ -25,8 +25,10 @@ package org.rhq.plugins.modcluster;
import java.util.HashSet;
import java.util.Set;
+import org.mc4j.ems.connection.EmsConnection;
import org.mc4j.ems.connection.bean.EmsBean;
+import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
@@ -37,26 +39,78 @@ import org.rhq.plugins.jmx.MBeanResourceComponent;
*
* @author Stefan Negrea
*/
+@SuppressWarnings("rawtypes")
public class ContextDiscoveryComponent implements ResourceDiscoveryComponent<MBeanResourceComponent> {
+ private final String JVM_ROUTE_PROPERTY = "jvmRoute";
+ private final String PROXY_INFO_PROPERTY = "proxyInfo";
+ private final String ADDITIONAL_CONFIG_BEAN_PROPERTY = "additionalConfigurationObjectName";
+
/* (non-Javadoc)
* @see org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent#discoverResources(org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext)
*/
public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext<MBeanResourceComponent> context) {
- Set<DiscoveredResourceDetails> entities = new HashSet<DiscoveredResourceDetails>();
+ String jvmRoute = this.getJvmRoute(context);
+ String rawProxyInfo = this.getRawProxyInfo(context);
- EmsBean statsBean = context.getParentResourceComponent().getEmsBean();
-
- String rawProxyInfo = (String) statsBean.getAttribute("proxyInfo").refresh().toString();
ProxyInfo proxyInfo = new ProxyInfo(rawProxyInfo);
+ Set<DiscoveredResourceDetails> entities = new HashSet<DiscoveredResourceDetails>();
for (ProxyInfo.Context availableContext : proxyInfo.getAvailableContexts()) {
DiscoveredResourceDetails detail = new DiscoveredResourceDetails(context.getResourceType(),
- availableContext.toString(), availableContext.toString(), null, "mod_cluster Webapp Context", null,
+ availableContext.createKey(), availableContext.createName(), null, "mod_cluster Webapp Context", null,
null);
entities.add(detail);
}
return entities;
}
+
+ /**
+ * Retrieves the jvm route for the node from the parent context.
+ *
+ * @param context the discovery context
+ * @return node's jvm route
+ */
+ private String getJvmRoute(ResourceDiscoveryContext<MBeanResourceComponent> context) {
+ Configuration pluginConfig = context.getParentResourceComponent().getResourceContext().getPluginConfiguration();
+ String objectName = pluginConfig.getSimple(ADDITIONAL_CONFIG_BEAN_PROPERTY).getStringValue();
+ EmsBean engineBean = this.loadBean(objectName, context.getParentResourceComponent());
+
+ return (String) engineBean.getAttribute(JVM_ROUTE_PROPERTY).refresh().toString();
+ }
+
+ /**
+ * Retrieves raw proxy configuration from the parent context.
+ *
+ * @param context the discovery context
+ * @return raw proxy configuration
+ */
+ private String getRawProxyInfo(ResourceDiscoveryContext<MBeanResourceComponent> context) {
+ EmsBean statsBean = context.getParentResourceComponent().getEmsBean();
+ return (String) statsBean.getAttribute(PROXY_INFO_PROPERTY).refresh().toString();
+ }
+
+ /**
+ * Loads the bean with the given object name.
+ *
+ * Subclasses are free to override this method in order to load the bean.
+ *
+ * @param objectName the name of the bean to load
+ * @return the bean that is loaded
+ */
+ protected EmsBean loadBean(String objectName, MBeanResourceComponent context) {
+ EmsConnection emsConnection = context.getEmsConnection();
+ EmsBean bean = emsConnection.getBean(objectName);
+ if (bean == null) {
+ // In some cases, this resource component may have been discovered by some means other than querying its
+ // parent's EMSConnection (e.g. ApplicationDiscoveryComponent uses a filesystem to discover EARs and
+ // WARs that are not yet deployed). In such cases, getBean() will return null, since EMS won't have the
+ // bean in its cache. To cover such cases, make an attempt to query the underlying MBeanServer for the
+ // bean before giving up.
+ emsConnection.queryBeans(objectName);
+ bean = emsConnection.getBean(objectName);
+ }
+ return bean;
+ }
}
\ No newline at end of file
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
index 52dd287..591fef6 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
@@ -25,6 +25,7 @@ import org.rhq.plugins.jmx.MBeanResourceComponent;
* @author Stefan Negrea
*
*/
+@SuppressWarnings("rawtypes")
public class ModclusterServerComponent extends MBeanResourceComponent {
/* (non-Javadoc)
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
index 36f490d..4cca539 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
@@ -33,11 +33,35 @@ import java.util.regex.Pattern;
*/
public class ProxyInfo {
- private List<Context> availableContexts = new ArrayList<ProxyInfo.Context>();
+ private Map<String, Node> availableNodes = new HashMap<String, Node>();
private Map<String, Vhost> availableVhosts = new HashMap<String, Vhost>();
+ private List<Context> availableContexts = new ArrayList<ProxyInfo.Context>();
public ProxyInfo(String rawProxyInfo) {
- Pattern vhostPattern = Pattern.compile("Vhost.*\n");
+ parseNodes(rawProxyInfo);
+ parseVhosts(rawProxyInfo);
+ parseContexts(rawProxyInfo);
+ }
+
+ private void parseNodes(String rawProxyInfo) {
+ Pattern nodePattern = Pattern.compile("Node:.*\n");
+ Matcher nodeMatcher = nodePattern.matcher(rawProxyInfo);
+ while (nodeMatcher.find()) {
+ String rawNode = nodeMatcher.group();
+ String[] nodePieces = rawNode.split(",");
+
+ String identifier = nodePieces[0];
+ identifier = identifier.substring(identifier.indexOf("[") + 1, identifier.indexOf("]"));
+
+ String jvmRoute = nodePieces[1];
+ jvmRoute = jvmRoute.substring(jvmRoute.indexOf(':')).trim();
+
+ availableNodes.put(jvmRoute, new Node(jvmRoute, identifier));
+ }
+ }
+
+ private void parseVhosts(String rawProxyInfo) {
+ Pattern vhostPattern = Pattern.compile("Vhost:.*\n");
Matcher vhostMatcher = vhostPattern.matcher(rawProxyInfo);
while (vhostMatcher.find()) {
String rawVhost = vhostMatcher.group();
@@ -52,8 +76,10 @@ public class ProxyInfo {
availableVhosts.put(identifier, new Vhost(identifier, host));
}
+ }
- Pattern contextPattern = Pattern.compile("Context.*[\n|}]");
+ private void parseContexts(String rawProxyInfo) {
+ Pattern contextPattern = Pattern.compile("Context:.*[\n|}]");
Matcher contextMatcher = contextPattern.matcher(rawProxyInfo);
while (contextMatcher.find()) {
String rawContext = contextMatcher.group();
@@ -70,7 +96,7 @@ public class ProxyInfo {
Vhost relatedVhost = availableVhosts.get(identifier);
- availableContexts.add(new Context(relatedVhost.getHost(), actualContext, isEnabled));
+ availableContexts.add(new Context("", relatedVhost.getHost(), actualContext, isEnabled));
}
}
@@ -82,7 +108,60 @@ public class ProxyInfo {
return Collections.unmodifiableList(new ArrayList<Vhost>(availableVhosts.values()));
}
- private static class Vhost {
+ public List<Node> getAvailableNodes() {
+ return Collections.unmodifiableList(new ArrayList<Node>(availableNodes.values()));
+ }
+
+ public static class Node {
+ private String jvmRoute;
+ private String nodeId;
+
+ public Node(String jvmRoute, String nodeId) {
+ this.jvmRoute = jvmRoute;
+ this.nodeId = nodeId;
+ }
+
+ public String getNodeId() {
+ return nodeId;
+ }
+
+ public String getJvmRoute() {
+ return jvmRoute;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((jvmRoute == null) ? 0 : jvmRoute.hashCode());
+ result = prime * result + ((nodeId == null) ? 0 : nodeId.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Node other = (Node) obj;
+ if (jvmRoute == null) {
+ if (other.jvmRoute != null)
+ return false;
+ } else if (!jvmRoute.equals(other.jvmRoute))
+ return false;
+ if (nodeId == null) {
+ if (other.nodeId != null)
+ return false;
+ } else if (!nodeId.equals(other.nodeId))
+ return false;
+ return true;
+ }
+ }
+
+ public static class Vhost {
private String identifier;
private String host;
@@ -99,20 +178,52 @@ public class ProxyInfo {
return host;
}
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((host == null) ? 0 : host.hashCode());
+ result = prime * result + ((identifier == null) ? 0 : identifier.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Vhost other = (Vhost) obj;
+ if (host == null) {
+ if (other.host != null)
+ return false;
+ } else if (!host.equals(other.host))
+ return false;
+ if (identifier == null) {
+ if (other.identifier != null)
+ return false;
+ } else if (!identifier.equals(other.identifier))
+ return false;
+ return true;
+ }
}
public static class Context {
private String path;
private String host;
+ private String jvmRoute;
private boolean isEnabled;
- public Context(String host, String path) {
- this(path, host, false);
+ public Context(String jvmRoute, String host, String path) {
+ this(jvmRoute, host, path, false);
}
- public Context(String host, String path, boolean isEnabled) {
- this.path = path;
+ public Context(String jvmRoute, String host, String path, boolean isEnabled) {
+ this.jvmRoute = jvmRoute;
this.host = host;
+ this.path = path;
this.isEnabled = isEnabled;
}
@@ -124,13 +235,25 @@ public class ProxyInfo {
return host;
}
+ public String getJvmRoute() {
+ return jvmRoute;
+ }
+
public boolean isEnabled() {
return isEnabled;
}
+ public String createKey() {
+ return jvmRoute + ":" + host + ":" + path;
+ }
+
+ public String createName() {
+ return host + ":" + path;
+ }
+
@Override
public String toString() {
- return host + ":" + path;
+ return createKey();
}
@Override
@@ -138,6 +261,7 @@ public class ProxyInfo {
final int prime = 31;
int result = 1;
result = prime * result + ((host == null) ? 0 : host.hashCode());
+ result = prime * result + ((jvmRoute == null) ? 0 : jvmRoute.hashCode());
result = prime * result + ((path == null) ? 0 : path.hashCode());
return result;
}
@@ -156,6 +280,11 @@ public class ProxyInfo {
return false;
} else if (!host.equals(other.host))
return false;
+ if (jvmRoute == null) {
+ if (other.jvmRoute != null)
+ return false;
+ } else if (!jvmRoute.equals(other.jvmRoute))
+ return false;
if (path == null) {
if (other.path != null)
return false;
@@ -164,9 +293,13 @@ public class ProxyInfo {
return true;
}
- public static Context fromString(String stringRepresentation) {
- String part[] = stringRepresentation.trim().split(":");
- return new Context(part[1], part[0]);
+ public static Context fromString(String stringRepresentation) throws Exception {
+ String parts[] = stringRepresentation.trim().split(":");
+ if (parts.length < 3) {
+ throw new Exception("Parsing error. Not enough information to create a context.");
+ }
+
+ return new Context(parts[0], parts[1], parts[2]);
}
}
}
\ No newline at end of file
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index b1a0f51..3c01b30 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -25,7 +25,9 @@
<plugin-configuration>
<c:simple-property name="objectName" readOnly="true" default="Catalina:type=ModClusterListener,*"/>
- <c:simple-property name="nameTemplate" default="mod_cluster"/>
+ <c:simple-property name="additionalConfigurationObjectName" readOnly="true" default="jboss.web:type=Engine"/>
+ <c:simple-property name="jvmRoute" readOnly="false"/>
+ <c:simple-property name="nameTemplate" default="mod_cluster"/>
</plugin-configuration>
<operation name="stop" displayName="Stop all webapps" description="Gracefully stops all webapps for all engines.">
@@ -129,6 +131,5 @@
</service>
-
</service>
</plugin>
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
index 8c8c6f4..df7d222 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
@@ -35,7 +35,7 @@ public class ProxyInfoTest {
private Log log = LogFactory.getLog(this.getClass());
@Test
- public void testProxyInfo() throws IOException {
+ public void testProxyInfo() throws Exception {
String[] availableFiles = new String[] { "/proxy_config/proxy_config_1.txt", "/proxy_config/proxy_config_2.txt" };
for (String testConfigurationFile : availableFiles) {
commit 066fa71d4b3943ae6845d40c58c160e5c0c0631a
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Fri Jul 22 14:31:38 2011 -0500
Added support for stopContext operation for webapp contexts. Updated service description. Added more complex integration tests for webapp context service.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
index 42a1d6e..23d7d62 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
@@ -18,6 +18,8 @@
*/
package org.rhq.plugins.modcluster;
+import java.util.concurrent.TimeUnit;
+
import org.mc4j.ems.connection.bean.EmsBean;
import org.rhq.core.domain.configuration.Configuration;
@@ -75,11 +77,14 @@ public class ContextComponent extends MBeanResourceComponent<MBeanResourceCompon
Object[] configuration = null;
if ("stopContext".equals(name)) {
configuration = new Object[] { context.getHost(), context.getPath(),
- parameters.getSimple("timeout").getLongValue(), parameters.getSimple("unit").getStringValue() };
+ parameters.getSimple("timeout").getLongValue(),
+ TimeUnit.valueOf(parameters.getSimple("unit").getStringValue()) };
} else {
configuration = new Object[] { context.getHost(), context.getPath() };
}
+ log.info(name + " - " + context.getHost() + " " + context.getPath());
+
ClassLoader cl = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(getEmsBean().getClass().getClassLoader());
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
index 4b3adcd..7cefa46 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
@@ -52,7 +52,8 @@ public class ContextDiscoveryComponent implements ResourceDiscoveryComponent<MBe
for (ProxyInfo.Context availableContext : proxyInfo.getAvailableContexts()) {
DiscoveredResourceDetails detail = new DiscoveredResourceDetails(context.getResourceType(),
- availableContext.toString(), availableContext.toString(), null, "mod_cluster Context", null, null);
+ availableContext.toString(), availableContext.toString(), null, "mod_cluster Webapp Context", null,
+ null);
entities.add(detail);
}
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index 70a9f2b..b1a0f51 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -2,6 +2,7 @@
<plugin name="mod_cluster"
displayName="mod_cluster"
+ description="Monitoring and management of mod_cluster plugin."
version="1.0"
package="org.rhq.plugins.modcluster"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
@@ -77,7 +78,7 @@
<c:simple-property name="workerTimeout" type="integer" description="Timeout to wait for an available worker (default is no wait)" />
<c:simple-property name="stickySession" type="boolean" description="Enables sticky session for the cluster."/>
<c:simple-property name="stickySessionRemove" type="boolean" description="Remove session when the request cannot be routed to the right node."/>
- <c:simple-property name="advertise" type="boolean" description="Enable autodiscovery of httpd servers."/>
+ <!-- c:simple-property name="advertise" type="boolean" description="Enable autodiscovery of httpd servers."/-->
<c:simple-property name="smax" type="integer" description="Maximum time on seconds for idle connections above smax."/>
<c:simple-property name="maxAttempts" type="integer" description="Maximum number of attempts to send the request to the backend server."/>
<c:simple-property name="advertiseSecurityKey" type="string" required="false" description="Security key for discovery."/>
@@ -95,7 +96,7 @@
<service name="mod_cluster Webapp Context"
discovery="ContextDiscoveryComponent"
class="ContextComponent"
- description="A mod_cluster context">
+ description="mod_cluster webapp context">
<operation name="disableContext" displayName="Disable webapp" description="Disable this webapp.">
<results>
@@ -110,7 +111,9 @@
<c:option value="MICROSECONDS" name="MICROSECONDS"/>
<c:option value="MILLISECONDS" name="MILLISECONDS"/>
<c:option value="NANOSECONDS" name="NANOSECONDS"/>
- <c:option value="SECONDS" name="SECONDS"/>
+ <c:option value="SECONDS" name="SECONDS"/>
+ <c:option value="HOURS" name="HOURS"/>
+ <c:option value="DAYS" name="DAYS"/>
</c:property-options>
</c:simple-property>
</parameters>
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
index 8bead55..57aed4d 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
@@ -33,6 +33,8 @@ import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Test;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.measurement.MeasurementData;
import org.rhq.core.domain.measurement.MeasurementDefinition;
import org.rhq.core.domain.measurement.MeasurementReport;
@@ -159,11 +161,23 @@ public class ModclusterPluginTest {
try {
OperationResult result = ((OperationFacet) resourceComponent).invokeOperation("enableContext", null);
log.info("Result of operation " + "enableContext" + " was: " + result.getSimpleResult());
+
+ Configuration config = new Configuration();
+ config.put(new PropertySimple("timeout", "1000"));
+ config.put(new PropertySimple("unit", java.util.concurrent.TimeUnit.SECONDS));
+ result = ((OperationFacet) resourceComponent).invokeOperation("stopContext", config);
+ log.info("Result of operation stopContext was: " + result.getSimpleResult());
+
+ result = ((OperationFacet) resourceComponent).invokeOperation("enableContext", null);
+ log.info("Result of operation enableContext was: " + result.getSimpleResult());
+
+ result = ((OperationFacet) resourceComponent).invokeOperation("disableContext", null);
+ log.info("Result of operation disableContext was: " + result.getSimpleResult());
+
} catch (Exception e) {
- log.info("Operation failed");
+ log.info("Operation failed. ", e);
}
- /*result = ((OperationFacet) resourceComponent).invokeOperation("disable", null);
- log.info("Result of operation test was: " + result.getSimpleResult());*/
+
}
}
commit df80d823044c1566232df99540628507ac32e136
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Tue Jul 19 23:16:19 2011 -0500
Returning back to simple availability methods (no availability collectors) after getting clarifications from the mod_cluster team with regards to JMX attributes and node refresh operations.
The simple method to get availability now works correctly for mod_cluster resources.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
index 8512ed5..42a1d6e 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
@@ -42,15 +42,19 @@ public class ContextComponent extends MBeanResourceComponent<MBeanResourceCompon
try {
Thread.currentThread().setContextClassLoader(getEmsBean().getClass().getClassLoader());
String rawProxyInfo = (String) getEmsBean().getAttribute("proxyInfo").refresh().toString();
+
ProxyInfo proxyInfo = new ProxyInfo(rawProxyInfo);
ProxyInfo.Context context = ProxyInfo.Context.fromString(resourceContext.getResourceKey());
- ProxyInfo.Context currentContext = proxyInfo.getAvailableContexts().get(
- proxyInfo.getAvailableContexts().indexOf(context));
+ int indexOfCurrentContext = proxyInfo.getAvailableContexts().indexOf(context);
+
+ if (indexOfCurrentContext != -1) {
+ ProxyInfo.Context currentContext = proxyInfo.getAvailableContexts().get(indexOfCurrentContext);
- if (currentContext.isEnabled()) {
- return AvailabilityType.UP;
+ if (currentContext.isEnabled()) {
+ return AvailabilityType.UP;
+ }
}
return AvailabilityType.DOWN;
@@ -68,12 +72,18 @@ public class ContextComponent extends MBeanResourceComponent<MBeanResourceCompon
ProxyInfo.Context context = ProxyInfo.Context.fromString(resourceContext.getResourceKey());
+ Object[] configuration = null;
+ if ("stopContext".equals(name)) {
+ configuration = new Object[] { context.getHost(), context.getPath(),
+ parameters.getSimple("timeout").getLongValue(), parameters.getSimple("unit").getStringValue() };
+ } else {
+ configuration = new Object[] { context.getHost(), context.getPath() };
+ }
+
ClassLoader cl = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(getEmsBean().getClass().getClassLoader());
-
- Object resultObject = getEmsBean().getOperation(name).invoke(
- new Object[] { context.getHost(), context.getPath() });
+ Object resultObject = getEmsBean().getOperation(name).invoke(configuration);
return new OperationResult(String.valueOf(resultObject));
} finally {
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
index e6495a1..52dd287 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
@@ -18,13 +18,7 @@
*/
package org.rhq.plugins.modcluster;
-import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.measurement.AvailabilityType;
-import org.rhq.core.pluginapi.availability.AvailabilityCollectorRunnable;
-import org.rhq.core.pluginapi.availability.AvailabilityFacet;
-import org.rhq.core.pluginapi.inventory.ResourceComponent;
-import org.rhq.core.pluginapi.inventory.ResourceContext;
-import org.rhq.core.pluginapi.operation.OperationResult;
import org.rhq.plugins.jmx.MBeanResourceComponent;
/**
@@ -33,66 +27,18 @@ import org.rhq.plugins.jmx.MBeanResourceComponent;
*/
public class ModclusterServerComponent extends MBeanResourceComponent {
- private AvailabilityCollectorRunnable availabilityCollector;
-
- /* (non-Javadoc)
- * @see org.rhq.plugins.jmx.MBeanResourceComponent#start(org.rhq.core.pluginapi.inventory.ResourceContext)
- */
- @Override
- public void start(ResourceContext context) {
-
- availabilityCollector = context.createAvailabilityCollectorRunnable(new AvailabilityFacet() {
- public AvailabilityType getAvailability() {
- try {
- OperationResult result = ModclusterServerComponent.this.invokeOperation("refresh",
- new Configuration());
-
- int numberOfAttempts = 0;
-
- //The configuration should be loaded in less than 20 attempts.
- //Only in extraneous cases (like network overload or a huge list webapp contexts)
- //it can take more than this.
- while (numberOfAttempts < 20) {
- String rawProxyInfo = (String) getEmsBean().getAttribute("proxyInfo").refresh().toString();
- ProxyInfo proxyInfo = new ProxyInfo(rawProxyInfo);
-
- if (proxyInfo.getAvailableContexts().size() != 0) {
- break;
- }
-
- numberOfAttempts++;
- Thread.sleep(2000);
- }
- } catch (Exception e) {
- log.info("mod_cluster availability update failed. Node configuration could not be refreshed.", e);
- return AvailabilityType.DOWN;
- }
-
- return ModclusterServerComponent.super.getAvailability();
- }
- }, 60000L); // 1 minute - the minimum interval allowed
-
- // Now that you've created your availability collector, you must start it. Once started,
- // it is assigned a thread in a thread pool and begins periodically collecting availability.
- availabilityCollector.start();
-
- super.start(context);
- }
-
- /**
- * Cleans the old resource context and the old MBean.
- * @see ResourceComponent#stop()
- */
- public void stop() {
- availabilityCollector.stop();
- super.stop();
- }
-
/* (non-Javadoc)
* @see org.rhq.plugins.jmx.MBeanResourceComponent#getAvailability()
*/
@Override
public AvailabilityType getAvailability() {
- return availabilityCollector.getLastKnownAvailability();
+ String rawProxyInfo = (String) getEmsBean().getAttribute("proxyInfo").refresh().toString();
+ ProxyInfo proxyInfo = new ProxyInfo(rawProxyInfo);
+
+ if (proxyInfo.getAvailableContexts().size() == 0) {
+ return AvailabilityType.DOWN;
+ }
+
+ return super.getAvailability();
}
}
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
index c517364..36f490d 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
@@ -34,7 +34,7 @@ import java.util.regex.Pattern;
public class ProxyInfo {
private List<Context> availableContexts = new ArrayList<ProxyInfo.Context>();
- private Map<String, Vhost> availableVHosts = new HashMap<String, Vhost>();
+ private Map<String, Vhost> availableVhosts = new HashMap<String, Vhost>();
public ProxyInfo(String rawProxyInfo) {
Pattern vhostPattern = Pattern.compile("Vhost.*\n");
@@ -50,7 +50,7 @@ public class ProxyInfo {
String host = vhostPieces[1].trim();
host = host.substring(host.indexOf(":") + 1).trim();
- availableVHosts.put(identifier, new Vhost(identifier, host));
+ availableVhosts.put(identifier, new Vhost(identifier, host));
}
Pattern contextPattern = Pattern.compile("Context.*[\n|}]");
@@ -68,7 +68,7 @@ public class ProxyInfo {
rawIsEnabled = rawIsEnabled.substring(rawIsEnabled.indexOf(':') + 1).trim();
boolean isEnabled = rawIsEnabled.equals("ENABLED") ? true : false;
- Vhost relatedVhost = availableVHosts.get(identifier);
+ Vhost relatedVhost = availableVhosts.get(identifier);
availableContexts.add(new Context(relatedVhost.getHost(), actualContext, isEnabled));
}
@@ -78,6 +78,10 @@ public class ProxyInfo {
return Collections.unmodifiableList(availableContexts);
}
+ public List<Vhost> getAvailableVhosts() {
+ return Collections.unmodifiableList(new ArrayList<Vhost>(availableVhosts.values()));
+ }
+
private static class Vhost {
private String identifier;
private String host;
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
index b7322bd..8bead55 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
@@ -72,7 +72,7 @@ public class ModclusterPluginTest {
log.info("...Loaded plugin: " + plugin);
}
} catch (Exception e) {
- e.printStackTrace();
+ log.info("Error initializing the context", e);
}
}
@@ -93,19 +93,13 @@ public class ModclusterPluginTest {
public void testDiscovery() throws Exception {
InventoryReport report = PluginContainer.getInstance().getInventoryManager().executeServerScanImmediately();
assert report != null;
- System.out.println("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
+ log.info("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
- Thread.sleep(10000);
+ Thread.sleep(1000);
report = PluginContainer.getInstance().getInventoryManager().executeServiceScanImmediately();
assert report != null;
- System.out.println("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
-
- Thread.sleep(10000);
-
- report = PluginContainer.getInstance().getInventoryManager().executeServiceScanImmediately();
- assert report != null;
- System.out.println("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
+ log.info("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
List<String> typeNames = new ArrayList<String>() {
{
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
index fb1ccba..8c8c6f4 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
@@ -50,10 +50,21 @@ public class ProxyInfoTest {
+ ProxyInfo.Context.class.getCanonicalName();
}
- assert (proxyInfo.getAvailableContexts().size() != 0) : "Raw proxy info parsing failed!";
+ assert (proxyInfo.getAvailableContexts().size() != 0) : "Raw proxy info parsing failed to parse application contexts!";
+ assert (proxyInfo.getAvailableVhosts().size() != 0) : "Raw proxy info parsing failed to parse vhosts!";
}
}
+ @Test
+ public void testProxyInfoWithEmptyConfig() throws IOException {
+ String testConfigurationFile = "/proxy_config/proxy_config_empty.txt";
+ String testConfiguration = readConfigFile(testConfigurationFile);
+ ProxyInfo proxyInfo = new ProxyInfo(testConfiguration);
+
+ assert (proxyInfo.getAvailableContexts().size() == 0) : "Raw proxy info parsing failed to parse an empty proxy config.";
+ assert (proxyInfo.getAvailableVhosts().size() == 0) : "Raw proxy info parsing failed to parse an empty proxy config.";
+ }
+
private String readConfigFile(String filePath) throws IOException {
StringBuffer tempBuffer = new StringBuffer();
byte[] readBuffer = new byte[1024];
commit e7be518553e576305b16109aa4e98826ce7d00ae
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Fri Jul 15 15:40:54 2011 -0500
Implemented getAvailability using the async collector because there is no guarantee when node full refreshes its configuration. The configuration is read from the httpd proxy and parsed; so network latency and number of loaded contexts influence the reload time.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
index ef13143..e6495a1 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
@@ -20,6 +20,10 @@ package org.rhq.plugins.modcluster;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.pluginapi.availability.AvailabilityCollectorRunnable;
+import org.rhq.core.pluginapi.availability.AvailabilityFacet;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.core.pluginapi.operation.OperationResult;
import org.rhq.plugins.jmx.MBeanResourceComponent;
@@ -29,14 +33,66 @@ import org.rhq.plugins.jmx.MBeanResourceComponent;
*/
public class ModclusterServerComponent extends MBeanResourceComponent {
+ private AvailabilityCollectorRunnable availabilityCollector;
+
+ /* (non-Javadoc)
+ * @see org.rhq.plugins.jmx.MBeanResourceComponent#start(org.rhq.core.pluginapi.inventory.ResourceContext)
+ */
@Override
- public AvailabilityType getAvailability() {
- try {
- OperationResult result = this.invokeOperation("refresh", new Configuration());
- } catch (Exception e) {
- log.info(e);
- }
+ public void start(ResourceContext context) {
+
+ availabilityCollector = context.createAvailabilityCollectorRunnable(new AvailabilityFacet() {
+ public AvailabilityType getAvailability() {
+ try {
+ OperationResult result = ModclusterServerComponent.this.invokeOperation("refresh",
+ new Configuration());
+
+ int numberOfAttempts = 0;
+
+ //The configuration should be loaded in less than 20 attempts.
+ //Only in extraneous cases (like network overload or a huge list webapp contexts)
+ //it can take more than this.
+ while (numberOfAttempts < 20) {
+ String rawProxyInfo = (String) getEmsBean().getAttribute("proxyInfo").refresh().toString();
+ ProxyInfo proxyInfo = new ProxyInfo(rawProxyInfo);
+
+ if (proxyInfo.getAvailableContexts().size() != 0) {
+ break;
+ }
+
+ numberOfAttempts++;
+ Thread.sleep(2000);
+ }
+ } catch (Exception e) {
+ log.info("mod_cluster availability update failed. Node configuration could not be refreshed.", e);
+ return AvailabilityType.DOWN;
+ }
+
+ return ModclusterServerComponent.super.getAvailability();
+ }
+ }, 60000L); // 1 minute - the minimum interval allowed
- return super.getAvailability();
+ // Now that you've created your availability collector, you must start it. Once started,
+ // it is assigned a thread in a thread pool and begins periodically collecting availability.
+ availabilityCollector.start();
+
+ super.start(context);
+ }
+
+ /**
+ * Cleans the old resource context and the old MBean.
+ * @see ResourceComponent#stop()
+ */
+ public void stop() {
+ availabilityCollector.stop();
+ super.stop();
+ }
+
+ /* (non-Javadoc)
+ * @see org.rhq.plugins.jmx.MBeanResourceComponent#getAvailability()
+ */
+ @Override
+ public AvailabilityType getAvailability() {
+ return availabilityCollector.getLastKnownAvailability();
}
}
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
index 874011a..b7322bd 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
@@ -87,7 +87,6 @@ public class ModclusterPluginTest {
PluginEnvironment pluginEnvironment = pluginManager.getPlugin(PLUGIN_NAME);
assert (pluginEnvironment != null) : "Null environment, plugin not loaded";
assert (pluginEnvironment.getPluginName().equals(PLUGIN_NAME));
-
}
@Test(dependsOnMethods = "testPluginLoad")
@@ -96,6 +95,14 @@ public class ModclusterPluginTest {
assert report != null;
System.out.println("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
+ Thread.sleep(10000);
+
+ report = PluginContainer.getInstance().getInventoryManager().executeServiceScanImmediately();
+ assert report != null;
+ System.out.println("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
+
+ Thread.sleep(10000);
+
report = PluginContainer.getInstance().getInventoryManager().executeServiceScanImmediately();
assert report != null;
System.out.println("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
@@ -103,7 +110,7 @@ public class ModclusterPluginTest {
List<String> typeNames = new ArrayList<String>() {
{
add(PLUGIN_NAME);
- add(PLUGIN_NAME + "_context");
+ add(PLUGIN_NAME + " Webapp Context");
}
};
diff --git a/modules/plugins/mod-cluster/src/test/resources/proxy_config/proxy_config_empty.txt b/modules/plugins/mod-cluster/src/test/resources/proxy_config/proxy_config_empty.txt
new file mode 100644
index 0000000..815b8a4
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/test/resources/proxy_config/proxy_config_empty.txt
@@ -0,0 +1 @@
+{192.168.0.101/192.168.0.101:6666=null}
commit 19c02c04340a49aae6749166e175a96a4602f2d7
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Mon Jul 11 15:33:59 2011 -0500
A couple of small configuration and test corrections.
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index cf12b89..70a9f2b 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -60,7 +60,7 @@
<c:simple-property name="result" type="boolean" description="The result of the operation" />
</results>
</operation>
- <operation name="refreshProxy" displayName="Remove a proxy" description="Remove a proxy.">
+ <operation name="removeProxy" displayName="Remove a proxy" description="Remove a proxy.">
<parameters>
<c:simple-property required="true" name="host" type="string" displayName="Proxy address"/>
<c:simple-property required="true" name="port" type="string" displayName="Proxy port"/>
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
index 41bf26a..fb1ccba 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
@@ -36,7 +36,6 @@ public class ProxyInfoTest {
@Test
public void testProxyInfo() throws IOException {
-
String[] availableFiles = new String[] { "/proxy_config/proxy_config_1.txt", "/proxy_config/proxy_config_2.txt" };
for (String testConfigurationFile : availableFiles) {
@@ -44,10 +43,6 @@ public class ProxyInfoTest {
ProxyInfo proxyInfo = new ProxyInfo(testConfiguration);
for (ProxyInfo.Context context : proxyInfo.getAvailableContexts()) {
- log.info(context.toString() + " - " + context.isEnabled());
-
- log.info(proxyInfo.getAvailableContexts().indexOf(context));
-
assert (proxyInfo.getAvailableContexts().indexOf(context) != -1) : "Equals and hash functions not implemented correctly for "
+ ProxyInfo.Context.class.getCanonicalName();
commit 8f5f1559d0d45b7405334d588b5272254ac119c9
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Mon Jul 11 15:33:39 2011 -0500
The configuration needs to be refreshed before computing availability on all the contexts. Attempt to correctly invoke the operation.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
index 783f579..ef13143 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
@@ -18,6 +18,9 @@
*/
package org.rhq.plugins.modcluster;
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.pluginapi.operation.OperationResult;
import org.rhq.plugins.jmx.MBeanResourceComponent;
/**
@@ -25,4 +28,15 @@ import org.rhq.plugins.jmx.MBeanResourceComponent;
*
*/
public class ModclusterServerComponent extends MBeanResourceComponent {
+
+ @Override
+ public AvailabilityType getAvailability() {
+ try {
+ OperationResult result = this.invokeOperation("refresh", new Configuration());
+ } catch (Exception e) {
+ log.info(e);
+ }
+
+ return super.getAvailability();
+ }
}
commit ae2f827b434bb95c2bcf76f7d5a3e1e07f910d90
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Mon Jul 11 13:23:22 2011 -0500
Added availability attribute for contexts. Also improved unit test and coverage.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
index 922197a..8512ed5 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
@@ -21,6 +21,7 @@ package org.rhq.plugins.modcluster;
import org.mc4j.ems.connection.bean.EmsBean;
import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.pluginapi.operation.OperationResult;
import org.rhq.plugins.jmx.MBeanResourceComponent;
@@ -36,18 +37,43 @@ public class ContextComponent extends MBeanResourceComponent<MBeanResourceCompon
}
@Override
+ public AvailabilityType getAvailability() {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ try {
+ Thread.currentThread().setContextClassLoader(getEmsBean().getClass().getClassLoader());
+ String rawProxyInfo = (String) getEmsBean().getAttribute("proxyInfo").refresh().toString();
+ ProxyInfo proxyInfo = new ProxyInfo(rawProxyInfo);
+
+ ProxyInfo.Context context = ProxyInfo.Context.fromString(resourceContext.getResourceKey());
+
+ ProxyInfo.Context currentContext = proxyInfo.getAvailableContexts().get(
+ proxyInfo.getAvailableContexts().indexOf(context));
+
+ if (currentContext.isEnabled()) {
+ return AvailabilityType.UP;
+ }
+
+ return AvailabilityType.DOWN;
+ } catch (Exception e) {
+ log.info(e);
+ return AvailabilityType.DOWN;
+ } finally {
+ Thread.currentThread().setContextClassLoader(cl);
+ }
+ }
+
+ @Override
public OperationResult invokeOperation(String name, Configuration parameters) throws Exception {
if ("enableContext".equals(name) || "disableContext".equals(name) || "stopContext".equals(name)) {
ProxyInfo.Context context = ProxyInfo.Context.fromString(resourceContext.getResourceKey());
- System.out.println(context.toString());
ClassLoader cl = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(getEmsBean().getClass().getClassLoader());
Object resultObject = getEmsBean().getOperation(name).invoke(
- new Object[] { context.host, context.path });
+ new Object[] { context.getHost(), context.getPath() });
return new OperationResult(String.valueOf(resultObject));
} finally {
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
index 40b24f9..c517364 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
@@ -50,9 +50,7 @@ public class ProxyInfo {
String host = vhostPieces[1].trim();
host = host.substring(host.indexOf(":") + 1).trim();
- System.out.println(identifier + "--" + host);
availableVHosts.put(identifier, new Vhost(identifier, host));
-
}
Pattern contextPattern = Pattern.compile("Context.*[\n|}]");
@@ -65,9 +63,14 @@ public class ProxyInfo {
String identifier = contextPieces[0];
identifier = identifier.substring(identifier.indexOf("[") + 1, identifier.indexOf("]"));
identifier = identifier.substring(0, identifier.lastIndexOf(":"));
+
+ String rawIsEnabled = contextPieces[2];
+ rawIsEnabled = rawIsEnabled.substring(rawIsEnabled.indexOf(':') + 1).trim();
+ boolean isEnabled = rawIsEnabled.equals("ENABLED") ? true : false;
+
Vhost relatedVhost = availableVHosts.get(identifier);
- availableContexts.add(new Context(relatedVhost.getHost(), actualContext));
+ availableContexts.add(new Context(relatedVhost.getHost(), actualContext, isEnabled));
}
}
@@ -95,12 +98,18 @@ public class ProxyInfo {
}
public static class Context {
- String path;
- String host;
+ private String path;
+ private String host;
+ private boolean isEnabled;
public Context(String host, String path) {
+ this(path, host, false);
+ }
+
+ public Context(String host, String path, boolean isEnabled) {
this.path = path;
this.host = host;
+ this.isEnabled = isEnabled;
}
public String getPath() {
@@ -111,14 +120,49 @@ public class ProxyInfo {
return host;
}
+ public boolean isEnabled() {
+ return isEnabled;
+ }
+
@Override
public String toString() {
return host + ":" + path;
}
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((host == null) ? 0 : host.hashCode());
+ result = prime * result + ((path == null) ? 0 : path.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Context other = (Context) obj;
+ if (host == null) {
+ if (other.host != null)
+ return false;
+ } else if (!host.equals(other.host))
+ return false;
+ if (path == null) {
+ if (other.path != null)
+ return false;
+ } else if (!path.equals(other.path))
+ return false;
+ return true;
+ }
+
public static Context fromString(String stringRepresentation) {
String part[] = stringRepresentation.trim().split(":");
- return new Context(part[0], part[1]);
+ return new Context(part[1], part[0]);
}
}
}
\ No newline at end of file
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
index be5e987..41bf26a 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
@@ -37,15 +37,26 @@ public class ProxyInfoTest {
@Test
public void testProxyInfo() throws IOException {
- String testConfiguration = readConfigFile("/proxy_config/proxy_config_1.txt");
+ String[] availableFiles = new String[] { "/proxy_config/proxy_config_1.txt", "/proxy_config/proxy_config_2.txt" };
- ProxyInfo proxyInfo = new ProxyInfo(testConfiguration);
+ for (String testConfigurationFile : availableFiles) {
+ String testConfiguration = readConfigFile(testConfigurationFile);
+ ProxyInfo proxyInfo = new ProxyInfo(testConfiguration);
- for (ProxyInfo.Context context : proxyInfo.getAvailableContexts()) {
- log.info(context.toString());
- }
+ for (ProxyInfo.Context context : proxyInfo.getAvailableContexts()) {
+ log.info(context.toString() + " - " + context.isEnabled());
+
+ log.info(proxyInfo.getAvailableContexts().indexOf(context));
+
+ assert (proxyInfo.getAvailableContexts().indexOf(context) != -1) : "Equals and hash functions not implemented correctly for "
+ + ProxyInfo.Context.class.getCanonicalName();
- assert (proxyInfo.getAvailableContexts().size() != 0) : "Raw proxy info parsing failed!";
+ assert (context.equals(ProxyInfo.Context.fromString(context.toString())) == true) : "fromString and toString are not equivalent for:"
+ + ProxyInfo.Context.class.getCanonicalName();
+ }
+
+ assert (proxyInfo.getAvailableContexts().size() != 0) : "Raw proxy info parsing failed!";
+ }
}
private String readConfigFile(String filePath) throws IOException {
diff --git a/modules/plugins/mod-cluster/src/test/resources/proxy_config/proxy_config_2.txt b/modules/plugins/mod-cluster/src/test/resources/proxy_config/proxy_config_2.txt
new file mode 100644
index 0000000..573967a
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/test/resources/proxy_config/proxy_config_2.txt
@@ -0,0 +1,16 @@
+{mobile-work/192.168.1.40:6666=Node: [1],Name: 4e6189af-0502-3305-8ff3-fad7fee8b516,Balancer: mycluster,LBGroup: ,Host: 127.0.0.1,Port: 8009,Type: ajp,Flushpackets: Off,Flushwait: 10,Ping: 10,Smax: 26,Ttl: 60,Elected: 3690,Read: 27864911,Transfered: 0,Connected: 0,Load: 100
+Node: [2],Name: node2,Balancer: mycluster,LBGroup: ,Host: 127.0.0.1,Port: 8009,Type: ajp,Flushpackets: Off,Flushwait: 10,Ping: 10,Smax: 26,Ttl: 60,Elected: 148,Read: 57994,Transfered: 0,Connected: 0,Load: 100
+Vhost: [1:1:1], Alias: test-agent-1
+Vhost: [2:1:2], Alias: remote-agent-2
+Context: [1:1:1], Context: /invoker, Status: DISABLED
+Context: [1:1:2], Context: /loaddemo, Status: DISABLED
+Context: [1:1:3], Context: /jbossws, Status: DISABLED
+Context: [1:1:4], Context: /juddi, Status: DISABLED
+Context: [1:1:5], Context: /jbossmq-httpil, Status: DISABLED
+Context: [1:1:6], Context: /web-console, Status: DISABLED
+Context: [1:1:7], Context: /jmx-console, Status: DISABLED
+Context: [1:1:8], Context: /, Status: DISABLED
+Context: [2:1:9], Context: /, Status: ENABLED
+Context: [2:1:10], Context: /loaddemo, Status: ENABLED
+Context: [2:1:11], Context: /juddi, Status: ENABLED
+Context: [2:1:12], Context: /invoker, Status: ENABLED}
\ No newline at end of file
commit 1ea6e2e37dd183c05072cbbc48e664deaa88da68
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Thu Jul 7 16:37:41 2011 -0500
Created separate unit test suite for proxy info parser. Also, the code now parses the vhost from the actual config property.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
index f2af2bc..40b24f9 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
@@ -20,7 +20,9 @@ package org.rhq.plugins.modcluster;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -32,17 +34,40 @@ import java.util.regex.Pattern;
public class ProxyInfo {
private List<Context> availableContexts = new ArrayList<ProxyInfo.Context>();
+ private Map<String, Vhost> availableVHosts = new HashMap<String, Vhost>();
public ProxyInfo(String rawProxyInfo) {
+ Pattern vhostPattern = Pattern.compile("Vhost.*\n");
+ Matcher vhostMatcher = vhostPattern.matcher(rawProxyInfo);
+ while (vhostMatcher.find()) {
+ String rawVhost = vhostMatcher.group();
+ String[] vhostPieces = rawVhost.split(",");
- Pattern test = Pattern.compile("Context.*\n");
- Matcher m = test.matcher(rawProxyInfo);
- while (m.find()) {
- String rawContext = m.group();
+ String identifier = vhostPieces[0].trim();
+ identifier = identifier.substring(identifier.indexOf("[") + 1, identifier.indexOf("]"));
+ identifier = identifier.substring(0, identifier.lastIndexOf(":"));
+
+ String host = vhostPieces[1].trim();
+ host = host.substring(host.indexOf(":") + 1).trim();
+
+ System.out.println(identifier + "--" + host);
+ availableVHosts.put(identifier, new Vhost(identifier, host));
+
+ }
+
+ Pattern contextPattern = Pattern.compile("Context.*[\n|}]");
+ Matcher contextMatcher = contextPattern.matcher(rawProxyInfo);
+ while (contextMatcher.find()) {
+ String rawContext = contextMatcher.group();
String[] contextPieces = rawContext.split(",");
String actualContext = contextPieces[1].substring(contextPieces[1].indexOf("/")).trim();
- availableContexts.add(new Context("localhost", actualContext));
+ String identifier = contextPieces[0];
+ identifier = identifier.substring(identifier.indexOf("[") + 1, identifier.indexOf("]"));
+ identifier = identifier.substring(0, identifier.lastIndexOf(":"));
+ Vhost relatedVhost = availableVHosts.get(identifier);
+
+ availableContexts.add(new Context(relatedVhost.getHost(), actualContext));
}
}
@@ -50,6 +75,25 @@ public class ProxyInfo {
return Collections.unmodifiableList(availableContexts);
}
+ private static class Vhost {
+ private String identifier;
+ private String host;
+
+ public Vhost(String identifier, String host) {
+ this.identifier = identifier;
+ this.host = host;
+ }
+
+ public String getIdentifier() {
+ return identifier;
+ }
+
+ public String getHost() {
+ return host;
+ }
+
+ }
+
public static class Context {
String path;
String host;
@@ -63,18 +107,10 @@ public class ProxyInfo {
return path;
}
- public void setPath(String path) {
- this.path = path;
- }
-
public String getHost() {
return host;
}
- public void setHost(String host) {
- this.host = host;
- }
-
@Override
public String toString() {
return host + ":" + path;
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
index 0d16e92..874011a 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
@@ -47,10 +47,9 @@ import org.rhq.core.pluginapi.inventory.ResourceComponent;
import org.rhq.core.pluginapi.measurement.MeasurementFacet;
import org.rhq.core.pluginapi.operation.OperationFacet;
import org.rhq.core.pluginapi.operation.OperationResult;
-import org.rhq.plugins.modcluster.ProxyInfo;
/**
- * @author Fady Matar
+ * @author Stefan Negrea
*/
@Test(groups = "modcluster-plugin")
public class ModclusterPluginTest {
@@ -83,31 +82,6 @@ public class ModclusterPluginTest {
}
@Test
- public void testProxyInfo() {
- String test = "{mobile-work/192.168.1.40:6666=Node: [1],Name: 4e6189af-0502-3305-8ff3-fad7fee8b516,Balancer: mycluster,LBGroup: ,Host: 127.0.0.1,Port: 8009,Type: ajp,Flushpackets: Off,Flushwait: 10,Ping: 10,Smax: 26,Ttl: 60,Elected: 3233,Read: 7355619,Transfered: 0,Connected: 0,Load: 100\n"
- + "Node: [2],Name: node2,Balancer: mycluster,LBGroup: ,Host: 127.0.0.1,Port: 8009,Type: ajp,Flushpackets: Off,Flushwait: 10,Ping: 10,Smax: 26,Ttl: 60,Elected: 0,Read: 0,Transfered: 0,Connected: 0,Load: 99\n"
- + "Vhost: [1:1:1], Alias: localhost\n"
- + "Vhost: [2:1:2], Alias: localhost\n"
- + "Context: [1:1:1], Context: /invoker, Status: DISABLED\n"
- + "Context: [1:1:2], Context: /loaddemo, Status: DISABLED\n"
- + "Context: [1:1:3], Context: /jbossws, Status: DISABLED\n"
- + "Context: [1:1:4], Context: /juddi, Status: DISABLED\n"
- + "Context: [1:1:5], Context: /jbossmq-httpil, Status: DISABLED\n"
- + "Context: [1:1:6], Context: /web-console, Status: DISABLED\n"
- + "Context: [1:1:7], Context: /jmx-console, Status: DISABLED\n"
- + "Context: [1:1:8], Context: /, Status: DISABLED\n"
- + "Context: [2:1:9], Context: /loaddemo, Status: ENABLED\n" + "}";
-
- ProxyInfo proxyInfo = new ProxyInfo(test);
-
- for (ProxyInfo.Context context : proxyInfo.getAvailableContexts()) {
- log.info(context.toString());
- }
-
- assert (proxyInfo.getAvailableContexts().size() != 0) : "Raw proxy info parsing failed!";
- }
-
- @Test
public void testPluginLoad() {
PluginManager pluginManager = PluginContainer.getInstance().getPluginManager();
PluginEnvironment pluginEnvironment = pluginManager.getPlugin(PLUGIN_NAME);
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
new file mode 100644
index 0000000..be5e987
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ProxyInfoTest.java
@@ -0,0 +1,66 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.modcluster.test;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.testng.annotations.Test;
+
+import org.rhq.plugins.modcluster.ProxyInfo;
+
+/**
+ * @author Stefan Negrea
+ */
+@Test(groups = "modcluster-plugin")
+public class ProxyInfoTest {
+ private Log log = LogFactory.getLog(this.getClass());
+
+ @Test
+ public void testProxyInfo() throws IOException {
+
+ String testConfiguration = readConfigFile("/proxy_config/proxy_config_1.txt");
+
+ ProxyInfo proxyInfo = new ProxyInfo(testConfiguration);
+
+ for (ProxyInfo.Context context : proxyInfo.getAvailableContexts()) {
+ log.info(context.toString());
+ }
+
+ assert (proxyInfo.getAvailableContexts().size() != 0) : "Raw proxy info parsing failed!";
+ }
+
+ private String readConfigFile(String filePath) throws IOException {
+ StringBuffer tempBuffer = new StringBuffer();
+ byte[] readBuffer = new byte[1024];
+ int bytesRead = 0;
+
+ InputStream resourceStream = getClass().getResourceAsStream(filePath);
+
+ while ((bytesRead = resourceStream.read(readBuffer)) != -1) {
+ tempBuffer.append(new String(readBuffer, 0, bytesRead));
+ }
+
+ resourceStream.close();
+
+ return tempBuffer.toString();
+ }
+}
\ No newline at end of file
diff --git a/modules/plugins/mod-cluster/src/test/resources/proxy_config/proxy_config_1.txt b/modules/plugins/mod-cluster/src/test/resources/proxy_config/proxy_config_1.txt
new file mode 100644
index 0000000..c99edd3
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/test/resources/proxy_config/proxy_config_1.txt
@@ -0,0 +1,13 @@
+{mobile-work/192.168.1.40:6666=Node: [1],Name: 4e6189af-0502-3305-8ff3-fad7fee8b516,Balancer: mycluster,LBGroup: ,Host: 127.0.0.1,Port: 8009,Type: ajp,Flushpackets: Off,Flushwait: 10,Ping: 10,Smax: 26,Ttl: 60,Elected: 3233,Read: 7355619,Transfered: 0,Connected: 0,Load: 100
+Node: [2],Name: node2,Balancer: mycluster,LBGroup: ,Host: 127.0.0.1,Port: 8009,Type: ajp,Flushpackets: Off,Flushwait: 10,Ping: 10,Smax: 26,Ttl: 60,Elected: 0,Read: 0,Transfered: 0,Connected: 0,Load: 99
+Vhost: [1:1:1], Alias: localhost
+Vhost: [2:1:2], Alias: localhost
+Context: [1:1:1], Context: /invoker, Status: DISABLED
+Context: [1:1:2], Context: /loaddemo, Status: DISABLED
+Context: [1:1:3], Context: /jbossws, Status: DISABLED
+Context: [1:1:4], Context: /juddi, Status: DISABLED
+Context: [1:1:5], Context: /jbossmq-httpil, Status: DISABLED
+Context: [1:1:6], Context: /web-console, Status: DISABLED
+Context: [1:1:7], Context: /jmx-console, Status: DISABLED
+Context: [1:1:8], Context: /, Status: DISABLED
+Context: [2:1:9], Context: /loaddemo, Status: ENABLED}
\ No newline at end of file
commit 98d1af05eae3cd7013b6a2315c601a29b62ab641
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Thu Jul 7 13:27:01 2011 -0600
Fine tunning the plugin based on UI testing.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
index fb72b5f..f2af2bc 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
@@ -77,7 +77,7 @@ public class ProxyInfo {
@Override
public String toString() {
- return path + ":" + host;
+ return host + ":" + path;
}
public static Context fromString(String stringRepresentation) {
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index 88357db..cf12b89 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -80,15 +80,14 @@
<c:simple-property name="advertise" type="boolean" description="Enable autodiscovery of httpd servers."/>
<c:simple-property name="smax" type="integer" description="Maximum time on seconds for idle connections above smax."/>
<c:simple-property name="maxAttempts" type="integer" description="Maximum number of attempts to send the request to the backend server."/>
- <c:simple-property name="advertiseSecurityKey" type="integer" description="Security key for discovery."/>
+ <c:simple-property name="advertiseSecurityKey" type="string" required="false" description="Security key for discovery."/>
<c:simple-property name="stickySessionForce" type="boolean" description="Return an error when the request cannot be routed to the right node."/>
- <c:simple-property name="balancer" type="string" description="Name of the balancer."/>
+ <c:simple-property name="balancer" type="string" required="false" description="Name of the balancer."/>
<c:simple-property name="flushPackets" type="boolean" description="Allows controlling flusing of packets."/>
- <c:simple-property name="socketTimeout" type="integer" description="Connection timeout for communication with the proxy." />
- <c:simple-property name="containerName" type="string" description="Object name of the container."/>
- <c:simple-property name="domain" type="string" description="Domain parameter, which allows tying a jvmRoute to a particular domain."/>
- <c:simple-property name="advertisePort" type="integer" description="Multicast port for discovery" />
- <c:simple-property name="advertiseGroupAddress" type="string" description="Multicast address for discovery."/>
+ <c:simple-property name="socketTimeout" type="integer" description="Connection timeout for communication with the proxy." />
+ <c:simple-property name="domain" type="string" required="false" description="Domain parameter, which allows tying a jvmRoute to a particular domain."/>
+ <c:simple-property name="advertisePort" type="integer" required="false" description="Multicast port for discovery" />
+ <c:simple-property name="advertiseGroupAddress" type="string" required="false" description="Multicast address for discovery."/>
<c:simple-property name="flushWait" type="integer" description="Time in ms to wait before flushing packets."/>
<c:simple-property name="ping" type="integer" description="Time in s to wait for a pong answer to a ping."/>
</resource-configuration>
commit 96a80b66d1a918c012cc3825ef151df87c42a0ec
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Thu Jul 7 10:38:53 2011 -0600
Changed the name of context objects to the proposed short notation.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
index 9cb6b86..fb72b5f 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
@@ -42,7 +42,7 @@ public class ProxyInfo {
String[] contextPieces = rawContext.split(",");
String actualContext = contextPieces[1].substring(contextPieces[1].indexOf("/")).trim();
- availableContexts.add(new Context(actualContext, "localhost"));
+ availableContexts.add(new Context("localhost", actualContext));
}
}
@@ -54,7 +54,7 @@ public class ProxyInfo {
String path;
String host;
- public Context(String path, String host) {
+ public Context(String host, String path) {
this.path = path;
this.host = host;
}
@@ -77,25 +77,12 @@ public class ProxyInfo {
@Override
public String toString() {
- return "Context [path=" + path + ", host=" + host + "]";
+ return path + ":" + host;
}
public static Context fromString(String stringRepresentation) {
- stringRepresentation = stringRepresentation.substring(stringRepresentation.indexOf('[') + 1);
- stringRepresentation = stringRepresentation.substring(0, stringRepresentation.indexOf(']'));
- stringRepresentation = stringRepresentation.trim();
-
- String host = null;
- String path = null;
- for (String part : stringRepresentation.split(",")) {
- part = part.trim();
- if (part.startsWith("path=")) {
- path = part.substring(5).trim();
- } else if (part.startsWith("host=")) {
- host = part.substring(5).trim();
- }
- }
- return new Context(path, host);
+ String part[] = stringRepresentation.trim().split(":");
+ return new Context(part[0], part[1]);
}
}
}
\ No newline at end of file
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index ad23d34..88357db 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -74,7 +74,7 @@
<metric property="className" displayName="Fully qualified class name of the managed object" displayType="summary" dataType="trait" />
<resource-configuration>
- <c:simple-property name="workerTimeout" type="integer" description="Timeout to wait for an available worker (default is no wait)"
+ <c:simple-property name="workerTimeout" type="integer" description="Timeout to wait for an available worker (default is no wait)" />
<c:simple-property name="stickySession" type="boolean" description="Enables sticky session for the cluster."/>
<c:simple-property name="stickySessionRemove" type="boolean" description="Remove session when the request cannot be routed to the right node."/>
<c:simple-property name="advertise" type="boolean" description="Enable autodiscovery of httpd servers."/>
@@ -83,7 +83,7 @@
<c:simple-property name="advertiseSecurityKey" type="integer" description="Security key for discovery."/>
<c:simple-property name="stickySessionForce" type="boolean" description="Return an error when the request cannot be routed to the right node."/>
<c:simple-property name="balancer" type="string" description="Name of the balancer."/>
- <c:simple-property name="flushPackets" type="boolean" descritpion="Allows controlling flusing of packets."/>
+ <c:simple-property name="flushPackets" type="boolean" description="Allows controlling flusing of packets."/>
<c:simple-property name="socketTimeout" type="integer" description="Connection timeout for communication with the proxy." />
<c:simple-property name="containerName" type="string" description="Object name of the container."/>
<c:simple-property name="domain" type="string" description="Domain parameter, which allows tying a jvmRoute to a particular domain."/>
commit 109bdc7c6ce20c3b514679be08f1735955945aa3
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Thu Jul 7 10:23:06 2011 -0600
Added support for all the mod_cluster available operations.
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index 17a4267..ad23d34 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -27,41 +27,70 @@
<c:simple-property name="nameTemplate" default="mod_cluster"/>
</plugin-configuration>
- <operation name="reset" displayName="Reset the node" description="Move the node out of an error state" />
- <operation name="refresh" displayName="Refresh configuration" description="Refresh configuration" />
- <operation name="enable" displayName="Enable all webapps" description="Enable all webapps for all engines">
+ <operation name="stop" displayName="Stop all webapps" description="Gracefully stops all webapps for all engines.">
+ <parameters>
+ <c:simple-property required="true" name="timeout" type="string" displayName="Session draining timeout"/>
+ <c:simple-property required="true" name="unit" default="MILLISECONDS" displayName="Time unit of the timeout parameter">
+ <c:property-options allowCustomValue="false">
+ <c:option value="MICROSECONDS" name="MICROSECONDS"/>
+ <c:option value="MILLISECONDS" name="MILLISECONDS"/>
+ <c:option value="NANOSECONDS" name="NANOSECONDS"/>
+ <c:option value="SECONDS" name="SECONDS"/>
+ </c:property-options>
+ </c:simple-property>
+ </parameters>
+ <results>
+ <c:simple-property name="result" type="boolean" description="The result of the operation" />
+ </results>
+ </operation>
+ <operation name="addProxy" displayName="Add a proxy" description="Add a proxy.">
+ <parameters>
+ <c:simple-property required="true" name="host" type="string" displayName="Proxy address"/>
+ <c:simple-property required="true" name="port" type="string" displayName="Proxy port"/>
+ </parameters>
+ </operation>
+ <operation name="enable" displayName="Enable all webapps" description="Enable all webapps for all engines">
<results>
<c:simple-property name="result" type="boolean" description="The result of the operation" />
</results>
- </operation>
- <operation name="disable" displayName="Disable all webpapps" description="Disable all webapps for all engines">
+ </operation>
+ <operation name="reset" displayName="Reset the node" description="Move the node out of an error state." />
+ <operation name="disable" displayName="Disable all webpapps" description="Disable all webapps for all engines.">
<results>
<c:simple-property name="result" type="boolean" description="The result of the operation" />
</results>
</operation>
+ <operation name="refreshProxy" displayName="Remove a proxy" description="Remove a proxy.">
+ <parameters>
+ <c:simple-property required="true" name="host" type="string" displayName="Proxy address"/>
+ <c:simple-property required="true" name="port" type="string" displayName="Proxy port"/>
+ </parameters>
+ </operation>
+ <operation name="refresh" displayName="Refresh configuration" description="Refresh configuration" />
+
<metric property="proxyConfiguration" displayName="Proxy Configuration" displayType="summary" dataType="trait" />
<metric property="modelerType" displayName="Type of the modeled resource" displayType="summary" dataType="trait" />
<metric property="className" displayName="Fully qualified class name of the managed object" displayType="summary" dataType="trait" />
<resource-configuration>
- <c:simple-property name="workerTimeout" type="int" description="Timeout to wait for an available worker (default is no wait)"
+ <c:simple-property name="workerTimeout" type="integer" description="Timeout to wait for an available worker (default is no wait)"
<c:simple-property name="stickySession" type="boolean" description="Enables sticky session for the cluster."/>
<c:simple-property name="stickySessionRemove" type="boolean" description="Remove session when the request cannot be routed to the right node."/>
<c:simple-property name="advertise" type="boolean" description="Enable autodiscovery of httpd servers."/>
- <c:simple-property name="smax" type="int" description="Maximum time on seconds for idle connections above smax."/>
- <c:simple-property name="maxAttempts" type="int" description="Maximum number of attempts to send the request to the backend server."/>
- <c:simple-property name="advertiseSecurityKey" type="int" description="Security key for discovery."/>
+ <c:simple-property name="smax" type="integer" description="Maximum time on seconds for idle connections above smax."/>
+ <c:simple-property name="maxAttempts" type="integer" description="Maximum number of attempts to send the request to the backend server."/>
+ <c:simple-property name="advertiseSecurityKey" type="integer" description="Security key for discovery."/>
<c:simple-property name="stickySessionForce" type="boolean" description="Return an error when the request cannot be routed to the right node."/>
<c:simple-property name="balancer" type="string" description="Name of the balancer."/>
<c:simple-property name="flushPackets" type="boolean" descritpion="Allows controlling flusing of packets."/>
- <c:simple-property name="socketTimeout" type="int" description="Connection timeout for communication with the proxy." />
+ <c:simple-property name="socketTimeout" type="integer" description="Connection timeout for communication with the proxy." />
<c:simple-property name="containerName" type="string" description="Object name of the container."/>
<c:simple-property name="domain" type="string" description="Domain parameter, which allows tying a jvmRoute to a particular domain."/>
- <c:simple-property name="advertisePort" type="int" description="Multicast port for discovery" />
+ <c:simple-property name="advertisePort" type="integer" description="Multicast port for discovery" />
<c:simple-property name="advertiseGroupAddress" type="string" description="Multicast address for discovery."/>
- <c:simple-property name="flushWait" type="int" description="Time in ms to wait before flushing packets."/>
- <c:simple-property name="ping" type="int" description="Time in s to wait for a pong answer to a ping"/>
+ <c:simple-property name="flushWait" type="integer" description="Time in ms to wait before flushing packets."/>
+ <c:simple-property name="ping" type="integer" description="Time in s to wait for a pong answer to a ping."/>
</resource-configuration>
<service name="mod_cluster Webapp Context"
@@ -69,19 +98,30 @@
class="ContextComponent"
description="A mod_cluster context">
- <operation name="enableContext" displayName="Enable webapp" description="Enable this webapp">
+ <operation name="disableContext" displayName="Disable webapp" description="Disable this webapp.">
<results>
- <c:simple-property name="result" type="boolean" description="The result of the operation" />
+ <c:simple-property name="result" type="boolean" description="The result of the operation."/>
</results>
</operation>
- <operation name="disableContext" displayName="Disable webapp" description="Disable this webapp">
+ <operation name="stopContext" displayName="Stop webapp" description="Gracefully stops this webapp.">
+ <parameters>
+ <c:simple-property required="true" name="timeout" type="integer" displayName="Session draining timeout"/>
+ <c:simple-property required="true" name="unit" default="MILLISECONDS" displayName="Time unit of the timeout parameter">
+ <c:property-options allowCustomValue="false">
+ <c:option value="MICROSECONDS" name="MICROSECONDS"/>
+ <c:option value="MILLISECONDS" name="MILLISECONDS"/>
+ <c:option value="NANOSECONDS" name="NANOSECONDS"/>
+ <c:option value="SECONDS" name="SECONDS"/>
+ </c:property-options>
+ </c:simple-property>
+ </parameters>
<results>
<c:simple-property name="result" type="boolean" description="The result of the operation" />
</results>
</operation>
- <operation name="stopContext" displayName="Stop webapp" description="Gracefully stops this webapp.">
+ <operation name="enableContext" displayName="Enable webapp" description="Enable this webapp.">
<results>
- <c:simple-property name="result" type="boolean" description="The result of the operation" />
+ <c:simple-property name="result" type="boolean" description="The result of the operation" />
</results>
</operation>
commit 9133ff50842297f30bed9fcb7553a66a38379d76
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Thu Jul 7 09:49:10 2011 -0600
Added all the properties available through the JMX interface to the plugin configuration.
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index b2179c3..17a4267 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -45,9 +45,23 @@
<metric property="className" displayName="Fully qualified class name of the managed object" displayType="summary" dataType="trait" />
<resource-configuration>
- <c:simple-property name="stickySessions" type="boolean" description="Enables sticky sessions."/>
+ <c:simple-property name="workerTimeout" type="int" description="Timeout to wait for an available worker (default is no wait)"
+ <c:simple-property name="stickySession" type="boolean" description="Enables sticky session for the cluster."/>
<c:simple-property name="stickySessionRemove" type="boolean" description="Remove session when the request cannot be routed to the right node."/>
<c:simple-property name="advertise" type="boolean" description="Enable autodiscovery of httpd servers."/>
+ <c:simple-property name="smax" type="int" description="Maximum time on seconds for idle connections above smax."/>
+ <c:simple-property name="maxAttempts" type="int" description="Maximum number of attempts to send the request to the backend server."/>
+ <c:simple-property name="advertiseSecurityKey" type="int" description="Security key for discovery."/>
+ <c:simple-property name="stickySessionForce" type="boolean" description="Return an error when the request cannot be routed to the right node."/>
+ <c:simple-property name="balancer" type="string" description="Name of the balancer."/>
+ <c:simple-property name="flushPackets" type="boolean" descritpion="Allows controlling flusing of packets."/>
+ <c:simple-property name="socketTimeout" type="int" description="Connection timeout for communication with the proxy." />
+ <c:simple-property name="containerName" type="string" description="Object name of the container."/>
+ <c:simple-property name="domain" type="string" description="Domain parameter, which allows tying a jvmRoute to a particular domain."/>
+ <c:simple-property name="advertisePort" type="int" description="Multicast port for discovery" />
+ <c:simple-property name="advertiseGroupAddress" type="string" description="Multicast address for discovery."/>
+ <c:simple-property name="flushWait" type="int" description="Time in ms to wait before flushing packets."/>
+ <c:simple-property name="ping" type="int" description="Time in s to wait for a pong answer to a ping"/>
</resource-configuration>
<service name="mod_cluster Webapp Context"
@@ -55,17 +69,17 @@
class="ContextComponent"
description="A mod_cluster context">
- <operation name="enableContext" displayName="Enable webapp" description="Enable the webapp">
+ <operation name="enableContext" displayName="Enable webapp" description="Enable this webapp">
<results>
<c:simple-property name="result" type="boolean" description="The result of the operation" />
</results>
</operation>
- <operation name="disableContext" displayName="Disable webpapp" description="Disable the webapp">
+ <operation name="disableContext" displayName="Disable webapp" description="Disable this webapp">
<results>
<c:simple-property name="result" type="boolean" description="The result of the operation" />
</results>
</operation>
- <operation name="stopContext" displayName="Stop webpapp" description="Gracefully stops the webapp">
+ <operation name="stopContext" displayName="Stop webapp" description="Gracefully stops this webapp.">
<results>
<c:simple-property name="result" type="boolean" description="The result of the operation" />
</results>
commit 93ac1b5c3ba6032e3c726f32e01d73e16d73e076
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Wed Jul 6 15:28:48 2011 -0500
A couple more tweaks to make the user interface for mod_cluster display correct and proper text.
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index cdfa7fb..b2179c3 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -24,7 +24,7 @@
<plugin-configuration>
<c:simple-property name="objectName" readOnly="true" default="Catalina:type=ModClusterListener,*"/>
- <c:simple-property name="nameTemplate" default="{application}"/>
+ <c:simple-property name="nameTemplate" default="mod_cluster"/>
</plugin-configuration>
<operation name="reset" displayName="Reset the node" description="Move the node out of an error state" />
@@ -50,22 +50,22 @@
<c:simple-property name="advertise" type="boolean" description="Enable autodiscovery of httpd servers."/>
</resource-configuration>
- <service name="mod_cluster_context"
+ <service name="mod_cluster Webapp Context"
discovery="ContextDiscoveryComponent"
class="ContextComponent"
description="A mod_cluster context">
- <operation name="enableContext" displayName="Enable webapp" description="Enable a single webapp">
+ <operation name="enableContext" displayName="Enable webapp" description="Enable the webapp">
<results>
<c:simple-property name="result" type="boolean" description="The result of the operation" />
</results>
</operation>
- <operation name="disableContext" displayName="Disable webpapp" description="Disable a single webapp">
+ <operation name="disableContext" displayName="Disable webpapp" description="Disable the webapp">
<results>
<c:simple-property name="result" type="boolean" description="The result of the operation" />
</results>
</operation>
- <operation name="stopContext" displayName="Stop webpapp" description="Gracefully stops a single webapp">
+ <operation name="stopContext" displayName="Stop webpapp" description="Gracefully stops the webapp">
<results>
<c:simple-property name="result" type="boolean" description="The result of the operation" />
</results>
commit bed08a054ca397b313d97022c29ad61f1b7e6a81
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Wed Jul 6 13:19:07 2011 -0500
Fine tuning the plugin configuration based other plugin configuration and test deployment issues.
diff --git a/modules/plugins/mod-cluster/pom.xml b/modules/plugins/mod-cluster/pom.xml
index 74defeb..4536125 100644
--- a/modules/plugins/mod-cluster/pom.xml
+++ b/modules/plugins/mod-cluster/pom.xml
@@ -12,7 +12,7 @@
<artifactId>modcluster-plugin</artifactId>
<packaging>jar</packaging>
- <name>mod_cluster RHQ Plugin</name>
+ <name>RHQ mod_cluster Plugin</name>
<description>mod_cluster RHQ Agent plugin</description>
<dependencies>
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index be4b25b..cdfa7fb 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -14,11 +14,12 @@
discovery="org.rhq.plugins.jmx.MBeanResourceDiscoveryComponent"
class="ModclusterServerComponent"
supportsManualAdd="true"
- description="mod_cluster plugin">
+ description="mod_cluster plugin"
+ singleton="true">
<runs-inside>
<parent-resource-type name="JBossAS Server" plugin="JBossAS"/>
- <parent-resource-type name="JBossAS Server" plugin="JBossAS5"/>
+ <parent-resource-type name="JBossAS5 Server" plugin="JBossAS5"/>
</runs-inside>
<plugin-configuration>
diff --git a/modules/plugins/pom.xml b/modules/plugins/pom.xml
index 02f6584..f32159e 100644
--- a/modules/plugins/pom.xml
+++ b/modules/plugins/pom.xml
@@ -125,10 +125,11 @@
<module>augeas</module>
<module>apache</module>
<module>tomcat</module>
- <module>jboss-as</module>
<module>hibernate</module>
+ <module>mod-cluster</module>
<module>rhq-server</module>
<module>jboss-cache</module>
+ <module>jboss-as</module>
<module>jboss-as-5</module>
<module>jboss-as-7</module>
<module>jboss-cache-v3</module>
commit af18d25dc8b66f9d95477e90356f6aecccf6077c
Merge: 7f4c0a9 67e6127
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Wed Jul 6 10:01:46 2011 -0500
Merge branch 'master' into mod_cluster_plugin
commit 7f4c0a99bb2121fd3496d3bc1af3079f4e922c3a
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Wed Jul 6 10:00:21 2011 -0500
Added dev profile for plugin deployment in the local plugin repo.
diff --git a/modules/plugins/mod-cluster/pom.xml b/modules/plugins/mod-cluster/pom.xml
index a19dfc0..74defeb 100644
--- a/modules/plugins/mod-cluster/pom.xml
+++ b/modules/plugins/mod-cluster/pom.xml
@@ -190,6 +190,82 @@
</plugins>
</build>
</profile>
+
+
+ <profile>
+ <id>dev</id>
+
+ <properties>
+ <rhq.rootDir>../../..</rhq.rootDir>
+ <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir>
+ <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/rhq-downloads/rhq-plugins</rhq.deploymentDir>
+ </properties>
+
+ <build>
+ <plugins>
+
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.1</version>
+ <executions>
+
+ <execution>
+ <id>deploy</id>
+ <phase>compile</phase>
+ <configuration>
+ <tasks>
+ <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}" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ <execution>
+ <id>deploy-jar-meta-inf</id>
+ <phase>package</phase>
+ <configuration>
+ <tasks>
+ <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>
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ <execution>
+ <id>undeploy</id>
+ <phase>clean</phase>
+ <configuration>
+ <tasks>
+ <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
+ <echo>*** Deleting ${deployment.file}...</echo>
+ <delete file="${deployment.file}" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ </executions>
+ </plugin>
+
+ </plugins>
+ </build>
+ </profile>
+
</profiles>
</project>
commit 060cf8983b9230adf3f26c936d0fe6c8d1966bd1
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Tue Jul 5 23:31:24 2011 -0500
All the context dependent operations are now passed for execution to the parent MBean. The operation arguments are parsed from the proxyInfo MBean property.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
index f73a151..922197a 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
@@ -1,24 +1,20 @@
/*
- * Jopr Management Platform
+ * RHQ Management Platform
* Copyright (C) 2005-2008 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation, and/or the GNU Lesser
- * General Public License, version 2.1, also as published by the Free
- * Software Foundation.
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License and the GNU Lesser General Public License
- * for more details.
+ * GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * and the GNU Lesser General Public License along with this program;
- * if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.rhq.plugins.modcluster;
@@ -29,10 +25,9 @@ import org.rhq.core.pluginapi.operation.OperationResult;
import org.rhq.plugins.jmx.MBeanResourceComponent;
/**
- * Manages a Hibernate Entity.
+ * Manages a mod_cluster context entity.
*
- * @author Greg Hinkle
- * @author John Mazzitelli
+ * @author Stefan Negrea
*/
public class ContextComponent extends MBeanResourceComponent<MBeanResourceComponent> {
@Override
@@ -42,46 +37,24 @@ public class ContextComponent extends MBeanResourceComponent<MBeanResourceCompon
@Override
public OperationResult invokeOperation(String name, Configuration parameters) throws Exception {
- if ("enableContext".equals(name)) {
- //String[] queryStrings = (String[]) getEmsBean().getAttribute("Queries").refresh();
- OperationResult result = new OperationResult();
- result.setSimpleResult("This works!");
- /*PropertyList queries = new PropertyList("queries");
- result.getComplexResults().put(queries);*/
+ if ("enableContext".equals(name) || "disableContext".equals(name) || "stopContext".equals(name)) {
+
+ ProxyInfo.Context context = ProxyInfo.Context.fromString(resourceContext.getResourceKey());
+ System.out.println(context.toString());
ClassLoader cl = Thread.currentThread().getContextClassLoader();
try {
- /*Thread.currentThread().setContextClassLoader(getEmsBean().getClass().getClassLoader());
- for (String queryString : queryStrings) {
- Object queryStatistics = getEmsBean().getOperation("getQueryStatistics").invoke(
- new Object[] { queryString });
-
- Long executionCount = (Long) queryStatistics.getClass().getMethod("getExecutionCount")
- .invoke(queryStatistics);
- Long executionRowCount = (Long) queryStatistics.getClass().getMethod("getExecutionRowCount")
- .invoke(queryStatistics);
- Long executionMinTime = (Long) queryStatistics.getClass().getMethod("getExecutionMinTime")
- .invoke(queryStatistics);
- Long executionMaxTime = (Long) queryStatistics.getClass().getMethod("getExecutionMaxTime")
- .invoke(queryStatistics);
- Long executionAvgTime = (Long) queryStatistics.getClass().getMethod("getExecutionAvgTime")
- .invoke(queryStatistics);
-
- PropertyMap query = new PropertyMap("query", new PropertySimple("query", queryString),
- new PropertySimple("executionCount", executionCount), new PropertySimple("executionRowCount",
- executionRowCount), new PropertySimple("executionMinTime", executionMinTime),
- new PropertySimple("executionMaxTime", executionMaxTime), new PropertySimple(
- "executionAvgTime", executionAvgTime));
+ Thread.currentThread().setContextClassLoader(getEmsBean().getClass().getClassLoader());
- queries.add(query);
- }*/
+ Object resultObject = getEmsBean().getOperation(name).invoke(
+ new Object[] { context.host, context.path });
- return result;
+ return new OperationResult(String.valueOf(resultObject));
} finally {
Thread.currentThread().setContextClassLoader(cl);
}
}
- return super.invokeOperation(name, parameters);
+ throw new Exception("Operation " + name + " not available mod_cluster_context service");
}
}
\ No newline at end of file
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
index 90e5c6b..4b3adcd 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
@@ -33,11 +33,15 @@ import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
import org.rhq.plugins.jmx.MBeanResourceComponent;
/**
- * Discovers hibernate entities from a hibernate stats mbean
+ * Discovers mod_cluster contexts from the proxyInfo mbean property.
*
- * @author Greg Hinkle
+ * @author Stefan Negrea
*/
public class ContextDiscoveryComponent implements ResourceDiscoveryComponent<MBeanResourceComponent> {
+
+ /* (non-Javadoc)
+ * @see org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent#discoverResources(org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext)
+ */
public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext<MBeanResourceComponent> context) {
Set<DiscoveredResourceDetails> entities = new HashSet<DiscoveredResourceDetails>();
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
index 15a9a68..9cb6b86 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
@@ -16,7 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
package org.rhq.plugins.modcluster;
import java.util.ArrayList;
@@ -25,16 +24,17 @@ import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+/**
+ * Simple parser for the raw proxy information provided by mod_cluster.
+ *
+ * @author Stefan Negrea
+ */
public class ProxyInfo {
private List<Context> availableContexts = new ArrayList<ProxyInfo.Context>();
public ProxyInfo(String rawProxyInfo) {
- System.out.println("--------------------------------------");
- System.out.println(rawProxyInfo);
- System.out.println("--------------------------------------");
-
Pattern test = Pattern.compile("Context.*\n");
Matcher m = test.matcher(rawProxyInfo);
while (m.find()) {
@@ -42,7 +42,7 @@ public class ProxyInfo {
String[] contextPieces = rawContext.split(",");
String actualContext = contextPieces[1].substring(contextPieces[1].indexOf("/")).trim();
- availableContexts.add(new Context(actualContext, "localHost"));
+ availableContexts.add(new Context(actualContext, "localhost"));
}
}
@@ -50,12 +50,11 @@ public class ProxyInfo {
return Collections.unmodifiableList(availableContexts);
}
- public class Context {
+ public static class Context {
String path;
String host;
public Context(String path, String host) {
- super();
this.path = path;
this.host = host;
}
@@ -80,5 +79,23 @@ public class ProxyInfo {
public String toString() {
return "Context [path=" + path + ", host=" + host + "]";
}
+
+ public static Context fromString(String stringRepresentation) {
+ stringRepresentation = stringRepresentation.substring(stringRepresentation.indexOf('[') + 1);
+ stringRepresentation = stringRepresentation.substring(0, stringRepresentation.indexOf(']'));
+ stringRepresentation = stringRepresentation.trim();
+
+ String host = null;
+ String path = null;
+ for (String part : stringRepresentation.split(",")) {
+ part = part.trim();
+ if (part.startsWith("path=")) {
+ path = part.substring(5).trim();
+ } else if (part.startsWith("host=")) {
+ host = part.substring(5).trim();
+ }
+ }
+ return new Context(path, host);
+ }
}
}
\ No newline at end of file
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index 084165e..be4b25b 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -45,6 +45,8 @@
<resource-configuration>
<c:simple-property name="stickySessions" type="boolean" description="Enables sticky sessions."/>
+ <c:simple-property name="stickySessionRemove" type="boolean" description="Remove session when the request cannot be routed to the right node."/>
+ <c:simple-property name="advertise" type="boolean" description="Enable autodiscovery of httpd servers."/>
</resource-configuration>
<service name="mod_cluster_context"
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
index deceb70..0d16e92 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
@@ -140,8 +140,14 @@ public class ModclusterPluginTest {
assert (resources.size() != 0) : "No mod_cluster or related instances found.";
if (resources.size() != 0) {
- testResourceMeasurement((Resource) resources.toArray()[0]);
- testContextOperations((Resource) resources.toArray()[1]);
+ for (Object objectResource : resources.toArray()) {
+ Resource resource = (Resource) objectResource;
+ if (resource.getResourceType().getName().equals("mod_cluster")) {
+ testResourceMeasurement(resource);
+ } else {
+ testContextOperations(resource);
+ }
+ }
}
}
@@ -175,9 +181,12 @@ public class ModclusterPluginTest {
.getResourceComponent(resource);
if (resourceComponent instanceof OperationFacet) {
- OperationResult result = ((OperationFacet) resourceComponent).invokeOperation("enableContext", null);
- log.info("Result of operation " + "enableContext" + " was: " + result.getSimpleResult());
-
+ try {
+ OperationResult result = ((OperationFacet) resourceComponent).invokeOperation("enableContext", null);
+ log.info("Result of operation " + "enableContext" + " was: " + result.getSimpleResult());
+ } catch (Exception e) {
+ log.info("Operation failed");
+ }
/*result = ((OperationFacet) resourceComponent).invokeOperation("disable", null);
log.info("Result of operation test was: " + result.getSimpleResult());*/
}
commit a23fc57dda98b70cb7c1b23af91b9e3e3597969a
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Tue Jul 5 18:43:06 2011 -0500
Added individual contexts as sub services to mod_cluster service.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
new file mode 100644
index 0000000..f73a151
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextComponent.java
@@ -0,0 +1,87 @@
+/*
+ * Jopr Management Platform
+ * Copyright (C) 2005-2008 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.rhq.plugins.modcluster;
+
+import org.mc4j.ems.connection.bean.EmsBean;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.pluginapi.operation.OperationResult;
+import org.rhq.plugins.jmx.MBeanResourceComponent;
+
+/**
+ * Manages a Hibernate Entity.
+ *
+ * @author Greg Hinkle
+ * @author John Mazzitelli
+ */
+public class ContextComponent extends MBeanResourceComponent<MBeanResourceComponent> {
+ @Override
+ protected EmsBean loadBean() {
+ return getResourceContext().getParentResourceComponent().getEmsBean();
+ }
+
+ @Override
+ public OperationResult invokeOperation(String name, Configuration parameters) throws Exception {
+ if ("enableContext".equals(name)) {
+ //String[] queryStrings = (String[]) getEmsBean().getAttribute("Queries").refresh();
+ OperationResult result = new OperationResult();
+ result.setSimpleResult("This works!");
+ /*PropertyList queries = new PropertyList("queries");
+ result.getComplexResults().put(queries);*/
+
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ try {
+ /*Thread.currentThread().setContextClassLoader(getEmsBean().getClass().getClassLoader());
+ for (String queryString : queryStrings) {
+ Object queryStatistics = getEmsBean().getOperation("getQueryStatistics").invoke(
+ new Object[] { queryString });
+
+ Long executionCount = (Long) queryStatistics.getClass().getMethod("getExecutionCount")
+ .invoke(queryStatistics);
+ Long executionRowCount = (Long) queryStatistics.getClass().getMethod("getExecutionRowCount")
+ .invoke(queryStatistics);
+ Long executionMinTime = (Long) queryStatistics.getClass().getMethod("getExecutionMinTime")
+ .invoke(queryStatistics);
+ Long executionMaxTime = (Long) queryStatistics.getClass().getMethod("getExecutionMaxTime")
+ .invoke(queryStatistics);
+ Long executionAvgTime = (Long) queryStatistics.getClass().getMethod("getExecutionAvgTime")
+ .invoke(queryStatistics);
+
+ PropertyMap query = new PropertyMap("query", new PropertySimple("query", queryString),
+ new PropertySimple("executionCount", executionCount), new PropertySimple("executionRowCount",
+ executionRowCount), new PropertySimple("executionMinTime", executionMinTime),
+ new PropertySimple("executionMaxTime", executionMaxTime), new PropertySimple(
+ "executionAvgTime", executionAvgTime));
+
+ queries.add(query);
+ }*/
+
+ return result;
+ } finally {
+ Thread.currentThread().setContextClassLoader(cl);
+ }
+ }
+
+ return super.invokeOperation(name, parameters);
+ }
+}
\ No newline at end of file
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
new file mode 100644
index 0000000..90e5c6b
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ContextDiscoveryComponent.java
@@ -0,0 +1,57 @@
+/*
+ * Jopr Management Platform
+ * Copyright (C) 2005-2008 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.rhq.plugins.modcluster;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.mc4j.ems.connection.bean.EmsBean;
+
+import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+import org.rhq.plugins.jmx.MBeanResourceComponent;
+
+/**
+ * Discovers hibernate entities from a hibernate stats mbean
+ *
+ * @author Greg Hinkle
+ */
+public class ContextDiscoveryComponent implements ResourceDiscoveryComponent<MBeanResourceComponent> {
+ public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext<MBeanResourceComponent> context) {
+ Set<DiscoveredResourceDetails> entities = new HashSet<DiscoveredResourceDetails>();
+
+ EmsBean statsBean = context.getParentResourceComponent().getEmsBean();
+
+ String rawProxyInfo = (String) statsBean.getAttribute("proxyInfo").refresh().toString();
+ ProxyInfo proxyInfo = new ProxyInfo(rawProxyInfo);
+
+ for (ProxyInfo.Context availableContext : proxyInfo.getAvailableContexts()) {
+ DiscoveredResourceDetails detail = new DiscoveredResourceDetails(context.getResourceType(),
+ availableContext.toString(), availableContext.toString(), null, "mod_cluster Context", null, null);
+ entities.add(detail);
+ }
+
+ return entities;
+ }
+}
\ No newline at end of file
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
index a98792e..783f579 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
@@ -18,9 +18,6 @@
*/
package org.rhq.plugins.modcluster;
-import org.rhq.core.domain.operation.OperationDefinition;
-import org.rhq.core.pluginapi.inventory.ResourceComponent;
-import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.plugins.jmx.MBeanResourceComponent;
/**
@@ -28,16 +25,4 @@ import org.rhq.plugins.jmx.MBeanResourceComponent;
*
*/
public class ModclusterServerComponent extends MBeanResourceComponent {
-
- /**
- * Stores the context and loads the MBean.
- * @see ResourceComponent#start(ResourceContext)
- */
- @Override
- public void start(ResourceContext context) {
- super.start(context);
-
- OperationDefinition test = new OperationDefinition(context.getResourceType(), "Text");
- context.getResourceType().addOperationDefinition(test);
- }
}
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
new file mode 100644
index 0000000..15a9a68
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ProxyInfo.java
@@ -0,0 +1,84 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.modcluster;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class ProxyInfo {
+
+ private List<Context> availableContexts = new ArrayList<ProxyInfo.Context>();
+
+ public ProxyInfo(String rawProxyInfo) {
+
+ System.out.println("--------------------------------------");
+ System.out.println(rawProxyInfo);
+ System.out.println("--------------------------------------");
+
+ Pattern test = Pattern.compile("Context.*\n");
+ Matcher m = test.matcher(rawProxyInfo);
+ while (m.find()) {
+ String rawContext = m.group();
+ String[] contextPieces = rawContext.split(",");
+ String actualContext = contextPieces[1].substring(contextPieces[1].indexOf("/")).trim();
+
+ availableContexts.add(new Context(actualContext, "localHost"));
+ }
+ }
+
+ public List<Context> getAvailableContexts() {
+ return Collections.unmodifiableList(availableContexts);
+ }
+
+ public class Context {
+ String path;
+ String host;
+
+ public Context(String path, String host) {
+ super();
+ this.path = path;
+ this.host = host;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public void setPath(String path) {
+ this.path = path;
+ }
+
+ public String getHost() {
+ return host;
+ }
+
+ public void setHost(String host) {
+ this.host = host;
+ }
+
+ @Override
+ public String toString() {
+ return "Context [path=" + path + ", host=" + host + "]";
+ }
+ }
+}
\ No newline at end of file
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index b8d7249..084165e 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -47,5 +47,29 @@
<c:simple-property name="stickySessions" type="boolean" description="Enables sticky sessions."/>
</resource-configuration>
+ <service name="mod_cluster_context"
+ discovery="ContextDiscoveryComponent"
+ class="ContextComponent"
+ description="A mod_cluster context">
+
+ <operation name="enableContext" displayName="Enable webapp" description="Enable a single webapp">
+ <results>
+ <c:simple-property name="result" type="boolean" description="The result of the operation" />
+ </results>
+ </operation>
+ <operation name="disableContext" displayName="Disable webpapp" description="Disable a single webapp">
+ <results>
+ <c:simple-property name="result" type="boolean" description="The result of the operation" />
+ </results>
+ </operation>
+ <operation name="stopContext" displayName="Stop webpapp" description="Gracefully stops a single webapp">
+ <results>
+ <c:simple-property name="result" type="boolean" description="The result of the operation" />
+ </results>
+ </operation>
+
+ </service>
+
+
</service>
</plugin>
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
index da0303e..deceb70 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
@@ -19,8 +19,10 @@
package org.rhq.plugins.modcluster.test;
import java.io.File;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
+import java.util.List;
import java.util.Queue;
import java.util.Set;
@@ -45,6 +47,7 @@ import org.rhq.core.pluginapi.inventory.ResourceComponent;
import org.rhq.core.pluginapi.measurement.MeasurementFacet;
import org.rhq.core.pluginapi.operation.OperationFacet;
import org.rhq.core.pluginapi.operation.OperationResult;
+import org.rhq.plugins.modcluster.ProxyInfo;
/**
* @author Fady Matar
@@ -80,6 +83,31 @@ public class ModclusterPluginTest {
}
@Test
+ public void testProxyInfo() {
+ String test = "{mobile-work/192.168.1.40:6666=Node: [1],Name: 4e6189af-0502-3305-8ff3-fad7fee8b516,Balancer: mycluster,LBGroup: ,Host: 127.0.0.1,Port: 8009,Type: ajp,Flushpackets: Off,Flushwait: 10,Ping: 10,Smax: 26,Ttl: 60,Elected: 3233,Read: 7355619,Transfered: 0,Connected: 0,Load: 100\n"
+ + "Node: [2],Name: node2,Balancer: mycluster,LBGroup: ,Host: 127.0.0.1,Port: 8009,Type: ajp,Flushpackets: Off,Flushwait: 10,Ping: 10,Smax: 26,Ttl: 60,Elected: 0,Read: 0,Transfered: 0,Connected: 0,Load: 99\n"
+ + "Vhost: [1:1:1], Alias: localhost\n"
+ + "Vhost: [2:1:2], Alias: localhost\n"
+ + "Context: [1:1:1], Context: /invoker, Status: DISABLED\n"
+ + "Context: [1:1:2], Context: /loaddemo, Status: DISABLED\n"
+ + "Context: [1:1:3], Context: /jbossws, Status: DISABLED\n"
+ + "Context: [1:1:4], Context: /juddi, Status: DISABLED\n"
+ + "Context: [1:1:5], Context: /jbossmq-httpil, Status: DISABLED\n"
+ + "Context: [1:1:6], Context: /web-console, Status: DISABLED\n"
+ + "Context: [1:1:7], Context: /jmx-console, Status: DISABLED\n"
+ + "Context: [1:1:8], Context: /, Status: DISABLED\n"
+ + "Context: [2:1:9], Context: /loaddemo, Status: ENABLED\n" + "}";
+
+ ProxyInfo proxyInfo = new ProxyInfo(test);
+
+ for (ProxyInfo.Context context : proxyInfo.getAvailableContexts()) {
+ log.info(context.toString());
+ }
+
+ assert (proxyInfo.getAvailableContexts().size() != 0) : "Raw proxy info parsing failed!";
+ }
+
+ @Test
public void testPluginLoad() {
PluginManager pluginManager = PluginContainer.getInstance().getPluginManager();
PluginEnvironment pluginEnvironment = pluginManager.getPlugin(PLUGIN_NAME);
@@ -98,12 +126,22 @@ public class ModclusterPluginTest {
assert report != null;
System.out.println("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
+ List<String> typeNames = new ArrayList<String>() {
+ {
+ add(PLUGIN_NAME);
+ add(PLUGIN_NAME + "_context");
+ }
+ };
+
Set<Resource> resources = findResource(PluginContainer.getInstance().getInventoryManager().getPlatform(),
- PLUGIN_NAME);
- log.info("Found " + resources.size() + " mod_cluster instance(s).");
+ typeNames);
+ log.info("Found " + resources.size() + " mod_cluster and mod_cluster_context instance(s).");
+
+ assert (resources.size() != 0) : "No mod_cluster or related instances found.";
if (resources.size() != 0) {
testResourceMeasurement((Resource) resources.toArray()[0]);
+ testContextOperations((Resource) resources.toArray()[1]);
}
}
@@ -132,7 +170,20 @@ public class ModclusterPluginTest {
}
}
- private Set<Resource> findResource(Resource parent, String typeName) {
+ private void testContextOperations(Resource resource) throws Exception {
+ ResourceComponent resourceComponent = PluginContainer.getInstance().getInventoryManager()
+ .getResourceComponent(resource);
+
+ if (resourceComponent instanceof OperationFacet) {
+ OperationResult result = ((OperationFacet) resourceComponent).invokeOperation("enableContext", null);
+ log.info("Result of operation " + "enableContext" + " was: " + result.getSimpleResult());
+
+ /*result = ((OperationFacet) resourceComponent).invokeOperation("disable", null);
+ log.info("Result of operation test was: " + result.getSimpleResult());*/
+ }
+ }
+
+ private Set<Resource> findResource(Resource parent, List<String> typeNames) {
Set<Resource> found = new HashSet<Resource>();
Queue<Resource> discoveryQueue = new LinkedList<Resource>();
@@ -142,7 +193,7 @@ public class ModclusterPluginTest {
Resource currentResource = discoveryQueue.poll();
log.info("Discovered resource of type: " + currentResource.getResourceType().getName());
- if (currentResource.getResourceType().getName().equals(typeName)) {
+ if (typeNames.contains(currentResource.getResourceType().getName())) {
found.add(currentResource);
}
commit a78a8e8b90cb76cf3412732008870804c2210a6b
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Tue Jul 5 15:46:03 2011 -0500
Attempt to manually manipulate the operations list for mod_cluster to dynamically load the contexts.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
index c70f53b..a98792e 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
@@ -18,6 +18,9 @@
*/
package org.rhq.plugins.modcluster;
+import org.rhq.core.domain.operation.OperationDefinition;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.plugins.jmx.MBeanResourceComponent;
/**
@@ -26,4 +29,15 @@ import org.rhq.plugins.jmx.MBeanResourceComponent;
*/
public class ModclusterServerComponent extends MBeanResourceComponent {
+ /**
+ * Stores the context and loads the MBean.
+ * @see ResourceComponent#start(ResourceContext)
+ */
+ @Override
+ public void start(ResourceContext context) {
+ super.start(context);
+
+ OperationDefinition test = new OperationDefinition(context.getResourceType(), "Text");
+ context.getResourceType().addOperationDefinition(test);
+ }
}
commit 302abb94355bf86db5f6e7cc419657d53210c7a5
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Tue Jul 5 15:45:23 2011 -0500
Added simple operations to the list of operations supported by the plugin. Complex operations to follow....
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterDiscoveryComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterDiscoveryComponent.java
deleted file mode 100644
index fa807a3..0000000
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterDiscoveryComponent.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 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.modcluster;
-
-import java.util.HashSet;
-import java.util.List;
-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.pluginapi.inventory.DiscoveredResourceDetails;
-import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
-import org.rhq.core.pluginapi.inventory.ManualAddFacet;
-import org.rhq.core.pluginapi.inventory.ProcessScanResult;
-import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
-import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
-
-/**
- * This can be the start of your own custom plugin's discovery component. Review the javadoc for
- * {@link ResourceDiscoveryComponent}.
- *
- * @author John Mazzitelli
- */
-@SuppressWarnings("unchecked")
-public class ModclusterDiscoveryComponent implements ResourceDiscoveryComponent, ManualAddFacet {
- private final Log log = LogFactory.getLog(ModclusterDiscoveryComponent.class);
-
- /**
- * This discovery method is the way the plugin supports "manual-add" capability. The plugin
- * descriptor must specify supportsManualAdd="true" to allow the resource to be manually added.
- * If that attribute is false, this method will never be used since it will not be possible to manually
- * add an instance of the resource.
- *
- * Review the javadoc for both {@link ManualAddFacet} and {@link ResourceDiscoveryContext} to learn what
- * you need to do in this method.
- *
- * @see ManualAddFacet#discoverResource(Configuration, ResourceDiscoveryContext)
- */
- @Override
- public DiscoveredResourceDetails discoverResource(Configuration pluginConfiguration,
- ResourceDiscoveryContext context) throws InvalidPluginConfigurationException {
-
- // pluginConfiguration contains information on a resource that was manually added by the user.
- // take it and build a details object that represents that resource.
-
- // key = this must be a unique string across all of your resources - see docs for uniqueness rules
- // name = this is the name you give the new resource; it does not necessarily have to be unique
- // version = this is any string that corresponds to the resource's version
- // description = this is any string that you want to assign as the default description for your resource
- String key = "My Manually Added Resource Key";
- String name = "My Resource";
- String version = "1.0";
- String description = "This describes My Resource";
-
- DiscoveredResourceDetails resource = new DiscoveredResourceDetails(context.getResourceType(), key, name,
- version, description, pluginConfiguration, null);
-
- return resource;
- }
-
- /**
- * Review the javadoc for both {@link ResourceDiscoveryComponent} and {@link ResourceDiscoveryContext} to learn what
- * you need to do in this method.
- *
- * @see ResourceDiscoveryComponent#discoverResources(ResourceDiscoveryContext)
- */
- @Override
- public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext context) {
- log.info("Discovering my custom plugin's resources");
-
- // if your plugin descriptor defined one or more <process-scan>s, then see if the plugin container
- // auto-discovered processes using those process scan definitions. Process all those that were found.
- List<ProcessScanResult> autoDiscoveryResults = context.getAutoDiscoveredProcesses();
- for (ProcessScanResult autoDiscoveryResult : autoDiscoveryResults) {
- // determine if you want to include the result in this method's returned set of discovered resources
- }
-
- // now perform your own discovery mechanism, if you have one. For each resource discovered, you need to
- // create a details object that describe the resource that you discovered.
- HashSet<DiscoveredResourceDetails> set = new HashSet<DiscoveredResourceDetails>();
-
- // key = this must be a unique string across all of your resources - see docs for uniqueness rules
- // name = this is the name you give the new resource; it does not necessarily have to be unique
- // version = this is any string that corresponds to the resource's version
- // description = this is any string that you want to assign as the default description for your resource
- String key = "My Resource Key";
- String name = "My Resource";
- String version = "1.0";
- String description = "This describes My Resource";
-
- DiscoveredResourceDetails resource = new DiscoveredResourceDetails(context.getResourceType(), key, name,
- version, description, null, null);
-
- set.add(resource);
-
- return set;
- }
-}
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index c924753..b8d7249 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -27,10 +27,25 @@
</plugin-configuration>
<operation name="reset" displayName="Reset the node" description="Move the node out of an error state" />
+ <operation name="refresh" displayName="Refresh configuration" description="Refresh configuration" />
+ <operation name="enable" displayName="Enable all webapps" description="Enable all webapps for all engines">
+ <results>
+ <c:simple-property name="result" type="boolean" description="The result of the operation" />
+ </results>
+ </operation>
+ <operation name="disable" displayName="Disable all webpapps" description="Disable all webapps for all engines">
+ <results>
+ <c:simple-property name="result" type="boolean" description="The result of the operation" />
+ </results>
+ </operation>
<metric property="proxyConfiguration" displayName="Proxy Configuration" displayType="summary" dataType="trait" />
<metric property="modelerType" displayName="Type of the modeled resource" displayType="summary" dataType="trait" />
<metric property="className" displayName="Fully qualified class name of the managed object" displayType="summary" dataType="trait" />
+ <resource-configuration>
+ <c:simple-property name="stickySessions" type="boolean" description="Enables sticky sessions."/>
+ </resource-configuration>
+
</service>
</plugin>
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
index 5f68989..da0303e 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
@@ -43,6 +43,8 @@ import org.rhq.core.pc.plugin.PluginEnvironment;
import org.rhq.core.pc.plugin.PluginManager;
import org.rhq.core.pluginapi.inventory.ResourceComponent;
import org.rhq.core.pluginapi.measurement.MeasurementFacet;
+import org.rhq.core.pluginapi.operation.OperationFacet;
+import org.rhq.core.pluginapi.operation.OperationResult;
/**
* @author Fady Matar
@@ -115,13 +117,19 @@ public class ModclusterPluginTest {
MeasurementReport report = new MeasurementReport();
((MeasurementFacet) resourceComponent).getValues(report, metricList);
- /*assert report.getNumericData().size() > 0 : "Measurement " + def.getName() + " not collected from "
- + resource;*/
MeasurementData data = report.getTraitData().iterator().next();
assert data != null : "Unable to collect trait [" + def.getName() + "] on " + resource;
log.info("Measurement: " + def.getName() + "=" + data.getValue());
}
}
+
+ if (resourceComponent instanceof OperationFacet) {
+ OperationResult result = ((OperationFacet) resourceComponent).invokeOperation("reset", null);
+ log.info("Result of operation test was: " + result);
+
+ result = ((OperationFacet) resourceComponent).invokeOperation("disable", null);
+ log.info("Result of operation test was: " + result.getSimpleResult());
+ }
}
private Set<Resource> findResource(Resource parent, String typeName) {
commit b6e3c85546af1faaac5e71ad6295a85e4b9d66b3
Merge: 3c46d2a 0ef2b57
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Fri Jul 1 16:15:00 2011 -0500
Merge branch 'master' of ssh://git.fedorahosted.org/git/rhq/rhq into mod_cluster_plugin
commit 3c46d2aaa05a0b355624f758977ef766bd3e8c6f
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Fri Jul 1 16:12:13 2011 -0500
Remove unused file.
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/LoadMetric.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/LoadMetric.java
deleted file mode 100644
index 1223508..0000000
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/LoadMetric.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2009 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.modcluster;
-
-import org.rhq.plugins.jmx.MBeanResourceComponent;
-
-/**
- * @author Stefan Negrea
- *
- */
-public class LoadMetric extends MBeanResourceComponent {
-
-}
commit 727836e4eca968619ec5307db7332eb132ac5562
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Fri Jul 1 15:11:36 2011 -0600
Added all the metrics proposed in the design document to the plugin with complete unit tests.
Also, corrected the cumbersome find resource code. No reason to have recursion when a simple queue can do the job more efficiently.
diff --git a/modules/plugins/mod-cluster/pom.xml b/modules/plugins/mod-cluster/pom.xml
index 869a25e..a19dfc0 100644
--- a/modules/plugins/mod-cluster/pom.xml
+++ b/modules/plugins/mod-cluster/pom.xml
@@ -69,6 +69,8 @@
<fileset dir="${settings.localRepository}/">
<include name="org/rhq/rhq-platform-plugin/${project.version}/rhq-platform-plugin-${project.version}.jar" />
<include name="org/rhq/rhq-jmx-plugin/${project.version}/rhq-jmx-plugin-${project.version}.jar" />
+ <include name="org/jboss/on/jopr-jboss-as-plugin/${project.version}/jopr-jboss-as-plugin-${project.version}.jar" />
+ <include name="org/jboss/on/jopr-jboss-as-5-plugin/${project.version}/jopr-jboss-as-5-plugin-${project.version}.jar" />
</fileset>
<fileset dir="${rhq.deploymentDir}">
<include name="${project.artifactId}-${project.version}.jar" />
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
index 6d6998a..c70f53b 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2008 Red Hat, Inc.
+ * Copyright (C) 2005-2009 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -18,151 +18,12 @@
*/
package org.rhq.plugins.modcluster;
-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.configuration.ConfigurationUpdateStatus;
-import org.rhq.core.domain.measurement.AvailabilityType;
-import org.rhq.core.domain.measurement.MeasurementDataNumeric;
-import org.rhq.core.domain.measurement.MeasurementReport;
-import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
-import org.rhq.core.pluginapi.configuration.ConfigurationFacet;
-import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport;
-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.plugins.jmx.MBeanResourceComponent;
/**
- * This can be the start of your own custom plugin's server component. Review the javadoc for {@link ResourceComponent}
- * and all the facet interfaces to learn what you can do in your resource component. This component has a lot of methods
- * in it because it implements all possible facets. If your resource does not support, for example, configuration, you
- * can remove the {@link ConfigurationFacet} from the <code>implements</code> clause and remove all method
- * implementations that that facet required.
- *
- * <p>You should not only read the javadoc in each of this class' methods, but you should also read the javadocs linked
- * by their "see" javadoc tags since those additional javadocs will contain a good deal of additional information you
- * will need to know.</p>
+ * @author Stefan Negrea
*
- * @author John Mazzitelli
*/
-public class ModclusterServerComponent implements ResourceComponent, MeasurementFacet, OperationFacet,
- ConfigurationFacet {
- private final Log log = LogFactory.getLog(ModclusterServerComponent.class);
-
- /**
- * Represents the resource configuration of the custom product being managed.
- */
- private Configuration resourceConfiguration;
-
- /**
- * All AMPS plugins are stateful - this context contains information that your resource component can use when
- * performing its processing.
- */
- private ResourceContext resourceContext;
-
- /**
- * This is called when your component has been started with the given context. You normally initialize some internal
- * state of your component as well as attempt to make a stateful connection to your managed resource.
- *
- * @see ResourceComponent#start(ResourceContext)
- */
- public void start(ResourceContext context) {
- resourceContext = context;
- }
-
- /**
- * This is called when the component is being stopped, usually due to the plugin container shutting down. You can
- * perform some cleanup here; though normally not much needs to be done here.
- *
- * @see ResourceComponent#stop()
- */
- public void stop() {
- }
-
- /**
- * All resource components must be able to tell the plugin container if the managed resource is available or not.
- * This method is called by the plugin container when it needs to know if the managed resource is actually up and
- * available.
- *
- * @see ResourceComponent#getAvailability()
- */
- public AvailabilityType getAvailability() {
- // TODO: here you normally make some type of connection attempt to the managed resource
- // to determine if it is really up and running.
- return AvailabilityType.UP;
- }
-
- /**
- * The plugin container will call this method when your resource component has been scheduled to collect some
- * measurements now. It is within this method that you actually talk to the managed resource and collect the
- * measurement data that is has emitted.
- *
- * @see MeasurementFacet#getValues(MeasurementReport, Set)
- */
- public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> requests) {
- for (MeasurementScheduleRequest request : requests) {
- String name = request.getName();
-
- // TODO: based on the request information, you must collect the requested measurement(s)
- // you can use the name of the measurement to determine what you actually need to collect
- try {
- Number value = new Integer(1); // dummy measurement value - this should come from the managed resource
- report.addData(new MeasurementDataNumeric(request, value.doubleValue()));
- } catch (Exception e) {
- log.error("Failed to obtain measurement [" + name + "]. Cause: " + e);
- }
- }
-
- return;
- }
-
- /**
- * The plugin container will call this method when it wants to invoke an operation on your managed resource. Your
- * plugin will connect to the managed resource and invoke the analogous operation in your own custom way.
- *
- * @see OperationFacet#invokeOperation(String, Configuration)
- */
- public OperationResult invokeOperation(String name, Configuration configuration) {
- return null;
- }
-
- /**
- * The plugin container will call this method and it needs to obtain the current configuration of the managed
- * resource. Your plugin will obtain the managed resource's configuration in your own custom way and populate the
- * returned Configuration object with the managed resource's configuration property values.
- *
- * @see ConfigurationFacet#loadResourceConfiguration()
- */
- public Configuration loadResourceConfiguration() {
- // here we simulate the loading of the managed resource's configuration
-
- if (resourceConfiguration == null) {
- // for this example, we will create a simple dummy configuration to start with.
- // note that it is empty, so we're assuming there are no required configs in the plugin descriptor.
- resourceConfiguration = new Configuration();
- }
-
- Configuration config = resourceConfiguration;
-
- return config;
- }
-
- /**
- * The plugin container will call this method when it has a new configuration for your managed resource. Your plugin
- * will re-configure the managed resource in your own custom way, setting its configuration based on the new values
- * of the given configuration.
- *
- * @see ConfigurationFacet#updateResourceConfiguration(ConfigurationUpdateReport)
- */
- public void updateResourceConfiguration(ConfigurationUpdateReport report) {
- // this simulates the plugin taking the new configuration and reconfiguring the managed resource
- resourceConfiguration = report.getConfiguration().deepCopy();
+public class ModclusterServerComponent extends MBeanResourceComponent {
- report.setStatus(ConfigurationUpdateStatus.SUCCESS);
- }
}
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index fe6d1b3..c924753 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -12,21 +12,25 @@
<service name="mod_cluster"
discovery="org.rhq.plugins.jmx.MBeanResourceDiscoveryComponent"
- class="LoadMetric"
+ class="ModclusterServerComponent"
supportsManualAdd="true"
description="mod_cluster plugin">
- <!-- runs-inside>
- <parent-resource-type name="JMX Server" plugin="JMX"/>
- </runs-inside-->
- <runs-inside>
- <parent-resource-type name="JMX Server" plugin="JMX"/>
- </runs-inside>
+ <runs-inside>
+ <parent-resource-type name="JBossAS Server" plugin="JBossAS"/>
+ <parent-resource-type name="JBossAS Server" plugin="JBossAS5"/>
+ </runs-inside>
- <plugin-configuration>
- <c:simple-property name="connectorAddress" default="http://192.168.1.56:6666"/>
- <c:simple-property name="objectName" readOnly="true" default="ModClusterServiceMBean"/>
+ <plugin-configuration>
+ <c:simple-property name="objectName" readOnly="true" default="Catalina:type=ModClusterListener,*"/>
+ <c:simple-property name="nameTemplate" default="{application}"/>
</plugin-configuration>
-
+
+ <operation name="reset" displayName="Reset the node" description="Move the node out of an error state" />
+
+ <metric property="proxyConfiguration" displayName="Proxy Configuration" displayType="summary" dataType="trait" />
+ <metric property="modelerType" displayName="Type of the modeled resource" displayType="summary" dataType="trait" />
+ <metric property="className" displayName="Fully qualified class name of the managed object" displayType="summary" dataType="trait" />
+
</service>
</plugin>
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
index 971ccb1..5f68989 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
@@ -20,6 +20,8 @@ package org.rhq.plugins.modcluster.test;
import java.io.File;
import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Queue;
import java.util.Set;
import org.apache.commons.logging.Log;
@@ -29,12 +31,18 @@ import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Test;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.domain.measurement.MeasurementData;
+import org.rhq.core.domain.measurement.MeasurementDefinition;
+import org.rhq.core.domain.measurement.MeasurementReport;
+import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.pc.PluginContainer;
import org.rhq.core.pc.PluginContainerConfiguration;
import org.rhq.core.pc.plugin.FileSystemPluginFinder;
import org.rhq.core.pc.plugin.PluginEnvironment;
import org.rhq.core.pc.plugin.PluginManager;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.measurement.MeasurementFacet;
/**
* @author Fady Matar
@@ -90,23 +98,53 @@ public class ModclusterPluginTest {
Set<Resource> resources = findResource(PluginContainer.getInstance().getInventoryManager().getPlatform(),
PLUGIN_NAME);
- log.info("Found " + resources.size() + "mod_cluster instance(s).");
+ log.info("Found " + resources.size() + " mod_cluster instance(s).");
+
+ if (resources.size() != 0) {
+ testResourceMeasurement((Resource) resources.toArray()[0]);
+ }
+ }
+
+ private void testResourceMeasurement(Resource resource) throws Exception {
+ ResourceComponent resourceComponent = PluginContainer.getInstance().getInventoryManager()
+ .getResourceComponent(resource);
+ if (resourceComponent instanceof MeasurementFacet) {
+ for (MeasurementDefinition def : resource.getResourceType().getMetricDefinitions()) {
+ Set<MeasurementScheduleRequest> metricList = new HashSet<MeasurementScheduleRequest>();
+ metricList.add(new MeasurementScheduleRequest(1, def.getName(), 1000, true, def.getDataType(), null));
+ MeasurementReport report = new MeasurementReport();
+ ((MeasurementFacet) resourceComponent).getValues(report, metricList);
+
+ /*assert report.getNumericData().size() > 0 : "Measurement " + def.getName() + " not collected from "
+ + resource;*/
+ MeasurementData data = report.getTraitData().iterator().next();
+ assert data != null : "Unable to collect trait [" + def.getName() + "] on " + resource;
+ log.info("Measurement: " + def.getName() + "=" + data.getValue());
+ }
+ }
}
private Set<Resource> findResource(Resource parent, String typeName) {
Set<Resource> found = new HashSet<Resource>();
- Resource platform = parent;
- for (Resource resource : platform.getChildResources()) {
- log.info("Discovered resource of type: " + resource.getResourceType().getName());
- if (resource.getResourceType().getName().equals(typeName)) {
- found.add(resource);
+
+ Queue<Resource> discoveryQueue = new LinkedList<Resource>();
+ discoveryQueue.add(parent);
+
+ while (!discoveryQueue.isEmpty()) {
+ Resource currentResource = discoveryQueue.poll();
+
+ log.info("Discovered resource of type: " + currentResource.getResourceType().getName());
+ if (currentResource.getResourceType().getName().equals(typeName)) {
+ found.add(currentResource);
}
- if (resource.getChildResources() != null) {
- for (Resource child : found) {
- found.addAll(findResource(child, typeName));
+
+ if (currentResource.getChildResources() != null) {
+ for (Resource child : currentResource.getChildResources()) {
+ discoveryQueue.add(child);
}
}
}
+
return found;
}
}
commit 5866fe5b6283debb6dfca115770301b1c1322489
Merge: 2884cc5 19558e1
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Tue Jun 28 09:31:15 2011 -0500
Merge branch 'master' of ssh://git.fedorahosted.org/git/rhq/rhq into mod_cluster_plugin
commit 2884cc5a209b7ab07f7fed6e8f38510c6c6683d5
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Tue Jun 28 09:21:49 2011 -0500
Attempts to make mod_cluster a simple derivation from JMX plugin.
diff --git a/.classpath b/.classpath
index 566c57d..6280671 100644
--- a/.classpath
+++ b/.classpath
@@ -266,5 +266,7 @@
<classpathentry excluding="**" kind="src" path="modules/enterprise/comm/src/test/resources"/>
<classpathentry excluding="**" kind="src" path="modules/enterprise/agent/src/main/resources"/>
<classpathentry excluding="**" kind="src" path="modules/enterprise/agent/src/test/resources"/>
+ <classpathentry kind="src" path="modules/plugins/mod-cluster/src/main/java"/>
+ <classpathentry kind="src" path="modules/plugins/mod-cluster/src/test/java"/>
<classpathentry kind="output" path="eclipse-classes"/>
</classpath>
diff --git a/modules/plugins/mod-cluster/pom.xml b/modules/plugins/mod-cluster/pom.xml
index e22efc7..869a25e 100644
--- a/modules/plugins/mod-cluster/pom.xml
+++ b/modules/plugins/mod-cluster/pom.xml
@@ -1,5 +1,3 @@
-<?xml version="1.0"?>
-
<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>
@@ -12,16 +10,11 @@
<groupId>org.rhq.plugins.modcluster</groupId>
<artifactId>modcluster-plugin</artifactId>
- <version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>mod_cluster RHQ Plugin</name>
<description>mod_cluster RHQ Agent plugin</description>
- <!--properties>
- <rhq.version>4.1.0-SNAPSHOT</rhq.version>
- </properties-->
-
<dependencies>
<dependency>
@@ -31,220 +24,170 @@
<scope>provided</scope>
</dependency>
- <!-- Below are the core modules that are required dependencies of all plugins -->
- <dependency>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-core-domain</artifactId>
- <version>${rhq.version}</version>
- <scope>provided</scope> <!-- provided by the agent/plugin-container -->
- </dependency>
-
- <dependency>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-core-plugin-api</artifactId>
- <version>${rhq.version}</version>
- <scope>provided</scope> <!-- provided by the agent/plugin-container -->
- </dependency>
-
- <dependency>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-core-native-system</artifactId>
- <version>${rhq.version}</version>
- <scope>provided</scope> <!-- provided by the agent/plugin-container -->
- </dependency>
-
- <!-- Fix for the Javac bug requiring annotations to be available when compiling classes. (fixed in JDK 6) -->
- <dependency>
- <groupId>javax.persistence</groupId>
- <artifactId>persistence-api</artifactId>
- <version>1.0</version>
- <scope>provided</scope> <!-- provided by the agent/plugin-container -->
- </dependency>
-
- <!-- Fix for the Javac bug requiring annotations to be available when compiling classes. (fixed in JDK 6) -->
- <dependency>
- <groupId>hibernate-annotations</groupId>
- <artifactId>hibernate-annotations</artifactId>
- <version>3.2.1.GA</version>
- <scope>provided</scope> <!-- provided by the agent/plugin-container -->
- </dependency>
-
- <!-- Fix for the Javac bug requiring annotations to be available when compiling classes. (fixed in JDK 6) -->
- <dependency>
- <groupId>javax.xml.bind</groupId>
- <artifactId>jaxb-api</artifactId>
- <version>2.1</version>
- <scope>provided</scope> <!-- provided by the agent/plugin-container -->
- </dependency>
-
- <!--
- Uncomment the one of the three logging systems your plugin uses: log4j, commons-logging or i18nlog
- All three are provided to your plugin by the agent/plugin-container.
- -->
- <dependency>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- <version>1.1</version>
- <scope>provided</scope>
- </dependency>
-
-
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
<scope>provided</scope>
</dependency>
-
- <!--
- <dependency>
- <groupId>i18nlog</groupId>
- <artifactId>i18nlog</artifactId>
- <version>1.0.9</version>
- <scope>provided</scope>
- </dependency>
- -->
-
- <!-- Define any third-party dependencies your plugin has here. -->
- <!--
- <dependency>
- <groupId>group-id-of-dependency-goes-here</groupId>
- <artifactId>artifact-id-of-dependency-goes-here</artifactId>
- <version>version-of-dependency-goes-here</version>
- </dependency>
- -->
</dependencies>
- <build>
- <plugins>
-
- <plugin>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <source>1.5</source>
- <target>1.5</target>
- </configuration>
- </plugin>
-
- <!--
- If your plugin has third-party jar dependencies that are not already available when deployed in the plugin
- container, you can package these jars in your plugin. They go in your plugin jar's "lib" directory.
- Uncomment the maven plugin definition below and define one or more jar files (aka "artifactItem" elements)
- that you want to include in your plugin jar.
- -->
- <!--
- <plugin>
- <artifactId>maven-dependency-plugin</artifactId>
- <executions>
- <execution>
- <id>copy-dependencies</id>
- <phase>process-resources</phase>
- <goals>
- <goal>copy</goal>
- </goals>
- <configuration>
- <artifactItems>
- <artifactItem>
- <groupId>your-third-party-dep-group</groupId>
- <artifactId>your-third-party-dep-artifact</artifactId>
- <version>your-third-party-dep-version</version>
- </artifactItem>
- </artifactItems>
- <outputDirectory>${project.build.outputDirectory}/lib</outputDirectory>
- </configuration>
- </execution>
- </executions>
- </plugin>
- -->
-
- </plugins>
- </build>
-
<profiles>
+
<profile>
- <id>dev</id>
+ <id>integration-tests</id>
+ <activation>
+ <property>
+ <name>maven.test.skip</name>
+ <value>!true</value>
+ </property>
+ </activation>
+
<properties>
- <!-- define the location of your RHQ root directory - typically rhq.rootDir is overridden in Maven's settings.xml -->
- <rhq.rootDir>/rhq/trunk</rhq.rootDir>
- <rhq.defaultDevContainerPath>dev-container</rhq.defaultDevContainerPath>
+ <rhq.rootDir>../../..</rhq.rootDir>
<rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir>
- <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/rhq.ear/rhq-downloads/rhq-plugins</rhq.deploymentDir>
+ <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/rhq-downloads/rhq-plugins</rhq.deploymentDir>
</properties>
+
<build>
<plugins>
+
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
- <version>1.1</version>
<executions>
<execution>
- <id>deploy</id>
- <phase>compile</phase>
+ <phase>process-test-resources</phase>
<configuration>
<tasks>
- <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}" />
+ <echo>Setting up plugin dependencies...</echo>
+ <property name="settings.localRepository" location="${user.home}/.m2/repository" />
+ <mkdir dir="target/testsetup" />
+
+ <mkdir dir="target/testsetup/plugins" />
+ <copy toDir="target/testsetup/plugins" flatten="true">
+ <fileset dir="${settings.localRepository}/">
+ <include name="org/rhq/rhq-platform-plugin/${project.version}/rhq-platform-plugin-${project.version}.jar" />
+ <include name="org/rhq/rhq-jmx-plugin/${project.version}/rhq-jmx-plugin-${project.version}.jar" />
+ </fileset>
+ <fileset dir="${rhq.deploymentDir}">
+ <include name="${project.artifactId}-${project.version}.jar" />
+ </fileset>
+ </copy>
+
+ <mkdir dir="target/testsetup/lib" />
+ <unzip dest="target/testsetup/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/testsetup/lib" flatten="true">
+ <fileset dir="target/testsetup/lib">
+ <include name="**/lib/*" />
+ </fileset>
+ </move>
+ <delete dir="target/testsetup/lib/hyperic-sigar-${sigar.version}" />
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
+
+ <execution>
+ <id>deploy</id>
+ <phase>compile</phase>
+ <configuration>
+ <tasks>
+ <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}" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
<execution>
<id>deploy-jar-meta-inf</id>
<phase>package</phase>
<configuration>
- <tasks>
- <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>
- </tasks>
+ <tasks>
+ <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>
+ </tasks>
</configuration>
<goals>
- <goal>run</goal>
+ <goal>run</goal>
</goals>
</execution>
+
<execution>
<id>undeploy</id>
<phase>clean</phase>
<configuration>
- <tasks>
- <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
- <echo>*** Deleting ${deployment.file}...</echo>
- <delete file="${deployment.file}" />
- </tasks>
+ <tasks>
+ <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
+ <echo>*** Deleting ${deployment.file}...</echo>
+ <delete file="${deployment.file}" />
+ </tasks>
</configuration>
<goals>
- <goal>run</goal>
+ <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>-Dorg.hyperic.sigar.path=${basedir}/target/testsetup/lib</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>
</profiles>
- <repositories>
- <repository>
- <id>jboss-public-repository-group</id>
- <name>JBoss Public Maven Repository Group</name>
- <url>https://repository.jboss.org/nexus/content/groups/public/</url>
- <snapshots>
- <enabled>false</enabled>
- </snapshots>
- </repository>
- </repositories>
-
</project>
-
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/LoadMetric.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/LoadMetric.java
new file mode 100644
index 0000000..1223508
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/LoadMetric.java
@@ -0,0 +1,29 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2009 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.modcluster;
+
+import org.rhq.plugins.jmx.MBeanResourceComponent;
+
+/**
+ * @author Stefan Negrea
+ *
+ */
+public class LoadMetric extends MBeanResourceComponent {
+
+}
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterDiscoveryComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterDiscoveryComponent.java
new file mode 100644
index 0000000..fa807a3
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterDiscoveryComponent.java
@@ -0,0 +1,116 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.modcluster;
+
+import java.util.HashSet;
+import java.util.List;
+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.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ManualAddFacet;
+import org.rhq.core.pluginapi.inventory.ProcessScanResult;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+
+/**
+ * This can be the start of your own custom plugin's discovery component. Review the javadoc for
+ * {@link ResourceDiscoveryComponent}.
+ *
+ * @author John Mazzitelli
+ */
+@SuppressWarnings("unchecked")
+public class ModclusterDiscoveryComponent implements ResourceDiscoveryComponent, ManualAddFacet {
+ private final Log log = LogFactory.getLog(ModclusterDiscoveryComponent.class);
+
+ /**
+ * This discovery method is the way the plugin supports "manual-add" capability. The plugin
+ * descriptor must specify supportsManualAdd="true" to allow the resource to be manually added.
+ * If that attribute is false, this method will never be used since it will not be possible to manually
+ * add an instance of the resource.
+ *
+ * Review the javadoc for both {@link ManualAddFacet} and {@link ResourceDiscoveryContext} to learn what
+ * you need to do in this method.
+ *
+ * @see ManualAddFacet#discoverResource(Configuration, ResourceDiscoveryContext)
+ */
+ @Override
+ public DiscoveredResourceDetails discoverResource(Configuration pluginConfiguration,
+ ResourceDiscoveryContext context) throws InvalidPluginConfigurationException {
+
+ // pluginConfiguration contains information on a resource that was manually added by the user.
+ // take it and build a details object that represents that resource.
+
+ // key = this must be a unique string across all of your resources - see docs for uniqueness rules
+ // name = this is the name you give the new resource; it does not necessarily have to be unique
+ // version = this is any string that corresponds to the resource's version
+ // description = this is any string that you want to assign as the default description for your resource
+ String key = "My Manually Added Resource Key";
+ String name = "My Resource";
+ String version = "1.0";
+ String description = "This describes My Resource";
+
+ DiscoveredResourceDetails resource = new DiscoveredResourceDetails(context.getResourceType(), key, name,
+ version, description, pluginConfiguration, null);
+
+ return resource;
+ }
+
+ /**
+ * Review the javadoc for both {@link ResourceDiscoveryComponent} and {@link ResourceDiscoveryContext} to learn what
+ * you need to do in this method.
+ *
+ * @see ResourceDiscoveryComponent#discoverResources(ResourceDiscoveryContext)
+ */
+ @Override
+ public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext context) {
+ log.info("Discovering my custom plugin's resources");
+
+ // if your plugin descriptor defined one or more <process-scan>s, then see if the plugin container
+ // auto-discovered processes using those process scan definitions. Process all those that were found.
+ List<ProcessScanResult> autoDiscoveryResults = context.getAutoDiscoveredProcesses();
+ for (ProcessScanResult autoDiscoveryResult : autoDiscoveryResults) {
+ // determine if you want to include the result in this method's returned set of discovered resources
+ }
+
+ // now perform your own discovery mechanism, if you have one. For each resource discovered, you need to
+ // create a details object that describe the resource that you discovered.
+ HashSet<DiscoveredResourceDetails> set = new HashSet<DiscoveredResourceDetails>();
+
+ // key = this must be a unique string across all of your resources - see docs for uniqueness rules
+ // name = this is the name you give the new resource; it does not necessarily have to be unique
+ // version = this is any string that corresponds to the resource's version
+ // description = this is any string that you want to assign as the default description for your resource
+ String key = "My Resource Key";
+ String name = "My Resource";
+ String version = "1.0";
+ String description = "This describes My Resource";
+
+ DiscoveredResourceDetails resource = new DiscoveredResourceDetails(context.getResourceType(), key, name,
+ version, description, null, null);
+
+ set.add(resource);
+
+ return set;
+ }
+}
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
new file mode 100644
index 0000000..6d6998a
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ModclusterServerComponent.java
@@ -0,0 +1,168 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.modcluster;
+
+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.configuration.ConfigurationUpdateStatus;
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.domain.measurement.MeasurementDataNumeric;
+import org.rhq.core.domain.measurement.MeasurementReport;
+import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
+import org.rhq.core.pluginapi.configuration.ConfigurationFacet;
+import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport;
+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;
+
+/**
+ * This can be the start of your own custom plugin's server component. Review the javadoc for {@link ResourceComponent}
+ * and all the facet interfaces to learn what you can do in your resource component. This component has a lot of methods
+ * in it because it implements all possible facets. If your resource does not support, for example, configuration, you
+ * can remove the {@link ConfigurationFacet} from the <code>implements</code> clause and remove all method
+ * implementations that that facet required.
+ *
+ * <p>You should not only read the javadoc in each of this class' methods, but you should also read the javadocs linked
+ * by their "see" javadoc tags since those additional javadocs will contain a good deal of additional information you
+ * will need to know.</p>
+ *
+ * @author John Mazzitelli
+ */
+public class ModclusterServerComponent implements ResourceComponent, MeasurementFacet, OperationFacet,
+ ConfigurationFacet {
+ private final Log log = LogFactory.getLog(ModclusterServerComponent.class);
+
+ /**
+ * Represents the resource configuration of the custom product being managed.
+ */
+ private Configuration resourceConfiguration;
+
+ /**
+ * All AMPS plugins are stateful - this context contains information that your resource component can use when
+ * performing its processing.
+ */
+ private ResourceContext resourceContext;
+
+ /**
+ * This is called when your component has been started with the given context. You normally initialize some internal
+ * state of your component as well as attempt to make a stateful connection to your managed resource.
+ *
+ * @see ResourceComponent#start(ResourceContext)
+ */
+ public void start(ResourceContext context) {
+ resourceContext = context;
+ }
+
+ /**
+ * This is called when the component is being stopped, usually due to the plugin container shutting down. You can
+ * perform some cleanup here; though normally not much needs to be done here.
+ *
+ * @see ResourceComponent#stop()
+ */
+ public void stop() {
+ }
+
+ /**
+ * All resource components must be able to tell the plugin container if the managed resource is available or not.
+ * This method is called by the plugin container when it needs to know if the managed resource is actually up and
+ * available.
+ *
+ * @see ResourceComponent#getAvailability()
+ */
+ public AvailabilityType getAvailability() {
+ // TODO: here you normally make some type of connection attempt to the managed resource
+ // to determine if it is really up and running.
+ return AvailabilityType.UP;
+ }
+
+ /**
+ * The plugin container will call this method when your resource component has been scheduled to collect some
+ * measurements now. It is within this method that you actually talk to the managed resource and collect the
+ * measurement data that is has emitted.
+ *
+ * @see MeasurementFacet#getValues(MeasurementReport, Set)
+ */
+ public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> requests) {
+ for (MeasurementScheduleRequest request : requests) {
+ String name = request.getName();
+
+ // TODO: based on the request information, you must collect the requested measurement(s)
+ // you can use the name of the measurement to determine what you actually need to collect
+ try {
+ Number value = new Integer(1); // dummy measurement value - this should come from the managed resource
+ report.addData(new MeasurementDataNumeric(request, value.doubleValue()));
+ } catch (Exception e) {
+ log.error("Failed to obtain measurement [" + name + "]. Cause: " + e);
+ }
+ }
+
+ return;
+ }
+
+ /**
+ * The plugin container will call this method when it wants to invoke an operation on your managed resource. Your
+ * plugin will connect to the managed resource and invoke the analogous operation in your own custom way.
+ *
+ * @see OperationFacet#invokeOperation(String, Configuration)
+ */
+ public OperationResult invokeOperation(String name, Configuration configuration) {
+ return null;
+ }
+
+ /**
+ * The plugin container will call this method and it needs to obtain the current configuration of the managed
+ * resource. Your plugin will obtain the managed resource's configuration in your own custom way and populate the
+ * returned Configuration object with the managed resource's configuration property values.
+ *
+ * @see ConfigurationFacet#loadResourceConfiguration()
+ */
+ public Configuration loadResourceConfiguration() {
+ // here we simulate the loading of the managed resource's configuration
+
+ if (resourceConfiguration == null) {
+ // for this example, we will create a simple dummy configuration to start with.
+ // note that it is empty, so we're assuming there are no required configs in the plugin descriptor.
+ resourceConfiguration = new Configuration();
+ }
+
+ Configuration config = resourceConfiguration;
+
+ return config;
+ }
+
+ /**
+ * The plugin container will call this method when it has a new configuration for your managed resource. Your plugin
+ * will re-configure the managed resource in your own custom way, setting its configuration based on the new values
+ * of the given configuration.
+ *
+ * @see ConfigurationFacet#updateResourceConfiguration(ConfigurationUpdateReport)
+ */
+ public void updateResourceConfiguration(ConfigurationUpdateReport report) {
+ // this simulates the plugin taking the new configuration and reconfiguring the managed resource
+ resourceConfiguration = report.getConfiguration().deepCopy();
+
+ report.setStatus(ConfigurationUpdateStatus.SUCCESS);
+ }
+}
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginDiscoveryComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginDiscoveryComponent.java
deleted file mode 100644
index 2abd0ea..0000000
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginDiscoveryComponent.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 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.modcluster;
-
-import java.util.HashSet;
-import java.util.List;
-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.pluginapi.inventory.DiscoveredResourceDetails;
-import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
-import org.rhq.core.pluginapi.inventory.ManualAddFacet;
-import org.rhq.core.pluginapi.inventory.ProcessScanResult;
-import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
-import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
-
-/**
- * This can be the start of your own custom plugin's discovery component. Review the javadoc for
- * {@link ResourceDiscoveryComponent}.
- *
- * @author John Mazzitelli
- */
-@SuppressWarnings("unchecked")
-public class SamplePluginDiscoveryComponent implements ResourceDiscoveryComponent, ManualAddFacet {
- private final Log log = LogFactory.getLog(SamplePluginDiscoveryComponent.class);
-
- /**
- * This discovery method is the way the plugin supports "manual-add" capability. The plugin
- * descriptor must specify supportsManualAdd="true" to allow the resource to be manually added.
- * If that attribute is false, this method will never be used since it will not be possible to manually
- * add an instance of the resource.
- *
- * Review the javadoc for both {@link ManualAddFacet} and {@link ResourceDiscoveryContext} to learn what
- * you need to do in this method.
- *
- * @see ManualAddFacet#discoverResource(Configuration, ResourceDiscoveryContext)
- */
- @Override
- public DiscoveredResourceDetails discoverResource(Configuration pluginConfiguration,
- ResourceDiscoveryContext context) throws InvalidPluginConfigurationException {
-
- // pluginConfiguration contains information on a resource that was manually added by the user.
- // take it and build a details object that represents that resource.
-
- // key = this must be a unique string across all of your resources - see docs for uniqueness rules
- // name = this is the name you give the new resource; it does not necessarily have to be unique
- // version = this is any string that corresponds to the resource's version
- // description = this is any string that you want to assign as the default description for your resource
- String key = "My Manually Added Resource Key";
- String name = "My Resource";
- String version = "1.0";
- String description = "This describes My Resource";
-
- DiscoveredResourceDetails resource = new DiscoveredResourceDetails(context.getResourceType(), key, name,
- version, description, pluginConfiguration, null);
-
- return resource;
- }
-
- /**
- * Review the javadoc for both {@link ResourceDiscoveryComponent} and {@link ResourceDiscoveryContext} to learn what
- * you need to do in this method.
- *
- * @see ResourceDiscoveryComponent#discoverResources(ResourceDiscoveryContext)
- */
- @Override
- public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext context) {
- log.info("Discovering my custom plugin's resources");
-
- // if your plugin descriptor defined one or more <process-scan>s, then see if the plugin container
- // auto-discovered processes using those process scan definitions. Process all those that were found.
- List<ProcessScanResult> autoDiscoveryResults = context.getAutoDiscoveredProcesses();
- for (ProcessScanResult autoDiscoveryResult : autoDiscoveryResults) {
- // determine if you want to include the result in this method's returned set of discovered resources
- }
-
- // now perform your own discovery mechanism, if you have one. For each resource discovered, you need to
- // create a details object that describe the resource that you discovered.
- HashSet<DiscoveredResourceDetails> set = new HashSet<DiscoveredResourceDetails>();
-
- // key = this must be a unique string across all of your resources - see docs for uniqueness rules
- // name = this is the name you give the new resource; it does not necessarily have to be unique
- // version = this is any string that corresponds to the resource's version
- // description = this is any string that you want to assign as the default description for your resource
- String key = "My Resource Key";
- String name = "My Resource";
- String version = "1.0";
- String description = "This describes My Resource";
-
- DiscoveredResourceDetails resource = new DiscoveredResourceDetails(context.getResourceType(), key, name,
- version, description, null, null);
-
- set.add(resource);
-
- return set;
- }
-}
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginServerComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginServerComponent.java
deleted file mode 100644
index 0236532..0000000
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginServerComponent.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 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.modcluster;
-
-import java.io.InputStream;
-import java.util.List;
-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.configuration.ConfigurationUpdateStatus;
-import org.rhq.core.domain.content.PackageType;
-import org.rhq.core.domain.content.transfer.DeployPackageStep;
-import org.rhq.core.domain.content.transfer.DeployPackagesResponse;
-import org.rhq.core.domain.content.transfer.RemovePackagesResponse;
-import org.rhq.core.domain.content.transfer.ResourcePackageDetails;
-import org.rhq.core.domain.measurement.AvailabilityType;
-import org.rhq.core.domain.measurement.MeasurementDataNumeric;
-import org.rhq.core.domain.measurement.MeasurementReport;
-import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
-import org.rhq.core.pluginapi.configuration.ConfigurationFacet;
-import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport;
-import org.rhq.core.pluginapi.content.ContentFacet;
-import org.rhq.core.pluginapi.content.ContentServices;
-import org.rhq.core.pluginapi.inventory.CreateChildResourceFacet;
-import org.rhq.core.pluginapi.inventory.CreateResourceReport;
-import org.rhq.core.pluginapi.inventory.DeleteResourceFacet;
-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;
-
-/**
- * This can be the start of your own custom plugin's server component. Review the javadoc for {@link ResourceComponent}
- * and all the facet interfaces to learn what you can do in your resource component. This component has a lot of methods
- * in it because it implements all possible facets. If your resource does not support, for example, configuration, you
- * can remove the {@link ConfigurationFacet} from the <code>implements</code> clause and remove all method
- * implementations that that facet required.
- *
- * <p>You should not only read the javadoc in each of this class' methods, but you should also read the javadocs linked
- * by their "see" javadoc tags since those additional javadocs will contain a good deal of additional information you
- * will need to know.</p>
- *
- * @author John Mazzitelli
- */
-public class SamplePluginServerComponent implements ResourceComponent, MeasurementFacet, OperationFacet,
- ConfigurationFacet, ContentFacet, DeleteResourceFacet, CreateChildResourceFacet {
- private final Log log = LogFactory.getLog(SamplePluginServerComponent.class);
-
- /**
- * Represents the resource configuration of the custom product being managed.
- */
- private Configuration resourceConfiguration;
-
- /**
- * All AMPS plugins are stateful - this context contains information that your resource component can use when
- * performing its processing.
- */
- private ResourceContext resourceContext;
-
- /**
- * This is called when your component has been started with the given context. You normally initialize some internal
- * state of your component as well as attempt to make a stateful connection to your managed resource.
- *
- * @see ResourceComponent#start(ResourceContext)
- */
- public void start(ResourceContext context) {
- resourceContext = context;
- }
-
- /**
- * This is called when the component is being stopped, usually due to the plugin container shutting down. You can
- * perform some cleanup here; though normally not much needs to be done here.
- *
- * @see ResourceComponent#stop()
- */
- public void stop() {
- }
-
- /**
- * All resource components must be able to tell the plugin container if the managed resource is available or not.
- * This method is called by the plugin container when it needs to know if the managed resource is actually up and
- * available.
- *
- * @see ResourceComponent#getAvailability()
- */
- public AvailabilityType getAvailability() {
- // TODO: here you normally make some type of connection attempt to the managed resource
- // to determine if it is really up and running.
- return AvailabilityType.UP;
- }
-
- /**
- * The plugin container will call this method when your resource component has been scheduled to collect some
- * measurements now. It is within this method that you actually talk to the managed resource and collect the
- * measurement data that is has emitted.
- *
- * @see MeasurementFacet#getValues(MeasurementReport, Set)
- */
- public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> requests) {
- for (MeasurementScheduleRequest request : requests) {
- String name = request.getName();
-
- // TODO: based on the request information, you must collect the requested measurement(s)
- // you can use the name of the measurement to determine what you actually need to collect
- try {
- Number value = new Integer(1); // dummy measurement value - this should come from the managed resource
- report.addData(new MeasurementDataNumeric(request, value.doubleValue()));
- } catch (Exception e) {
- log.error("Failed to obtain measurement [" + name + "]. Cause: " + e);
- }
- }
-
- return;
- }
-
- /**
- * The plugin container will call this method when it wants to invoke an operation on your managed resource. Your
- * plugin will connect to the managed resource and invoke the analogous operation in your own custom way.
- *
- * @see OperationFacet#invokeOperation(String, Configuration)
- */
- public OperationResult invokeOperation(String name, Configuration configuration) {
- return null;
- }
-
- /**
- * The plugin container will call this method and it needs to obtain the current configuration of the managed
- * resource. Your plugin will obtain the managed resource's configuration in your own custom way and populate the
- * returned Configuration object with the managed resource's configuration property values.
- *
- * @see ConfigurationFacet#loadResourceConfiguration()
- */
- public Configuration loadResourceConfiguration() {
- // here we simulate the loading of the managed resource's configuration
-
- if (resourceConfiguration == null) {
- // for this example, we will create a simple dummy configuration to start with.
- // note that it is empty, so we're assuming there are no required configs in the plugin descriptor.
- resourceConfiguration = new Configuration();
- }
-
- Configuration config = resourceConfiguration;
-
- return config;
- }
-
- /**
- * The plugin container will call this method when it has a new configuration for your managed resource. Your plugin
- * will re-configure the managed resource in your own custom way, setting its configuration based on the new values
- * of the given configuration.
- *
- * @see ConfigurationFacet#updateResourceConfiguration(ConfigurationUpdateReport)
- */
- public void updateResourceConfiguration(ConfigurationUpdateReport report) {
- // this simulates the plugin taking the new configuration and reconfiguring the managed resource
- resourceConfiguration = report.getConfiguration().deepCopy();
-
- report.setStatus(ConfigurationUpdateStatus.SUCCESS);
- }
-
- /**
- * When this is called, the plugin is responsible for scanning its managed resource and look for content that need
- * to be managed for that resource. This method should only discover packages of the given package type.
- *
- * @see ContentFacet#discoverDeployedPackages(PackageType)
- */
- public Set<ResourcePackageDetails> discoverDeployedPackages(PackageType type) {
- return null;
- }
-
- /**
- * The plugin container calls this method when new packages need to be deployed/installed on resources.
- *
- * @see ContentFacet#deployPackages(Set, ContentServices)
- */
- public DeployPackagesResponse deployPackages(Set<ResourcePackageDetails> packages, ContentServices contentServices) {
- return null;
- }
-
- /**
- * When a remote client wants to see the actual data content for an installed package, this method will be called.
- * This method must return a stream of data containing the full content of the package.
- *
- * @see ContentFacet#retrievePackageBits(ResourcePackageDetails)
- */
- public InputStream retrievePackageBits(ResourcePackageDetails packageDetails) {
- return null;
- }
-
- /**
- * This is the method that is used when the component has to create the installation steps and their results.
- *
- * @see ContentFacet#generateInstallationSteps(ResourcePackageDetails)
- */
- public List<DeployPackageStep> generateInstallationSteps(ResourcePackageDetails packageDetails) {
- return null;
- }
-
- /**
- * This is called when the actual content of packages should be deleted from the managed resource.
- *
- * @see ContentFacet#removePackages(Set)
- */
- public RemovePackagesResponse removePackages(Set<ResourcePackageDetails> packages) {
- return null;
- }
-
- /**
- * When called, the plugin container is asking the plugin to create a new managed resource. The new resource's
- * details need to be added to the given report.
- *
- * @see CreateChildResourceFacet#createResource(CreateResourceReport)
- */
- public CreateResourceReport createResource(CreateResourceReport report) {
- return null;
- }
-
- /**
- * When called, the plugin container is asking the plugin to delete a managed resource.
- *
- * @see DeleteResourceFacet#deleteResource()
- */
- public void deleteResource() {
- }
-}
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index 1a99bf7..fe6d1b3 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -10,97 +10,23 @@
<depends plugin="JMX" />
- <!--
- CHANGE: The following is a sample server resource type. This entry is here to serve as a model and should
- be removed prior to deploying the plugin. Multiple resource types (either server or service) may be
- defined at this level.
- -->
- <server name="mod_cluster"
- discovery="SamplePluginDiscoveryComponent"
- class="SamplePluginServerComponent"
+ <service name="mod_cluster"
+ discovery="org.rhq.plugins.jmx.MBeanResourceDiscoveryComponent"
+ class="LoadMetric"
supportsManualAdd="true"
description="mod_cluster plugin">
-
- <!--
- CHANGE: Categories are optional; this entire section may be removed if there is no need to further group
- related child resources. Categories defined at this level can carry metadata on the category itself,
- such as a display name and description.
- -->
- <subcategories>
- <subcategory name="Category1" displayName="Sample Category 1"
- description="This is a sample category that should be removed."/>
- <subcategory name="Category2" >
- <subcategory name="ChildCategory2a" />
- </subcategory>
- </subcategories>
-
- <!--
- CHANGE: The entire plugin configuration is optional. If there are properties specific to handling how the
- resource component will connect to the resource, they should be added here. If the plugin-configuration
- entity is specified, at least one property must be provided.
- -->
- <plugin-configuration>
- <c:simple-property name="SamplePluginProperty" displayName="Sample Plugin Property" default="Value" />
+
+ <!-- runs-inside>
+ <parent-resource-type name="JMX Server" plugin="JMX"/>
+ </runs-inside-->
+ <runs-inside>
+ <parent-resource-type name="JMX Server" plugin="JMX"/>
+ </runs-inside>
+
+ <plugin-configuration>
+ <c:simple-property name="connectorAddress" default="http://192.168.1.56:6666"/>
+ <c:simple-property name="objectName" readOnly="true" default="ModClusterServiceMBean"/>
</plugin-configuration>
- <!--
- CHANGE: The process-scan element requests the plugin container provide the discovery component for
- this resource type with the results of scanning the machine for running processes. If there is
- no use for this in a given resource type, this entry may be omitted.
- -->
- <process-scan name="ScanIdentifier" query="process|basename|match=^java.*,arg|org.jboss.Main|match=.*"/>
-
- <!--
- CHANGE: An operation element is added for each operation that may be executed against resources of this type.
- The parameters element is optional; properties defined within will be displayed to the user when
- invoking the operation. If the resource has no applicable operations, these elements may be omitted.
-
- REQUIRED INTERFACE: The resource component for this resource type must implement the OperationFacet interface
- if any operations are specified.
- -->
- <operation name="testSimple"
- description="Test simple-property configuration element for a resource operation">
- <parameters>
- <c:group name="required" displayName="Required Parameters" hiddenByDefault="false">
- <c:description>All of these properties are required</c:description>
- <c:simple-property name="aNumber" type="integer" required="true" default="42" displayName="A Number" description="A number between 1 and 100, inclusive">
- <c:constraint>
- <c:integer-constraint minimum="1" maximum="100"/>
- </c:constraint>
- </c:simple-property>
- </c:group>
- </parameters>
- <results>
- <c:simple-property name="results" />
- </results>
- </operation>
-
- <!--
- CHANGE: For each measurement that should be collected for resources of this type, a metric element is added.
- In addition to identifying the metric, a default collection interval and whether or not the
- metric is even collected by default are indicated. If the resource has no measurements to be
- collected, these elements may be omitted.
-
- REQUIRED INTERFACE: The resource component for this resource type must implement the MeasurementFacet interface
- if any metrics are specified.
- -->
- <metric property="MeasurementName"
- displayName="The Measurement Name"
- description="Describes what this measurement is actually telling you"
- defaultOn="true"
- defaultInterval="300000"
- category="performance" />
-
- <!--
- CHANGE: Resource configuration properties are used to configure resources themselves, as compared to the plugin
- configuration which refers to the connection to a resource. If the resource-configuration
- entity is specified, at least one property must be provided.
-
- REQUIRED INTERFACE: The resource component for this resource type must implement the ConfigurationFacet
- interface if a resource-configuration element is supplied.
- -->
- <resource-configuration>
- <c:simple-property name="port" type="integer" displayName="Port on which to listen" />
- </resource-configuration>
- </server>
+ </service>
</plugin>
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
index bada521..971ccb1 100644
--- a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
@@ -24,6 +24,9 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.testng.annotations.AfterSuite;
+import org.testng.annotations.BeforeSuite;
+import org.testng.annotations.Test;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
import org.rhq.core.domain.resource.Resource;
@@ -32,22 +35,19 @@ import org.rhq.core.pc.PluginContainerConfiguration;
import org.rhq.core.pc.plugin.FileSystemPluginFinder;
import org.rhq.core.pc.plugin.PluginEnvironment;
import org.rhq.core.pc.plugin.PluginManager;
-import org.testng.annotations.AfterSuite;
-import org.testng.annotations.BeforeSuite;
-import org.testng.annotations.Test;
/**
* @author Fady Matar
*/
-@Test(groups = "tomcat-plugin")
+@Test(groups = "modcluster-plugin")
public class ModclusterPluginTest {
private Log log = LogFactory.getLog(this.getClass());
- private static final String PLUGIN_NAME = "Tomcat";
+ private static final String PLUGIN_NAME = "mod_cluster";
@BeforeSuite
public void start() {
try {
- File pluginDir = new File("target/itest/plugins");
+ File pluginDir = new File("target/testsetup/plugins");
PluginContainerConfiguration pcConfig = new PluginContainerConfiguration();
pcConfig.setPluginFinder(new FileSystemPluginFinder(pluginDir));
pcConfig.setPluginDirectory(pluginDir);
@@ -75,16 +75,22 @@ public class ModclusterPluginTest {
PluginEnvironment pluginEnvironment = pluginManager.getPlugin(PLUGIN_NAME);
assert (pluginEnvironment != null) : "Null environment, plugin not loaded";
assert (pluginEnvironment.getPluginName().equals(PLUGIN_NAME));
+
}
@Test(dependsOnMethods = "testPluginLoad")
public void testDiscovery() throws Exception {
InventoryReport report = PluginContainer.getInstance().getInventoryManager().executeServerScanImmediately();
assert report != null;
- log.info("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
+ System.out.println("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
+
+ report = PluginContainer.getInstance().getInventoryManager().executeServiceScanImmediately();
+ assert report != null;
+ System.out.println("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
+
Set<Resource> resources = findResource(PluginContainer.getInstance().getInventoryManager().getPlatform(),
- "Tomcat");
- log.info("Found " + resources.size() + " ews / apache tomcat instance(s).");
+ PLUGIN_NAME);
+ log.info("Found " + resources.size() + "mod_cluster instance(s).");
}
private Set<Resource> findResource(Resource parent, String typeName) {
commit 82bacafdbd2cc892ad6e98a2a7362ae36cc61c57
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Thu Jun 23 11:09:56 2011 -0500
A couple of updates to modcluster plugin based on tomcat plugin (modified the initial template commit).
diff --git a/modules/plugins/mod-cluster/pom.xml b/modules/plugins/mod-cluster/pom.xml
index b72c93d..e22efc7 100644
--- a/modules/plugins/mod-cluster/pom.xml
+++ b/modules/plugins/mod-cluster/pom.xml
@@ -1,25 +1,36 @@
<?xml version="1.0"?>
-<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">
+<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>
- <groupId>org.rhq.sample.skeletonplugin</groupId>
- <artifactId>skeleton-plugin</artifactId>
+ <parent>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-plugins-parent</artifactId>
+ <version>4.1.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.rhq.plugins.modcluster</groupId>
+ <artifactId>modcluster-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
- <name>Skeleton RHQ Plugin Template</name>
- <description>A template for building a custom RHQ Agent plugin</description>
+ <name>mod_cluster RHQ Plugin</name>
+ <description>mod_cluster RHQ Agent plugin</description>
- <properties>
+ <!--properties>
<rhq.version>4.1.0-SNAPSHOT</rhq.version>
- </properties>
+ </properties-->
<dependencies>
+ <dependency>
+ <groupId>${rhq.groupId}</groupId>
+ <artifactId>rhq-jmx-plugin</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
<!-- Below are the core modules that are required dependencies of all plugins -->
<dependency>
<groupId>org.rhq</groupId>
@@ -77,15 +88,14 @@
<scope>provided</scope>
</dependency>
- <!--
+
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
<scope>provided</scope>
</dependency>
- -->
-
+
<!--
<dependency>
<groupId>i18nlog</groupId>
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginDiscoveryComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginDiscoveryComponent.java
index 2bb46e6..2abd0ea 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginDiscoveryComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginDiscoveryComponent.java
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-package org.rhq.sample.skeletonplugin;
+package org.rhq.plugins.modcluster;
import java.util.HashSet;
import java.util.List;
@@ -113,4 +113,4 @@ public class SamplePluginDiscoveryComponent implements ResourceDiscoveryComponen
return set;
}
-}
\ No newline at end of file
+}
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginServerComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginServerComponent.java
index 701afb0..0236532 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginServerComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginServerComponent.java
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-package org.rhq.sample.skeletonplugin;
+package org.rhq.plugins.modcluster;
import java.io.InputStream;
import java.util.List;
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index 2547af7..1a99bf7 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -1,36 +1,25 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<!--
- See the rhq-plugin.xsd file for detailed documentatoin on the schema. The notes in this file are to
- facilitate using this file as a base plugin descriptor.
--->
-
-<!--
- CHANGE: The name (and optional displayName) should be changed to reflect the plugin being developed. Keep in mind
- the value for name must be unique across all other plugins that are deployed.
-
- The package attribute should be changed to reflect the package in which all of the component classes
- are built.
--->
-<plugin name="SkeletonPlugin"
- displayName="Skeleton Plugin"
+<plugin name="mod_cluster"
+ displayName="mod_cluster"
version="1.0"
- package="org.rhq.sample.skeletonplugin"
+ package="org.rhq.plugins.modcluster"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
+ <depends plugin="JMX" />
- <!--
+ <!--
CHANGE: The following is a sample server resource type. This entry is here to serve as a model and should
be removed prior to deploying the plugin. Multiple resource types (either server or service) may be
defined at this level.
-->
- <server name="Sample Plugin Server"
+ <server name="mod_cluster"
discovery="SamplePluginDiscoveryComponent"
class="SamplePluginServerComponent"
supportsManualAdd="true"
- description="This is a sample resource type and should be removed.">
+ description="mod_cluster plugin">
<!--
CHANGE: Categories are optional; this entire section may be removed if there is no need to further group
diff --git a/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
new file mode 100644
index 0000000..bada521
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/test/java/org/rhq/plugins/modcluster/test/ModclusterPluginTest.java
@@ -0,0 +1,106 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.modcluster.test;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.pc.PluginContainer;
+import org.rhq.core.pc.PluginContainerConfiguration;
+import org.rhq.core.pc.plugin.FileSystemPluginFinder;
+import org.rhq.core.pc.plugin.PluginEnvironment;
+import org.rhq.core.pc.plugin.PluginManager;
+import org.testng.annotations.AfterSuite;
+import org.testng.annotations.BeforeSuite;
+import org.testng.annotations.Test;
+
+/**
+ * @author Fady Matar
+ */
+@Test(groups = "tomcat-plugin")
+public class ModclusterPluginTest {
+ private Log log = LogFactory.getLog(this.getClass());
+ private static final String PLUGIN_NAME = "Tomcat";
+
+ @BeforeSuite
+ public void start() {
+ try {
+ File pluginDir = new File("target/itest/plugins");
+ PluginContainerConfiguration pcConfig = new PluginContainerConfiguration();
+ pcConfig.setPluginFinder(new FileSystemPluginFinder(pluginDir));
+ pcConfig.setPluginDirectory(pluginDir);
+
+ pcConfig.setInsideAgent(false);
+ PluginContainer.getInstance().setConfiguration(pcConfig);
+ PluginContainer.getInstance().initialize();
+ log.info("PC started.");
+ for (String plugin : PluginContainer.getInstance().getPluginManager().getMetadataManager().getPluginNames()) {
+ log.info("...Loaded plugin: " + plugin);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @AfterSuite
+ public void stop() {
+ PluginContainer.getInstance().shutdown();
+ }
+
+ @Test
+ public void testPluginLoad() {
+ PluginManager pluginManager = PluginContainer.getInstance().getPluginManager();
+ PluginEnvironment pluginEnvironment = pluginManager.getPlugin(PLUGIN_NAME);
+ assert (pluginEnvironment != null) : "Null environment, plugin not loaded";
+ assert (pluginEnvironment.getPluginName().equals(PLUGIN_NAME));
+ }
+
+ @Test(dependsOnMethods = "testPluginLoad")
+ public void testDiscovery() throws Exception {
+ InventoryReport report = PluginContainer.getInstance().getInventoryManager().executeServerScanImmediately();
+ assert report != null;
+ log.info("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");
+ Set<Resource> resources = findResource(PluginContainer.getInstance().getInventoryManager().getPlatform(),
+ "Tomcat");
+ log.info("Found " + resources.size() + " ews / apache tomcat instance(s).");
+ }
+
+ private Set<Resource> findResource(Resource parent, String typeName) {
+ Set<Resource> found = new HashSet<Resource>();
+ Resource platform = parent;
+ for (Resource resource : platform.getChildResources()) {
+ log.info("Discovered resource of type: " + resource.getResourceType().getName());
+ if (resource.getResourceType().getName().equals(typeName)) {
+ found.add(resource);
+ }
+ if (resource.getChildResources() != null) {
+ for (Resource child : found) {
+ found.addAll(findResource(child, typeName));
+ }
+ }
+ }
+ return found;
+ }
+}
diff --git a/modules/plugins/mod-cluster/src/test/resources/log4j.xml b/modules/plugins/mod-cluster/src/test/resources/log4j.xml
new file mode 100644
index 0000000..9ac1be8
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/test/resources/log4j.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<!-- ===================================================================== -->
+<!-- -->
+<!-- Log4j Configuration -->
+<!-- -->
+<!-- ===================================================================== -->
+
+<!-- $Id: log4j.xml 9973 2008-05-08 00:57:31Z ispringer $ -->
+
+<!--
+ | For more configuration infromation and examples see the Jakarta Log4j
+ | owebsite: http://jakarta.apache.org/log4j
+ -->
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="true">
+
+ <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">
+ <!-- The default pattern: Date Priority [Category] Messagen -->
+
+ <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n"/>
+
+ <!--<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="Threshold" value="DEBUG"/>
+ <param name="Append" value="false"/>
+
+ <layout class="org.apache.log4j.PatternLayout">
+ <!-- The default pattern: Date Priority [Category] Messagen -->
+ <!--
+ <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n"/>
+ -->
+ <param name="ConversionPattern" value="%-5p %d{dd-MM HH:mm:ss,SSS} (%F:%M:%L) -%m%n"/>
+ </layout>
+ </appender>
+
+ <root>
+ <appender-ref ref="CONSOLE"/>
+ <appender-ref ref="FILE"/>
+ </root>
+
+</log4j:configuration>
commit 68ca76535a5aa082a5adbfa3adae1d49c9da2300
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Wed Jun 22 15:52:27 2011 -0500
Start for mod_cluster plugin from skeleton-plugin template.
diff --git a/modules/plugins/mod-cluster/pom.xml b/modules/plugins/mod-cluster/pom.xml
new file mode 100644
index 0000000..b72c93d
--- /dev/null
+++ b/modules/plugins/mod-cluster/pom.xml
@@ -0,0 +1,240 @@
+<?xml version="1.0"?>
+
+<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>
+
+ <groupId>org.rhq.sample.skeletonplugin</groupId>
+ <artifactId>skeleton-plugin</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <name>Skeleton RHQ Plugin Template</name>
+ <description>A template for building a custom RHQ Agent plugin</description>
+
+ <properties>
+ <rhq.version>4.1.0-SNAPSHOT</rhq.version>
+ </properties>
+
+ <dependencies>
+
+ <!-- Below are the core modules that are required dependencies of all plugins -->
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-domain</artifactId>
+ <version>${rhq.version}</version>
+ <scope>provided</scope> <!-- provided by the agent/plugin-container -->
+ </dependency>
+
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-plugin-api</artifactId>
+ <version>${rhq.version}</version>
+ <scope>provided</scope> <!-- provided by the agent/plugin-container -->
+ </dependency>
+
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-native-system</artifactId>
+ <version>${rhq.version}</version>
+ <scope>provided</scope> <!-- provided by the agent/plugin-container -->
+ </dependency>
+
+ <!-- Fix for the Javac bug requiring annotations to be available when compiling classes. (fixed in JDK 6) -->
+ <dependency>
+ <groupId>javax.persistence</groupId>
+ <artifactId>persistence-api</artifactId>
+ <version>1.0</version>
+ <scope>provided</scope> <!-- provided by the agent/plugin-container -->
+ </dependency>
+
+ <!-- Fix for the Javac bug requiring annotations to be available when compiling classes. (fixed in JDK 6) -->
+ <dependency>
+ <groupId>hibernate-annotations</groupId>
+ <artifactId>hibernate-annotations</artifactId>
+ <version>3.2.1.GA</version>
+ <scope>provided</scope> <!-- provided by the agent/plugin-container -->
+ </dependency>
+
+ <!-- Fix for the Javac bug requiring annotations to be available when compiling classes. (fixed in JDK 6) -->
+ <dependency>
+ <groupId>javax.xml.bind</groupId>
+ <artifactId>jaxb-api</artifactId>
+ <version>2.1</version>
+ <scope>provided</scope> <!-- provided by the agent/plugin-container -->
+ </dependency>
+
+ <!--
+ Uncomment the one of the three logging systems your plugin uses: log4j, commons-logging or i18nlog
+ All three are provided to your plugin by the agent/plugin-container.
+ -->
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <version>1.1</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <!--
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>1.2.14</version>
+ <scope>provided</scope>
+ </dependency>
+ -->
+
+ <!--
+ <dependency>
+ <groupId>i18nlog</groupId>
+ <artifactId>i18nlog</artifactId>
+ <version>1.0.9</version>
+ <scope>provided</scope>
+ </dependency>
+ -->
+
+ <!-- Define any third-party dependencies your plugin has here. -->
+ <!--
+ <dependency>
+ <groupId>group-id-of-dependency-goes-here</groupId>
+ <artifactId>artifact-id-of-dependency-goes-here</artifactId>
+ <version>version-of-dependency-goes-here</version>
+ </dependency>
+ -->
+
+ </dependencies>
+
+ <build>
+ <plugins>
+
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+
+ <!--
+ If your plugin has third-party jar dependencies that are not already available when deployed in the plugin
+ container, you can package these jars in your plugin. They go in your plugin jar's "lib" directory.
+ Uncomment the maven plugin definition below and define one or more jar files (aka "artifactItem" elements)
+ that you want to include in your plugin jar.
+ -->
+ <!--
+ <plugin>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy-dependencies</id>
+ <phase>process-resources</phase>
+ <goals>
+ <goal>copy</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>your-third-party-dep-group</groupId>
+ <artifactId>your-third-party-dep-artifact</artifactId>
+ <version>your-third-party-dep-version</version>
+ </artifactItem>
+ </artifactItems>
+ <outputDirectory>${project.build.outputDirectory}/lib</outputDirectory>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ -->
+
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>dev</id>
+ <properties>
+ <!-- define the location of your RHQ root directory - typically rhq.rootDir is overridden in Maven's settings.xml -->
+ <rhq.rootDir>/rhq/trunk</rhq.rootDir>
+ <rhq.defaultDevContainerPath>dev-container</rhq.defaultDevContainerPath>
+ <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir>
+ <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/rhq.ear/rhq-downloads/rhq-plugins</rhq.deploymentDir>
+ </properties>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.1</version>
+ <executions>
+ <execution>
+ <id>deploy</id>
+ <phase>compile</phase>
+ <configuration>
+ <tasks>
+ <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}" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>deploy-jar-meta-inf</id>
+ <phase>package</phase>
+ <configuration>
+ <tasks>
+ <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>
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>undeploy</id>
+ <phase>clean</phase>
+ <configuration>
+ <tasks>
+ <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
+ <echo>*** Deleting ${deployment.file}...</echo>
+ <delete file="${deployment.file}" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+ <repositories>
+ <repository>
+ <id>jboss-public-repository-group</id>
+ <name>JBoss Public Maven Repository Group</name>
+ <url>https://repository.jboss.org/nexus/content/groups/public/</url>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+
+</project>
+
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginDiscoveryComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginDiscoveryComponent.java
new file mode 100644
index 0000000..2bb46e6
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginDiscoveryComponent.java
@@ -0,0 +1,116 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.sample.skeletonplugin;
+
+import java.util.HashSet;
+import java.util.List;
+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.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ManualAddFacet;
+import org.rhq.core.pluginapi.inventory.ProcessScanResult;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+
+/**
+ * This can be the start of your own custom plugin's discovery component. Review the javadoc for
+ * {@link ResourceDiscoveryComponent}.
+ *
+ * @author John Mazzitelli
+ */
+@SuppressWarnings("unchecked")
+public class SamplePluginDiscoveryComponent implements ResourceDiscoveryComponent, ManualAddFacet {
+ private final Log log = LogFactory.getLog(SamplePluginDiscoveryComponent.class);
+
+ /**
+ * This discovery method is the way the plugin supports "manual-add" capability. The plugin
+ * descriptor must specify supportsManualAdd="true" to allow the resource to be manually added.
+ * If that attribute is false, this method will never be used since it will not be possible to manually
+ * add an instance of the resource.
+ *
+ * Review the javadoc for both {@link ManualAddFacet} and {@link ResourceDiscoveryContext} to learn what
+ * you need to do in this method.
+ *
+ * @see ManualAddFacet#discoverResource(Configuration, ResourceDiscoveryContext)
+ */
+ @Override
+ public DiscoveredResourceDetails discoverResource(Configuration pluginConfiguration,
+ ResourceDiscoveryContext context) throws InvalidPluginConfigurationException {
+
+ // pluginConfiguration contains information on a resource that was manually added by the user.
+ // take it and build a details object that represents that resource.
+
+ // key = this must be a unique string across all of your resources - see docs for uniqueness rules
+ // name = this is the name you give the new resource; it does not necessarily have to be unique
+ // version = this is any string that corresponds to the resource's version
+ // description = this is any string that you want to assign as the default description for your resource
+ String key = "My Manually Added Resource Key";
+ String name = "My Resource";
+ String version = "1.0";
+ String description = "This describes My Resource";
+
+ DiscoveredResourceDetails resource = new DiscoveredResourceDetails(context.getResourceType(), key, name,
+ version, description, pluginConfiguration, null);
+
+ return resource;
+ }
+
+ /**
+ * Review the javadoc for both {@link ResourceDiscoveryComponent} and {@link ResourceDiscoveryContext} to learn what
+ * you need to do in this method.
+ *
+ * @see ResourceDiscoveryComponent#discoverResources(ResourceDiscoveryContext)
+ */
+ @Override
+ public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext context) {
+ log.info("Discovering my custom plugin's resources");
+
+ // if your plugin descriptor defined one or more <process-scan>s, then see if the plugin container
+ // auto-discovered processes using those process scan definitions. Process all those that were found.
+ List<ProcessScanResult> autoDiscoveryResults = context.getAutoDiscoveredProcesses();
+ for (ProcessScanResult autoDiscoveryResult : autoDiscoveryResults) {
+ // determine if you want to include the result in this method's returned set of discovered resources
+ }
+
+ // now perform your own discovery mechanism, if you have one. For each resource discovered, you need to
+ // create a details object that describe the resource that you discovered.
+ HashSet<DiscoveredResourceDetails> set = new HashSet<DiscoveredResourceDetails>();
+
+ // key = this must be a unique string across all of your resources - see docs for uniqueness rules
+ // name = this is the name you give the new resource; it does not necessarily have to be unique
+ // version = this is any string that corresponds to the resource's version
+ // description = this is any string that you want to assign as the default description for your resource
+ String key = "My Resource Key";
+ String name = "My Resource";
+ String version = "1.0";
+ String description = "This describes My Resource";
+
+ DiscoveredResourceDetails resource = new DiscoveredResourceDetails(context.getResourceType(), key, name,
+ version, description, null, null);
+
+ set.add(resource);
+
+ return set;
+ }
+}
\ No newline at end of file
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginServerComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginServerComponent.java
new file mode 100644
index 0000000..701afb0
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/SamplePluginServerComponent.java
@@ -0,0 +1,245 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.sample.skeletonplugin;
+
+import java.io.InputStream;
+import java.util.List;
+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.configuration.ConfigurationUpdateStatus;
+import org.rhq.core.domain.content.PackageType;
+import org.rhq.core.domain.content.transfer.DeployPackageStep;
+import org.rhq.core.domain.content.transfer.DeployPackagesResponse;
+import org.rhq.core.domain.content.transfer.RemovePackagesResponse;
+import org.rhq.core.domain.content.transfer.ResourcePackageDetails;
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.domain.measurement.MeasurementDataNumeric;
+import org.rhq.core.domain.measurement.MeasurementReport;
+import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
+import org.rhq.core.pluginapi.configuration.ConfigurationFacet;
+import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport;
+import org.rhq.core.pluginapi.content.ContentFacet;
+import org.rhq.core.pluginapi.content.ContentServices;
+import org.rhq.core.pluginapi.inventory.CreateChildResourceFacet;
+import org.rhq.core.pluginapi.inventory.CreateResourceReport;
+import org.rhq.core.pluginapi.inventory.DeleteResourceFacet;
+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;
+
+/**
+ * This can be the start of your own custom plugin's server component. Review the javadoc for {@link ResourceComponent}
+ * and all the facet interfaces to learn what you can do in your resource component. This component has a lot of methods
+ * in it because it implements all possible facets. If your resource does not support, for example, configuration, you
+ * can remove the {@link ConfigurationFacet} from the <code>implements</code> clause and remove all method
+ * implementations that that facet required.
+ *
+ * <p>You should not only read the javadoc in each of this class' methods, but you should also read the javadocs linked
+ * by their "see" javadoc tags since those additional javadocs will contain a good deal of additional information you
+ * will need to know.</p>
+ *
+ * @author John Mazzitelli
+ */
+public class SamplePluginServerComponent implements ResourceComponent, MeasurementFacet, OperationFacet,
+ ConfigurationFacet, ContentFacet, DeleteResourceFacet, CreateChildResourceFacet {
+ private final Log log = LogFactory.getLog(SamplePluginServerComponent.class);
+
+ /**
+ * Represents the resource configuration of the custom product being managed.
+ */
+ private Configuration resourceConfiguration;
+
+ /**
+ * All AMPS plugins are stateful - this context contains information that your resource component can use when
+ * performing its processing.
+ */
+ private ResourceContext resourceContext;
+
+ /**
+ * This is called when your component has been started with the given context. You normally initialize some internal
+ * state of your component as well as attempt to make a stateful connection to your managed resource.
+ *
+ * @see ResourceComponent#start(ResourceContext)
+ */
+ public void start(ResourceContext context) {
+ resourceContext = context;
+ }
+
+ /**
+ * This is called when the component is being stopped, usually due to the plugin container shutting down. You can
+ * perform some cleanup here; though normally not much needs to be done here.
+ *
+ * @see ResourceComponent#stop()
+ */
+ public void stop() {
+ }
+
+ /**
+ * All resource components must be able to tell the plugin container if the managed resource is available or not.
+ * This method is called by the plugin container when it needs to know if the managed resource is actually up and
+ * available.
+ *
+ * @see ResourceComponent#getAvailability()
+ */
+ public AvailabilityType getAvailability() {
+ // TODO: here you normally make some type of connection attempt to the managed resource
+ // to determine if it is really up and running.
+ return AvailabilityType.UP;
+ }
+
+ /**
+ * The plugin container will call this method when your resource component has been scheduled to collect some
+ * measurements now. It is within this method that you actually talk to the managed resource and collect the
+ * measurement data that is has emitted.
+ *
+ * @see MeasurementFacet#getValues(MeasurementReport, Set)
+ */
+ public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> requests) {
+ for (MeasurementScheduleRequest request : requests) {
+ String name = request.getName();
+
+ // TODO: based on the request information, you must collect the requested measurement(s)
+ // you can use the name of the measurement to determine what you actually need to collect
+ try {
+ Number value = new Integer(1); // dummy measurement value - this should come from the managed resource
+ report.addData(new MeasurementDataNumeric(request, value.doubleValue()));
+ } catch (Exception e) {
+ log.error("Failed to obtain measurement [" + name + "]. Cause: " + e);
+ }
+ }
+
+ return;
+ }
+
+ /**
+ * The plugin container will call this method when it wants to invoke an operation on your managed resource. Your
+ * plugin will connect to the managed resource and invoke the analogous operation in your own custom way.
+ *
+ * @see OperationFacet#invokeOperation(String, Configuration)
+ */
+ public OperationResult invokeOperation(String name, Configuration configuration) {
+ return null;
+ }
+
+ /**
+ * The plugin container will call this method and it needs to obtain the current configuration of the managed
+ * resource. Your plugin will obtain the managed resource's configuration in your own custom way and populate the
+ * returned Configuration object with the managed resource's configuration property values.
+ *
+ * @see ConfigurationFacet#loadResourceConfiguration()
+ */
+ public Configuration loadResourceConfiguration() {
+ // here we simulate the loading of the managed resource's configuration
+
+ if (resourceConfiguration == null) {
+ // for this example, we will create a simple dummy configuration to start with.
+ // note that it is empty, so we're assuming there are no required configs in the plugin descriptor.
+ resourceConfiguration = new Configuration();
+ }
+
+ Configuration config = resourceConfiguration;
+
+ return config;
+ }
+
+ /**
+ * The plugin container will call this method when it has a new configuration for your managed resource. Your plugin
+ * will re-configure the managed resource in your own custom way, setting its configuration based on the new values
+ * of the given configuration.
+ *
+ * @see ConfigurationFacet#updateResourceConfiguration(ConfigurationUpdateReport)
+ */
+ public void updateResourceConfiguration(ConfigurationUpdateReport report) {
+ // this simulates the plugin taking the new configuration and reconfiguring the managed resource
+ resourceConfiguration = report.getConfiguration().deepCopy();
+
+ report.setStatus(ConfigurationUpdateStatus.SUCCESS);
+ }
+
+ /**
+ * When this is called, the plugin is responsible for scanning its managed resource and look for content that need
+ * to be managed for that resource. This method should only discover packages of the given package type.
+ *
+ * @see ContentFacet#discoverDeployedPackages(PackageType)
+ */
+ public Set<ResourcePackageDetails> discoverDeployedPackages(PackageType type) {
+ return null;
+ }
+
+ /**
+ * The plugin container calls this method when new packages need to be deployed/installed on resources.
+ *
+ * @see ContentFacet#deployPackages(Set, ContentServices)
+ */
+ public DeployPackagesResponse deployPackages(Set<ResourcePackageDetails> packages, ContentServices contentServices) {
+ return null;
+ }
+
+ /**
+ * When a remote client wants to see the actual data content for an installed package, this method will be called.
+ * This method must return a stream of data containing the full content of the package.
+ *
+ * @see ContentFacet#retrievePackageBits(ResourcePackageDetails)
+ */
+ public InputStream retrievePackageBits(ResourcePackageDetails packageDetails) {
+ return null;
+ }
+
+ /**
+ * This is the method that is used when the component has to create the installation steps and their results.
+ *
+ * @see ContentFacet#generateInstallationSteps(ResourcePackageDetails)
+ */
+ public List<DeployPackageStep> generateInstallationSteps(ResourcePackageDetails packageDetails) {
+ return null;
+ }
+
+ /**
+ * This is called when the actual content of packages should be deleted from the managed resource.
+ *
+ * @see ContentFacet#removePackages(Set)
+ */
+ public RemovePackagesResponse removePackages(Set<ResourcePackageDetails> packages) {
+ return null;
+ }
+
+ /**
+ * When called, the plugin container is asking the plugin to create a new managed resource. The new resource's
+ * details need to be added to the given report.
+ *
+ * @see CreateChildResourceFacet#createResource(CreateResourceReport)
+ */
+ public CreateResourceReport createResource(CreateResourceReport report) {
+ return null;
+ }
+
+ /**
+ * When called, the plugin container is asking the plugin to delete a managed resource.
+ *
+ * @see DeleteResourceFacet#deleteResource()
+ */
+ public void deleteResource() {
+ }
+}
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
new file mode 100644
index 0000000..2547af7
--- /dev/null
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+ See the rhq-plugin.xsd file for detailed documentatoin on the schema. The notes in this file are to
+ facilitate using this file as a base plugin descriptor.
+-->
+
+<!--
+ CHANGE: The name (and optional displayName) should be changed to reflect the plugin being developed. Keep in mind
+ the value for name must be unique across all other plugins that are deployed.
+
+ The package attribute should be changed to reflect the package in which all of the component classes
+ are built.
+-->
+<plugin name="SkeletonPlugin"
+ displayName="Skeleton Plugin"
+ version="1.0"
+ package="org.rhq.sample.skeletonplugin"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+
+ <!--
+ CHANGE: The following is a sample server resource type. This entry is here to serve as a model and should
+ be removed prior to deploying the plugin. Multiple resource types (either server or service) may be
+ defined at this level.
+ -->
+ <server name="Sample Plugin Server"
+ discovery="SamplePluginDiscoveryComponent"
+ class="SamplePluginServerComponent"
+ supportsManualAdd="true"
+ description="This is a sample resource type and should be removed.">
+
+ <!--
+ CHANGE: Categories are optional; this entire section may be removed if there is no need to further group
+ related child resources. Categories defined at this level can carry metadata on the category itself,
+ such as a display name and description.
+ -->
+ <subcategories>
+ <subcategory name="Category1" displayName="Sample Category 1"
+ description="This is a sample category that should be removed."/>
+ <subcategory name="Category2" >
+ <subcategory name="ChildCategory2a" />
+ </subcategory>
+ </subcategories>
+
+ <!--
+ CHANGE: The entire plugin configuration is optional. If there are properties specific to handling how the
+ resource component will connect to the resource, they should be added here. If the plugin-configuration
+ entity is specified, at least one property must be provided.
+ -->
+ <plugin-configuration>
+ <c:simple-property name="SamplePluginProperty" displayName="Sample Plugin Property" default="Value" />
+ </plugin-configuration>
+
+ <!--
+ CHANGE: The process-scan element requests the plugin container provide the discovery component for
+ this resource type with the results of scanning the machine for running processes. If there is
+ no use for this in a given resource type, this entry may be omitted.
+ -->
+ <process-scan name="ScanIdentifier" query="process|basename|match=^java.*,arg|org.jboss.Main|match=.*"/>
+
+ <!--
+ CHANGE: An operation element is added for each operation that may be executed against resources of this type.
+ The parameters element is optional; properties defined within will be displayed to the user when
+ invoking the operation. If the resource has no applicable operations, these elements may be omitted.
+
+ REQUIRED INTERFACE: The resource component for this resource type must implement the OperationFacet interface
+ if any operations are specified.
+ -->
+ <operation name="testSimple"
+ description="Test simple-property configuration element for a resource operation">
+ <parameters>
+ <c:group name="required" displayName="Required Parameters" hiddenByDefault="false">
+ <c:description>All of these properties are required</c:description>
+ <c:simple-property name="aNumber" type="integer" required="true" default="42" displayName="A Number" description="A number between 1 and 100, inclusive">
+ <c:constraint>
+ <c:integer-constraint minimum="1" maximum="100"/>
+ </c:constraint>
+ </c:simple-property>
+ </c:group>
+ </parameters>
+ <results>
+ <c:simple-property name="results" />
+ </results>
+ </operation>
+
+ <!--
+ CHANGE: For each measurement that should be collected for resources of this type, a metric element is added.
+ In addition to identifying the metric, a default collection interval and whether or not the
+ metric is even collected by default are indicated. If the resource has no measurements to be
+ collected, these elements may be omitted.
+
+ REQUIRED INTERFACE: The resource component for this resource type must implement the MeasurementFacet interface
+ if any metrics are specified.
+ -->
+ <metric property="MeasurementName"
+ displayName="The Measurement Name"
+ description="Describes what this measurement is actually telling you"
+ defaultOn="true"
+ defaultInterval="300000"
+ category="performance" />
+
+ <!--
+ CHANGE: Resource configuration properties are used to configure resources themselves, as compared to the plugin
+ configuration which refers to the connection to a resource. If the resource-configuration
+ entity is specified, at least one property must be provided.
+
+ REQUIRED INTERFACE: The resource component for this resource type must implement the ConfigurationFacet
+ interface if a resource-configuration element is supplied.
+ -->
+ <resource-configuration>
+ <c:simple-property name="port" type="integer" displayName="Port on which to listen" />
+ </resource-configuration>
+ </server>
+</plugin>
12 years, 10 months
[rhq] Branch 'as7plugin' - 2 commits - modules/plugins
by Heiko W. Rupp
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java | 49 ++++-
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java | 19 +-
modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml | 83 ++--------
3 files changed, 65 insertions(+), 86 deletions(-)
New commits:
commit f1b3ecdcd88a1dca8e39236caca260f51a100311
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Thu Jul 28 15:44:35 2011 +0200
BZ 726378 - management port settings on AS7 were not honored.
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
index 322e453..9aa9db0 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
@@ -111,12 +111,15 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
this.context = context;
pluginConfiguration = context.getPluginConfiguration();
- String typeName = context.getResourceType().getName();
- // TODO can we use parent's connection and only set this up for top level base component?
- host = pluginConfiguration.getSimpleValue("hostname", LOCALHOST);
- String portString = pluginConfiguration.getSimpleValue("port", DEFAULT_HTTP_MANAGEMENT_PORT);
- port = Integer.parseInt(portString);
- connection = new ASConnection(host,port);
+ if (!(context.getParentResourceComponent() instanceof BaseComponent)) {
+ host = pluginConfiguration.getSimpleValue("hostname", LOCALHOST);
+ String portString = pluginConfiguration.getSimpleValue("port", DEFAULT_HTTP_MANAGEMENT_PORT);
+ port = Integer.parseInt(portString);
+ connection = new ASConnection(host,port);
+ }
+ else {
+ connection = ((BaseComponent)context.getParentResourceComponent()).getASConnection();
+ }
path = pluginConfiguration.getSimpleValue("path", null);
key = context.getResourceKey();
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java
index 475fd62..471fd42 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java
@@ -79,11 +79,8 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
String psName = psr.getProcessScan().getName();
String description = discoveryContext.getResourceType().getDescription();
String version = null;
- String startScript;
- if (psName.equals("ProcessController")) {
- serverNameFull = "ProcessController";
- serverName = "ProcessController";
- } else if (psName.equals("HostController")) {
+
+ if (psName.equals("HostController")) {
readStandaloneOrHostXml(psr.getProcessInfo(), true);
HostPort hp = getDomainControllerFromHostXml();
if (hp.isLocal) {
@@ -118,11 +115,10 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
tmp = tmp.substring( i + 8);
tmp = tmp.substring(0,tmp.indexOf("/"));
serverNameFull = tmp;
-
- String host = findHost(psr.getProcessInfo(),true);
- config.put(new PropertySimple("domainHost",host));
-
}
+ String host = findHost(psr.getProcessInfo(),true);
+ config.put(new PropertySimple("domainHost",host));
+
config.put(new PropertySimple("baseDir",serverNameFull));
serverName = findHostName();
if (serverName.isEmpty())
@@ -139,6 +135,11 @@ public class BaseProcessDiscovery extends AbstractBaseDiscovery implements Resou
}
String logFile = getLogFileFromCommandLine(commandLine);
initLogEventSourcesConfigProp(logFile,config);
+
+ HostPort managmentPort = getManagementPortFromHostXml();
+ config.put(new PropertySimple("hostname",managmentPort.host));
+ config.put(new PropertySimple("port",managmentPort.port));
+
// String javaClazz = psr.getProcessInfo().getName();
commit d46c2fc9b284b6c4d8d1ef50d098f495a4ae9a50
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Thu Jul 28 13:17:00 2011 +0200
Initial support for messaging (JMS)
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
index 776e5ef..322e453 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
@@ -23,6 +23,8 @@ import org.apache.commons.logging.LogFactory;
import org.codehaus.jackson.JsonNode;
import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.Property;
+import org.rhq.core.domain.configuration.PropertyList;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
@@ -480,12 +482,34 @@ public class BaseComponent implements ResourceComponent, MeasurementFacet, Confi
} else if (what.equals("destination")) {
address.addAll(pathToAddress(getPath()));
String newName = parameters.getSimpleValue("name","");
-// String type = parameters.getSimpleValue("type","Queue").toLowerCase();
-// address.add(new PROPERTY_VALUE(type,newName));
- String queueName = parameters.getSimpleValue("queue-address","");
- Map<String,Object> props = new HashMap<String, Object>();
- props.put("queue-address",queueName);
+ String type = parameters.getSimpleValue("type","jms-queue").toLowerCase();
+ address.add(new PROPERTY_VALUE(type,newName));
+ PropertyList jndiNamesProp = parameters.getList("entries");
+ if (jndiNamesProp==null || jndiNamesProp.getList().isEmpty()) {
+ OperationResult fail = new OperationResult();
+ fail.setErrorMessage("No jndi bindings given");
+ return fail;
+ }
+ List<String> jndiNames = new ArrayList<String>();
+ for (Property p : jndiNamesProp.getList()) {
+ PropertySimple ps = (PropertySimple) p;
+ jndiNames.add(ps.getStringValue());
+ }
+
operation = new Operation(op,address);
+ operation.addAdditionalProperty("entries",jndiNames);
+ if (type.equals("jms-queue")) {
+ PropertySimple ps = (PropertySimple) parameters.get("durable");
+ if (ps!=null) {
+ boolean durable = ps.getBooleanValue();
+ operation.addAdditionalProperty("durable",durable);
+ }
+ String selector = parameters.getSimpleValue("selector","");
+ if (!selector.isEmpty())
+ operation.addAdditionalProperty("selector",selector);
+ }
+
+
} else if (what.equals("managed-server")) {
String chost = parameters.getSimpleValue("hostname","");
String serverName = parameters.getSimpleValue("servername","");
diff --git a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
index 6a8698e..20395e0 100644
--- a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
@@ -444,7 +444,7 @@
<server name="Messaging"
discovery="SubsystemDiscovery"
class="BaseComponent"
- description="The underlying HornetQ based messaging subsystem"
+ description="The HornetQ based messaging subsystem"
singleton="true"
>
<runs-inside>
@@ -459,15 +459,16 @@
<operation name="destination:add" displayName="Add destination" description="Add a Queue or Topic">
<parameters>
<c:simple-property name="name" description="Name of the Destination" required="true"/>
- <c:simple-property name="queue-address" description="The queue address defines what address is used for routing messages." required="true"/>
+ <c:list-property name="entries" description="The JNDI names the destination should be bound to." required="true">
+ <c:simple-property name="entry" description="A single JNDI name. Note, this is relative to java:jboss/jms/"/>
+ </c:list-property>
<c:simple-property name="type" description="Type of Destination to create" default="Queue">
<c:property-options>
- <c:option value="Queue"/>
- <c:option value="Topic"/>
+ <c:option value="jms-queue" name="Queue"/>
+ <c:option value="jms-topic" name="Topic"/>
</c:property-options>
</c:simple-property>
- <c:simple-property name="filter" description="The queue message filter definition."/>
- <c:simple-property name="durable" description="Defines whether the queue is durable." type="boolean" default="false"/>
+ <c:simple-property name="durable" description="Defines whether the queue is durable (for Queues only)." type="boolean" default="false"/>
</parameters>
<results>
<c:simple-property name="operationResult"/>
@@ -487,73 +488,23 @@
<c:simple-property name="journal-type" />
</resource-configuration>
- <!-- this is no child resource TODO
-
- <service name="Acceptor"
- discovery="SubsystemDiscovery"
- class="BaseComponent"
- >
- <plugin-configuration>
- <c:simple-property name="path" readOnly="true" default="acceptor"/>
- </plugin-configuration>
- </service>
- <service name="MessagingConnector"
- discovery="SubsystemDiscovery"
- class="BaseComponent"
- >
- <plugin-configuration>
- <c:simple-property name="path" readOnly="true" default="connector"/>
- </plugin-configuration>
- </service>
- <service name="HQueue"
- discovery="SubsystemDiscovery"
- class="BaseComponent"
- >
- <plugin-configuration>
- <c:simple-property name="path" readOnly="true" default="queue"/>
- </plugin-configuration>
- <resource-configuration>
- <c:simple-property name="queue-address" required="true"/>
- <c:simple-property name="filter" />
- <c:simple-property name="durable" type="boolean"/>
- </resource-configuration>
-
- </service>
--->
- </server>
-
- <server name="JMS"
- discovery="SubsystemDiscovery"
- class="JmsComponent"
- description="The JMS messaging subsystem"
- singleton="true"
- >
- <runs-inside>
- <parent-resource-type name="Profile" plugin="jboss-as-7"/>
- <parent-resource-type name="JBossAS7-Standalone" plugin="jboss-as-7"/>
- </runs-inside>
-
- <plugin-configuration>
- <c:simple-property name="path" readOnly="true" default="subsystem=jms"/>
- </plugin-configuration>
-
- <service name="Queue"
+ <service name="JMS Queue"
discovery="SubsystemDiscovery"
class="JmsComponent"
- createDeletePolicy="both"
+ createDeletePolicy="delete-only"
>
<plugin-configuration>
- <c:simple-property name="path" readOnly="true" default="queue"/>
+ <c:simple-property name="path" readOnly="true" default="jms-queue"/>
</plugin-configuration>
<resource-configuration> <!-- See BZ 705713 TODO -->
- <c:simple-property name="durable" required="false" type="boolean" readOnly="false" default="false"
+ <c:simple-property name="durable" required="false" type="boolean" readOnly="true" default="false"
description="Whether the queue is durable or not."/>
- <c:list-property name="entries" required="false" readOnly="false"
+ <c:list-property name="entries" required="false" readOnly="true"
description="The jndi names the queue will be bound to.">
<c:simple-property name="entries" type="string"/>
</c:list-property>
- <c:simple-property name="selector" required="false" type="string" readOnly="false" description="The queue selector."/>
+ <c:simple-property name="selector" required="false" type="string" readOnly="true" description="The queue selector."/>
<c:template name="add" description="Properties when adding a new queue" >
<c:simple-property name="durable" required="false" type="boolean" default="false"
description="Whether the queue is durable or not."/>
@@ -565,16 +516,16 @@
</c:template>
</resource-configuration>
</service>
- <service name="Topic"
+ <service name="JMS Topic"
discovery="SubsystemDiscovery"
class="JmsComponent"
- createDeletePolicy="both"
+ createDeletePolicy="delete-only"
>
<plugin-configuration>
- <c:simple-property name="path" readOnly="true" default="topic"/>
+ <c:simple-property name="path" readOnly="true" default="jms-topic"/>
</plugin-configuration>
<resource-configuration> <!-- See BZ 705713 TODO -->
- <c:list-property name="entries" required="false" readOnly="false"
+ <c:list-property name="entries" required="false" readOnly="true"
description="The jndi names the queue will be bound to.">
<c:simple-property name="entries" type="string"/>
</c:list-property>
12 years, 10 months
[rhq] Branch 'drift' - modules/enterprise
by John Sanda
dev/null |binary
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/system/SystemManagerBean.java | 4 ++--
2 files changed, 2 insertions(+), 2 deletions(-)
New commits:
commit fb4f3a1cfdf55801cf74293fe05a626af98c33b9
Author: John Sanda <jsanda(a)redhat.com>
Date: Thu Jul 28 09:11:14 2011 -0400
fix typo and remove gwt library that was only for prototyping
diff --git a/modules/enterprise/gui/coregui/lib/morphia-gwt-0.99-SNAPSHOT.jar b/modules/enterprise/gui/coregui/lib/morphia-gwt-0.99-SNAPSHOT.jar
deleted file mode 100644
index e8a10a6..0000000
Binary files a/modules/enterprise/gui/coregui/lib/morphia-gwt-0.99-SNAPSHOT.jar and /dev/null differ
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/system/SystemManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/system/SystemManagerBean.java
index 229183d..a039930 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/system/SystemManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/system/SystemManagerBean.java
@@ -201,7 +201,7 @@ public class SystemManagerBean implements SystemManagerLocal, SystemManagerRemot
}
private Map<String, String> getDriftServerPlugins() {
- DriftServerPluginManager pluginMgr = getDriftSererPluginManager();
+ DriftServerPluginManager pluginMgr = getDriftServerPluginManager();
Map<String, String> plugins = new HashMap<String, String>();
for (ServerPluginEnvironment env : pluginMgr.getPluginEnvironments()) {
@@ -211,7 +211,7 @@ public class SystemManagerBean implements SystemManagerLocal, SystemManagerRemot
return plugins;
}
- private DriftServerPluginManager getDriftSererPluginManager() {
+ private DriftServerPluginManager getDriftServerPluginManager() {
MasterServerPluginContainer masterPC = LookupUtil.getServerPluginService().getMasterPluginContainer();
if (masterPC == null) {
log.warn(MasterServerPluginContainer.class.getSimpleName() + " is not started yet");
12 years, 10 months