/* * RHQ Management Platform * Copyright (C) 2005-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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ package org.rhq.enterprise.server.discovery; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.when; import static org.rhq.core.domain.resource.CreateResourceStatus.SUCCESS; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.sql.Connection; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Random; import java.util.UUID; import javax.ejb.EJBException; import javax.persistence.Query; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.dbunit.database.DatabaseConfig; import org.dbunit.database.DatabaseConnection; import org.dbunit.database.IDatabaseConnection; import org.dbunit.dataset.IDataSet; import org.dbunit.dataset.datatype.IDataTypeFactory; import org.dbunit.dataset.xml.FlatXmlDataSet; import org.dbunit.dataset.xml.FlatXmlProducer; import org.dbunit.ext.oracle.Oracle10DataTypeFactory; import org.dbunit.ext.oracle.OracleDataTypeFactory; import org.dbunit.ext.postgresql.PostgresqlDataTypeFactory; import org.dbunit.operation.DatabaseOperation; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.testng.annotations.Test; import org.xml.sax.InputSource; import org.rhq.core.clientapi.agent.discovery.DiscoveryAgentService; import org.rhq.core.clientapi.server.discovery.InventoryReport; import org.rhq.core.domain.cloud.StorageNode; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.criteria.ResourceCriteria; import org.rhq.core.domain.discovery.MergeInventoryReportResults; import org.rhq.core.domain.discovery.MergeInventoryReportResults.ResourceTypeFlyweight; import org.rhq.core.domain.discovery.MergeResourceResponse; import org.rhq.core.domain.discovery.PlatformSyncInfo; import org.rhq.core.domain.discovery.ResourceSyncInfo; import org.rhq.core.domain.resource.Agent; import org.rhq.core.domain.resource.CreateResourceHistory; 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.domain.util.PageControl; import org.rhq.core.domain.util.PageList; import org.rhq.core.domain.util.collection.ArrayUtils; import org.rhq.enterprise.server.auth.SubjectManagerLocal; import org.rhq.enterprise.server.resource.ResourceManagerLocal; import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal; import org.rhq.enterprise.server.test.AbstractEJB3Test; import org.rhq.enterprise.server.test.TestServerCommunicationsService; import org.rhq.enterprise.server.test.TransactionCallback; import org.rhq.enterprise.server.util.LookupUtil; import org.rhq.enterprise.server.util.ResourceTreeHelper; /** * A unit test for {@link DiscoveryBossBean}. */ public class DiscoveryBossBeanTest extends AbstractEJB3Test { private static final Log LOG = LogFactory.getLog(DiscoveryBossBeanTest.class); private DiscoveryBossLocal discoveryBoss; private SubjectManagerLocal subjectManager; private ResourceManagerLocal resourceManager; private ResourceTypeManagerLocal resourceTypeManager; private ResourceType platformType; private ResourceType serverType; private ResourceType serviceType1; private ResourceType serviceType2; private ResourceType storagePlatformType; private ResourceType storageServerType; private Agent agent; private TestServerCommunicationsService agentServiceContainer; @Override protected void beforeMethod() throws Exception { discoveryBoss = LookupUtil.getDiscoveryBoss(); subjectManager = LookupUtil.getSubjectManager(); resourceManager = LookupUtil.getResourceManager(); resourceTypeManager = LookupUtil.getResourceTypeManager(); initDB(); platformType = getEntityManager().find(ResourceType.class, 15641); serverType = getEntityManager().find(ResourceType.class, 15642); serviceType1 = getEntityManager().find(ResourceType.class, 15643); serviceType2 = getEntityManager().find(ResourceType.class, 15644); agent = getEntityManager().find(Agent.class, 15641); storagePlatformType = getEntityManager().find(ResourceType.class, 15651); storageServerType = getEntityManager().find(ResourceType.class, 15652); agentServiceContainer = prepareForTestAgents(); agentServiceContainer.discoveryService = Mockito.mock(DiscoveryAgentService.class); when( agentServiceContainer.discoveryService.manuallyAddResource(any(ResourceType.class), anyInt(), any(Configuration.class), anyInt())).thenAnswer(new Answer<MergeResourceResponse>() { public MergeResourceResponse answer(InvocationOnMock invocation) throws Throwable { Resource resource = new Resource(1000000); resource.setUuid(UUID.randomUUID().toString()); ResourceType resourceType = (ResourceType) invocation.getArguments()[0]; resource.setResourceType(resourceType); long randomLong = UUID.randomUUID().getLeastSignificantBits(); resource.setResourceKey(prefix("key-" + randomLong)); resource.setName(prefix("name-" + randomLong)); int parentResourceId = (Integer) invocation.getArguments()[1]; Resource parentResource = resourceManager.getResource(subjectManager.getOverlord(), parentResourceId); resource.setParentResource(parentResource); Integer ownerSubjectId = (Integer) invocation.getArguments()[3]; MergeResourceResponse response = discoveryBoss.addResource(resource, ownerSubjectId); return response; } }); prepareScheduler(); } @Override protected void afterMethod() throws Exception { try { cleanDB(); } finally { unprepareForTestAgents(); unprepareScheduler(); } } @Test(groups = "integration.ejb3") public void testBasicInventoryReport() throws Exception { InventoryReport inventoryReport = new InventoryReport(agent); Resource platform = new Resource(prefix("alpha"), prefix("platform"), platformType); Resource server = new Resource(prefix("bravo"), prefix("server"), serverType); platform.addChildResource(server); Resource service1 = new Resource(prefix("charlie"), prefix("service 1"), serviceType1); Resource service2 = new Resource(prefix("delta"), prefix("service 2"), serviceType2); server.addChildResource(service1); server.addChildResource(service2); platform.setUuid(String.valueOf(new Random().nextInt())); server.setUuid(String.valueOf(new Random().nextInt())); service1.setUuid(String.valueOf(new Random().nextInt())); service2.setUuid(String.valueOf(new Random().nextInt())); inventoryReport.addAddedRoot(platform); MergeInventoryReportResults results = discoveryBoss.mergeInventoryReport(serialize(inventoryReport)); assert results != null; assert checkIgnoredTypes(results) : "nothing should have been ignored in this test"; assertNotNull(results.getPlatformSyncInfo()); } @Test(groups = "integration.ejb3") public void testUpdateInventoryReport() throws Exception { // First just submit the platform InventoryReport inventoryReport = new InventoryReport(agent); Resource platform = new Resource(prefix("alpha"), prefix("platform"), platformType); platform.setUuid(String.valueOf(new Random().nextInt())); inventoryReport.addAddedRoot(platform); MergeInventoryReportResults results = discoveryBoss.mergeInventoryReport(serialize(inventoryReport)); assert results != null; assert checkIgnoredTypes(results) : "nothing should have been ignored in this test"; assertNotNull(results.getPlatformSyncInfo()); Collection<ResourceSyncInfo> syncInfos = discoveryBoss.getResourceSyncInfo(results.getPlatformSyncInfo() .getPlatform().getId()); assert syncInfos != null; assert !syncInfos.isEmpty(); platform.setId(results.getPlatformSyncInfo().getPlatform().getId()); // Now submit the server and its children as an update report inventoryReport = new InventoryReport(agent); Resource server = new Resource(prefix("bravo"), prefix("server"), serverType); platform.addChildResource(server); Resource service1 = new Resource(prefix("charlie"), prefix("service 1"), serviceType1); Resource service2 = new Resource(prefix("delta"), prefix("service 2"), serviceType2); server.addChildResource(service1); server.addChildResource(service2); server.setUuid(String.valueOf(new Random().nextInt())); service1.setUuid(String.valueOf(new Random().nextInt())); service2.setUuid(String.valueOf(new Random().nextInt())); inventoryReport.addAddedRoot(server); results = discoveryBoss.mergeInventoryReport(serialize(inventoryReport)); assert results != null; assert checkIgnoredTypes(results) : "nothing should have been ignored in this test"; assertNotNull(results.getPlatformSyncInfo()); } // given test interaction there could be ignored types, make sure they are not relevant to these tests private boolean checkIgnoredTypes(MergeInventoryReportResults results) { return checkIgnoredTypes(results, 0); } // given test interaction there could be ignored types, make sure they are not relevant to these tests private boolean checkIgnoredTypes(MergeInventoryReportResults results, int expectedNumberOfIgnoredTypes) { int numberOfRelevantIgnoredTypes = 0; Collection<ResourceTypeFlyweight> ignoredTypes = results.getIgnoredResourceTypes(); if (null != ignoredTypes) { if (ignoredTypes.contains(new ResourceTypeFlyweight(serverType))) { ++numberOfRelevantIgnoredTypes; } if (ignoredTypes.contains(new ResourceTypeFlyweight(serviceType1))) { ++numberOfRelevantIgnoredTypes; } if (ignoredTypes.contains(new ResourceTypeFlyweight(serviceType2))) { ++numberOfRelevantIgnoredTypes; } } return expectedNumberOfIgnoredTypes == numberOfRelevantIgnoredTypes; } @Test(groups = "integration.ejb3") public void testManuallyAddResource() throws Exception { InventoryReport inventoryReport = new InventoryReport(agent); Resource platform = new Resource(prefix("alpha"), prefix("platform"), platformType); Resource server = new Resource(prefix("bravo"), prefix("server"), serverType); platform.addChildResource(server); Resource service2 = new Resource(prefix("delta"), prefix("service 2"), serviceType2); server.addChildResource(service2); platform.setUuid(String.valueOf(new Random().nextInt())); server.setUuid(String.valueOf(new Random().nextInt())); service2.setUuid(String.valueOf(new Random().nextInt())); inventoryReport.addAddedRoot(platform); MergeInventoryReportResults results = discoveryBoss.mergeInventoryReport(serialize(inventoryReport)); assert results != null; assert checkIgnoredTypes(results) : "nothing should have been ignored in this test"; assertNotNull(results.getPlatformSyncInfo()); assertNotNull(results.getPlatformSyncInfo().getTopLevelServerIds()); assertTrue(!results.getPlatformSyncInfo().getTopLevelServerIds().isEmpty()); Integer resourceId = results.getPlatformSyncInfo().getTopLevelServerIds().iterator().next(); Collection<ResourceSyncInfo> syncInfos = discoveryBoss.getResourceSyncInfo(resourceId); assert syncInfos != null; assert !syncInfos.isEmpty(); Resource resource1 = discoveryBoss.manuallyAddResource(subjectManager.getOverlord(), serviceType2.getId(), resourceId, new Configuration()); try { Resource resource2 = discoveryBoss.manuallyAddResource(subjectManager.getOverlord(), serviceType2.getId(), resourceId, new Configuration()); fail("Manually adding a singleton that already existed succeeded: " + resource2); } catch (EJBException e) { assertEquals(String.valueOf(e.getCause()), RuntimeException.class, e.getCause().getClass()); assertTrue(String.valueOf(e.getCause()), e.getCause().getMessage().contains("singleton")); } } @Test(groups = "integration.ejb3") public void testIgnoreUnignoreAndImportResources() throws Exception { // First create an inventory report for a new platform with servers InventoryReport inventoryReport = new InventoryReport(agent); Resource platform = new Resource(prefix("platform"), prefix("platform"), platformType); platform.setUuid(String.valueOf(new Random().nextInt())); for (int i = 0; i < 17; i++) { String serverString = prefix("server " + String.valueOf(i)); Resource server = new Resource(serverString, serverString, serverType); server.setUuid(String.valueOf(new Random().nextInt())); platform.addChildResource(server); } inventoryReport.addAddedRoot(platform); // Merge this inventory report MergeInventoryReportResults mergeResults = discoveryBoss.mergeInventoryReport(serialize(inventoryReport)); assert mergeResults != null; assert checkIgnoredTypes(mergeResults) : "nothing should have been ignored: " + mergeResults.getIgnoredResourceTypes(); PlatformSyncInfo platformSyncInfo = mergeResults.getPlatformSyncInfo(); assert platformSyncInfo != null; // Check merge result assertEquals(InventoryStatus.NEW, platformSyncInfo.getPlatform().getInventoryStatus()); assertEquals(platform.getChildResources().size(), platformSyncInfo.getTopLevelServerIds().size()); // Collect the resource ids generated for the platform and the servers int platformId = platformSyncInfo.getPlatform().getId(); List<Integer> serverIds = new LinkedList<Integer>(); for (Integer serverId : platformSyncInfo.getTopLevelServerIds()) { serverIds.add(serverId); } int[] arrayOfServerIds = ArrayUtils.unwrapCollection(serverIds); // Now test ignore, unignore and import behavior discoveryBoss.importResources(subjectManager.getOverlord(), new int[] { platformId }); discoveryBoss.ignoreResources(subjectManager.getOverlord(), arrayOfServerIds); try { discoveryBoss.importResources(subjectManager.getOverlord(), arrayOfServerIds); fail("Import resources should fail for ignored resources"); } catch (EJBException e) { assertEquals(String.valueOf(e.getCause()), IllegalArgumentException.class, e.getCause().getClass()); assertTrue(String.valueOf(e.getCause()), e.getCause().getMessage().startsWith("Can only set inventory status to")); } discoveryBoss.unignoreAndImportResources(subjectManager.getOverlord(), arrayOfServerIds); // excursus: take this time to do a side test of the resource criteria filtering on parent inv status List<InventoryStatus> committedStatus = new ArrayList<InventoryStatus>(1); List<InventoryStatus> ignoredStatus = new ArrayList<InventoryStatus>(1); committedStatus.add(InventoryStatus.COMMITTED); ignoredStatus.add(InventoryStatus.IGNORED); ResourceCriteria criteria = new ResourceCriteria(); criteria.addFilterParentInventoryStatuses(committedStatus); criteria.addFilterId(serverIds.get(0)); // excursus: look for the server with the given ID but only if the parent is committed (this should return the resource) List<Resource> lookup = resourceManager.findResourcesByCriteria(subjectManager.getOverlord(), criteria); assert 1 == lookup.size() : lookup; assert lookup.get(0).getId() == serverIds.get(0) : lookup; // excursus: look for the server with the given ID but only if the parent is ignored (this should return nothing) criteria.addFilterParentInventoryStatuses(ignoredStatus); lookup = resourceManager.findResourcesByCriteria(subjectManager.getOverlord(), criteria); assert lookup.isEmpty() : lookup; } @Test(groups = "integration.ejb3") public void testIgnoreResourceType() throws Exception { // ignore the server type immediately resourceTypeManager.setResourceTypeIgnoreFlagAndUninventoryResources(subjectManager.getOverlord(), serverType.getId(), true); // create an inventory report with a platform and a server - the server will be of the ignored type InventoryReport inventoryReport = new InventoryReport(agent); Resource platform = new Resource(prefix("platform"), prefix("platform"), platformType); platform.setUuid(String.valueOf(new Random().nextInt())); Resource server = new Resource(prefix("server0"), prefix("server0"), serverType); server.setUuid(String.valueOf(new Random().nextInt())); platform.addChildResource(server); inventoryReport.addAddedRoot(platform); // Merge this inventory report MergeInventoryReportResults mergeResults = discoveryBoss.mergeInventoryReport(serialize(inventoryReport)); assert mergeResults != null; PlatformSyncInfo platformSyncInfo = mergeResults.getPlatformSyncInfo(); assert platformSyncInfo != null; assertNotNull(mergeResults.getIgnoredResourceTypes()); assert checkIgnoredTypes(mergeResults, 1) : "expected one ignored type"; assert mergeResults.getIgnoredResourceTypes().contains(new ResourceTypeFlyweight(serverType)); // Check merge result - make sure we should not see any children under the platform (it should have been ignored) assertEquals(InventoryStatus.NEW, platformSyncInfo.getPlatform().getInventoryStatus()); assertEquals(platformSyncInfo.getTopLevelServerIds().size(), 0); } @Test(groups = "integration.ejb3") public void testReturnAllIgnoredResourceTypes() throws Exception { // ignore the service types immediately resourceTypeManager.setResourceTypeIgnoreFlagAndUninventoryResources(subjectManager.getOverlord(), serviceType1.getId(), true); resourceTypeManager.setResourceTypeIgnoreFlagAndUninventoryResources(subjectManager.getOverlord(), serviceType2.getId(), true); // create an inventory report with just a platform and a server InventoryReport inventoryReport = new InventoryReport(agent); Resource platform = new Resource(prefix("platform"), prefix("platform"), platformType); platform.setUuid(String.valueOf(new Random().nextInt())); Resource server = new Resource(prefix("server0"), prefix("server0"), serverType); server.setUuid(String.valueOf(new Random().nextInt())); platform.addChildResource(server); inventoryReport.addAddedRoot(platform); // Merge this inventory report MergeInventoryReportResults mergeResults = discoveryBoss.mergeInventoryReport(serialize(inventoryReport)); assert mergeResults != null; PlatformSyncInfo platformSyncInfo = mergeResults.getPlatformSyncInfo(); assert platformSyncInfo != null; // now see that we were told about the service types being ignored (even though we had no resources of that type in the report) Collection<ResourceTypeFlyweight> ignoredResourceTypes = mergeResults.getIgnoredResourceTypes(); assertNotNull(ignoredResourceTypes); assert checkIgnoredTypes(mergeResults, 2) : "expected two ignored types"; assert ignoredResourceTypes.contains(new ResourceTypeFlyweight(serviceType1)); assert ignoredResourceTypes.contains(new ResourceTypeFlyweight(serviceType2)); } @Test(groups = "integration.ejb3") public void testIgnoreResourceTypeAndUninventoryResources() throws Exception { // First create an inventory report for a new platform with servers - nothing is ignored yet InventoryReport inventoryReport = new InventoryReport(agent); Resource platform = new Resource(prefix("platform"), prefix("platform"), platformType); platform.setUuid(String.valueOf(new Random().nextInt())); for (int i = 0; i < 17; i++) { String serverString = prefix("server " + String.valueOf(i)); Resource server = new Resource(serverString, serverString, serverType); server.setUuid(String.valueOf(new Random().nextInt())); platform.addChildResource(server); } inventoryReport.addAddedRoot(platform); // Merge this inventory report to get platform and servers in NEW state MergeInventoryReportResults mergeResults = discoveryBoss.mergeInventoryReport(serialize(inventoryReport)); assert mergeResults != null; assert checkIgnoredTypes(mergeResults) : "nothing should have been ignored: " + mergeResults.getIgnoredResourceTypes(); PlatformSyncInfo platformSyncInfo = mergeResults.getPlatformSyncInfo(); assert platformSyncInfo != null; // Collect the resource ids generated for the platform and the servers int platformId = platformSyncInfo.getPlatform().getId(); List<Integer> serverIds = new LinkedList<Integer>(); for (Integer serverId : platformSyncInfo.getTopLevelServerIds()) { serverIds.add(serverId); } int[] arrayOfServerIds = ArrayUtils.unwrapCollection(serverIds); // Now import platform and servers into inventory discoveryBoss.importResources(subjectManager.getOverlord(), new int[] { platformId }); discoveryBoss.importResources(subjectManager.getOverlord(), arrayOfServerIds); // make sure servers are committed into inventory now List<Integer> serverTypeIdInList = new ArrayList<Integer>(1); serverTypeIdInList.add(serverType.getId()); PageList<Resource> allServers = resourceManager.findResourceByIds(subjectManager.getOverlord(), arrayOfServerIds, false, PageControl.getUnlimitedInstance()); for (Resource aServer : allServers) { assert aServer.getInventoryStatus() == InventoryStatus.COMMITTED : "should be committed: " + aServer; } assert allServers.getTotalSize() == arrayOfServerIds.length : "all servers were not committed into inventory"; // now ignore the server type - this should uninventory all servers resourceTypeManager.setResourceTypeIgnoreFlagAndUninventoryResources(subjectManager.getOverlord(), serverType.getId(), true); // make sure all servers were uninventoried allServers = resourceManager.findResourceByIds(subjectManager.getOverlord(), arrayOfServerIds, false, PageControl.getUnlimitedInstance()); for (Resource aServer : allServers) { assert aServer.getInventoryStatus() != InventoryStatus.COMMITTED : "should not be committed: " + aServer; } // Merge the inventory report again to simulate another discovery - the servers should be ignored now mergeResults = discoveryBoss.mergeInventoryReport(serialize(inventoryReport)); assert mergeResults != null; platformSyncInfo = mergeResults.getPlatformSyncInfo(); assert platformSyncInfo != null; assertNotNull(mergeResults.getIgnoredResourceTypes()); assert checkIgnoredTypes(mergeResults, 1) : "expected one ignored type"; assert mergeResults.getIgnoredResourceTypes().contains(new ResourceTypeFlyweight(serverType)); assertEquals(InventoryStatus.COMMITTED, platformSyncInfo.getPlatform().getInventoryStatus()); // notice platform is committed now assertEquals(platformSyncInfo.getTopLevelServerIds().size(), 0); // notice there are no server children now } @Test(groups = "integration.ejb3") public void testAutoImportStorageNode() throws Exception { // create an inventory report for a storage node InventoryReport inventoryReport = new InventoryReport(agent); Resource storagePlatform = new Resource(prefix("storagePlatform"), prefix("storagePlatform"), storagePlatformType); storagePlatform.setUuid(String.valueOf(new Random().nextInt())); Resource storageNode = new Resource(prefix("storageNode"), prefix("storageNode"), storageServerType); storageNode.setUuid(String.valueOf(new Random().nextInt())); storagePlatform.addChildResource(storageNode); storageNode.setPluginConfiguration(Configuration.builder().addSimple("nativeTransportPort", 9142) .addSimple("storagePort", 7100).addSimple("host", "localhost").build()); inventoryReport.addAddedRoot(storagePlatform); // Merge this inventory report MergeInventoryReportResults mergeResults = discoveryBoss.mergeInventoryReport(serialize(inventoryReport)); assert mergeResults != null; assert checkIgnoredTypes(mergeResults) : "nothing should have been ignored: " + mergeResults.getIgnoredResourceTypes(); PlatformSyncInfo platformSyncInfo = mergeResults.getPlatformSyncInfo(); assert platformSyncInfo != null; // Check merge result assertEquals(InventoryStatus.COMMITTED, platformSyncInfo.getPlatform().getInventoryStatus()); assertEquals(storagePlatform.getChildResources().size(), platformSyncInfo.getTopLevelServerIds().size()); storageNode = resourceManager.getResourceById(subjectManager.getOverlord(), platformSyncInfo .getTopLevelServerIds().iterator().next()); assertNotNull(storageNode); assertEquals(InventoryStatus.COMMITTED, storageNode.getInventoryStatus()); } @Test(groups = "integration.ejb3") public void testPersistUserSuppliedResourceNameOnCreatedResource() throws Exception { // First inventory the platform and the server InventoryReport inventoryReport = new InventoryReport(agent); Resource platform = new Resource(prefix("userPlatform"), prefix("platform"), platformType); platform.setUuid(String.valueOf(new Random().nextInt())); Resource server = new Resource(prefix("userServer"), prefix("server"), serverType); server.setUuid(String.valueOf(new Random().nextInt())); platform.addChildResource(server); inventoryReport.addAddedRoot(platform); MergeInventoryReportResults results = discoveryBoss.mergeInventoryReport(serialize(inventoryReport)); assertNotNull(results); assert checkIgnoredTypes(results) : "nothing should have been ignored in this test " + results.getIgnoredResourceTypes(); final PlatformSyncInfo firstDiscoverySyncInfo = results.getPlatformSyncInfo(); assertNotNull(firstDiscoverySyncInfo); // Then simulate a create resource request final String userSuppliedResourceName = prefix("User Supplied Resource Name"); final String newResourceKey = prefix("Created Resource Key"); final int serverResourceId = firstDiscoverySyncInfo.getTopLevelServerIds().iterator().next(); executeInTransaction(false, new TransactionCallback() { @Override public void execute() throws Exception { Resource serverResource = getEntityManager().find(Resource.class, serverResourceId); CreateResourceHistory createResourceHistory = new CreateResourceHistory(serverResource, serviceType1, subjectManager.getOverlord().getName(), new Configuration()); createResourceHistory.setCreatedResourceName(userSuppliedResourceName); createResourceHistory.setNewResourceKey(newResourceKey); createResourceHistory.setStatus(SUCCESS); getEntityManager().persist(createResourceHistory); serverResource.addCreateChildResourceHistory(createResourceHistory); getEntityManager().flush(); } }); // Eventually inventory the newly discovered service inventoryReport = new InventoryReport(agent); Resource service1 = new Resource(newResourceKey, prefix("Plugin Computed Resource Name"), serviceType1); service1.setUuid(String.valueOf(new Random().nextInt())); server.setId(serverResourceId); server.addChildResource(service1); inventoryReport.addAddedRoot(server); results = discoveryBoss.mergeInventoryReport(serialize(inventoryReport)); assertNotNull(results); assert checkIgnoredTypes(results) : "nothing should have been ignored in this test " + results.getIgnoredResourceTypes(); PlatformSyncInfo secondDiscoverySyncInfo = results.getPlatformSyncInfo(); assertNotNull(secondDiscoverySyncInfo); // Check that the resource ends with the user supplied name in inventory Integer toplevelServerId = secondDiscoverySyncInfo.getTopLevelServerIds().iterator().next(); Collection<ResourceSyncInfo> topLevelServerSyncInfo = discoveryBoss.getResourceSyncInfo(toplevelServerId); assert topLevelServerSyncInfo.size() == 2; Iterator<ResourceSyncInfo> iter = topLevelServerSyncInfo.iterator(); Integer childId = iter.next().getId(); childId = childId.equals(toplevelServerId) ? iter.next().getId() : childId; Resource service1Resource = getEntityManager().find(Resource.class, childId); assertEquals(userSuppliedResourceName, service1Resource.getName()); } /** * Use this to fake like your remoting objects. Can be used to keep your own copy of objects locally transient. * * @param object * @return */ @SuppressWarnings("unchecked") private static <T> T serialize(T object) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(10000); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(object); if (LOG.isDebugEnabled()) { LOG.debug("****** Size of serialized object: " + baos.size()); } ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray())); Object transfered = ois.readObject(); return (T) transfered; } catch (Exception e) { throw new RuntimeException("Failed serializing and deserializing object: " + object); } } public void initDB() throws Exception { Connection connection = null; try { connection = getConnection(); IDatabaseConnection dbUnitConnection = new DatabaseConnection(connection); setDbType(dbUnitConnection); DatabaseOperation.REFRESH.execute(dbUnitConnection, getDataSet()); } finally { if (connection != null) { connection.close(); } } } public void cleanDB() throws Exception { Connection connection = null; try { getTransactionManager().begin(); Query q; List<?> doomed; q = em.createQuery("" // + "SELECT r FROM Resource r" // + " WHERE r.resourceType.name LIKE '" + getPrefix() + "%'" // + " OR r.resourceType.name = 'RHQ Storage Node'" // + " ORDER BY r.id DESC"); doomed = q.getResultList(); for (Object removeMe : doomed) { Resource res = em.getReference(Resource.class, ((Resource) removeMe).getId()); StorageNode storageNode = findStorageNode(res); if (storageNode != null) { storageNode.setResource(null); } for (Iterator<CreateResourceHistory> historyIterator = res.getCreateChildResourceRequests().iterator(); historyIterator .hasNext();) { CreateResourceHistory history = historyIterator.next(); historyIterator.remove(); em.remove(history); } if (LOG.isDebugEnabled()) { LOG.debug("Deleting resource " + res); } ResourceTreeHelper.deleteResource(em, res); } em.flush(); getTransactionManager().commit(); } catch (Exception e) { try { LOG.error("CANNOT CLEAN UP TEST: Cause: " + e); getTransactionManager().rollback(); } catch (Exception ignore) { } } try { connection = getConnection(); IDatabaseConnection dbUnitConnection = new DatabaseConnection(connection); setDbType(dbUnitConnection); DatabaseOperation.DELETE.execute(dbUnitConnection, getDataSet()); } finally { if (connection != null) { connection.close(); } } } private StorageNode findStorageNode(Resource resource) { List<StorageNode> storageNodes = em .createQuery("SELECT s FROM StorageNode s where s.resource = :resource", StorageNode.class) .setParameter("resource", resource).getResultList(); if (storageNodes.isEmpty()) { return null; } return storageNodes.get(0); } void setDbType(IDatabaseConnection connection) throws Exception { DatabaseConfig dbConfig = connection.getConfig(); String name = connection.getConnection().getMetaData().getDatabaseProductName().toLowerCase(); int major = connection.getConnection().getMetaData().getDatabaseMajorVersion(); IDataTypeFactory type = null; if (name.contains("postgres")) { type = new PostgresqlDataTypeFactory(); } else if (name.contains("oracle")) { if (major >= 10) { type = new Oracle10DataTypeFactory(); } else { type = new OracleDataTypeFactory(); } } if (type != null) { dbConfig.setProperty("http://www.dbunit.org/properties/datatypeFactory", type); } } IDataSet getDataSet() throws Exception { FlatXmlProducer xmlProducer = new FlatXmlProducer(new InputSource(getClass().getResourceAsStream( getDataSetFile()))); xmlProducer.setColumnSensing(true); return new FlatXmlDataSet(xmlProducer); } String getDataSetFile() { return getPrefix() + ".xml"; } String prefix(String suffix) { return getPrefix() + "-" + suffix; } String getPrefix() { return getClass().getSimpleName(); } }