modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
| 3
modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/StaleTypeException.java
| 25
modules/core/domain-test-utils/pom.xml
| 36
modules/core/domain-test-utils/src/main/java/org/rhq/core/domain/resource/BuilderException.java
| 49 +
modules/core/domain-test-utils/src/main/java/org/rhq/core/domain/resource/ResourceBuilder.java
| 413 ++++++++++
modules/core/domain-test-utils/src/main/java/org/rhq/core/domain/resource/ResourceTypeBuilder.java
| 139 +++
modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java
| 5
modules/core/plugin-container/src/main/java/org/rhq/core/pc/RebootRequestListener.java
| 11
modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
| 14
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
| 2
modules/core/pom.xml
| 1
modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
| 9
modules/enterprise/remoting/cli/pom.xml
| 8
modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/BuilderException.java
| 49 -
modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/ResourceBuilder.java
| 374 ---------
modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/ResourceTypeBuilder.java
| 140 ---
modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/TabularWriterTest.java
| 14
modules/enterprise/server/jar/pom.xml
| 8
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DeletedResourceTypeFilter.java
| 64 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
| 11
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
| 4
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
| 4
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/InventoryReportFilter.java
| 9
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/test/DiscoveryTestBean.java
| 7
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/discovery/DeletedResourceTypeFilterTest.java
| 110 ++
25 files changed, 932 insertions(+), 577 deletions(-)
New commits:
commit 22e236aa3085f9dd1a52a574fa6d06c7d325380d
Author: John Sanda <jsanda(a)redhat.com>
Date: Wed Oct 27 08:53:51 2010 -0400
Reject incoming reports (on the server) that contain stale resource types
This commit contains two changes needed for BZ 549852. First, filtering
logic has been added in DiscoveryBossBean.mergeInventoryReport to reject
inventory reports that include any resource types that have been marked
for deletion. A report is rejected by throwing a StaleTypeException.
The second change is handling the StaleTypeException in the agent and in
the plugin container. A new listener interface, RebootRequestListener,
has been added to the PC. When InventoryManager catches a
StaleTypeException, it notifies the listener that a reboot is needed.
This listener is the agent. The agent shuts down the PC, clears out the
data directory, and then restarts the PC.
diff --git
a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
index 0622fc5..98e7d5c 100644
---
a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
+++
b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
@@ -63,7 +63,8 @@ public interface DiscoveryServerService {
*/
@LimitedConcurrency(CONCURRENCY_LIMIT_INVENTORY_REPORT)
@Timeout(1000L * 60 * 30)
- ResourceSyncInfo mergeInventoryReport(InventoryReport inventoryReport) throws
InvalidInventoryReportException;
+ ResourceSyncInfo mergeInventoryReport(InventoryReport inventoryReport)
+ throws InvalidInventoryReportException, StaleTypeException;
/**
* Merges a new availability report from the agent into the server. This updates the
availability statuses of known
diff --git
a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/StaleTypeException.java
b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/StaleTypeException.java
index 699717f..07c9486 100644
---
a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/StaleTypeException.java
+++
b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/StaleTypeException.java
@@ -4,7 +4,9 @@ package org.rhq.core.clientapi.server.discovery;
* Exception to indicate that a report contains one or more resource types that have been
marked for
* deletion.
*/
-public class StaleTypeException extends InvalidInventoryReportException {
+public class StaleTypeException extends Exception {
+ private static final long serialVersionUID = 1L;
+
public StaleTypeException() {
super();
}
diff --git
a/modules/core/domain-test-utils/src/main/java/org/rhq/core/domain/resource/ResourceBuilder.java
b/modules/core/domain-test-utils/src/main/java/org/rhq/core/domain/resource/ResourceBuilder.java
index 425fe3e..c065d1f 100644
---
a/modules/core/domain-test-utils/src/main/java/org/rhq/core/domain/resource/ResourceBuilder.java
+++
b/modules/core/domain-test-utils/src/main/java/org/rhq/core/domain/resource/ResourceBuilder.java
@@ -36,9 +36,7 @@ import java.util.Random;
* in a valid state, specifically, fields that are not nullable are required to have
non-null values. Using a builder
* should help make the intent of tests clearer and more self-documenting.
* <br/><br/>
- * A couple things need to be pointed out. First, this class currently does not yet
provide support for all Resource
- * fields/properties. Secondly, this class will likely be moved to a test utility module
in a subsequent commit so that
- * it can be reused by other tests in other modules.
+ * Note that this class currently does not yet provide support for all Resource
fields/properties.
*
* @author John Sanda
*/
diff --git
a/modules/core/domain-test-utils/src/main/java/org/rhq/core/domain/resource/ResourceTypeBuilder.java
b/modules/core/domain-test-utils/src/main/java/org/rhq/core/domain/resource/ResourceTypeBuilder.java
index f7d2736..2e83fd3 100644
---
a/modules/core/domain-test-utils/src/main/java/org/rhq/core/domain/resource/ResourceTypeBuilder.java
+++
b/modules/core/domain-test-utils/src/main/java/org/rhq/core/domain/resource/ResourceTypeBuilder.java
@@ -30,9 +30,7 @@ import java.util.HashSet;
* created in a valid state, specifically fields that are not nullable are required to
have non-null values. Using the
* builder should help make the intent of tests clearer and more self-documenting.
* <br/><br/>
- * A couple things need to be pointed out. First, this class currently does not yet
provide support for all
- * ResourceType fields/properties. Secondly, this class will likely be moved to a test
utility module in a subsequent
- * commit so that it can be reused by other tests in other modules.
+ * Note that this class currently does not yet provide support for all ResourceType
fields/properties.
*
* @author John Sanda
*/
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java
index c403878..57d9b14 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java
@@ -581,4 +581,9 @@ public class PluginContainer implements ContainerService {
public boolean isInsideAgent() {
return (this.configuration != null &&
this.configuration.isInsideAgent());
}
+
+ public void addRebootRequestListener(RebootRequestListener listener) {
+ inventoryManager.addRebootRequestListener(listener);
+ }
+
}
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/RebootRequestListener.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/RebootRequestListener.java
new file mode 100644
index 0000000..3ce1976
--- /dev/null
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/RebootRequestListener.java
@@ -0,0 +1,11 @@
+package org.rhq.core.pc;
+
+/**
+ * This listener can be notified by the plugin container when some condition occurs that
+ * PC needs to be rebooted.
+ */
+public interface RebootRequestListener {
+
+ void reboot();
+
+}
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 2e15f8e..85955f6 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -58,6 +58,7 @@ import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeResponse;
import org.rhq.core.clientapi.server.discovery.DiscoveryServerService;
import org.rhq.core.clientapi.server.discovery.InvalidInventoryReportException;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.clientapi.server.discovery.StaleTypeException;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.discovery.AvailabilityReport;
import org.rhq.core.domain.discovery.MergeResourceResponse;
@@ -77,6 +78,7 @@ import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.pc.ContainerService;
import org.rhq.core.pc.PluginContainer;
import org.rhq.core.pc.PluginContainerConfiguration;
+import org.rhq.core.pc.RebootRequestListener;
import org.rhq.core.pc.ServerServices;
import org.rhq.core.pc.agent.AgentRegistrar;
import org.rhq.core.pc.agent.AgentService;
@@ -195,6 +197,8 @@ public class InventoryManager extends AgentService implements
ContainerService,
*/
private ResourceUpgradeDelegate resourceUpgradeDelegate = new
ResourceUpgradeDelegate(this);
+ private RebootRequestListener rebootRequestListener;
+
public InventoryManager() {
super(DiscoveryAgentService.class);
}
@@ -954,6 +958,12 @@ public class InventoryManager extends AgentService implements
ContainerService,
log.debug(String.format("Server DONE merging inventory report [%d]
ms.",
(System.currentTimeMillis() - startTime)));
}
+ } catch (StaleTypeException e) {
+ log.error("Failed to merge inventory report with server. The report
contains one or more resource types " +
+ "that have been marked for deletion. Notifying the plugin container
that a reboot is needed to purge " +
+ "stale types.");
+ rebootRequestListener.reboot();
+ return false;
} catch (InvalidInventoryReportException e) {
log.error("Failure sending inventory report to Server - was this
Agent's platform deleted?", e);
if ((this.platform != null) && (this.platform.getInventoryStatus() ==
InventoryStatus.NEW)
@@ -2697,6 +2707,10 @@ public class InventoryManager extends AgentService implements
ContainerService,
}
}
+ public void addRebootRequestListener(RebootRequestListener listener) {
+ rebootRequestListener = listener;
+ }
+
/**
* That class implements a listener that gets called when the resource got activated
* @author hrupp
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
index ab1cd2b..bf12749 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
@@ -43,6 +43,7 @@ import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.agent.discovery.InvalidPluginConfigurationClientException;
import org.rhq.core.clientapi.server.discovery.InvalidInventoryReportException;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.clientapi.server.discovery.StaleTypeException;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
@@ -344,6 +345,7 @@ public class ResourceUpgradeFailureHandlingTest extends
ResourceUpgradeTestBase
expectations.will(getCurrentServerSideInventory().upgradeResources());
} catch (InvalidInventoryReportException e) {
//this is not going to happen because we're mocking the invocation
+ } catch (StaleTypeException e) {
}
}
diff --git
a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
index 43c2ba5..f6e7cf2 100644
--- a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
+++ b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
@@ -90,6 +90,7 @@ import org.rhq.core.domain.cloud.composite.FailoverListComposite;
import org.rhq.core.domain.cloud.composite.FailoverListComposite.ServerEntry;
import org.rhq.core.pc.PluginContainer;
import org.rhq.core.pc.PluginContainerConfiguration;
+import org.rhq.core.pc.RebootRequestListener;
import org.rhq.core.pc.ServerServices;
import org.rhq.core.pc.inventory.InventoryManager;
import org.rhq.core.pc.plugin.FileSystemPluginFinder;
@@ -1778,6 +1779,14 @@ public class AgentMain {
plugin_container.initialize();
LOG.debug(AgentI18NResourceKeys.PLUGIN_CONTAINER_INITIALIZED, pc_config);
+ plugin_container.addRebootRequestListener(new RebootRequestListener() {
+ public void reboot() {
+ shutdownPluginContainer();
+ cleanDataDirectory();
+ startPluginContainer(0L);
+ }
+ });
+
return plugin_container.isStarted();
}
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index 182aa7f..0378d95 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -115,7 +115,8 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
@EJB
private SystemManagerLocal systemManager;
- public ResourceSyncInfo mergeInventoryReport(InventoryReport report) throws
InvalidInventoryReportException {
+ public ResourceSyncInfo mergeInventoryReport(InventoryReport report)
+ throws InvalidInventoryReportException, StaleTypeException {
validateInventoryReport(report);
InventoryReportFilter filter = new DeletedResourceTypeFilter(subjectManager,
resourceTypeManager);
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
index c9208fc..c9f7c2c 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
@@ -33,6 +33,7 @@ import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeResponse;
import org.rhq.core.clientapi.server.discovery.InvalidInventoryReportException;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.clientapi.server.discovery.StaleTypeException;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.discovery.MergeResourceResponse;
@@ -60,7 +61,8 @@ public interface DiscoveryBossLocal extends DiscoveryBossRemote {
*
* @throws InvalidInventoryReportException if the inventory report is invalid
*/
- ResourceSyncInfo mergeInventoryReport(InventoryReport report) throws
InvalidInventoryReportException;
+ ResourceSyncInfo mergeInventoryReport(InventoryReport report)
+ throws InvalidInventoryReportException, StaleTypeException;
/**
* Returns a map of platforms (the keys) and their servers (the values) that are in
the auto-discovery queue but not
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
index 1b939b9..65f8c7c 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
@@ -30,6 +30,7 @@ import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeResponse;
import org.rhq.core.clientapi.server.discovery.DiscoveryServerService;
import org.rhq.core.clientapi.server.discovery.InvalidInventoryReportException;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.clientapi.server.discovery.StaleTypeException;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.discovery.AvailabilityReport;
@@ -65,7 +66,8 @@ public class DiscoveryServerServiceImpl implements
DiscoveryServerService {
/**
* @see DiscoveryServerService#mergeInventoryReport(InventoryReport)
*/
- public ResourceSyncInfo mergeInventoryReport(InventoryReport report) throws
InvalidInventoryReportException {
+ public ResourceSyncInfo mergeInventoryReport(InventoryReport report)
+ throws InvalidInventoryReportException, StaleTypeException {
long start = System.currentTimeMillis();
DiscoveryBossLocal discoveryBoss = LookupUtil.getDiscoveryBoss();
ResourceSyncInfo syncInfo;
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/test/DiscoveryTestBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/test/DiscoveryTestBean.java
index 39f8635..f1056b1 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/test/DiscoveryTestBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/test/DiscoveryTestBean.java
@@ -39,6 +39,7 @@ import org.rhq.core.clientapi.server.core.CoreServerService;
import org.rhq.core.clientapi.server.discovery.DiscoveryServerService;
import org.rhq.core.clientapi.server.discovery.InvalidInventoryReportException;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.clientapi.server.discovery.StaleTypeException;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.authz.Role;
import org.rhq.core.domain.criteria.ResourceTypeCriteria;
@@ -147,6 +148,8 @@ public class DiscoveryTestBean implements DiscoveryTestLocal {
this.discoveryServerService.mergeInventoryReport(report);
} catch (InvalidInventoryReportException e) {
throw new RuntimeException(e);
+ } catch (StaleTypeException e) {
+ throw new RuntimeException(e);
}
}
@@ -170,6 +173,8 @@ public class DiscoveryTestBean implements DiscoveryTestLocal {
this.discoveryServerService.mergeInventoryReport(report);
} catch (InvalidInventoryReportException e) {
throw new RuntimeException(e);
+ } catch (StaleTypeException e) {
+ throw new RuntimeException(e);
}
}
@@ -187,6 +192,8 @@ public class DiscoveryTestBean implements DiscoveryTestLocal {
this.discoveryServerService.mergeInventoryReport(report);
} catch (InvalidInventoryReportException e) {
throw new RuntimeException(e);
+ } catch (StaleTypeException e) {
+ throw new RuntimeException(e);
}
}
commit e045184a9d3de2e47c5c56412fdb99f26edfe903
Author: John Sanda <jsanda(a)redhat.com>
Date: Tue Oct 26 13:49:02 2010 -0400
Reject inventory reports that contain "stale" resource types
If an inventory report that is sent up to the server contains a resource
type that is marked for deletion, DiscoveryBossBean will throw an
exception letting the plugin container know that it needs to restart so
that it can update its plugins and resource types.
This is also the initial commit for the domain-test-utils module. I have
pulled ResourceBuilder and ResourceTypeBuilder out of the cli module and
moved them into this new module so that they can more easily be shared
across modules.
diff --git
a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/StaleTypeException.java
b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/StaleTypeException.java
new file mode 100644
index 0000000..699717f
--- /dev/null
+++
b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/StaleTypeException.java
@@ -0,0 +1,23 @@
+package org.rhq.core.clientapi.server.discovery;
+
+/**
+ * Exception to indicate that a report contains one or more resource types that have been
marked for
+ * deletion.
+ */
+public class StaleTypeException extends InvalidInventoryReportException {
+ public StaleTypeException() {
+ super();
+ }
+
+ public StaleTypeException(String message) {
+ super(message);
+ }
+
+ public StaleTypeException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public StaleTypeException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/modules/core/domain-test-utils/pom.xml
b/modules/core/domain-test-utils/pom.xml
new file mode 100644
index 0000000..97cb509
--- /dev/null
+++ b/modules/core/domain-test-utils/pom.xml
@@ -0,0 +1,36 @@
+<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-domain-test-utils</artifactId>
+ <name>RHQ Domain Model Test Utils</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>${rhq.groupId}</groupId>
+ <artifactId>rhq-core-domain</artifactId>
+ <version>${project.version}</version>
+ <type>ejb</type>
+ </dependency>
+ <dependency>
+ <groupId>hibernate-annotations</groupId>
+ <artifactId>hibernate-annotations</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>hibernate-entitymanager</groupId>
+ <artifactId>hibernate-entitymanager</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.persistence</groupId>
+ <artifactId>persistence-api</artifactId>
+ <version>1.0</version>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git
a/modules/core/domain-test-utils/src/main/java/org/rhq/core/domain/resource/BuilderException.java
b/modules/core/domain-test-utils/src/main/java/org/rhq/core/domain/resource/BuilderException.java
new file mode 100644
index 0000000..7277c3c
--- /dev/null
+++
b/modules/core/domain-test-utils/src/main/java/org/rhq/core/domain/resource/BuilderException.java
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ *
+ * 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.core.domain.resource;
+
+/**
+ * A builder will throw this exception if it is unable to build the target object. For
example, if example if all
+ * required properites of the target object do not have non-null values, then the builder
will throw this exception.
+ *
+ * @author John Sanda
+ */
+public class BuilderException extends RuntimeException {
+
+ public BuilderException() {
+ super();
+ }
+
+ public BuilderException(String message) {
+ super(message);
+ }
+
+ public BuilderException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public BuilderException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git
a/modules/core/domain-test-utils/src/main/java/org/rhq/core/domain/resource/ResourceBuilder.java
b/modules/core/domain-test-utils/src/main/java/org/rhq/core/domain/resource/ResourceBuilder.java
new file mode 100644
index 0000000..425fe3e
--- /dev/null
+++
b/modules/core/domain-test-utils/src/main/java/org/rhq/core/domain/resource/ResourceBuilder.java
@@ -0,0 +1,415 @@
+/*
+ * 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.
+ *
+ * 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.core.domain.resource;
+
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.domain.measurement.ResourceAvailability;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * ResoureBuilder is a builder object that creates Resource objects. The builder ensures
that a Resource is created
+ * in a valid state, specifically, fields that are not nullable are required to have
non-null values. Using a builder
+ * should help make the intent of tests clearer and more self-documenting.
+ * <br/><br/>
+ * A couple things need to be pointed out. First, this class currently does not yet
provide support for all Resource
+ * fields/properties. Secondly, this class will likely be moved to a test utility module
in a subsequent commit so that
+ * it can be reused by other tests in other modules.
+ *
+ * @author John Sanda
+ */
+public class ResourceBuilder {
+
+ private ResourceBuilder parentBuilder;
+
+ private Resource resource;
+
+ private Random random;
+
+ private boolean useDefaultResourceType;
+
+ private ResourceCategory category;
+
+ private List<ResourceBuilder> childBuilders = new
ArrayList<ResourceBuilder>();
+
+ public static class AssociationBuilder {
+ private ResourceBuilder resourceBuilder;
+
+ private int count;
+
+ AssociationBuilder(ResourceBuilder builder, int count) {
+ resourceBuilder = builder;
+ this.count = count;
+ }
+
+ public ResourceBuilder randomChildServers() {
+ for (int i = 0; i < count; ++i) {
+ ResourceBuilder childBuilder = new
ResourceBuilder(ResourceCategory.SERVER, resourceBuilder);
+ resourceBuilder.childBuilders.add(childBuilder.createRandomServer());
+ }
+ return resourceBuilder;
+ }
+
+ public ResourceBuilder randomChildServices() {
+ for (int i = 0; i < count; ++i) {
+ ResourceBuilder childBuilder = new
ResourceBuilder(ResourceCategory.SERVICE, resourceBuilder);
+ resourceBuilder.childBuilders.add(childBuilder.createRandomService());
+ }
+ return resourceBuilder;
+ }
+ }
+
+ public static class ChildrenResourceBuilder {
+ private ResourceBuilder parentBuilder;
+
+ ChildrenResourceBuilder(ResourceBuilder builder, ResourceCategory category, int
numChildren) {
+ parentBuilder = builder;
+ parentBuilder.childBuilders = new
ArrayList<ResourceBuilder>(numChildren);
+ for (int i = 0; i < numChildren; ++i) {
+ parentBuilder.childBuilders.add(new ResourceBuilder(category,
parentBuilder).createResource());
+ }
+ }
+
+ public ChildrenResourceBuilder inInventory() {
+ for (ResourceBuilder childBuilder : parentBuilder.childBuilders) {
+ childBuilder.inInventory();
+ }
+ return this;
+ }
+
+ public ChildrenResourceBuilder notInInventory() {
+ for (ResourceBuilder childBuilder : parentBuilder.childBuilders) {
+ childBuilder.notInInventory();
+ }
+ return this;
+ }
+
+ public ResourceBuilder included() {
+ return parentBuilder;
+ }
+ }
+
+
+ public ResourceBuilder() {
+ }
+
+ private ResourceBuilder(ResourceCategory category, ResourceBuilder parentBuilder) {
+ this.category = category;
+ this.parentBuilder = parentBuilder;
+ }
+
+ public ResourceBuilder createResource() {
+ resource = new Resource();
+ random = new Random();
+ return this;
+ }
+
+ public ResourceBuilder createPlatform() {
+ category = ResourceCategory.PLATFORM;
+ return createResource();
+ }
+
+ public ResourceBuilder createServer() {
+ category = ResourceCategory.SERVER;
+ return createResource();
+ }
+
+ public ResourceBuilder createRandomServer() {
+ category = ResourceCategory.SERVER;
+ createResource();
+ withRandomId();
+ withRandomName("server:");
+ withRandomResourceKey("server:");
+ withRandomUuid("server:");
+ withDefaultServerResourceType();
+
+ return this;
+ }
+
+ public ResourceBuilder createService() {
+ category = ResourceCategory.SERVICE;
+ return createResource();
+ }
+
+ public ResourceBuilder createRandomService() {
+ category = ResourceCategory.SERVICE;
+ createResource();
+ withRandomId();
+ withRandomName("service:");
+ withRandomResourceKey("service:");
+ withRandomUuid("service:");
+ withDefaultServiceResourceType();
+
+ return this;
+ }
+
+ /**
+ * Using a default resource type results in
<code>Resource.resourceType</code> being assigned to a new
+ * ResourceType object that has some default values applied to it. If the Resource
being created is a platform, then
+ * the ResourceType will be a platform. More specifically,
<code>ResourceType.category</code> will be assigned a
+ * value of {@link ResourceCategory#PLATFORM}. Likewise, if the Resource being
created is a server, then its
+ * ResourceType object will have a category of {@link ResourceCategory#SERVER}. And
if the Resource is a service,
+ * then the ResourceType category will be {@link ResourceCategory#SERVICE}.
+ * <br/><br/>
+ * The resource type name defaults to the name of resource. And the plugin name (as
specified by
+ * ResourceType.plugin) defaults to <code>Resource.name + "
Plugin"</code>
+ * <br/><br/>
+ * When using a default resource type, the resource must be created using one of
{@link #createPlatform()},
+ * {@link #createServer()}, or {@link #createService()}; otherwise, an exception will
be thrown since the builder
+ * will not have sufficient information to create the resource type.
+ * <br/><br/>
+ * Lastly, if you specify that a default resource type by calling this method and
also specify the resource tye
+ * with {@link #withResourceType(ResourceType)}, the latter will be overwritten
regardless of when it is called. The
+ * default will be used instead.
+ *
+ * @return The builder
+ *
+ */
+ public ResourceBuilder usingDefaultResourceType() {
+ useDefaultResourceType = true;
+ return this;
+ }
+
+ public ResourceBuilder withId(int id) {
+ resource.setId(id);
+ return this;
+ }
+
+ public ResourceBuilder withRandomId() {
+ resource.setId(random.nextInt());
+ return this;
+ }
+
+ public ResourceBuilder withResourceKey(String key) {
+ resource.setResourceKey(key);
+ return this;
+ }
+
+ public ResourceBuilder withRandomResourceKey(String prefix) {
+ resource.setResourceKey(prefix + randomString());
+ return this;
+ }
+
+ public ResourceBuilder withRandomResourceKey() {
+ return withRandomResourceKey("");
+ }
+
+ public ResourceBuilder withName(String name) {
+ resource.setName(name);
+ return this;
+ }
+
+ public ResourceBuilder withRandomName(String prefix) {
+ resource.setName(prefix + randomString());
+ return this;
+ }
+
+ public ResourceBuilder withRandomName() {
+ return withRandomName("");
+ }
+
+ public ResourceBuilder withResourceType(ResourceType resourceType) {
+ resource.setResourceType(resourceType);
+ return this;
+ }
+
+ public ResourceBuilder withUuid(String uuid) {
+ resource.setUuid(uuid);
+ return this;
+ }
+
+ public ResourceBuilder withRandomUuid(String prefix) {
+ resource.setUuid(prefix + randomString());
+ return this;
+ }
+
+ public ResourceBuilder withRandomUuid() {
+ return withRandomUuid("");
+ }
+
+ public ResourceBuilder withVersion(String version) {
+ resource.setVersion(version);
+ return this;
+ }
+
+ public ResourceBuilder withCurrentAvailability(AvailabilityType availabilityType) {
+ ResourceAvailability availability = new ResourceAvailability(resource,
availabilityType);
+ resource.setCurrentAvailability(availability);
+ return this;
+ }
+
+ public ResourceBuilder withInventoryStatus(InventoryStatus inventoryStatus) {
+ resource.setInventoryStatus(inventoryStatus);
+ return this;
+ }
+
+ /**
+ * Set the <code>inventoryStatus</code> to {@link
InventoryStatus#COMMITTED}
+ *
+ * @return The builder
+ */
+ public ResourceBuilder inInventory() {
+ resource.setInventoryStatus(InventoryStatus.COMMITTED);
+ return this;
+ }
+
+ /**
+ * Set the <code>inventoryStatus</code> to {@link InventoryStatus#NEW}
+ *
+ * @return The builder
+ */
+ public ResourceBuilder notInInventory() {
+ resource.setInventoryStatus(InventoryStatus.NEW);
+ return this;
+ }
+
+ public AssociationBuilder with(int count) {
+ return new AssociationBuilder(this, count);
+ }
+
+ public ResourceBuilder withChildService() {
+ ResourceBuilder childBuilder = new ResourceBuilder(ResourceCategory.SERVICE,
this);
+ childBuilders.add(childBuilder.createService());
+ return childBuilder;
+ }
+
+ public ResourceBuilder included() {
+ return this.parentBuilder;
+ }
+
+ public Resource build() {
+ String errors = validate();
+ if (errors != null) {
+ throw new BuilderException(errors);
+ }
+
+ if (useDefaultResourceType) {
+ withDefaultResourceType();
+ }
+
+ for (ResourceBuilder childBuilder : childBuilders) {
+ resource.addChildResource(childBuilder.build());
+ }
+
+ return resource;
+ }
+
+ private String validate() {
+ StringBuilder errors = new StringBuilder();
+
+ if (resource.getUuid() == null) {
+ // Making uuid required since it is used in equals/hashCode
+ errors.append("uuid is a required property\n");
+ }
+
+ if (resource.getName() == null) {
+ errors.append("name is a required property\n");
+ }
+
+ if (useDefaultResourceType && category == null) {
+ errors.append("When using default resource type, the resource must be
created with one of " +
+ "createPlatform(), createServer(), or createService()\n");
+ }
+
+ // We only care that resourceType is set if we are not using a default type. If
we are using a default,
+ // then the resourceType property will be set after validation, assuming there
are no validation errors.
+ if (!useDefaultResourceType && resource.getResourceType() == null) {
+ errors.append("resourceType is a required property\n");
+ }
+
+ for (ResourceBuilder childBuilder : childBuilders) {
+ String childErrors = childBuilder.validate();
+ if (childErrors != null) {
+ errors.append("The following child resource errors were
found:\n" + childErrors);
+ }
+ }
+
+ if (errors.length() == 0) {
+ return null;
+ }
+
+ return "Unable to build Resource instance due to the following validation
errors:\n" + errors;
+ }
+
+ private ResourceBuilder withDefaultResourceType() {
+ switch (category) {
+ case PLATFORM: return withDefaultPlatformResourceType();
+ case SERVER: return withDefaultServerResourceType();
+ default: return withDefaultServiceResourceType();
+ }
+ }
+
+ /**
+ * The default platform resource type is as its name implies a platform type whose
name defaults to the resource
+ * name and the plugin name (i.e., ResourceType.plugin property) defaults to resource
name + 'Plugin'.
+ *
+ * @return The builder
+ */
+ private ResourceBuilder withDefaultPlatformResourceType() {
+ resource.setResourceType(new ResourceTypeBuilder().createPlatformResourceType()
+ .withName(resource.getName())
+ .withPlugin(resource.getName() + " Plugin")
+ .withParentResourceType(resource.getResourceType())
+ .build());
+ return this;
+ }
+
+ /**
+ * The default server resource type is as its name implies a server type whose name
defaults to the resource name
+ * and the plugin name (i.e., ResourceType.plugin property) defaults to resource name
+ 'Plugin'
+ *
+ * @return The builder
+ */
+ private ResourceBuilder withDefaultServerResourceType() {
+ resource.setResourceType(new ResourceTypeBuilder().createServerResourceType()
+ .withName(resource.getName())
+ .withPlugin(resource.getName() + " Plugin")
+ .withParentResourceType(resource.getResourceType())
+ .build());
+ return this;
+ }
+
+ /**
+ * The default service resource type is as its name implies a service type whose name
defaults to the resource name
+ * and the plugin name (i.e., ResourceType.plugin property) defaults to resource name
+ 'Plugin'
+ *
+ * @return The builder
+ */
+ private ResourceBuilder withDefaultServiceResourceType() {
+ resource.setResourceType(new ResourceTypeBuilder().createServerResourceType()
+ .withName(resource.getName())
+ .withPlugin(resource.getName() + " Plugin")
+ .withParentResourceType(resource.getResourceType())
+ .build());
+ return this;
+ }
+
+ private String randomString() {
+ return new BigInteger(16, random).toString(32);
+ }
+
+}
diff --git
a/modules/core/domain-test-utils/src/main/java/org/rhq/core/domain/resource/ResourceTypeBuilder.java
b/modules/core/domain-test-utils/src/main/java/org/rhq/core/domain/resource/ResourceTypeBuilder.java
new file mode 100644
index 0000000..f7d2736
--- /dev/null
+++
b/modules/core/domain-test-utils/src/main/java/org/rhq/core/domain/resource/ResourceTypeBuilder.java
@@ -0,0 +1,141 @@
+/*
+ * 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.
+ *
+ * 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.core.domain.resource;
+
+import java.util.HashSet;
+
+/**
+ * ResourceTypeBuilder is a builder that creates ResourceType objects. The builder
ensures that the ResourceType is
+ * created in a valid state, specifically fields that are not nullable are required to
have non-null values. Using the
+ * builder should help make the intent of tests clearer and more self-documenting.
+ * <br/><br/>
+ * A couple things need to be pointed out. First, this class currently does not yet
provide support for all
+ * ResourceType fields/properties. Secondly, this class will likely be moved to a test
utility module in a subsequent
+ * commit so that it can be reused by other tests in other modules.
+ *
+ * @author John Sanda
+ */
+public class ResourceTypeBuilder {
+
+ private ResourceType resourceType;
+
+ public ResourceTypeBuilder createResourceType() {
+ resourceType = new ResourceType();
+ resourceType.setParentResourceTypes(new HashSet<ResourceType>());
+ resourceType.setChildResourceTypes(new HashSet<ResourceType>());
+
+ return this;
+ }
+
+ public ResourceTypeBuilder createPlatformResourceType() {
+ return createResourceType().withCategory(ResourceCategory.PLATFORM);
+ }
+
+ public ResourceTypeBuilder createServerResourceType() {
+ return createResourceType().withCategory(ResourceCategory.SERVER);
+ }
+
+ public ResourceTypeBuilder createServiceResourceType() {
+ return createResourceType().withCategory(ResourceCategory.SERVICE);
+ }
+
+ public ResourceTypeBuilder withId(int id) {
+ resourceType.setId(id);
+ return this;
+ }
+
+ public ResourceTypeBuilder withName(String name) {
+ resourceType.setName(name);
+ return this;
+ }
+
+ public ResourceTypeBuilder withPlugin(String plugin) {
+ resourceType.setPlugin(plugin);
+ return this;
+ }
+
+ public ResourceTypeBuilder withCategory(ResourceCategory category) {
+ resourceType.setCategory(category);
+ return this;
+ }
+
+ public ResourceTypeBuilder thatIsDeleted() {
+ resourceType.setDeleted(true);
+ return this;
+ }
+
+ public ResourceTypeBuilder withParentResourceType(ResourceType parentResourceType) {
+ if (parentResourceType != null) {
+ resourceType.addParentResourceType(parentResourceType);
+ }
+ return this;
+ }
+
+ public ResourceTypeBuilder withParentResourceTypes(ResourceType...
parentResourceTypes) {
+ for (ResourceType parent : parentResourceTypes) {
+ resourceType.addParentResourceType(parent);
+ }
+ return this;
+ }
+
+ public ResourceType build() {
+ String errors = valdiate();
+ if (errors != null) {
+ throw new BuilderException(errors);
+ }
+
+ return resourceType;
+ }
+
+ private String valdiate() {
+ StringBuilder errors = new StringBuilder();
+
+ if (resourceType.getName() == null) {
+ errors.append("name is a required property\n");
+ }
+
+ if (resourceType.getCategory() == null) {
+ errors.append("category is a required property\n");
+ }
+
+ if (resourceType.getCreationDataType() == null) {
+ errors.append("creationDate is a required property\n");
+ }
+
+ if (resourceType.getCreateDeletePolicy() == null) {
+ errors.append("createDeletePolicy is a required property\n");
+ }
+
+ if (resourceType.getPlugin() == null) {
+ errors.append("plugin is a required property\n");
+ }
+
+ if (errors.length() == 0) {
+ return null;
+ }
+
+ return "Unable to build ResourceType instance due to the following
validation errors:\n" + errors;
+ }
+
+}
diff --git a/modules/core/pom.xml b/modules/core/pom.xml
index f6f8289..b936f26 100644
--- a/modules/core/pom.xml
+++ b/modules/core/pom.xml
@@ -47,6 +47,7 @@
<module>comm-api</module>
<module>dbutils</module>
<module>domain</module>
+ <module>domain-test-utils</module>
<module>plugin-api</module>
<module>client-api</module>
<module>plugin-container</module>
diff --git a/modules/enterprise/remoting/cli/pom.xml
b/modules/enterprise/remoting/cli/pom.xml
index 9811869..d2c0f16 100644
--- a/modules/enterprise/remoting/cli/pom.xml
+++ b/modules/enterprise/remoting/cli/pom.xml
@@ -31,7 +31,13 @@
<groupId>${groupId}</groupId>
<artifactId>rhq-remoting-client-api</artifactId>
<version>${project.version}</version>
- </dependency>
+ </dependency>
+
+ <dependency>
+ <groupId>${groupId}</groupId>
+ <artifactId>rhq-core-domain-test-utils</artifactId>
+ <version>${version}</version>
+ </dependency>
<dependency>
<groupId>commons-logging</groupId>
diff --git
a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/BuilderException.java
b/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/BuilderException.java
deleted file mode 100644
index 8d06434..0000000
---
a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/BuilderException.java
+++ /dev/null
@@ -1,49 +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, 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.client;
-
-/**
- * A builder will throw this exception if it is unable to build the target object. For
example, if example if all
- * required properites of the target object do not have non-null values, then the builder
will throw this exception.
- *
- * @author John Sanda
- */
-public class BuilderException extends RuntimeException {
-
- public BuilderException() {
- super();
- }
-
- public BuilderException(String message) {
- super(message);
- }
-
- public BuilderException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public BuilderException(Throwable cause) {
- super(cause);
- }
-}
diff --git
a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/ResourceBuilder.java
b/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/ResourceBuilder.java
deleted file mode 100644
index 30dba39..0000000
---
a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/ResourceBuilder.java
+++ /dev/null
@@ -1,374 +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, 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.client;
-
-import org.rhq.core.domain.measurement.AvailabilityType;
-import org.rhq.core.domain.measurement.ResourceAvailability;
-import org.rhq.core.domain.resource.InventoryStatus;
-import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.resource.ResourceCategory;
-import org.rhq.core.domain.resource.ResourceType;
-
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-
-/**
- * ResoureBuilder is a builder object that creates Resource objects. The builder ensures
that a Resource is created
- * in a valid state, specifically, fields that are not nullable are required to have
non-null values. Using a builder
- * should help make the intent of tests clearer and more self-documenting.
- * <br/><br/>
- * A couple things need to be pointed out. First, this class currently does not yet
provide support for all Resource
- * fields/properties. Secondly, this class will likely be moved to a test utility module
in a subsequent commit so that
- * it can be reused by other tests in other modules.
- *
- * @author John Sanda
- */
-public class ResourceBuilder {
-
- private ResourceBuilder parentBuilder;
-
- private Resource resource;
-
- private Random random;
-
- private boolean useDefaultResourceType;
-
- private ResourceCategory category;
-
- private List<ResourceBuilder> childBuilders;
-
- static class AssociationBuilder {
- private ResourceBuilder resourceBuilder;
-
- private int count;
-
- AssociationBuilder(ResourceBuilder builder, int count) {
- resourceBuilder = builder;
- this.count = count;
- }
-
- public ChildrenResourceBuilder childServices() {
- return new ChildrenResourceBuilder(resourceBuilder, ResourceCategory.SERVICE,
count);
- }
- }
-
- static class ChildrenResourceBuilder {
- private ResourceBuilder parentBuilder;
-
- ChildrenResourceBuilder(ResourceBuilder builder, ResourceCategory category, int
numChildren) {
- parentBuilder = builder;
- parentBuilder.childBuilders = new
ArrayList<ResourceBuilder>(numChildren);
- for (int i = 0; i < numChildren; ++i) {
- parentBuilder.childBuilders.add(new ResourceBuilder(category,
parentBuilder).createResource());
- }
- }
-
- public ChildrenResourceBuilder inInventory() {
- for (ResourceBuilder childBuilder : parentBuilder.childBuilders) {
- childBuilder.inInventory();
- }
- return this;
- }
-
- public ChildrenResourceBuilder notInInventory() {
- for (ResourceBuilder childBuilder : parentBuilder.childBuilders) {
- childBuilder.notInInventory();
- }
- return this;
- }
-
- public ResourceBuilder included() {
- return parentBuilder;
- }
- }
-
-
- public ResourceBuilder() {
- }
-
- private ResourceBuilder(ResourceCategory category, ResourceBuilder parentBuilder) {
- this.category = category;
- this.parentBuilder = parentBuilder;
- }
-
- public ResourceBuilder createResource() {
- resource = new Resource();
- random = new Random();
- return this;
- }
-
- public ResourceBuilder createPlatform() {
- category = ResourceCategory.PLATFORM;
- return createResource();
- }
-
- public ResourceBuilder createServer() {
- category = ResourceCategory.SERVER;
- return createResource();
- }
-
- public ResourceBuilder createService() {
- category = ResourceCategory.SERVICE;
- return createResource();
- }
-
- /**
- * Using a default resource type results in
<code>Resource.resourceType</code> being assigned to a new
- * ResourceType object that has some default values applied to it. If the Resource
being created is a platform, then
- * the ResourceType will be a platform. More specifically,
<code>ResourceType.category</code> will be assigned a
- * value of {@link ResourceCategory#PLATFORM}. Likewise, if the Resource being
created is a server, then its
- * ResourceType object will have a category of {@link ResourceCategory#SERVER}. And
if the Resource is a service,
- * then the ResourceType category will be {@link ResourceCategory#SERVICE}.
- * <br/><br/>
- * The resource type name defaults to the name of resource. And the plugin name (as
specified by
- * ResourceType.plugin) defaults to <code>Resource.name + "
Plugin"</code>
- * <br/><br/>
- * When using a default resource type, the resource must be created using one of
{@link #createPlatform()},
- * {@link #createServer()}, or {@link #createService()}; otherwise, an exception will
be thrown since the builder
- * will not have sufficient information to create the resource type.
- * <br/><br/>
- * Lastly, if you specify that a default resource type by calling this method and
also specify the resource tye
- * with {@link #withResourceType(ResourceType)}, the latter will be overwritten
regardless of when it is called. The
- * default will be used instead.
- *
- * @return The builder
- *
- */
- public ResourceBuilder usingDefaultResourceType() {
- useDefaultResourceType = true;
- return this;
- }
-
- public ResourceBuilder withId(int id) {
- resource.setId(id);
- return this;
- }
-
- public ResourceBuilder withRandomId() {
- resource.setId(random.nextInt());
- return this;
- }
-
- public ResourceBuilder withResourceKey(String key) {
- resource.setResourceKey(key);
- return this;
- }
-
- public ResourceBuilder withRandomResourceKey(String prefix) {
- resource.setResourceKey(prefix + randomString());
- return this;
- }
-
- public ResourceBuilder withRandomResourceKey() {
- return withRandomResourceKey("");
- }
-
- public ResourceBuilder withName(String name) {
- resource.setName(name);
- return this;
- }
-
- public ResourceBuilder withRandomName(String prefix) {
- resource.setName(prefix + randomString());
- return this;
- }
-
- public ResourceBuilder withRandomName() {
- return withRandomName("");
- }
-
- public ResourceBuilder withResourceType(ResourceType resourceType) {
- resource.setResourceType(resourceType);
- return this;
- }
-
- public ResourceBuilder withUuid(String uuid) {
- resource.setUuid(uuid);
- return this;
- }
-
- public ResourceBuilder withRandomUuid(String prefix) {
- resource.setUuid(prefix + randomString());
- return this;
- }
-
- public ResourceBuilder withRandomUuid() {
- return withRandomUuid("");
- }
-
- public ResourceBuilder withVersion(String version) {
- resource.setVersion(version);
- return this;
- }
-
- public ResourceBuilder withCurrentAvailability(AvailabilityType availabilityType) {
- ResourceAvailability availability = new ResourceAvailability(resource,
availabilityType);
- resource.setCurrentAvailability(availability);
- return this;
- }
-
- public ResourceBuilder withInventoryStatus(InventoryStatus inventoryStatus) {
- resource.setInventoryStatus(inventoryStatus);
- return this;
- }
-
- /**
- * Set the <code>inventoryStatus</code> to {@link
InventoryStatus#COMMITTED}
- *
- * @return The builder
- */
- public ResourceBuilder inInventory() {
- resource.setInventoryStatus(InventoryStatus.COMMITTED);
- return this;
- }
-
- /**
- * Set the <code>inventoryStatus</code> to {@link InventoryStatus#NEW}
- *
- * @return The builder
- */
- public ResourceBuilder notInInventory() {
- resource.setInventoryStatus(InventoryStatus.NEW);
- return this;
- }
-
- public AssociationBuilder with(int count) {
- return new AssociationBuilder(this, count);
- }
-
- public Resource build() {
- String errors = validate();
- if (errors != null) {
- throw new BuilderException(errors);
- }
-
- if (useDefaultResourceType) {
- withDefaultResourceType();
- }
-
- if (childBuilders != null) {
- int i = 1;
- for (ResourceBuilder childBuilder : childBuilders) {
- resource.addChildResource(childBuilder
- .withName("child-" + i)
- .withUuid("child-" + i++)
- .withVersion(resource.getVersion())
- .withDefaultResourceType()
- .build());
- }
- }
-
- return resource;
- }
-
- private String validate() {
- StringBuilder errors = new StringBuilder();
-
- if (resource.getUuid() == null) {
- // Making uuid required since it is used in equals/hashCode
- errors.append("uuid is a required property\n");
- }
-
- if (resource.getName() == null) {
- errors.append("name is a required property\n");
- }
-
- if (useDefaultResourceType && category == null) {
- errors.append("When using default resource type, the resource must be
created with one of " +
- "createPlatform(), createServer(), or createService()\n");
- }
-
- // We only care that resourceType is set if we are not using a default type. If
we are using a default,
- // then the resourceType property will be set after validation, assuming there
are no validation errors.
- if (!useDefaultResourceType && resource.getResourceType() == null) {
- errors.append("resourceType is a required property\n");
- }
-
- if (errors.length() == 0) {
- return null;
- }
-
- return "Unable to build Resource instance due to the following validation
errors:\n" + errors;
- }
-
- private ResourceBuilder withDefaultResourceType() {
- switch (category) {
- case PLATFORM: return withDefaultPlatformResourceType();
- case SERVER: return withDefaultServerResourceType();
- default: return withDefaultServicePlatformResourceType();
- }
- }
-
- /**
- * The default platform resource type is as its name implies a platform type whose
name defaults to the resource
- * name and the plugin name (i.e., ResourceType.plugin property) defaults to resource
name + 'Plugin'.
- *
- * @return The builder
- */
- private ResourceBuilder withDefaultPlatformResourceType() {
- resource.setResourceType(new ResourceTypeBuilder().createPlatformResourceType()
- .withName(resource.getName())
- .withPlugin(resource.getName() + " Plugin")
- .withParentResourceType(resource.getResourceType())
- .build());
- return this;
- }
-
- /**
- * The default server resource type is as its name implies a server type whose name
defaults to the resource name
- * and the plugin name (i.e., ResourceType.plugin property) defaults to resource name
+ 'Plugin'
- *
- * @return The builder
- */
- private ResourceBuilder withDefaultServerResourceType() {
- resource.setResourceType(new ResourceTypeBuilder().createServerResourceType()
- .withName(resource.getName())
- .withPlugin(resource.getName() + " Plugin")
- .withParentResourceType(resource.getResourceType())
- .build());
- return this;
- }
-
- /**
- * The default service resource type is as its name implies a service type whose name
defaults to the resource name
- * and the plugin name (i.e., ResourceType.plugin property) defaults to resource name
+ 'Plugin'
- *
- * @return The builder
- */
- private ResourceBuilder withDefaultServicePlatformResourceType() {
- resource.setResourceType(new ResourceTypeBuilder().createServerResourceType()
- .withName(resource.getName())
- .withPlugin(resource.getName() + " Plugin")
- .withParentResourceType(resource.getResourceType())
- .build());
- return this;
- }
-
- private String randomString() {
- return new BigInteger(16, random).toString(32);
- }
-
-}
diff --git
a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/ResourceTypeBuilder.java
b/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/ResourceTypeBuilder.java
deleted file mode 100644
index 73abefd..0000000
---
a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/ResourceTypeBuilder.java
+++ /dev/null
@@ -1,140 +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, 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.client;
-
-import org.rhq.core.domain.resource.ResourceCategory;
-import org.rhq.core.domain.resource.ResourceType;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * ResourceTypeBuilder is a builder that creates ResourceType objects. The builder
ensures that the ResourceType is
- * created in a valid state, specifically fields that are not nullable are required to
have non-null values. Using the
- * builder should help make the intent of tests clearer and more self-documenting.
- * <br/><br/>
- * A couple things need to be pointed out. First, this class currently does not yet
provide support for all
- * ResourceType fields/properties. Secondly, this class will likely be moved to a test
utility module in a subsequent
- * commit so that it can be reused by other tests in other modules.
- *
- * @author John Sanda
- */
-public class ResourceTypeBuilder {
-
- private ResourceType resourceType;
-
- public ResourceTypeBuilder createResourceType() {
- resourceType = new ResourceType();
- resourceType.setParentResourceTypes(new HashSet<ResourceType>());
- resourceType.setChildResourceTypes(new HashSet<ResourceType>());
-
- return this;
- }
-
- public ResourceTypeBuilder createPlatformResourceType() {
- return createResourceType().withCategory(ResourceCategory.PLATFORM);
- }
-
- public ResourceTypeBuilder createServerResourceType() {
- return createResourceType().withCategory(ResourceCategory.SERVER);
- }
-
- public ResourceTypeBuilder createServiceResourceType() {
- return createResourceType().withCategory(ResourceCategory.SERVICE);
- }
-
- public ResourceTypeBuilder withId(int id) {
- resourceType.setId(id);
- return this;
- }
-
- public ResourceTypeBuilder withName(String name) {
- resourceType.setName(name);
- return this;
- }
-
- public ResourceTypeBuilder withPlugin(String plugin) {
- resourceType.setPlugin(plugin);
- return this;
- }
-
- public ResourceTypeBuilder withCategory(ResourceCategory category) {
- resourceType.setCategory(category);
- return this;
- }
-
- public ResourceTypeBuilder withParentResourceType(ResourceType parentResourceType) {
- if (parentResourceType != null) {
- resourceType.addParentResourceType(parentResourceType);
- }
- return this;
- }
-
- public ResourceTypeBuilder withParentResourceTypes(ResourceType...
parentResourceTypes) {
- for (ResourceType parent : parentResourceTypes) {
- resourceType.addParentResourceType(parent);
- }
- return this;
- }
-
- public ResourceType build() {
- String errors = valdiate();
- if (errors != null) {
- throw new BuilderException(errors);
- }
-
- return resourceType;
- }
-
- private String valdiate() {
- StringBuilder errors = new StringBuilder();
-
- if (resourceType.getName() == null) {
- errors.append("name is a required property\n");
- }
-
- if (resourceType.getCategory() == null) {
- errors.append("category is a required property\n");
- }
-
- if (resourceType.getCreationDataType() == null) {
- errors.append("creationDate is a required property\n");
- }
-
- if (resourceType.getCreateDeletePolicy() == null) {
- errors.append("createDeletePolicy is a required property\n");
- }
-
- if (resourceType.getPlugin() == null) {
- errors.append("plugin is a required property\n");
- }
-
- if (errors.length() == 0) {
- return null;
- }
-
- return "Unable to build ResourceType instance due to the following
validation errors:\n" + errors;
- }
-
-}
diff --git
a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/TabularWriterTest.java
b/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/TabularWriterTest.java
index 4470434..c9d8bb6 100644
---
a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/TabularWriterTest.java
+++
b/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/TabularWriterTest.java
@@ -25,11 +25,9 @@ package org.rhq.enterprise.client;
import static org.testng.Assert.*;
-import org.rhq.core.domain.measurement.AvailabilityType;
-import org.rhq.core.domain.measurement.ResourceAvailability;
import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.resource.ResourceCategory;
-import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.resource.ResourceBuilder;
+
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@@ -40,12 +38,10 @@ import javax.persistence.OneToOne;
import javax.persistence.OneToMany;
import java.io.PrintWriter;
import java.io.StringWriter;
-import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import static org.rhq.core.domain.measurement.AvailabilityType.*;
-import static org.rhq.core.domain.resource.ResourceCategory.*;
public class TabularWriterTest {
@@ -261,9 +257,9 @@ public class TabularWriterTest {
.withUuid("12345")
.withVersion("1.0")
.inInventory()
- .with(2).childServices()
- .notInInventory()
- .included()
+ .with(2).randomChildServices()
+// .notInInventory()
+// .included()
.build();
writer.print(parent.getChildResources());
diff --git a/modules/enterprise/server/jar/pom.xml
b/modules/enterprise/server/jar/pom.xml
index 2abdae5..060a8f6 100644
--- a/modules/enterprise/server/jar/pom.xml
+++ b/modules/enterprise/server/jar/pom.xml
@@ -80,6 +80,14 @@
<groupId>org.rhq</groupId>
<artifactId>test-utils</artifactId>
<version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-domain-test-utils</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
</dependency>
<!-- 3rd Party Deps -->
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DeletedResourceTypeFilter.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DeletedResourceTypeFilter.java
new file mode 100644
index 0000000..ea4d430
--- /dev/null
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DeletedResourceTypeFilter.java
@@ -0,0 +1,64 @@
+package org.rhq.enterprise.server.discovery;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.domain.criteria.ResourceTypeCriteria;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.enterprise.server.auth.SubjectManagerLocal;
+import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal;
+
+public class DeletedResourceTypeFilter implements InventoryReportFilter {
+
+ private SubjectManagerLocal subjectMgr;
+
+ private ResourceTypeManagerLocal resourceTypeMgr;
+
+ private Set<String> deletedTypes;
+
+ public DeletedResourceTypeFilter(SubjectManagerLocal subjectManager,
ResourceTypeManagerLocal resourceTypeManager) {
+ subjectMgr = subjectManager;
+ resourceTypeMgr = resourceTypeManager;
+ deletedTypes = new HashSet<String>();
+ loadDeletedTypes();
+ }
+
+ private void loadDeletedTypes() {
+ ResourceTypeCriteria criteria = new ResourceTypeCriteria();
+ criteria.addFilterDeleted(true);
+ PageList<ResourceType> results =
resourceTypeMgr.findResourceTypesByCriteria(subjectMgr.getOverlord(),
+ criteria);
+ for (ResourceType type : results) {
+ deletedTypes.add(type.getName() + "::" + type.getPlugin());
+ }
+ }
+
+ public boolean accept(InventoryReport report) {
+ for (Resource resource : report.getAddedRoots()) {
+ if (containsDeletedType(resource)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private boolean containsDeletedType(Resource resource) {
+ if (isDeleted(resource.getResourceType())) {
+ return true;
+ }
+ for (Resource child : resource.getChildResources()) {
+ if (containsDeletedType(child)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean isDeleted(ResourceType type) {
+ return deletedTypes.contains(type.getName() + "::" +
type.getPlugin());
+ }
+}
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index c593d62..182aa7f 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -47,6 +47,7 @@ import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeResponse;
import org.rhq.core.clientapi.server.discovery.InvalidInventoryReportException;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.clientapi.server.discovery.StaleTypeException;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.configuration.Configuration;
@@ -116,6 +117,13 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
public ResourceSyncInfo mergeInventoryReport(InventoryReport report) throws
InvalidInventoryReportException {
validateInventoryReport(report);
+
+ InventoryReportFilter filter = new DeletedResourceTypeFilter(subjectManager,
resourceTypeManager);
+ if (!filter.accept(report)) {
+ throw new StaleTypeException("The report contains one or more resource
types that have been marked for " +
+ "deletion.");
+ }
+
Agent agent = report.getAgent();
long start = System.currentTimeMillis();
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/InventoryReportFilter.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/InventoryReportFilter.java
new file mode 100644
index 0000000..78ac3e1
--- /dev/null
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/InventoryReportFilter.java
@@ -0,0 +1,9 @@
+package org.rhq.enterprise.server.discovery;
+
+import org.rhq.core.clientapi.server.discovery.InventoryReport;
+
+public interface InventoryReportFilter {
+
+ boolean accept(InventoryReport report);
+
+}
diff --git
a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/discovery/DeletedResourceTypeFilterTest.java
b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/discovery/DeletedResourceTypeFilterTest.java
new file mode 100644
index 0000000..13de583
--- /dev/null
+++
b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/discovery/DeletedResourceTypeFilterTest.java
@@ -0,0 +1,110 @@
+package org.rhq.enterprise.server.discovery;
+
+import java.util.List;
+
+import org.jmock.Expectations;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.criteria.ResourceTypeCriteria;
+import org.rhq.core.domain.resource.Agent;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceBuilder;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.resource.ResourceTypeBuilder;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.enterprise.server.auth.SubjectManagerLocal;
+import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal;
+import org.rhq.test.JMockTest;
+
+import static org.testng.Assert.*;
+
+public class DeletedResourceTypeFilterTest extends JMockTest {
+
+ SubjectManagerLocal subjectMgr;
+
+ ResourceTypeManagerLocal resourceTypeMgr;
+
+ DeletedResourceTypeFilter filter;
+
+ @BeforeMethod
+ public void init() {
+ subjectMgr = context.mock(SubjectManagerLocal.class);
+ resourceTypeMgr = context.mock(ResourceTypeManagerLocal.class);
+ }
+
+ @Test
+ public void acceptReportWithNoDeletedTypes() {
+ context.checking(new Expectations() {{
+ allowing(subjectMgr).getOverlord();
+ will(returnValue(new Subject("overlord", true, true)));
+
+
allowing(resourceTypeMgr).findResourceTypesByCriteria(with(aNonNull(Subject.class)),
+ with(aNonNull(ResourceTypeCriteria.class)));
+ will(returnValue(new PageList<ResourceType>()));
+ }});
+
+ InventoryReport report = createReport();
+ report.addAddedRoot(new ResourceBuilder()
+ .createRandomServer()
+ .with(2).randomChildServices()
+ .build());
+ report.addAddedRoot(new ResourceBuilder()
+ .createRandomService()
+ .with(2).randomChildServices()
+ .build());
+
+ filter = new DeletedResourceTypeFilter(subjectMgr, resourceTypeMgr);
+
+ assertTrue(filter.accept(report), "Expected report to be accepted when it
does not contain any deleted " +
+ "resource types");
+ }
+
+ @Test
+ public void rejectReportWithDeletedTypes() {
+ ResourceType deletedServiceType = new ResourceTypeBuilder()
+ .createServiceResourceType()
+ .withName("TestService")
+ .withPlugin("TestPlugin")
+ .thatIsDeleted()
+ .build();
+
+ final PageList<ResourceType> deletedTypes = new
PageList<ResourceType>();
+ deletedTypes.add(deletedServiceType);
+
+ context.checking(new Expectations() {{
+ allowing(subjectMgr).getOverlord();
+ will(returnValue(new Subject("overlord", true, true)));
+
+
allowing(resourceTypeMgr).findResourceTypesByCriteria(with(aNonNull(Subject.class)),
+ with(aNonNull(ResourceTypeCriteria.class)));
+ will(returnValue(deletedTypes));
+ }});
+
+ InventoryReport report = createReport();
+ report.addAddedRoot(new ResourceBuilder()
+ .createRandomServer()
+ .withChildService()
+ .withName("ChildService")
+ .withUuid("c1")
+ .withResourceType(new ResourceTypeBuilder()
+ .createServiceResourceType()
+ .withName("TestService")
+ .withPlugin("TestPlugin")
+ .build())
+ .included()
+ .build());
+
+ filter = new DeletedResourceTypeFilter(subjectMgr, resourceTypeMgr);
+
+ assertFalse(filter.accept(report), "Expected report to be rejected since it
contains deleted resource types");
+ }
+
+ InventoryReport createReport() {
+ Agent agent = new Agent("localhost", "localhost", 1234,
"1234", "test-token");
+ return new InventoryReport(agent);
+ }
+
+}