modules/core/client-api-test-utils/pom.xml
| 44
modules/core/client-api-test-utils/src/main/java/org/rhq/enterprise/server/configuration/metadata/PluginDescriptorUtil.java
| 144 ++
modules/core/client-api/pom.xml
| 7
modules/core/client-api/src/test/groovy/org/rhq/core/clientapi/agent/metadata/PluginMetadataParserTest.groovy
| 30
modules/enterprise/server/jar/pom.xml
| 39
modules/enterprise/server/jar/src/test/groovy/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBeanTest.groovy
| 512 ++++++++++
pom.xml
| 2
7 files changed, 761 insertions(+), 17 deletions(-)
New commits:
commit 7b5ab536af92182ad9b9a3bf17d767bd57454a0b
Author: John Sanda <jsanda(a)redhat.com>
Date: Wed Oct 27 15:44:28 2010 -0400
Updating tests in ResourceMetadataManagerBeanTest
Moving PluginDescriptorUtil into a separate test module making it easier
to re-use across modules.
diff --git a/modules/core/client-api-test-utils/pom.xml
b/modules/core/client-api-test-utils/pom.xml
new file mode 100644
index 0000000..a7ba0a3
--- /dev/null
+++ b/modules/core/client-api-test-utils/pom.xml
@@ -0,0 +1,44 @@
+<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-parent</artifactId>
+ <version>4.0.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-client-api-test-utils</artifactId>
+
+ <name>RHQ Client API Test Utils</name>
+ <description>Provides a test utility library for client API
classes</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>${rhq.groupId}</groupId>
+ <artifactId>rhq-core-domain</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${rhq.groupId}</groupId>
+ <artifactId>rhq-core-client-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-jxpath</groupId>
+ <artifactId>commons-jxpath</artifactId>
+ <version>1.3</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.persistence</groupId>
+ <artifactId>persistence-api</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>jboss.jboss-embeddable-ejb3</groupId>
+ <artifactId>hibernate-all</artifactId>
+ <version>1.0.0.Alpha9</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git
a/modules/core/client-api-test-utils/src/main/java/org/rhq/enterprise/server/configuration/metadata/PluginDescriptorUtil.java
b/modules/core/client-api-test-utils/src/main/java/org/rhq/enterprise/server/configuration/metadata/PluginDescriptorUtil.java
new file mode 100644
index 0000000..b67d904
--- /dev/null
+++
b/modules/core/client-api-test-utils/src/main/java/org/rhq/enterprise/server/configuration/metadata/PluginDescriptorUtil.java
@@ -0,0 +1,144 @@
+package org.rhq.enterprise.server.configuration.metadata;
+
+import java.io.FileNotFoundException;
+import java.io.StringReader;
+import java.net.URL;
+
+import javax.xml.XMLConstants;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.util.ValidationEventCollector;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+
+import org.apache.commons.jxpath.JXPathContext;
+
+import org.rhq.core.clientapi.agent.metadata.ConfigurationMetadataParser;
+import org.rhq.core.clientapi.agent.metadata.PluginMetadataParser;
+import org.rhq.core.clientapi.descriptor.DescriptorPackages;
+import org.rhq.core.clientapi.descriptor.plugin.PluginDescriptor;
+import org.rhq.core.clientapi.descriptor.plugin.ResourceDescriptor;
+import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
+
+public class PluginDescriptorUtil {
+
+ /**
+ * Loads the plugin descriptor from the specified file. The file path specified
should
+ * be a class path relative path. For example, if the descriptor file is located at
+ * org.rhq.enterprise.server.configuration.my-descriptor.xml, then you should
specify
+ * /org/rhq/enterprise/server/configuration/my-descriptor.xml.
+ *
+ * @param file The class path relative path of the descriptor file
+ * @return The {@link PluginDescriptor}
+ */
+ public static PluginDescriptor loadPluginDescriptor(String file) {
+ try {
+ URL pluginDescriptorURL = PluginDescriptorUtil.class.getResource(file);
+ if (pluginDescriptorURL == null) {
+ throw new FileNotFoundException("File " + file + " not
found");
+ }
+
+ JAXBContext jaxbContext =
JAXBContext.newInstance(DescriptorPackages.PC_PLUGIN);
+ URL pluginSchemaURL =
PluginDescriptorUtil.class.getClassLoader().getResource("rhq-plugin.xsd");
+ Schema pluginSchema =
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(
+ pluginSchemaURL);
+ Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+ ValidationEventCollector vec = new ValidationEventCollector();
+ unmarshaller.setEventHandler(vec);
+ unmarshaller.setSchema(pluginSchema);
+
+ return (PluginDescriptor)
unmarshaller.unmarshal(pluginDescriptorURL.openStream());
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Transforms the given string into a plugin descriptor object.
+ *
+ * @param string The plugin descriptor specified as a string
+ * @return The {@link PluginDescriptor}
+ */
+ public static PluginDescriptor toPluginDescriptor(String string) {
+ try {
+ JAXBContext jaxbContext =
JAXBContext.newInstance(DescriptorPackages.PC_PLUGIN);
+ URL pluginSchemaURL =
PluginMetadataParser.class.getClassLoader().getResource("rhq-plugin.xsd");
+ Schema pluginSchema =
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(pluginSchemaURL);
+
+ Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+ ValidationEventCollector vec = new ValidationEventCollector();
+ unmarshaller.setEventHandler(vec);
+ unmarshaller.setSchema(pluginSchema);
+
+ StringReader reader = new StringReader(string);
+
+ return (PluginDescriptor) unmarshaller.unmarshal(reader);
+ }
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Searches for and returns the matching descriptor element (or elements) from the
plugin
+ * descriptor. <code>path</code> should be an XPath-like expression. See
+ *
http://commons.apache.org/jxpath/users-guide.html for more information on
supported syntax.
+ *
+ * @param descriptor The plugin descriptor
+ * @param path The XPath-ish search expression
+ * @return The matching element or elements from the descriptor
+ */
+ public static Object find(PluginDescriptor descriptor, String path) {
+ JXPathContext context = JXPathContext.newContext(descriptor);
+ return context.getValue(path);
+ }
+
+ /**
+ * This method does a few things. It first searches the descriptor with the
specified
+ * <code>path</code>. When a matching element is found, which is
presumably either a
+ * {@link org.rhq.core.clientapi.descriptor.plugin.ServerDescriptor} or a
+ * {@link org.rhq.core.clientapi.descriptor.plugin.ServerDescriptor}, its plugin
+ * configuration is retrieved. It then gets parsed and the resulting
+ * {@link ConfigurationDefinition} is returned.
+ *
+ * @param descriptor The plugin descriptor
+ * @param path The XPath-ish expression that specifies the path to the element from
which
+ * the plugin configuration should be loaded
+ * @param configName A name to give the configuration definition
+ * @return The parsed {@link ConfigurationDefinition}
+ */
+ public static ConfigurationDefinition loadPluginConfigDefFor(PluginDescriptor
descriptor, String path,
+ String configName) {
+ try {
+ ResourceDescriptor resourceDescriptor = (ResourceDescriptor) find(descriptor,
path);
+ return ConfigurationMetadataParser.parse(configName,
resourceDescriptor.getPluginConfiguration());
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * This method does a few things. It first searches the descriptor with the
specified
+ * <code>path</code>. When a matching element is found, which is
presumably either a
+ * {@link org.rhq.core.clientapi.descriptor.plugin.ServerDescriptor} or a
+ * {@link org.rhq.core.clientapi.descriptor.plugin.ServerDescriptor}, its resource
+ * configuration is retrieved. It then gets parsed and the resulting
+ * {@link ConfigurationDefinition} is returned.
+ *
+ * @param descriptor The plugin descriptor
+ * @param path The XPath-ish expression that specifies the path to the element from
which
+ * the resource configuration should be loaded
+ * @param configName A name to give the configuration definition
+ * @return The parsed {@link ConfigurationDefinition}
+ */
+ public static ConfigurationDefinition loadResourceConfigDefFor(PluginDescriptor
descriptor, String path,
+ String configName) {
+ try {
+ ResourceDescriptor resourceDescriptor = (ResourceDescriptor) find(descriptor,
path);
+ return ConfigurationMetadataParser.parse(configName,
resourceDescriptor.getResourceConfiguration());
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git a/modules/core/client-api/pom.xml b/modules/core/client-api/pom.xml
index 4617b45..80dda55 100644
--- a/modules/core/client-api/pom.xml
+++ b/modules/core/client-api/pom.xml
@@ -63,6 +63,13 @@
</dependency>
<dependency>
+ <groupId>${groupId}</groupId>
+ <artifactId>rhq-core-client-api-test-utils</artifactId>
+ <version>${version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<scope>test</scope>
diff --git
a/modules/core/client-api/src/test/groovy/org/rhq/core/clientapi/agent/metadata/PluginMetadataParserTest.groovy
b/modules/core/client-api/src/test/groovy/org/rhq/core/clientapi/agent/metadata/PluginMetadataParserTest.groovy
index e5bf3c5..2b28537 100644
---
a/modules/core/client-api/src/test/groovy/org/rhq/core/clientapi/agent/metadata/PluginMetadataParserTest.groovy
+++
b/modules/core/client-api/src/test/groovy/org/rhq/core/clientapi/agent/metadata/PluginMetadataParserTest.groovy
@@ -31,6 +31,8 @@ import org.rhq.core.clientapi.descriptor.plugin.PluginDescriptor
import org.testng.annotations.Test
import org.rhq.core.domain.configuration.definition.ConfigurationFormat
+import static
org.rhq.enterprise.server.configuration.metadata.PluginDescriptorUtil.toPluginDescriptor
+
class PluginMetadataParserTest {
@@ -374,19 +376,19 @@ class PluginMetadataParserTest {
}
- static PluginDescriptor toPluginDescriptor(String string) {
- JAXBContext jaxbContext = JAXBContext.newInstance(DescriptorPackages.PC_PLUGIN)
- URL pluginSchemaURL =
PluginMetadataParser.class.getClassLoader().getResource("rhq-plugin.xsd")
- Schema pluginSchema =
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(pluginSchemaURL)
-
- Unmarshaller unmarshaller = jaxbContext.createUnmarshaller()
- ValidationEventCollector vec = new ValidationEventCollector()
- unmarshaller.setEventHandler(vec)
- unmarshaller.setSchema(pluginSchema)
-
- StringReader reader = new StringReader(string)
-
- return (PluginDescriptor) unmarshaller.unmarshal(reader);
- }
+// static PluginDescriptor toPluginDescriptor(String string) {
+// JAXBContext jaxbContext = JAXBContext.newInstance(DescriptorPackages.PC_PLUGIN)
+// URL pluginSchemaURL =
PluginMetadataParser.class.getClassLoader().getResource("rhq-plugin.xsd")
+// Schema pluginSchema =
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(pluginSchemaURL)
+//
+// Unmarshaller unmarshaller = jaxbContext.createUnmarshaller()
+// ValidationEventCollector vec = new ValidationEventCollector()
+// unmarshaller.setEventHandler(vec)
+// unmarshaller.setSchema(pluginSchema)
+//
+// StringReader reader = new StringReader(string)
+//
+// return (PluginDescriptor) unmarshaller.unmarshal(reader);
+// }
}
diff --git a/modules/enterprise/server/jar/pom.xml
b/modules/enterprise/server/jar/pom.xml
index 060a8f6..123d42e 100644
--- a/modules/enterprise/server/jar/pom.xml
+++ b/modules/enterprise/server/jar/pom.xml
@@ -352,6 +352,13 @@
<!--================ Test Deps ================-->
<dependency>
+ <groupId>${groupId}</groupId>
+ <artifactId>rhq-core-client-api-test-utils</artifactId>
+ <version>${version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
<groupId>jboss.jboss-embeddable-ejb3</groupId>
<artifactId>jboss-ejb3-all</artifactId>
<version>${jboss-embeddable-ejb3.version}</version>
@@ -407,16 +414,25 @@
<artifactId>opencsv</artifactId>
<version>1.8</version>
<scope>test</scope>
- </dependency>
+ </dependency>
<dependency>
<groupId>org.rhq.helpers</groupId>
<artifactId>perftest-support</artifactId>
<version>${project.version}</version>
<scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>ant</groupId>
+ <artifactId>ant</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>ant</groupId>
+ <artifactId>ant-launcher</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
-
<dependency>
<groupId>commons-jxpath</groupId>
<artifactId>commons-jxpath</artifactId>
@@ -424,6 +440,12 @@
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.codehaus.groovy</groupId>
+ <artifactId>groovy-all</artifactId>
+ <scope>test</scope>
+ </dependency>
+
</dependencies>
<build>
@@ -554,6 +576,19 @@ Build-OS-Version=${os.version}
</executions>
</plugin>
+ <plugin>
+ <groupId>org.codehaus.groovy.maven</groupId>
+ <artifactId>gmaven-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>testCompile</goal>
+ </goals>
+ </execution>
+ </executions>
+
+ </plugin>
+
</plugins>
</build>
diff --git
a/modules/enterprise/server/jar/src/test/groovy/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBeanTest.groovy
b/modules/enterprise/server/jar/src/test/groovy/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBeanTest.groovy
new file mode 100644
index 0000000..f7ea824
--- /dev/null
+++
b/modules/enterprise/server/jar/src/test/groovy/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBeanTest.groovy
@@ -0,0 +1,512 @@
+package org.rhq.enterprise.server.resource.metadata
+
+import org.testng.annotations.Test
+import org.testng.Assert
+
+import static
org.rhq.enterprise.server.configuration.metadata.PluginDescriptorUtil.toPluginDescriptor
+import org.rhq.core.domain.plugin.Plugin
+import org.rhq.core.clientapi.descriptor.plugin.PluginDescriptor
+import org.apache.maven.artifact.versioning.ComparableVersion
+import org.rhq.core.util.MessageDigestGenerator
+import org.rhq.enterprise.server.test.AbstractEJB3Test
+import org.rhq.enterprise.server.util.LookupUtil
+import org.rhq.core.domain.resource.ResourceType
+import org.rhq.test.AssertUtils
+import org.rhq.core.domain.criteria.ResourceTypeCriteria
+import org.rhq.core.domain.criteria.OperationDefinitionCriteria
+
+class ResourceMetadataManagerBeanTest extends AbstractEJB3Test {
+
+ @Test(groups = ['NewPlugin'])
+ void registerPlugin() {
+ def pluginDescriptor =
+ """
+ <plugin name="TestPlugin" displayName="Test Plugin"
package="org.rhq.plugins.test"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+ <server name="ServerA"
+ description="Server A description"
+ class="org.rhq.plugins.test.ServerA"
+ discovery="org.rhq.plugins.test.ServerADiscoveryComponent">
+
+ <subcategories>
+ <subcategory name="Resources" description="Resources
subcategory"/>
+ <subcategory name="Applications" description="Applications
subcategory"/>
+ </subcategories>
+
+ <plugin-configuration>
+ <c:simple-property name="connectionPropertyX"
default="x"/>
+ <c:simple-property name="connectionPropertyY"
default="y"/>
+ </plugin-configuration>
+
+ <process-scan name="serverA"
query="process|basename|match=^java.*,arg|org.jboss.Main|match=.*"/>
+
+ <operation name="start">
+ <parameters>
+ <c:simple-property name="immediate"
type="boolean"/>
+ </parameters>
+ <results>
+ <c:simple-property name="exitCode"
type="integer"/>
+ </results>
+ </operation>
+
+ <operation name="stop">
+ <parameters>
+ <c:simple-property name="immediate"
type="boolean"/>
+ </parameters>
+ <results>
+ <c:simple-property name="exitCode"
type="integer"/>
+ </results>
+ </operation>
+
+ <metric displayName="Metric 1" property="metric1"
displayType="summary" defaultInterval="300000"/>
+ <metric displayName="Metric 2" property="metric2"
displayType="summary" defaultInterval="300000"/>
+
+ <event name="logAEntry" description="an entry was appended to a
log file"/>
+ <event name="logBEntry" description="an entry was appended to a
log file"/>
+
+ <service name="Child1"
+ description="Child 1 description"
+ class="org.rhq.plugins.test.Child1"
+
discovery="org.rhq.plugins.test.Child1ServiceDiscoveryComponent"/>
+ <service name="Child2"
+ description="Child 2 description"
+ class="org.rhq.plugins.test.Child2"
+
discovery="org.rhq.plugins.test.Child2ServiceDiscoveryComponent"/>
+ </server>
+
+ <server name="ServerB"
+ description="Server B description"
+ class="org.rhq.plugins.test.ServerB"
+ discovery="org.rhq.plugins.test.ServerBDiscoveryComponent"/>
+
+ <server name="ServerC"
+ description="Server C description"
+ class="org.rhq.plugins.test.ServerC"
+ discovery="org.rhq.plugins.test.ServerCDiscoveryComponent">
+
+ <operation name="run">
+ <parameters>
+ <c:simple-property name="script"/>
+ </parameters>
+ <results>
+ <c:simple-property name="errors"/>
+ </results>
+ </operation>
+
+ <event name="serverCEvent" description="an entry was appended
to a log file"/>
+ </server>
+ </plugin>
+ """
+
+ def args = createPlugin("test-plugin", pluginDescriptor, "1.0")
+ Assert.assertNotNull args.plugin
+ Assert.assertNotNull args.pluginFile
+ Assert.assertNotNull args.pluginDescriptor
+
+ def subjectMgr = LookupUtil.subjectManager
+ def resourceMetadataMgr = LookupUtil.resourceMetadataManager
+
+ resourceMetadataMgr.registerPlugin(subjectMgr.overlord, args.plugin,
args.pluginDescriptor, args.pluginFile, false)
+ }
+
+ @Test(dependsOnMethods = ['registerPlugin'], groups = ['NewPlugin'])
+ void persistNewTypes() {
+ def newTypes = ['ServerA', 'ServerB']
+ assertTypesPersisted "Failed to persist new types", newTypes,
'TestPlugin'
+ }
+
+ @Test(dependsOnMethods = ['persistNewTypes'], groups = ['NewPlugin'])
+ void persistSubcategories() {
+ assertAssociationEquals(
+ 'ServerA',
+ 'subCategories',
+ ['Resources', 'Applications']
+ )
+ }
+
+ @Test(dependsOnMethods = ['persistNewTypes'], groups = ['NewPlugin'])
+ void persistMeasurementDefinitions() {
+ assertAssociationEquals(
+ 'ServerA',
+ 'metricDefinitions',
+ ['metric1', 'metric2']
+ )
+ }
+
+ @Test(dependsOnMethods = ['persistNewTypes'], groups = ['NewPlugin'])
+ void persistEventDefinitions() {
+ assertAssociationEquals(
+ 'ServerA',
+ 'eventDefinitions',
+ ['logAEntry', 'logBEntry']
+ )
+ }
+
+ @Test(dependsOnMethods = ['persistNewTypes'], groups = ['NewPlugin'])
+ void persistOperationDefinitions() {
+ assertAssociationEquals(
+ 'ServerA',
+ 'operationDefinitions',
+ ['start', 'stop']
+ )
+ }
+
+ @Test(dependsOnMethods = ['persistNewTypes'], groups = ['NewPlugin'])
+ void persistProcessScans() {
+ assertAssociationEquals(
+ 'ServerA',
+ 'processScans',
+ ['serverA']
+ )
+ }
+
+ @Test(dependsOnMethods = ['persistNewTypes'], groups = ['NewPlugin'])
+ void persistChildTypes() {
+ assertAssociationEquals(
+ 'ServerA',
+ 'childResourceTypes',
+ ['Child1', 'Child2']
+ )
+
+ @Test(dependsOnMethods = ['persistNewTypes'], groups =
['NewPlugin'])
+ void persistPluginConfigurationDefinition
+ assertAssociationExists('ServerA', 'pluginConfigurationDefinition')
+ }
+
+ @Test(groups = ['UpgradePlugin'], dependsOnGroups = ['NewPlugin'])
+ void upgradePlugin() {
+ def pluginDescriptor =
+ """
+ <plugin name="TestPlugin" displayName="Test Plugin"
package="org.rhq.plugins.test"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+ <server name="ServerA"
+ description="Server A description"
+ class="org.rhq.plugins.test.ServerA"
+ discovery="org.rhq.plugins.test.ServerADiscoveryComponent">
+
+ <subcategories>
+ <subcategory name="Resources" description="Resources
subcategory"/>
+ <subcategory name="Applications" description="Applications
subcategory"/>
+ </subcategories>
+
+ <plugin-configuration>
+ <c:simple-property name="connectionPropertyX"
default="x"/>
+ <c:simple-property name="connectionPropertyY"
default="y"/>
+ </plugin-configuration>
+
+ <process-scan name="processA"
query="process|basename|match=^java.*,arg|org.jboss.MainA|match=.*"/>
+ <process-scan name="processB"
query="process|basename|match=^java.*,arg|org.jboss.MainB|match=.*"/>
+
+ <operation name="start">
+ <parameters>
+ <c:simple-property name="immediate"
type="boolean"/>
+ </parameters>
+ <results>
+ <c:simple-property name="exitCode"
type="integer"/>
+ </results>
+ </operation>
+
+ <operation name="shutdown">
+ <parameters>
+ <c:simple-property name="immediate"
type="boolean"/>
+ </parameters>
+ <results>
+ <c:simple-property name="exitCode"
type="integer"/>
+ </results>
+ </operation>
+
+ <operation name="restart">
+ <parameters>
+ <c:simple-property name="immediate"
type="boolean"/>
+ </parameters>
+ <results>
+ <c:simple-property name="exitCode"
type="integer"/>
+ </results>
+ </operation>
+
+ <metric displayName="Metric 1" property="metric1"
displayType="summary" defaultInterval="300000"/>
+ <metric displayName="Metric 2" property="metric2"
displayType="summary" defaultInterval="300000"/>
+
+ <event name="logAEntry" description="an entry was appended to a
log file"/>
+ <event name="logCEntry" description="an entry was appended to a
log file"/>
+
+ <service name="Child1"
+ description="Child 1 description"
+ class="org.rhq.plugins.test.Child1"
+
discovery="org.rhq.plugins.test.Child1ServiceDiscoveryComponent"/>
+
+ <service name="Child3"
+ description="Child 3 description"
+ class="org.rhq.plugins.test.Child3"
+
discovery="org.rhq.plugins.test.Child3ServiceDiscoveryComponent"/>
+ </server>
+ <server name="ServerB"
+ description="Server B description"
+ class="org.rhq.plugins.test.ServerB"
+ discovery="org.rhq.plugins.test.ServerBDiscoveryComponent">
+ <service name="Child2"
+ description="Child 2 description"
+ class="org.rhq.plugins.test.Child2"
+
discovery="org.rhq.plugins.test.Child2ServiceDiscoveryComponent"/>
+ </server>
+ </plugin>
+ """
+
+ def args = createPlugin("test-plugin", pluginDescriptor, "2.0")
+ Assert.assertNotNull args.plugin
+ Assert.assertNotNull args.pluginFile
+ Assert.assertNotNull args.pluginDescriptor
+
+ def subjectMgr = LookupUtil.subjectManager
+ def resourceMetadataMgr = LookupUtil.resourceMetadataManager
+
+ resourceMetadataMgr.registerPlugin(subjectMgr.overlord, args.plugin,
args.pluginDescriptor, args.pluginFile, true)
+ }
+
+ @Test(dependsOnMethods = ['upgradePlugin'], groups =
['UpgradePlugin'])
+ void upgradeOperationDefinitions() {
+ assertAssociationEquals(
+ 'ServerA',
+ 'operationDefinitions',
+ ['start', 'shutdown', 'restart']
+ )
+ }
+
+ @Test(dependsOnMethods = ['upgradePlugin'], groups =
['UpgradePlugin'])
+ void upgradeChildResources() {
+ assertAssociationEquals(
+ 'ServerA',
+ 'childResourceTypes',
+ ['Child1', 'Child3']
+ )
+ }
+
+ @Test(dependsOnMethods = ['upgradePlugin'], groups =
['UpgradePlugin'])
+ void upgradeParentType() {
+ assertAssociationEquals(
+ 'ServerB',
+ 'childResourceTypes',
+ ['Child2']
+ )
+ }
+
+ @Test(dependsOnMethods = ['upgradePlugin'], groups =
['UpgradePlugin'])
+ void upgradeEventDefinitions() {
+ assertAssociationEquals(
+ 'ServerA',
+ 'eventDefinitions',
+ ['logAEntry', 'logCEntry']
+ )
+ }
+
+ @Test(dependsOnMethods = ['upgradePlugin'], groups =
['UpgradePlugin'])
+ void upgradeProcessScans() {
+ assertAssociationEquals(
+ 'ServerA',
+ 'processScans',
+ ['processA', 'processB']
+ )
+ }
+
+ @Test(dependsOnMethods = ['upgradePlugin'], groups =
['UpgradePlugin'])
+ void deleteOperationDefsForRemovedType() {
+ def operationMgr = LookupUtil.operationManager
+ def subjectMgr = LookupUtil.subjectManager
+
+ def criteria = new OperationDefinitionCriteria()
+ criteria.addFilterResourceTypeName 'ServerC'
+ criteria.addFilterName 'run'
+
+ def operationDefs =
operationMgr.findOperationDefinitionsByCriteria(subjectMgr.overlord, criteria)
+
+ assertEquals "The operation definition should have been deleted", 0,
operationDefs.size()
+ }
+
+ @Test(dependsOnMethods = ['upgradePlugin'], groups =
['UpgradePlugin'])
+ void deleteEventDefsForRemovedType() {
+ def results = entityManager.createQuery(
+ "from EventDefinition e where e.name = :ename and e.resourceType.name =
:rname")
+ .setParameter("ename", "serverCEvent")
+ .setParameter("rname", "ServerC")
+ .getResultList()
+
+ assertEquals "The event definition(s) should have been deleted", 0,
results.size()
+ }
+
+ def buildPlugin(String pluginFileName, String version, String descriptor) {
+ def args = createPlugin("test-plugin", pluginDescriptor, "2.0")
+ Assert.assertNotNull args.plugin
+ Assert.assertNotNull args.pluginFile
+ Assert.assertNotNull args.pluginDescriptor
+
+ def subjectMgr = LookupUtil.subjectManager
+ def resourceMetadataMgr = LookupUtil.resourceMetadataManager
+
+ resourceMetadataMgr.registerPlugin(subjectMgr.overlord, args.plugin,
args.pluginDescriptor, args.pluginFile, true)
+ }
+
+ /**
+ * This method creates the plugin-related artifacts that are need to call
+ * ResourceMetadataManager.registerPlugin. It creates the PluginDescriptor object, and
+ * then it generates the plugin jar file. Lastly, the Plugin object is created. A map
+ * is returned containing these generated artifacts. The map keys are
pluginDescriptor,
+ * pluginFile, and plugin.
+ *
+ * @param pluginFileName The name to give the generated plugin file. This should not
+ * include the file extension, i.e., the '.jar'
+ *
+ * @param descriptor The plugin descriptor as a string
+ *
+ * @param version The plugin version which will be the version stored in MANIFEST.MF
+ *
+ * @return A map containing the generated artifacts. The maps keys are
pluginDescriptor,
+ * pluginFile, and plugin
+ */
+ def createPlugin(String pluginFileName, String descriptor, String version) {
+ def pluginDescriptor = toPluginDescriptor(descriptor)
+ def pluginFilePath = "$currentWorkingDir/${pluginFileName}.jar"
+
+ def ant = new AntBuilder()
+ ant.delete(dir: "$pluginWorkDir")
+ ant.delete(file: pluginFilePath)
+
+ ant.mkdir(dir: "$pluginWorkDir/META-INF")
+ new File("$pluginWorkDir/META-INF/rhq-plugin.xml").text = descriptor
+ ant.jar(destfile: "$currentWorkingDir/${pluginFileName}.jar", basedir:
"$pluginWorkDir") {
+ manifest {
+ attribute(name: "Specification-Version", value: version)
+ attribute(name: "Implementation-Version", value: version)
+ }
+ }
+
+ def pluginFile = new File(pluginFilePath)
+
+ def plugin = new Plugin(pluginDescriptor.name, pluginFilePath)
+ plugin.displayName = pluginDescriptor.name
+ plugin.enabled = true
+ plugin.description = pluginDescriptor.description
+ plugin.ampsVersion = getAmpsVersion(pluginDescriptor)
+ plugin.version = pluginDescriptor.version
+ plugin.MD5 = MessageDigestGenerator.getDigestString(pluginFile)
+
+ return [pluginDescriptor: pluginDescriptor, pluginFile: pluginFile, plugin: plugin]
+ }
+
+ String getPluginWorkDir() {
+ "${currentWorkingDir}/work"
+ }
+
+ String getCurrentWorkingDir() {
+ getClass().getResource(".").toURI().path
+ }
+
+ String getAmpsVersion(PluginDescriptor pluginDescriptor) {
+ if (pluginDescriptor.ampsVersion == null) {
+ return "2.0"
+ }
+
+ ComparableVersion version = new ComparableVersion(pluginDescriptor.ampsVersion)
+ ComparableVersion version2 = new ComparableVersion("2.0")
+
+ if (version.compareTo(version2) <= 0) {
+ return "2.0"
+ }
+
+ return pluginDescriptor.ampsVersion
+ }
+
+ void assertTypesPersisted(msg, types, plugin) {
+ def typesNotFound = []
+ def resourceTypeMgr = LookupUtil.resourceTypeManager
+
+ types.each {
+ if (resourceTypeMgr.getResourceTypeByNameAndPlugin(it, plugin) == null) {
+ typesNotFound << it
+ }
+ }
+
+ if (typesNotFound.size() > 0) {
+ fail "$msg: The following types were not found: $typesNotFound"
+ }
+ }
+
+ /**
+ * This custom assertion looks up the specified resource type and then looks at the
value
+ * of the specified property name which is assumed to be a collection. It is also
assumed
+ * that each element in the collection has a name property, and it is the value of the
name
+ * property that is compared against the expected values.
+ *
+ * This method fails if either any of the expected names is not found or if one of the
+ * actual names does not exist in the expected list.
+ *
+ * @param resourceTypeName The resource type to look up
+ * @param propertyName The name of the property to be inspected
+ * @param expected A list of names expected to be found in each of the elements of the
property
+ */
+ void assertAssociationEquals(String resourceTypeName, String propertyName, List
expected) {
+ def subjectMgr = LookupUtil.subjectManager
+ def resourceTypeMgr = LookupUtil.resourceTypeManager
+
+ def fetch = "fetch${propertyName.capitalize()}"
+ def criteria = new ResourceTypeCriteria()
+ criteria.addFilterName resourceTypeName
+ criteria.addFilterPluginName 'TestPlugin'
+ criteria."$fetch" true
+
+ def resourceTypes = resourceTypeMgr.findResourceTypesByCriteria(subjectMgr.overlord,
criteria)
+ def resourceType = resourceTypes[0]
+ def expectedSet = expected as Set
+ def missing = []
+ def unexpected = []
+
+ expectedSet.each { expectedProperty ->
+ if (resourceType[propertyName].find { it.name == expectedProperty } == null) {
+ missing << it
+ }
+ }
+
+ resourceType[propertyName].each { actualProperty ->
+ if (expectedSet.find { it == actualProperty.name } == null) {
+ unexpected << actualProperty.name
+ }
+ }
+
+ def errors = ""
+ if (missing.size() > 0) {
+ errors = "Failed to find the following $propertyName(s) for type
'$resourceTypeName': $missing"
+ }
+ if (unexpected.size() > 0) {
+ errors += "\n The following $propertyName(s) were found but not expected for
type '$resourceTypeName': $unexpected"
+ }
+
+ assertTrue(errors, errors.length() == 0)
+ }
+
+ void assertAssociationExists(String resourceTypeName, String propertyName) {
+ def subjectMgr = LookupUtil.subjectManager
+ def resourceTypeMgr = LookupUtil.resourceTypeManager
+
+ def fetch = "fetch${propertyName.capitalize()}"
+ def criteria = new ResourceTypeCriteria()
+ criteria.addFilterName resourceTypeName
+ criteria.addFilterPluginName 'TestPlugin'
+ criteria."$fetch" true
+
+ def resourceTypes = resourceTypeMgr.findResourceTypesByCriteria(subjectMgr.overlord,
criteria)
+ def resourceType = resourceTypes[0]
+
+ assertNotNull("Failed to find $propertyName for type
'$resourceTypeName'", resourceType[propertyName])
+ }
+
+ void assertResourceTypeEquals(String msg, ResourceType expected, ResourceType actual)
{
+ AssertUtils.assertPropertiesMatch(msg, expected, actual,
"childResourceTypes", "parentResourceTypes",
+ "pluginConfigurationDefinition",
"resourceConfigurationDefinition", "subCategory",
"metricDefinitions",
+ "eventDefinitions", "operationDefinitions",
"processScans", "packageTypes", "resources",
"resourceGroups",
+ "productVersions", "bundleType",
"childSubCategories", "helpText", "classLoaderType")
+ }
+
+}
diff --git a/pom.xml b/pom.xml
index f95c754..cd3f6ab 100644
--- a/pom.xml
+++ b/pom.xml
@@ -406,7 +406,7 @@
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
- <version>1.6.0</version>
+ <version>1.7.5</version>
</dependency>
<dependency>