modules/core/arquillian-integration/container/src/main/java/org/rhq/test/arquillian/FakeServerInventory.java | 19
modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/inventory/DiscoveryTest.java | 221 ++++++++++
modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/inventory/testplugin/ManualAddDiscoveryComponent.java | 34 +
modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/inventory/testplugin/TestResourceComponent.java | 103 ++++
modules/core/plugin-container-itest/src/test/resources/test-great-grandchild-discovery-plugin.xml | 60 ++
modules/core/plugin-container/src/main/java/org/rhq/core/pc/availability/AvailabilityContextImpl.java | 7
modules/core/plugin-container/src/main/java/org/rhq/core/pc/event/EventContextImpl.java | 7
modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java | 23 -
8 files changed, 461 insertions(+), 13 deletions(-)
New commits:
commit bf517b9d9a0f31ae370e7c8b952c45083d054866
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Tue Jul 31 10:19:23 2012 -0500
[BZ 832090] - adding an integration test for checking that all the PC
subsystems obtain the synced resource after manual add.
(cherry picked from commit ac7fe40163f22ed7b634d1ec8138fb0182e1617d)
Conflicts:
modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/inventory/DiscoveryTest.java
modules/core/plugin-container-itest/src/test/resources/test-great-grandchild-discovery-plugin.xml
diff --git a/modules/core/arquillian-integration/container/src/main/java/org/rhq/test/arquillian/FakeServerInventory.java b/modules/core/arquillian-integration/container/src/main/java/org/rhq/test/arquillian/FakeServerInventory.java
index 0b7b043..37e4ff2 100644
--- a/modules/core/arquillian-integration/container/src/main/java/org/rhq/test/arquillian/FakeServerInventory.java
+++ b/modules/core/arquillian-integration/container/src/main/java/org/rhq/test/arquillian/FakeServerInventory.java
@@ -41,6 +41,7 @@ import org.mockito.stubbing.Answer;
import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeResponse;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.domain.discovery.MergeResourceResponse;
import org.rhq.core.domain.discovery.ResourceSyncInfo;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
@@ -186,6 +187,24 @@ public class FakeServerInventory {
return discoveryChecker;
}
+ public synchronized Answer<MergeResourceResponse> addResource() {
+ return new Answer<MergeResourceResponse>() {
+ @Override
+ public MergeResourceResponse answer(InvocationOnMock invocation) throws Throwable {
+ Resource r = (Resource) invocation.getArguments()[0];
+ int subjectId = (Integer) invocation.getArguments()[1];
+
+ LOG.debug("A request to add a resource [" + r + "] made by subject with id " + subjectId);
+
+ boolean exists = getResourceStore().containsKey(r.getUuid());
+
+ r = fakePersist(r, InventoryStatus.COMMITTED, new HashSet<String>());
+
+ return new MergeResourceResponse(r.getId(), exists);
+ }
+ };
+ }
+
public synchronized Answer<ResourceSyncInfo> mergeInventoryReport(final InventoryStatus requiredInventoryStatus) {
return new Answer<ResourceSyncInfo>() {
@Override
diff --git a/modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/inventory/DiscoveryTest.java b/modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/inventory/DiscoveryTest.java
new file mode 100644
index 0000000..8880b92
--- /dev/null
+++ b/modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/inventory/DiscoveryTest.java
@@ -0,0 +1,221 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2012 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.Matchers.anyInt;
+import static org.mockito.Mockito.when;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.mockito.Mockito;
+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.configuration.Configuration;
+import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.domain.discovery.MergeResourceResponse;
+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.availability.AvailabilityContextImpl;
+import org.rhq.core.pc.content.ContentContextImpl;
+import org.rhq.core.pc.event.EventContextImpl;
+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.core.pc.operation.OperationContextImpl;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
+import org.rhq.test.arquillian.AfterDiscovery;
+import org.rhq.test.arquillian.BeforeDiscovery;
+import org.rhq.test.arquillian.FakeServerInventory;
+import org.rhq.test.arquillian.MockingServerServices;
+import org.rhq.test.arquillian.RunDiscovery;
+import org.rhq.test.shrinkwrap.RhqAgentPluginArchive;
+
+/**
+ * A unit test for testing discovery.
+ */
+public class DiscoveryTest 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 FakeServerInventory fakeServerInventory;
+
+ private FakeServerInventory.CompleteDiscoveryChecker discoveryCompleteChecker;
+
+ @BeforeDiscovery
+ public void resetServerServices() throws Exception {
+ // Set up our fake server discovery ServerService, which will auto-import all Resources in reports it receives.
+ serverServices.resetMocks();
+ fakeServerInventory = new FakeServerInventory();
+ discoveryCompleteChecker = fakeServerInventory.createAsyncDiscoveryCompletionChecker(4);
+ when(serverServices.getDiscoveryServerService().mergeInventoryReport(any(InventoryReport.class))).then(
+ fakeServerInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+ }
+
+ @AfterDiscovery
+ public void waitForAsyncDiscoveries() throws Exception {
+ if (discoveryCompleteChecker != null) {
+ discoveryCompleteChecker.waitForDiscoveryComplete(10000);
+ }
+ }
+
+ /**
+ * Tests that discovery was only run once per ResourceType. This tests a deep, 4-level hierarchy.
+ *
+ * @throws Exception if an error occurs
+ */
+ @RunDiscovery
+ @Test(groups = "pc.itest.discovery", priority = 10)
+ public void testDiscoveryRunsOnlyOncePerType() throws Exception {
+ // make sure our inventory is as we expect it to be
+ validatePluginContainerInventory();
+
+ // reset our discovery component's internal storage
+ TestResourceDiscoveryComponent.getExecutionCountsByResourceType().clear();
+
+ // run our own discovery scan
+ this.pluginContainer.getInventoryManager().executeServiceScanImmediately();
+
+ Map<ResourceType, Integer> executionCountsByResourceType = TestResourceDiscoveryComponent
+ .getExecutionCountsByResourceType();
+ Map<ResourceType, Integer> flaggedExecutionCountsByResourceType = new HashMap<ResourceType, Integer>();
+ for (ResourceType resourceType : executionCountsByResourceType.keySet()) {
+ Integer count = executionCountsByResourceType.get(resourceType);
+ if (count != 1) {
+ flaggedExecutionCountsByResourceType.put(resourceType, count);
+ }
+ }
+ Assert.assertTrue(flaggedExecutionCountsByResourceType.isEmpty(),
+ "Discovery was not executed once (and only once) for the following types: "
+ + flaggedExecutionCountsByResourceType);
+ }
+
+ @Test(groups = "pc.itest.discovery", priority = 10)
+ public void testResourceSyncedWithServerAfterManualAdd() throws Exception {
+ Mockito.when(serverServices.getDiscoveryServerService().addResource(any(Resource.class), anyInt())).then(
+ fakeServerInventory.addResource());
+
+ InventoryManager inventoryManager = pluginContainer.getInventoryManager();
+
+ Resource platform = inventoryManager.getPlatform();
+
+ Configuration myPluginConfig = new Configuration();
+ myPluginConfig.put(new PropertySimple("test", "value"));
+
+ ResourceType resourceType = pluginContainer.getPluginManager().getMetadataManager()
+ .getType("Manual Add Server", "test");
+
+ MergeResourceResponse response = inventoryManager.manuallyAddResource(resourceType, platform.getId(),
+ myPluginConfig, -1);
+
+ assertFalse(response.resourceAlreadyExisted(), "The manual add resource shouldn't have existed");
+ assertNotEquals(response.getResourceId(), 0, "The manual add resource should have had its resource id set");
+
+ ResourceContainer resourceContainer = inventoryManager.getResourceContainer(response.getResourceId());
+ ResourceContext<?> resourceContext = resourceContainer.getResourceContext();
+
+ assertEquals(resourceContext.getPluginConfiguration(), myPluginConfig,
+ "The manual add resource doesn't have the expected plugin config.");
+
+ assertTrue(resourceContext.getAvailabilityContext() instanceof AvailabilityContextImpl,
+ "Unexpected implementation clas of the AvailabilityContext, please fix this test.");
+ assertEquals(((AvailabilityContextImpl) resourceContext.getAvailabilityContext()).getResource().getId(),
+ response.getResourceId(),
+ "Availability subsystem isn't aware of the correct resource id for manual add resource");
+
+ assertTrue(resourceContext.getContentContext() instanceof ContentContextImpl,
+ "Unexpected implementation class of ContentContext, please fix this test");
+ assertEquals(((ContentContextImpl) resourceContext.getContentContext()).getResourceId(),
+ response.getResourceId(),
+ "Content subsystem isn't aware of the correct resource id for manual add resource");
+
+ assertTrue(resourceContext.getEventContext() instanceof EventContextImpl,
+ "Unexpected implementation clas of the EventContext, please fix this test.");
+ assertEquals(((EventContextImpl) resourceContext.getEventContext()).getResource().getId(),
+ response.getResourceId(), "Event subsystem isn't aware of the correct resource id for manual add resource");
+
+ assertTrue(resourceContext.getOperationContext() instanceof OperationContextImpl,
+ "Unexpected implementation clas of the OperationContext, please fix this test.");
+ assertEquals(((OperationContextImpl) resourceContext.getOperationContext()).getResourceId(),
+ response.getResourceId(),
+ "Operation subsystem isn't aware of the correct resource id for manual add resource");
+ }
+
+ private void validatePluginContainerInventory() throws Exception {
+ System.out.println("Validating PC inventory...");
+
+ Resource platform = pluginContainer.getInventoryManager().getPlatform();
+ Assert.assertNotNull(platform);
+ Assert.assertEquals(platform.getInventoryStatus(), InventoryStatus.COMMITTED);
+
+ Resource server = platform.getChildResources().iterator().next();
+ Assert.assertNotNull(server);
+ Assert.assertEquals(server.getInventoryStatus(), InventoryStatus.COMMITTED);
+ assert server.getResourceType().getName().equals("Test Server");
+
+ Resource child = server.getChildResources().iterator().next();
+ Assert.assertNotNull(child);
+ Assert.assertEquals(child.getInventoryStatus(), InventoryStatus.COMMITTED);
+ assert child.getResourceType().getName().equals("Test Service Child");
+
+ Resource grandchild = child.getChildResources().iterator().next();
+ Assert.assertNotNull(grandchild);
+ Assert.assertEquals(grandchild.getInventoryStatus(), InventoryStatus.COMMITTED);
+ assert grandchild.getResourceType().getName().equals("Test Service GrandChild");
+
+ Resource greatgrandchild = grandchild.getChildResources().iterator().next();
+ Assert.assertNotNull(greatgrandchild);
+ Assert.assertEquals(greatgrandchild.getInventoryStatus(), InventoryStatus.COMMITTED);
+ assert greatgrandchild.getResourceType().getName().equals("Test Service GreatGrandChild");
+
+ System.out.println("PC inventory validated successfully!");
+ }
+
+}
diff --git a/modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/inventory/testplugin/ManualAddDiscoveryComponent.java b/modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/inventory/testplugin/ManualAddDiscoveryComponent.java
new file mode 100644
index 0000000..95701b2
--- /dev/null
+++ b/modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/inventory/testplugin/ManualAddDiscoveryComponent.java
@@ -0,0 +1,34 @@
+package org.rhq.core.pc.inventory.testplugin;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ManualAddFacet;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+
+public class ManualAddDiscoveryComponent implements ResourceDiscoveryComponent<ResourceComponent<?>>,
+ ManualAddFacet<ResourceComponent<?>> {
+
+ @Override
+ public DiscoveredResourceDetails discoverResource(Configuration pluginConfiguration,
+ ResourceDiscoveryContext<ResourceComponent<?>> context) throws InvalidPluginConfigurationException {
+
+ ResourceType resourceType = context.getResourceType();
+
+ return new DiscoveredResourceDetails(resourceType, "SINGLETON", resourceType.getName(), "1.0",
+ resourceType.getDescription(), pluginConfiguration, null);
+ }
+
+ @Override
+ public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext<ResourceComponent<?>> context)
+ throws InvalidPluginConfigurationException, Exception {
+ return Collections.emptySet();
+ }
+
+}
diff --git a/modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/inventory/testplugin/TestResourceComponent.java b/modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/inventory/testplugin/TestResourceComponent.java
index d56d598..20ccf76 100644
--- a/modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/inventory/testplugin/TestResourceComponent.java
+++ b/modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/inventory/testplugin/TestResourceComponent.java
@@ -18,15 +18,49 @@
*/
package org.rhq.core.pc.inventory.testplugin;
+import java.io.InputStream;
+import java.util.List;
+import java.util.Set;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.content.PackageType;
+import org.rhq.core.domain.content.transfer.DeployPackageStep;
+import org.rhq.core.domain.content.transfer.DeployPackagesResponse;
+import org.rhq.core.domain.content.transfer.RemovePackagesResponse;
+import org.rhq.core.domain.content.transfer.ResourcePackageDetails;
import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.domain.measurement.MeasurementReport;
+import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
+import org.rhq.core.pluginapi.bundle.BundleDeployRequest;
+import org.rhq.core.pluginapi.bundle.BundleDeployResult;
+import org.rhq.core.pluginapi.bundle.BundleFacet;
+import org.rhq.core.pluginapi.bundle.BundlePurgeRequest;
+import org.rhq.core.pluginapi.bundle.BundlePurgeResult;
+import org.rhq.core.pluginapi.configuration.ConfigurationFacet;
+import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport;
+import org.rhq.core.pluginapi.content.ContentFacet;
+import org.rhq.core.pluginapi.content.ContentServices;
+import org.rhq.core.pluginapi.inventory.CreateChildResourceFacet;
+import org.rhq.core.pluginapi.inventory.CreateResourceReport;
+import org.rhq.core.pluginapi.inventory.DeleteResourceFacet;
import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
import org.rhq.core.pluginapi.inventory.ResourceComponent;
import org.rhq.core.pluginapi.inventory.ResourceContext;
+import org.rhq.core.pluginapi.measurement.MeasurementFacet;
+import org.rhq.core.pluginapi.operation.OperationFacet;
+import org.rhq.core.pluginapi.operation.OperationResult;
+import org.rhq.core.pluginapi.support.SnapshotReportRequest;
+import org.rhq.core.pluginapi.support.SnapshotReportResults;
+import org.rhq.core.pluginapi.support.SupportFacet;
/**
+ * This resource component implements most (all?) of the facets so that all the plugin container subsystems can work
+ * with it.
+ *
* @author Ian Springer
*/
-public class TestResourceComponent implements ResourceComponent<ResourceComponent<?>> {
+public class TestResourceComponent implements ResourceComponent<ResourceComponent<?>>, OperationFacet, ContentFacet,
+ ConfigurationFacet, MeasurementFacet, DeleteResourceFacet, CreateChildResourceFacet, BundleFacet, SupportFacet {
private ResourceContext<ResourceComponent<?>> resourceContext;
@@ -46,4 +80,71 @@ public class TestResourceComponent implements ResourceComponent<ResourceComponen
return;
}
+ @Override
+ public SnapshotReportResults getSnapshotReport(SnapshotReportRequest request) throws Exception {
+ return null;
+ }
+
+ @Override
+ public BundleDeployResult deployBundle(BundleDeployRequest request) {
+ return null;
+ }
+
+ @Override
+ public BundlePurgeResult purgeBundle(BundlePurgeRequest request) {
+ return null;
+ }
+
+ @Override
+ public CreateResourceReport createResource(CreateResourceReport report) {
+ return null;
+ }
+
+ @Override
+ public void deleteResource() throws Exception {
+ }
+
+ @Override
+ public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> metrics) throws Exception {
+ }
+
+ @Override
+ public Configuration loadResourceConfiguration() throws Exception {
+ return null;
+ }
+
+ @Override
+ public void updateResourceConfiguration(ConfigurationUpdateReport report) {
+ }
+
+ @Override
+ public List<DeployPackageStep> generateInstallationSteps(ResourcePackageDetails packageDetails) {
+ return null;
+ }
+
+ @Override
+ public DeployPackagesResponse deployPackages(Set<ResourcePackageDetails> packages, ContentServices contentServices) {
+ return null;
+ }
+
+ @Override
+ public RemovePackagesResponse removePackages(Set<ResourcePackageDetails> packages) {
+ return null;
+ }
+
+ @Override
+ public Set<ResourcePackageDetails> discoverDeployedPackages(PackageType type) {
+ return null;
+ }
+
+ @Override
+ public InputStream retrievePackageBits(ResourcePackageDetails packageDetails) {
+ return null;
+ }
+
+ @Override
+ public OperationResult invokeOperation(String name, Configuration parameters) throws InterruptedException,
+ Exception {
+ return null;
+ }
}
diff --git a/modules/core/plugin-container-itest/src/test/resources/test-great-grandchild-discovery-plugin.xml b/modules/core/plugin-container-itest/src/test/resources/test-great-grandchild-discovery-plugin.xml
new file mode 100644
index 0000000..a1e222a
--- /dev/null
+++ b/modules/core/plugin-container-itest/src/test/resources/test-great-grandchild-discovery-plugin.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="test"
+ displayName="Test"
+ description="a test plugin"
+ package="org.rhq.core.pc.inventory.testplugin"
+ version="1.0"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <server name="Test Server"
+ discovery="TestResourceDiscoveryComponent"
+ class="TestResourceComponent">
+
+ <service name="Test Service Child"
+ discovery="TestResourceDiscoveryComponent"
+ class="TestResourceComponent">
+
+ <service name="Test Service GrandChild"
+ discovery="TestResourceDiscoveryComponent"
+ class="TestResourceComponent">
+
+ <service name="Test Service GreatGrandChild"
+ discovery="TestResourceDiscoveryComponent"
+ class="TestResourceComponent">
+ </service>
+ </service>
+ </service>
+ </server>
+
+ <server name="Manual Add Server"
+ discovery="ManualAddDiscoveryComponent"
+ class="TestResourceComponent">
+ <plugin-configuration>
+ <c:simple-property name="test" />
+ </plugin-configuration>
+ <operation name="test" />
+ <metric property="test" />
+ <event name="test" />
+ <content name="test" category="executableScript" />
+ <resource-configuration>
+ <c:simple-property name="test" />
+ </resource-configuration>
+
+ <drift-definition name="test">
+ <basedir>
+ <value-context>fileSystem</value-context>
+ <value-name>test</value-name>
+ </basedir>
+ </drift-definition>
+
+ <bundle-target>
+ <destination-base-dir name="test">
+ <value-context>fileSystem</value-context>
+ <value-name>test</value-name>
+ </destination-base-dir>
+ </bundle-target>
+
+ </server>
+</plugin>
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/availability/AvailabilityContextImpl.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/availability/AvailabilityContextImpl.java
index f34d673..32fb361 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/availability/AvailabilityContextImpl.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/availability/AvailabilityContextImpl.java
@@ -79,4 +79,11 @@ public class AvailabilityContextImpl implements AvailabilityContext {
public void enable() {
PluginContainer.getInstance().getInventoryManager().setResourceEnablement(resource.getId(), true);
}
+
+ /**
+ * Only used in tests
+ */
+ public Resource getResource() {
+ return resource;
+ }
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/event/EventContextImpl.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/event/EventContextImpl.java
index a50a658..fd360cf 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/event/EventContextImpl.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/event/EventContextImpl.java
@@ -108,6 +108,13 @@ public class EventContextImpl implements EventContext {
return getEventManager().getSigar();
}
+ /**
+ * Only used for testing purposes.
+ */
+ public Resource getResource() {
+ return resource;
+ }
+
private void registerEventPollerInternal(final EventPoller poller, int pollingInterval, final String sourceLocation) {
EventDefinition eventDefinition = EventUtility.getEventDefinition(poller.getEventType(),
this.resource.getResourceType());
commit 5a4b2ec79c9f05a13f24d253aea91227df7fd40f
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Tue Jul 31 10:16:39 2012 -0500
[BZ 832090] - Make sure to activate the resource only after it has been
synced with the server during manual add so that the subsystems dependent
on the resource id get the correct one.
(cherry picked from commit 662d3ef2ad7ac1b49257565b08c7c7f61187d3a2)
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 7288038..31974c4 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
@@ -694,7 +694,6 @@ public class InventoryManager extends AgentService implements ContainerService,
MergeResourceResponse mergeResourceResponse;
Resource resource = null;
boolean resourceAlreadyExisted = false;
- Throwable startError = null;
try {
ResourceContainer parentResourceContainer = getResourceContainer(parentResourceId);
@@ -805,14 +804,6 @@ public class InventoryManager extends AgentService implements ContainerService,
if (log.isDebugEnabled()) {
log.debug("Activating resource [" + resource + "]...");
}
- // if it fails to start keep going, we already have the resource in inventory and
- // need to coordinate with the server. The new resource will be unavailable but at least
- // it will be accessible and editable by the user. Report the start exception at the end.
- try {
- activateResource(resource, resourceContainer, newPluginConfig);
- } catch (Throwable t) {
- startError = t;
- }
// NOTE: We don't mess with inventory status - that's the server's responsibility.
@@ -829,11 +820,19 @@ public class InventoryManager extends AgentService implements ContainerService,
postProcessNewlyCommittedResources(newResources);
performServiceScan(resource.getId());
- if (null != startError) {
- handleInvalidPluginConfigurationResourceError(resource, startError);
+ // Note that it is important to activate the resource *AFTER* it has been synced with the
+ // server so that the resource has a valid id (which is needed by at least the content
+ // subsystem).
+ try {
+ activateResource(resource, resourceContainer, newPluginConfig);
+ } catch (Throwable t) {
+ // if it fails to start keep going, we already have the resource in inventory and
+ // we are in sync with the server. The new resource will be unavailable but at least
+ // it will be accessible and editable by the user. Report the start exception at the end.
+ handleInvalidPluginConfigurationResourceError(resource, t);
throw new PluginContainerException("The resource [" + resource
+ "] has been added but could not be started. Verify the supplied configuration values: ",
- startError);
+ t);
}
}