modules/core/domain/src/main/java/org/rhq/core/domain/discovery/ResourceSyncInfo.java
| 28 +
modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/inventory/IgnoreTypesInventoryManagerTest.java
| 263 ++++++++++
2 files changed, 291 insertions(+)
New commits:
commit 086ce6d1e6bf8db3f9ece62b8d6ed60de00379e5
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Sun Mar 24 00:32:48 2013 -0400
BZ 535289 - integration test of agent-side discovery/inventory when resource types are
ignored then unignored
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/discovery/ResourceSyncInfo.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/discovery/ResourceSyncInfo.java
index eb3b97d..b0a5315 100644
---
a/modules/core/domain/src/main/java/org/rhq/core/domain/discovery/ResourceSyncInfo.java
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/discovery/ResourceSyncInfo.java
@@ -24,6 +24,7 @@ package org.rhq.core.domain.discovery;
import java.io.Serializable;
import java.util.Collection;
+import java.util.HashSet;
import javax.persistence.Column;
import javax.persistence.Entity;
@@ -39,6 +40,7 @@ import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.rhq.core.domain.resource.InventoryStatus;
+import org.rhq.core.domain.resource.Resource;
/**
* @author Ian Springer
@@ -103,4 +105,30 @@ public class ResourceSyncInfo implements Serializable {
return childSyncInfos;
}
+ public static ResourceSyncInfo buildResourceSyncInfo(Resource resource) {
+ Collection<ResourceSyncInfo> children;
+
+ if (resource.getChildResources() != null) {
+ children = new
HashSet<ResourceSyncInfo>(resource.getChildResources().size());
+ for (Resource child : resource.getChildResources()) {
+ children.add(buildResourceSyncInfo(child));
+ }
+ } else {
+ children = new HashSet<ResourceSyncInfo>(0);
+ }
+
+ ResourceSyncInfo syncInfo = new ResourceSyncInfo(resource.getId(),
resource.getUuid(), resource.getMtime(),
+ resource.getInventoryStatus(), children);
+
+ return syncInfo;
+ }
+
+ private ResourceSyncInfo(int id, String uuid, long mtime, InventoryStatus istatus,
+ Collection<ResourceSyncInfo> children) {
+ this.id = id;
+ this.uuid = uuid;
+ this.mtime = mtime;
+ this.inventoryStatus = istatus;
+ this.childSyncInfos = children;
+ }
}
diff --git
a/modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/inventory/IgnoreTypesInventoryManagerTest.java
b/modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/inventory/IgnoreTypesInventoryManagerTest.java
new file mode 100644
index 0000000..682b63a
--- /dev/null
+++
b/modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/inventory/IgnoreTypesInventoryManagerTest.java
@@ -0,0 +1,263 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2013 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.core.pc.inventory;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.when;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.container.test.api.TargetsContainer;
+import org.jboss.arquillian.test.api.ArquillianResource;
+import org.jboss.arquillian.testng.Arquillian;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+
+import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.domain.discovery.MergeInventoryReportResults;
+import org.rhq.core.domain.discovery.ResourceSyncInfo;
+import org.rhq.core.domain.resource.InventoryStatus;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.pc.PluginContainer;
+import org.rhq.core.pc.PluginContainerConfiguration;
+import org.rhq.core.pc.inventory.testplugin.ManualAddDiscoveryComponent;
+import org.rhq.core.pc.inventory.testplugin.TestResourceComponent;
+import org.rhq.core.pc.inventory.testplugin.TestResourceDiscoveryComponent;
+import org.rhq.test.arquillian.AfterDiscovery;
+import org.rhq.test.arquillian.BeforeDiscovery;
+import org.rhq.test.arquillian.MockingServerServices;
+import org.rhq.test.arquillian.RunDiscovery;
+import org.rhq.test.shrinkwrap.RhqAgentPluginArchive;
+
+/**
+ * Test the server ignoring resource types and notifying the {@link InventoryManager}
about it.
+ *
+ * @author John Mazzitelli
+ */
+@RunDiscovery
+public class IgnoreTypesInventoryManagerTest extends Arquillian {
+
+ @Deployment(name = "test")
+ @TargetsContainer("pc")
+ public static RhqAgentPluginArchive getTestPlugin() {
+ RhqAgentPluginArchive pluginJar = ShrinkWrap.create(RhqAgentPluginArchive.class,
"test-plugin.jar");
+ return
pluginJar.setPluginDescriptor("test-great-grandchild-discovery-plugin.xml").addClasses(
+ TestResourceDiscoveryComponent.class, TestResourceComponent.class,
ManualAddDiscoveryComponent.class);
+ }
+
+ @ArquillianResource
+ private MockingServerServices serverServices;
+
+ @ArquillianResource
+ private PluginContainerConfiguration pluginContainerConfiguration;
+
+ @ArquillianResource
+ private PluginContainer pluginContainer;
+
+ private Resource platform;
+ private HashMap<String, Resource> simulatedInventory; // key == UUID
+
+ private Collection<ResourceType> ignoredTypes;
+
+ private CountDownLatch gotIgnoredTypeFromAgent;
+
+ @BeforeDiscovery
+ public void resetServerServices() throws Exception {
+ platform = null;
+ simulatedInventory = new HashMap<String, Resource>();
+ gotIgnoredTypeFromAgent = new CountDownLatch(1); // will be open once we know
agent discovered types we want ignored
+
+ ignoredTypes = new HashSet<ResourceType>();
+ ignoredTypes.add(new ResourceType("Test Service GrandChild",
"test", null, null));
+ ignoredTypes.add(new ResourceType("Manual Add Server",
"test", null, null));
+
+ serverServices.resetMocks();
+
+
when(serverServices.getDiscoveryServerService().mergeInventoryReport(any(InventoryReport.class))).then(
+ mergeInventoryReport());
+ }
+
+ @AfterDiscovery
+ public void afterDiscovery() throws Exception {
+ // wait for agent discovery to start getting ignored types
+ // actually, I don't think this latch will ever count down - if I did this
right,
+ // the first inventory report will tell the agent about the ignored types -
before the agent
+ // even attempted to discover resources of that type. Therefore, the agent will
probably never
+ // send up resources of the ignored types. But we have to wait anyway for the few
inventory reports
+ // that have to be received (which includes the resources of the unignored
types).
+ gotIgnoredTypeFromAgent.await(20L, TimeUnit.SECONDS);
+ }
+
+ @Test
+ public void testIgnoreTypes() throws Exception {
+ // make sure the agent inventory does not have any resources of the ignored
types
+ validatePartiallyIgnoredInventory();
+
+ // simulate the unignoring of all types (i.e. don't ignore any types
anymore)
+ ignoredTypes.clear();
+
+ // Now execute a full discovery again, this time, we should see the full
inventory come in
+ System.out.println("Executing full discovery...");
+ InventoryManager inventoryManager = pluginContainer.getInventoryManager();
+ InventoryReport report = inventoryManager.executeServerScanImmediately();
+ inventoryManager.handleReport(report);
+ report = inventoryManager.executeServiceScanImmediately();
+ inventoryManager.handleReport(report);
+ waitForFullInventory();
+ validateFullInventory();
+ }
+
+ private void waitForFullInventory() throws Exception {
+ long start = System.currentTimeMillis();
+ while (getInventoryDepth(platform) < 5) {
+ Thread.sleep(1000);
+ if (System.currentTimeMillis() - start > 30000L) {
+ break; // this should never take longer than 30s
+ }
+ }
+ return;
+ }
+
+ private int getInventoryDepth(Resource root) {
+ if (root == null) {
+ return 0;
+ }
+ int maxDepth = 0;
+ for (Resource c : root.getChildResources()) {
+ int childDepth = getInventoryDepth(c);
+ if (maxDepth < childDepth) {
+ maxDepth = childDepth;
+ }
+ }
+ return maxDepth + 1;
+ }
+
+ private Answer<MergeInventoryReportResults> mergeInventoryReport() {
+ return new Answer<MergeInventoryReportResults>() {
+ @Override
+ public MergeInventoryReportResults answer(InvocationOnMock invocation) throws
Throwable {
+ InventoryReport inventoryReport = (InventoryReport)
invocation.getArguments()[0];
+ return simulateInventoryReportServerProcessing(inventoryReport);
+ }
+ };
+ }
+
+ private MergeInventoryReportResults
simulateInventoryReportServerProcessing(InventoryReport inventoryReport) {
+ ResourceSyncInfo syncInfo = null;
+ if (inventoryReport.getAddedRoots() != null &&
!inventoryReport.getAddedRoots().isEmpty()) {
+ for (Resource res : inventoryReport.getAddedRoots()) {
+ persistInSimulatedInventory(res);
+ }
+ syncInfo = ResourceSyncInfo.buildResourceSyncInfo(platform);
+ }
+ return new MergeInventoryReportResults(syncInfo, ignoredTypes);
+ }
+
+ private void persistInSimulatedInventory(Resource res) {
+ if (!ignoredTypes.contains(res.getResourceType())) {
+ if (!simulatedInventory.containsKey(res.getUuid())) {
+ Resource persisted = new Resource(res.getResourceKey(), res.getName(),
res.getResourceType());
+ persisted.setUuid(res.getUuid());
+ persisted.setInventoryStatus(InventoryStatus.COMMITTED);
+ simulatedInventory.put(persisted.getUuid(), persisted);
+ if (res.getParentResource() == Resource.ROOT) {
+ platform = persisted;
+ } else {
+ Resource parent =
simulatedInventory.get(res.getParentResource().getUuid());
+ parent.addChildResource(persisted);
+ }
+ }
+ for (Resource child : res.getChildResources()) {
+ persistInSimulatedInventory(child);
+ }
+ } else {
+ gotIgnoredTypeFromAgent.countDown();
+ }
+ return;
+ }
+
+ private void validateFullInventory() {
+ System.out.println("Validating full inventory...");
+
+ // get platform
+ Resource platform = pluginContainer.getInventoryManager().getPlatform();
+ Assert.assertNotNull(platform);
+ Assert.assertEquals(platform.getInventoryStatus(), InventoryStatus.COMMITTED);
+
+ // get top server
+ Assert.assertEquals(platform.getChildResources().size(), 1, "plat children:
" + platform.getChildResources());
+ Resource server = platform.getChildResources().iterator().next();
+ Assert.assertNotNull(server);
+ Assert.assertEquals(server.getInventoryStatus(), InventoryStatus.COMMITTED);
+
+ // get top server's immediate child service
+ Assert.assertEquals(server.getChildResources().size(), 1, "srv children:
" + server.getChildResources());
+ Resource service = server.getChildResources().iterator().next();
+ Assert.assertNotNull(service);
+ Assert.assertEquals(service.getInventoryStatus(), InventoryStatus.COMMITTED);
+
+ // get top server's grandchild service
+ Assert.assertEquals(service.getChildResources().size(), 1, "svc children:
" + service.getChildResources());
+ Resource grandchild = service.getChildResources().iterator().next();
+ Assert.assertNotNull(grandchild);
+ Assert.assertEquals(grandchild.getInventoryStatus(), InventoryStatus.COMMITTED);
+
+ // get top server's great-grandchild service
+ Assert.assertEquals(grandchild.getChildResources().size(), 1, "svc grandch:
" + grandchild.getChildResources());
+ Resource greatgrandchild = grandchild.getChildResources().iterator().next();
+ Assert.assertNotNull(greatgrandchild);
+ Assert.assertEquals(greatgrandchild.getInventoryStatus(),
InventoryStatus.COMMITTED);
+
+ assert greatgrandchild.getChildResources().isEmpty() : "great grandchild
should have no children";
+ }
+
+ private void validatePartiallyIgnoredInventory() {
+ System.out.println("Validating partially ignored inventory...");
+
+ // get platform
+ Resource platform = pluginContainer.getInventoryManager().getPlatform();
+ Assert.assertNotNull(platform);
+ Assert.assertEquals(platform.getInventoryStatus(), InventoryStatus.COMMITTED);
+
+ // get top server
+ Assert.assertEquals(platform.getChildResources().size(), 1, "plat children:
" + platform.getChildResources());
+ Resource server = platform.getChildResources().iterator().next();
+ Assert.assertNotNull(server);
+ Assert.assertEquals(server.getInventoryStatus(), InventoryStatus.COMMITTED);
+
+ // get top server's immediate child service
+ Assert.assertEquals(server.getChildResources().size(), 1, "srv children:
" + server.getChildResources());
+ Resource service = server.getChildResources().iterator().next();
+ Assert.assertNotNull(service);
+ Assert.assertEquals(service.getInventoryStatus(), InventoryStatus.COMMITTED);
+
+ // the grandchild service type is ignored, we should have no children from here
on down
+ assert service.getChildResources().isEmpty() : "grandchild should have been
ignored";
+ }
+}