modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/PluginMetadataManager.java
| 5
modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
| 154 +++
modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeResponse.java
| 80 +
modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
| 12
modules/core/dbutils/src/main/scripts/dbsetup/sysconfig-data.xml
| 3
modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceErrorType.java
| 7
modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
| 121 ++
modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ResourceErrorTest.java
| 4
modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeContext.java
| 89 +
modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
| 45
modules/core/plugin-container/pom.xml
| 146 ++
modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java
| 2
modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AutoDiscoveryExecutor.java
| 2
modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
| 470 +++++++--
modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/RuntimeDiscoveryExecutor.java
| 7
modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginComponentFactory.java
| 15
modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/DiscoverySuspendedException.java
| 50 +
modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
| 267 +++++
modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/DiscoveryComponentProxyFactory.java
| 10
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
| 352 +++++++
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ForwardingProxy.java
| 72 +
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
| 493 ++++++++++
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
| 331 ++++++
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
| 413 ++++++++
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/DiscComponent.java
| 70 +
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/ResComponent.java
| 46
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/rhq-plugin.xml
| 18
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseDiscoveryComponent.java
| 80 +
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponent.java
| 118 ++
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponentInterface.java
| 36
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java
| 68 +
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/NothingDiscoveringDiscoveryComponent.java
| 42
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/rhq-plugin.xml
| 39
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/rhq-plugin.xml
| 32
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/rhq-plugin.xml
| 31
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml
| 32
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml
| 31
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/root/rhq-plugin.xml
| 25
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
| 28
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
| 25
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml
| 45
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
| 43
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/DiscComponent.java
| 22
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/ResComponent.java
| 21
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/rhq-plugin.xml
| 18
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/DiscComponent.java
| 54 +
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/ResComponent.java
| 21
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/rhq-plugin.xml
| 18
modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
| 42
modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/i18n/AgentI18NResourceKeys.java
| 3
modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/promptcmd/DiscoveryPromptCommand.java
| 2
modules/enterprise/agent/src/test/java/org/rhq/enterprise/agent/PluginContainerConditionalRestart.java
| 31
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
| 5
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewForm.java
| 299 ++++++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
| 327 +-----
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ResourceErrorsDataSource.java
| 100 ++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
| 5
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
| 9
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/config/SystemConfigForm.java
| 15
modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties
| 2
modules/enterprise/gui/portal-war/src/main/webapp/admin/config/GeneralPropertiesConfigForm.jsp
| 104 --
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/RHQConstants.java
| 3
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
| 111 ++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
| 14
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
| 8
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
| 34
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
| 13
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
| 152 +--
68 files changed, 4835 insertions(+), 557 deletions(-)
New commits:
commit 4969aa53cf7f5ff45fbb1510d2f110560f3f6a8f
Merge: 065319e... 1b86f3a...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Oct 5 14:18:01 2010 +0200
Merge branch '_resource-upgrade' into resource-upgrade
commit 1b86f3abaf44ebb4e0d62cb75a559b130500cd9f
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Oct 5 14:17:46 2010 +0200
BZ 593270 - the new style resource key for apache is
<server-root>||<httpd-conf>. Implemented the ResourceUpgradeFacet to upgrade
existing resources to that new format.
diff --git
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
index 660f727..ca8f972 100644
---
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
+++
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
@@ -170,38 +170,24 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
public ResourceUpgradeReport upgrade(ResourceUpgradeContext<PlatformComponent>
context) {
String inventoriedResourceKey = context.getResourceKey();
- File inventoriedResourceKeyAsPath = new File(inventoriedResourceKey);
- //the resource key we use now is a full path to the httpd.conf.
- //in the old version, it was the server root.
- //so if the inventoried resource key is a path to a file,
- //we know it's a new style resource key.
- if (inventoriedResourceKeyAsPath.isFile()) {
+ //check if the inventoried resource has the old format of the resource key.
+ //the old format was "server-root", while the new format
+ //is "server-root||httpd-conf". Checking for "||" in the
resource key is therefore
+ //enough.
+ if (inventoriedResourceKey.contains("||")) {
return null;
}
+
+ //all the information we need for the new style resource key is
+ //actually present in the plugin configuration of the existing resource
+ //already, so let's just generate the new style resource key from it.
+ String resourceKey = formatResourceKey(context.getPluginConfiguration());
- Configuration pluginConfiguration = context.getPluginConfiguration();
+ ResourceUpgradeReport rep = new ResourceUpgradeReport();
+ rep.setNewResourceKey(resourceKey);
- String serverRoot = pluginConfiguration.getSimpleValue("serverRoot",
null);
- String httpdConf = pluginConfiguration.getSimpleValue("configFile",
null);
-
- String resourceKey = null;
-
- if (httpdConf != null) {
- File httpdConfFile = new File(httpdConf);
- if (!httpdConfFile.isAbsolute()) {
- httpdConfFile = new File(serverRoot, httpdConf);
- }
-
- resourceKey = httpdConfFile.getPath();
-
- ResourceUpgradeReport rep = new ResourceUpgradeReport();
- rep.setNewResourceKey(resourceKey);
-
- return rep;
- }
-
- return null;
+ return rep;
}
public DiscoveredResourceDetails discoverResource(Configuration pluginConfig,
@@ -256,15 +242,7 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
name = uri.getHost() + ":" + uri.getPort();
}
- String serverRoot =
pluginConfig.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_SERVER_ROOT)
- .getStringValue();
-
- String key = FileUtils.getCanonicalPath(serverRoot);
-
- //BZ 612189 - reverting to the serverRoot as the resource key temporarily until
we have the resource
- //upgrade functionality ready (BZ 592038). Uncommenting the line below will make
the resource key totally unique
- //(see BZ 593270).
- //key += "|" + httpdConf;
+ String key = formatResourceKey(pluginConfig);
DiscoveredResourceDetails resourceDetails = new
DiscoveredResourceDetails(discoveryContext.getResourceType(),
key, name, version, PRODUCT_DESCRIPTION, pluginConfig, processInfo);
@@ -455,4 +433,14 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
}
return null;
}
+
+ private static String formatResourceKey(Configuration pluginConfiguration) {
+ String serverRoot =
pluginConfiguration.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_SERVER_ROOT).getStringValue();
+ String httpdConf =
pluginConfiguration.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_HTTPD_CONF).getStringValue();
+
+ serverRoot = FileUtils.getCanonicalPath(serverRoot);
+ httpdConf = FileUtils.getCanonicalPath(httpdConf);
+
+ return serverRoot + "||" + httpdConf;
+ }
}
commit a0edcceda8b63f23cc6570fb1da34251f245f3c0
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Oct 5 13:35:57 2010 +0200
code formatting
diff --git
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
index c305ec4..660f727 100644
---
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
+++
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
@@ -21,18 +21,14 @@ package org.rhq.plugins.apache;
import java.io.File;
import java.io.IOException;
import java.net.URI;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.rhq.augeas.node.AugeasNode;
-import org.rhq.augeas.tree.AugeasTree;
import org.rhq.augeas.util.Glob;
import org.rhq.augeas.util.GlobFilter;
import org.rhq.core.domain.configuration.Configuration;
@@ -45,7 +41,6 @@ import org.rhq.core.pluginapi.inventory.ManualAddFacet;
import org.rhq.core.pluginapi.inventory.ProcessScanResult;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
-import org.rhq.core.pluginapi.inventory.ManualAddFacet;
import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
import org.rhq.core.pluginapi.util.FileUtils;
@@ -58,8 +53,8 @@ import org.rhq.plugins.apache.parser.ApacheParserImpl;
import org.rhq.plugins.apache.util.ApacheBinaryInfo;
import org.rhq.plugins.apache.util.AugeasNodeValueUtil;
import org.rhq.plugins.apache.util.HttpdAddressUtility;
-import org.rhq.plugins.apache.util.OsProcessUtility;
import org.rhq.plugins.apache.util.HttpdAddressUtility.Address;
+import org.rhq.plugins.apache.util.OsProcessUtility;
import org.rhq.plugins.platform.PlatformComponent;
import org.rhq.rhqtransform.impl.PluginDescriptorBasedAugeasConfiguration;
@@ -69,13 +64,14 @@ import
org.rhq.rhqtransform.impl.PluginDescriptorBasedAugeasConfiguration;
* @author Ian Springer
* @author Lukas Krejci
*/
-public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponent<PlatformComponent>,
ManualAddFacet<PlatformComponent>,
- ResourceUpgradeFacet<PlatformComponent> {
+public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponent<PlatformComponent>,
+ ManualAddFacet<PlatformComponent>,
ResourceUpgradeFacet<PlatformComponent> {
private static final String PRODUCT_DESCRIPTION = "Apache Web Server";
private static final Log log =
LogFactory.getLog(ApacheServerDiscoveryComponent.class);
- public Set<DiscoveredResourceDetails>
discoverResources(ResourceDiscoveryContext<PlatformComponent> discoveryContext)
throws Exception {
+ public Set<DiscoveredResourceDetails>
+ discoverResources(ResourceDiscoveryContext<PlatformComponent>
discoveryContext) throws Exception {
Set<DiscoveredResourceDetails> discoveredResources = new
HashSet<DiscoveredResourceDetails>();
// Process any PC-discovered OS processes...
@@ -89,16 +85,16 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
continue;
}
if (!executablePath.isAbsolute()) {
- log.error("Executable path (" + executablePath + ") is not
absolute for Apache [" +
- process.getProcessInfo() + "]." +
- "Please restart Apache specifying an absolute path for the
executable.");
+ log.error("Executable path (" + executablePath + ") is not
absolute for Apache ["
+ + process.getProcessInfo() + "]."
+ + "Please restart Apache specifying an absolute path for the
executable.");
continue;
}
log.debug("Apache executable path: " + executablePath);
ApacheBinaryInfo binaryInfo;
try {
- binaryInfo = ApacheBinaryInfo.getInfo(executablePath.getPath(),
- discoveryContext.getSystemInformation());
+ binaryInfo = ApacheBinaryInfo
+ .getInfo(executablePath.getPath(),
discoveryContext.getSystemInformation());
} catch (Exception e) {
log.error("'" + executablePath + "' is not a valid
Apache executable (" + e + ").");
continue;
@@ -130,38 +126,40 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
PropertySimple configFile = new
PropertySimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_HTTPD_CONF,
serverConfigFile);
pluginConfig.put(configFile);
-
- PropertySimple inclusionGlobs = new
PropertySimple(PluginDescriptorBasedAugeasConfiguration.INCLUDE_GLOBS_PROP,
serverConfigFile);
+
+ PropertySimple inclusionGlobs = new PropertySimple(
+ PluginDescriptorBasedAugeasConfiguration.INCLUDE_GLOBS_PROP,
serverConfigFile);
pluginConfig.put(inclusionGlobs);
-
- ApacheDirectiveTree serverConfig =
loadParser(serverConfigFile.getAbsolutePath(),serverRoot);
-
+
+ ApacheDirectiveTree serverConfig =
loadParser(serverConfigFile.getAbsolutePath(), serverRoot);
+
String serverUrl = null;
String vhostsGlobInclude = null;
-
+
//now check if the httpd.conf doesn't redefine the ServerRoot
List<ApacheDirective> serverRoots =
serverConfig.search("/ServerRoot");
if (!serverRoots.isEmpty()) {
serverRoot =
AugeasNodeValueUtil.unescape(serverRoots.get(0).getValuesAsString());
serverRootProp.setValue(serverRoot);
- }
+ }
+
+ serverUrl = getUrl(serverConfig, binaryInfo.getVersion());
+ vhostsGlobInclude = scanForGlobInclude(serverConfig);
- serverUrl = getUrl(serverConfig, binaryInfo.getVersion());
- vhostsGlobInclude = scanForGlobInclude(serverConfig);
-
if (serverUrl != null) {
Property urlProp = new
PropertySimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_URL, serverUrl);
- pluginConfig.put(urlProp);
+ pluginConfig.put(urlProp);
}
-
+
if (vhostsGlobInclude != null) {
- pluginConfig.put(new
PropertySimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_VHOST_FILES_MASK,
vhostsGlobInclude));
- }else
- {
+ pluginConfig.put(new
PropertySimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_VHOST_FILES_MASK,
+ vhostsGlobInclude));
+ } else {
if (serverConfigFile.exists())
- pluginConfig.put(new
PropertySimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_VHOST_FILES_MASK,
serverConfigFile.getParent()+File.separator+"*"));
+ pluginConfig.put(new
PropertySimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_VHOST_FILES_MASK,
+ serverConfigFile.getParent() + File.separator +
"*"));
}
-
+
discoveredResources.add(createResourceDetails(discoveryContext,
pluginConfig, process.getProcessInfo(),
binaryInfo));
}
@@ -202,18 +200,16 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
return rep;
}
-
+
return null;
}
public DiscoveredResourceDetails discoverResource(Configuration pluginConfig,
-
ResourceDiscoveryContext<PlatformComponent> discoveryContext)
- throws InvalidPluginConfigurationException {
+ ResourceDiscoveryContext<PlatformComponent> discoveryContext) throws
InvalidPluginConfigurationException {
validateServerRootAndServerConfigFile(pluginConfig);
- String executablePath = pluginConfig
- .getSimpleValue(ApacheServerComponent.PLUGIN_CONFIG_PROP_EXECUTABLE_PATH,
- ApacheServerComponent.DEFAULT_EXECUTABLE_PATH);
+ String executablePath =
pluginConfig.getSimpleValue(ApacheServerComponent.PLUGIN_CONFIG_PROP_EXECUTABLE_PATH,
+ ApacheServerComponent.DEFAULT_EXECUTABLE_PATH);
String absoluteExecutablePath =
ApacheServerComponent.resolvePathRelativeToServerRoot(pluginConfig,
executablePath).getPath();
ApacheBinaryInfo binaryInfo;
@@ -222,13 +218,12 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
} catch (Exception e) {
throw new InvalidPluginConfigurationException("'" +
absoluteExecutablePath
+ "' is not a valid Apache executable (" + e + ").
Please make sure the '"
- + ApacheServerComponent.PLUGIN_CONFIG_PROP_EXECUTABLE_PATH
- + "' connection property is set correctly.");
+ + ApacheServerComponent.PLUGIN_CONFIG_PROP_EXECUTABLE_PATH + "'
connection property is set correctly.");
}
if (!isSupportedVersion(binaryInfo.getVersion())) {
- throw new InvalidPluginConfigurationException("Version of Apache
executable ("
- + binaryInfo.getVersion() + ") is not a supported version; supported
versions are 1.3.x and 2.x.");
+ throw new InvalidPluginConfigurationException("Version of Apache
executable (" + binaryInfo.getVersion()
+ + ") is not a supported version; supported versions are 1.3.x and
2.x.");
}
ProcessInfo processInfo = null;
@@ -236,8 +231,7 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
DiscoveredResourceDetails resourceDetails =
createResourceDetails(discoveryContext, pluginConfig,
processInfo, binaryInfo);
return resourceDetails;
- }
- catch (Exception e) {
+ } catch (Exception e) {
throw new RuntimeException("Failed to create resource details during
manual add.");
}
}
@@ -247,8 +241,9 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
return (version != null) && (version.startsWith("1.3") ||
version.startsWith("2."));
}
- private DiscoveredResourceDetails
createResourceDetails(ResourceDiscoveryContext<PlatformComponent> discoveryContext,
- Configuration pluginConfig, ProcessInfo processInfo, ApacheBinaryInfo binaryInfo)
throws Exception {
+ private DiscoveredResourceDetails createResourceDetails(
+ ResourceDiscoveryContext<PlatformComponent> discoveryContext, Configuration
pluginConfig,
+ ProcessInfo processInfo, ApacheBinaryInfo binaryInfo) throws Exception {
String httpdConf =
pluginConfig.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_HTTPD_CONF).getStringValue();
String version = binaryInfo.getVersion();
String serverUrl =
pluginConfig.getSimpleValue(ApacheServerComponent.PLUGIN_CONFIG_PROP_URL, null);
@@ -258,19 +253,19 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
name = httpdConf;
} else {
URI uri = new URI(serverUrl);
- name = uri.getHost() + ":" + uri.getPort();
+ name = uri.getHost() + ":" + uri.getPort();
}
String serverRoot =
pluginConfig.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_SERVER_ROOT)
.getStringValue();
-
+
String key = FileUtils.getCanonicalPath(serverRoot);
//BZ 612189 - reverting to the serverRoot as the resource key temporarily until
we have the resource
//upgrade functionality ready (BZ 592038). Uncommenting the line below will make
the resource key totally unique
//(see BZ 593270).
//key += "|" + httpdConf;
-
+
DiscoveredResourceDetails resourceDetails = new
DiscoveredResourceDetails(discoveryContext.getResourceType(),
key, name, version, PRODUCT_DESCRIPTION, pluginConfig, processInfo);
log.debug("Apache Server resource details created: " +
resourceDetails);
@@ -290,7 +285,6 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
return addr == null ? null : "http://" + addr.host + ":" +
addr.port + "/";
}
-
@Nullable
private String getServerRoot(@NotNull ApacheBinaryInfo binaryInfo, @NotNull
ProcessInfo processInfo) {
// First see if -d was specified on the httpd command line.
@@ -315,12 +309,12 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
currentWorkingDir = processInfo.getCurrentWorkingDirectory();
} catch (Exception e) {
log.error("Unable to determine current working directory of Apache
process [" + processInfo
- + "], which is needed to determine the server root of the
Apache instance.", e);
+ + "], which is needed to determine the server root of the Apache
instance.", e);
return null;
}
if (currentWorkingDir == null) {
log.error("Unable to determine current working directory of Apache
process [" + processInfo
- + "], which is needed to determine the server root of the
Apache instance.");
+ + "], which is needed to determine the server root of the Apache
instance.");
return null;
} else {
rootFile = new File(currentWorkingDir, root);
@@ -396,12 +390,12 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
}
private static void validateServerRootAndServerConfigFile(Configuration pluginConfig)
{
- String serverRoot =
pluginConfig.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_SERVER_ROOT).getStringValue();
+ String serverRoot =
pluginConfig.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_SERVER_ROOT)
+ .getStringValue();
File serverRootFile;
try {
serverRootFile = new File(serverRoot).getCanonicalFile(); // this will
resolve symlinks
- }
- catch (IOException e) {
+ } catch (IOException e) {
serverRootFile = null;
}
if (serverRootFile == null || !serverRootFile.isDirectory()) {
@@ -413,8 +407,7 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
File httpdConfFile;
try {
httpdConfFile = new File(httpdConf).getCanonicalFile(); // this will resolve
symlinks
- }
- catch (IOException e) {
+ } catch (IOException e) {
httpdConfFile = null;
}
if (httpdConfFile == null || !httpdConfFile.isFile()) {
@@ -423,15 +416,15 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
+ ApacheServerComponent.PLUGIN_CONFIG_PROP_HTTPD_CONF + "'
connection property is set correctly.");
}
}
-
- private static ApacheDirectiveTree loadParser(String path,String serverRoot) throws
Exception{
+
+ private static ApacheDirectiveTree loadParser(String path, String serverRoot) throws
Exception {
ApacheDirectiveTree tree = new ApacheDirectiveTree();
- ApacheParser parser = new ApacheParserImpl(tree,serverRoot);
+ ApacheParser parser = new ApacheParserImpl(tree, serverRoot);
ApacheConfigReader.buildTree(path, parser);
return tree;
}
-
+
public static String scanForGlobInclude(ApacheDirectiveTree tree) {
try {
List<ApacheDirective> includes = tree.search("/Include");
@@ -440,9 +433,9 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
if (Glob.isWildcard(include)) {
//we only take the '*.something' into account here
//so that we have a useful mask to base the file names on.
-
+
//the only special glob character allowed is *.
- for(char specialChar : GlobFilter.WILDCARD_CHARS) {
+ for (char specialChar : GlobFilter.WILDCARD_CHARS) {
if (specialChar == '*') {
if (include.indexOf(specialChar) !=
include.lastIndexOf(specialChar)) {
//more than 1 star... that's too much
@@ -462,4 +455,4 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
}
return null;
}
-}
\ No newline at end of file
+}
commit 065319e2048376d93509e31dd526789b26947b4f
Merge: 98a4d17... 297cc73...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Oct 5 12:49:38 2010 +0200
Merge branch 'master' into resource-upgrade
commit 98a4d17665d0fed83e0fd2c28770545178b00150
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Oct 5 12:48:12 2010 +0200
making the getResourcesWithType(ResourceType, Set<Resource>) private again.
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 c5004dd..351f751 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
@@ -1668,7 +1668,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
return getResourcesWithType(serverType, this.platform.getChildResources());
}
- public Set<Resource> getResourcesWithType(ResourceType serverType,
Set<Resource> resources) {
+ private Set<Resource> getResourcesWithType(ResourceType serverType,
Set<Resource> resources) {
Set<Resource> servers = new HashSet<Resource>();
if (resources == null) {
commit 98ab21b9a9348520b30fae149d67d39af7553373
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Oct 4 18:58:14 2010 +0200
Getting the InventoryManager.handleReport(InventoryReport) inline with the version in
master, updating the upgrade tests to accommodate for the changed behavior.
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 ec40b0c..c5004dd 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
@@ -932,30 +932,16 @@ public class InventoryManager extends AgentService implements
ContainerService,
}
/**
- * @see #handleReport(InventoryReport, boolean)
- * @param report
- * @return
- */
- public boolean handleReport(InventoryReport report) {
- return handleReport(report, false);
- }
-
- /**
* Send an inventory report to the Server.
*
* @param report the inventory report to be sent
- * @param forceServerRoundtrip whether to report to the server even if there are no
resources to report.
* @return true if sending the report to the Server succeeded, or false otherwise
*/
- public boolean handleReport(InventoryReport report, boolean forceServerRoundtrip) {
+ public boolean handleReport(InventoryReport report) {
if (!configuration.isInsideAgent()) {
return true;
}
- if (report.getAddedRoots().isEmpty() && !forceServerRoundtrip) {
- return true; // nothing to do
- }
-
ResourceSyncInfo syncInfo;
try {
String reportType = (report.isRuntimeReport()) ? "runtime" :
"server";
@@ -2659,7 +2645,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
log.debug("Executing resource upgrade.");
- boolean syncResult = handleReport(new InventoryReport(getAgent()), true);
+ boolean syncResult = handleReport(new InventoryReport(getAgent()));
if (!syncResult) {
log.warn("Resource upgrade failed to sync up the inventory with the
server.");
return;
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 ebb73be..ab1cd2b 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
@@ -342,10 +342,6 @@ public class ResourceUpgradeFailureHandlingTest extends
ResourceUpgradeTestBase
expectations.allowing(getCurrentDiscoveryServerService()).upgradeResources(
expectations.with(Expectations.any(Set.class)));
expectations.will(getCurrentServerSideInventory().upgradeResources());
-
-
expectations.allowing(getCurrentDiscoveryServerService()).postProcessNewlyCommittedResources(
- expectations.with(Expectations.any(Set.class)));
-
} catch (InvalidInventoryReportException e) {
//this is not going to happen because we're mocking the invocation
}
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 8b966c3..e2a8a84 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -93,7 +93,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
{
defineDefaultExpectations(this);
- between(1,
4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+
allowing(getCurrentDiscoveryServerService()).mergeInventoryReport(
with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
@@ -144,7 +144,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
{
defineDefaultExpectations(this);
- between(1,
4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+
allowing(getCurrentDiscoveryServerService()).mergeInventoryReport(
with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
@@ -197,7 +197,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
//the rest of the inventory merges are executed by discoveries,
so let's import the
//discovered stuff into the server-side inventory.
- between(1,
3).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+
allowing(getCurrentDiscoveryServerService()).mergeInventoryReport(
with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
@@ -242,7 +242,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
{
defineDefaultExpectations(this);
- between(1,
4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+
allowing(getCurrentDiscoveryServerService()).mergeInventoryReport(
with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
@@ -276,7 +276,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
{
defineDefaultExpectations(this);
- between(1,
4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+
allowing(getCurrentDiscoveryServerService()).mergeInventoryReport(
with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(requiredInventoryStatus));
}
@@ -317,7 +317,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
{
defineDefaultExpectations(this);
- between(1,
4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+
allowing(getCurrentDiscoveryServerService()).mergeInventoryReport(
with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
index 0aefafd..c299cce 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
@@ -402,6 +402,9 @@ public abstract class ResourceUpgradeTestBase {
expectations.allowing(getCurrentDiscoveryServerService()).getResources(
expectations.with(Expectations.any(Set.class)),
expectations.with(Expectations.any(boolean.class)));
expectations.will(getCurrentServerSideInventory().getResources());
+
+
expectations.allowing(getCurrentDiscoveryServerService()).postProcessNewlyCommittedResources(
+ expectations.with(Expectations.any(Set.class)));
}
protected void cleanDataDir() throws IOException {
commit 65c3b23735a092f9675cb2e878b79039b5ab9c93
Merge: e7fb6ed... ebd4ec6...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Oct 4 18:37:55 2010 +0200
Merge branch 'master' into resource-upgrade
diff --cc
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
index 150a692,4e14b75..a004680
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
@@@ -238,11 -274,11 +275,15 @@@ public class ResourceGWTServiceImpl ext
}
public void unignoreResources(Integer[] resourceIds) {
- discoveryBoss.unignoreResources(getSessionSubject(), resourceIds);
+ try {
+ discoveryBoss.unignoreResources(getSessionSubject(), resourceIds);
+ } catch (Exception e) {
+ throw new RuntimeException(ThrowableUtil.getAllMessages(e));
+ }
}
-
-}
+
+ public List<ResourceError> findResourceErrors(int resourceId) {
+ return
SerialUtility.prepare(resourceManager.findResourceErrors(getSessionSubject(),
resourceId),
+ "ResourceService.getResourceErrors");
+ }
+}
commit e7fb6edacd4c172a236cfc39b19096f03cef85ee
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Oct 4 18:34:25 2010 +0200
Discovery now recurses to child resource types of the existing resources even if the
discovery of the existing resources' type is disallowed due to upgrade failure.
This means that no new siblings will be discovered but the existing resources
"contents" will be up-to-date with the plugin version.
Added tests for this behaviour and updated the existing to reflect the changes.
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 99a0513..ec40b0c 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
@@ -91,6 +91,7 @@ import org.rhq.core.pc.plugin.BlacklistedException;
import org.rhq.core.pc.plugin.CanonicalResourceKey;
import org.rhq.core.pc.plugin.PluginComponentFactory;
import org.rhq.core.pc.plugin.PluginManager;
+import org.rhq.core.pc.upgrade.DiscoverySuspendedException;
import org.rhq.core.pc.upgrade.ResourceUpgradeDelegate;
import org.rhq.core.pc.util.DiscoveryComponentProxyFactory;
import org.rhq.core.pc.util.FacetLockType;
@@ -289,18 +290,22 @@ public class InventoryManager extends AgentService implements
ContainerService,
* @param context the context for use by the discovery component
* @return the details of all discovered resources, may be empty or
<code>null</code>
*
+ * @throws DiscoverySuspendedException if the discovery is suspended due to a
resource upgrade failure
* @throws Exception if the discovery component threw an exception
*/
public Set<DiscoveredResourceDetails>
invokeDiscoveryComponent(ResourceContainer parentResourceContainer,
- ResourceDiscoveryComponent component, ResourceDiscoveryContext context) throws
Exception {
+ ResourceDiscoveryComponent component, ResourceDiscoveryContext context) throws
DiscoverySuspendedException, Exception {
Resource parentResource = parentResourceContainer == null ? null :
parentResourceContainer.getResource();
if (resourceUpgradeDelegate.hasUpgradeFailedInChildren(parentResource,
context.getResourceType())) {
- log.debug("Discovery of [" + context.getResourceType() + "]
has been disallowed under "
- + (parentResource == null ? " the platform " : parentResource)
- + " because some of its siblings failed to upgrade.");
- return null;
+ String message = "Discovery of [" + context.getResourceType() +
"] has been suspended under "
+ + (parentResource == null ? " the platform " : parentResource)
+ + " because some of its siblings failed to upgrade.";
+
+ log.debug(message);
+
+ throw new DiscoverySuspendedException(message);
}
long timeout = getDiscoveryComponentTimeout(context.getResourceType());
@@ -699,19 +704,29 @@ public class InventoryManager extends AgentService implements
ContainerService,
// Ask the plugin's discovery component to find the new resource,
throwing exceptions if it cannot be
// found at all.
- Set<DiscoveredResourceDetails> discoveredResources =
invokeDiscoveryComponent(parentResourceContainer,
- discoveryComponent, discoveryContext);
- if ((discoveredResources == null) || discoveredResources.isEmpty()) {
- log.info("Plugin Error: During manual add, discovery component
method ["
- + discoveryComponent.getClass().getName() +
".discoverResources()] returned "
- + discoveredResources + " when passed a single plugin
configuration "
- + "(either the resource type was blacklisted or the plugin
developer "
- + "did not implement support for manually discovered
resources correctly).");
- throw new PluginContainerException("The [" +
resourceType.getPlugin()
- + "] plugin does not properly support manual addition of
[" + resourceType.getName()
- + "] resources.");
+ try {
+ Set<DiscoveredResourceDetails> discoveredResources =
invokeDiscoveryComponent(parentResourceContainer,
+ discoveryComponent, discoveryContext);
+ if ((discoveredResources == null) || discoveredResources.isEmpty())
{
+ log.info("Plugin Error: During manual add, discovery
component method ["
+ + discoveryComponent.getClass().getName() +
".discoverResources()] returned "
+ + discoveredResources + " when passed a single plugin
configuration "
+ + "(either the resource type was blacklisted or the
plugin developer "
+ + "did not implement support for manually discovered
resources correctly).");
+ throw new PluginContainerException("The [" +
resourceType.getPlugin()
+ + "] plugin does not properly support manual addition of
[" + resourceType.getName()
+ + "] resources.");
+ }
+ discoveredResourceDetails = discoveredResources.iterator().next();
+ } catch (DiscoverySuspendedException e) {
+ String message = "The discovery class [" +
discoveryComponent.getClass().getName() + "]" +
+ " uses a legacy implementation of \"manual add\"
functionality. Some of the child resources" +
+ " with the resource type [" + resourceType + "] under
the parent resource [" + parentResourceContainer.getResource() + "]" +
+ " failed to upgrade, which makes it impossible to support the
legacy manual-add implementation. Either upgrade the plugin [" +
+ resourceType.getPlugin() + "] to successfully upgrade all
resources or consider implementing the ManuallAdd facet.";
+ log.info(message);
+ throw new PluginContainerException(message, e);
}
- discoveredResourceDetails = discoveredResources.iterator().next();
}
// Create the new Resource and add it to inventory if it isn't already
there.
@@ -1844,6 +1859,8 @@ public class InventoryManager extends AgentService implements
ContainerService,
try {
discoveredResources = invokeDiscoveryComponent(null, component,
context);
+ } catch (DiscoverySuspendedException e) {
+ log.error("Discovery seems to be suspended for platforms due
to upgrade error.", e);
} catch (Throwable e) {
log.warn("Platform plugin discovery failed - skipping",
e);
}
@@ -2179,35 +2196,47 @@ public class InventoryManager extends AgentService implements
ContainerService,
parentResourceContext, SystemInfoFactory.createSystemInfo(),
processScanResults,
Collections.EMPTY_LIST, this.configuration.getContainerName(),
this.configuration.getPluginContainerDeployment());
- Set<DiscoveredResourceDetails> discoveredResources =
invokeDiscoveryComponent(parentContainer,
- discoveryComponent, context);
newResources = new HashSet<Resource>();
- if ((discoveredResources != null) &&
(!discoveredResources.isEmpty())) {
- IdentityHashMap<Configuration, DiscoveredResourceDetails>
pluginConfigObjects = new IdentityHashMap<Configuration,
DiscoveredResourceDetails>();
- for (DiscoveredResourceDetails discoveredResource : discoveredResources)
{
- if (discoveredResource == null) {
- throw new IllegalStateException("Plugin error: Discovery
class "
- + discoveryComponent.getClass().getName()
- + " returned a Set containing one or more null
items.");
- }
- if (!discoveredResource.getResourceType().equals(resourceType)) {
- throw new IllegalStateException("Plugin error: Discovery
class "
- + discoveryComponent.getClass().getName()
- + " returned a DiscoveredResourceDetails with an
incorrect ResourceType (was "
- + discoveredResource.getResourceType().getName() + " but
should have been "
- + resourceType.getName());
+ try {
+ Set<DiscoveredResourceDetails> discoveredResources =
invokeDiscoveryComponent(parentContainer,
+ discoveryComponent, context);
+ if ((discoveredResources != null) &&
(!discoveredResources.isEmpty())) {
+ IdentityHashMap<Configuration, DiscoveredResourceDetails>
pluginConfigObjects = new IdentityHashMap<Configuration,
DiscoveredResourceDetails>();
+ for (DiscoveredResourceDetails discoveredResource :
discoveredResources) {
+ if (discoveredResource == null) {
+ throw new IllegalStateException("Plugin error: Discovery
class "
+ + discoveryComponent.getClass().getName()
+ + " returned a Set containing one or more null
items.");
+ }
+ if (!discoveredResource.getResourceType().equals(resourceType))
{
+ throw new IllegalStateException("Plugin error: Discovery
class "
+ + discoveryComponent.getClass().getName()
+ + " returned a DiscoveredResourceDetails with an
incorrect ResourceType (was "
+ + discoveredResource.getResourceType().getName() + "
but should have been "
+ + resourceType.getName());
+ }
+ if (null != pluginConfigObjects
+ .put(discoveredResource.getPluginConfiguration(),
discoveredResource)) {
+ throw new IllegalStateException("The plugin component
"
+ + discoveryComponent.getClass().getName()
+ + " returned multiple resources that point to the
same plugin configuration object on the "
+ + "resource type [" + resourceType + "].
This is not allowed, please use "
+ +
"ResoureDiscoveryContext.getDefaultPluginConfiguration() "
+ + "for each discovered resource.");
+ }
+ Resource newResource =
InventoryManager.createNewResource(discoveredResource);
+ newResources.add(newResource);
}
- if (null != pluginConfigObjects
- .put(discoveredResource.getPluginConfiguration(),
discoveredResource)) {
- throw new IllegalStateException("The plugin component
"
- + discoveryComponent.getClass().getName()
- + " returned multiple resources that point to the same
plugin configuration object on the "
- + "resource type [" + resourceType + "]. This
is not allowed, please use "
- +
"ResoureDiscoveryContext.getDefaultPluginConfiguration() "
- + "for each discovered resource.");
+ }
+ } catch (DiscoverySuspendedException e) {
+ //ok, the discovery is suspended for this resource type under this
parent.
+ //but we can continue the discovery in the child resource types of the
existing resources.
+ //we can therefore pretend that the discovery returned the existing
resources so that
+ //we can recurse into their children up in the call-chain.
+ for(Resource existingResource : parentResource.getChildResources()) {
+ if (resourceType.equals(existingResource.getResourceType())) {
+ newResources.add(existingResource);
}
- Resource newResource =
InventoryManager.createNewResource(discoveredResource);
- newResources.add(newResource);
}
}
} catch (Throwable e) {
@@ -2654,14 +2683,14 @@ public class InventoryManager extends AgentService implements
ContainerService,
if (container != null) {
if (container.getResourceComponentState() == ResourceComponentState.STARTED)
{
try {
- resourceUpgradeDelegate.processAndQueue(container);
+ if (resourceUpgradeDelegate.processAndQueue(container)) {
+ for (Resource child : resource.getChildResources()) {
+ upgradeResource(child);
+ }
+ }
} catch (PluginContainerException e) {
log.error("Exception thrown while upgrading [" + resource +
"].", e);
}
-
- for (Resource child : resource.getChildResources()) {
- upgradeResource(child);
- }
} else {
String message = "The resource container for resource [" +
resource
+ "] wasn't started while upgrading.";
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/DiscoverySuspendedException.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/DiscoverySuspendedException.java
new file mode 100644
index 0000000..5cb695d
--- /dev/null
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/DiscoverySuspendedException.java
@@ -0,0 +1,50 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.upgrade;
+
+import org.rhq.core.pc.inventory.InventoryManager;
+
+/**
+ * This exception is thrown from the {@link
InventoryManager#invokeDiscoveryComponent(org.rhq.core.pc.inventory.ResourceContainer,
org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent,
org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext)} if the
+ * discovery is suspended for given resource type due to a resource upgrade failure.
+ *
+ * @author Lukas Krejci
+ */
+public class DiscoverySuspendedException extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+ public DiscoverySuspendedException() {
+ super();
+ }
+
+ public DiscoverySuspendedException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public DiscoverySuspendedException(String message) {
+ super(message);
+ }
+
+ public DiscoverySuspendedException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
index 98a897e..06d2cd0 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
@@ -26,6 +26,7 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+
import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
import org.rhq.core.domain.resource.Resource;
@@ -61,7 +62,7 @@ public class ResourceUpgradeDelegate {
private Set<Resource> failedResources = new HashSet<Resource>();
private Map<Resource, Set<ResourceType>> failedResourceTypesPerParent =
new HashMap<Resource, Set<ResourceType>>();
private boolean mergeFailed;
-
+
public ResourceUpgradeDelegate(InventoryManager inventoryManager) {
this.inventoryManager = inventoryManager;
}
@@ -84,13 +85,17 @@ public class ResourceUpgradeDelegate {
/**
* Asks the resource's discovery component to upgrade the resource.
* @param resourceContainer
- * @return true if the resource was queued for upgrade, false otherwise
+ * @return true if the resource was queued for upgrade with no problems,
+ * false if there was some problem upgrading and the resource container was
deactivated as
+ * a results of that.
* @throws PluginContainerException on error
*/
- public void processAndQueue(ResourceContainer resourceContainer) throws
PluginContainerException {
+ public boolean processAndQueue(ResourceContainer resourceContainer) throws
PluginContainerException {
if (enabled) {
- executeResourceUpgradeFacetAndStoreRequest(resourceContainer);
+ return executeResourceUpgradeFacetAndStoreRequest(resourceContainer);
}
+
+ return true;
}
/**
@@ -99,7 +104,7 @@ public class ResourceUpgradeDelegate {
public boolean hasUpgradeMergeFailed() {
return mergeFailed;
}
-
+
/**
* Tells whether given resource had a upgrade failure during the {@link
#processAndQueue(ResourceContainer)} invocation.
*
@@ -109,7 +114,7 @@ public class ResourceUpgradeDelegate {
public boolean hasUpgradeFailed(Resource resource) {
return mergeFailed || failedResources.contains(resource);
}
-
+
/**
* Tells whether at least one of the children with given resource type of the given
parent resource
* had an upgrade failure during {@link #processAndQueue(ResourceContainer)}
invocation.
@@ -120,35 +125,35 @@ public class ResourceUpgradeDelegate {
if (mergeFailed) {
return true;
}
-
+
Set<ResourceType> failedTypes =
failedResourceTypesPerParent.get(parentResource);
-
+
return failedTypes != null &&
failedTypes.contains(childrenResourceType);
}
-
+
public void sendRequests() throws Throwable {
if (enabled && requests.size() > 0) {
try {
inventoryManager.mergeResourcesFromUpgrade(requests);
} catch (Throwable t) {
mergeFailed = true;
-
+
//deactivate all the resources to be upgraded. We might have a problem
//because they have not been upgraded because the merge failed.
- for(ResourceUpgradeRequest request : requests) {
+ for (ResourceUpgradeRequest request : requests) {
ResourceContainer container =
inventoryManager.getResourceContainer(request.getResourceId());
if (container != null) {
inventoryManager.deactivateResource(container.getResource());
}
}
-
+
throw t;
}
}
}
@SuppressWarnings("unchecked")
- private <T extends ResourceComponent> void
executeResourceUpgradeFacetAndStoreRequest(
+ private <T extends ResourceComponent> boolean
executeResourceUpgradeFacetAndStoreRequest(
ResourceContainer resourceContainer) throws PluginContainerException {
ResourceComponent<T> parentResourceComponent =
resourceContainer.getResourceContext()
@@ -166,16 +171,16 @@ public class ResourceUpgradeDelegate {
if (!(discoveryComponent instanceof ResourceUpgradeFacet)) {
//well, there's no point in continuing if the resource doesn't
support the facet
- return;
+ return true;
}
ResourceUpgradeContext<ResourceComponent<T>> upgradeContext =
inventoryManager.createResourceUpgradeContext(
resource, parentResourceComponent, discoveryComponent);
ResourceUpgradeRequest request = new ResourceUpgradeRequest(resource.getId());
-
+
request.setTimestamp(System.currentTimeMillis());
-
+
ResourceUpgradeReport upgradeReport = null;
try {
upgradeReport =
inventoryManager.invokeDiscoveryComponentResourceUpgradeFacet(resource.getResourceType(),
@@ -189,13 +194,13 @@ public class ResourceUpgradeDelegate {
String upgradeErrors = null;
if ((upgradeErrors = checkUpgradeValid(resource, upgradeReport)) != null) {
String errorString = "Upgrading the resource [" + resource +
"] using these updates [" + upgradeReport
- + "] would render the inventory invalid because of the following
reasons: " + upgradeErrors;
-
+ + "] would render the inventory invalid because of the following
reasons: " + upgradeErrors;
+
log.error(errorString);
-
+
IllegalStateException ex = new IllegalStateException(errorString);
ex.fillInStackTrace();
-
+
request.setErrorProperties(ex);
} else {
request.fillInFromReport(upgradeReport);
@@ -207,20 +212,24 @@ public class ResourceUpgradeDelegate {
if (request.hasSomethingToUpgrade()) {
requests.add(request);
}
-
+
if (request.getUpgradeErrorMessage() != null) {
failedResources.add(resource);
-
+
Set<ResourceType> failedResourceTypesInParent =
failedResourceTypesPerParent.get(parentResource);
if (failedResourceTypesInParent == null) {
failedResourceTypesInParent = new HashSet<ResourceType>();
failedResourceTypesPerParent.put(parentResource,
failedResourceTypesInParent);
}
-
+
failedResourceTypesInParent.add(resource.getResourceType());
-
+
inventoryManager.deactivateResource(resource);
+
+ return false;
}
+
+ return true;
}
private String checkUpgradeValid(Resource resource, ResourceUpgradeReport
upgradeReport) {
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 7eafafc..ebb73be 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
@@ -156,9 +156,9 @@ public class ResourceUpgradeFailureHandlingTest extends
ResourceUpgradeTestBase
//check that the resources are upgraded
checkResourcesUpgraded(resources.get(PARENT_DEP_SIBLING_TYPE), 1);
- checkResourcesUpgraded(resources.get(PARENT_TYPE), 2);
- checkResourcesUpgraded(resources.get(SIBLING_TYPE), 30);
- checkResourcesUpgraded(resources.get(TEST_TYPE), 30);
+ checkResourcesUpgraded(resources.get(PARENT_TYPE), 3);
+ checkResourcesUpgraded(resources.get(SIBLING_TYPE), 45);
+ checkResourcesUpgraded(resources.get(TEST_TYPE), 45);
}
public Expectations getExpectations(Mockery context) throws Exception {
@@ -206,19 +206,24 @@ public class ResourceUpgradeFailureHandlingTest extends
ResourceUpgradeTestBase
checkNumberOfResources(resources, ROOT_TYPE, 1);
checkNumberOfResources(resources, PARENT_DEP_TYPE, 1);
- checkNumberOfResources(resources, PARENT_TYPE, 2);
- checkResourcesUpgraded(resources.get(PARENT_TYPE), 2);
+ checkResourcesUpgraded(resources.get(PARENT_TYPE), 3);
checkResourcesUpgraded(resources.get(PARENT_DEP_SIBLING_TYPE), 1);
Resource parent0 = findResourceWithOrdinal(PARENT_TYPE, 0);
Resource parent1 = findResourceWithOrdinal(PARENT_TYPE, 1);
-
- Set<Resource> siblingsUnderParent0 =
filterResources(parent0.getChildResources(), SIBLING_TYPE);
+ Resource parent2 = findResourceWithOrdinal(PARENT_TYPE, 2);
+
Set<Resource> testsUnderParent0 =
filterResources(parent0.getChildResources(), TEST_TYPE);
- Set<Resource> siblingsUnderParent1 =
filterResources(parent1.getChildResources(), SIBLING_TYPE);
+ Set<Resource> siblingsUnderParent0 =
filterResources(parent0.getChildResources(), SIBLING_TYPE);
Set<Resource> testsUnderParent1 =
filterResources(parent1.getChildResources(), TEST_TYPE);
-
+ Set<Resource> siblingsUnderParent1 =
filterResources(parent1.getChildResources(), SIBLING_TYPE);
+ Set<Resource> testsUnderParent2 =
filterResources(parent2.getChildResources(), TEST_TYPE);
+ Set<Resource> siblingsUnderParent2 =
filterResources(parent2.getChildResources(), SIBLING_TYPE);
+
+ //first check for the successful upgrades
+ checkResourcesUpgraded(testsUnderParent2, 15);
+ checkResourcesUpgraded(siblingsUnderParent2, 15);
checkResourcesUpgraded(siblingsUnderParent0, 15);
checkResourcesUpgraded(testsUnderParent1, 15);
@@ -257,10 +262,72 @@ public class ResourceUpgradeFailureHandlingTest extends
ResourceUpgradeTestBase
}
@Test
- public void testFailureOnDependencies() {
- //TODO implement
- //check that stuff works if there is an upgrade failure on some of the resources
- //in the plugin some "in the middle" of the plugin dep graph
+ public void testFailureOnDependencies() throws Exception {
+ setCurrentServerSideInventory(new FakeServerInventory());
+
+ executeTestWithPlugins(getAllDepsFor(TEST_V1_PLUGIN_NAME,
PARENT_SIBLING_V1_PLUGIN_NAME),
+ new AbstractTestPayload(true, Collections.<ResType> emptyList()) {
+ public void test(Map<ResType, Set<Resource>>
resourceUpgradeTestResources) {
+ //in here we set up the failures that are going to happen when
+ //the v2 plugins are run
+
+ Resource parent = findResourceWithOrdinal(PARENT_DEP_TYPE, 0);
+ assertNotNull(parent, "Failed to find the parent to setup the
failures for.");
+
+ addChildrenToFail(parent, PARENT_TYPE, 0);
+ }
+
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+ }
+ };
+ }
+ });
+
+ executeTestWithPlugins(getAllDepsFor(TEST_V2_PLUGIN_NAME,
PARENT_SIBLING_V2_PLUGIN_NAME),
+ new AbstractTestPayload(false, ALL_TYPES) {
+ public void test(Map<ResType, Set<Resource>> resources) {
+ checkPresenceOfResourceTypes(resources, getExpectedResourceTypes());
+
+ checkNumberOfResources(resources, ROOT_TYPE, 1);
+ checkNumberOfResources(resources, PARENT_DEP_TYPE, 1);
+ checkResourcesUpgraded(resources.get(PARENT_DEP_SIBLING_TYPE), 1);
+
+ //check that the failed resources have the error attached to them
+ //we find the resource instance from the map provided to this method
+ //because that map contains the resources as found on the server-side
+ //(i.e. they include error objects).
+ Resource parent0 = getEqualFrom(resources.get(PARENT_TYPE),
findResourceWithOrdinal(PARENT_TYPE, 0));
+ Resource parent1 = getEqualFrom(resources.get(PARENT_TYPE),
findResourceWithOrdinal(PARENT_TYPE, 1));
+
+ //v2 plugin discovers 3 resources but because parent0 failed to
upgrade,
+ //the discovery shouldn't have occurred leaving us with the 2
already existing resources.
+ checkNumberOfResources(resources, PARENT_TYPE, 2);
+ checkResourceFailedUpgrade(parent0);
+ checkOthersUpgraded(resources.get(PARENT_TYPE), parent0);
+
+ //parent1 upgraded ok, so discovering its children should have
executed.
+ //this is v2, so we should find 15 of each.
+ checkResourcesUpgraded(filterResources(parent1.getChildResources(),
TEST_TYPE), 15);
+ checkResourcesUpgraded(filterResources(parent1.getChildResources(),
SIBLING_TYPE), 15);
+
+ //these shouldn't have been upgraded. in v1 we had 10 resources
of TEST_TYPE
+ //and 10 resources of SIBLING_TYPE and that's what we should be
seeing
+ //now.
+
checkResourcesNotUpgraded(filterResources(parent0.getChildResources(), TEST_TYPE), 10);
+
checkResourcesNotUpgraded(filterResources(parent0.getChildResources(), SIBLING_TYPE),
10);
+ }
+
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+ }
+ };
+ }
+ });
}
@SuppressWarnings("unchecked")
@@ -317,6 +384,22 @@ public class ResourceUpgradeFailureHandlingTest extends
ResourceUpgradeTestBase
}
}
+ private static void checkResourcesNotUpgraded(Set<Resource> resources, int
expectedSize) {
+ assertEquals(resources.size(), expectedSize, "The set of resources has
unexpected size.");
+ for(Resource res : resources) {
+ assertFalse(res.getResourceKey().startsWith(UPGRADED_RESOURCE_KEY_PREFIX),
"Resource " + res
+ + " seems to be upgraded even though it shouldn't.");
+
+ ResourceContainer rc =
PluginContainer.getInstance().getInventoryManager().getResourceContainer(res);
+
+ assertEquals(rc.getResourceComponentState(), ResourceComponentState.STOPPED,
+ "A resource that has not been upgraded due to upgrade error in
parent should be stopped.");
+
+ //recurse, since the whole subtree under the failed resource should be not
upgraded and stopped.
+ checkResourcesNotUpgraded(res.getChildResources(),
res.getChildResources().size());
+ }
+ }
+
private static void checkResourceFailedUpgrade(Resource resource) {
assertFalse(resource.getResourceKey().startsWith(UPGRADED_RESOURCE_KEY_PREFIX),
"Resource " + resource
+ " seems to be upgraded even though it shouldn't.");
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
index 3d709b0..0f6671b 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
@@ -21,7 +21,7 @@
</runs-inside>
<plugin-configuration>
- <c:simple-property name="count" default="2" />
+ <c:simple-property name="count" default="3" />
<c:simple-property name="key"
default="UPGRADED-test-resource-parent-%n,parent-%p" />
</plugin-configuration>
commit 9533fc2898f18af7262f513049d7261516787f4f
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Oct 4 14:50:49 2010 +0200
Upgrade even the non-commited resources to prevent duplication of resources in the
auto-discovery queue
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 c6f1169..99a0513 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
@@ -2650,11 +2650,6 @@ public class InventoryManager extends AgentService implements
ContainerService,
}
private void upgradeResource(Resource resource) {
- //only process committed resources
- if (resource.getInventoryStatus() != InventoryStatus.COMMITTED) {
- return;
- }
-
ResourceContainer container = getResourceContainer(resource);
if (container != null) {
if (container.getResourceComponentState() == ResourceComponentState.STARTED)
{
@@ -2668,8 +2663,17 @@ public class InventoryManager extends AgentService implements
ContainerService,
upgradeResource(child);
}
} else {
- log.error("The resource container for resource [" + resource
- + "] wasn't started during upgrade. This should not
happen.");
+ String message = "The resource container for resource [" +
resource
+ + "] wasn't started while upgrading.";
+
+ if (resource.getChildResources().isEmpty()) {
+ log.info(message
+ + " If this is the first time the plugin container starts up
and has completely empty inventory, you can ignore this message.");
+ } else {
+ log.error(message
+ + " This can potentially cause the discovery to find
resources logically equivalent to already "
+ + "existing resources if the corresponding plugins support
upgrade for that particular resource type.");
+ }
}
} else {
log.error("Resource container not initialized for resource [" +
resource
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
index 39597ee..0dd3459 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
@@ -80,8 +80,6 @@ public class FakeServerInventory {
this.failing = failing;
}
- //need to synchronize, because resource upgrade is async and can overlap with
- //resource discovery.
public synchronized CustomAction mergeInventoryReport(final InventoryStatus
requiredInventoryStatus) {
return new CustomAction("updateServerSideInventory") {
public Object invoke(Invocation invocation) throws Throwable {
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 04858c6..8b966c3 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -71,7 +71,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
}
@Test
- public void testIgnoreUncommittedResources() throws Exception {
+ public void testIncludeUncommittedResources() throws Exception {
setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.NEW);
@@ -82,11 +82,12 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
Resource discoveredResource =
discoveredResources.get(SINGLETON_TYPE).iterator().next();
- assertEquals(discoveredResource.getResourceKey(),
"resource-key-v1");
- assertEquals(discoveredResource.getName(),
"resource-name-v1");
- assertEquals(discoveredResource.getDescription(),
"resource-description-v1");
+ assertEquals(discoveredResource.getResourceKey(),
"resource-key-v2");
+ assertEquals(discoveredResource.getName(),
"resource-name-v2");
+ assertEquals(discoveredResource.getDescription(),
"resource-description-v2");
}
+ @SuppressWarnings("unchecked")
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
@@ -95,6 +96,9 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
between(1,
4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
+
+
oneOf(getCurrentDiscoveryServerService()).upgradeResources(with(any(Set.class)));
+ will(getCurrentServerSideInventory().upgradeResources());
}
};
}
commit 8ecbe7dec08b0e2e1f86ad8e1e56efd9f651cc7e
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Oct 4 14:32:55 2010 +0200
code formatting
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 de52cd8..c6f1169 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
@@ -242,16 +242,19 @@ public class InventoryManager extends AgentService implements
ContainerService,
// inside EmbJopr).
if (configuration.isInsideAgent()) {
// After an initial delay (5s by default), periodically run an
availability check (every 1m by default).
-
availabilityThreadPoolExecutor.scheduleWithFixedDelay(availabilityExecutor, configuration
- .getAvailabilityScanInitialDelay(),
configuration.getAvailabilityScanPeriod(), TimeUnit.SECONDS);
+
availabilityThreadPoolExecutor.scheduleWithFixedDelay(availabilityExecutor,
+ configuration.getAvailabilityScanInitialDelay(),
configuration.getAvailabilityScanPeriod(),
+ TimeUnit.SECONDS);
// After an initial delay (10s by default), periodically run a server
discovery scan (every 15m by default).
- inventoryThreadPoolExecutor.scheduleWithFixedDelay(serverScanExecutor,
configuration
- .getServerDiscoveryInitialDelay(),
configuration.getServerDiscoveryPeriod(), TimeUnit.SECONDS);
+ inventoryThreadPoolExecutor.scheduleWithFixedDelay(serverScanExecutor,
+ configuration.getServerDiscoveryInitialDelay(),
configuration.getServerDiscoveryPeriod(),
+ TimeUnit.SECONDS);
// After an initial delay (20s by default), periodically run a service
discovery scan (every 1d by default).
- inventoryThreadPoolExecutor.scheduleWithFixedDelay(serviceScanExecutor,
configuration
- .getServiceDiscoveryInitialDelay(),
configuration.getServiceDiscoveryPeriod(), TimeUnit.SECONDS);
+ inventoryThreadPoolExecutor.scheduleWithFixedDelay(serviceScanExecutor,
+ configuration.getServiceDiscoveryInitialDelay(),
configuration.getServiceDiscoveryPeriod(),
+ TimeUnit.SECONDS);
}
} finally {
inventoryLock.writeLock().unlock();
@@ -288,22 +291,23 @@ public class InventoryManager extends AgentService implements
ContainerService,
*
* @throws Exception if the discovery component threw an exception
*/
- public Set<DiscoveredResourceDetails>
invokeDiscoveryComponent(ResourceContainer parentResourceContainer,
ResourceDiscoveryComponent component,
- ResourceDiscoveryContext context) throws Exception {
+ public Set<DiscoveredResourceDetails>
invokeDiscoveryComponent(ResourceContainer parentResourceContainer,
+ ResourceDiscoveryComponent component, ResourceDiscoveryContext context) throws
Exception {
Resource parentResource = parentResourceContainer == null ? null :
parentResourceContainer.getResource();
-
+
if (resourceUpgradeDelegate.hasUpgradeFailedInChildren(parentResource,
context.getResourceType())) {
- log.debug("Discovery of [" + context.getResourceType() + "]
has been disallowed under " + (parentResource == null ? " the platform " :
parentResource) +
- " because some of its siblings failed to upgrade.");
+ log.debug("Discovery of [" + context.getResourceType() + "]
has been disallowed under "
+ + (parentResource == null ? " the platform " : parentResource)
+ + " because some of its siblings failed to upgrade.");
return null;
}
-
+
long timeout = getDiscoveryComponentTimeout(context.getResourceType());
try {
- ResourceDiscoveryComponent proxy =
this.discoveryComponentProxyFactory.getDiscoveryComponentProxy(context
- .getResourceType(), component, timeout);
+ ResourceDiscoveryComponent proxy =
this.discoveryComponentProxyFactory.getDiscoveryComponentProxy(
+ context.getResourceType(), component, timeout);
Set<DiscoveredResourceDetails> results =
proxy.discoverResources(context);
return results;
} catch (TimeoutException te) {
@@ -335,8 +339,8 @@ public class InventoryManager extends AgentService implements
ContainerService,
long timeout = getDiscoveryComponentTimeout(context.getResourceType());
try {
- ManualAddFacet proxy =
this.discoveryComponentProxyFactory.getDiscoveryComponentProxy(context
- .getResourceType(), component, timeout, ManualAddFacet.class);
+ ManualAddFacet proxy =
this.discoveryComponentProxyFactory.getDiscoveryComponentProxy(
+ context.getResourceType(), component, timeout, ManualAddFacet.class);
DiscoveredResourceDetails result = proxy.discoverResource(pluginConfig,
context);
return result;
} catch (TimeoutException te) {
@@ -375,8 +379,8 @@ public class InventoryManager extends AgentService implements
ContainerService,
component, timeout, ClassLoaderFacet.class);
ResourceDiscoveryContext discoveryContext = new
ResourceDiscoveryContext(resourceType, parentComponent,
- parentResourceContext, SystemInfoFactory.createSystemInfo(), null, null,
this.configuration
- .getContainerName(), this.configuration.getPluginContainerDeployment());
+ parentResourceContext, SystemInfoFactory.createSystemInfo(), null, null,
+ this.configuration.getContainerName(),
this.configuration.getPluginContainerDeployment());
// Configurations are not immutable, so clone the plugin config, so the plugin
will not be able to change the
// actual PC-managed plugin config.
@@ -384,8 +388,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
// TODO (ips): Clone the ResourceType too for the same reason.
DiscoveredResourceDetails details = new DiscoveredResourceDetails(resourceType,
resource.getResourceKey(),
- resource.getName(), resource.getVersion(), resource.getDescription(),
pluginConfigClone,
- null); // TODO: I have a feeling we'll need process info, how to get
it??
+ resource.getName(), resource.getVersion(), resource.getDescription(),
pluginConfigClone, null); // TODO: I have a feeling we'll need process info, how to
get it??
List<URL> results = proxy.getAdditionalClasspathUrls(discoveryContext,
details);
@@ -592,7 +595,8 @@ public class InventoryManager extends AgentService implements
ContainerService,
@NotNull
// TODO (ips): Perhaps refactor this so that it shares code with
AvailablityExecutor.checkInventory().
- public Availability getCurrentAvailability(Resource resource) {
+ public
+ Availability getCurrentAvailability(Resource resource) {
AvailabilityType availType = null; // i.e. UNKNOWN;
ResourceContainer resourceContainer = getResourceContainer(resource);
if (resourceContainer != null) {
@@ -665,8 +669,8 @@ public class InventoryManager extends AgentService implements
ContainerService,
ResourceDiscoveryContext<ResourceComponent> discoveryContext = new
ResourceDiscoveryContext<ResourceComponent>(
resourceType, parentResourceComponent,
parentResourceContainer.getResourceContext(),
SystemInfoFactory.createSystemInfo(), new
ArrayList<ProcessScanResult>(0),
- new ArrayList<Configuration>(0),
this.configuration.getContainerName(), this.configuration
- .getPluginContainerDeployment());
+ new ArrayList<Configuration>(0),
this.configuration.getContainerName(),
+ this.configuration.getPluginContainerDeployment());
// Ask the plugin's discovery component to find the new resource,
throwing exceptions if it cannot be
// found at all.
@@ -695,8 +699,8 @@ public class InventoryManager extends AgentService implements
ContainerService,
// Ask the plugin's discovery component to find the new resource,
throwing exceptions if it cannot be
// found at all.
- Set<DiscoveredResourceDetails> discoveredResources =
invokeDiscoveryComponent(parentResourceContainer, discoveryComponent,
- discoveryContext);
+ Set<DiscoveredResourceDetails> discoveredResources =
invokeDiscoveryComponent(parentResourceContainer,
+ discoveryComponent, discoveryContext);
if ((discoveredResources == null) || discoveredResources.isEmpty()) {
log.info("Plugin Error: During manual add, discovery component
method ["
+ discoveryComponent.getClass().getName() +
".discoverResources()] returned "
@@ -850,8 +854,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
if ((this.platform != null) && (this.platform.getInventoryStatus() ==
InventoryStatus.NEW)
&& newPlatformWasDeletedRecently) {
// let's make sure we are registered; its probable that our platform
was deleted and we need to re-register
- log
- .info("No committed resources to send in our availability report
- the platform/agent was deleted, let's re-register again");
+ log.info("No committed resources to send in our availability report
- the platform/agent was deleted, let's re-register again");
registerWithServer();
newPlatformWasDeletedRecently = false; // we've tried to recover from
our platform being deleted, let's not do it again
}
@@ -891,8 +894,8 @@ public class InventoryManager extends AgentService implements
ContainerService,
log.debug("Availability report content: " +
report.toString(log.isTraceEnabled()));
}
- boolean ok =
configuration.getServerServices().getDiscoveryServerService().mergeAvailabilityReport(
- report);
+ boolean ok =
configuration.getServerServices().getDiscoveryServerService()
+ .mergeAvailabilityReport(report);
if (!ok) {
// I guess I could immediately call
executeAvailabilityScanImmediately and pass its results to
// mergeAvailabilityReport again right now, but what happens if
we've queued up a bunch of
@@ -955,8 +958,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
if ((this.platform != null) && (this.platform.getInventoryStatus() ==
InventoryStatus.NEW)
&& newPlatformWasDeletedRecently) {
// let's make sure we are registered; its probable that our platform
was deleted and we need to re-register
- log
- .info("The inventory report was invalid probably because the
platform/Agent was deleted; let's re-register...");
+ log.info("The inventory report was invalid probably because the
platform/Agent was deleted; let's re-register...");
registerWithServer();
newPlatformWasDeletedRecently = false; // we've tried to recover from
our platform being deleted, let's not do it again
}
@@ -974,8 +976,8 @@ public class InventoryManager extends AgentService implements
ContainerService,
if (syncInfo != null) {
synchInventory(syncInfo);
} else {
- purgeObsoleteResources(Collections.<String>emptySet());
-
+ purgeObsoleteResources(Collections.<String> emptySet());
+
//can't live without a platform, but we just deleted it. Let's
rediscover it.
discoverPlatform();
}
@@ -1113,7 +1115,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
return;
}
boolean scan =
removeResourceAndIndicateIfScanIsNeeded(resourceContainer.getResource());
-
+
//only actually schedule the scanning when we are finished with resource upgrade.
The resource upgrade
//happens before any scanning infrastructure is established.
if (!resourceUpgradeDelegate.enabled() && scan) {
@@ -1152,8 +1154,8 @@ public class InventoryManager extends AgentService implements
ContainerService,
parent.removeChildResource(resource);
}
- PluginContainer.getInstance().getMeasurementManager().unscheduleCollection(
- Collections.singleton(resource.getId()));
+ PluginContainer.getInstance().getMeasurementManager()
+ .unscheduleCollection(Collections.singleton(resource.getId()));
if (this.resourceContainers.remove(resource.getUuid()) == null) {
if (log.isDebugEnabled()) {
@@ -1258,8 +1260,8 @@ public class InventoryManager extends AgentService implements
ContainerService,
logMessage.append("description, ");
}
- logMessage.replace(logMessage.length() - 1, logMessage.length(),
"to become [").append(
- existingResource.toString()).append("]");
+ logMessage.replace(logMessage.length() - 1, logMessage.length(),
"to become [")
+ .append(existingResource.toString()).append("]");
log.info(logMessage.toString());
} else {
@@ -1429,7 +1431,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
}
return;
}
-
+
ResourceComponent component = container.getResourceComponent();
// if the component already exists and is started, and the resource's plugin
config has not changed, there is
@@ -1490,8 +1492,8 @@ public class InventoryManager extends AgentService implements
ContainerService,
log.warn("Cannot give activated resource its discovery component.
Cause: " + e);
}
-
ConfigurationUtility.normalizeConfiguration(resource.getPluginConfiguration(), type
- .getPluginConfigurationDefinition());
+
ConfigurationUtility.normalizeConfiguration(resource.getPluginConfiguration(),
+ type.getPluginConfigurationDefinition());
ResourceComponent parentComponent = null;
if (resource.getParentResource() != null) {
@@ -1855,8 +1857,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
}
} else {
// This is very strange - there are no platform types - we should never be
missing the built-in platform plugin.
- log
- .error("Missing platform plugin(s) - falling back to dummy platform
impl; this should only occur in tests!");
+ log.error("Missing platform plugin(s) - falling back to dummy platform
impl; this should only occur in tests!");
// TODO: Set sysprop (e.g. rhq.test.mode=true) in integration tests,
// and throw a runtime exception here if that sysprop is not set.
return getTestPlatform();
@@ -2049,7 +2050,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
public boolean hasUpgradeMergeFailed() {
return resourceUpgradeDelegate.hasUpgradeMergeFailed();
}
-
+
/**
* Always use this before accessing the event listeners because this ensures
* thread safety.
@@ -2176,9 +2177,10 @@ public class InventoryManager extends AgentService implements
ContainerService,
try {
ResourceDiscoveryContext context = new ResourceDiscoveryContext(resourceType,
parentComponent,
parentResourceContext, SystemInfoFactory.createSystemInfo(),
processScanResults,
- Collections.EMPTY_LIST, this.configuration.getContainerName(),
this.configuration
- .getPluginContainerDeployment());
- Set<DiscoveredResourceDetails> discoveredResources =
invokeDiscoveryComponent(parentContainer, discoveryComponent, context);
+ Collections.EMPTY_LIST, this.configuration.getContainerName(),
+ this.configuration.getPluginContainerDeployment());
+ Set<DiscoveredResourceDetails> discoveredResources =
invokeDiscoveryComponent(parentContainer,
+ discoveryComponent, context);
newResources = new HashSet<Resource>();
if ((discoveredResources != null) &&
(!discoveredResources.isEmpty())) {
IdentityHashMap<Configuration, DiscoveredResourceDetails>
pluginConfigObjects = new IdentityHashMap<Configuration,
DiscoveredResourceDetails>();
@@ -2403,8 +2405,8 @@ public class InventoryManager extends AgentService implements
ContainerService,
if (log.isDebugEnabled()) {
log.debug("Merging [" + modifiedResourceIds.size() + "]
modified Resources into local inventory...");
}
- Set<Resource> modifiedResources =
configuration.getServerServices().getDiscoveryServerService().getResources(
- modifiedResourceIds, false);
+ Set<Resource> modifiedResources =
configuration.getServerServices().getDiscoveryServerService()
+ .getResources(modifiedResourceIds, false);
syncSchedules(modifiedResources); // RHQ-792, mtime is the indicator that
schedules should be sync'ed too
for (Resource modifiedResource : modifiedResources) {
mergeResource(modifiedResource);
@@ -2620,12 +2622,12 @@ public class InventoryManager extends AgentService implements
ContainerService,
private void upgradeResources() {
try {
-
+
if (!configuration.isInsideAgent()) {
log.debug("Skipping resource upgrade in embedded mode.");
return;
}
-
+
log.debug("Executing resource upgrade.");
boolean syncResult = handleReport(new InventoryReport(getAgent()), true);
@@ -2635,7 +2637,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
}
upgradeResource(getPlatform());
-
+
log.debug("Sending the upgrade requests to the server.");
resourceUpgradeDelegate.sendRequests();
commit 9050f4bfab5114ff31e19cb9c04b2d087dba2bff
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Oct 4 14:04:52 2010 +0200
Adding the test for handling the failure to upgrade some of the resources on the leaf
of the plugin dependency graph.
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ForwardingProxy.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ForwardingProxy.java
new file mode 100644
index 0000000..7c7d277
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ForwardingProxy.java
@@ -0,0 +1,72 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.upgrade;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+/**
+ * This class provides a simple proxy that just forwards the calls to the
+ * actual object.
+ * <p>
+ * This seemingly pointless behavior is useful when dealing with the classes
+ * loaded in different classloaders.
+ * <p>
+ * The arguments passed to the method invocations of the proxy must unfortunately be
"understandable"
+ * both in the "current" classloader and in the context of the classloader
that loaded the target object.
+ * I don't know about a generic solution to this problem.
+ * A partial solution would be to serialize the arguments and deserialize them in the
context
+ * of the target classloader but that doesn't cut it for non-serializable classes
obviously.
+ *
+ * @author Lukas Krejci
+ */
+public class ForwardingProxy {
+
+ private static class ForwardingHandler implements InvocationHandler {
+ private Object target;
+
+ public ForwardingHandler(Object target) {
+ this.target = target;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
+ Method targetMethod = findMethodOnTarget(method);
+
+ return targetMethod.invoke(target, args);
+ }
+
+ private Method findMethodOnTarget(Method method) throws SecurityException,
NoSuchMethodException {
+ Class<?>[] origParamTypes = method.getParameterTypes();
+
+ return target.getClass().getMethod(method.getName(), origParamTypes);
+ }
+ }
+
+ public static <T> T forward(Object target, Class<T> targetInterface,
Class<?>... additionalInterfaces) {
+ Class<?>[] interfaces = new Class<?>[additionalInterfaces.length +
1];
+ interfaces[0] = targetInterface;
+ System.arraycopy(additionalInterfaces, 0, interfaces, 1,
additionalInterfaces.length);
+
+ Object proxy = Proxy.newProxyInstance(targetInterface.getClassLoader(),
interfaces, new ForwardingHandler(target));
+ return targetInterface.cast(proxy);
+ }
+}
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 5949b76..7eafafc 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
@@ -20,14 +20,17 @@
package org.rhq.core.pc.upgrade;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -36,10 +39,20 @@ import org.jmock.Expectations;
import org.jmock.Mockery;
import org.testng.annotations.Test;
+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.domain.configuration.Configuration;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceErrorType;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.pc.PluginContainer;
+import org.rhq.core.pc.inventory.InventoryManager;
+import org.rhq.core.pc.inventory.ResourceContainer;
+import org.rhq.core.pc.inventory.ResourceContainer.ResourceComponentState;
+import org.rhq.core.pc.upgrade.plugins.multi.base.BaseResourceComponentInterface;
import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
/**
@@ -76,7 +89,7 @@ public class ResourceUpgradeFailureHandlingTest extends
ResourceUpgradeTestBase
private static final String TEST_V2_PLUGIN_NAME =
"/resource-upgrade-test-plugin-multi-test-2.0.0.jar";
private static final String UPGRADED_RESOURCE_KEY_PREFIX = "UPGRADED";
-
+
private static final HashMap<String, List<String>> DEPS;
static {
@@ -100,9 +113,12 @@ public class ResourceUpgradeFailureHandlingTest extends
ResourceUpgradeTestBase
private static final ResType SIBLING_TYPE = new
ResType("TestResourceSibling", "test");
private static final ResType PARENT_TYPE = new
ResType("TestResourceParent", "test");
private static final ResType PARENT_DEP_TYPE = new
ResType("ParentDependency", "parentdep");
- private static final ResType PARENT_SIBLING_TYPE = new
ResType("ParentDepSibling", "parentsibling");
+ private static final ResType PARENT_DEP_SIBLING_TYPE = new
ResType("ParentDepSibling", "parentsibling");
private static final ResType ROOT_TYPE = new ResType("Root",
"root");
+ private static List<ResType> ALL_TYPES = Arrays.asList(TEST_TYPE, SIBLING_TYPE,
PARENT_TYPE, PARENT_DEP_TYPE,
+ PARENT_DEP_SIBLING_TYPE, ROOT_TYPE);
+
protected Collection<String> getRequiredPlugins() {
return Arrays.asList(BASE_PLUGIN_NAME, PARENT_DEP_V1_PLUGIN_NAME,
PARENT_DEP_V2_PLUGIN_NAME,
PARENT_SIBLING_V1_PLUGIN_NAME, PARENT_SIBLING_V2_PLUGIN_NAME,
ROOT_PLUGIN_NAME, SIBLING_V1_PLUGIN_NAME,
@@ -129,26 +145,20 @@ public class ResourceUpgradeFailureHandlingTest extends
ResourceUpgradeTestBase
});
//now let's run with v2 plugins and check the layout of the inventory
- executeTestWithPlugins(
- getAllDepsFor(TEST_V2_PLUGIN_NAME, PARENT_SIBLING_V2_PLUGIN_NAME),
- new AbstractTestPayload(false, Arrays.asList(TEST_TYPE, SIBLING_TYPE,
PARENT_TYPE, PARENT_DEP_TYPE,
- PARENT_SIBLING_TYPE, ROOT_TYPE)) {
+ executeTestWithPlugins(getAllDepsFor(TEST_V2_PLUGIN_NAME,
PARENT_SIBLING_V2_PLUGIN_NAME),
+ new AbstractTestPayload(false, ALL_TYPES) {
public void test(Map<ResType, Set<Resource>> resources) {
checkPresenceOfResourceTypes(resources, getExpectedResourceTypes());
checkNumberOfResources(resources, ROOT_TYPE, 1);
checkNumberOfResources(resources, PARENT_DEP_TYPE, 1);
- checkNumberOfResources(resources, PARENT_SIBLING_TYPE, 1);
- checkNumberOfResources(resources, PARENT_TYPE, 2);
- checkNumberOfResources(resources, SIBLING_TYPE, 30);
- checkNumberOfResources(resources, TEST_TYPE, 30);
-
+
//check that the resources are upgraded
- checkResourcesUpgraded(resources.get(PARENT_SIBLING_TYPE));
- checkResourcesUpgraded(resources.get(PARENT_TYPE));
- checkResourcesUpgraded(resources.get(SIBLING_TYPE));
- checkResourcesUpgraded(resources.get(TEST_TYPE));
+ checkResourcesUpgraded(resources.get(PARENT_DEP_SIBLING_TYPE), 1);
+ checkResourcesUpgraded(resources.get(PARENT_TYPE), 2);
+ checkResourcesUpgraded(resources.get(SIBLING_TYPE), 30);
+ checkResourcesUpgraded(resources.get(TEST_TYPE), 30);
}
public Expectations getExpectations(Mockery context) throws Exception {
@@ -162,10 +172,88 @@ public class ResourceUpgradeFailureHandlingTest extends
ResourceUpgradeTestBase
}
@Test
- public void testFailureOnLeaf() {
- //TODO implement
- //check that the system behaves correctly if there is an upgrade failure
- //at the leaf node of the plugin dep graph
+ public void testFailureOnLeaf() throws Exception {
+ setCurrentServerSideInventory(new FakeServerInventory());
+
+ executeTestWithPlugins(getAllDepsFor(TEST_V1_PLUGIN_NAME,
PARENT_SIBLING_V1_PLUGIN_NAME),
+ new AbstractTestPayload(true, Collections.<ResType> emptyList()) {
+ public void test(Map<ResType, Set<Resource>>
resourceUpgradeTestResources) {
+ //in here we set up the failures that are going to happen when
+ //the v2 plugins are run
+
+ Resource parent0 = findResourceWithOrdinal(PARENT_TYPE, 0);
+ assertNotNull(parent0, "Failed to find the parent to setup the
failures for.");
+ Resource parent1 = findResourceWithOrdinal(PARENT_TYPE, 1);
+ assertNotNull(parent1, "Failed to find the parent to setup the
failures for.");
+
+ addChildrenToFail(parent0, TEST_TYPE, 1, 2);
+ addChildrenToFail(parent1, SIBLING_TYPE, 1);
+ }
+
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+ }
+ };
+ }
+ });
+
+ executeTestWithPlugins(getAllDepsFor(TEST_V2_PLUGIN_NAME,
PARENT_SIBLING_V2_PLUGIN_NAME),
+ new AbstractTestPayload(false, ALL_TYPES) {
+ public void test(Map<ResType, Set<Resource>> resources) {
+ checkPresenceOfResourceTypes(resources, getExpectedResourceTypes());
+
+ checkNumberOfResources(resources, ROOT_TYPE, 1);
+ checkNumberOfResources(resources, PARENT_DEP_TYPE, 1);
+ checkNumberOfResources(resources, PARENT_TYPE, 2);
+
+ checkResourcesUpgraded(resources.get(PARENT_TYPE), 2);
+ checkResourcesUpgraded(resources.get(PARENT_DEP_SIBLING_TYPE), 1);
+
+ Resource parent0 = findResourceWithOrdinal(PARENT_TYPE, 0);
+ Resource parent1 = findResourceWithOrdinal(PARENT_TYPE, 1);
+
+ Set<Resource> siblingsUnderParent0 =
filterResources(parent0.getChildResources(), SIBLING_TYPE);
+ Set<Resource> testsUnderParent0 =
filterResources(parent0.getChildResources(), TEST_TYPE);
+ Set<Resource> siblingsUnderParent1 =
filterResources(parent1.getChildResources(), SIBLING_TYPE);
+ Set<Resource> testsUnderParent1 =
filterResources(parent1.getChildResources(), TEST_TYPE);
+
+ checkResourcesUpgraded(siblingsUnderParent0, 15);
+ checkResourcesUpgraded(testsUnderParent1, 15);
+
+ //there should be no newly discovered sibling resources of the failed
ones
+ assertEquals(testsUnderParent0.size(), 10);
+ assertEquals(siblingsUnderParent1.size(), 10);
+
+ //check that the failed resources have the error attached to them
+ //we find the resource instance from the map provided to this method
+ //because that map contains the resources as found on the server-side
+ //(i.e. they include error objects).
+ Resource failedTest1 = getEqualFrom(resources.get(TEST_TYPE),
+ findResourceWithOrdinal(testsUnderParent0, 1));
+ Resource failedTest2 = getEqualFrom(resources.get(TEST_TYPE),
+ findResourceWithOrdinal(testsUnderParent0, 2));
+
+ checkResourceFailedUpgrade(failedTest1);
+ checkResourceFailedUpgrade(failedTest2);
+ checkOthersUpgraded(testsUnderParent0, failedTest1, failedTest2);
+
+ Resource failedSibling = getEqualFrom(resources.get(SIBLING_TYPE),
+ findResourceWithOrdinal(siblingsUnderParent1, 1));
+
+ checkResourceFailedUpgrade(failedSibling);
+ checkOthersUpgraded(siblingsUnderParent1, failedSibling);
+ }
+
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+ }
+ };
+ }
+ });
}
@Test
@@ -180,13 +268,14 @@ public class ResourceUpgradeFailureHandlingTest extends
ResourceUpgradeTestBase
protected void defineDefaultExpectations(Expectations expectations) {
super.defineDefaultExpectations(expectations);
try {
- expectations.allowing(getCurrentDiscoveryServerService())
-
.mergeInventoryReport(expectations.with(Expectations.any(InventoryReport.class)));
+
expectations.allowing(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ expectations.with(Expectations.any(InventoryReport.class)));
expectations.will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
-
expectations.allowing(getCurrentDiscoveryServerService()).upgradeResources(expectations.with(Expectations.any(Set.class)));
+ expectations.allowing(getCurrentDiscoveryServerService()).upgradeResources(
+ expectations.with(Expectations.any(Set.class)));
expectations.will(getCurrentServerSideInventory().upgradeResources());
-
+
expectations.allowing(getCurrentDiscoveryServerService()).postProcessNewlyCommittedResources(
expectations.with(Expectations.any(Set.class)));
@@ -214,10 +303,112 @@ public class ResourceUpgradeFailureHandlingTest extends
ResourceUpgradeTestBase
private static void checkNumberOfResources(Map<ResType, Set<Resource>>
resources, ResType type, int count) {
assertEquals(resources.get(type).size(), count, "Unexpected number of "
+ type + " discovered.");
}
-
- private static void checkResourcesUpgraded(Set<Resource> resources) {
- for(Resource res : resources) {
- assertTrue(res.getResourceKey().startsWith(UPGRADED_RESOURCE_KEY_PREFIX),
"Resource " + res + " doesn't seem to be upgraded even though it
should.");
+
+ private static void checkResourcesUpgraded(Set<Resource> resources, int
expectedSize) {
+ assertEquals(resources.size(), expectedSize, "The set of resources has
unexpected size.");
+ for (Resource res : resources) {
+ assertTrue(res.getResourceKey().startsWith(UPGRADED_RESOURCE_KEY_PREFIX),
"Resource " + res
+ + " doesn't seem to be upgraded even though it should.");
+
+ ResourceContainer rc =
PluginContainer.getInstance().getInventoryManager().getResourceContainer(res);
+
+ assertEquals(rc.getResourceComponentState(), ResourceComponentState.STARTED,
+ "A resource that successfully upgraded should be started.");
+ }
+ }
+
+ private static void checkResourceFailedUpgrade(Resource resource) {
+ assertFalse(resource.getResourceKey().startsWith(UPGRADED_RESOURCE_KEY_PREFIX),
"Resource " + resource
+ + " seems to be upgraded even though it shouldn't.");
+ assertTrue(resource.getResourceErrors(ResourceErrorType.UPGRADE).size() == 1,
+ "The failed resource should have an error associated with it.");
+
+ ResourceContainer rc =
PluginContainer.getInstance().getInventoryManager().getResourceContainer(resource);
+
+ assertEquals(rc.getResourceComponentState(), ResourceComponentState.STOPPED,
+ "A resource that failed to upgrade should be stopped.");
+ }
+
+ private static void checkOthersUpgraded(Set<Resource> resources, Resource...
failedResource) {
+ Set<Resource> others = new HashSet<Resource>(resources);
+ others.removeAll(Arrays.asList(failedResource));
+ checkResourcesUpgraded(others, others.size());
+ }
+
+ private void addChildrenToFail(Resource parent, ResType childResType, int...
childrenOrdinals) {
+ InventoryManager inventoryManager =
PluginContainer.getInstance().getInventoryManager();
+ ResourceContainer parentContainer =
inventoryManager.getResourceContainer(parent);
+ BaseResourceComponentInterface parentComponent = (BaseResourceComponentInterface)
parentContainer
+ .getResourceComponent();
+
+ Map<String, Set<Integer>> childrenToFail = new HashMap<String,
Set<Integer>>();
+ Set<Integer> ordinals = new HashSet<Integer>();
+ for (int i = 0; i < childrenOrdinals.length; ++i) {
+ ordinals.add(childrenOrdinals[i]);
+ }
+
+ childrenToFail.put(childResType.getResourceTypeName(), ordinals);
+
+ Configuration newPluginConfig =
parentComponent.createPluginConfigurationWithMarkedFailures(childrenToFail);
+
+ try {
+ int resourceId = parent.getId();
+ inventoryManager.updatePluginConfiguration(resourceId, newPluginConfig);
+ } catch (InvalidPluginConfigurationClientException e) {
+ fail("Updating plugin configuration failed.", e);
+ } catch (PluginContainerException e) {
+ fail("Updating plugin configuration failed.", e);
+ }
+ }
+
+ private Resource findResourceWithOrdinal(ResType resType, int ordinal) {
+ ResourceType resourceType =
PluginContainer.getInstance().getPluginManager().getMetadataManager()
+ .getType(resType.getResourceTypeName(),
resType.getResourceTypePluginName());
+
+ InventoryManager inventoryManager =
PluginContainer.getInstance().getInventoryManager();
+ Set<Resource> resources =
inventoryManager.getResourcesWithType(resourceType);
+
+ return findResourceWithOrdinal(resources, ordinal);
+ }
+
+ private Resource findResourceWithOrdinal(Set<Resource> resources, int ordinal)
{
+ for (Resource r : resources) {
+ Configuration pluginConfig = r.getPluginConfiguration();
+ String ordinalString = pluginConfig.getSimpleValue("ordinal",
null);
+
+ if (ordinalString != null && Integer.parseInt(ordinalString) ==
ordinal) {
+ return r;
+ }
+ }
+
+ return null;
+ }
+
+ private Set<Resource> filterResources(Set<Resource> resources, ResType
resType) {
+ Set<Resource> ret = new HashSet<Resource>(resources);
+
+ Iterator<Resource> it = ret.iterator();
+
+ while (it.hasNext()) {
+ ResourceType resourceType = it.next().getResourceType();
+
+ if (!resourceType.getName().equals(resType.getResourceTypeName())
+ || !resourceType.getPlugin().equals(resType.getResourceTypePluginName()))
{
+
+ it.remove();
+ }
}
+
+ return ret;
+ }
+
+ private static <T> T getEqualFrom(Collection<? extends T> collection, T
object) {
+ for (T other : collection) {
+ if (object.equals(other)) {
+ return other;
+ }
+ }
+
+ return null;
}
}
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index d47d00c..04858c6 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -37,12 +37,13 @@ import java.util.Set;
import org.jmock.Expectations;
import org.jmock.Mockery;
+import org.testng.annotations.Test;
+
import org.rhq.core.clientapi.server.discovery.InventoryReport;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.pc.PluginContainer;
import org.rhq.core.pc.inventory.ResourceContainer;
-import org.testng.annotations.Test;
/**
* Test cases for resource upgrade.
@@ -55,234 +56,255 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
private static final String PLUGIN_V1_FILENAME =
"/resource-upgrade-test-plugin-1.0.0.jar";
private static final String PLUGIN_V2_FILENAME =
"/resource-upgrade-test-plugin-2.0.0.jar";
private static final String FAILING_PLUGIN_FILE_NAME =
"/resource-upgrade-test-plugin-3.0.0.jar";
-
+
private static final String SINGLETON_RESOURCE_TYPE_NAME = "Resource";
private static final String SINGLETON_RESOURCE_TYPE_PLUGIN_NAME =
"ResourceUpgradeTest";
- private static final ResType SINGLETON_TYPE = new
ResType(SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME);
-
+ private static final ResType SINGLETON_TYPE = new
ResType(SINGLETON_RESOURCE_TYPE_NAME,
+ SINGLETON_RESOURCE_TYPE_PLUGIN_NAME);
+
private static List<ResType> getMyExpectedTypes() {
return Arrays.asList(SINGLETON_TYPE);
}
-
+
protected Collection<String> getRequiredPlugins() {
return Arrays.asList(PLUGIN_V1_FILENAME, PLUGIN_V2_FILENAME,
FAILING_PLUGIN_FILE_NAME);
}
-
+
@Test
public void testIgnoreUncommittedResources() throws Exception {
setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.NEW);
-
- TestPayload testNoChange = new AbstractTestPayload(false, getMyExpectedTypes()) {
+
+ TestPayload testNoChange = new AbstractTestPayload(false, getMyExpectedTypes())
{
public void test(Map<ResType, Set<Resource>> discoveredResources)
{
- assertEquals(discoveredResources.size(), 1, "Expected single test
resource but multiple found.");
-
+ assertEquals(discoveredResources.get(SINGLETON_TYPE).size(), 1,
+ "Expected single test resource but multiple found.");
+
Resource discoveredResource =
discoveredResources.get(SINGLETON_TYPE).iterator().next();
assertEquals(discoveredResource.getResourceKey(),
"resource-key-v1");
assertEquals(discoveredResource.getName(),
"resource-name-v1");
assertEquals(discoveredResource.getDescription(),
"resource-description-v1");
}
-
+
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
defineDefaultExpectations(this);
-
- between(1,
4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+
+ between(1,
4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
}
};
}
};
-
+
executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), testNoChange);
}
-
+
@Test
public void testUpgradeData() throws Exception {
setCurrentServerSideInventory(new FakeServerInventory());
upgradeTest(false);
}
-
+
@Test
public void testInventoryReinitializationFromServerDuringUpgrade() throws Exception
{
setCurrentServerSideInventory(new FakeServerInventory());
upgradeTest(true);
}
-
+
@Test
public void testSkipUpgradeWhenServerUnavailable() throws Exception {
setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
-
+
getCurrentServerSideInventory().setFailing(true);
- TestPayload test = new AbstractTestPayload(false, getMyExpectedTypes()) {
+ TestPayload test = new AbstractTestPayload(false, getMyExpectedTypes()) {
public void test(Map<ResType, Set<Resource>> discoveredResources)
{
- assertEquals(discoveredResources.size(), 1, "Expected single test
resource but multiple found.");
-
+ assertEquals(discoveredResources.get(SINGLETON_TYPE).size(), 1,
+ "Expected single test resource but multiple found.");
+
Resource discoveredResource =
discoveredResources.get(SINGLETON_TYPE).iterator().next();
-
+
assertEquals(discoveredResource.getResourceKey(),
"resource-key-v1");
assertEquals(discoveredResource.getName(),
"resource-name-v1");
assertEquals(discoveredResource.getDescription(),
"resource-description-v1");
}
-
+
@SuppressWarnings("unchecked")
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
defineDefaultExpectations(this);
-
- between(1,
4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+
+ between(1,
4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
-
+
never(getCurrentDiscoveryServerService()).upgradeResources(with(any(Set.class)));
}
};
}
};
-
+
executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), test);
}
-
+
@Test
public void testUpgradeWithPlatformDeletedOnServer() throws Exception {
setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
-
- TestPayload test = new AbstractTestPayload(false, getMyExpectedTypes()) {
+
+ TestPayload test = new AbstractTestPayload(false, getMyExpectedTypes()) {
public void test(Map<ResType, Set<Resource>> discoveredResources)
{
- assertEquals(discoveredResources.size(), 1, "Expected single test
resource but multiple found.");
-
+ assertEquals(discoveredResources.get(SINGLETON_TYPE).size(), 1,
+ "Expected single test resource but multiple found.");
+
Resource discoveredResource =
discoveredResources.get(SINGLETON_TYPE).iterator().next();
-
+
assertEquals(discoveredResource.getResourceKey(),
"resource-key-v2");
assertEquals(discoveredResource.getName(),
"resource-name-v2");
assertEquals(discoveredResource.getDescription(),
"resource-description-v2");
- ResourceContainer container =
PluginContainer.getInstance().getInventoryManager().getResourceContainer(discoveredResource);
+ ResourceContainer container =
PluginContainer.getInstance().getInventoryManager()
+ .getResourceContainer(discoveredResource);
File dataDir = container.getResourceContext().getDataDirectory();
-
+
File marker = new File(dataDir, "upgrade-succeeded");
-
- assertFalse(marker.exists(), "The upgrade seems to have occured even
though there shouldn't have been a resource to upgrade.");
+
+ assertFalse(marker.exists(),
+ "The upgrade seems to have occured even though there
shouldn't have been a resource to upgrade.");
}
-
+
@SuppressWarnings("unchecked")
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
defineDefaultExpectations(this);
-
+
//the first merge will be triggered from within the upgrade
process and we are
//going to report null sync.
-
oneOf(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+ oneOf(getCurrentDiscoveryServerService())
+ .mergeInventoryReport(with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().clearPlatform());
-
+
//the rest of the inventory merges are executed by discoveries,
so let's import the
//discovered stuff into the server-side inventory.
- between(1,
3).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+ between(1,
3).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
-
+
never(getCurrentDiscoveryServerService()).upgradeResources(with(any(Set.class)));
}
};
}
};
-
+
executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), test);
}
-
+
@Test
public void testUpgradeFailureHandling() throws Exception {
setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
-
- TestPayload test = new AbstractTestPayload(false, getMyExpectedTypes()) {
+
+ TestPayload test = new AbstractTestPayload(false, getMyExpectedTypes()) {
public void test(Map<ResType, Set<Resource>>
resourceUpgradeTestResources) {
- assertEquals(resourceUpgradeTestResources.size(), 1, "Expected
single test resource but multiple found.");
-
+ assertEquals(resourceUpgradeTestResources.get(SINGLETON_TYPE).size(), 1,
+ "Expected single test resource but multiple found.");
+
Resource discoveredResource =
resourceUpgradeTestResources.get(SINGLETON_TYPE).iterator().next();
-
- assertTrue(discoveredResource.getResourceErrors().size() > 0,
"There should be upgrade errors persisted on the server side.");
-
+
+ assertTrue(discoveredResource.getResourceErrors().size() > 0,
+ "There should be upgrade errors persisted on the server
side.");
+
//the discovery of the failed resource mustn't have run
- ResourceContainer container =
PluginContainer.getInstance().getInventoryManager().getResourceContainer(discoveredResource);
+ ResourceContainer container =
PluginContainer.getInstance().getInventoryManager()
+ .getResourceContainer(discoveredResource);
File dataDir = container.getResourceContext().getDataDirectory();
-
+
File marker = new File(dataDir, "failing-discovery-ran");
-
- assertFalse(marker.exists(), "The discovery of the resource type
with a failed upgraded resource must not be executed but it was.");
+
+ assertFalse(marker.exists(),
+ "The discovery of the resource type with a failed upgraded
resource must not be executed but it was.");
}
-
+
@SuppressWarnings("unchecked")
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
defineDefaultExpectations(this);
-
- between(1,
4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+
+ between(1,
4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
-
+
oneOf(getCurrentDiscoveryServerService()).upgradeResources(with(any(Set.class)));
will(getCurrentServerSideInventory().upgradeResources());
}
};
}
};
-
+
executeTestWithPlugins(Collections.singleton(FAILING_PLUGIN_FILE_NAME), test);
}
-
+
private void initialSyncAndDiscovery(final InventoryStatus requiredInventoryStatus)
throws Exception {
cleanDataDir();
- executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), new
AbstractTestPayload(true, getMyExpectedTypes()) {
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), new
AbstractTestPayload(true,
+ getMyExpectedTypes()) {
public void test(Map<ResType, Set<Resource>> discoveredResources)
{
- assertEquals(discoveredResources.size(), 1, "Expected single test
resource but multiple found.");
-
+ assertEquals(discoveredResources.get(SINGLETON_TYPE).size(), 1,
+ "Expected single test resource but multiple found.");
+
Resource discoveredResource =
discoveredResources.get(SINGLETON_TYPE).iterator().next();
-
+
assertEquals(discoveredResource.getResourceKey(),
"resource-key-v1");
assertEquals(discoveredResource.getName(),
"resource-name-v1");
assertEquals(discoveredResource.getDescription(),
"resource-description-v1");
}
-
+
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
defineDefaultExpectations(this);
-
- between(1,
4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+
+ between(1,
4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(requiredInventoryStatus));
}
};
}
- });
-
+ });
+
}
-
private void upgradeTest(boolean clearInventoryDat) throws Exception {
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
-
- executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), new
AbstractTestPayload(clearInventoryDat, getMyExpectedTypes()) {
+
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), new
AbstractTestPayload(clearInventoryDat,
+ getMyExpectedTypes()) {
public void test(Map<ResType, Set<Resource>> discoveredResources)
{
- assertEquals(discoveredResources.size(), 1, "Expected single test
resource but multiple found.");
-
+ assertEquals(discoveredResources.get(SINGLETON_TYPE).size(), 1,
+ "Expected single test resource but multiple found.");
+
Resource discoveredResource =
discoveredResources.get(SINGLETON_TYPE).iterator().next();
-
+
assertEquals(discoveredResource.getResourceKey(),
"resource-key-v2");
assertEquals(discoveredResource.getName(),
"resource-name-v2");
assertEquals(discoveredResource.getDescription(),
"resource-description-v2");
-
- ResourceContainer container =
PluginContainer.getInstance().getInventoryManager().getResourceContainer(discoveredResource);
+
+ ResourceContainer container =
PluginContainer.getInstance().getInventoryManager()
+ .getResourceContainer(discoveredResource);
File dataDir = container.getResourceContext().getDataDirectory();
-
+
File marker = new File(dataDir, "upgrade-succeeded");
-
- assertTrue(marker.exists(), "The upgrade success marker file
wasn't found. This means the upgrade didn't actually run.");
+
+ assertTrue(marker.exists(),
+ "The upgrade success marker file wasn't found. This means
the upgrade didn't actually run.");
}
@SuppressWarnings("unchecked")
@@ -290,10 +312,11 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
return new Expectations() {
{
defineDefaultExpectations(this);
-
- between(1,
4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+
+ between(1,
4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
-
+
oneOf(getCurrentDiscoveryServerService()).upgradeResources(with(any(Set.class)));
will(getCurrentServerSideInventory().upgradeResources());
}
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponent.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponent.java
index c5bbf3a..04d3767 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponent.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponent.java
@@ -19,11 +19,18 @@
package org.rhq.core.pc.upgrade.plugins.multi.base;
-import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.Property;
+import org.rhq.core.domain.configuration.PropertyList;
+import org.rhq.core.domain.configuration.PropertyMap;
+import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
import org.rhq.core.pluginapi.inventory.ResourceComponent;
@@ -33,13 +40,11 @@ import org.rhq.core.pluginapi.inventory.ResourceContext;
*
* @author Lukas Krejci
*/
-public class BaseResourceComponent<T extends ResourceComponent> implements
ResourceComponent<T> {
+public class BaseResourceComponent<T extends ResourceComponent> implements
ResourceComponent<T>, BaseResourceComponentInterface {
private ResourceContext<T> context;
private final Log log = LogFactory.getLog(getClass());
- private Set<Integer> childrenToFailUpgrade;
-
public AvailabilityType getAvailability() {
return AvailabilityType.UP;
}
@@ -57,11 +62,57 @@ public class BaseResourceComponent<T extends ResourceComponent>
implements Resou
return
context.getPluginConfiguration().getSimple("ordinal").getIntegerValue();
}
- public Set<Integer> getChildrenToFailUpgrade() {
- return childrenToFailUpgrade == null ? Collections.<Integer>emptySet() :
childrenToFailUpgrade;
+ public Map<String, Set<Integer>> getChildrenToFailUpgrade() {
+
+ Map<String, Set<Integer>> ret = new HashMap<String,
Set<Integer>>();
+
+ Configuration pluginConfig = context.getPluginConfiguration();
+ PropertyList childrenToFail = pluginConfig.getList("childrenToFail");
+
+ if (childrenToFail != null) {
+ for(Property p : childrenToFail.getList()) {
+ PropertyMap entry = (PropertyMap) p;
+
+ String type = entry.getSimpleValue("type", null);
+
+ PropertyList typeList = entry.getList("children");
+
+ if (type != null && typeList != null) {
+ Set<Integer> ordinals = new HashSet<Integer>();
+
+ for(Property pp : typeList.getList()) {
+ ordinals.add(((PropertySimple)pp).getIntegerValue());
+ }
+
+ ret.put(type, ordinals);
+ }
+ }
+ }
+
+ return ret;
}
- public void setChildrenToFailUpgrade(Set<Integer> childrenToFailUpgrade) {
- this.childrenToFailUpgrade = childrenToFailUpgrade;
+ public Configuration createPluginConfigurationWithMarkedFailures(Map<String,
Set<Integer>> childrenToFailUpgrade) {
+ Configuration ret = context.getPluginConfiguration().clone();
+ PropertyList list = new PropertyList("childrenToFail");
+
+ for(Map.Entry<String, Set<Integer>> entry :
childrenToFailUpgrade.entrySet()) {
+ PropertyMap configEntry = new PropertyMap("childrenInType");
+ configEntry.put(new PropertySimple("type", entry.getKey()));
+
+ PropertyList typeList = new PropertyList("children");
+
+ for(Integer childOrdinal : entry.getValue()) {
+ typeList.add(new PropertySimple("ordinal", childOrdinal));
+ }
+
+ configEntry.put(typeList);
+
+ list.add(configEntry);
+ }
+
+ ret.put(list);
+
+ return ret;
}
}
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponentInterface.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponentInterface.java
new file mode 100644
index 0000000..1c9bef0
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponentInterface.java
@@ -0,0 +1,36 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.upgrade.plugins.multi.base;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.rhq.core.domain.configuration.Configuration;
+
+/**
+ * This is to support proxying to required methods from the tests.
+ *
+ * @author Lukas Krejci
+ */
+public interface BaseResourceComponentInterface {
+
+ Configuration createPluginConfigurationWithMarkedFailures(Map<String,
Set<Integer>> childrenToFailUpgrade);
+
+}
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java
index ec1cb20..5b8af94 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java
@@ -19,6 +19,8 @@
package org.rhq.core.pc.upgrade.plugins.multi.base;
+import java.util.Set;
+
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
@@ -41,7 +43,10 @@ public class BaseUpgradingDiscoveryComponent<T extends
BaseResourceComponent> ex
boolean fail =
Boolean.getBoolean(pluginConfig.getSimpleValue("failUpgrade",
"false"));
if (!fail && parent != null) {
- fail = parent.getChildrenToFailUpgrade().contains(Integer.valueOf(ordinal));
+ String typeName = inventoriedResource.getResourceType().getName();
+ Set<Integer> failingOrdinals =
parent.getChildrenToFailUpgrade().get(typeName);
+
+ fail = failingOrdinals != null &&
failingOrdinals.contains(Integer.valueOf(ordinal));
}
if (fail) {
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/NothingDiscoveringDiscoveryComponent.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/NothingDiscoveringDiscoveryComponent.java
new file mode 100644
index 0000000..b6189e5
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/NothingDiscoveringDiscoveryComponent.java
@@ -0,0 +1,42 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.upgrade.plugins.multi.base;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+
+/**
+ *
+ * @author Lukas Krejci
+ */
+public class NothingDiscoveringDiscoveryComponent<T extends ResourceComponent>
implements ResourceDiscoveryComponent<T> {
+
+ public Set<DiscoveredResourceDetails>
discoverResources(ResourceDiscoveryContext<T> context)
+ throws InvalidPluginConfigurationException, Exception {
+
+ return Collections.emptySet();
+ }
+}
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
index d3ea7b7..e3b4f9b 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
@@ -11,7 +11,7 @@
<depends plugin="base" useClasses="true"/>
- <server name="Bogus" class="BaseDiscoveryComponent">
+ <server name="Bogus" class="BaseDiscoveryComponent"
discovery="NothingDiscoveringDiscoveryComponent">
<!-- This service is put in the type hierarchy in the v1/v2 test plugins -->
<service name="TestResourceSibling"
discovery="BaseDiscoveryComponent"
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
index f7f7a2c..e7792b9 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
@@ -10,7 +10,7 @@
<depends plugin="base" useClasses="true"/>
- <server name="Bogus" class="BaseDiscoveryComponent">
+ <server name="Bogus" class="BaseDiscoveryComponent"
discovery="NothingDiscoveringDiscoveryComponent">
<!-- This service is put in the type hierarchy in the v1/v2 test plugins -->
<service name="TestResourceSibling"
discovery="BaseUpgradingDiscoveryComponent"
commit e6dd8c2618a009053b06c3f63fff808fc5e64dbf
Merge: 14fd25e... 3c5a00e...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Oct 1 12:58:36 2010 +0200
Merge branch 'master' into resource-upgrade
commit 14fd25e86c1a4013c1047c343f3860720a3f9c68
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Oct 1 12:55:37 2010 +0200
Adapted the resource upgrade test infrastructure to work with the new requirements of
the failure handling tests and added the first round of the failure handling tests.
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
index adb3989..39597ee 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
@@ -59,68 +59,69 @@ public class FakeServerInventory {
private Map<String, Resource> resourceStore = new HashMap<String,
Resource>();
private int counter;
private boolean failing;
-
+
private static final Comparator<Resource> ID_COMPARATOR = new
Comparator<Resource>() {
public int compare(Resource o1, Resource o2) {
return o1.getId() - o2.getId();
}
};
-
+
private static final Comparator<Resource> RESOURCE_TYPE_COMPARATOR = new
Comparator<Resource>() {
public int compare(Resource o1, Resource o2) {
return o1.getResourceType().equals(o2.getResourceType()) ? 0 : o1.getId() -
o2.getId();
}
};
-
+
public FakeServerInventory() {
this(false);
}
-
+
public FakeServerInventory(boolean failing) {
this.failing = failing;
}
-
+
//need to synchronize, because resource upgrade is async and can overlap with
//resource discovery.
public synchronized CustomAction mergeInventoryReport(final InventoryStatus
requiredInventoryStatus) {
return new CustomAction("updateServerSideInventory") {
public Object invoke(Invocation invocation) throws Throwable {
throwIfFailing();
-
+
InventoryReport inventoryReport = (InventoryReport)
invocation.getParameter(0);
-
- for(Resource res : inventoryReport.getAddedRoots()) {
+
+ for (Resource res : inventoryReport.getAddedRoots()) {
+ Resource persisted = fakePersist(res, requiredInventoryStatus, new
HashSet<String>());
+
if (res.getParentResource() == Resource.ROOT) {
- platform = fakePersist(res, requiredInventoryStatus, new
HashSet<String>());
- break;
+ platform = persisted;
}
}
return getSyncInfo();
- }
+ }
};
}
-
+
public synchronized CustomAction clearPlatform() {
return new CustomAction("updateServerSideInventory - report platform deleted
on the server") {
public Object invoke(Invocation invocation) throws Throwable {
throwIfFailing();
-
+
platform = null;
-
+
return getSyncInfo();
}
};
}
-
+
public synchronized CustomAction upgradeResources() {
return new CustomAction("upgradeServerSideInventory") {
- @SuppressWarnings({"serial", "unchecked"})
+ @SuppressWarnings({ "serial", "unchecked" })
public Object invoke(Invocation invocation) throws Throwable {
throwIfFailing();
-
+
Set<ResourceUpgradeRequest> requests =
(Set<ResourceUpgradeRequest>) invocation.getParameter(0);
Set<ResourceUpgradeResponse> responses = new
HashSet<ResourceUpgradeResponse>();
-
+
for (final ResourceUpgradeRequest request : requests) {
Resource resource = findResource(platform, new Resource() {
public int getId() {
@@ -134,16 +135,18 @@ public class FakeServerInventory {
if (request.getNewName() != null) {
resource.setName(request.getNewName());
}
-
+
if (request.getNewResourceKey() != null) {
resource.setResourceKey(request.getNewResourceKey());
}
-
+
if (request.getUpgradeErrorMessage() != null) {
- ResourceError error = new ResourceError(resource,
ResourceErrorType.UPGRADE, request.getUpgradeErrorMessage(),
request.getUpgradeErrorStackTrace(), request.getTimestamp());
+ ResourceError error = new ResourceError(resource,
ResourceErrorType.UPGRADE,
+ request.getUpgradeErrorMessage(),
request.getUpgradeErrorStackTrace(),
+ request.getTimestamp());
resource.getResourceErrors().add(error);
}
-
+
ResourceUpgradeResponse resp = new ResourceUpgradeResponse();
resp.setResourceId(resource.getId());
resp.setUpgradedResourceName(resource.getName());
@@ -156,21 +159,21 @@ public class FakeServerInventory {
}
};
}
-
+
public synchronized CustomAction getResources() {
return new CustomAction("getResources") {
@SuppressWarnings("unchecked")
public Object invoke(Invocation invocation) throws Throwable {
throwIfFailing();
-
- Set<Integer> resourceIds =
(Set<Integer>)invocation.getParameter(0);
+
+ Set<Integer> resourceIds = (Set<Integer>)
invocation.getParameter(0);
boolean includeDescendants = (Boolean) invocation.getParameter(1);
-
+
return getResources(resourceIds, includeDescendants);
}
- };
+ };
}
-
+
public boolean isFailing() {
return failing;
}
@@ -191,12 +194,12 @@ public class FakeServerInventory {
}
return result;
}
-
+
@SuppressWarnings("serial")
- private Set<Resource> getResources(Set<Integer> resourceIds, boolean
includeDescendants) {
+ private Set<Resource> getResources(Set<Integer> resourceIds, boolean
includeDescendants) {
Set<Resource> result = new HashSet<Resource>();
-
- for(final Integer id : resourceIds) {
+
+ for (final Integer id : resourceIds) {
Resource r = findResource(platform, new Resource() {
public int getId() {
return id;
@@ -204,19 +207,20 @@ public class FakeServerInventory {
}, ID_COMPARATOR);
if (r != null) {
result.add(r);
-
+
if (includeDescendants) {
- for(Resource child : r.getChildResources()) {
+ for (Resource child : r.getChildResources()) {
result.addAll(getResources(Collections.singleton(child.getId()),
true));
}
}
}
}
-
+
return result;
}
-
- private Resource fakePersist(Resource agentSideResource, InventoryStatus
requiredInventoryStatus, Set<String> inProgressUUIds) {
+
+ private Resource fakePersist(Resource agentSideResource, InventoryStatus
requiredInventoryStatus,
+ Set<String> inProgressUUIds) {
Resource persisted = resourceStore.get(agentSideResource.getUuid());
if (!inProgressUUIds.add(agentSideResource.getUuid())) {
return persisted;
@@ -237,94 +241,114 @@ public class FakeServerInventory {
persisted.setInventoryStatus(requiredInventoryStatus);
persisted.setResourceKey(agentSideResource.getResourceKey());
persisted.setResourceType(agentSideResource.getResourceType());
-
+
Resource parent = agentSideResource.getParentResource();
if (parent != null && parent != Resource.ROOT) {
-
persisted.setParentResource(fakePersist(agentSideResource.getParentResource(),
requiredInventoryStatus, inProgressUUIds));
+
persisted.setParentResource(fakePersist(agentSideResource.getParentResource(),
requiredInventoryStatus,
+ inProgressUUIds));
} else {
persisted.setParentResource(parent);
}
Set<Resource> childResources = new HashSet<Resource>();
persisted.setChildResources(childResources);
- for(Resource child : agentSideResource.getChildResources()) {
+ for (Resource child : agentSideResource.getChildResources()) {
childResources.add(fakePersist(child, requiredInventoryStatus,
inProgressUUIds));
}
-
+
inProgressUUIds.remove(agentSideResource.getUuid());
-
+
return persisted;
}
-
+
private ResourceSyncInfo getSyncInfo() {
return platform != null ? convert(platform) : null;
}
-
+
private void throwIfFailing() {
if (failing) {
throw new RuntimeException("Fake server inventory is in the failing
mode.");
}
}
-
+
private static ResourceSyncInfo convert(Resource root) {
+ return convertInternal(root, new HashMap<String, ResourceSyncInfo>());
+ }
+
+ private static ResourceSyncInfo convertInternal(Resource root, Map<String,
ResourceSyncInfo> intermediateResults) {
+ ResourceSyncInfo ret = intermediateResults.get(root.getUuid());
+
+ if (ret != null) {
+ return ret;
+ }
+
try {
- ResourceSyncInfo ret = new ResourceSyncInfo();
-
+ ret = new ResourceSyncInfo();
+
+ intermediateResults.put(root.getUuid(), ret);
+
Class<ResourceSyncInfo> clazz = ResourceSyncInfo.class;
getPrivateField(clazz, "id").set(ret, root.getId());
getPrivateField(clazz, "uuid").set(ret, root.getUuid());
getPrivateField(clazz, "mtime").set(ret, root.getMtime());
getPrivateField(clazz, "inventoryStatus").set(ret,
root.getInventoryStatus());
- getPrivateField(clazz, "parent").set(ret, null);
-
+
+ ResourceSyncInfo parent = root.getParentResource() == null ? null :
convertInternal(
+ root.getParentResource(), intermediateResults);
+
+ getPrivateField(clazz, "parent").set(ret, parent);
+
Set<ResourceSyncInfo> children = new
LinkedHashSet<ResourceSyncInfo>();
- for(Resource child : root.getChildResources()) {
- ResourceSyncInfo syncChild = convert(child);
- getPrivateField(clazz, "parent").set(syncChild, ret);
-
- children.add(convert(child));
- }
+ for (Resource child : root.getChildResources()) {
+ ResourceSyncInfo syncChild = convertInternal(child,
intermediateResults);
+
+ children.add(syncChild);
+ }
getPrivateField(clazz, "childSyncInfos").set(ret, children);
-
+
return ret;
} catch (Exception e) {
fail("Failed to convert resource " + root + " to a
ResourceSyncInfo. This should not happen.", e);
return null;
}
- }
-
+ }
+
private static Field getPrivateField(Class<?> clazz, String fieldName) throws
NoSuchFieldException {
Field field = clazz.getDeclaredField(fieldName);
if (!field.isAccessible()) {
field.setAccessible(true);
}
-
+
return field;
}
-
+
private static Resource findResource(Resource root, Resource template,
Comparator<Resource> comparator) {
- if (root == null) return null;
+ if (root == null)
+ return null;
if (comparator.compare(root, template) == 0) {
return root;
} else {
- for(Resource child : root.getChildResources()) {
+ for (Resource child : root.getChildResources()) {
Resource found = findResource(child, template, comparator);
- if (found != null) return found;
+ if (found != null)
+ return found;
}
}
-
+
return null;
- }
-
- private static void findResources(Resource root, Resource template,
Set<Resource> result, Comparator<Resource> comparator) {
- if (root == null) return;
+ }
+
+ private static void findResources(Resource root, Resource template,
Set<Resource> result,
+ Comparator<Resource> comparator) {
+ if (root == null)
+ return;
if (comparator.compare(root, template) == 0) {
result.add(root);
} else {
- for(Resource child : root.getChildResources()) {
+ for (Resource child : root.getChildResources()) {
findResources(child, template, result, comparator);
}
- }
+ }
}
}
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 25eca30..5949b76 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
@@ -19,11 +19,29 @@
package org.rhq.core.pc.upgrade;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
import org.testng.annotations.Test;
+import org.rhq.core.clientapi.server.discovery.InvalidInventoryReportException;
+import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.domain.resource.InventoryStatus;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
+
/**
* The plugins and their resource types form the following dependency structure:
* <pre>
@@ -35,6 +53,10 @@ import org.testng.annotations.Test;
* </pre>
* The dependencies in the above "chart" are formed using either the
<code><runs-inside></code>
* or <code>sourcePlugin/sourceType</code> approaches just to test that both
are handled correctly.
+ * <p>
+ * The <code>parentdep</code>, <code>parentsibling</code>,
<code>test</code> and <code>sibling</code> plugins are present
+ * in two versions and support the {@link ResourceUpgradeFacet}, while the rest of the
plugins is
+ * present only in single version.
*
* @author Lukas Krejci
*/
@@ -53,29 +75,149 @@ public class ResourceUpgradeFailureHandlingTest extends
ResourceUpgradeTestBase
private static final String TEST_V1_PLUGIN_NAME =
"/resource-upgrade-test-plugin-multi-test-1.0.0.jar";
private static final String TEST_V2_PLUGIN_NAME =
"/resource-upgrade-test-plugin-multi-test-2.0.0.jar";
+ private static final String UPGRADED_RESOURCE_KEY_PREFIX = "UPGRADED";
+
+ private static final HashMap<String, List<String>> DEPS;
+
+ static {
+ DEPS = new HashMap<String, List<String>>();
+
+ DEPS.put(BASE_PLUGIN_NAME, Collections.<String> emptyList());
+ DEPS.put(PARENT_DEP_V1_PLUGIN_NAME, Arrays.asList(BASE_PLUGIN_NAME,
ROOT_PLUGIN_NAME));
+ DEPS.put(PARENT_DEP_V2_PLUGIN_NAME, DEPS.get(PARENT_DEP_V1_PLUGIN_NAME));
+ DEPS.put(PARENT_SIBLING_V1_PLUGIN_NAME, Arrays.asList(BASE_PLUGIN_NAME,
ROOT_PLUGIN_NAME));
+ DEPS.put(PARENT_SIBLING_V2_PLUGIN_NAME,
DEPS.get(PARENT_SIBLING_V1_PLUGIN_NAME));
+ DEPS.put(ROOT_PLUGIN_NAME, Arrays.asList(BASE_PLUGIN_NAME));
+ DEPS.put(SIBLING_V1_PLUGIN_NAME, Arrays.asList(BASE_PLUGIN_NAME,
ROOT_PLUGIN_NAME, PARENT_DEP_V1_PLUGIN_NAME));
+ DEPS.put(SIBLING_V2_PLUGIN_NAME, Arrays.asList(BASE_PLUGIN_NAME,
ROOT_PLUGIN_NAME, PARENT_DEP_V2_PLUGIN_NAME));
+ DEPS.put(TEST_V1_PLUGIN_NAME,
+ Arrays.asList(BASE_PLUGIN_NAME, ROOT_PLUGIN_NAME, PARENT_DEP_V1_PLUGIN_NAME,
SIBLING_V1_PLUGIN_NAME));
+ DEPS.put(TEST_V2_PLUGIN_NAME,
+ Arrays.asList(BASE_PLUGIN_NAME, ROOT_PLUGIN_NAME, PARENT_DEP_V1_PLUGIN_NAME,
SIBLING_V2_PLUGIN_NAME));
+ }
+
+ private static final ResType TEST_TYPE = new ResType("TestResource",
"test");
+ private static final ResType SIBLING_TYPE = new
ResType("TestResourceSibling", "test");
+ private static final ResType PARENT_TYPE = new
ResType("TestResourceParent", "test");
+ private static final ResType PARENT_DEP_TYPE = new
ResType("ParentDependency", "parentdep");
+ private static final ResType PARENT_SIBLING_TYPE = new
ResType("ParentDepSibling", "parentsibling");
+ private static final ResType ROOT_TYPE = new ResType("Root",
"root");
+
protected Collection<String> getRequiredPlugins() {
return Arrays.asList(BASE_PLUGIN_NAME, PARENT_DEP_V1_PLUGIN_NAME,
PARENT_DEP_V2_PLUGIN_NAME,
PARENT_SIBLING_V1_PLUGIN_NAME, PARENT_SIBLING_V2_PLUGIN_NAME,
ROOT_PLUGIN_NAME, SIBLING_V1_PLUGIN_NAME,
SIBLING_V2_PLUGIN_NAME, TEST_V1_PLUGIN_NAME, TEST_V2_PLUGIN_NAME);
}
-
+
@Test
- public void testSuccess() {
- //TODO implement
- //check that all the stuff is properly upgraded on success
+ public void testSuccess() throws Exception {
+ setCurrentServerSideInventory(new FakeServerInventory());
+
+ //let it all run in v1
+ executeTestWithPlugins(getAllDepsFor(TEST_V1_PLUGIN_NAME,
PARENT_SIBLING_V1_PLUGIN_NAME),
+ new AbstractTestPayload(true, Collections.<ResType> emptyList()) {
+ public void test(Map<ResType, Set<Resource>>
resourceUpgradeTestResources) {
+ }
+
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+ }
+ };
+ }
+ });
+
+ //now let's run with v2 plugins and check the layout of the inventory
+ executeTestWithPlugins(
+ getAllDepsFor(TEST_V2_PLUGIN_NAME, PARENT_SIBLING_V2_PLUGIN_NAME),
+ new AbstractTestPayload(false, Arrays.asList(TEST_TYPE, SIBLING_TYPE,
PARENT_TYPE, PARENT_DEP_TYPE,
+ PARENT_SIBLING_TYPE, ROOT_TYPE)) {
+
+ public void test(Map<ResType, Set<Resource>> resources) {
+ checkPresenceOfResourceTypes(resources, getExpectedResourceTypes());
+
+ checkNumberOfResources(resources, ROOT_TYPE, 1);
+ checkNumberOfResources(resources, PARENT_DEP_TYPE, 1);
+ checkNumberOfResources(resources, PARENT_SIBLING_TYPE, 1);
+ checkNumberOfResources(resources, PARENT_TYPE, 2);
+ checkNumberOfResources(resources, SIBLING_TYPE, 30);
+ checkNumberOfResources(resources, TEST_TYPE, 30);
+
+ //check that the resources are upgraded
+ checkResourcesUpgraded(resources.get(PARENT_SIBLING_TYPE));
+ checkResourcesUpgraded(resources.get(PARENT_TYPE));
+ checkResourcesUpgraded(resources.get(SIBLING_TYPE));
+ checkResourcesUpgraded(resources.get(TEST_TYPE));
+ }
+
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+ }
+ };
+ }
+ });
}
-
+
@Test
public void testFailureOnLeaf() {
//TODO implement
//check that the system behaves correctly if there is an upgrade failure
//at the leaf node of the plugin dep graph
}
-
+
@Test
public void testFailureOnDependencies() {
//TODO implement
//check that stuff works if there is an upgrade failure on some of the resources
//in the plugin some "in the middle" of the plugin dep graph
}
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void defineDefaultExpectations(Expectations expectations) {
+ super.defineDefaultExpectations(expectations);
+ try {
+ expectations.allowing(getCurrentDiscoveryServerService())
+
.mergeInventoryReport(expectations.with(Expectations.any(InventoryReport.class)));
+
expectations.will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
+
+
expectations.allowing(getCurrentDiscoveryServerService()).upgradeResources(expectations.with(Expectations.any(Set.class)));
+ expectations.will(getCurrentServerSideInventory().upgradeResources());
+
+
expectations.allowing(getCurrentDiscoveryServerService()).postProcessNewlyCommittedResources(
+ expectations.with(Expectations.any(Set.class)));
+
+ } catch (InvalidInventoryReportException e) {
+ //this is not going to happen because we're mocking the invocation
+ }
+ }
+
+ private Set<String> getAllDepsFor(String... plugins) {
+ HashSet<String> deps = new HashSet<String>();
+ for (String plugin : plugins) {
+ deps.add(plugin);
+ deps.addAll(DEPS.get(plugin));
+ }
+
+ return deps;
+ }
+
+ private static void checkPresenceOfResourceTypes(Map<ResType,
Set<Resource>> resources, Set<ResType> expectedTypes) {
+ for (ResType resType : expectedTypes) {
+ assertNotNull(resources.get(resType), "Expecting some resources of type
" + resType);
+ }
+ }
+
+ private static void checkNumberOfResources(Map<ResType, Set<Resource>>
resources, ResType type, int count) {
+ assertEquals(resources.get(type).size(), count, "Unexpected number of "
+ type + " discovered.");
+ }
+
+ private static void checkResourcesUpgraded(Set<Resource> resources) {
+ for(Resource res : resources) {
+ assertTrue(res.getResourceKey().startsWith(UPGRADED_RESOURCE_KEY_PREFIX),
"Resource " + res + " doesn't seem to be upgraded even though it
should.");
+ }
+ }
}
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 8cfec36..d47d00c 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -31,6 +31,8 @@ import java.io.File;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.jmock.Expectations;
@@ -54,8 +56,13 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
private static final String PLUGIN_V2_FILENAME =
"/resource-upgrade-test-plugin-2.0.0.jar";
private static final String FAILING_PLUGIN_FILE_NAME =
"/resource-upgrade-test-plugin-3.0.0.jar";
- static final String SINGLETON_RESOURCE_TYPE_NAME = "Resource";
- static final String SINGLETON_RESOURCE_TYPE_PLUGIN_NAME =
"ResourceUpgradeTest";
+ private static final String SINGLETON_RESOURCE_TYPE_NAME = "Resource";
+ private static final String SINGLETON_RESOURCE_TYPE_PLUGIN_NAME =
"ResourceUpgradeTest";
+ private static final ResType SINGLETON_TYPE = new
ResType(SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME);
+
+ private static List<ResType> getMyExpectedTypes() {
+ return Arrays.asList(SINGLETON_TYPE);
+ }
protected Collection<String> getRequiredPlugins() {
return Arrays.asList(PLUGIN_V1_FILENAME, PLUGIN_V2_FILENAME,
FAILING_PLUGIN_FILE_NAME);
@@ -66,11 +73,11 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.NEW);
- TestPayload testNoChange = new AbstractTestPayload(false,
SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
- public void test(Set<Resource> discoveredResources) {
+ TestPayload testNoChange = new AbstractTestPayload(false, getMyExpectedTypes()) {
+ public void test(Map<ResType, Set<Resource>> discoveredResources)
{
assertEquals(discoveredResources.size(), 1, "Expected single test
resource but multiple found.");
- Resource discoveredResource = discoveredResources.iterator().next();
+ Resource discoveredResource =
discoveredResources.get(SINGLETON_TYPE).iterator().next();
assertEquals(discoveredResource.getResourceKey(),
"resource-key-v1");
assertEquals(discoveredResource.getName(),
"resource-name-v1");
@@ -111,11 +118,11 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
getCurrentServerSideInventory().setFailing(true);
- TestPayload test = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME,
SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
- public void test(Set<Resource> discoveredResources) {
+ TestPayload test = new AbstractTestPayload(false, getMyExpectedTypes()) {
+ public void test(Map<ResType, Set<Resource>> discoveredResources)
{
assertEquals(discoveredResources.size(), 1, "Expected single test
resource but multiple found.");
- Resource discoveredResource = discoveredResources.iterator().next();
+ Resource discoveredResource =
discoveredResources.get(SINGLETON_TYPE).iterator().next();
assertEquals(discoveredResource.getResourceKey(),
"resource-key-v1");
assertEquals(discoveredResource.getName(),
"resource-name-v1");
@@ -145,11 +152,11 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
- TestPayload test = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME,
SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
- public void test(Set<Resource> discoveredResources) {
+ TestPayload test = new AbstractTestPayload(false, getMyExpectedTypes()) {
+ public void test(Map<ResType, Set<Resource>> discoveredResources)
{
assertEquals(discoveredResources.size(), 1, "Expected single test
resource but multiple found.");
- Resource discoveredResource = discoveredResources.iterator().next();
+ Resource discoveredResource =
discoveredResources.get(SINGLETON_TYPE).iterator().next();
assertEquals(discoveredResource.getResourceKey(),
"resource-key-v2");
assertEquals(discoveredResource.getName(),
"resource-name-v2");
@@ -193,11 +200,11 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
- TestPayload test = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME,
SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
- public void test(Set<Resource> resourceUpgradeTestResources) {
+ TestPayload test = new AbstractTestPayload(false, getMyExpectedTypes()) {
+ public void test(Map<ResType, Set<Resource>>
resourceUpgradeTestResources) {
assertEquals(resourceUpgradeTestResources.size(), 1, "Expected
single test resource but multiple found.");
- Resource discoveredResource =
resourceUpgradeTestResources.iterator().next();
+ Resource discoveredResource =
resourceUpgradeTestResources.get(SINGLETON_TYPE).iterator().next();
assertTrue(discoveredResource.getResourceErrors().size() > 0,
"There should be upgrade errors persisted on the server side.");
@@ -231,11 +238,11 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
private void initialSyncAndDiscovery(final InventoryStatus requiredInventoryStatus)
throws Exception {
cleanDataDir();
- executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), new
AbstractTestPayload(true, SINGLETON_RESOURCE_TYPE_NAME,
SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
- public void test(Set<Resource> discoveredResources) {
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), new
AbstractTestPayload(true, getMyExpectedTypes()) {
+ public void test(Map<ResType, Set<Resource>> discoveredResources)
{
assertEquals(discoveredResources.size(), 1, "Expected single test
resource but multiple found.");
- Resource discoveredResource = discoveredResources.iterator().next();
+ Resource discoveredResource =
discoveredResources.get(SINGLETON_TYPE).iterator().next();
assertEquals(discoveredResource.getResourceKey(),
"resource-key-v1");
assertEquals(discoveredResource.getName(),
"resource-name-v1");
@@ -260,11 +267,11 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
private void upgradeTest(boolean clearInventoryDat) throws Exception {
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
- executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), new
AbstractTestPayload(clearInventoryDat, SINGLETON_RESOURCE_TYPE_NAME,
SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
- public void test(Set<Resource> discoveredResources) {
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), new
AbstractTestPayload(clearInventoryDat, getMyExpectedTypes()) {
+ public void test(Map<ResType, Set<Resource>> discoveredResources)
{
assertEquals(discoveredResources.size(), 1, "Expected single test
resource but multiple found.");
- Resource discoveredResource = discoveredResources.iterator().next();
+ Resource discoveredResource =
discoveredResources.get(SINGLETON_TYPE).iterator().next();
assertEquals(discoveredResource.getResourceKey(),
"resource-key-v2");
assertEquals(discoveredResource.getName(),
"resource-name-v2");
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
index 3aa772b..0aefafd 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
@@ -25,6 +25,9 @@ import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import org.apache.commons.io.FileUtils;
@@ -73,6 +76,78 @@ public abstract class ResourceUpgradeTestBase {
private ResourceFactoryServerService currentResourceFactoryServerService;
private FakeServerInventory currentServerSideInventory;
+ protected static class ResType {
+ private String resourceTypeName;
+ private String resourceTypePluginName;
+
+ public ResType(String resourceTypeName, String resourceTypePluginName) {
+ super();
+ this.resourceTypeName = resourceTypeName;
+ this.resourceTypePluginName = resourceTypePluginName;
+ }
+
+ public String getResourceTypeName() {
+ return resourceTypeName;
+ }
+
+ public String getResourceTypePluginName() {
+ return resourceTypePluginName;
+ }
+
+ @Override
+ public int hashCode() {
+ return resourceTypeName.hashCode() * resourceTypePluginName.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ if (!(other instanceof ResType)) {
+ return false;
+ }
+
+ ResType o = (ResType)other;
+
+ return resourceTypeName.equals(o.getResourceTypeName()) &&
resourceTypePluginName.equals(o.getResourceTypePluginName());
+ }
+
+ @Override
+ public String toString() {
+ return "ResType[name='" + resourceTypeName + "',
plugin='" + resourceTypePluginName + "']";
+ }
+ }
+
+ protected interface TestPayload {
+ Expectations getExpectations(Mockery context) throws Exception;
+
+ void test(Map<ResType,Set<Resource>> resourceUpgradeTestResources);
+
+ boolean isClearInventoryDat();
+
+ Set<ResType> getExpectedResourceTypes();
+ }
+
+ protected static abstract class AbstractTestPayload implements TestPayload {
+ private boolean clearInventoryDat;
+ private Set<ResType> resourceTypes;
+
+ public AbstractTestPayload(boolean clearInventoryDat, Collection<ResType>
resourceTypes) {
+ this.clearInventoryDat = clearInventoryDat;
+ this.resourceTypes = new HashSet<ResType>(resourceTypes);
+ }
+
+ public boolean isClearInventoryDat() {
+ return clearInventoryDat;
+ }
+
+ public Set<ResType> getExpectedResourceTypes() {
+ return resourceTypes;
+ }
+ }
+
@BeforeClass
public void init() {
tmpDir = getTmpDirectory();
@@ -81,21 +156,21 @@ public abstract class ResourceUpgradeTestBase {
dataDir = new File(tmpDir, DATA_DIR_NAME);
assertTrue(dataDir.mkdir(), "Could not create plugin container data
directory.");
}
-
+
@BeforeClass
public void verifyPluginsExist() {
for (String plugin : getRequiredPlugins()) {
verifyPluginExists(plugin);
}
}
-
+
@AfterClass
public void undeployPlugins() throws IOException {
FileUtils.deleteDirectory(tmpDir);
}
-
+
protected abstract Collection<String> getRequiredPlugins();
-
+
protected void setCurrentServerSideInventory(FakeServerInventory
currentServerSideInventory) {
this.currentServerSideInventory = currentServerSideInventory;
}
@@ -103,8 +178,9 @@ public abstract class ResourceUpgradeTestBase {
protected FakeServerInventory getCurrentServerSideInventory() {
return currentServerSideInventory;
}
-
- protected void setCurrentResourceFactoryServerService(ResourceFactoryServerService
currentResourceFactoryServerService) {
+
+ protected void setCurrentResourceFactoryServerService(
+ ResourceFactoryServerService currentResourceFactoryServerService) {
this.currentResourceFactoryServerService = currentResourceFactoryServerService;
}
@@ -178,24 +254,24 @@ public abstract class ResourceUpgradeTestBase {
protected static File getTmpDirectory() {
File ret = new File(System.getProperty("java.io.tmpdir"),
"resource-upgrade-test" + System.currentTimeMillis());
-
+
while (ret.exists() || !ret.mkdir()) {
ret = new File(System.getProperty("java.io.tmpdir"),
"resource-upgrade-test" + System.currentTimeMillis());
}
-
+
return ret;
}
private PluginContainerConfiguration createPluginContainerConfiguration(Mockery
context) throws Exception {
PluginContainerConfiguration conf = new PluginContainerConfiguration();
-
+
conf.setPluginDirectory(new File(tmpDir, PLUGINS_DIR_NAME));
conf.setDataDirectory(new File(tmpDir, DATA_DIR_NAME));
conf.setTemporaryDirectory(new File(tmpDir, TMP_DIR_NAME));
conf.setInsideAgent(true); //pc must think it's inside an agent so that it
persists the inventory between restarts
conf.setPluginFinder(new FileSystemPluginFinder(conf.getPluginDirectory()));
- conf.setCreateResourceClassloaders(false);
-
+ conf.setCreateResourceClassloaders(false);
+
//we're not interested in any scans happening out of our control
conf.setAvailabilityScanInitialDelay(Long.MAX_VALUE);
conf.setConfigurationDiscoveryInitialDelay(Long.MAX_VALUE);
@@ -204,7 +280,7 @@ public abstract class ResourceUpgradeTestBase {
conf.setMeasurementCollectionInitialDelay(Long.MAX_VALUE);
conf.setServerDiscoveryInitialDelay(Long.MAX_VALUE);
conf.setServiceDiscoveryInitialDelay(Long.MAX_VALUE);
-
+
setCurrentBundleServerService(context.mock(BundleServerService.class));
setCurrentConfigurationServerService(context.mock(ConfigurationServerService.class));
setCurrentContentServerService(context.mock(ContentServerService.class));
@@ -214,7 +290,7 @@ public abstract class ResourceUpgradeTestBase {
setCurrentMeasurementServerService(context.mock(MeasurementServerService.class));
setCurrentOperationServerService(context.mock(OperationServerService.class));
setCurrentResourceFactoryServerService(context.mock(ResourceFactoryServerService.class));
-
+
ServerServices serverServices = new ServerServices();
serverServices.setBundleServerService(getCurrentBundleServerService());
serverServices.setConfigurationServerService(getCurrentConfigurationServerService());
@@ -225,9 +301,9 @@ public abstract class ResourceUpgradeTestBase {
serverServices.setMeasurementServerService(getCurrentMeasurementServerService());
serverServices.setOperationServerService(getCurrentOperationServerService());
serverServices.setResourceFactoryServerService(getCurrentResourceFactoryServerService());
-
+
conf.setServerServices(serverServices);
-
+
return conf;
}
@@ -236,104 +312,76 @@ public abstract class ResourceUpgradeTestBase {
*/
protected void verifyPluginExists(String pluginResourcePath) {
URL url = getClass().getResource(pluginResourcePath);
-
+
File pluginFile = FileUtils.toFile(url);
-
+
assertTrue(pluginFile.exists(), pluginFile.getAbsoluteFile() + " plugin jar
could not be found.");
}
private void copyPlugin(String pluginResourcePath, File pluginDirectory) throws
IOException {
URL pluginUrl = getClass().getResource(pluginResourcePath);
-
+
File pluginFile = new File(pluginResourcePath);
String pluginFileName = pluginFile.getName();
-
- FileUtils.copyURLToFile(pluginUrl, new File(pluginDirectory, pluginFileName));
- }
-
- protected interface TestPayload {
- Expectations getExpectations(Mockery context) throws Exception;
- void test(Set<Resource> resourceUpgradeTestResources);
- boolean isClearInventoryDat();
- String getResourceTypeName();
- String getResourceTypePluginName();
- }
-
- protected static abstract class AbstractTestPayload implements TestPayload {
- private boolean clearInventoryDat;
- private String resourceTypeName;
- private String resourceTypePluginName;
-
- public AbstractTestPayload(boolean clearInventoryDat, String
resourceTypeName, String resourceTypePluginName) {
- this.clearInventoryDat = clearInventoryDat;
- this.resourceTypeName = resourceTypeName;
- this.resourceTypePluginName = resourceTypePluginName;
- }
-
- public boolean isClearInventoryDat() {
- return clearInventoryDat;
- }
-
- public String getResourceTypeName() {
- return resourceTypeName;
- }
-
- public String getResourceTypePluginName() {
- return resourceTypePluginName;
- }
- }
- /**
- *
- */
- public ResourceUpgradeTestBase() {
- super();
+ FileUtils.copyURLToFile(pluginUrl, new File(pluginDirectory, pluginFileName));
}
private Set<Resource> getTestingResources(String resourceTypeName, String
resourceTypePluginName) {
- ResourceType resType =
PluginContainer.getInstance().getPluginManager().getMetadataManager().getType(resourceTypeName,
resourceTypePluginName);
-
+ ResourceType resType =
PluginContainer.getInstance().getPluginManager().getMetadataManager()
+ .getType(resourceTypeName, resourceTypePluginName);
+
return getCurrentServerSideInventory().findResourcesByType(resType);
}
protected void executeTestWithPlugins(Set<String> pluginResourcePaths,
TestPayload test) throws Exception {
FileUtils.cleanDirectory(new File(tmpDir, PLUGINS_DIR_NAME));
-
- for(String pluginResourcePath : pluginResourcePaths) {
+
+ for (String pluginResourcePath : pluginResourcePaths) {
copyPlugin(pluginResourcePath, pluginDir);
}
-
+
Mockery context = new Mockery();
-
+
PluginContainerConfiguration pcConfig =
createPluginContainerConfiguration(context);
-
+
if (test.isClearInventoryDat()) {
File inventoryDat = new File(pcConfig.getDataDirectory(),
"inventory.dat");
inventoryDat.delete();
}
-
+
context.checking(test.getExpectations(context));
-
+
PluginContainer.getInstance().setConfiguration(pcConfig);
PluginContainer.getInstance().initialize();
-
+
try {
//give the pc the time to finish resource upgrade
Thread.sleep(1000);
-
+
//execute full discovery
InventoryManager im = PluginContainer.getInstance().getInventoryManager();
im.executeServerScanImmediately();
- im.executeServiceScanImmediately();
-
- Set<Resource> resources =
getTestingResources(test.getResourceTypeName(), test.getResourceTypePluginName());
-
+
+ //do the service scan a couple of times so that we can commit
+ //the resources deep in the type hierarchy
+ for(int i = 0; i < 10; ++i) {
+ im.executeServiceScanImmediately();
+ }
+
+ Map<ResType, Set<Resource>> resources = new HashMap<ResType,
Set<Resource>>();
+
+ for(ResType type : test.getExpectedResourceTypes()) {
+ Set<Resource> rs = getTestingResources(type.getResourceTypeName(),
type.getResourceTypePluginName());
+ resources.put(type, rs);
+ }
+
test.test(resources);
-
+
context.assertIsSatisfied();
} finally {
- PluginContainer.getInstance().shutdown();
- }
+ PluginContainer.getInstance().shutdown();
+ }
}
@SuppressWarnings("unchecked")
@@ -346,11 +394,13 @@ public abstract class ResourceUpgradeTestBase {
expectations.ignoring(getCurrentMeasurementServerService());
expectations.ignoring(getCurrentOperationServerService());
expectations.ignoring(getCurrentResourceFactoryServerService());
-
+
//just ignore these invocations if we get a availability scan in the PC...
-
expectations.allowing(getCurrentDiscoveryServerService()).mergeAvailabilityReport(expectations.with(Expectations.any(AvailabilityReport.class)));
-
-
expectations.allowing(getCurrentDiscoveryServerService()).getResources(expectations.with(Expectations.any(Set.class)),
expectations.with(Expectations.any(boolean.class)));
+
expectations.allowing(getCurrentDiscoveryServerService()).mergeAvailabilityReport(
+ expectations.with(Expectations.any(AvailabilityReport.class)));
+
+ expectations.allowing(getCurrentDiscoveryServerService()).getResources(
+ expectations.with(Expectations.any(Set.class)),
expectations.with(Expectations.any(boolean.class)));
expectations.will(getCurrentServerSideInventory().getResources());
}
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseDiscoveryComponent.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseDiscoveryComponent.java
index 61d4fe0..a03dff5 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseDiscoveryComponent.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseDiscoveryComponent.java
@@ -46,15 +46,25 @@ public class BaseDiscoveryComponent<T extends ResourceComponent>
implements Reso
String keyTemplate = pluginConfig.getSimpleValue("key", null);
int count = pluginConfig.getSimple("count").getIntegerValue();
- int parentN =
context.getParentResourceContext().getPluginConfiguration().getSimple("ordinal")
- .getIntegerValue();
+ int parentN = 0;
+
+ if (context.getParentResourceContext() != null) {
+ PropertySimple parentOrdinalProperty =
context.getParentResourceContext().getPluginConfiguration()
+ .getSimple("ordinal");
+
+ if (parentOrdinalProperty != null) {
+ parentN = parentOrdinalProperty.getIntegerValue();
+ }
+ }
for (int i = 0; i < count; ++i) {
String key = getResourceKey(keyTemplate, i, parentN);
+ pluginConfig = context.getDefaultPluginConfiguration();
+
pluginConfig.put(new PropertySimple("ordinal", i));
-
+
DiscoveredResourceDetails detail = new
DiscoveredResourceDetails(context.getResourceType(), key, key, null,
null, pluginConfig, null);
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java
index beb36db..ec1cb20 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java
@@ -28,34 +28,36 @@ import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
*
* @author Lukas Krejci
*/
-public class BaseUpgradingDiscoveryComponent<T extends BaseResourceComponent>
extends BaseDiscoveryComponent<T> implements ResourceUpgradeFacet<T> {
+public class BaseUpgradingDiscoveryComponent<T extends BaseResourceComponent>
extends BaseDiscoveryComponent<T>
+ implements ResourceUpgradeFacet<T> {
public ResourceUpgradeReport upgrade(ResourceUpgradeContext<T>
inventoriedResource) {
Configuration pluginConfig = inventoriedResource.getPluginConfiguration();
-
+
BaseResourceComponent<?> parent =
inventoriedResource.getParentResourceComponent();
int ordinal = pluginConfig.getSimple("ordinal").getIntegerValue();
int parentOrdinal = parent == null ? 0 : parent.getOrdinal();
-
+
boolean fail =
Boolean.getBoolean(pluginConfig.getSimpleValue("failUpgrade",
"false"));
-
+
if (!fail && parent != null) {
fail = parent.getChildrenToFailUpgrade().contains(Integer.valueOf(ordinal));
}
-
+
if (fail) {
throw new RuntimeException("Failing the resource upgrade
purposefully.");
}
-
+
String newKey = pluginConfig.getSimpleValue("upgradedKey", null);
-
+
if (newKey == null) {
return null;
}
-
+
ResourceUpgradeReport report = new ResourceUpgradeReport();
-
+
report.setNewResourceKey(getResourceKey(newKey, ordinal, parentOrdinal));
- return null;
+
+ return report;
}
}
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml
index f5e6920..608793c 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml
@@ -22,8 +22,8 @@
<plugin-configuration>
<c:simple-property name="count" default="1" />
- <c:simple-property name="key"
default="test-resource-parent-sibling-%n,parent-%p" />
- <c:simple-property name="upgradedKey"
default="UPGRADED-test-resource-parent-sibling-%n,parent-%p" />
+ <c:simple-property name="key"
default="test-resource-parent-dep-sibling-%n,parent-%p" />
+ <c:simple-property name="upgradedKey"
default="UPGRADED-test-resource-parent-dep-sibling-%n,parent-%p" />
</plugin-configuration>
</server>
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml
index d138066..ddda11a 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml
@@ -22,7 +22,7 @@
<plugin-configuration>
<c:simple-property name="count" default="1" />
- <c:simple-property name="key"
default="UPGRADED-test-resource-parent-sibling-%n,parent-%p" />
+ <c:simple-property name="key"
default="UPGRADED-test-resource-parent-dep-sibling-%n,parent-%p" />
</plugin-configuration>
</server>
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
index 44a1033..d3ea7b7 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
@@ -11,10 +11,18 @@
<depends plugin="base" useClasses="true"/>
- <!-- This service is put in the type hierarchy in the v1/v2 test plugins -->
- <service name="TestResourceSibling"
- discovery="BaseDiscoveryComponent"
- class="BaseResourceComponent" />
+ <server name="Bogus" class="BaseDiscoveryComponent">
+ <!-- This service is put in the type hierarchy in the v1/v2 test plugins -->
+ <service name="TestResourceSibling"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+ <plugin-configuration>
+ <c:simple-property name="count" default="10" />
+ <c:simple-property name="key"
default="test-resource-sibling-%n,parent-%p" />
+ <c:simple-property name="upgradedKey"
default="UPGRADED-test-resource-sibling-%n,parent-%p" />
+ </plugin-configuration>
+ </service>
+ </server>
</plugin>
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
index aeab68f..f7f7a2c 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
@@ -10,10 +10,16 @@
<depends plugin="base" useClasses="true"/>
+ <server name="Bogus" class="BaseDiscoveryComponent">
<!-- This service is put in the type hierarchy in the v1/v2 test plugins -->
<service name="TestResourceSibling"
discovery="BaseUpgradingDiscoveryComponent"
- class="BaseResourceComponent" />
-
+ class="BaseResourceComponent">
+ <plugin-configuration>
+ <c:simple-property name="count" default="15" />
<!-- This intentionally differs from v1 -->
+ <c:simple-property name="key"
default="UPGRADED-test-resource-sibling-%n,parent-%p" />
+ </plugin-configuration>
+ </service>
+ </server>
</plugin>
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml
index e934494..ebe9793 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml
@@ -37,13 +37,8 @@
</plugin-configuration>
</service>
- <service name="TestResourceSibling" sourcePlugin="sibling"
sourceType="TestResourceSibling">
- <plugin-configuration>
- <c:simple-property name="count" default="10" />
- <c:simple-property name="key"
default="test-resource-sibling-%n,parent-%p" />
- <c:simple-property name="upgradedKey"
default="UPGRADED-test-resource-sibling-%n,parent-%p" />
- </plugin-configuration>
- </service>
+ <service name="TestResourceSibling" sourcePlugin="sibling"
sourceType="TestResourceSibling"
+ class="BaseResourceComponent"
discovery="BaseDiscoveryComponent" />
</server>
</plugin>
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
index 96658e3..3d709b0 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
@@ -26,7 +26,7 @@
</plugin-configuration>
<service name="TestResource"
- discovery="BaseDiscoveryComponent"
+ discovery="BaseUpgradingDiscoveryComponent"
class="BaseResourceComponent">
<plugin-configuration>
<c:simple-property name="count" default="15" />
<!-- This intentionally differs from v1 -->
@@ -35,13 +35,8 @@
</service>
- <service name="TestResourceSibling" sourcePlugin="sibling"
sourceType="TestResourceSibling">
- <plugin-configuration>
- <c:simple-property name="count" default="15" />
<!-- This intentionally differs from v1 -->
- <c:simple-property name="key"
default="UPGRADED-test-resource-sibling-%n,parent-%p" />
- </plugin-configuration>
- </service>
-
+ <service name="TestResourceSibling" sourcePlugin="sibling"
sourceType="TestResourceSibling"
+ class="BaseResourceComponent"
discovery="BaseUpgradingDiscoveryComponent" />
</server>
</plugin>
commit c99d68dd036f243a2f28e000e10385d27bbdb785
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Sep 29 13:53:45 2010 +0200
Adding a skeleton of what will need to be tested for upgrade failure handling.
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
new file mode 100644
index 0000000..25eca30
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
@@ -0,0 +1,81 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.upgrade;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.testng.annotations.Test;
+
+/**
+ * The plugins and their resource types form the following dependency structure:
+ * <pre>
+ * Root(root)
+ * / \
+ * ParentDependency(parentdep) ParentDepSibling(parentsibling)
+ * / \
+ * TestResource(test) TestResourceSibling(sibling)
+ * </pre>
+ * The dependencies in the above "chart" are formed using either the
<code><runs-inside></code>
+ * or <code>sourcePlugin/sourceType</code> approaches just to test that both
are handled correctly.
+ *
+ * @author Lukas Krejci
+ */
+@Test(sequential = true, invocationCount = 1)
+public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase {
+
+ //plugin names
+ private static final String BASE_PLUGIN_NAME =
"/resource-upgrade-test-plugin-multi-base-1.0.0.jar";
+ private static final String PARENT_DEP_V1_PLUGIN_NAME =
"/resource-upgrade-test-plugin-multi-parentdep-1.0.0.jar";
+ private static final String PARENT_DEP_V2_PLUGIN_NAME =
"/resource-upgrade-test-plugin-multi-parentdep-2.0.0.jar";
+ private static final String PARENT_SIBLING_V1_PLUGIN_NAME =
"/resource-upgrade-test-plugin-multi-parentsibling-1.0.0.jar";
+ private static final String PARENT_SIBLING_V2_PLUGIN_NAME =
"/resource-upgrade-test-plugin-multi-parentsibling-2.0.0.jar";
+ private static final String ROOT_PLUGIN_NAME =
"/resource-upgrade-test-plugin-multi-root-1.0.0.jar";
+ private static final String SIBLING_V1_PLUGIN_NAME =
"/resource-upgrade-test-plugin-multi-sibling-1.0.0.jar";
+ private static final String SIBLING_V2_PLUGIN_NAME =
"/resource-upgrade-test-plugin-multi-sibling-2.0.0.jar";
+ private static final String TEST_V1_PLUGIN_NAME =
"/resource-upgrade-test-plugin-multi-test-1.0.0.jar";
+ private static final String TEST_V2_PLUGIN_NAME =
"/resource-upgrade-test-plugin-multi-test-2.0.0.jar";
+
+ protected Collection<String> getRequiredPlugins() {
+ return Arrays.asList(BASE_PLUGIN_NAME, PARENT_DEP_V1_PLUGIN_NAME,
PARENT_DEP_V2_PLUGIN_NAME,
+ PARENT_SIBLING_V1_PLUGIN_NAME, PARENT_SIBLING_V2_PLUGIN_NAME,
ROOT_PLUGIN_NAME, SIBLING_V1_PLUGIN_NAME,
+ SIBLING_V2_PLUGIN_NAME, TEST_V1_PLUGIN_NAME, TEST_V2_PLUGIN_NAME);
+ }
+
+ @Test
+ public void testSuccess() {
+ //TODO implement
+ //check that all the stuff is properly upgraded on success
+ }
+
+ @Test
+ public void testFailureOnLeaf() {
+ //TODO implement
+ //check that the system behaves correctly if there is an upgrade failure
+ //at the leaf node of the plugin dep graph
+ }
+
+ @Test
+ public void testFailureOnDependencies() {
+ //TODO implement
+ //check that stuff works if there is an upgrade failure on some of the resources
+ //in the plugin some "in the middle" of the plugin dep graph
+ }
+}
commit 4f504f582fc9040bcf5ed7f7dd24cfd3bc2adbad
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Sep 29 13:49:24 2010 +0200
some more minor changes to class structure and plugin names.
diff --git a/modules/core/plugin-container/pom.xml
b/modules/core/plugin-container/pom.xml
index 035bf36..4d6e753 100644
--- a/modules/core/plugin-container/pom.xml
+++ b/modules/core/plugin-container/pom.xml
@@ -281,7 +281,7 @@
<!-- <copy
toDir="${project.build.testOutputDirectory}/tmp/multi/v1/org/rhq/core/pc/upgrade/plugins/multi/v1">
<fileset
file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/v1/*.class"
/>
</copy> -->
- <jar
destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-1.0.0.jar">
+ <jar
destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-test-1.0.0.jar">
<fileset
dir="${project.build.testOutputDirectory}/tmp/multi/v1"
includes="**/*.class,**/rhq-plugin.xml" />
</jar>
@@ -291,7 +291,7 @@
<!-- <copy
toDir="${project.build.testOutputDirectory}/tmp/multi/v2/org/rhq/core/pc/upgrade/plugins/multi/v2">
<fileset
file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/v2/*.class"
/>
</copy> -->
- <jar
destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-2.0.0.jar">
+ <jar
destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-test-2.0.0.jar">
<fileset
dir="${project.build.testOutputDirectory}/tmp/multi/v2"
includes="**/*.class,**/rhq-plugin.xml" />
</jar>
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index e13ea3d..8cfec36 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -28,6 +28,8 @@ import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import java.io.File;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.Set;
@@ -38,7 +40,6 @@ import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.pc.PluginContainer;
import org.rhq.core.pc.inventory.ResourceContainer;
-import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
@@ -56,11 +57,8 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
static final String SINGLETON_RESOURCE_TYPE_NAME = "Resource";
static final String SINGLETON_RESOURCE_TYPE_PLUGIN_NAME =
"ResourceUpgradeTest";
- @BeforeClass
- public void sanityCheck() {
- verifyPluginExists(PLUGIN_V1_FILENAME);
- verifyPluginExists(PLUGIN_V2_FILENAME);
- verifyPluginExists(FAILING_PLUGIN_FILE_NAME);
+ protected Collection<String> getRequiredPlugins() {
+ return Arrays.asList(PLUGIN_V1_FILENAME, PLUGIN_V2_FILENAME,
FAILING_PLUGIN_FILE_NAME);
}
@Test
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
index f03f2a4..3aa772b 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
@@ -24,6 +24,7 @@ import static org.testng.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import java.net.URL;
+import java.util.Collection;
import java.util.Set;
import org.apache.commons.io.FileUtils;
@@ -53,7 +54,7 @@ import org.testng.annotations.BeforeClass;
*
* @author Lukas Krejci
*/
-public class ResourceUpgradeTestBase {
+public abstract class ResourceUpgradeTestBase {
private static final String PLUGINS_DIR_NAME = "plugins";
private static final String DATA_DIR_NAME = "data";
@@ -81,11 +82,20 @@ public class ResourceUpgradeTestBase {
assertTrue(dataDir.mkdir(), "Could not create plugin container data
directory.");
}
+ @BeforeClass
+ public void verifyPluginsExist() {
+ for (String plugin : getRequiredPlugins()) {
+ verifyPluginExists(plugin);
+ }
+ }
+
@AfterClass
public void undeployPlugins() throws IOException {
FileUtils.deleteDirectory(tmpDir);
}
+ protected abstract Collection<String> getRequiredPlugins();
+
protected void setCurrentServerSideInventory(FakeServerInventory
currentServerSideInventory) {
this.currentServerSideInventory = currentServerSideInventory;
}
commit b97e79bcbd5c557fba29030f7aa0f8b4c629c56f
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Sep 29 13:48:28 2010 +0200
Simplify plugin names, declare correct discovery components for upgrade failure test
plugins.
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/rhq-plugin.xml
index 7edfba1..d262c75 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/rhq-plugin.xml
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/rhq-plugin.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTestBase"
+<plugin name="base"
displayName=""
description=""
package="org.rhq.core.pc.upgrade.plugins.multi.base"
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/rhq-plugin.xml
index 3612974..8cadc84 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/rhq-plugin.xml
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/rhq-plugin.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTestParentDep"
+<plugin name="parentdep"
displayName="Resource Upgrade Multi Test"
description="Resource Upgrade Multi Test"
package="org.rhq.core.pc.upgrade.plugins.multi.base"
@@ -9,15 +9,15 @@
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
- <depends plugin="ResourceUpgradeMultiTestBase"
useClasses="true"/>
- <depends plugin="ResourceUpgradeMultiTestRoot"/>
+ <depends plugin="base" useClasses="true"/>
+ <depends plugin="root"/>
<server name="ParentDependency"
discovery="BaseDiscoveryComponent"
class="BaseResourceComponent">
<runs-inside>
- <parent-resource-type name="Root"
plugin="ResourceUpgradeMultiTestRoot"/>
+ <parent-resource-type name="Root" plugin="root"/>
</runs-inside>
<plugin-configuration>
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/rhq-plugin.xml
index 6b95114..8169122 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/rhq-plugin.xml
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/rhq-plugin.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTestParentDep"
+<plugin name="parentdep"
displayName="Resource Upgrade Multi Test"
description="Resource Upgrade Multi Test"
package="org.rhq.core.pc.upgrade.plugins.multi.base"
@@ -9,15 +9,15 @@
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
- <depends plugin="ResourceUpgradeMultiTestBase"
useClasses="true"/>
- <depends plugin="ResourceUpgradeMultiTestRoot"/>
+ <depends plugin="base" useClasses="true"/>
+ <depends plugin="root"/>
<server name="ParentDependency"
- discovery="BaseDiscoveryComponent"
+ discovery="BaseUpgradingDiscoveryComponent"
class="BaseResourceComponent">
<runs-inside>
- <parent-resource-type name="Root"
plugin="ResourceUpgradeMultiTestRoot"/>
+ <parent-resource-type name="Root" plugin="root"/>
</runs-inside>
<plugin-configuration>
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml
index fbade54..f5e6920 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTestParentSibling"
+<plugin name="parentsibling"
displayName="Resource Upgrade Multi Test"
description="Resource Upgrade Multi Test"
package="org.rhq.core.pc.upgrade.plugins.multi.base"
@@ -9,15 +9,15 @@
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
- <depends plugin="ResourceUpgradeMultiTestBase"
useClasses="true"/>
- <depends plugin="ResourceUpgradeMultiTestRoot"/>
+ <depends plugin="base" useClasses="true"/>
+ <depends plugin="root"/>
<server name="ParentDepSibling"
discovery="BaseDiscoveryComponent"
class="BaseResourceComponent">
<runs-inside>
- <parent-resource-type name="Root"
plugin="ResourceUpgradeMultiTestRoot"/>
+ <parent-resource-type name="Root" plugin="root"/>
</runs-inside>
<plugin-configuration>
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml
index f16d526..d138066 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTestParentSibling"
+<plugin name="parentsibling"
displayName="Resource Upgrade Multi Test"
description="Resource Upgrade Multi Test"
package="org.rhq.core.pc.upgrade.plugins.multi.base"
@@ -9,15 +9,15 @@
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
- <depends plugin="ResourceUpgradeMultiTestBase"
useClasses="true"/>
- <depends plugin="ResourceUpgradeMultiTestRoot"/>
+ <depends plugin="base" useClasses="true"/>
+ <depends plugin="root"/>
<server name="ParentDepSibling"
- discovery="BaseDiscoveryComponent"
+ discovery="BaseUpgradingDiscoveryComponent"
class="BaseResourceComponent">
<runs-inside>
- <parent-resource-type name="Root"
plugin="ResourceUpgradeMultiTestRoot"/>
+ <parent-resource-type name="Root" plugin="root"/>
</runs-inside>
<plugin-configuration>
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/root/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/root/rhq-plugin.xml
index b5efbb1..e95c9bd 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/root/rhq-plugin.xml
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/root/rhq-plugin.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTestRoot"
+<plugin name="root"
displayName=""
description=""
package="org.rhq.core.pc.upgrade.plugins.multi.base"
@@ -9,6 +9,8 @@
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
+ <depends plugin="base" useClasses="true"/>
+
<server name="Root"
discovery="BaseDiscoveryComponent"
class="BaseResourceComponent">
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
index f87ef4d..44a1033 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTestSibling"
+<plugin name="sibling"
displayName="Resource Upgrade Multi Test"
description="Resource Upgrade Multi Test"
package="org.rhq.core.pc.upgrade.plugins.multi.base"
@@ -9,30 +9,12 @@
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
- <depends plugin="ResourceUpgradeMultiTestBase"
useClasses="true"/>
- <depends plugin="ResourceUpgradeMultiTestParentDep"/>
+ <depends plugin="base" useClasses="true"/>
- <server name="TestResourceParentSibling"
- discovery="BaseDiscoveryComponent"
- class="BaseResourceComponent">
-
- <plugin-configuration>
- <c:simple-property name="count" default="2" />
- <c:simple-property name="key"
default="test-resource-parent-sibling-%n,parent-%p" />
- <c:simple-property name="upgradedKey"
default="UPGRADED-test-resource-parent-sibling-%n,parent-%p" />
- </plugin-configuration>
-
- <service name="TestResourceSibling"
+ <!-- This service is put in the type hierarchy in the v1/v2 test plugins -->
+ <service name="TestResourceSibling"
discovery="BaseDiscoveryComponent"
- class="BaseResourceComponent">
- <plugin-configuration>
- <c:simple-property name="count" default="10" />
- <c:simple-property name="key"
default="test-resource-sibling-%n,parent-%p" />
- <c:simple-property name="upgradedKey"
default="UPGRADED-test-resource-sibling-%n,parent-%p" />
- </plugin-configuration>
-
- </service>
- </server>
+ class="BaseResourceComponent" />
</plugin>
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
index e6ab95f..aeab68f 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTestSibling"
+<plugin name="sibling"
displayName="Resource Upgrade Multi Test"
description="Resource Upgrade Multi Test"
package="org.rhq.core.pc.upgrade.plugins.multi.base"
@@ -8,34 +8,12 @@
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
- <depends plugin="ResourceUpgradeMultiTestBase"
useClasses="true"/>
- <depends plugin="ResourceUpgradeMultiTestParentDep"/>
+ <depends plugin="base" useClasses="true"/>
- <server name="TestResourceParentSibling"
- discovery="BaseUpgradingDiscoveryComponent"
- class="BaseResourceComponent">
-
- <runs-inside>
- <parent-resource-type name="ParentDependency"
plugin="ResourceUpgradeMultiTestParentDep"/>
- </runs-inside>
-
- <plugin-configuration>
- <c:simple-property name="count" default="2" />
- <c:simple-property name="key"
default="UPGRADED-test-resource-parent-sibling-%n,parent-%p" />
- </plugin-configuration>
-
- <service name="TestResourceSibling"
- discovery="BaseDiscoveryComponent"
- class="BaseResourceComponent">
- <plugin-configuration>
- <c:simple-property name="count" default="15" />
- <c:simple-property name="key"
default="UPGRADED-test-resource-sibling-%n,parent-%p" />
- </plugin-configuration>
-
- </service>
-
-
- </server>
+ <!-- This service is put in the type hierarchy in the v1/v2 test plugins -->
+ <service name="TestResourceSibling"
+ discovery="BaseUpgradingDiscoveryComponent"
+ class="BaseResourceComponent" />
</plugin>
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml
index 32ad438..e934494 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTest"
+<plugin name="test"
displayName="Resource Upgrade Multi Test"
description="Resource Upgrade Multi Test"
package="org.rhq.core.pc.upgrade.plugins.multi.base"
@@ -9,15 +9,16 @@
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
- <depends plugin="ResourceUpgradeMultiTestBase"
useClasses="true"/>
- <depends plugin="ResourceUpgradeMultiTestParentDep"/>
+ <depends plugin="base" useClasses="true"/>
+ <depends plugin="parentdep"/>
+ <depends plugin="sibling" />
<server name="TestResourceParent"
discovery="BaseDiscoveryComponent"
class="BaseResourceComponent">
<runs-inside>
- <parent-resource-type name="ParentDependency"
plugin="ResourceUpgradeMultiTestParentDep"/>
+ <parent-resource-type name="ParentDependency"
plugin="parentdep"/>
</runs-inside>
<plugin-configuration>
@@ -29,13 +30,20 @@
<service name="TestResource"
discovery="BaseDiscoveryComponent"
class="BaseResourceComponent">
- <plugin-configuration>
- <c:simple-property name="count" default="10" />
- <c:simple-property name="key"
default="test-resource-%n,parent-%p" />
- <c:simple-property name="upgradedKey"
default="UPGRADED-test-resource-%n,parent-%p" />
- </plugin-configuration>
-
- </service>
+ <plugin-configuration>
+ <c:simple-property name="count" default="10" />
+ <c:simple-property name="key"
default="test-resource-%n,parent-%p" />
+ <c:simple-property name="upgradedKey"
default="UPGRADED-test-resource-%n,parent-%p" />
+ </plugin-configuration>
+ </service>
+
+ <service name="TestResourceSibling" sourcePlugin="sibling"
sourceType="TestResourceSibling">
+ <plugin-configuration>
+ <c:simple-property name="count" default="10" />
+ <c:simple-property name="key"
default="test-resource-sibling-%n,parent-%p" />
+ <c:simple-property name="upgradedKey"
default="UPGRADED-test-resource-sibling-%n,parent-%p" />
+ </plugin-configuration>
+ </service>
</server>
</plugin>
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
index 824d3fe..96658e3 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTest"
+<plugin name="test"
displayName="Resource Upgrade Multi Test"
description="Resource Upgrade Multi Test"
package="org.rhq.core.pc.upgrade.plugins.multi.base"
@@ -8,15 +8,16 @@
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
- <depends plugin="ResourceUpgradeMultiTestBase"
useClasses="true"/>
- <depends plugin="ResourceUpgradeMultiTestParentDep"/>
+ <depends plugin="base" useClasses="true"/>
+ <depends plugin="parentdep"/>
+ <depends plugin="sibling"/>
<server name="TestResourceParent"
discovery="BaseUpgradingDiscoveryComponent"
class="BaseResourceComponent">
<runs-inside>
- <parent-resource-type name="ParentDependency"
plugin="ResourceUpgradeMultiTestParentDep"/>
+ <parent-resource-type name="ParentDependency"
plugin="parentdep"/>
</runs-inside>
<plugin-configuration>
@@ -27,13 +28,19 @@
<service name="TestResource"
discovery="BaseDiscoveryComponent"
class="BaseResourceComponent">
- <plugin-configuration>
- <c:simple-property name="count" default="15" />
- <c:simple-property name="key"
default="UPGRADED-test-resource-%n,parent-%p" />
- </plugin-configuration>
+ <plugin-configuration>
+ <c:simple-property name="count" default="15" />
<!-- This intentionally differs from v1 -->
+ <c:simple-property name="key"
default="UPGRADED-test-resource-%n,parent-%p" />
+ </plugin-configuration>
</service>
+ <service name="TestResourceSibling" sourcePlugin="sibling"
sourceType="TestResourceSibling">
+ <plugin-configuration>
+ <c:simple-property name="count" default="15" />
<!-- This intentionally differs from v1 -->
+ <c:simple-property name="key"
default="UPGRADED-test-resource-sibling-%n,parent-%p" />
+ </plugin-configuration>
+ </service>
</server>
commit 097f744dec27c5584cf6203bbaff6fc041753b26
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Sep 29 13:12:09 2010 +0200
Extracted a base class from the upgrade test in preparation for adding another round
of tests.
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 0a2a660..e13ea3d 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -23,43 +23,23 @@
package org.rhq.core.pc.upgrade;
-import static org.testng.Assert.assertTrue;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
import java.io.File;
-import java.io.IOException;
-import java.net.URL;
import java.util.Collections;
import java.util.Set;
-import org.apache.commons.io.FileUtils;
import org.jmock.Expectations;
import org.jmock.Mockery;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
-import org.rhq.core.clientapi.server.bundle.BundleServerService;
-import org.rhq.core.clientapi.server.configuration.ConfigurationServerService;
-import org.rhq.core.clientapi.server.content.ContentServerService;
-import org.rhq.core.clientapi.server.core.CoreServerService;
-import org.rhq.core.clientapi.server.discovery.DiscoveryServerService;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
-import org.rhq.core.clientapi.server.event.EventServerService;
-import org.rhq.core.clientapi.server.inventory.ResourceFactoryServerService;
-import org.rhq.core.clientapi.server.measurement.MeasurementServerService;
-import org.rhq.core.clientapi.server.operation.OperationServerService;
-import org.rhq.core.domain.discovery.AvailabilityReport;
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.ServerServices;
-import org.rhq.core.pc.inventory.InventoryManager;
import org.rhq.core.pc.inventory.ResourceContainer;
-import org.rhq.core.pc.plugin.FileSystemPluginFinder;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
/**
* Test cases for resource upgrade.
@@ -67,39 +47,14 @@ import org.rhq.core.pc.plugin.FileSystemPluginFinder;
* @author Lukas Krejci
*/
@Test(sequential = true, invocationCount = 1)
-public class ResourceUpgradeTest {
+public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
private static final String PLUGIN_V1_FILENAME =
"/resource-upgrade-test-plugin-1.0.0.jar";
private static final String PLUGIN_V2_FILENAME =
"/resource-upgrade-test-plugin-2.0.0.jar";
private static final String FAILING_PLUGIN_FILE_NAME =
"/resource-upgrade-test-plugin-3.0.0.jar";
- private static final String PLUGINS_DIR_NAME = "plugins";
- private static final String DATA_DIR_NAME = "data";
- private static final String TMP_DIR_NAME = "tmp";
-
- private static final String SINGLETON_RESOURCE_TYPE_NAME = "Resource";
- private static final String SINGLETON_RESOURCE_TYPE_PLUGIN_NAME =
"ResourceUpgradeTest";
-
- private File tmpDir;
- private File pluginDir;
- private File dataDir;
-
- private BundleServerService currentBundleServerService;
- private ConfigurationServerService currentConfigurationServerService;
- private ContentServerService currentContentServerService;
- private CoreServerService currentCoreServerService;
- private DiscoveryServerService currentDiscoveryServerService;
- private EventServerService currentEventServerService;
- private MeasurementServerService currentMeasurementServerService;
- private OperationServerService currentOperationServerService;
- private ResourceFactoryServerService currentResourceFactoryServerService;
-
- private FakeServerInventory currentServerSideInventory;
-
- @AfterClass
- public void undeployPlugins() throws IOException {
- FileUtils.deleteDirectory(tmpDir);
- }
+ static final String SINGLETON_RESOURCE_TYPE_NAME = "Resource";
+ static final String SINGLETON_RESOURCE_TYPE_PLUGIN_NAME =
"ResourceUpgradeTest";
@BeforeClass
public void sanityCheck() {
@@ -108,18 +63,9 @@ public class ResourceUpgradeTest {
verifyPluginExists(FAILING_PLUGIN_FILE_NAME);
}
- @BeforeClass(dependsOnMethods = "sanityCheck")
- public void init() {
- tmpDir = getTmpDirectory();
- pluginDir = new File(tmpDir, PLUGINS_DIR_NAME);
- assertTrue(pluginDir.mkdir(), "Could not create plugin deploy
directory.");
- dataDir = new File(tmpDir, DATA_DIR_NAME);
- assertTrue(dataDir.mkdir(), "Could not create plugin container data
directory.");
- }
-
@Test
public void testIgnoreUncommittedResources() throws Exception {
- currentServerSideInventory = new FakeServerInventory();
+ setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.NEW);
TestPayload testNoChange = new AbstractTestPayload(false,
SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
@@ -138,8 +84,8 @@ public class ResourceUpgradeTest {
{
defineDefaultExpectations(this);
- between(1,
4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
-
will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+ between(1,
4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
}
};
}
@@ -150,22 +96,22 @@ public class ResourceUpgradeTest {
@Test
public void testUpgradeData() throws Exception {
- currentServerSideInventory = new FakeServerInventory();
+ setCurrentServerSideInventory(new FakeServerInventory());
upgradeTest(false);
}
@Test
public void testInventoryReinitializationFromServerDuringUpgrade() throws Exception
{
- currentServerSideInventory = new FakeServerInventory();
+ setCurrentServerSideInventory(new FakeServerInventory());
upgradeTest(true);
}
@Test
public void testSkipUpgradeWhenServerUnavailable() throws Exception {
- currentServerSideInventory = new FakeServerInventory();
+ setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
- currentServerSideInventory.setFailing(true);
+ getCurrentServerSideInventory().setFailing(true);
TestPayload test = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME,
SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
public void test(Set<Resource> discoveredResources) {
@@ -184,10 +130,10 @@ public class ResourceUpgradeTest {
{
defineDefaultExpectations(this);
- between(1,
4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
-
will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+ between(1,
4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
-
never(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
+
never(getCurrentDiscoveryServerService()).upgradeResources(with(any(Set.class)));
}
};
}
@@ -198,7 +144,7 @@ public class ResourceUpgradeTest {
@Test
public void testUpgradeWithPlatformDeletedOnServer() throws Exception {
- currentServerSideInventory = new FakeServerInventory();
+ setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
TestPayload test = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME,
SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
@@ -227,15 +173,15 @@ public class ResourceUpgradeTest {
//the first merge will be triggered from within the upgrade
process and we are
//going to report null sync.
-
oneOf(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
- will(currentServerSideInventory.clearPlatform());
+
oneOf(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(getCurrentServerSideInventory().clearPlatform());
//the rest of the inventory merges are executed by discoveries,
so let's import the
//discovered stuff into the server-side inventory.
- between(1,
3).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
-
will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+ between(1,
3).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
-
never(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
+
never(getCurrentDiscoveryServerService()).upgradeResources(with(any(Set.class)));
}
};
}
@@ -246,7 +192,7 @@ public class ResourceUpgradeTest {
@Test
public void testUpgradeFailureHandling() throws Exception {
- currentServerSideInventory = new FakeServerInventory();
+ setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
TestPayload test = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME,
SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
@@ -272,11 +218,11 @@ public class ResourceUpgradeTest {
{
defineDefaultExpectations(this);
- between(1,
4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
-
will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+ between(1,
4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
-
oneOf(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
- will(currentServerSideInventory.upgradeResources());
+
oneOf(getCurrentDiscoveryServerService()).upgradeResources(with(any(Set.class)));
+ will(getCurrentServerSideInventory().upgradeResources());
}
};
}
@@ -297,20 +243,21 @@ public class ResourceUpgradeTest {
assertEquals(discoveredResource.getName(),
"resource-name-v1");
assertEquals(discoveredResource.getDescription(),
"resource-description-v1");
}
-
+
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
defineDefaultExpectations(this);
- between(1,
4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
-
will(currentServerSideInventory.mergeInventoryReport(requiredInventoryStatus));
+ between(1,
4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+
will(getCurrentServerSideInventory().mergeInventoryReport(requiredInventoryStatus));
}
};
}
});
}
+
private void upgradeTest(boolean clearInventoryDat) throws Exception {
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
@@ -339,189 +286,14 @@ public class ResourceUpgradeTest {
{
defineDefaultExpectations(this);
- between(1,
4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
-
will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+ between(1,
4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
-
oneOf(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
- will(currentServerSideInventory.upgradeResources());
+
oneOf(getCurrentDiscoveryServerService()).upgradeResources(with(any(Set.class)));
+ will(getCurrentServerSideInventory().upgradeResources());
}
};
}
});
}
-
- private PluginContainerConfiguration createPluginContainerConfiguration(Mockery
context) throws Exception {
- PluginContainerConfiguration conf = new PluginContainerConfiguration();
-
- conf.setPluginDirectory(new File(tmpDir, PLUGINS_DIR_NAME));
- conf.setDataDirectory(new File(tmpDir, DATA_DIR_NAME));
- conf.setTemporaryDirectory(new File(tmpDir, TMP_DIR_NAME));
- conf.setInsideAgent(true); //pc must think it's inside an agent so that it
persists the inventory between restarts
- conf.setPluginFinder(new FileSystemPluginFinder(conf.getPluginDirectory()));
- conf.setCreateResourceClassloaders(false);
-
- //we're not interested in any scans happening out of our control
- conf.setAvailabilityScanInitialDelay(Long.MAX_VALUE);
- conf.setConfigurationDiscoveryInitialDelay(Long.MAX_VALUE);
- conf.setContentDiscoveryInitialDelay(Long.MAX_VALUE);
- conf.setEventSenderInitialDelay(Long.MAX_VALUE);
- conf.setMeasurementCollectionInitialDelay(Long.MAX_VALUE);
- conf.setServerDiscoveryInitialDelay(Long.MAX_VALUE);
- conf.setServiceDiscoveryInitialDelay(Long.MAX_VALUE);
-
- currentBundleServerService = context.mock(BundleServerService.class);
- currentConfigurationServerService =
context.mock(ConfigurationServerService.class);
- currentContentServerService = context.mock(ContentServerService.class);
- currentCoreServerService = context.mock(CoreServerService.class);
- currentDiscoveryServerService = context.mock(DiscoveryServerService.class);
- currentEventServerService = context.mock(EventServerService.class);
- currentMeasurementServerService = context.mock(MeasurementServerService.class);
- currentOperationServerService = context.mock(OperationServerService.class);
- currentResourceFactoryServerService =
context.mock(ResourceFactoryServerService.class);
-
- ServerServices serverServices = new ServerServices();
- serverServices.setBundleServerService(currentBundleServerService);
- serverServices.setConfigurationServerService(currentConfigurationServerService);
- serverServices.setContentServerService(currentContentServerService);
- serverServices.setCoreServerService(currentCoreServerService);
- serverServices.setDiscoveryServerService(currentDiscoveryServerService);
- serverServices.setEventServerService(currentEventServerService);
- serverServices.setMeasurementServerService(currentMeasurementServerService);
- serverServices.setOperationServerService(currentOperationServerService);
-
serverServices.setResourceFactoryServerService(currentResourceFactoryServerService);
-
- conf.setServerServices(serverServices);
-
- return conf;
- }
-
- /**
- * @param pluginResourcePath
- */
- private void verifyPluginExists(String pluginResourcePath) {
- URL url = getClass().getResource(pluginResourcePath);
-
- File pluginFile = FileUtils.toFile(url);
-
- assertTrue(pluginFile.exists(), pluginFile.getAbsoluteFile() + " plugin jar
could not be found.");
- }
-
- private void copyPlugin(String pluginResourcePath, File pluginDirectory) throws
IOException {
- URL pluginUrl = getClass().getResource(pluginResourcePath);
-
- File pluginFile = new File(pluginResourcePath);
- String pluginFileName = pluginFile.getName();
-
- FileUtils.copyURLToFile(pluginUrl, new File(pluginDirectory, pluginFileName));
- }
-
- private static File getTmpDirectory() {
- File ret = new File(System.getProperty("java.io.tmpdir"),
"resource-upgrade-test" + System.currentTimeMillis());
-
- while (ret.exists() || !ret.mkdir()) {
- ret = new File(System.getProperty("java.io.tmpdir"),
"resource-upgrade-test" + System.currentTimeMillis());
- }
-
- return ret;
- }
-
- private interface TestPayload {
- Expectations getExpectations(Mockery context) throws Exception;
- void test(Set<Resource> resourceUpgradeTestResources);
- boolean isClearInventoryDat();
- String getResourceTypeName();
- String getResourceTypePluginName();
- }
-
- private static abstract class AbstractTestPayload implements TestPayload {
- private boolean clearInventoryDat;
- private String resourceTypeName;
- private String resourceTypePluginName;
-
- public AbstractTestPayload(boolean clearInventoryDat, String resourceTypeName,
String resourceTypePluginName) {
- this.clearInventoryDat = clearInventoryDat;
- this.resourceTypeName = resourceTypeName;
- this.resourceTypePluginName = resourceTypePluginName;
- }
-
- public boolean isClearInventoryDat() {
- return clearInventoryDat;
- }
-
- public String getResourceTypeName() {
- return resourceTypeName;
- }
-
- public String getResourceTypePluginName() {
- return resourceTypePluginName;
- }
- }
-
- private Set<Resource> getTestingResources(String resourceTypeName, String
resourceTypePluginName) {
- ResourceType resType =
PluginContainer.getInstance().getPluginManager().getMetadataManager().getType(resourceTypeName,
resourceTypePluginName);
-
- return currentServerSideInventory.findResourcesByType(resType);
- }
-
- private void executeTestWithPlugins(Set<String> pluginResourcePaths,
TestPayload test) throws Exception {
- FileUtils.cleanDirectory(new File(tmpDir, PLUGINS_DIR_NAME));
-
- for(String pluginResourcePath : pluginResourcePaths) {
- copyPlugin(pluginResourcePath, pluginDir);
- }
-
- Mockery context = new Mockery();
-
- PluginContainerConfiguration pcConfig =
createPluginContainerConfiguration(context);
-
- if (test.isClearInventoryDat()) {
- File inventoryDat = new File(pcConfig.getDataDirectory(),
"inventory.dat");
- inventoryDat.delete();
- }
-
- context.checking(test.getExpectations(context));
-
- PluginContainer.getInstance().setConfiguration(pcConfig);
- PluginContainer.getInstance().initialize();
-
- try {
- //give the pc the time to finish resource upgrade
- Thread.sleep(1000);
-
- //execute full discovery
- InventoryManager im = PluginContainer.getInstance().getInventoryManager();
- im.executeServerScanImmediately();
- im.executeServiceScanImmediately();
-
- Set<Resource> resources =
getTestingResources(test.getResourceTypeName(), test.getResourceTypePluginName());
-
- test.test(resources);
-
- context.assertIsSatisfied();
- } finally {
- PluginContainer.getInstance().shutdown();
- }
- }
-
- @SuppressWarnings("unchecked")
- private void defineDefaultExpectations(Expectations expectations) {
- expectations.ignoring(currentBundleServerService);
- expectations.ignoring(currentConfigurationServerService);
- expectations.ignoring(currentContentServerService);
- expectations.ignoring(currentCoreServerService);
- expectations.ignoring(currentEventServerService);
- expectations.ignoring(currentMeasurementServerService);
- expectations.ignoring(currentOperationServerService);
- expectations.ignoring(currentResourceFactoryServerService);
-
- //just ignore these invocations if we get a availability scan in the PC...
-
expectations.allowing(currentDiscoveryServerService).mergeAvailabilityReport(expectations.with(Expectations.any(AvailabilityReport.class)));
-
-
expectations.allowing(currentDiscoveryServerService).getResources(expectations.with(Expectations.any(Set.class)),
expectations.with(Expectations.any(boolean.class)));
- expectations.will(currentServerSideInventory.getResources());
- }
-
- private void cleanDataDir() throws IOException {
- FileUtils.cleanDirectory(new File(tmpDir, DATA_DIR_NAME));
- }
}
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
new file mode 100644
index 0000000..f03f2a4
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
@@ -0,0 +1,350 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.upgrade;
+
+import static org.testng.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Set;
+
+import org.apache.commons.io.FileUtils;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.rhq.core.clientapi.server.bundle.BundleServerService;
+import org.rhq.core.clientapi.server.configuration.ConfigurationServerService;
+import org.rhq.core.clientapi.server.content.ContentServerService;
+import org.rhq.core.clientapi.server.core.CoreServerService;
+import org.rhq.core.clientapi.server.discovery.DiscoveryServerService;
+import org.rhq.core.clientapi.server.event.EventServerService;
+import org.rhq.core.clientapi.server.inventory.ResourceFactoryServerService;
+import org.rhq.core.clientapi.server.measurement.MeasurementServerService;
+import org.rhq.core.clientapi.server.operation.OperationServerService;
+import org.rhq.core.domain.discovery.AvailabilityReport;
+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.ServerServices;
+import org.rhq.core.pc.inventory.InventoryManager;
+import org.rhq.core.pc.plugin.FileSystemPluginFinder;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+
+/**
+ *
+ * @author Lukas Krejci
+ */
+public class ResourceUpgradeTestBase {
+
+ private static final String PLUGINS_DIR_NAME = "plugins";
+ private static final String DATA_DIR_NAME = "data";
+ private static final String TMP_DIR_NAME = "tmp";
+ private File tmpDir;
+ private File pluginDir;
+ private File dataDir;
+ private BundleServerService currentBundleServerService;
+ private ConfigurationServerService currentConfigurationServerService;
+ private ContentServerService currentContentServerService;
+ private CoreServerService currentCoreServerService;
+ private DiscoveryServerService currentDiscoveryServerService;
+ private EventServerService currentEventServerService;
+ private MeasurementServerService currentMeasurementServerService;
+ private OperationServerService currentOperationServerService;
+ private ResourceFactoryServerService currentResourceFactoryServerService;
+ private FakeServerInventory currentServerSideInventory;
+
+ @BeforeClass
+ public void init() {
+ tmpDir = getTmpDirectory();
+ pluginDir = new File(tmpDir, PLUGINS_DIR_NAME);
+ assertTrue(pluginDir.mkdir(), "Could not create plugin deploy
directory.");
+ dataDir = new File(tmpDir, DATA_DIR_NAME);
+ assertTrue(dataDir.mkdir(), "Could not create plugin container data
directory.");
+ }
+
+ @AfterClass
+ public void undeployPlugins() throws IOException {
+ FileUtils.deleteDirectory(tmpDir);
+ }
+
+ protected void setCurrentServerSideInventory(FakeServerInventory
currentServerSideInventory) {
+ this.currentServerSideInventory = currentServerSideInventory;
+ }
+
+ protected FakeServerInventory getCurrentServerSideInventory() {
+ return currentServerSideInventory;
+ }
+
+ protected void setCurrentResourceFactoryServerService(ResourceFactoryServerService
currentResourceFactoryServerService) {
+ this.currentResourceFactoryServerService = currentResourceFactoryServerService;
+ }
+
+ protected ResourceFactoryServerService getCurrentResourceFactoryServerService() {
+ return currentResourceFactoryServerService;
+ }
+
+ protected void setCurrentOperationServerService(OperationServerService
currentOperationServerService) {
+ this.currentOperationServerService = currentOperationServerService;
+ }
+
+ protected OperationServerService getCurrentOperationServerService() {
+ return currentOperationServerService;
+ }
+
+ protected void setCurrentMeasurementServerService(MeasurementServerService
currentMeasurementServerService) {
+ this.currentMeasurementServerService = currentMeasurementServerService;
+ }
+
+ protected MeasurementServerService getCurrentMeasurementServerService() {
+ return currentMeasurementServerService;
+ }
+
+ protected void setCurrentEventServerService(EventServerService
currentEventServerService) {
+ this.currentEventServerService = currentEventServerService;
+ }
+
+ protected EventServerService getCurrentEventServerService() {
+ return currentEventServerService;
+ }
+
+ protected void setCurrentDiscoveryServerService(DiscoveryServerService
currentDiscoveryServerService) {
+ this.currentDiscoveryServerService = currentDiscoveryServerService;
+ }
+
+ protected DiscoveryServerService getCurrentDiscoveryServerService() {
+ return currentDiscoveryServerService;
+ }
+
+ protected void setCurrentCoreServerService(CoreServerService
currentCoreServerService) {
+ this.currentCoreServerService = currentCoreServerService;
+ }
+
+ protected CoreServerService getCurrentCoreServerService() {
+ return currentCoreServerService;
+ }
+
+ protected void setCurrentContentServerService(ContentServerService
currentContentServerService) {
+ this.currentContentServerService = currentContentServerService;
+ }
+
+ protected ContentServerService getCurrentContentServerService() {
+ return currentContentServerService;
+ }
+
+ protected void setCurrentConfigurationServerService(ConfigurationServerService
currentConfigurationServerService) {
+ this.currentConfigurationServerService = currentConfigurationServerService;
+ }
+
+ protected ConfigurationServerService getCurrentConfigurationServerService() {
+ return currentConfigurationServerService;
+ }
+
+ protected void setCurrentBundleServerService(BundleServerService
currentBundleServerService) {
+ this.currentBundleServerService = currentBundleServerService;
+ }
+
+ protected BundleServerService getCurrentBundleServerService() {
+ return currentBundleServerService;
+ }
+
+ protected static File getTmpDirectory() {
+ File ret = new File(System.getProperty("java.io.tmpdir"),
"resource-upgrade-test" + System.currentTimeMillis());
+
+ while (ret.exists() || !ret.mkdir()) {
+ ret = new File(System.getProperty("java.io.tmpdir"),
"resource-upgrade-test" + System.currentTimeMillis());
+ }
+
+ return ret;
+ }
+
+ private PluginContainerConfiguration createPluginContainerConfiguration(Mockery
context) throws Exception {
+ PluginContainerConfiguration conf = new PluginContainerConfiguration();
+
+ conf.setPluginDirectory(new File(tmpDir, PLUGINS_DIR_NAME));
+ conf.setDataDirectory(new File(tmpDir, DATA_DIR_NAME));
+ conf.setTemporaryDirectory(new File(tmpDir, TMP_DIR_NAME));
+ conf.setInsideAgent(true); //pc must think it's inside an agent so that it
persists the inventory between restarts
+ conf.setPluginFinder(new FileSystemPluginFinder(conf.getPluginDirectory()));
+ conf.setCreateResourceClassloaders(false);
+
+ //we're not interested in any scans happening out of our control
+ conf.setAvailabilityScanInitialDelay(Long.MAX_VALUE);
+ conf.setConfigurationDiscoveryInitialDelay(Long.MAX_VALUE);
+ conf.setContentDiscoveryInitialDelay(Long.MAX_VALUE);
+ conf.setEventSenderInitialDelay(Long.MAX_VALUE);
+ conf.setMeasurementCollectionInitialDelay(Long.MAX_VALUE);
+ conf.setServerDiscoveryInitialDelay(Long.MAX_VALUE);
+ conf.setServiceDiscoveryInitialDelay(Long.MAX_VALUE);
+
+ setCurrentBundleServerService(context.mock(BundleServerService.class));
+
setCurrentConfigurationServerService(context.mock(ConfigurationServerService.class));
+ setCurrentContentServerService(context.mock(ContentServerService.class));
+ setCurrentCoreServerService(context.mock(CoreServerService.class));
+ setCurrentDiscoveryServerService(context.mock(DiscoveryServerService.class));
+ setCurrentEventServerService(context.mock(EventServerService.class));
+
setCurrentMeasurementServerService(context.mock(MeasurementServerService.class));
+ setCurrentOperationServerService(context.mock(OperationServerService.class));
+
setCurrentResourceFactoryServerService(context.mock(ResourceFactoryServerService.class));
+
+ ServerServices serverServices = new ServerServices();
+ serverServices.setBundleServerService(getCurrentBundleServerService());
+
serverServices.setConfigurationServerService(getCurrentConfigurationServerService());
+ serverServices.setContentServerService(getCurrentContentServerService());
+ serverServices.setCoreServerService(getCurrentCoreServerService());
+ serverServices.setDiscoveryServerService(getCurrentDiscoveryServerService());
+ serverServices.setEventServerService(getCurrentEventServerService());
+
serverServices.setMeasurementServerService(getCurrentMeasurementServerService());
+ serverServices.setOperationServerService(getCurrentOperationServerService());
+
serverServices.setResourceFactoryServerService(getCurrentResourceFactoryServerService());
+
+ conf.setServerServices(serverServices);
+
+ return conf;
+ }
+
+ /**
+ * @param pluginResourcePath
+ */
+ protected void verifyPluginExists(String pluginResourcePath) {
+ URL url = getClass().getResource(pluginResourcePath);
+
+ File pluginFile = FileUtils.toFile(url);
+
+ assertTrue(pluginFile.exists(), pluginFile.getAbsoluteFile() + " plugin jar
could not be found.");
+ }
+
+ private void copyPlugin(String pluginResourcePath, File pluginDirectory) throws
IOException {
+ URL pluginUrl = getClass().getResource(pluginResourcePath);
+
+ File pluginFile = new File(pluginResourcePath);
+ String pluginFileName = pluginFile.getName();
+
+ FileUtils.copyURLToFile(pluginUrl, new File(pluginDirectory, pluginFileName));
+ }
+
+ protected interface TestPayload {
+ Expectations getExpectations(Mockery context) throws Exception;
+ void test(Set<Resource> resourceUpgradeTestResources);
+ boolean isClearInventoryDat();
+ String getResourceTypeName();
+ String getResourceTypePluginName();
+ }
+
+ protected static abstract class AbstractTestPayload implements TestPayload {
+ private boolean clearInventoryDat;
+ private String resourceTypeName;
+ private String resourceTypePluginName;
+
+ public AbstractTestPayload(boolean clearInventoryDat, String
resourceTypeName, String resourceTypePluginName) {
+ this.clearInventoryDat = clearInventoryDat;
+ this.resourceTypeName = resourceTypeName;
+ this.resourceTypePluginName = resourceTypePluginName;
+ }
+
+ public boolean isClearInventoryDat() {
+ return clearInventoryDat;
+ }
+
+ public String getResourceTypeName() {
+ return resourceTypeName;
+ }
+
+ public String getResourceTypePluginName() {
+ return resourceTypePluginName;
+ }
+ }
+
+ /**
+ *
+ */
+ public ResourceUpgradeTestBase() {
+ super();
+ }
+
+ private Set<Resource> getTestingResources(String resourceTypeName, String
resourceTypePluginName) {
+ ResourceType resType =
PluginContainer.getInstance().getPluginManager().getMetadataManager().getType(resourceTypeName,
resourceTypePluginName);
+
+ return getCurrentServerSideInventory().findResourcesByType(resType);
+ }
+
+ protected void executeTestWithPlugins(Set<String> pluginResourcePaths,
TestPayload test) throws Exception {
+ FileUtils.cleanDirectory(new File(tmpDir, PLUGINS_DIR_NAME));
+
+ for(String pluginResourcePath : pluginResourcePaths) {
+ copyPlugin(pluginResourcePath, pluginDir);
+ }
+
+ Mockery context = new Mockery();
+
+ PluginContainerConfiguration pcConfig =
createPluginContainerConfiguration(context);
+
+ if (test.isClearInventoryDat()) {
+ File inventoryDat = new File(pcConfig.getDataDirectory(),
"inventory.dat");
+ inventoryDat.delete();
+ }
+
+ context.checking(test.getExpectations(context));
+
+ PluginContainer.getInstance().setConfiguration(pcConfig);
+ PluginContainer.getInstance().initialize();
+
+ try {
+ //give the pc the time to finish resource upgrade
+ Thread.sleep(1000);
+
+ //execute full discovery
+ InventoryManager im = PluginContainer.getInstance().getInventoryManager();
+ im.executeServerScanImmediately();
+ im.executeServiceScanImmediately();
+
+ Set<Resource> resources =
getTestingResources(test.getResourceTypeName(), test.getResourceTypePluginName());
+
+ test.test(resources);
+
+ context.assertIsSatisfied();
+ } finally {
+ PluginContainer.getInstance().shutdown();
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void defineDefaultExpectations(Expectations expectations) {
+ expectations.ignoring(getCurrentBundleServerService());
+ expectations.ignoring(getCurrentConfigurationServerService());
+ expectations.ignoring(getCurrentContentServerService());
+ expectations.ignoring(getCurrentCoreServerService());
+ expectations.ignoring(getCurrentEventServerService());
+ expectations.ignoring(getCurrentMeasurementServerService());
+ expectations.ignoring(getCurrentOperationServerService());
+ expectations.ignoring(getCurrentResourceFactoryServerService());
+
+ //just ignore these invocations if we get a availability scan in the PC...
+
expectations.allowing(getCurrentDiscoveryServerService()).mergeAvailabilityReport(expectations.with(Expectations.any(AvailabilityReport.class)));
+
+
expectations.allowing(getCurrentDiscoveryServerService()).getResources(expectations.with(Expectations.any(Set.class)),
expectations.with(Expectations.any(boolean.class)));
+ expectations.will(getCurrentServerSideInventory().getResources());
+ }
+
+ protected void cleanDataDir() throws IOException {
+ FileUtils.cleanDirectory(new File(tmpDir, DATA_DIR_NAME));
+ }
+}
commit 1863f1ab0c4473e6a79c469c16b73b6810733325
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Sep 29 12:58:32 2010 +0200
Preparing the upgrade tests to accept more complicated scenarios.
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 1479345..0a2a660 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -77,6 +77,9 @@ public class ResourceUpgradeTest {
private static final String DATA_DIR_NAME = "data";
private static final String TMP_DIR_NAME = "tmp";
+ private static final String SINGLETON_RESOURCE_TYPE_NAME = "Resource";
+ private static final String SINGLETON_RESOURCE_TYPE_PLUGIN_NAME =
"ResourceUpgradeTest";
+
private File tmpDir;
private File pluginDir;
private File dataDir;
@@ -119,8 +122,12 @@ public class ResourceUpgradeTest {
currentServerSideInventory = new FakeServerInventory();
initialSyncAndDiscovery(InventoryStatus.NEW);
- TestPayload testNoChange = new TestPayload() {
- public void test(Resource discoveredResource) {
+ TestPayload testNoChange = new AbstractTestPayload(false,
SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
+ public void test(Set<Resource> discoveredResources) {
+ assertEquals(discoveredResources.size(), 1, "Expected single test
resource but multiple found.");
+
+ Resource discoveredResource = discoveredResources.iterator().next();
+
assertEquals(discoveredResource.getResourceKey(),
"resource-key-v1");
assertEquals(discoveredResource.getName(),
"resource-name-v1");
assertEquals(discoveredResource.getDescription(),
"resource-description-v1");
@@ -138,7 +145,7 @@ public class ResourceUpgradeTest {
}
};
- executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false,
testNoChange);
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), testNoChange);
}
@Test
@@ -160,8 +167,12 @@ public class ResourceUpgradeTest {
currentServerSideInventory.setFailing(true);
- TestPayload test = new TestPayload() {
- public void test(Resource discoveredResource) {
+ TestPayload test = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME,
SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
+ public void test(Set<Resource> discoveredResources) {
+ assertEquals(discoveredResources.size(), 1, "Expected single test
resource but multiple found.");
+
+ Resource discoveredResource = discoveredResources.iterator().next();
+
assertEquals(discoveredResource.getResourceKey(),
"resource-key-v1");
assertEquals(discoveredResource.getName(),
"resource-name-v1");
assertEquals(discoveredResource.getDescription(),
"resource-description-v1");
@@ -182,7 +193,7 @@ public class ResourceUpgradeTest {
}
};
- executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, test);
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), test);
}
@Test
@@ -190,8 +201,12 @@ public class ResourceUpgradeTest {
currentServerSideInventory = new FakeServerInventory();
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
- TestPayload test = new TestPayload() {
- public void test(Resource discoveredResource) {
+ TestPayload test = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME,
SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
+ public void test(Set<Resource> discoveredResources) {
+ assertEquals(discoveredResources.size(), 1, "Expected single test
resource but multiple found.");
+
+ Resource discoveredResource = discoveredResources.iterator().next();
+
assertEquals(discoveredResource.getResourceKey(),
"resource-key-v2");
assertEquals(discoveredResource.getName(),
"resource-name-v2");
assertEquals(discoveredResource.getDescription(),
"resource-description-v2");
@@ -226,7 +241,7 @@ public class ResourceUpgradeTest {
}
};
- executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, test);
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), test);
}
@Test
@@ -234,12 +249,16 @@ public class ResourceUpgradeTest {
currentServerSideInventory = new FakeServerInventory();
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
- TestPayload test = new TestPayload() {
- public void test(Resource resourceUpgradeTestResource) {
- assertTrue(resourceUpgradeTestResource.getResourceErrors().size() > 0,
"There should be upgrade errors persisted on the server side.");
+ TestPayload test = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME,
SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
+ public void test(Set<Resource> resourceUpgradeTestResources) {
+ assertEquals(resourceUpgradeTestResources.size(), 1, "Expected
single test resource but multiple found.");
+
+ Resource discoveredResource =
resourceUpgradeTestResources.iterator().next();
+
+ assertTrue(discoveredResource.getResourceErrors().size() > 0,
"There should be upgrade errors persisted on the server side.");
//the discovery of the failed resource mustn't have run
- ResourceContainer container =
PluginContainer.getInstance().getInventoryManager().getResourceContainer(resourceUpgradeTestResource);
+ ResourceContainer container =
PluginContainer.getInstance().getInventoryManager().getResourceContainer(discoveredResource);
File dataDir = container.getResourceContext().getDataDirectory();
File marker = new File(dataDir, "failing-discovery-ran");
@@ -263,13 +282,17 @@ public class ResourceUpgradeTest {
}
};
- executeTestWithPlugins(Collections.singleton(FAILING_PLUGIN_FILE_NAME), false,
test);
+ executeTestWithPlugins(Collections.singleton(FAILING_PLUGIN_FILE_NAME), test);
}
private void initialSyncAndDiscovery(final InventoryStatus requiredInventoryStatus)
throws Exception {
cleanDataDir();
- executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), true, new
TestPayload() {
- public void test(Resource discoveredResource) {
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), new
AbstractTestPayload(true, SINGLETON_RESOURCE_TYPE_NAME,
SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
+ public void test(Set<Resource> discoveredResources) {
+ assertEquals(discoveredResources.size(), 1, "Expected single test
resource but multiple found.");
+
+ Resource discoveredResource = discoveredResources.iterator().next();
+
assertEquals(discoveredResource.getResourceKey(),
"resource-key-v1");
assertEquals(discoveredResource.getName(),
"resource-name-v1");
assertEquals(discoveredResource.getDescription(),
"resource-description-v1");
@@ -292,8 +315,12 @@ public class ResourceUpgradeTest {
private void upgradeTest(boolean clearInventoryDat) throws Exception {
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
- executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME),
clearInventoryDat, new TestPayload() {
- public void test(Resource discoveredResource) {
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), new
AbstractTestPayload(clearInventoryDat, SINGLETON_RESOURCE_TYPE_NAME,
SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
+ public void test(Set<Resource> discoveredResources) {
+ assertEquals(discoveredResources.size(), 1, "Expected single test
resource but multiple found.");
+
+ Resource discoveredResource = discoveredResources.iterator().next();
+
assertEquals(discoveredResource.getResourceKey(),
"resource-key-v2");
assertEquals(discoveredResource.getName(),
"resource-name-v2");
assertEquals(discoveredResource.getDescription(),
"resource-description-v2");
@@ -400,16 +427,43 @@ public class ResourceUpgradeTest {
private interface TestPayload {
Expectations getExpectations(Mockery context) throws Exception;
- void test(Resource resourceUpgradeTestResource);
+ void test(Set<Resource> resourceUpgradeTestResources);
+ boolean isClearInventoryDat();
+ String getResourceTypeName();
+ String getResourceTypePluginName();
}
- private Set<Resource> getTestingResources() {
- ResourceType resType =
PluginContainer.getInstance().getPluginManager().getMetadataManager().getType("Resource",
"ResourceUpgradeTest");
+ private static abstract class AbstractTestPayload implements TestPayload {
+ private boolean clearInventoryDat;
+ private String resourceTypeName;
+ private String resourceTypePluginName;
+
+ public AbstractTestPayload(boolean clearInventoryDat, String resourceTypeName,
String resourceTypePluginName) {
+ this.clearInventoryDat = clearInventoryDat;
+ this.resourceTypeName = resourceTypeName;
+ this.resourceTypePluginName = resourceTypePluginName;
+ }
+
+ public boolean isClearInventoryDat() {
+ return clearInventoryDat;
+ }
+
+ public String getResourceTypeName() {
+ return resourceTypeName;
+ }
+
+ public String getResourceTypePluginName() {
+ return resourceTypePluginName;
+ }
+ }
+
+ private Set<Resource> getTestingResources(String resourceTypeName, String
resourceTypePluginName) {
+ ResourceType resType =
PluginContainer.getInstance().getPluginManager().getMetadataManager().getType(resourceTypeName,
resourceTypePluginName);
return currentServerSideInventory.findResourcesByType(resType);
}
- private void executeTestWithPlugins(Set<String> pluginResourcePaths, boolean
clearInventoryDat, TestPayload test) throws Exception {
+ private void executeTestWithPlugins(Set<String> pluginResourcePaths,
TestPayload test) throws Exception {
FileUtils.cleanDirectory(new File(tmpDir, PLUGINS_DIR_NAME));
for(String pluginResourcePath : pluginResourcePaths) {
@@ -420,7 +474,7 @@ public class ResourceUpgradeTest {
PluginContainerConfiguration pcConfig =
createPluginContainerConfiguration(context);
- if (clearInventoryDat) {
+ if (test.isClearInventoryDat()) {
File inventoryDat = new File(pcConfig.getDataDirectory(),
"inventory.dat");
inventoryDat.delete();
}
@@ -439,14 +493,9 @@ public class ResourceUpgradeTest {
im.executeServerScanImmediately();
im.executeServiceScanImmediately();
- Set<Resource> resources = getTestingResources();
-
- assertEquals(resources.size(), 1, "There should be only a single testing
resource but " + resources
- + " were found.");
-
- Resource discoveredResource = resources.iterator().next();
+ Set<Resource> resources =
getTestingResources(test.getResourceTypeName(), test.getResourceTypePluginName());
- test.test(discoveredResource);
+ test.test(resources);
context.assertIsSatisfied();
} finally {
commit 659920513807b095cdd0ac91c3f1c2e091d090a7
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Sep 29 12:57:21 2010 +0200
Setting the height of the errorsGrid to a fixed value so that it stays at the bottom
of the page.
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
index 95bec5f..b439d44 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
@@ -23,11 +23,7 @@ import org.rhq.core.domain.resource.composite.ResourceComposite;
import org.rhq.enterprise.gui.coregui.client.components.table.Table;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
-import com.smartgwt.client.data.DSCallback;
-import com.smartgwt.client.data.DSRequest;
-import com.smartgwt.client.data.DSResponse;
import com.smartgwt.client.types.Alignment;
-import com.smartgwt.client.types.GroupStartOpen;
import com.smartgwt.client.widgets.HTMLPane;
import com.smartgwt.client.widgets.IButton;
import com.smartgwt.client.widgets.Window;
@@ -44,13 +40,11 @@ import com.smartgwt.client.widgets.grid.events.CellClickHandler;
*/
public class OverviewView extends LocatableVLayout {
- private ResourceComposite resourceComposite;
private OverviewForm form;
private Table errorsGrid;
public OverviewView(String locatorId, ResourceComposite resourceComposite) {
super(locatorId);
- this.resourceComposite = resourceComposite;
form = new OverviewForm(extendLocatorId("form"), resourceComposite);
errorsGrid = new Table(extendLocatorId("errors"), "Detected
errors", null, null, new String[] { ResourceErrorsDataSource.DETAIL_ID });
@@ -61,7 +55,7 @@ public class OverviewView extends LocatableVLayout {
errorsGrid.setDataSource(errors);
form.setHeight("*");
- errorsGrid.setHeight("10%");
+ errorsGrid.setHeight(200); //this should be just enough to fit the maximum of 3
rows in this table (there's at most 1 error per type)
addMember(form);
addMember(errorsGrid);
commit c704c79f4acfedf4d959de6d7d27db1b22efa1f3
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Sep 29 12:44:55 2010 +0200
Adding a bunch of test plugins for dependency resolution during resource upgrade
failure handling.
diff --git a/modules/core/plugin-container/pom.xml
b/modules/core/plugin-container/pom.xml
index 4b09ef8..035bf36 100644
--- a/modules/core/plugin-container/pom.xml
+++ b/modules/core/plugin-container/pom.xml
@@ -195,6 +195,106 @@
<fileset
dir="${project.build.testOutputDirectory}/tmp/failing"
includes="**/*.class,**/rhq-plugin.xml" />
</jar>
+ <copy
toDir="${project.build.testOutputDirectory}/tmp/multi/base/META-INF">
+ <fileset
file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/base/rhq-plugin.xml"
/>
+ </copy>
+ <copy
toDir="${project.build.testOutputDirectory}/tmp/multi/base/org/rhq/core/pc/upgrade/plugins/multi/base">
+ <fileset
file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/base/*.class"
/>
+ </copy>
+ <jar
destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-base-1.0.0.jar">
+ <fileset
dir="${project.build.testOutputDirectory}/tmp/multi/base"
includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
+ <copy
toDir="${project.build.testOutputDirectory}/tmp/multi/parentdep1/META-INF">
+ <fileset
file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/rhq-plugin.xml"
/>
+ </copy>
+ <!-- <copy
toDir="${project.build.testOutputDirectory}/tmp/multi/parentdep1/org/rhq/core/pc/upgrade/plugins/multi/parentdep1">
+ <fileset
file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/*.class"
/>
+ </copy> -->
+ <jar
destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-parentdep-1.0.0.jar">
+ <fileset
dir="${project.build.testOutputDirectory}/tmp/multi/parentdep1"
includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
+ <copy
toDir="${project.build.testOutputDirectory}/tmp/multi/parentdep2/META-INF">
+ <fileset
file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/rhq-plugin.xml"
/>
+ </copy>
+ <!-- <copy
toDir="${project.build.testOutputDirectory}/tmp/multi/parentdep2/org/rhq/core/pc/upgrade/plugins/multi/parentdep2">
+ <fileset
file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/*.class"
/>
+ </copy> -->
+ <jar
destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-parentdep-2.0.0.jar">
+ <fileset
dir="${project.build.testOutputDirectory}/tmp/multi/parentdep2"
includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
+ <copy
toDir="${project.build.testOutputDirectory}/tmp/multi/parentsibling1/META-INF">
+ <fileset
file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml"
/>
+ </copy>
+ <!-- <copy
toDir="${project.build.testOutputDirectory}/tmp/multi/parentsibling1/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1">
+ <fileset
file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/*.class"
/>
+ </copy> -->
+ <jar
destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-parentsibling-1.0.0.jar">
+ <fileset
dir="${project.build.testOutputDirectory}/tmp/multi/parentsibling1"
includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
+ <copy
toDir="${project.build.testOutputDirectory}/tmp/multi/parentsibling2/META-INF">
+ <fileset
file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml"
/>
+ </copy>
+ <!-- <copy
toDir="${project.build.testOutputDirectory}/tmp/multi/parentsibling2/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2">
+ <fileset
file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/*.class"
/>
+ </copy> -->
+ <jar
destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-parentsibling-2.0.0.jar">
+ <fileset
dir="${project.build.testOutputDirectory}/tmp/multi/parentsibling2"
includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
+ <copy
toDir="${project.build.testOutputDirectory}/tmp/multi/root/META-INF">
+ <fileset
file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/root/rhq-plugin.xml"
/>
+ </copy>
+ <!-- <copy
toDir="${project.build.testOutputDirectory}/tmp/multi/root/org/rhq/core/pc/upgrade/plugins/multi/root">
+ <fileset
file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/root/*.class"
/>
+ </copy> -->
+ <jar
destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-root-1.0.0.jar">
+ <fileset
dir="${project.build.testOutputDirectory}/tmp/multi/root"
includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
+ <copy
toDir="${project.build.testOutputDirectory}/tmp/multi/sibling1/META-INF">
+ <fileset
file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml"
/>
+ </copy>
+ <!-- <copy
toDir="${project.build.testOutputDirectory}/tmp/multi/sibling1/org/rhq/core/pc/upgrade/plugins/multi/sibling1">
+ <fileset
file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/sibling1/*.class"
/>
+ </copy> -->
+ <jar
destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-sibling-1.0.0.jar">
+ <fileset
dir="${project.build.testOutputDirectory}/tmp/multi/sibling1"
includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
+ <copy
toDir="${project.build.testOutputDirectory}/tmp/multi/sibling2/META-INF">
+ <fileset
file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml"
/>
+ </copy>
+ <!-- <copy
toDir="${project.build.testOutputDirectory}/tmp/multi/sibling2/org/rhq/core/pc/upgrade/plugins/multi/sibling2">
+ <fileset
file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/sibling2/*.class"
/>
+ </copy> -->
+ <jar
destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-sibling-2.0.0.jar">
+ <fileset
dir="${project.build.testOutputDirectory}/tmp/multi/sibling2"
includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
+ <copy
toDir="${project.build.testOutputDirectory}/tmp/multi/v1/META-INF">
+ <fileset
file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml"
/>
+ </copy>
+ <!-- <copy
toDir="${project.build.testOutputDirectory}/tmp/multi/v1/org/rhq/core/pc/upgrade/plugins/multi/v1">
+ <fileset
file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/v1/*.class"
/>
+ </copy> -->
+ <jar
destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-1.0.0.jar">
+ <fileset
dir="${project.build.testOutputDirectory}/tmp/multi/v1"
includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
+ <copy
toDir="${project.build.testOutputDirectory}/tmp/multi/v2/META-INF">
+ <fileset
file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml"
/>
+ </copy>
+ <!-- <copy
toDir="${project.build.testOutputDirectory}/tmp/multi/v2/org/rhq/core/pc/upgrade/plugins/multi/v2">
+ <fileset
file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/v2/*.class"
/>
+ </copy> -->
+ <jar
destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-2.0.0.jar">
+ <fileset
dir="${project.build.testOutputDirectory}/tmp/multi/v2"
includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
<delete
dir="${project.build.testOutputDirectory}/tmp"/>
</tasks>
</configuration>
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseDiscoveryComponent.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseDiscoveryComponent.java
new file mode 100644
index 0000000..61d4fe0
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseDiscoveryComponent.java
@@ -0,0 +1,70 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.upgrade.plugins.multi.base;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+
+/**
+ *
+ * @author Lukas Krejci
+ */
+public class BaseDiscoveryComponent<T extends ResourceComponent> implements
ResourceDiscoveryComponent<T> {
+
+ public Set<DiscoveredResourceDetails>
discoverResources(ResourceDiscoveryContext<T> context)
+ throws InvalidPluginConfigurationException, Exception {
+
+ HashSet<DiscoveredResourceDetails> results = new
HashSet<DiscoveredResourceDetails>();
+
+ Configuration pluginConfig = context.getDefaultPluginConfiguration();
+
+ String keyTemplate = pluginConfig.getSimpleValue("key", null);
+ int count = pluginConfig.getSimple("count").getIntegerValue();
+
+ int parentN =
context.getParentResourceContext().getPluginConfiguration().getSimple("ordinal")
+ .getIntegerValue();
+
+ for (int i = 0; i < count; ++i) {
+
+ String key = getResourceKey(keyTemplate, i, parentN);
+
+ pluginConfig.put(new PropertySimple("ordinal", i));
+
+ DiscoveredResourceDetails detail = new
DiscoveredResourceDetails(context.getResourceType(), key, key, null,
+ null, pluginConfig, null);
+
+ results.add(detail);
+ }
+
+ return results;
+ }
+
+ protected static String getResourceKey(String template, int n, int parentN) {
+ return template.replace("%n",
Integer.toString(n)).replace("%p", Integer.toString(parentN));
+ }
+}
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponent.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponent.java
new file mode 100644
index 0000000..c5bbf3a
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponent.java
@@ -0,0 +1,67 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.upgrade.plugins.multi.base;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
+
+/**
+ *
+ * @author Lukas Krejci
+ */
+public class BaseResourceComponent<T extends ResourceComponent> implements
ResourceComponent<T> {
+
+ private ResourceContext<T> context;
+ private final Log log = LogFactory.getLog(getClass());
+
+ private Set<Integer> childrenToFailUpgrade;
+
+ public AvailabilityType getAvailability() {
+ return AvailabilityType.UP;
+ }
+
+ public void start(ResourceContext<T> context) throws
InvalidPluginConfigurationException, Exception {
+ log.info("Starting multi resource child component with resource key
'" + context.getResourceKey() + "'.");
+ this.context = context;
+ }
+
+ public void stop() {
+ log.info("Stopping multi resource child component with resource key
'" + context.getResourceKey() + "'.");
+ }
+
+ public int getOrdinal() {
+ return
context.getPluginConfiguration().getSimple("ordinal").getIntegerValue();
+ }
+
+ public Set<Integer> getChildrenToFailUpgrade() {
+ return childrenToFailUpgrade == null ? Collections.<Integer>emptySet() :
childrenToFailUpgrade;
+ }
+
+ public void setChildrenToFailUpgrade(Set<Integer> childrenToFailUpgrade) {
+ this.childrenToFailUpgrade = childrenToFailUpgrade;
+ }
+}
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java
new file mode 100644
index 0000000..beb36db
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java
@@ -0,0 +1,61 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.upgrade.plugins.multi.base;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
+
+/**
+ *
+ * @author Lukas Krejci
+ */
+public class BaseUpgradingDiscoveryComponent<T extends BaseResourceComponent>
extends BaseDiscoveryComponent<T> implements ResourceUpgradeFacet<T> {
+
+ public ResourceUpgradeReport upgrade(ResourceUpgradeContext<T>
inventoriedResource) {
+ Configuration pluginConfig = inventoriedResource.getPluginConfiguration();
+
+ BaseResourceComponent<?> parent =
inventoriedResource.getParentResourceComponent();
+ int ordinal = pluginConfig.getSimple("ordinal").getIntegerValue();
+ int parentOrdinal = parent == null ? 0 : parent.getOrdinal();
+
+ boolean fail =
Boolean.getBoolean(pluginConfig.getSimpleValue("failUpgrade",
"false"));
+
+ if (!fail && parent != null) {
+ fail = parent.getChildrenToFailUpgrade().contains(Integer.valueOf(ordinal));
+ }
+
+ if (fail) {
+ throw new RuntimeException("Failing the resource upgrade
purposefully.");
+ }
+
+ String newKey = pluginConfig.getSimpleValue("upgradedKey", null);
+
+ if (newKey == null) {
+ return null;
+ }
+
+ ResourceUpgradeReport report = new ResourceUpgradeReport();
+
+ report.setNewResourceKey(getResourceKey(newKey, ordinal, parentOrdinal));
+ return null;
+ }
+}
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/rhq-plugin.xml
new file mode 100644
index 0000000..7edfba1
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/rhq-plugin.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plugin name="ResourceUpgradeMultiTestBase"
+ displayName=""
+ description=""
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="1.0.0"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <!--
+ Only the inheriting plugins create the concrete resources based on the
+ classes defined in this abstract base plugin.
+
+ These are the plugin configuration properties needed by the base plugin:
+
+ key = the template to create the resource key from
+ count = the number of resources to discover
+ upgradedKey = this *must* be specified on the resource type *to be upgraded* and
+ *must* be the same as the key template on the resource type that
+ it is upgraded to (i.e. the plugin.v1.upgradedKey ==
plugin.v2.key)
+
+ the discovery add a new property called "ordinal" to the plugin config
+ of the created resources, which contains the index of that resource amongst
+ its siblings.
+
+ the key template can contain %n which is replaced by the ordinal and %p which
+ is replaced by the ordinal of its parent.
+
+
+
+ if the discovery component of the concrete resource is (or inherits from)
+ BaseUpgradingDiscoveryComponent, it can specify further plugin config properties
+ influencing the upgrade:
+
+ failUpgrade = true to throw an exception during upgrade
+ -->
+
+</plugin>
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/rhq-plugin.xml
new file mode 100644
index 0000000..3612974
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/rhq-plugin.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeMultiTestParentDep"
+ displayName="Resource Upgrade Multi Test"
+ description="Resource Upgrade Multi Test"
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="1.0.0"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <depends plugin="ResourceUpgradeMultiTestBase"
useClasses="true"/>
+ <depends plugin="ResourceUpgradeMultiTestRoot"/>
+
+ <server name="ParentDependency"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+
+ <runs-inside>
+ <parent-resource-type name="Root"
plugin="ResourceUpgradeMultiTestRoot"/>
+ </runs-inside>
+
+ <plugin-configuration>
+ <c:simple-property name="count" default="1" />
+ <c:simple-property name="key"
default="test-resource-parent-dep-%n,parent-%p" />
+ <c:simple-property name="upgradedKey"
default="UPGRADED-test-resource-parent-dep-%n,parent-%p" />
+ </plugin-configuration>
+
+ </server>
+
+</plugin>
+
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/rhq-plugin.xml
new file mode 100644
index 0000000..6b95114
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/rhq-plugin.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeMultiTestParentDep"
+ displayName="Resource Upgrade Multi Test"
+ description="Resource Upgrade Multi Test"
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="2.0.0"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <depends plugin="ResourceUpgradeMultiTestBase"
useClasses="true"/>
+ <depends plugin="ResourceUpgradeMultiTestRoot"/>
+
+ <server name="ParentDependency"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+
+ <runs-inside>
+ <parent-resource-type name="Root"
plugin="ResourceUpgradeMultiTestRoot"/>
+ </runs-inside>
+
+ <plugin-configuration>
+ <c:simple-property name="count" default="1" />
+ <c:simple-property name="key"
default="UPGRADED-test-resource-parent-dep-%n,parent-%p" />
+ </plugin-configuration>
+
+ </server>
+
+</plugin>
+
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml
new file mode 100644
index 0000000..fbade54
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeMultiTestParentSibling"
+ displayName="Resource Upgrade Multi Test"
+ description="Resource Upgrade Multi Test"
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="1.0.0"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <depends plugin="ResourceUpgradeMultiTestBase"
useClasses="true"/>
+ <depends plugin="ResourceUpgradeMultiTestRoot"/>
+
+ <server name="ParentDepSibling"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+
+ <runs-inside>
+ <parent-resource-type name="Root"
plugin="ResourceUpgradeMultiTestRoot"/>
+ </runs-inside>
+
+ <plugin-configuration>
+ <c:simple-property name="count" default="1" />
+ <c:simple-property name="key"
default="test-resource-parent-sibling-%n,parent-%p" />
+ <c:simple-property name="upgradedKey"
default="UPGRADED-test-resource-parent-sibling-%n,parent-%p" />
+ </plugin-configuration>
+
+ </server>
+
+</plugin>
+
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml
new file mode 100644
index 0000000..f16d526
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeMultiTestParentSibling"
+ displayName="Resource Upgrade Multi Test"
+ description="Resource Upgrade Multi Test"
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="2.0.0"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <depends plugin="ResourceUpgradeMultiTestBase"
useClasses="true"/>
+ <depends plugin="ResourceUpgradeMultiTestRoot"/>
+
+ <server name="ParentDepSibling"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+
+ <runs-inside>
+ <parent-resource-type name="Root"
plugin="ResourceUpgradeMultiTestRoot"/>
+ </runs-inside>
+
+ <plugin-configuration>
+ <c:simple-property name="count" default="1" />
+ <c:simple-property name="key"
default="UPGRADED-test-resource-parent-sibling-%n,parent-%p" />
+ </plugin-configuration>
+
+ </server>
+
+</plugin>
+
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/root/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/root/rhq-plugin.xml
new file mode 100644
index 0000000..b5efbb1
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/root/rhq-plugin.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeMultiTestRoot"
+ displayName=""
+ description=""
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="1.0.0"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <server name="Root"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+
+ <plugin-configuration>
+ <c:simple-property name="count" default="1" />
+ <c:simple-property name="key"
default="test-resource-root-%n" />
+ </plugin-configuration>
+ </server>
+
+</plugin>
+
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
new file mode 100644
index 0000000..f87ef4d
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeMultiTestSibling"
+ displayName="Resource Upgrade Multi Test"
+ description="Resource Upgrade Multi Test"
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="1.0.0"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <depends plugin="ResourceUpgradeMultiTestBase"
useClasses="true"/>
+ <depends plugin="ResourceUpgradeMultiTestParentDep"/>
+
+ <server name="TestResourceParentSibling"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+
+ <plugin-configuration>
+ <c:simple-property name="count" default="2" />
+ <c:simple-property name="key"
default="test-resource-parent-sibling-%n,parent-%p" />
+ <c:simple-property name="upgradedKey"
default="UPGRADED-test-resource-parent-sibling-%n,parent-%p" />
+ </plugin-configuration>
+
+ <service name="TestResourceSibling"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+ <plugin-configuration>
+ <c:simple-property name="count" default="10" />
+ <c:simple-property name="key"
default="test-resource-sibling-%n,parent-%p" />
+ <c:simple-property name="upgradedKey"
default="UPGRADED-test-resource-sibling-%n,parent-%p" />
+ </plugin-configuration>
+
+ </service>
+ </server>
+
+</plugin>
+
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
new file mode 100644
index 0000000..e6ab95f
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plugin name="ResourceUpgradeMultiTestSibling"
+ displayName="Resource Upgrade Multi Test"
+ description="Resource Upgrade Multi Test"
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="2.0.0"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <depends plugin="ResourceUpgradeMultiTestBase"
useClasses="true"/>
+ <depends plugin="ResourceUpgradeMultiTestParentDep"/>
+
+ <server name="TestResourceParentSibling"
+ discovery="BaseUpgradingDiscoveryComponent"
+ class="BaseResourceComponent">
+
+ <runs-inside>
+ <parent-resource-type name="ParentDependency"
plugin="ResourceUpgradeMultiTestParentDep"/>
+ </runs-inside>
+
+ <plugin-configuration>
+ <c:simple-property name="count" default="2" />
+ <c:simple-property name="key"
default="UPGRADED-test-resource-parent-sibling-%n,parent-%p" />
+ </plugin-configuration>
+
+ <service name="TestResourceSibling"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+ <plugin-configuration>
+ <c:simple-property name="count" default="15" />
+ <c:simple-property name="key"
default="UPGRADED-test-resource-sibling-%n,parent-%p" />
+ </plugin-configuration>
+
+ </service>
+
+
+ </server>
+
+</plugin>
+
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml
new file mode 100644
index 0000000..32ad438
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeMultiTest"
+ displayName="Resource Upgrade Multi Test"
+ description="Resource Upgrade Multi Test"
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="1.0.0"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <depends plugin="ResourceUpgradeMultiTestBase"
useClasses="true"/>
+ <depends plugin="ResourceUpgradeMultiTestParentDep"/>
+
+ <server name="TestResourceParent"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+
+ <runs-inside>
+ <parent-resource-type name="ParentDependency"
plugin="ResourceUpgradeMultiTestParentDep"/>
+ </runs-inside>
+
+ <plugin-configuration>
+ <c:simple-property name="count" default="2" />
+ <c:simple-property name="key"
default="test-resource-parent-%n,parent-%p" />
+ <c:simple-property name="upgradedKey"
default="UPGRADED-test-resource-parent-%n,parent-%p" />
+ </plugin-configuration>
+
+ <service name="TestResource"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+ <plugin-configuration>
+ <c:simple-property name="count" default="10" />
+ <c:simple-property name="key"
default="test-resource-%n,parent-%p" />
+ <c:simple-property name="upgradedKey"
default="UPGRADED-test-resource-%n,parent-%p" />
+ </plugin-configuration>
+
+ </service>
+ </server>
+
+</plugin>
+
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
new file mode 100644
index 0000000..824d3fe
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plugin name="ResourceUpgradeMultiTest"
+ displayName="Resource Upgrade Multi Test"
+ description="Resource Upgrade Multi Test"
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="2.0.0"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <depends plugin="ResourceUpgradeMultiTestBase"
useClasses="true"/>
+ <depends plugin="ResourceUpgradeMultiTestParentDep"/>
+
+ <server name="TestResourceParent"
+ discovery="BaseUpgradingDiscoveryComponent"
+ class="BaseResourceComponent">
+
+ <runs-inside>
+ <parent-resource-type name="ParentDependency"
plugin="ResourceUpgradeMultiTestParentDep"/>
+ </runs-inside>
+
+ <plugin-configuration>
+ <c:simple-property name="count" default="2" />
+ <c:simple-property name="key"
default="UPGRADED-test-resource-parent-%n,parent-%p" />
+ </plugin-configuration>
+
+ <service name="TestResource"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+ <plugin-configuration>
+ <c:simple-property name="count" default="15" />
+ <c:simple-property name="key"
default="UPGRADED-test-resource-%n,parent-%p" />
+ </plugin-configuration>
+
+ </service>
+
+
+ </server>
+
+</plugin>
+
commit c2f5b5363d1023106bc7e12a78999603c4c5f26e
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Sep 28 10:39:33 2010 +0200
remove the commented-out portions of the resource upgrade code.
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 1b0ed8e..de52cd8 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
@@ -1232,10 +1232,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
for (ResourceUpgradeResponse upgradeResponse : serverUpdates) {
String resourceKey = upgradeResponse.getUpgradedResourceKey();
String name = upgradeResponse.getUpgradedResourceName();
- //String version = upgradeReport.getNewVersion();
String description = upgradeResponse.getUpgradedResourceDescription();
- //Configuration pluginConfiguration =
upgradeReport.getNewPluginConfiguration();
- //Configuration resourceConfiguration =
upgradeReport.getNewResourceConfiguration();
//only bother if there's something to upgrade at all on this
resource.
if (resourceKey != null || name != null || description != null) {
@@ -1256,23 +1253,11 @@ public class InventoryManager extends AgentService implements
ContainerService,
logMessage.append("name, ");
}
- //if (version != null) {
- // existingResource.setVersion(version);
- //}
-
if (description != null) {
existingResource.setDescription(description);
logMessage.append("description, ");
}
- //if (pluginConfiguration != null) {
- //
existingResource.setPluginConfiguration(pluginConfiguration);
- //}
- //
- //if (resourceConfiguration != null) {
- //
existingResource.setResourceConfiguration(resourceConfiguration);
- //}
-
logMessage.replace(logMessage.length() - 1, logMessage.length(),
"to become [").append(
existingResource.toString()).append("]");
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 51287b7..e4cbf03 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
@@ -495,10 +495,7 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
String resourceKey = upgradeRequest.getNewResourceKey();
String name = upgradeRequest.getNewName();
-// String version = upgradeReport.getNewVersion();
String description = upgradeRequest.getNewDescription();
-// Configuration pluginConfiguration =
upgradeReport.getNewPluginConfiguration();
-// Configuration resourceConfiguration =
upgradeReport.getNewResourceConfiguration();
if (resourceKey != null || name != null || description != null) {
StringBuilder logMessage = new StringBuilder("Resource [")
@@ -516,38 +513,12 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
}
ret.setUpgradedResourceName(resource.getName());
-// if (version != null) {
-// changed = updateResourceVersion(resource, version) || changed;
-// }
-
if (allowGenericPropertiesUpgrade &&
needsUpgrade(resource.getDescription(), description)) {
resource.setDescription(description);
logMessage.append("description, ");
}
ret.setUpgradedResourceDescription(resource.getDescription());
-
-// if (pluginConfiguration != null) {
-// if (!equalOrNull(pluginConfiguration,
resource.getPluginConfiguration())) {
-// log.info("Resource [" + resource + "] upgraded
its plugin configuration from [" +
-// resource.getPluginConfiguration() + "] to [" +
pluginConfiguration + "]");
-// changed = true;
-// resource.setPluginConfiguration(pluginConfiguration);
-// }
-// }
-//
-// if (resourceConfiguration != null) {
-// if (!equalOrNull(resourceConfiguration,
resource.getResourceConfiguration())) {
-// //XXX Will this create a new history entry?
-//
-// log.info("Resource [" + resource + "] upgraded
its resource configuration from [" +
-// resource.getResourceConfiguration() + "] to [" +
resourceConfiguration + "]");
-//
-// changed = true;
-// resource.setResourceConfiguration(resourceConfiguration);
-// }
-// }
-
-
+
//finally let's remove the potential previous upgrade error. we've
now successfully
//upgraded the resource.
List<ResourceError> upgradeErrors =
resourceManager.findResourceErrors(subjectManager.getOverlord(), resource.getId(),
ResourceErrorType.UPGRADE);
commit 0ae5aa90c40d239e294857a961596ee500643dee
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Sep 28 10:36:32 2010 +0200
Clear the upgrade errors if the upgrade for given resource succeeds.
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 a480fb7..51287b7 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
@@ -481,7 +481,7 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
* @param existingResource
* @param upgradeRequest
* @param allowGenericPropertiesUpgrade name and description are only upgraded if
this is true
- * @return true if the resource was changed, false otherwise
+ * @return response to the upgrade request detailing what has been accepted on the
server side
*/
private ResourceUpgradeResponse upgradeResource(@NotNull Resource resource,
ResourceUpgradeRequest upgradeRequest, boolean allowGenericPropertiesUpgrade) {
if (upgradeRequest.getUpgradeErrorMessage() != null) {
@@ -547,6 +547,14 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
// }
// }
+
+ //finally let's remove the potential previous upgrade error. we've
now successfully
+ //upgraded the resource.
+ List<ResourceError> upgradeErrors =
resourceManager.findResourceErrors(subjectManager.getOverlord(), resource.getId(),
ResourceErrorType.UPGRADE);
+ for(ResourceError error : upgradeErrors) {
+ entityManager.remove(error);
+ }
+
logMessage.replace(logMessage.length() - 1, logMessage.length(),
"to become
[").append(resource.toString()).append("]");
commit c1b1f4dfdcf05c39879133c9fb562f8ecada6690
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Sep 24 14:32:23 2010 +0200
Handling the resource upgrade failure by disabling discovery of its siblings of the
same type.
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 563a786..1b0ed8e 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
@@ -192,7 +192,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
/**
* Handles the resource upgrade during the initialization of the inventory manager.
*/
- private ResourceUpgradeDelegate resourceUpgradeDelegate;
+ private ResourceUpgradeDelegate resourceUpgradeDelegate = new
ResourceUpgradeDelegate(this);
public InventoryManager() {
super(DiscoveryAgentService.class);
@@ -222,7 +222,6 @@ public class InventoryManager extends AgentService implements
ContainerService,
//try the resource upgrade before we have any schedulers set up
//so that we don't get any interventions from concurrently running
//discoveries.
- resourceUpgradeDelegate = new ResourceUpgradeDelegate(this);
upgradeResources();
availabilityCollectors = new AvailabilityCollectorThreadPool();
@@ -282,15 +281,24 @@ public class InventoryManager extends AgentService implements
ContainerService,
* an empty set if nothing is discovered. This may return
<code>null</code> if for some reason
* we could not invoke the discovery component.
*
+ * @param parentResourceContainer the container of the resource under which we are
going to execute the discovery
* @param component the discovery component that will actually go out and discover
resources
* @param context the context for use by the discovery component
* @return the details of all discovered resources, may be empty or
<code>null</code>
*
* @throws Exception if the discovery component threw an exception
*/
- public Set<DiscoveredResourceDetails>
invokeDiscoveryComponent(ResourceDiscoveryComponent component,
+ public Set<DiscoveredResourceDetails>
invokeDiscoveryComponent(ResourceContainer parentResourceContainer,
ResourceDiscoveryComponent component,
ResourceDiscoveryContext context) throws Exception {
+ Resource parentResource = parentResourceContainer == null ? null :
parentResourceContainer.getResource();
+
+ if (resourceUpgradeDelegate.hasUpgradeFailedInChildren(parentResource,
context.getResourceType())) {
+ log.debug("Discovery of [" + context.getResourceType() + "]
has been disallowed under " + (parentResource == null ? " the platform " :
parentResource) +
+ " because some of its siblings failed to upgrade.");
+ return null;
+ }
+
long timeout = getDiscoveryComponentTimeout(context.getResourceType());
try {
@@ -687,7 +695,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
// Ask the plugin's discovery component to find the new resource,
throwing exceptions if it cannot be
// found at all.
- Set<DiscoveredResourceDetails> discoveredResources =
invokeDiscoveryComponent(discoveryComponent,
+ Set<DiscoveredResourceDetails> discoveredResources =
invokeDiscoveryComponent(parentResourceContainer, discoveryComponent,
discoveryContext);
if ((discoveredResources == null) || discoveredResources.isEmpty()) {
log.info("Plugin Error: During manual add, discovery component
method ["
@@ -1207,7 +1215,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
return resourceContainer.updateAvailability(availabilityType);
}
- public void mergeResourceFromUpgrade(Set<ResourceUpgradeRequest>
upgradeRequests) {
+ public void mergeResourcesFromUpgrade(Set<ResourceUpgradeRequest>
upgradeRequests) {
Set<ResourceUpgradeResponse> serverUpdates = null;
try {
ServerServices serverServices = this.configuration.getServerServices();
@@ -1430,6 +1438,13 @@ public class InventoryManager extends AgentService implements
ContainerService,
@SuppressWarnings("unchecked")
public void activateResource(Resource resource, @NotNull ResourceContainer container,
boolean updatedPluginConfig)
throws InvalidPluginConfigurationException, PluginContainerException {
+ if (resourceUpgradeDelegate.hasUpgradeFailed(resource)) {
+ if (log.isTraceEnabled()) {
+ log.trace("Skipping activation of " + resource + " - it
has failed to upgrade.");
+ }
+ return;
+ }
+
ResourceComponent component = container.getResourceComponent();
// if the component already exists and is started, and the resource's plugin
config has not changed, there is
@@ -1762,7 +1777,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
* Shutdown the ResourceComponents from the bottom up.
* @param resource The resource to deactivate
*/
- private void deactivateResource(Resource resource) {
+ public void deactivateResource(Resource resource) {
this.inventoryLock.writeLock().lock();
try {
ResourceContainer container = getResourceContainer(resource);
@@ -1841,7 +1856,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
Set<DiscoveredResourceDetails> discoveredResources = null;
try {
- discoveredResources = invokeDiscoveryComponent(component,
context);
+ discoveredResources = invokeDiscoveryComponent(null, component,
context);
} catch (Throwable e) {
log.warn("Platform plugin discovery failed - skipping",
e);
}
@@ -2043,6 +2058,13 @@ public class InventoryManager extends AgentService implements
ContainerService,
}
}
+ /**
+ * @return true if the inventory manager failed to merge the upgrade requests with
the server during startup.
+ */
+ public boolean hasUpgradeMergeFailed() {
+ return resourceUpgradeDelegate.hasUpgradeMergeFailed();
+ }
+
/**
* Always use this before accessing the event listeners because this ensures
* thread safety.
@@ -2171,7 +2193,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
parentResourceContext, SystemInfoFactory.createSystemInfo(),
processScanResults,
Collections.EMPTY_LIST, this.configuration.getContainerName(),
this.configuration
.getPluginContainerDeployment());
- Set<DiscoveredResourceDetails> discoveredResources =
invokeDiscoveryComponent(discoveryComponent, context);
+ Set<DiscoveredResourceDetails> discoveredResources =
invokeDiscoveryComponent(parentContainer, discoveryComponent, context);
newResources = new HashSet<Resource>();
if ((discoveredResources != null) &&
(!discoveredResources.isEmpty())) {
IdentityHashMap<Configuration, DiscoveredResourceDetails>
pluginConfigObjects = new IdentityHashMap<Configuration,
DiscoveredResourceDetails>();
@@ -2613,6 +2635,12 @@ public class InventoryManager extends AgentService implements
ContainerService,
private void upgradeResources() {
try {
+
+ if (!configuration.isInsideAgent()) {
+ log.debug("Skipping resource upgrade in embedded mode.");
+ return;
+ }
+
log.debug("Executing resource upgrade.");
boolean syncResult = handleReport(new InventoryReport(getAgent()), true);
@@ -2622,7 +2650,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
}
upgradeResource(getPlatform());
-
+
log.debug("Sending the upgrade requests to the server.");
resourceUpgradeDelegate.sendRequests();
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
index 025ba3a..98a897e 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
@@ -19,15 +19,17 @@
package org.rhq.core.pc.upgrade;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-
import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.pc.PluginContainer;
import org.rhq.core.pc.inventory.InventoryManager;
@@ -56,7 +58,10 @@ public class ResourceUpgradeDelegate {
private Set<ResourceUpgradeRequest> requests = new
HashSet<ResourceUpgradeRequest>();
private InventoryManager inventoryManager;
-
+ private Set<Resource> failedResources = new HashSet<Resource>();
+ private Map<Resource, Set<ResourceType>> failedResourceTypesPerParent =
new HashMap<Resource, Set<ResourceType>>();
+ private boolean mergeFailed;
+
public ResourceUpgradeDelegate(InventoryManager inventoryManager) {
this.inventoryManager = inventoryManager;
}
@@ -88,11 +93,56 @@ public class ResourceUpgradeDelegate {
}
}
- public void sendRequests() {
- if (enabled) {
- if (requests.size() > 0) {
- inventoryManager.mergeResourceFromUpgrade(requests);
- requests.clear();
+ /**
+ * @return true if {@link #sendRequests()} threw an exception, false otherwise
+ */
+ public boolean hasUpgradeMergeFailed() {
+ return mergeFailed;
+ }
+
+ /**
+ * Tells whether given resource had a upgrade failure during the {@link
#processAndQueue(ResourceContainer)} invocation.
+ *
+ * @param resource the resource to test
+ * @return true if there was an error upgrading this resource, false otherwise
+ */
+ public boolean hasUpgradeFailed(Resource resource) {
+ return mergeFailed || failedResources.contains(resource);
+ }
+
+ /**
+ * Tells whether at least one of the children with given resource type of the given
parent resource
+ * had an upgrade failure during {@link #processAndQueue(ResourceContainer)}
invocation.
+ *
+ * @return true if at least one of the children of given type failed to upgrade,
false otherwise
+ */
+ public boolean hasUpgradeFailedInChildren(Resource parentResource, ResourceType
childrenResourceType) {
+ if (mergeFailed) {
+ return true;
+ }
+
+ Set<ResourceType> failedTypes =
failedResourceTypesPerParent.get(parentResource);
+
+ return failedTypes != null &&
failedTypes.contains(childrenResourceType);
+ }
+
+ public void sendRequests() throws Throwable {
+ if (enabled && requests.size() > 0) {
+ try {
+ inventoryManager.mergeResourcesFromUpgrade(requests);
+ } catch (Throwable t) {
+ mergeFailed = true;
+
+ //deactivate all the resources to be upgraded. We might have a problem
+ //because they have not been upgraded because the merge failed.
+ for(ResourceUpgradeRequest request : requests) {
+ ResourceContainer container =
inventoryManager.getResourceContainer(request.getResourceId());
+ if (container != null) {
+ inventoryManager.deactivateResource(container.getResource());
+ }
+ }
+
+ throw t;
}
}
}
@@ -157,6 +207,20 @@ public class ResourceUpgradeDelegate {
if (request.hasSomethingToUpgrade()) {
requests.add(request);
}
+
+ if (request.getUpgradeErrorMessage() != null) {
+ failedResources.add(resource);
+
+ Set<ResourceType> failedResourceTypesInParent =
failedResourceTypesPerParent.get(parentResource);
+ if (failedResourceTypesInParent == null) {
+ failedResourceTypesInParent = new HashSet<ResourceType>();
+ failedResourceTypesPerParent.put(parentResource,
failedResourceTypesInParent);
+ }
+
+ failedResourceTypesInParent.add(resource.getResourceType());
+
+ inventoryManager.deactivateResource(resource);
+ }
}
private String checkUpgradeValid(Resource resource, ResourceUpgradeReport
upgradeReport) {
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 244d2f2..1479345 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -237,6 +237,14 @@ public class ResourceUpgradeTest {
TestPayload test = new TestPayload() {
public void test(Resource resourceUpgradeTestResource) {
assertTrue(resourceUpgradeTestResource.getResourceErrors().size() > 0,
"There should be upgrade errors persisted on the server side.");
+
+ //the discovery of the failed resource mustn't have run
+ ResourceContainer container =
PluginContainer.getInstance().getInventoryManager().getResourceContainer(resourceUpgradeTestResource);
+ File dataDir = container.getResourceContext().getDataDirectory();
+
+ File marker = new File(dataDir, "failing-discovery-ran");
+
+ assertFalse(marker.exists(), "The discovery of the resource type
with a failed upgraded resource must not be executed but it was.");
}
@SuppressWarnings("unchecked")
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/DiscComponent.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/DiscComponent.java
index 54153e6..75bfbd7 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/DiscComponent.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/DiscComponent.java
@@ -19,6 +19,8 @@
package org.rhq.core.pc.upgrade.plugins.failing;
+import java.io.File;
+import java.io.IOException;
import java.util.Collections;
import java.util.Set;
@@ -44,6 +46,20 @@ public class DiscComponent implements
ResourceDiscoveryComponent<ResourceCompone
public Set<DiscoveredResourceDetails>
discoverResources(ResourceDiscoveryContext<ResourceComponent> context)
throws InvalidPluginConfigurationException, Exception {
+
+ //create a marker file so that the testing code knows this method has run
+ File dataDir = context.getParentResourceContext().getDataDirectory();
+ if (dataDir != null) {
+ if (!(dataDir.exists())) {
+ dataDir.mkdir();
+ }
+ File marker = new File(dataDir, "failing-discovery-ran");
+ try {
+ marker.createNewFile();
+ } catch (IOException e) {
+ }
+ }
+
return Collections.singleton(new
DiscoveredResourceDetails(context.getResourceType(), RESOURCE_KEY,
RESOURCE_NAME, null, RESOURCE_DESCRIPTION,
context.getDefaultPluginConfiguration(), null));
}
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 d1894cb..43c2ba5 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
@@ -91,6 +91,7 @@ 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.ServerServices;
+import org.rhq.core.pc.inventory.InventoryManager;
import org.rhq.core.pc.plugin.FileSystemPluginFinder;
import org.rhq.core.system.SystemInfoFactory;
import org.rhq.core.util.ObjectNameFactory;
@@ -1591,6 +1592,7 @@ public class AgentMain {
* <ul>
* <li>Registering with the server (if the agent needs to do so at
startup)</li>
* <li>Updating the plugins with the latest versions that are found on the
server</li>
+ * <li>Setup a conditional restart of the plugin container, see {@link
PluginContainerConditionalRestartListener}</li>
* </ul>
*
* @return <code>true</code> if the agent is not registered or the agent
was asked to re-register with the server;
@@ -1623,6 +1625,10 @@ public class AgentMain {
updatePlugins();
}
+ //the next thing is to setup the conditional restart of the PC if it fails to
merge
+ //the upgrade results with the server due to some network glitch
+ m_clientSender.addStateListener(new PluginContainerConditionalRestartListener(),
false);
+
return register;
}
@@ -3390,6 +3396,42 @@ public class AgentMain {
}
/**
+ * This listener restarts the plugin container upon establishing the connection with
the server
+ * if the following conditions are met:
+ * <ol>
+ * <li> The plugin container is started
+ * <li> It performed the resource upgrade but failed to merge the changes to
the server
+ * </ol>
+ * By restarting the plugin container in such conditions, we essentially re-run the
resource upgrade
+ * and let the plugin container try to re-merge with the server that we know has just
connected.
+ *
+ * @author Lukas Krejci
+ */
+ private class PluginContainerConditionalRestartListener implements
ClientCommandSenderStateListener {
+ public boolean startedSending(ClientCommandSender sender) {
+ try {
+ InventoryManager inventoryManager =
PluginContainer.getInstance().getInventoryManager();
+ if (inventoryManager != null &&
inventoryManager.hasUpgradeMergeFailed()) {
+
m_output.println(MSG.getMsg(AgentI18NResourceKeys.RESTARTING_PLUGIN_CONTAINER_AFTER_UPGRADE_MERGE_FAILURE));
+
LOG.info(AgentI18NResourceKeys.RESTARTING_PLUGIN_CONTAINER_AFTER_UPGRADE_MERGE_FAILURE);
+
+ PluginContainerPromptCommand pcCommand = new
PluginContainerPromptCommand();
+ pcCommand.execute(AgentMain.this, new String[] { "stop"
});
+ pcCommand.execute(AgentMain.this, new String[] { "start"
});
+ }
+ } catch (Exception e) {
+ LOG.error("Failed to restart the plugin container when server
connection established.");
+ }
+ return true;
+ }
+
+ public boolean stoppedSending(ClientCommandSender sender) {
+ //do nothing but keep listening
+ return true;
+ }
+ }
+
+ /**
* When the agent starts up, it needs to create the communications servers before
starting the plugin container;
* however, the agent must not process any incoming commands until after the plugin
container fully starts. This
* command listener will actually block indefinitely all commands from being
processed until its told to open the
diff --git
a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/i18n/AgentI18NResourceKeys.java
b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/i18n/AgentI18NResourceKeys.java
index eb1df86..c28349c 100644
---
a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/i18n/AgentI18NResourceKeys.java
+++
b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/i18n/AgentI18NResourceKeys.java
@@ -2050,4 +2050,7 @@ public interface AgentI18NResourceKeys {
@I18NMessage("Done.")
String AVAILABILITY_REPORT_SENT = "PromptCommand.availability.sent";
+
+ @I18NMessage("Restarting the plugin container due to previous failure to merge
the upgrade results with the server.")
+ String RESTARTING_PLUGIN_CONTAINER_AFTER_UPGRADE_MERGE_FAILURE =
"AgentMain.pc-conditional-restart";
}
\ No newline at end of file
diff --git
a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/promptcmd/DiscoveryPromptCommand.java
b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/promptcmd/DiscoveryPromptCommand.java
index 8736f05..1de2dfb 100644
---
a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/promptcmd/DiscoveryPromptCommand.java
+++
b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/promptcmd/DiscoveryPromptCommand.java
@@ -359,7 +359,7 @@ public class DiscoveryPromptCommand implements AgentPromptCommand {
PluginContainerDeployment.AGENT);
Set<DiscoveredResourceDetails> discoveredResources;
- discoveredResources =
inventoryManager.invokeDiscoveryComponent(discoveryComponent, context);
+ discoveredResources =
inventoryManager.invokeDiscoveryComponent(platformContainer, discoveryComponent,
context);
if (discoveredResources != null) {
for (DiscoveredResourceDetails discoveredResource : discoveredResources)
{
out.println(MSG.getMsg(AgentI18NResourceKeys.DISCOVERY_COMPONENT_RESULT,
discoveredResource
diff --git
a/modules/enterprise/agent/src/test/java/org/rhq/enterprise/agent/PluginContainerConditionalRestart.java
b/modules/enterprise/agent/src/test/java/org/rhq/enterprise/agent/PluginContainerConditionalRestart.java
new file mode 100644
index 0000000..b88d097
--- /dev/null
+++
b/modules/enterprise/agent/src/test/java/org/rhq/enterprise/agent/PluginContainerConditionalRestart.java
@@ -0,0 +1,31 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.enterprise.agent;
+
+import org.testng.annotations.Test;
+
+/**
+ *
+ * @author Lukas Krejci
+ */
+@Test
+public class PluginContainerConditionalRestart {
+ //TODO implement
+}
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
index 29815cc..95bec5f 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
@@ -23,7 +23,11 @@ import org.rhq.core.domain.resource.composite.ResourceComposite;
import org.rhq.enterprise.gui.coregui.client.components.table.Table;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
+import com.smartgwt.client.data.DSCallback;
+import com.smartgwt.client.data.DSRequest;
+import com.smartgwt.client.data.DSResponse;
import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.types.GroupStartOpen;
import com.smartgwt.client.widgets.HTMLPane;
import com.smartgwt.client.widgets.IButton;
import com.smartgwt.client.widgets.Window;
@@ -41,43 +45,37 @@ import com.smartgwt.client.widgets.grid.events.CellClickHandler;
public class OverviewView extends LocatableVLayout {
private ResourceComposite resourceComposite;
-
+ private OverviewForm form;
+ private Table errorsGrid;
+
public OverviewView(String locatorId, ResourceComposite resourceComposite) {
super(locatorId);
this.resourceComposite = resourceComposite;
- }
-
- @Override
- protected void onDraw() {
- super.onDraw();
-
- setLeft("10%");
- setWidth("80%");
-
- if (this.resourceComposite != null) {
- onResourceSelected(this.resourceComposite);
- }
- }
-
- public void onResourceSelected(ResourceComposite resourceComposite) {
- addMember(new OverviewForm(extendLocatorId("form"),
resourceComposite));
- buildErrorListGrid(resourceComposite);
- }
+ form = new OverviewForm(extendLocatorId("form"), resourceComposite);
+ errorsGrid = new Table(extendLocatorId("errors"), "Detected
errors", null, null, new String[] { ResourceErrorsDataSource.DETAIL_ID });
- private void buildErrorListGrid(ResourceComposite resourceComposite) {
- final Resource resource = resourceComposite.getResource();
- final Table errorsGrid = new Table(extendLocatorId("errors"));
+ Resource resource = resourceComposite.getResource();
+ ResourceErrorsDataSource errors = new
ResourceErrorsDataSource(resource.getId());
errorsGrid.setShowFooter(false);
-//
errorsGrid.getListGrid().setGroupByField(ResourceErrorsDataSource.ERROR_TYPE_ID);
-// errorsGrid.getListGrid().setGroupStartOpen(GroupStartOpen.ALL);
-// errorsGrid.getListGrid().setShowGroupSummary(true);
-
- errorsGrid.setDataSource(new ResourceErrorsDataSource(resource.getId()));
+ errorsGrid.setDataSource(errors);
- //hide only works after we set the datasource
- errorsGrid.getListGrid().hideField(ResourceErrorsDataSource.DETAIL_ID);
+ form.setHeight("*");
+ errorsGrid.setHeight("10%");
+ addMember(form);
+ addMember(errorsGrid);
+
+ }
+
+ @Override
+ public void onInit() {
+ super.onInit();
+ initErrorsGrid();
+ }
+
+ private void initErrorsGrid() {
+ errorsGrid.setTooltip("Click on the rows to see the error details.");
errorsGrid.getListGrid().addCellClickHandler(new CellClickHandler() {
public void onCellClick(CellClickEvent event) {
ListGridRecord record = event.getRecord();
@@ -113,7 +111,5 @@ public class OverviewView extends LocatableVLayout {
w.show();
}
});
-
- addMember(errorsGrid);
}
}
commit 34483f9ca83545ab317caf12545531ab5d9b31e9
Merge: b9e1f2c... 24ba997...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Sep 20 16:58:46 2010 +0200
Merge branch 'master' into resource-upgrade
diff --cc
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewForm.java
index 074b3c9,0000000..2479c87
mode 100644,000000..100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewForm.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewForm.java
@@@ -1,298 -1,0 +1,299 @@@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.enterprise.gui.coregui.client.inventory.resource.detail.summary;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.EnumSet;
+import java.util.List;
+
+import org.rhq.core.domain.measurement.DataType;
+import org.rhq.core.domain.measurement.DisplayType;
+import org.rhq.core.domain.measurement.MeasurementDataTrait;
+import org.rhq.core.domain.measurement.MeasurementDefinition;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.resource.composite.ResourceComposite;
+import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.components.form.EnhancedDynamicForm;
+import org.rhq.enterprise.gui.coregui.client.components.form.TogglableTextItem;
+import org.rhq.enterprise.gui.coregui.client.components.form.ValueUpdatedHandler;
+import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGWTServiceAsync;
+import
org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
+import org.rhq.enterprise.gui.coregui.client.util.message.Message;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.util.SC;
+import com.smartgwt.client.widgets.form.fields.FormItem;
+import com.smartgwt.client.widgets.form.fields.HeaderItem;
+import com.smartgwt.client.widgets.form.fields.SpacerItem;
+import com.smartgwt.client.widgets.form.fields.StaticTextItem;
+
+/**
+ * The Resource Summary>Overview tab, the form with resource data.
+ *
+ * @author Greg Hinkle
+ * @author Ian Springer
+ */
+public class OverviewForm extends EnhancedDynamicForm {
+
+ private ResourceGWTServiceAsync resourceService =
GWTServiceLookup.getResourceService();
+ private ResourceComposite resourceComposite;
+
- public OverviewForm(ResourceComposite resourceComposite) {
++ public OverviewForm(String locatorId, ResourceComposite resourceComposite) {
++ super(locatorId);
+ this.resourceComposite = resourceComposite;
+ }
+
+ @Override
+ protected void onDraw() {
+ super.onDraw();
+
+ setLeft("10%");
+ setWidth("80%");
+
+ if (this.resourceComposite != null) {
+ setResource(this.resourceComposite);
+ }
+ }
+
+ public void setResource(ResourceComposite resourceComposite) {
+
+ this.resourceComposite = resourceComposite;
+ Resource resource = resourceComposite.getResource();
+
+ // Load metric defs.
+
ResourceTypeRepository.Cache.getInstance().getResourceTypes(resource.getResourceType().getId(),
+ EnumSet.of(ResourceTypeRepository.MetadataType.measurements),
+ new ResourceTypeRepository.TypeLoadedCallback() {
+ public void onTypesLoaded(ResourceType type) {
+ try {
+ buildForm(type);
+ loadTraitValues();
+ } catch (Exception e) {
+ SC.say("Form load failure");
+ e.printStackTrace();
+ }
+ }
+ });
+ }
+
+ private void loadTraitValues() {
+ final Resource resource = resourceComposite.getResource();
+ GWTServiceLookup.getMeasurementDataService().findCurrentTraitsForResource(
+ resource.getId(),
+ DisplayType.SUMMARY,
+ new AsyncCallback<List<MeasurementDataTrait>>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Failed to load
traits for " + resource + ".",
+ caught);
+ }
+
+ public void onSuccess(List<MeasurementDataTrait> result) {
+ // TODO: Implement this method.
+ for (MeasurementDataTrait trait : result) {
+ String formId = trait.getName().replaceAll("\\.",
"_").replaceAll(" ", "__");
+ FormItem item = getItem(formId);
+
+ if (item != null) {
+ setValue(formId, trait.getValue());
+ }
+ }
+ markForRedraw();
+ }
+ }
+ );
+
+ }
+
+ private void buildForm(ResourceType type) {
+ List<MeasurementDefinition> traits = new
ArrayList<MeasurementDefinition>();
+
+ for (MeasurementDefinition measurement : type.getMetricDefinitions()) {
+ if (measurement.getDataType() == DataType.TRAIT &&
measurement.getDisplayType() == DisplayType.SUMMARY) {
+ traits.add(measurement);
+ }
+ }
+
+ Collections.sort(traits, new Comparator<MeasurementDefinition>() {
+ public int compare(MeasurementDefinition o1, MeasurementDefinition o2) {
+ return new
Integer(o1.getDisplayOrder()).compareTo(o2.getDisplayOrder());
+ }
+ });
+
+ List<FormItem> formItems = new ArrayList<FormItem>();
+
+ HeaderItem headerItem = new HeaderItem("header",
"Summary");
+ headerItem.setValue("Summary");
+ formItems.add(headerItem);
+
+ StaticTextItem typeItem = new StaticTextItem("type",
"Type");
+ typeItem.setTooltip("Plugin: " + type.getPlugin() +
"\n<br>" + "Type: " + type.getName());
+ typeItem.setValue(type.getName() + " (" + type.getPlugin() +
")");
+ formItems.add(typeItem);
+
+ final Resource resource = this.resourceComposite.getResource();
+ boolean modifiable =
this.resourceComposite.getResourcePermission().isInventory();
+
+ final FormItem nameItem = (modifiable) ? new TogglableTextItem() : new
StaticTextItem();
+ nameItem.setName("name");
+ nameItem.setTitle("Name");
+ nameItem.setValue(resource.getName());
+ if (nameItem instanceof TogglableTextItem) {
+ TogglableTextItem togglableNameItem = (TogglableTextItem) nameItem;
+ togglableNameItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
+ public void onValueUpdated(final String newName) {
+ final String oldName = resource.getName();
+ if (newName.equals(oldName)) {
+ return;
+ }
+ resource.setName(newName);
+ OverviewForm.this.resourceService.updateResource(resource, new
AsyncCallback<Void>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Failed to change
name of Resource with id "
+ + resource.getId()
+ + " from \"" + oldName +
"\" to \"" + newName + "\".", caught);
+ // We failed to update it on the Server, so change back the
Resource and the form item to
+ // the original value.
+ resource.setName(oldName);
+ nameItem.setValue(oldName);
+ }
+
+ public void onSuccess(Void result) {
+ CoreGUI.getMessageCenter().notify(new Message("Name of
Resource with id "
+ + resource.getId() + " was changed
from \""
+ + oldName + "\" to
\"" + newName + "\".", Message.Severity.Info));
+ }
+ });
+ }
+ });
+ }
+ formItems.add(nameItem);
+
+ final FormItem descriptionItem = (modifiable) ? new TogglableTextItem() : new
StaticTextItem();
+ descriptionItem.setName("description");
+ descriptionItem.setTitle("Description");
+ descriptionItem.setValue(resource.getDescription());
+ if (descriptionItem instanceof TogglableTextItem) {
+ TogglableTextItem togglableDescriptionItem = (TogglableTextItem)
descriptionItem;
+ togglableDescriptionItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
+ public void onValueUpdated(final String newDescription) {
+ final String oldDescription = resource.getDescription();
+ if (newDescription.equals(oldDescription)) {
+ return;
+ }
+ resource.setDescription(newDescription);
+ OverviewForm.this.resourceService.updateResource(resource, new
AsyncCallback<Void>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Failed to change
description of Resource with id "
+ + resource.getId()
+ + " from \"" +
oldDescription + "\" to \"" + newDescription + "\".",
caught);
+ // We failed to update it on the Server, so change back the
Resource and the form item to
+ // the original value.
+ resource.setDescription(oldDescription);
+ descriptionItem.setValue(oldDescription);
+ }
+
+ public void onSuccess(Void result) {
+ CoreGUI.getMessageCenter().notify(new
Message("Description of Resource with id "
+ + resource.getId() + " was changed
from \""
+ + oldDescription + "\" to
\"" + newDescription + "\".", Message.Severity.Info));
+ }
+ });
+ }
+ });
+ }
+ formItems.add(descriptionItem);
+
+ final FormItem locationItem = (modifiable) ? new TogglableTextItem() : new
StaticTextItem();
+ locationItem.setName("location");
+ locationItem.setTitle("Location");
+ locationItem.setValue(resource.getLocation());
+ if (locationItem instanceof TogglableTextItem) {
+ TogglableTextItem togglableNameItem = (TogglableTextItem) locationItem;
+ togglableNameItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
+ public void onValueUpdated(final String newLocation) {
+ final String oldLocation = resource.getLocation();
+ if (newLocation.equals(oldLocation)) {
+ return;
+ }
+ resource.setLocation(newLocation);
+ OverviewForm.this.resourceService.updateResource(resource, new
AsyncCallback<Void>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Failed to change
location of Resource with id "
+ + resource.getId()
+ + " from \"" +
oldLocation + "\" to \"" + newLocation + "\".",
caught);
+ // We failed to update it on the Server, so change back the
Resource and the form item to
+ // the original value.
+ resource.setLocation(oldLocation);
+ locationItem.setValue(oldLocation);
+ }
+
+ public void onSuccess(Void result) {
+ CoreGUI.getMessageCenter().notify(new Message("Location
of Resource with id "
+ + resource.getId() + " was changed
from \""
+ + oldLocation + "\" to
\"" + newLocation + "\".", Message.Severity.Info));
+ }
+ });
+ }
+ });
+ }
+ formItems.add(locationItem);
+
+
+ StaticTextItem versionItem = new StaticTextItem("version",
"Version");
+ formItems.add(versionItem);
+
+ StaticTextItem parentItem = new StaticTextItem("parent",
"Parent");
+ formItems.add(parentItem);
+
+ for (MeasurementDefinition trait : traits) {
+ String id = trait.getDisplayName().replaceAll("\\.",
"_").replaceAll(" ", "__");
+
+ StaticTextItem item = new StaticTextItem(id, trait.getDisplayName());
+ item.setTooltip(trait.getDescription());
+ formItems.add(item);
+// item.setValue("?");
+ }
+
+// SectionItem section = new SectionItem("Summary",
"Summary");
+// section.setTitle("Summary");
+// section.setDefaultValue("Summary");
+// section.setCanCollapse(true);
+// section.setCellStyle("HidablePlainSectionHeader");
+// section.setItemIds(itemIds.toArray(new String[itemIds.size()]));
+// formItems.add(0, section);
+
+ formItems.add(new SpacerItem());
+ setItems(formItems.toArray(new FormItem[formItems.size()]));
+
+ setValue("type", type.getName() + " (" + type.getPlugin() +
")");
+ setValue("name", resource.getName());
+ setValue("description", resource.getDescription());
+ setValue("location", resource.getLocation());
+ setValue("version", (resource.getVersion() != null) ?
resource.getVersion() : "<i>none</i>");
+ Resource parentResource = resource.getParentResource();
+ setValue("parent", parentResource != null ?
+ ("<a href=\"#Resource/" + parentResource.getId() +
"\">" +
+ parentResource.getName() + "</a>") :
"<i>none</i>");
+ }
+}
diff --cc
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
index 10bde5b,4cf2119..29815cc
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
@@@ -18,31 -18,49 +18,32 @@@
*/
package org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.summary;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.EnumSet;
-import java.util.List;
-
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.smartgwt.client.util.SC;
-import com.smartgwt.client.widgets.form.fields.FormItem;
-import com.smartgwt.client.widgets.form.fields.HeaderItem;
-import com.smartgwt.client.widgets.form.fields.SpacerItem;
-import com.smartgwt.client.widgets.form.fields.StaticTextItem;
-
-import org.rhq.core.domain.measurement.DataType;
-import org.rhq.core.domain.measurement.DisplayType;
-import org.rhq.core.domain.measurement.MeasurementDataTrait;
-import org.rhq.core.domain.measurement.MeasurementDefinition;
import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.composite.ResourceComposite;
-import org.rhq.enterprise.gui.coregui.client.CoreGUI;
-import org.rhq.enterprise.gui.coregui.client.components.form.EnhancedDynamicForm;
-import org.rhq.enterprise.gui.coregui.client.components.form.TogglableTextItem;
-import org.rhq.enterprise.gui.coregui.client.components.form.ValueUpdatedHandler;
-import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
-import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGWTServiceAsync;
-import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceSelectListener;
-import
org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
-import org.rhq.enterprise.gui.coregui.client.util.message.Message;
+import org.rhq.enterprise.gui.coregui.client.components.table.Table;
++import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
+
+import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.widgets.HTMLPane;
+import com.smartgwt.client.widgets.IButton;
+import com.smartgwt.client.widgets.Window;
+import com.smartgwt.client.widgets.events.ClickEvent;
+import com.smartgwt.client.widgets.events.ClickHandler;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+import com.smartgwt.client.widgets.grid.events.CellClickEvent;
+import com.smartgwt.client.widgets.grid.events.CellClickHandler;
- import com.smartgwt.client.widgets.layout.VLayout;
/**
* The Resource Summary>Overview tab.
*
- * @author Greg Hinkle
- * @author Ian Springer
+ * @author Lukas Krejci
*/
- public class OverviewView extends VLayout {
-public class OverviewView extends EnhancedDynamicForm implements ResourceSelectListener
{
++public class OverviewView extends LocatableVLayout {
- private ResourceGWTServiceAsync resourceService =
GWTServiceLookup.getResourceService();
private ResourceComposite resourceComposite;
- public OverviewView(ResourceComposite resourceComposite) {
+ public OverviewView(String locatorId, ResourceComposite resourceComposite) {
+ super(locatorId);
this.resourceComposite = resourceComposite;
}
@@@ -59,60 -77,218 +60,60 @@@
}
public void onResourceSelected(ResourceComposite resourceComposite) {
- addMember(new OverviewForm(resourceComposite));
-
- this.resourceComposite = resourceComposite;
- Resource resource = resourceComposite.getResource();
-
- // Load metric defs.
-
ResourceTypeRepository.Cache.getInstance().getResourceTypes(resource.getResourceType().getId(),
- EnumSet.of(ResourceTypeRepository.MetadataType.measurements),
- new ResourceTypeRepository.TypeLoadedCallback() {
- public void onTypesLoaded(ResourceType type) {
- try {
- buildForm(type);
- loadTraitValues();
- } catch (Exception e) {
- SC.say("Form load failure");
- e.printStackTrace();
- }
- }
- });
++ addMember(new OverviewForm(extendLocatorId("form"),
resourceComposite));
+ buildErrorListGrid(resourceComposite);
}
- private void loadTraitValues() {
+ private void buildErrorListGrid(ResourceComposite resourceComposite) {
final Resource resource = resourceComposite.getResource();
- Table errorsGrid = new Table("Errors");
-
GWTServiceLookup.getMeasurementDataService().findCurrentTraitsForResource(resource.getId(),
- DisplayType.SUMMARY, new
AsyncCallback<List<MeasurementDataTrait>>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError("Failed to load traits
for " + resource + ".", caught);
- }
-
- public void onSuccess(List<MeasurementDataTrait> result) {
- // TODO: Implement this method.
- for (MeasurementDataTrait trait : result) {
- String formId = trait.getName().replaceAll("\\.",
"_").replaceAll(" ", "__");
- FormItem item = getItem(formId);
-
- if (item != null) {
- setValue(formId, trait.getValue());
- }
++ final Table errorsGrid = new Table(extendLocatorId("errors"));
+
+ errorsGrid.setShowFooter(false);
+//
errorsGrid.getListGrid().setGroupByField(ResourceErrorsDataSource.ERROR_TYPE_ID);
+// errorsGrid.getListGrid().setGroupStartOpen(GroupStartOpen.ALL);
+// errorsGrid.getListGrid().setShowGroupSummary(true);
+
+ errorsGrid.setDataSource(new ResourceErrorsDataSource(resource.getId()));
+
+ //hide only works after we set the datasource
+ errorsGrid.getListGrid().hideField(ResourceErrorsDataSource.DETAIL_ID);
+
+ errorsGrid.getListGrid().addCellClickHandler(new CellClickHandler() {
+ public void onCellClick(CellClickEvent event) {
+ ListGridRecord record = event.getRecord();
+ final Window w = new Window();
+ w.setTitle("Error Details");
+ w.setIsModal(true);
+ w.setShowMinimizeButton(false);
+ w.setShowModalMask(true);
+ w.setWidth(640);
+ w.setHeight(480);
+ w.centerInPage();
+ w.setCanDragResize(true);
+
- VLayout layout = new VLayout(10);
++ LocatableVLayout layout = new
LocatableVLayout(errorsGrid.extendLocatorId("dialogLayout"), 10);
+ layout.setDefaultLayoutAlign(Alignment.CENTER);
+ layout.setLayoutMargin(10);
+
+ w.addItem(layout);
+
+ HTMLPane details = new HTMLPane();
+ details.setContents("<pre>" +
record.getAttribute(ResourceErrorsDataSource.DETAIL_ID) + "</pre>");
+ layout.addMember(details);
+
+ IButton ok = new IButton("Ok");
+ ok.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ w.destroy();
}
- markForRedraw();
- }
- });
-
- }
-
- private void buildForm(ResourceType type) {
- List<MeasurementDefinition> traits = new
ArrayList<MeasurementDefinition>();
-
- for (MeasurementDefinition measurement : type.getMetricDefinitions()) {
- if (measurement.getDataType() == DataType.TRAIT &&
measurement.getDisplayType() == DisplayType.SUMMARY) {
- traits.add(measurement);
- }
- }
-
- Collections.sort(traits, new Comparator<MeasurementDefinition>() {
- public int compare(MeasurementDefinition o1, MeasurementDefinition o2) {
- return new
Integer(o1.getDisplayOrder()).compareTo(o2.getDisplayOrder());
+ });
+
+ layout.addMember(ok);
+
+ w.show();
}
});
-
- List<FormItem> formItems = new ArrayList<FormItem>();
-
- HeaderItem headerItem = new HeaderItem("header",
"Summary");
- headerItem.setValue("Summary");
- formItems.add(headerItem);
-
- StaticTextItem typeItem = new StaticTextItem("type",
"Type");
- typeItem.setTooltip("Plugin: " + type.getPlugin() +
"\n<br>" + "Type: " + type.getName());
- typeItem.setValue(type.getName() + " (" + type.getPlugin() +
")");
- formItems.add(typeItem);
-
- final Resource resource = this.resourceComposite.getResource();
- boolean modifiable =
this.resourceComposite.getResourcePermission().isInventory();
-
- final FormItem nameItem = (modifiable) ? new TogglableTextItem() : new
StaticTextItem();
- nameItem.setName("name");
- nameItem.setTitle("Name");
- nameItem.setValue(resource.getName());
- if (nameItem instanceof TogglableTextItem) {
- TogglableTextItem togglableNameItem = (TogglableTextItem) nameItem;
- togglableNameItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
- public void onValueUpdated(final String newName) {
- final String oldName = resource.getName();
- if (newName.equals(oldName)) {
- return;
- }
- resource.setName(newName);
- OverviewView.this.resourceService.updateResource(resource, new
AsyncCallback<Void>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError(
- "Failed to change name of Resource with id " +
resource.getId() + " from \"" + oldName
- + "\" to \"" + newName +
"\".", caught);
- // We failed to update it on the Server, so change back the
Resource and the form item to
- // the original value.
- resource.setName(oldName);
- nameItem.setValue(oldName);
- }
-
- public void onSuccess(Void result) {
- CoreGUI.getMessageCenter().notify(
- new Message("Name of Resource with id " +
resource.getId() + " was changed from \""
- + oldName + "\" to \"" + newName
+ "\".", Message.Severity.Info));
- }
- });
- }
- });
- }
- formItems.add(nameItem);
-
- final FormItem descriptionItem = (modifiable) ? new TogglableTextItem() : new
StaticTextItem();
- descriptionItem.setName("description");
- descriptionItem.setTitle("Description");
- descriptionItem.setValue(resource.getDescription());
- if (descriptionItem instanceof TogglableTextItem) {
- TogglableTextItem togglableDescriptionItem = (TogglableTextItem)
descriptionItem;
- togglableDescriptionItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
- public void onValueUpdated(final String newDescription) {
- final String oldDescription = resource.getDescription();
- if (newDescription.equals(oldDescription)) {
- return;
- }
- resource.setDescription(newDescription);
- OverviewView.this.resourceService.updateResource(resource, new
AsyncCallback<Void>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError(
- "Failed to change description of Resource with id
" + resource.getId() + " from \""
- + oldDescription + "\" to \"" +
newDescription + "\".", caught);
- // We failed to update it on the Server, so change back the
Resource and the form item to
- // the original value.
- resource.setDescription(oldDescription);
- descriptionItem.setValue(oldDescription);
- }
-
- public void onSuccess(Void result) {
- CoreGUI.getMessageCenter().notify(
- new Message("Description of Resource with id "
+ resource.getId()
- + " was changed from \"" +
oldDescription + "\" to \"" + newDescription + "\".",
- Message.Severity.Info));
- }
- });
- }
- });
- }
- formItems.add(descriptionItem);
-
- final FormItem locationItem = (modifiable) ? new TogglableTextItem() : new
StaticTextItem();
- locationItem.setName("location");
- locationItem.setTitle("Location");
- locationItem.setValue(resource.getLocation());
- if (locationItem instanceof TogglableTextItem) {
- TogglableTextItem togglableNameItem = (TogglableTextItem) locationItem;
- togglableNameItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
- public void onValueUpdated(final String newLocation) {
- final String oldLocation = resource.getLocation();
- if (newLocation.equals(oldLocation)) {
- return;
- }
- resource.setLocation(newLocation);
- OverviewView.this.resourceService.updateResource(resource, new
AsyncCallback<Void>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError(
- "Failed to change location of Resource with id
" + resource.getId() + " from \""
- + oldLocation + "\" to \"" +
newLocation + "\".", caught);
- // We failed to update it on the Server, so change back the
Resource and the form item to
- // the original value.
- resource.setLocation(oldLocation);
- locationItem.setValue(oldLocation);
- }
-
- public void onSuccess(Void result) {
- CoreGUI.getMessageCenter().notify(
- new Message("Location of Resource with id " +
resource.getId() + " was changed from \""
- + oldLocation + "\" to \"" +
newLocation + "\".", Message.Severity.Info));
- }
- });
- }
- });
- }
- formItems.add(locationItem);
-
- StaticTextItem versionItem = new StaticTextItem("version",
"Version");
- formItems.add(versionItem);
-
- StaticTextItem parentItem = new StaticTextItem("parent",
"Parent");
- formItems.add(parentItem);
-
- for (MeasurementDefinition trait : traits) {
- String id = trait.getDisplayName().replaceAll("\\.",
"_").replaceAll(" ", "__");
-
- StaticTextItem item = new StaticTextItem(id, trait.getDisplayName());
- item.setTooltip(trait.getDescription());
- formItems.add(item);
- // item.setValue("?");
- }
-
- // SectionItem section = new SectionItem("Summary",
"Summary");
- // section.setTitle("Summary");
- // section.setDefaultValue("Summary");
- // section.setCanCollapse(true);
- // section.setCellStyle("HidablePlainSectionHeader");
- // section.setItemIds(itemIds.toArray(new String[itemIds.size()]));
- // formItems.add(0, section);
-
- formItems.add(new SpacerItem());
- setItems(formItems.toArray(new FormItem[formItems.size()]));
-
- setValue("type", type.getName() + " (" + type.getPlugin() +
")");
- setValue("name", resource.getName());
- setValue("description", resource.getDescription());
- setValue("location", resource.getLocation());
- setValue("version", (resource.getVersion() != null) ?
resource.getVersion() : "<i>none</i>");
- Resource parentResource = resource.getParentResource();
- setValue("parent", parentResource != null ? ("<a
href=\"#Resource/" + parentResource.getId() + "\">"
- + parentResource.getName() + "</a>") :
"<i>none</i>");
+
+ addMember(errorsGrid);
}
}
diff --cc
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
index 267b0f1,dd5e77b..4ac0f61
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
@@@ -225,8 -226,18 +227,22 @@@ public abstract class RPCDataSource<T>
addField(field);
}
}
+
+ public void addFields(DataSourceField... fields) {
+ addFields(Arrays.asList(fields));
+ }
+
+ public ListGridRecord getEditedRecord(DSRequest request) {
+ // Retrieving values before edit
+ JavaScriptObject oldValues =
request.getAttributeAsJavaScriptObject("oldValues");
+ // Creating new record for combining old values with changes
+ ListGridRecord newRecord = new ListGridRecord();
+ // Copying properties from old record
+ JSOHelper.apply(oldValues, newRecord.getJsObj());
+ // Retrieving changed values
+ JavaScriptObject data = request.getData();
+ // Apply changes
+ JSOHelper.apply(data, newRecord.getJsObj());
+ return newRecord;
+ }
}
commit b9e1f2c995a66a147793c72dbeb13df7c162128e
Merge: 0cd6acd... e5fac0a...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Sep 14 18:33:01 2010 +0200
Merge branch 'master' into resource-upgrade
diff --cc
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
index c06d0c2,b282e41..5990b60
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
@@@ -28,7 -28,8 +28,9 @@@ import org.rhq.core.domain.configuratio
import org.rhq.core.domain.criteria.ResourceCriteria;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceError;
+ import org.rhq.core.domain.resource.composite.DisambiguationReport;
+ import org.rhq.core.domain.resource.composite.ProblemResourceComposite;
import org.rhq.core.domain.resource.composite.RecentlyAddedResourceComposite;
import org.rhq.core.domain.resource.composite.ResourceComposite;
import org.rhq.core.domain.util.PageControl;
@@@ -65,7 -68,5 +69,7 @@@ public interface ResourceGWTService ext
void ignoreResources(Integer[] resourceIds);
void unignoreResources(Integer[] resourceIds);
+
+ List<ResourceError> findResourceErrors(int resourceId);
--}
++}
diff --cc
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
index e63978a,ac2abc2..10bde5b
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
@@@ -18,33 -18,50 +18,31 @@@
*/
package org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.summary;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.EnumSet;
-import java.util.List;
-
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.smartgwt.client.util.SC;
-import com.smartgwt.client.widgets.form.fields.FormItem;
-import com.smartgwt.client.widgets.form.fields.HeaderItem;
-import com.smartgwt.client.widgets.form.fields.SpacerItem;
-import com.smartgwt.client.widgets.form.fields.StaticTextItem;
-
-import org.rhq.core.domain.measurement.DataType;
-import org.rhq.core.domain.measurement.DisplayType;
-import org.rhq.core.domain.measurement.MeasurementDataTrait;
-import org.rhq.core.domain.measurement.MeasurementDefinition;
import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.composite.ResourceComposite;
-import org.rhq.enterprise.gui.coregui.client.CoreGUI;
-import org.rhq.enterprise.gui.coregui.client.components.form.EnhancedDynamicForm;
-import org.rhq.enterprise.gui.coregui.client.components.form.TogglableTextItem;
-import org.rhq.enterprise.gui.coregui.client.components.form.ValueUpdatedHandler;
-import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
-import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGWTServiceAsync;
-import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceSelectListener;
-import
org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
-import org.rhq.enterprise.gui.coregui.client.util.message.Message;
+import org.rhq.enterprise.gui.coregui.client.components.table.Table;
- import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceSelectListener;
+
+import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.widgets.HTMLPane;
+import com.smartgwt.client.widgets.IButton;
+import com.smartgwt.client.widgets.Window;
+import com.smartgwt.client.widgets.events.ClickEvent;
+import com.smartgwt.client.widgets.events.ClickHandler;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+import com.smartgwt.client.widgets.grid.events.CellClickEvent;
+import com.smartgwt.client.widgets.grid.events.CellClickHandler;
+import com.smartgwt.client.widgets.layout.VLayout;
/**
* The Resource Summary>Overview tab.
*
- * @author Greg Hinkle
- * @author Ian Springer
+ * @author Lukas Krejci
*/
- public class OverviewView extends VLayout implements ResourceSelectListener {
-public class OverviewView extends EnhancedDynamicForm implements ResourceSelectListener
{
++public class OverviewView extends VLayout {
- private ResourceGWTServiceAsync resourceService =
GWTServiceLookup.getResourceService();
private ResourceComposite resourceComposite;
-
public OverviewView(ResourceComposite resourceComposite) {
-- super();
this.resourceComposite = resourceComposite;
}
diff --cc
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
index 4f3f3ce,cb2768f..267b0f1
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
@@@ -18,9 -18,10 +18,11 @@@
*/
package org.rhq.enterprise.gui.coregui.client.util;
+import java.util.Arrays;
+ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+ import java.util.Map;
import com.smartgwt.client.data.DSRequest;
import com.smartgwt.client.data.DSResponse;
@@@ -183,11 -221,7 +222,11 @@@ public abstract class RPCDataSource<T>
*/
public void addFields(List<DataSourceField> fields) {
for (DataSourceField field : fields) {
- addField(field);
+ addField(field);
}
}
+
+ public void addFields(DataSourceField... fields) {
+ addFields(Arrays.asList(fields));
+ }
}
diff --cc
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
index b933248,25b19b0..6db01f8
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
@@@ -35,7 -35,8 +35,9 @@@ import org.rhq.core.domain.configuratio
import org.rhq.core.domain.criteria.ResourceCriteria;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceError;
+ import org.rhq.core.domain.resource.composite.DisambiguationReport;
+ import org.rhq.core.domain.resource.composite.ProblemResourceComposite;
import org.rhq.core.domain.resource.composite.RecentlyAddedResourceComposite;
import org.rhq.core.domain.resource.composite.ResourceComposite;
import org.rhq.core.domain.util.PageControl;
@@@ -215,9 -239,5 +240,9 @@@ public class ResourceGWTServiceImpl ext
public void unignoreResources(Integer[] resourceIds) {
discoveryBoss.unignoreResources(getSessionSubject(), resourceIds);
}
-
-}
+
+ public List<ResourceError> findResourceErrors(int resourceId) {
+ return
SerialUtility.prepare(resourceManager.findResourceErrors(getSessionSubject(),
resourceId),
+ "ResourceService.getResourceErrors");
+ }
- }
++}
commit 0cd6acd2fe93a35a9b2cdbde0828c416ac49f67d
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Aug 24 17:48:01 2010 +0200
Make tests work with the changed test plugin jars location, added tests for upgrade
failure reporting.
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
index 19c1d95..adb3989 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
@@ -43,6 +43,8 @@ import org.rhq.core.clientapi.server.discovery.InventoryReport;
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.ResourceError;
+import org.rhq.core.domain.resource.ResourceErrorType;
import org.rhq.core.domain.resource.ResourceType;
/**
@@ -137,6 +139,11 @@ public class FakeServerInventory {
resource.setResourceKey(request.getNewResourceKey());
}
+ if (request.getUpgradeErrorMessage() != null) {
+ ResourceError error = new ResourceError(resource,
ResourceErrorType.UPGRADE, request.getUpgradeErrorMessage(),
request.getUpgradeErrorStackTrace(), request.getTimestamp());
+ resource.getResourceErrors().add(error);
+ }
+
ResourceUpgradeResponse resp = new ResourceUpgradeResponse();
resp.setResourceId(resource.getId());
resp.setUpgradedResourceName(resource.getName());
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 202e0c0..244d2f2 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -69,8 +69,9 @@ import org.rhq.core.pc.plugin.FileSystemPluginFinder;
@Test(sequential = true, invocationCount = 1)
public class ResourceUpgradeTest {
- private static final String PLUGIN_V1_FILENAME =
"resource-upgrade-test-plugin-1.0.0.jar";
- private static final String PLUGIN_V2_FILENAME =
"resource-upgrade-test-plugin-2.0.0.jar";
+ private static final String PLUGIN_V1_FILENAME =
"/resource-upgrade-test-plugin-1.0.0.jar";
+ private static final String PLUGIN_V2_FILENAME =
"/resource-upgrade-test-plugin-2.0.0.jar";
+ private static final String FAILING_PLUGIN_FILE_NAME =
"/resource-upgrade-test-plugin-3.0.0.jar";
private static final String PLUGINS_DIR_NAME = "plugins";
private static final String DATA_DIR_NAME = "data";
@@ -101,6 +102,7 @@ public class ResourceUpgradeTest {
public void sanityCheck() {
verifyPluginExists(PLUGIN_V1_FILENAME);
verifyPluginExists(PLUGIN_V2_FILENAME);
+ verifyPluginExists(FAILING_PLUGIN_FILE_NAME);
}
@BeforeClass(dependsOnMethods = "sanityCheck")
@@ -227,6 +229,35 @@ public class ResourceUpgradeTest {
executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, test);
}
+ @Test
+ public void testUpgradeFailureHandling() throws Exception {
+ currentServerSideInventory = new FakeServerInventory();
+ initialSyncAndDiscovery(InventoryStatus.COMMITTED);
+
+ TestPayload test = new TestPayload() {
+ public void test(Resource resourceUpgradeTestResource) {
+ assertTrue(resourceUpgradeTestResource.getResourceErrors().size() > 0,
"There should be upgrade errors persisted on the server side.");
+ }
+
+ @SuppressWarnings("unchecked")
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+
+ between(1,
4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
+
will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+
+
oneOf(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
+ will(currentServerSideInventory.upgradeResources());
+ }
+ };
+ }
+ };
+
+ executeTestWithPlugins(Collections.singleton(FAILING_PLUGIN_FILE_NAME), false,
test);
+ }
+
private void initialSyncAndDiscovery(final InventoryStatus requiredInventoryStatus)
throws Exception {
cleanDataDir();
executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), true, new
TestPayload() {
commit 90b602f22c280ee63deb7e51470db1fcda9b79a1
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Aug 24 17:46:58 2010 +0200
Final touches on the Server side error reporting.
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
index cc63040..e63978a 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
@@ -24,7 +24,6 @@ import org.rhq.enterprise.gui.coregui.client.components.table.Table;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceSelectListener;
import com.smartgwt.client.types.Alignment;
-import com.smartgwt.client.types.GroupStartOpen;
import com.smartgwt.client.widgets.HTMLPane;
import com.smartgwt.client.widgets.IButton;
import com.smartgwt.client.widgets.Window;
@@ -33,7 +32,6 @@ import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.grid.events.CellClickEvent;
import com.smartgwt.client.widgets.grid.events.CellClickHandler;
-import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;
/**
@@ -92,9 +90,10 @@ public class OverviewView extends VLayout implements
ResourceSelectListener {
w.setWidth(640);
w.setHeight(480);
w.centerInPage();
+ w.setCanDragResize(true);
VLayout layout = new VLayout(10);
- layout.setLayoutAlign(Alignment.CENTER);
+ layout.setDefaultLayoutAlign(Alignment.CENTER);
layout.setLayoutMargin(10);
w.addItem(layout);
@@ -109,7 +108,6 @@ public class OverviewView extends VLayout implements
ResourceSelectListener {
w.destroy();
}
});
- ok.setAlign(Alignment.CENTER);
layout.addMember(ok);
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ResourceErrorsDataSource.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ResourceErrorsDataSource.java
index 4957fc7..1843f2b 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ResourceErrorsDataSource.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ResourceErrorsDataSource.java
@@ -90,7 +90,7 @@ public class ResourceErrorsDataSource extends
RPCDataSource<ResourceError> {
ListGridRecord record = new ListGridRecord();
record.setAttribute(DETAIL_ID, from.getDetail());
- record.setAttribute(ERROR_TYPE_ID, from.getErrorType());
+ record.setAttribute(ERROR_TYPE_ID, from.getErrorType().toString());
record.setAttribute(SUMMARY_ID, from.getSummary());
record.setAttribute(TIME_OCCURED_ID, new Date(from.getTimeOccurred()));
commit f0b6cda14af2bce898dd6af66b4bb2627a836d72
Merge: d689f70... 66234db...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Aug 24 13:25:05 2010 +0200
Merge branch 'master' into resource-upgrade
diff --cc
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
index 1ea9630,950d28c..4f3f3ce
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
@@@ -18,8 -18,8 +18,9 @@@
*/
package org.rhq.enterprise.gui.coregui.client.util;
+import java.util.Arrays;
import java.util.Collection;
+ import java.util.List;
import com.smartgwt.client.data.DSRequest;
import com.smartgwt.client.data.DSResponse;
@@@ -172,13 -173,16 +174,20 @@@ public abstract class RPCDataSource<T>
return response;
}
- public void addFields(Collection<DataSourceField> fields) {
+ /**
+ * Add the specified fields to this data source. When the data source is associated
with a
+ * {@link com.smartgwt.client.widgets.grid.ListGrid}, the fields will be displayed
in the order they are specified
+ * here.
+ *
+ * @param fields the fields to be added
+ */
+ public void addFields(List<DataSourceField> fields) {
for (DataSourceField field : fields) {
- addField(field);
+ addField(field);
}
}
+
+ public void addFields(DataSourceField... fields) {
+ addFields(Arrays.asList(fields));
+ }
}
commit d689f70de060cdb776cea923f759f0e5de226955
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Aug 24 13:17:24 2010 +0200
Upgrade errors (and other resource errors) shown in the summary tab. Not everything
seems to work yet.
diff --git
a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
index 9532920..aca9c90 100644
---
a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
+++
b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
@@ -41,7 +41,7 @@ public class ResourceUpgradeRequest extends ResourceUpgradeReport {
private String upgradeErrorMessage;
private String upgradeErrorStackTrace;
private long timestamp;
-
+
public ResourceUpgradeRequest(int resourceId) {
this.resourceId = resourceId;
}
@@ -74,14 +74,37 @@ public class ResourceUpgradeRequest extends ResourceUpgradeReport {
public long getTimestamp() {
return timestamp;
}
-
+
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
-
+
public void setErrorProperties(Throwable t) {
- upgradeErrorMessage = t.getMessage();
+ upgradeErrorMessage = null;
+ upgradeErrorStackTrace = null;
+
+ //first try to extract an error message from the exception
+ //or some of its parents
+ Throwable p = t;
+ while (upgradeErrorMessage == null && p != null) {
+ upgradeErrorMessage = p.getMessage();
+ if (upgradeErrorMessage == null) {
+ upgradeErrorMessage = p.getLocalizedMessage();
+ }
+ p = p.getCause();
+ }
+
+ //ok, we have no error messages. But we have to supply something
+ //as the message, so let's use the class name as a last resort.
+ if (upgradeErrorMessage == null) {
+ if (t.getClass().getCanonicalName() != null) {
+ upgradeErrorMessage = t.getClass().getCanonicalName();
+ } else if (t.getClass().getName() != null) {
+ upgradeErrorMessage = t.getClass().getName();
+ }
+ }
+ //print the stack trace into a string
StringWriter string = new StringWriter();
PrintWriter w = new PrintWriter(string);
t.printStackTrace(w);
diff --git
a/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ResourceErrorTest.java
b/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ResourceErrorTest.java
index 8fdc2f7..6630d4b 100644
---
a/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ResourceErrorTest.java
+++
b/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ResourceErrorTest.java
@@ -92,7 +92,7 @@ public class ResourceErrorTest extends AbstractEJB3Test {
q.setParameter("resourceId", newResource.getId());
assert q.getResultList().size() == 2;
- q =
em.createNamedQuery(ResourceError.QUERY_FIND_BY_RESOURCE_ID_AND_ERROR_TYPE);
+ q =
em.createNamedQuery(ResourceError.QUERY_FIND_BY_RESOURCE_ID_AND_ERROR_TYPES);
q.setParameter("resourceId", newResource.getId());
q.setParameter("errorType",
ResourceErrorType.INVALID_PLUGIN_CONFIGURATION);
assert q.getResultList().size() == 2;
@@ -129,7 +129,7 @@ public class ResourceErrorTest extends AbstractEJB3Test {
assert errors.get(0).getDetail().equals("test detail");
assert errors.get(0).getTimeOccurred() == 12345;
- q =
em.createNamedQuery(ResourceError.QUERY_FIND_BY_RESOURCE_ID_AND_ERROR_TYPE);
+ q =
em.createNamedQuery(ResourceError.QUERY_FIND_BY_RESOURCE_ID_AND_ERROR_TYPES);
q.setParameter("resourceId", newResource.getId());
q.setParameter("errorType",
ResourceErrorType.INVALID_PLUGIN_CONFIGURATION);
errors = q.getResultList();
diff --git a/modules/core/plugin-container/pom.xml
b/modules/core/plugin-container/pom.xml
index a4ca249..4b09ef8 100644
--- a/modules/core/plugin-container/pom.xml
+++ b/modules/core/plugin-container/pom.xml
@@ -163,26 +163,39 @@
<id>process-test-classes</id>
<phase>process-test-classes</phase>
<configuration>
- <tasks>
- <echo>Assembling the two resource upgrade test
plugins</echo>
- <copy
toDir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v1/META-INF">
+ <tasks unless="maven.test.skip">
+ <echo>Assembling the resource upgrade test plugins</echo>
+ <copy
toDir="${project.build.testOutputDirectory}/tmp/v1/META-INF">
<fileset
file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/v1/rhq-plugin.xml"
/>
</copy>
- <jar
destfile="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-1.0.0.jar">
- <fileset
dir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v1"
includes="*.class,**/rhq-plugin.xml" />
+ <copy
toDir="${project.build.testOutputDirectory}/tmp/v1/org/rhq/core/pc/upgrade/plugins/v1">
+ <fileset
file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v1/*.class"
/>
+ </copy>
+ <jar
destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-1.0.0.jar">
+ <fileset
dir="${project.build.testOutputDirectory}/tmp/v1"
includes="**/*.class,**/rhq-plugin.xml" />
</jar>
- <copy
toDir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v2/META-INF">
+
+ <copy
toDir="${project.build.testOutputDirectory}/tmp/v2/META-INF">
<fileset
file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/v2/rhq-plugin.xml"
/>
</copy>
- <jar
destfile="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar">
- <fileset
dir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v2"
includes="*.class,**/rhq-plugin.xml" />
+ <copy
toDir="${project.build.testOutputDirectory}/tmp/v2/org/rhq/core/pc/upgrade/plugins/v2">
+ <fileset
file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v2/*.class"
/>
+ </copy>
+ <jar
destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-2.0.0.jar">
+ <fileset
dir="${project.build.testOutputDirectory}/tmp/v2"
includes="**/*.class,**/rhq-plugin.xml" />
</jar>
- <copy
toDir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/failing/META-INF">
+
+ <copy
toDir="${project.build.testOutputDirectory}/tmp/failing/META-INF">
<fileset
file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/failing/rhq-plugin.xml"
/>
</copy>
- <jar
destfile="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-3.0.0.jar">
- <fileset
dir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/failing"
includes="*.class,**/rhq-plugin.xml" />
+ <copy
toDir="${project.build.testOutputDirectory}/tmp/failing/org/rhq/core/pc/upgrade/plugins/failing">
+ <fileset
file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/failing/*.class"
/>
+ </copy>
+ <jar
destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-3.0.0.jar">
+ <fileset
dir="${project.build.testOutputDirectory}/tmp/failing"
includes="**/*.class,**/rhq-plugin.xml" />
</jar>
+
+ <delete
dir="${project.build.testOutputDirectory}/tmp"/>
</tasks>
</configuration>
<goals>
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
index f92e7d5..c06d0c2 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
@@ -28,6 +28,7 @@ import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.criteria.ResourceCriteria;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.domain.resource.composite.RecentlyAddedResourceComposite;
import org.rhq.core.domain.resource.composite.ResourceComposite;
import org.rhq.core.domain.util.PageControl;
@@ -64,5 +65,7 @@ public interface ResourceGWTService extends RemoteService {
void ignoreResources(Integer[] resourceIds);
void unignoreResources(Integer[] resourceIds);
+
+ List<ResourceError> findResourceErrors(int resourceId);
}
\ No newline at end of file
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
index 2fff538..cc63040 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
@@ -18,20 +18,22 @@
*/
package org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.summary;
-import java.util.ArrayList;
-import java.util.List;
-
import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.domain.resource.composite.ResourceComposite;
+import org.rhq.enterprise.gui.coregui.client.components.table.Table;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceSelectListener;
-import com.smartgwt.client.util.SC;
-import com.smartgwt.client.widgets.grid.ListGrid;
-import com.smartgwt.client.widgets.grid.ListGridField;
+import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.types.GroupStartOpen;
+import com.smartgwt.client.widgets.HTMLPane;
+import com.smartgwt.client.widgets.IButton;
+import com.smartgwt.client.widgets.Window;
+import com.smartgwt.client.widgets.events.ClickEvent;
+import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.grid.ListGridRecord;
-import com.smartgwt.client.widgets.grid.events.RecordClickEvent;
-import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
+import com.smartgwt.client.widgets.grid.events.CellClickEvent;
+import com.smartgwt.client.widgets.grid.events.CellClickHandler;
+import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;
/**
@@ -62,41 +64,59 @@ public class OverviewView extends VLayout implements
ResourceSelectListener {
public void onResourceSelected(ResourceComposite resourceComposite) {
addMember(new OverviewForm(resourceComposite));
- ListGrid errorsGrid = buildErrorListGrid(resourceComposite);
- if (errorsGrid != null) {
- addMember(errorsGrid);
- }
+ buildErrorListGrid(resourceComposite);
}
- private static ListGrid buildErrorListGrid(ResourceComposite resourceComposite) {
+ private void buildErrorListGrid(ResourceComposite resourceComposite) {
final Resource resource = resourceComposite.getResource();
- ListGrid errorsGrid = null;
- if (resource.getResourceErrors() != null &&
resource.getResourceErrors().size() > 0) {
- errorsGrid = new ListGrid();
-
- ListGridField summaryField = new ListGridField("summary",
"Errors");
- summaryField.addRecordClickHandler(new RecordClickHandler() {
-
- @Override
- public void onRecordClick(RecordClickEvent event) {
- String detail = event.getRecord().getAttribute("detail");
- SC.say("Error details", detail);
- }
- });
-
- errorsGrid.setFields(summaryField);
-
- List<ListGridRecord> errorList = new
ArrayList<ListGridRecord>();
- for (ResourceError error : resource.getResourceErrors()) {
- ListGridRecord record = new ListGridRecord();
- record.setAttribute("summary", error.getSummary());
- record.setAttribute("detail", error.getDetail());
- errorList.add(record);
+ Table errorsGrid = new Table("Errors");
+
+ errorsGrid.setShowFooter(false);
+//
errorsGrid.getListGrid().setGroupByField(ResourceErrorsDataSource.ERROR_TYPE_ID);
+// errorsGrid.getListGrid().setGroupStartOpen(GroupStartOpen.ALL);
+// errorsGrid.getListGrid().setShowGroupSummary(true);
+
+ errorsGrid.setDataSource(new ResourceErrorsDataSource(resource.getId()));
+
+ //hide only works after we set the datasource
+ errorsGrid.getListGrid().hideField(ResourceErrorsDataSource.DETAIL_ID);
+
+ errorsGrid.getListGrid().addCellClickHandler(new CellClickHandler() {
+ public void onCellClick(CellClickEvent event) {
+ ListGridRecord record = event.getRecord();
+ final Window w = new Window();
+ w.setTitle("Error Details");
+ w.setIsModal(true);
+ w.setShowMinimizeButton(false);
+ w.setShowModalMask(true);
+ w.setWidth(640);
+ w.setHeight(480);
+ w.centerInPage();
+
+ VLayout layout = new VLayout(10);
+ layout.setLayoutAlign(Alignment.CENTER);
+ layout.setLayoutMargin(10);
+
+ w.addItem(layout);
+
+ HTMLPane details = new HTMLPane();
+ details.setContents("<pre>" +
record.getAttribute(ResourceErrorsDataSource.DETAIL_ID) + "</pre>");
+ layout.addMember(details);
+
+ IButton ok = new IButton("Ok");
+ ok.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ w.destroy();
+ }
+ });
+ ok.setAlign(Alignment.CENTER);
+
+ layout.addMember(ok);
+
+ w.show();
}
-
- errorsGrid.setRecords(errorList.toArray(new
ListGridRecord[errorList.size()]));
- }
-
- return errorsGrid;
+ });
+
+ addMember(errorsGrid);
}
}
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ResourceErrorsDataSource.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ResourceErrorsDataSource.java
new file mode 100644
index 0000000..4957fc7
--- /dev/null
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ResourceErrorsDataSource.java
@@ -0,0 +1,100 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.enterprise.gui.coregui.client.inventory.resource.detail.summary;
+
+import java.util.Date;
+import java.util.List;
+
+import org.rhq.core.domain.resource.ResourceError;
+import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGWTServiceAsync;
+import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.data.DSRequest;
+import com.smartgwt.client.data.DSResponse;
+import com.smartgwt.client.data.fields.DataSourceDateField;
+import com.smartgwt.client.data.fields.DataSourceDateTimeField;
+import com.smartgwt.client.data.fields.DataSourceEnumField;
+import com.smartgwt.client.data.fields.DataSourceTextField;
+import com.smartgwt.client.rpc.RPCResponse;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+
+/**
+ *
+ * @author Lukas Krejci
+ */
+public class ResourceErrorsDataSource extends RPCDataSource<ResourceError> {
+
+ public static final String SUMMARY_ID = "summary";
+ public static final String DETAIL_ID = "detail";
+ public static final String ERROR_TYPE_ID = "errorType";
+ public static final String TIME_OCCURED_ID = "timeOccured";
+
+ ResourceGWTServiceAsync resourceService;
+ int resourceId;
+
+ public ResourceErrorsDataSource(int resourceId) {
+ resourceService = GWTServiceLookup.getResourceService();
+ this.resourceId = resourceId;
+
+ addFields(new DataSourceTextField(SUMMARY_ID, "Summary"),
+ new DataSourceTextField(DETAIL_ID, "Detailed Message"),
+ new DataSourceEnumField(ERROR_TYPE_ID, "Error Type"), new
DataSourceDateTimeField(TIME_OCCURED_ID, "Time"));
+ }
+
+ /* (non-Javadoc)
+ * @see
org.rhq.enterprise.gui.coregui.client.util.RPCDataSource#executeFetch(com.smartgwt.client.data.DSRequest,
com.smartgwt.client.data.DSResponse)
+ */
+ @Override
+ protected void executeFetch(final DSRequest request, final DSResponse response) {
+ resourceService.findResourceErrors(resourceId, new
AsyncCallback<List<ResourceError>>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError(
+ "Failed to find resource errors for resource with id: " +
resourceId, caught);
+ response.setStatus(RPCResponse.STATUS_FAILURE);
+ processResponse(request.getRequestId(), response);
+ }
+
+ public void onSuccess(List<ResourceError> result) {
+ response.setData(buildRecords(result));
+ processResponse(request.getRequestId(), response);
+ };
+ });
+ }
+
+ public ResourceError copyValues(ListGridRecord from) {
+ //This is read-only datasource, so no need to implement this.
+ return null;
+ }
+
+ public ListGridRecord copyValues(ResourceError from) {
+ ListGridRecord record = new ListGridRecord();
+
+ record.setAttribute(DETAIL_ID, from.getDetail());
+ record.setAttribute(ERROR_TYPE_ID, from.getErrorType());
+ record.setAttribute(SUMMARY_ID, from.getSummary());
+ record.setAttribute(TIME_OCCURED_ID, new Date(from.getTimeOccurred()));
+
+ return record;
+ }
+
+}
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
index 1b6f6cd..1ea9630 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
@@ -18,6 +18,7 @@
*/
package org.rhq.enterprise.gui.coregui.client.util;
+import java.util.Arrays;
import java.util.Collection;
import com.smartgwt.client.data.DSRequest;
@@ -176,4 +177,8 @@ public abstract class RPCDataSource<T> extends DataSource {
addField(field);
}
}
+
+ public void addFields(DataSourceField... fields) {
+ addFields(Arrays.asList(fields));
+ }
}
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
index c10254e..b933248 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
@@ -35,6 +35,7 @@ import
org.rhq.core.domain.configuration.definition.ConfigurationTemplate;
import org.rhq.core.domain.criteria.ResourceCriteria;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.domain.resource.composite.RecentlyAddedResourceComposite;
import org.rhq.core.domain.resource.composite.ResourceComposite;
import org.rhq.core.domain.util.PageControl;
@@ -215,4 +216,8 @@ public class ResourceGWTServiceImpl extends AbstractGWTServiceImpl
implements Re
discoveryBoss.unignoreResources(getSessionSubject(), resourceIds);
}
+ public List<ResourceError> findResourceErrors(int resourceId) {
+ return
SerialUtility.prepare(resourceManager.findResourceErrors(getSessionSubject(),
resourceId),
+ "ResourceService.getResourceErrors");
+ }
}
\ No newline at end of file
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 b773384..a480fb7 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
@@ -486,7 +486,7 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
private ResourceUpgradeResponse upgradeResource(@NotNull Resource resource,
ResourceUpgradeRequest upgradeRequest, boolean allowGenericPropertiesUpgrade) {
if (upgradeRequest.getUpgradeErrorMessage() != null) {
ResourceError error = new ResourceError(resource, ResourceErrorType.UPGRADE,
upgradeRequest.getUpgradeErrorMessage(), upgradeRequest.getUpgradeErrorStackTrace(),
upgradeRequest.getTimestamp());
- entityManager.persist(error);
+ resourceManager.addResourceError(error);
return null;
}
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
index 5a4cf92..29672cc 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
@@ -1708,6 +1708,21 @@ public class ResourceManagerBean implements ResourceManagerLocal,
ResourceManage
return query.getResultList();
}
+ @NotNull
+ @SuppressWarnings("unchecked")
+ public List<ResourceError> findResourceErrors(Subject user, int resourceId) {
+ // do authz check
+ if (!authorizationManager.canViewResource(user, resourceId)) {
+ throw new PermissionException("User [" + user + "] does not
have permission to view resource ["
+ + resourceId + "]");
+ }
+
+ // we passed authz check, now get the errors
+ Query query =
entityManager.createNamedQuery(ResourceError.QUERY_FIND_BY_RESOURCE_ID);
+ query.setParameter("resourceId", resourceId);
+ return query.getResultList();
+ }
+
public void addResourceError(ResourceError resourceError) {
Subject overlord = subjectManager.getOverlord();
Resource resource;
@@ -1718,9 +1733,10 @@ public class ResourceManagerBean implements ResourceManagerLocal,
ResourceManage
}
if (resourceError.getErrorType() ==
ResourceErrorType.INVALID_PLUGIN_CONFIGURATION
- || resourceError.getErrorType() == ResourceErrorType.AVAILABILITY_CHECK) {
- // there should be at most one invalid plugin configuration error and one
availability check error per
- // resource, so delete any currently existing ones before we add this new
one
+ || resourceError.getErrorType() == ResourceErrorType.AVAILABILITY_CHECK
+ || resourceError.getErrorType() == ResourceErrorType.UPGRADE) {
+ // there should be at most one invalid plugin configuration error,
availability check
+ // or upgrade error per resource, so delete any currently existing ones
before we add this new one
List<ResourceError> doomedErrors =
resource.getResourceErrors(resourceError.getErrorType());
// there should only ever be at most 1, but loop through the list just in
case something got screwed up
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
index a2f26ff..b84a104 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
@@ -319,6 +319,17 @@ public interface ResourceManagerLocal {
List<ResourceError> findResourceErrors(Subject user, int resourceId,
ResourceErrorType errorType);
/**
+ * Returns all the errors that have occurred for the given resource.
+ *
+ * @param user the user asking to see the errors
+ * @param resourceId the resource whose errors are to be returned
+ *
+ * @return the list of resource errors
+ */
+ @NotNull
+ List<ResourceError> findResourceErrors(Subject user, int resourceId);
+
+ /**
* Indicates an error occurred on a resource. The given error will be associated with
the resource found in the
* error.
*
commit 4e8ae3349ff28b025741a1c3bb0d1a827c0feff8
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Aug 20 15:14:27 2010 +0200
first stab at the errors display GUI.
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewForm.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewForm.java
new file mode 100644
index 0000000..074b3c9
--- /dev/null
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewForm.java
@@ -0,0 +1,298 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.enterprise.gui.coregui.client.inventory.resource.detail.summary;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.EnumSet;
+import java.util.List;
+
+import org.rhq.core.domain.measurement.DataType;
+import org.rhq.core.domain.measurement.DisplayType;
+import org.rhq.core.domain.measurement.MeasurementDataTrait;
+import org.rhq.core.domain.measurement.MeasurementDefinition;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.resource.composite.ResourceComposite;
+import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.components.form.EnhancedDynamicForm;
+import org.rhq.enterprise.gui.coregui.client.components.form.TogglableTextItem;
+import org.rhq.enterprise.gui.coregui.client.components.form.ValueUpdatedHandler;
+import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGWTServiceAsync;
+import
org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
+import org.rhq.enterprise.gui.coregui.client.util.message.Message;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.util.SC;
+import com.smartgwt.client.widgets.form.fields.FormItem;
+import com.smartgwt.client.widgets.form.fields.HeaderItem;
+import com.smartgwt.client.widgets.form.fields.SpacerItem;
+import com.smartgwt.client.widgets.form.fields.StaticTextItem;
+
+/**
+ * The Resource Summary>Overview tab, the form with resource data.
+ *
+ * @author Greg Hinkle
+ * @author Ian Springer
+ */
+public class OverviewForm extends EnhancedDynamicForm {
+
+ private ResourceGWTServiceAsync resourceService =
GWTServiceLookup.getResourceService();
+ private ResourceComposite resourceComposite;
+
+ public OverviewForm(ResourceComposite resourceComposite) {
+ this.resourceComposite = resourceComposite;
+ }
+
+ @Override
+ protected void onDraw() {
+ super.onDraw();
+
+ setLeft("10%");
+ setWidth("80%");
+
+ if (this.resourceComposite != null) {
+ setResource(this.resourceComposite);
+ }
+ }
+
+ public void setResource(ResourceComposite resourceComposite) {
+
+ this.resourceComposite = resourceComposite;
+ Resource resource = resourceComposite.getResource();
+
+ // Load metric defs.
+
ResourceTypeRepository.Cache.getInstance().getResourceTypes(resource.getResourceType().getId(),
+ EnumSet.of(ResourceTypeRepository.MetadataType.measurements),
+ new ResourceTypeRepository.TypeLoadedCallback() {
+ public void onTypesLoaded(ResourceType type) {
+ try {
+ buildForm(type);
+ loadTraitValues();
+ } catch (Exception e) {
+ SC.say("Form load failure");
+ e.printStackTrace();
+ }
+ }
+ });
+ }
+
+ private void loadTraitValues() {
+ final Resource resource = resourceComposite.getResource();
+ GWTServiceLookup.getMeasurementDataService().findCurrentTraitsForResource(
+ resource.getId(),
+ DisplayType.SUMMARY,
+ new AsyncCallback<List<MeasurementDataTrait>>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Failed to load traits
for " + resource + ".",
+ caught);
+ }
+
+ public void onSuccess(List<MeasurementDataTrait> result) {
+ // TODO: Implement this method.
+ for (MeasurementDataTrait trait : result) {
+ String formId = trait.getName().replaceAll("\\.",
"_").replaceAll(" ", "__");
+ FormItem item = getItem(formId);
+
+ if (item != null) {
+ setValue(formId, trait.getValue());
+ }
+ }
+ markForRedraw();
+ }
+ }
+ );
+
+ }
+
+ private void buildForm(ResourceType type) {
+ List<MeasurementDefinition> traits = new
ArrayList<MeasurementDefinition>();
+
+ for (MeasurementDefinition measurement : type.getMetricDefinitions()) {
+ if (measurement.getDataType() == DataType.TRAIT &&
measurement.getDisplayType() == DisplayType.SUMMARY) {
+ traits.add(measurement);
+ }
+ }
+
+ Collections.sort(traits, new Comparator<MeasurementDefinition>() {
+ public int compare(MeasurementDefinition o1, MeasurementDefinition o2) {
+ return new
Integer(o1.getDisplayOrder()).compareTo(o2.getDisplayOrder());
+ }
+ });
+
+ List<FormItem> formItems = new ArrayList<FormItem>();
+
+ HeaderItem headerItem = new HeaderItem("header", "Summary");
+ headerItem.setValue("Summary");
+ formItems.add(headerItem);
+
+ StaticTextItem typeItem = new StaticTextItem("type",
"Type");
+ typeItem.setTooltip("Plugin: " + type.getPlugin() +
"\n<br>" + "Type: " + type.getName());
+ typeItem.setValue(type.getName() + " (" + type.getPlugin() +
")");
+ formItems.add(typeItem);
+
+ final Resource resource = this.resourceComposite.getResource();
+ boolean modifiable =
this.resourceComposite.getResourcePermission().isInventory();
+
+ final FormItem nameItem = (modifiable) ? new TogglableTextItem() : new
StaticTextItem();
+ nameItem.setName("name");
+ nameItem.setTitle("Name");
+ nameItem.setValue(resource.getName());
+ if (nameItem instanceof TogglableTextItem) {
+ TogglableTextItem togglableNameItem = (TogglableTextItem) nameItem;
+ togglableNameItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
+ public void onValueUpdated(final String newName) {
+ final String oldName = resource.getName();
+ if (newName.equals(oldName)) {
+ return;
+ }
+ resource.setName(newName);
+ OverviewForm.this.resourceService.updateResource(resource, new
AsyncCallback<Void>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Failed to change
name of Resource with id "
+ + resource.getId()
+ + " from \"" + oldName +
"\" to \"" + newName + "\".", caught);
+ // We failed to update it on the Server, so change back the
Resource and the form item to
+ // the original value.
+ resource.setName(oldName);
+ nameItem.setValue(oldName);
+ }
+
+ public void onSuccess(Void result) {
+ CoreGUI.getMessageCenter().notify(new Message("Name of
Resource with id "
+ + resource.getId() + " was changed
from \""
+ + oldName + "\" to
\"" + newName + "\".", Message.Severity.Info));
+ }
+ });
+ }
+ });
+ }
+ formItems.add(nameItem);
+
+ final FormItem descriptionItem = (modifiable) ? new TogglableTextItem() : new
StaticTextItem();
+ descriptionItem.setName("description");
+ descriptionItem.setTitle("Description");
+ descriptionItem.setValue(resource.getDescription());
+ if (descriptionItem instanceof TogglableTextItem) {
+ TogglableTextItem togglableDescriptionItem = (TogglableTextItem)
descriptionItem;
+ togglableDescriptionItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
+ public void onValueUpdated(final String newDescription) {
+ final String oldDescription = resource.getDescription();
+ if (newDescription.equals(oldDescription)) {
+ return;
+ }
+ resource.setDescription(newDescription);
+ OverviewForm.this.resourceService.updateResource(resource, new
AsyncCallback<Void>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Failed to change
description of Resource with id "
+ + resource.getId()
+ + " from \"" +
oldDescription + "\" to \"" + newDescription + "\".",
caught);
+ // We failed to update it on the Server, so change back the
Resource and the form item to
+ // the original value.
+ resource.setDescription(oldDescription);
+ descriptionItem.setValue(oldDescription);
+ }
+
+ public void onSuccess(Void result) {
+ CoreGUI.getMessageCenter().notify(new
Message("Description of Resource with id "
+ + resource.getId() + " was changed
from \""
+ + oldDescription + "\" to
\"" + newDescription + "\".", Message.Severity.Info));
+ }
+ });
+ }
+ });
+ }
+ formItems.add(descriptionItem);
+
+ final FormItem locationItem = (modifiable) ? new TogglableTextItem() : new
StaticTextItem();
+ locationItem.setName("location");
+ locationItem.setTitle("Location");
+ locationItem.setValue(resource.getLocation());
+ if (locationItem instanceof TogglableTextItem) {
+ TogglableTextItem togglableNameItem = (TogglableTextItem) locationItem;
+ togglableNameItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
+ public void onValueUpdated(final String newLocation) {
+ final String oldLocation = resource.getLocation();
+ if (newLocation.equals(oldLocation)) {
+ return;
+ }
+ resource.setLocation(newLocation);
+ OverviewForm.this.resourceService.updateResource(resource, new
AsyncCallback<Void>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Failed to change
location of Resource with id "
+ + resource.getId()
+ + " from \"" + oldLocation
+ "\" to \"" + newLocation + "\".", caught);
+ // We failed to update it on the Server, so change back the
Resource and the form item to
+ // the original value.
+ resource.setLocation(oldLocation);
+ locationItem.setValue(oldLocation);
+ }
+
+ public void onSuccess(Void result) {
+ CoreGUI.getMessageCenter().notify(new Message("Location
of Resource with id "
+ + resource.getId() + " was changed
from \""
+ + oldLocation + "\" to
\"" + newLocation + "\".", Message.Severity.Info));
+ }
+ });
+ }
+ });
+ }
+ formItems.add(locationItem);
+
+
+ StaticTextItem versionItem = new StaticTextItem("version",
"Version");
+ formItems.add(versionItem);
+
+ StaticTextItem parentItem = new StaticTextItem("parent",
"Parent");
+ formItems.add(parentItem);
+
+ for (MeasurementDefinition trait : traits) {
+ String id = trait.getDisplayName().replaceAll("\\.",
"_").replaceAll(" ", "__");
+
+ StaticTextItem item = new StaticTextItem(id, trait.getDisplayName());
+ item.setTooltip(trait.getDescription());
+ formItems.add(item);
+// item.setValue("?");
+ }
+
+// SectionItem section = new SectionItem("Summary",
"Summary");
+// section.setTitle("Summary");
+// section.setDefaultValue("Summary");
+// section.setCanCollapse(true);
+// section.setCellStyle("HidablePlainSectionHeader");
+// section.setItemIds(itemIds.toArray(new String[itemIds.size()]));
+// formItems.add(0, section);
+
+ formItems.add(new SpacerItem());
+ setItems(formItems.toArray(new FormItem[formItems.size()]));
+
+ setValue("type", type.getName() + " (" + type.getPlugin() +
")");
+ setValue("name", resource.getName());
+ setValue("description", resource.getDescription());
+ setValue("location", resource.getLocation());
+ setValue("version", (resource.getVersion() != null) ?
resource.getVersion() : "<i>none</i>");
+ Resource parentResource = resource.getParentResource();
+ setValue("parent", parentResource != null ?
+ ("<a href=\"#Resource/" + parentResource.getId() +
"\">" +
+ parentResource.getName() + "</a>") :
"<i>none</i>");
+ }
+}
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
index ac2abc2..2fff538 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
@@ -19,53 +19,35 @@
package org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.summary;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.EnumSet;
import java.util.List;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.smartgwt.client.util.SC;
-import com.smartgwt.client.widgets.form.fields.FormItem;
-import com.smartgwt.client.widgets.form.fields.HeaderItem;
-import com.smartgwt.client.widgets.form.fields.SpacerItem;
-import com.smartgwt.client.widgets.form.fields.StaticTextItem;
-
-import org.rhq.core.domain.measurement.DataType;
-import org.rhq.core.domain.measurement.DisplayType;
-import org.rhq.core.domain.measurement.MeasurementDataTrait;
-import org.rhq.core.domain.measurement.MeasurementDefinition;
import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.domain.resource.composite.ResourceComposite;
-import org.rhq.enterprise.gui.coregui.client.CoreGUI;
-import org.rhq.enterprise.gui.coregui.client.components.form.EnhancedDynamicForm;
-import org.rhq.enterprise.gui.coregui.client.components.form.TogglableTextItem;
-import org.rhq.enterprise.gui.coregui.client.components.form.ValueUpdatedHandler;
-import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
-import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGWTServiceAsync;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceSelectListener;
-import
org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
-import org.rhq.enterprise.gui.coregui.client.util.message.Message;
+
+import com.smartgwt.client.util.SC;
+import com.smartgwt.client.widgets.grid.ListGrid;
+import com.smartgwt.client.widgets.grid.ListGridField;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+import com.smartgwt.client.widgets.grid.events.RecordClickEvent;
+import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
+import com.smartgwt.client.widgets.layout.VLayout;
/**
* The Resource Summary>Overview tab.
*
- * @author Greg Hinkle
- * @author Ian Springer
+ * @author Lukas Krejci
*/
-public class OverviewView extends EnhancedDynamicForm implements ResourceSelectListener
{
+public class OverviewView extends VLayout implements ResourceSelectListener {
- private ResourceGWTServiceAsync resourceService =
GWTServiceLookup.getResourceService();
private ResourceComposite resourceComposite;
-
public OverviewView(ResourceComposite resourceComposite) {
super();
this.resourceComposite = resourceComposite;
}
-
@Override
protected void onDraw() {
super.onDraw();
@@ -78,225 +60,43 @@ public class OverviewView extends EnhancedDynamicForm implements
ResourceSelectL
}
}
-
public void onResourceSelected(ResourceComposite resourceComposite) {
-
- this.resourceComposite = resourceComposite;
- Resource resource = resourceComposite.getResource();
-
- // Load metric defs.
-
ResourceTypeRepository.Cache.getInstance().getResourceTypes(resource.getResourceType().getId(),
- EnumSet.of(ResourceTypeRepository.MetadataType.measurements),
- new ResourceTypeRepository.TypeLoadedCallback() {
- public void onTypesLoaded(ResourceType type) {
- try {
- buildForm(type);
- loadTraitValues();
- } catch (Exception e) {
- SC.say("Form load failure");
- e.printStackTrace();
- }
- }
- });
+ addMember(new OverviewForm(resourceComposite));
+ ListGrid errorsGrid = buildErrorListGrid(resourceComposite);
+ if (errorsGrid != null) {
+ addMember(errorsGrid);
+ }
}
- private void loadTraitValues() {
+ private static ListGrid buildErrorListGrid(ResourceComposite resourceComposite) {
final Resource resource = resourceComposite.getResource();
- GWTServiceLookup.getMeasurementDataService().findCurrentTraitsForResource(
- resource.getId(),
- DisplayType.SUMMARY,
- new AsyncCallback<List<MeasurementDataTrait>>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError("Failed to load traits
for " + resource + ".",
- caught);
- }
-
- public void onSuccess(List<MeasurementDataTrait> result) {
- // TODO: Implement this method.
- for (MeasurementDataTrait trait : result) {
- String formId = trait.getName().replaceAll("\\.",
"_").replaceAll(" ", "__");
- FormItem item = getItem(formId);
-
- if (item != null) {
- setValue(formId, trait.getValue());
- }
- }
- markForRedraw();
- }
- }
- );
-
- }
-
- private void buildForm(ResourceType type) {
- List<MeasurementDefinition> traits = new
ArrayList<MeasurementDefinition>();
-
- for (MeasurementDefinition measurement : type.getMetricDefinitions()) {
- if (measurement.getDataType() == DataType.TRAIT &&
measurement.getDisplayType() == DisplayType.SUMMARY) {
- traits.add(measurement);
- }
- }
-
- Collections.sort(traits, new Comparator<MeasurementDefinition>() {
- public int compare(MeasurementDefinition o1, MeasurementDefinition o2) {
- return new
Integer(o1.getDisplayOrder()).compareTo(o2.getDisplayOrder());
- }
- });
-
- List<FormItem> formItems = new ArrayList<FormItem>();
-
- HeaderItem headerItem = new HeaderItem("header", "Summary");
- headerItem.setValue("Summary");
- formItems.add(headerItem);
+ ListGrid errorsGrid = null;
+ if (resource.getResourceErrors() != null &&
resource.getResourceErrors().size() > 0) {
+ errorsGrid = new ListGrid();
- StaticTextItem typeItem = new StaticTextItem("type",
"Type");
- typeItem.setTooltip("Plugin: " + type.getPlugin() +
"\n<br>" + "Type: " + type.getName());
- typeItem.setValue(type.getName() + " (" + type.getPlugin() +
")");
- formItems.add(typeItem);
+ ListGridField summaryField = new ListGridField("summary",
"Errors");
+ summaryField.addRecordClickHandler(new RecordClickHandler() {
- final Resource resource = this.resourceComposite.getResource();
- boolean modifiable =
this.resourceComposite.getResourcePermission().isInventory();
-
- final FormItem nameItem = (modifiable) ? new TogglableTextItem() : new
StaticTextItem();
- nameItem.setName("name");
- nameItem.setTitle("Name");
- nameItem.setValue(resource.getName());
- if (nameItem instanceof TogglableTextItem) {
- TogglableTextItem togglableNameItem = (TogglableTextItem) nameItem;
- togglableNameItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
- public void onValueUpdated(final String newName) {
- final String oldName = resource.getName();
- if (newName.equals(oldName)) {
- return;
- }
- resource.setName(newName);
- OverviewView.this.resourceService.updateResource(resource, new
AsyncCallback<Void>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError("Failed to change
name of Resource with id "
- + resource.getId()
- + " from \"" + oldName +
"\" to \"" + newName + "\".", caught);
- // We failed to update it on the Server, so change back the
Resource and the form item to
- // the original value.
- resource.setName(oldName);
- nameItem.setValue(oldName);
- }
-
- public void onSuccess(Void result) {
- CoreGUI.getMessageCenter().notify(new Message("Name of
Resource with id "
- + resource.getId() + " was changed
from \""
- + oldName + "\" to
\"" + newName + "\".", Message.Severity.Info));
- }
- });
+ @Override
+ public void onRecordClick(RecordClickEvent event) {
+ String detail = event.getRecord().getAttribute("detail");
+ SC.say("Error details", detail);
}
});
- }
- formItems.add(nameItem);
-
- final FormItem descriptionItem = (modifiable) ? new TogglableTextItem() : new
StaticTextItem();
- descriptionItem.setName("description");
- descriptionItem.setTitle("Description");
- descriptionItem.setValue(resource.getDescription());
- if (descriptionItem instanceof TogglableTextItem) {
- TogglableTextItem togglableDescriptionItem = (TogglableTextItem)
descriptionItem;
- togglableDescriptionItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
- public void onValueUpdated(final String newDescription) {
- final String oldDescription = resource.getDescription();
- if (newDescription.equals(oldDescription)) {
- return;
- }
- resource.setDescription(newDescription);
- OverviewView.this.resourceService.updateResource(resource, new
AsyncCallback<Void>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError("Failed to change
description of Resource with id "
- + resource.getId()
- + " from \"" +
oldDescription + "\" to \"" + newDescription + "\".",
caught);
- // We failed to update it on the Server, so change back the
Resource and the form item to
- // the original value.
- resource.setDescription(oldDescription);
- descriptionItem.setValue(oldDescription);
- }
-
- public void onSuccess(Void result) {
- CoreGUI.getMessageCenter().notify(new
Message("Description of Resource with id "
- + resource.getId() + " was changed
from \""
- + oldDescription + "\" to
\"" + newDescription + "\".", Message.Severity.Info));
- }
- });
- }
- });
- }
- formItems.add(descriptionItem);
- final FormItem locationItem = (modifiable) ? new TogglableTextItem() : new
StaticTextItem();
- locationItem.setName("location");
- locationItem.setTitle("Location");
- locationItem.setValue(resource.getLocation());
- if (locationItem instanceof TogglableTextItem) {
- TogglableTextItem togglableNameItem = (TogglableTextItem) locationItem;
- togglableNameItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
- public void onValueUpdated(final String newLocation) {
- final String oldLocation = resource.getLocation();
- if (newLocation.equals(oldLocation)) {
- return;
- }
- resource.setLocation(newLocation);
- OverviewView.this.resourceService.updateResource(resource, new
AsyncCallback<Void>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError("Failed to change
location of Resource with id "
- + resource.getId()
- + " from \"" + oldLocation
+ "\" to \"" + newLocation + "\".", caught);
- // We failed to update it on the Server, so change back the
Resource and the form item to
- // the original value.
- resource.setLocation(oldLocation);
- locationItem.setValue(oldLocation);
- }
+ errorsGrid.setFields(summaryField);
- public void onSuccess(Void result) {
- CoreGUI.getMessageCenter().notify(new Message("Location
of Resource with id "
- + resource.getId() + " was changed
from \""
- + oldLocation + "\" to
\"" + newLocation + "\".", Message.Severity.Info));
- }
- });
- }
- });
- }
- formItems.add(locationItem);
-
-
- StaticTextItem versionItem = new StaticTextItem("version",
"Version");
- formItems.add(versionItem);
-
- StaticTextItem parentItem = new StaticTextItem("parent",
"Parent");
- formItems.add(parentItem);
-
- for (MeasurementDefinition trait : traits) {
- String id = trait.getDisplayName().replaceAll("\\.",
"_").replaceAll(" ", "__");
+ List<ListGridRecord> errorList = new
ArrayList<ListGridRecord>();
+ for (ResourceError error : resource.getResourceErrors()) {
+ ListGridRecord record = new ListGridRecord();
+ record.setAttribute("summary", error.getSummary());
+ record.setAttribute("detail", error.getDetail());
+ errorList.add(record);
+ }
- StaticTextItem item = new StaticTextItem(id, trait.getDisplayName());
- item.setTooltip(trait.getDescription());
- formItems.add(item);
-// item.setValue("?");
+ errorsGrid.setRecords(errorList.toArray(new
ListGridRecord[errorList.size()]));
}
-// SectionItem section = new SectionItem("Summary",
"Summary");
-// section.setTitle("Summary");
-// section.setDefaultValue("Summary");
-// section.setCanCollapse(true);
-// section.setCellStyle("HidablePlainSectionHeader");
-// section.setItemIds(itemIds.toArray(new String[itemIds.size()]));
-// formItems.add(0, section);
-
- formItems.add(new SpacerItem());
- setItems(formItems.toArray(new FormItem[formItems.size()]));
-
- setValue("type", type.getName() + " (" + type.getPlugin() +
")");
- setValue("name", resource.getName());
- setValue("description", resource.getDescription());
- setValue("location", resource.getLocation());
- setValue("version", (resource.getVersion() != null) ?
resource.getVersion() : "<i>none</i>");
- Resource parentResource = resource.getParentResource();
- setValue("parent", parentResource != null ?
- ("<a href=\"#Resource/" + parentResource.getId() +
"\">" +
- parentResource.getName() + "</a>") :
"<i>none</i>");
+ return errorsGrid;
}
}
commit d266142e299215832de65b40be45e40862f56128
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Aug 20 15:14:04 2010 +0200
adding a test plugin that fails the upgrade so that we can add the tests for handling
that scenario
diff --git a/modules/core/plugin-container/pom.xml
b/modules/core/plugin-container/pom.xml
index 4b4524a..a4ca249 100644
--- a/modules/core/plugin-container/pom.xml
+++ b/modules/core/plugin-container/pom.xml
@@ -177,6 +177,12 @@
<jar
destfile="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar">
<fileset
dir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v2"
includes="*.class,**/rhq-plugin.xml" />
</jar>
+ <copy
toDir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/failing/META-INF">
+ <fileset
file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/failing/rhq-plugin.xml"
/>
+ </copy>
+ <jar
destfile="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-3.0.0.jar">
+ <fileset
dir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/failing"
includes="*.class,**/rhq-plugin.xml" />
+ </jar>
</tasks>
</configuration>
<goals>
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/DiscComponent.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/DiscComponent.java
new file mode 100644
index 0000000..54153e6
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/DiscComponent.java
@@ -0,0 +1,54 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.upgrade.plugins.failing;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
+import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
+
+/**
+ *
+ * @author Lukas Krejci
+ */
+public class DiscComponent implements
ResourceDiscoveryComponent<ResourceComponent>,
+ ResourceUpgradeFacet<ResourceComponent> {
+
+ private static final String RESOURCE_KEY = "resource-key-failing";
+ private static final String RESOURCE_NAME = "resource-name-failing";
+ private static final String RESOURCE_DESCRIPTION =
"resource-description-failing";
+
+ public Set<DiscoveredResourceDetails>
discoverResources(ResourceDiscoveryContext<ResourceComponent> context)
+ throws InvalidPluginConfigurationException, Exception {
+ return Collections.singleton(new
DiscoveredResourceDetails(context.getResourceType(), RESOURCE_KEY,
+ RESOURCE_NAME, null, RESOURCE_DESCRIPTION,
context.getDefaultPluginConfiguration(), null));
+ }
+
+ public ResourceUpgradeReport upgrade(ResourceUpgradeContext<ResourceComponent>
inventoriedResource) {
+ throw new RuntimeException("Failing the upgrade purposefully.");
+ }
+}
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/ResComponent.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/ResComponent.java
new file mode 100644
index 0000000..4c33adc
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/ResComponent.java
@@ -0,0 +1,46 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.upgrade.plugins.failing;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
+
+/**
+ *
+ * @author Lukas Krejci
+ */
+public class ResComponent implements ResourceComponent<ResourceComponent> {
+ private static final Log log = LogFactory.getLog(ResComponent.class);
+
+ public AvailabilityType getAvailability() {
+ return AvailabilityType.UP;
+ }
+
+ public void start(ResourceContext<ResourceComponent> context) throws
InvalidPluginConfigurationException, Exception {
+ log.info("~~~ starting the resource upgrade test failing component with
resource key: " + context.getResourceKey());
+ }
+
+ public void stop() {
+ }
+}
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/rhq-plugin.xml
new file mode 100644
index 0000000..9e750d1
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/rhq-plugin.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeTest"
+ displayName="Resource Upgrade Test"
+ description="Resource Upgrade Test"
+ package="org.rhq.core.pc.upgrade.plugins.failing"
+ version="3.0.0"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <server name="Resource"
+ discovery="DiscComponent"
+ class="ResComponent"
+ singleton="true" />
+
+</plugin>
+
commit 6dde2f7be37f23a5e8a9b25ccf66e99541fd3bc7
Merge: d58520e... 462e15f...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Aug 20 12:50:39 2010 +0200
Merge branch 'master' into resource-upgrade
commit d58520e4a31ab38e03151e827488776d4dcca93f
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Aug 20 12:46:29 2010 +0200
Added agent and server side support for upgrade error reporting.
diff --git
a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
index f055e8c..9532920 100644
---
a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
+++
b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
@@ -23,6 +23,9 @@
package org.rhq.core.clientapi.agent.upgrade;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
import org.rhq.core.domain.resource.ResourceUpgradeReport;
/**
@@ -34,44 +37,95 @@ public class ResourceUpgradeRequest extends ResourceUpgradeReport {
private static final long serialVersionUID = 1L;
- private int resourceId;
+ private final int resourceId;
+ private String upgradeErrorMessage;
+ private String upgradeErrorStackTrace;
+ private long timestamp;
- public ResourceUpgradeRequest() {
-
+ public ResourceUpgradeRequest(int resourceId) {
+ this.resourceId = resourceId;
}
public ResourceUpgradeRequest(int resourceId, ResourceUpgradeReport report) {
- setResourceId(resourceId);
- setNewDescription(report.getNewDescription());
- setNewName(report.getNewName());
- setNewResourceKey(report.getNewResourceKey());
+ this.resourceId = resourceId;
+ fillInFromReport(report);
}
-
+
public int getResourceId() {
return resourceId;
}
- public void setResourceId(int resourceId) {
- this.resourceId = resourceId;
+ public String getUpgradeErrorMessage() {
+ return upgradeErrorMessage;
+ }
+
+ public void setUpgradeErrorMessage(String upgradeErrorMessage) {
+ this.upgradeErrorMessage = upgradeErrorMessage;
+ }
+
+ public String getUpgradeErrorStackTrace() {
+ return upgradeErrorStackTrace;
+ }
+
+ public void setUpgradeErrorStackTrace(String upgradeErrorStackTrace) {
+ this.upgradeErrorStackTrace = upgradeErrorStackTrace;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
}
+ public void setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ public void setErrorProperties(Throwable t) {
+ upgradeErrorMessage = t.getMessage();
+
+ StringWriter string = new StringWriter();
+ PrintWriter w = new PrintWriter(string);
+ t.printStackTrace(w);
+ w.close();
+
+ upgradeErrorStackTrace = string.toString();
+ }
+
+ public void fillInFromReport(ResourceUpgradeReport report) {
+ setNewDescription(report.getNewDescription());
+ setNewName(report.getNewName());
+ setNewResourceKey(report.getNewResourceKey());
+ }
+
+ @Override
+ public boolean hasSomethingToUpgrade() {
+ return super.hasSomethingToUpgrade() || upgradeErrorMessage != null ||
upgradeErrorStackTrace != null;
+ }
+
@Override
public int hashCode() {
return 31 * resourceId;
}
-
+
@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}
-
+
if (!(other instanceof ResourceUpgradeRequest)) {
return false;
}
-
+
ResourceUpgradeRequest r = (ResourceUpgradeRequest) other;
-
+
return r.getResourceId() == resourceId;
}
+
+ @Override
+ public String toString() {
+ return "ResourceUpgradeRequest[resourceId = '" + resourceId +
"', newResourceKey = '" + getNewResourceKey()
+ + "', newName = '" + getNewName() + "',
newDescription = '" + getNewDescription()
+ + "', upgradeErrorMessage = '" + upgradeErrorMessage +
"', upgradeErrorStackTrace = '"
+ + upgradeErrorStackTrace + "']";
+ }
}
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceErrorType.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceErrorType.java
index 1435cc3..8fcedb7 100644
---
a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceErrorType.java
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceErrorType.java
@@ -36,5 +36,10 @@ public enum ResourceErrorType {
/**
* An exception was thrown by the Resource component's getAvailablity() method
the last time it was called.
*/
- AVAILABILITY_CHECK
+ AVAILABILITY_CHECK,
+
+ /**
+ * There was an attempt to upgrade the resource on the agent but it failed.
+ */
+ UPGRADE
}
\ No newline at end of file
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 728b2e3..3af9b84 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
@@ -1202,14 +1202,14 @@ public class InventoryManager extends AgentService implements
ContainerService,
return resourceContainer.updateAvailability(availabilityType);
}
- public void mergeResourceFromUpgrade(Set<ResourceUpgradeRequest>
upgradeReports) {
+ public void mergeResourceFromUpgrade(Set<ResourceUpgradeRequest>
upgradeRequests) {
Set<ResourceUpgradeResponse> serverUpdates = null;
try {
ServerServices serverServices = this.configuration.getServerServices();
if (serverServices != null) {
DiscoveryServerService discoveryServerService =
serverServices.getDiscoveryServerService();
- serverUpdates = discoveryServerService.upgradeResources(upgradeReports);
+ serverUpdates =
discoveryServerService.upgradeResources(upgradeRequests);
}
} catch (Exception e) {
log.error("Failed to process resource upgrades on the server.",
e);
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
index 5b33fe1..025ba3a 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
@@ -82,12 +82,10 @@ public class ResourceUpgradeDelegate {
* @return true if the resource was queued for upgrade, false otherwise
* @throws PluginContainerException on error
*/
- public boolean processAndQueue(ResourceContainer resourceContainer) throws
PluginContainerException {
+ public void processAndQueue(ResourceContainer resourceContainer) throws
PluginContainerException {
if (enabled) {
- return executeResourceUpgradeFacetAndStoreRequest(resourceContainer);
+ executeResourceUpgradeFacetAndStoreRequest(resourceContainer);
}
-
- return false;
}
public void sendRequests() {
@@ -100,7 +98,7 @@ public class ResourceUpgradeDelegate {
}
@SuppressWarnings("unchecked")
- private <T extends ResourceComponent> boolean
executeResourceUpgradeFacetAndStoreRequest(
+ private <T extends ResourceComponent> void
executeResourceUpgradeFacetAndStoreRequest(
ResourceContainer resourceContainer) throws PluginContainerException {
ResourceComponent<T> parentResourceComponent =
resourceContainer.getResourceContext()
@@ -118,36 +116,47 @@ public class ResourceUpgradeDelegate {
if (!(discoveryComponent instanceof ResourceUpgradeFacet)) {
//well, there's no point in continuing if the resource doesn't
support the facet
- return false;
+ return;
}
ResourceUpgradeContext<ResourceComponent<T>> upgradeContext =
inventoryManager.createResourceUpgradeContext(
resource, parentResourceComponent, discoveryComponent);
- ResourceUpgradeReport upgradeReport;
+ ResourceUpgradeRequest request = new ResourceUpgradeRequest(resource.getId());
+
+ request.setTimestamp(System.currentTimeMillis());
+
+ ResourceUpgradeReport upgradeReport = null;
try {
upgradeReport =
inventoryManager.invokeDiscoveryComponentResourceUpgradeFacet(resource.getResourceType(),
discoveryComponent, upgradeContext);
} catch (Throwable t) {
log.error("ResourceUpgradeFacet threw an exception while upgrading
resource [" + resource + "]", t);
- return false;
+ request.setErrorProperties(t);
}
- if (upgradeReport == null || !upgradeReport.hasSomethingToUpgrade()) {
- return false;
- }
+ if (upgradeReport != null && upgradeReport.hasSomethingToUpgrade()) {
+ String upgradeErrors = null;
+ if ((upgradeErrors = checkUpgradeValid(resource, upgradeReport)) != null) {
+ String errorString = "Upgrading the resource [" + resource +
"] using these updates [" + upgradeReport
+ + "] would render the inventory invalid because of the following
reasons: " + upgradeErrors;
+
+ log.error(errorString);
+
+ IllegalStateException ex = new IllegalStateException(errorString);
+ ex.fillInStackTrace();
+
+ request.setErrorProperties(ex);
+ } else {
+ request.fillInFromReport(upgradeReport);
+ }
- String upgradeErrors = null;
- if ((upgradeErrors = checkUpgradeValid(resource, upgradeReport)) != null) {
- log.error("Upgrading the resource [" + resource + "] using
these updates [" + upgradeReport
- + "] would render the inventory invalid because of the following
reasons: " + upgradeErrors);
- return false;
}
//everything went ok, let's queue a upgrade request that will be sent to the
server
- requests.add(new ResourceUpgradeRequest(resource.getId(), upgradeReport));
-
- return true;
+ if (request.hasSomethingToUpgrade()) {
+ requests.add(request);
+ }
}
private String checkUpgradeValid(Resource resource, ResourceUpgradeReport
upgradeReport) {
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 304cbad..b773384 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
@@ -58,6 +58,8 @@ import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.ProductVersion;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceCategory;
+import org.rhq.core.domain.resource.ResourceError;
+import org.rhq.core.domain.resource.ResourceErrorType;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.domain.util.PageControl;
@@ -422,7 +424,9 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
Resource existingResource = this.entityManager.find(Resource.class,
request.getResourceId());
if (existingResource != null) {
ResourceUpgradeResponse upgradedData = upgradeResource(existingResource,
request, allowGenericPropertiesUpgrade);
- result.add(upgradedData);
+ if (upgradedData != null) {
+ result.add(upgradedData);
+ }
}
}
return result;
@@ -475,18 +479,24 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
/**
* @param existingResource
- * @param upgradeReport
+ * @param upgradeRequest
* @param allowGenericPropertiesUpgrade name and description are only upgraded if
this is true
* @return true if the resource was changed, false otherwise
*/
- private ResourceUpgradeResponse upgradeResource(@NotNull Resource resource,
ResourceUpgradeReport upgradeReport, boolean allowGenericPropertiesUpgrade) {
+ private ResourceUpgradeResponse upgradeResource(@NotNull Resource resource,
ResourceUpgradeRequest upgradeRequest, boolean allowGenericPropertiesUpgrade) {
+ if (upgradeRequest.getUpgradeErrorMessage() != null) {
+ ResourceError error = new ResourceError(resource, ResourceErrorType.UPGRADE,
upgradeRequest.getUpgradeErrorMessage(), upgradeRequest.getUpgradeErrorStackTrace(),
upgradeRequest.getTimestamp());
+ entityManager.persist(error);
+ return null;
+ }
+
ResourceUpgradeResponse ret = new ResourceUpgradeResponse();
ret.setResourceId(resource.getId());
- String resourceKey = upgradeReport.getNewResourceKey();
- String name = upgradeReport.getNewName();
+ String resourceKey = upgradeRequest.getNewResourceKey();
+ String name = upgradeRequest.getNewName();
// String version = upgradeReport.getNewVersion();
- String description = upgradeReport.getNewDescription();
+ String description = upgradeRequest.getNewDescription();
// Configuration pluginConfiguration =
upgradeReport.getNewPluginConfiguration();
// Configuration resourceConfiguration =
upgradeReport.getNewResourceConfiguration();
commit 5b093893923a739ed2634c73e05392e917b8e7fb
Merge: 63d04ea... a13c17d...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Aug 11 16:43:07 2010 +0200
Merge branch 'master' into resource-upgrade
diff --cc
modules/enterprise/gui/portal-war/src/main/webapp/admin/config/GeneralPropertiesConfigForm.jsp
index 136c37c,45526f7..0000000
deleted file mode 100644,100644
---
a/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/GeneralPropertiesConfigForm.jsp
+++ /dev/null
diff --cc
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index add8168,2773b4c..304cbad
---
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
@@@ -659,22 -559,10 +659,22 @@@ public class DiscoveryBossBean implemen
*/
ResourceType resourceType = resource.getResourceType();
Resource parent = resource;
+ Subject overlord = subjectManager.getOverlord();
while (parent != null && existingResource == null) {
parent = parent.getParentResource();
- existingResource =
resourceManager.getResourceByParentAndKey(subjectManager.getOverlord(), parent,
+ //check if the parent itself is inventoried. This might not be the case
+ //during initial sync-up for resource upgrade.
+ Resource existingParent = null;
+ if (parent != null) {
+ existingParent = entityManager.find(Resource.class,
parent.getId());
+ if (existingParent == null) {
+ //well, this parent is not known to the server, so there's
no
+ //point in trying to find a child of it...
+ continue;
+ }
+ }
+ existingResource = resourceManager.getResourceByParentAndKey(overlord,
existingParent,
- resource.getResourceKey(), resourceType.getPlugin(),
resourceType.getName());
+ resource.getResourceKey(), resourceType.getPlugin(),
resourceType.getName());
}
if (existingResource != null) {
@@@ -905,8 -808,4 +920,8 @@@
updateInventoryStatus(subject, platforms, servers, target);
}
-}
+
+ private static <T> boolean needsUpgrade(T oldValue, T newValue) {
+ return newValue != null && (oldValue == null ||
!newValue.equals(oldValue));
+ }
- }
++}
commit 63d04eaf7e697a241efe59832d7a4e127a084f92
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Jul 12 18:39:22 2010 +0200
Adding tests for graceful handling of server-side exceptions and platform
"disappearance" on the server-side.
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 a5c3d1f..6fe7e96 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
@@ -940,8 +940,16 @@ public class InventoryManager extends AgentService implements
ContainerService,
//resource upgrade executor to sync up with the server side inventory *JUST
AFTER*
//this agent registered with the server for the very first time. In that case
//the server hasn't received any info from us yet.
+ //Another (rare) scenario where this would happen would be when the platform
resource type
+ //would change.
+ //In either case, let's sync up with the server - if it's got nothing,
neither should the agent.
if (syncInfo != null) {
synchInventory(syncInfo);
+ } else {
+ purgeObsoleteResources(Collections.<String>emptySet());
+
+ //can't live without a platform, but we just deleted it. Let's
rediscover it.
+ discoverPlatform();
}
return true;
@@ -1077,8 +1085,10 @@ public class InventoryManager extends AgentService implements
ContainerService,
return;
}
boolean scan =
removeResourceAndIndicateIfScanIsNeeded(resourceContainer.getResource());
-
- if (scan) {
+
+ //only actually schedule the scanning when we are finished with resource upgrade.
The resource upgrade
+ //happens before any scanning infrastructure is established.
+ if (!resourceUpgradeDelegate.enabled() && scan) {
log.info("Deleted resource #[" + resourceId + "] - this will
trigger a server scan now");
inventoryThreadPoolExecutor.submit((Callable<InventoryReport>)
this.serverScanExecutor);
}
@@ -2612,14 +2622,13 @@ public class InventoryManager extends AgentService implements
ContainerService,
ResourceContainer container = getResourceContainer(resource);
if (container != null) {
- try {
- container = getResourceContainer(resource);
- resourceUpgradeDelegate.processAndQueue(container);
- } catch (PluginContainerException e) {
- log.error("Exception thrown while upgrading [" + resource +
"].");
- }
-
if (container.getResourceComponentState() == ResourceComponentState.STARTED)
{
+ try {
+ resourceUpgradeDelegate.processAndQueue(container);
+ } catch (PluginContainerException e) {
+ log.error("Exception thrown while upgrading [" + resource +
"].", e);
+ }
+
for (Resource child : resource.getChildResources()) {
upgradeResource(child);
}
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
index c3bdbf4..19c1d95 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
@@ -56,7 +56,8 @@ public class FakeServerInventory {
private Resource platform;
private Map<String, Resource> resourceStore = new HashMap<String,
Resource>();
private int counter;
-
+ private boolean failing;
+
private static final Comparator<Resource> ID_COMPARATOR = new
Comparator<Resource>() {
public int compare(Resource o1, Resource o2) {
return o1.getId() - o2.getId();
@@ -69,11 +70,21 @@ public class FakeServerInventory {
}
};
+ public FakeServerInventory() {
+ this(false);
+ }
+
+ public FakeServerInventory(boolean failing) {
+ this.failing = failing;
+ }
+
//need to synchronize, because resource upgrade is async and can overlap with
//resource discovery.
public synchronized CustomAction mergeInventoryReport(final InventoryStatus
requiredInventoryStatus) {
return new CustomAction("updateServerSideInventory") {
public Object invoke(Invocation invocation) throws Throwable {
+ throwIfFailing();
+
InventoryReport inventoryReport = (InventoryReport)
invocation.getParameter(0);
for(Resource res : inventoryReport.getAddedRoots()) {
@@ -87,10 +98,24 @@ public class FakeServerInventory {
};
}
+ public synchronized CustomAction clearPlatform() {
+ return new CustomAction("updateServerSideInventory - report platform deleted
on the server") {
+ public Object invoke(Invocation invocation) throws Throwable {
+ throwIfFailing();
+
+ platform = null;
+
+ return getSyncInfo();
+ }
+ };
+ }
+
public synchronized CustomAction upgradeResources() {
return new CustomAction("upgradeServerSideInventory") {
@SuppressWarnings({"serial", "unchecked"})
public Object invoke(Invocation invocation) throws Throwable {
+ throwIfFailing();
+
Set<ResourceUpgradeRequest> requests =
(Set<ResourceUpgradeRequest>) invocation.getParameter(0);
Set<ResourceUpgradeResponse> responses = new
HashSet<ResourceUpgradeResponse>();
@@ -129,6 +154,8 @@ public class FakeServerInventory {
return new CustomAction("getResources") {
@SuppressWarnings("unchecked")
public Object invoke(Invocation invocation) throws Throwable {
+ throwIfFailing();
+
Set<Integer> resourceIds =
(Set<Integer>)invocation.getParameter(0);
boolean includeDescendants = (Boolean) invocation.getParameter(1);
@@ -137,6 +164,14 @@ public class FakeServerInventory {
};
}
+ public boolean isFailing() {
+ return failing;
+ }
+
+ public void setFailing(boolean failing) {
+ this.failing = failing;
+ }
+
@SuppressWarnings("serial")
public synchronized Set<Resource> findResourcesByType(final ResourceType type)
{
Set<Resource> result = new HashSet<Resource>();
@@ -218,6 +253,12 @@ public class FakeServerInventory {
return platform != null ? convert(platform) : null;
}
+ private void throwIfFailing() {
+ if (failing) {
+ throw new RuntimeException("Fake server inventory is in the failing
mode.");
+ }
+ }
+
private static ResourceSyncInfo convert(Resource root) {
try {
ResourceSyncInfo ret = new ResourceSyncInfo();
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index b5d571f..202e0c0 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -25,6 +25,7 @@ package org.rhq.core.pc.upgrade;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
import java.io.File;
import java.io.IOException;
@@ -151,11 +152,83 @@ public class ResourceUpgradeTest {
}
@Test
- public void testRecoveryWithServerUnavailable() throws Exception {
- //TODO implement
+ public void testSkipUpgradeWhenServerUnavailable() throws Exception {
+ currentServerSideInventory = new FakeServerInventory();
+ initialSyncAndDiscovery(InventoryStatus.COMMITTED);
+
+ currentServerSideInventory.setFailing(true);
+
+ TestPayload test = new TestPayload() {
+ public void test(Resource discoveredResource) {
+ assertEquals(discoveredResource.getResourceKey(),
"resource-key-v1");
+ assertEquals(discoveredResource.getName(),
"resource-name-v1");
+ assertEquals(discoveredResource.getDescription(),
"resource-description-v1");
+ }
+
+ @SuppressWarnings("unchecked")
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+
+ between(1,
4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
+
will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+
+
never(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
+ }
+ };
+ }
+ };
+
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, test);
+ }
+
+ @Test
+ public void testUpgradeWithPlatformDeletedOnServer() throws Exception {
+ currentServerSideInventory = new FakeServerInventory();
+ initialSyncAndDiscovery(InventoryStatus.COMMITTED);
+
+ TestPayload test = new TestPayload() {
+ public void test(Resource discoveredResource) {
+ assertEquals(discoveredResource.getResourceKey(),
"resource-key-v2");
+ assertEquals(discoveredResource.getName(),
"resource-name-v2");
+ assertEquals(discoveredResource.getDescription(),
"resource-description-v2");
+
+ ResourceContainer container =
PluginContainer.getInstance().getInventoryManager().getResourceContainer(discoveredResource);
+ File dataDir = container.getResourceContext().getDataDirectory();
+
+ File marker = new File(dataDir, "upgrade-succeeded");
+
+ assertFalse(marker.exists(), "The upgrade seems to have occured even
though there shouldn't have been a resource to upgrade.");
+ }
+
+ @SuppressWarnings("unchecked")
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+
+ //the first merge will be triggered from within the upgrade
process and we are
+ //going to report null sync.
+
oneOf(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(currentServerSideInventory.clearPlatform());
+
+ //the rest of the inventory merges are executed by discoveries,
so let's import the
+ //discovered stuff into the server-side inventory.
+ between(1,
3).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
+
will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+
+
never(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
+ }
+ };
+ }
+ };
+
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, test);
}
private void initialSyncAndDiscovery(final InventoryStatus requiredInventoryStatus)
throws Exception {
+ cleanDataDir();
executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), true, new
TestPayload() {
public void test(Resource discoveredResource) {
assertEquals(discoveredResource.getResourceKey(),
"resource-key-v1");
@@ -303,40 +376,43 @@ public class ResourceUpgradeTest {
for(String pluginResourcePath : pluginResourcePaths) {
copyPlugin(pluginResourcePath, pluginDir);
}
-
+
Mockery context = new Mockery();
-
+
PluginContainerConfiguration pcConfig =
createPluginContainerConfiguration(context);
-
+
if (clearInventoryDat) {
File inventoryDat = new File(pcConfig.getDataDirectory(),
"inventory.dat");
inventoryDat.delete();
}
-
+
context.checking(test.getExpectations(context));
-
+
PluginContainer.getInstance().setConfiguration(pcConfig);
PluginContainer.getInstance().initialize();
-
- //give the pc the time to finish resource upgrade
- Thread.sleep(1000);
-
- //execute full discovery
- InventoryManager im = PluginContainer.getInstance().getInventoryManager();
- im.executeServerScanImmediately();
- im.executeServiceScanImmediately();
-
- Set<Resource> resources = getTestingResources();
-
- assertEquals(resources.size(), 1, "There should be only a single testing
resource but " + resources + " were found.");
-
- Resource discoveredResource = resources.iterator().next();
-
- test.test(discoveredResource);
-
- PluginContainer.getInstance().shutdown();
-
- context.assertIsSatisfied();
+
+ try {
+ //give the pc the time to finish resource upgrade
+ Thread.sleep(1000);
+
+ //execute full discovery
+ InventoryManager im = PluginContainer.getInstance().getInventoryManager();
+ im.executeServerScanImmediately();
+ im.executeServiceScanImmediately();
+
+ Set<Resource> resources = getTestingResources();
+
+ assertEquals(resources.size(), 1, "There should be only a single testing
resource but " + resources
+ + " were found.");
+
+ Resource discoveredResource = resources.iterator().next();
+
+ test.test(discoveredResource);
+
+ context.assertIsSatisfied();
+ } finally {
+ PluginContainer.getInstance().shutdown();
+ }
}
@SuppressWarnings("unchecked")
@@ -356,4 +432,8 @@ public class ResourceUpgradeTest {
expectations.allowing(currentDiscoveryServerService).getResources(expectations.with(Expectations.any(Set.class)),
expectations.with(Expectations.any(boolean.class)));
expectations.will(currentServerSideInventory.getResources());
}
+
+ private void cleanDataDir() throws IOException {
+ FileUtils.cleanDirectory(new File(tmpDir, DATA_DIR_NAME));
+ }
}
commit 178d4de9fb18d7f9045e673e64c33a359436be81
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Jul 6 19:12:26 2010 -0400
generate the two resource upgrade test plugins rather than have the .jar files
committed directly to git
this way we can see the source and change it if we ever need to.
also allows us to have source to step through in a debugger
diff --git a/modules/core/plugin-container/pom.xml
b/modules/core/plugin-container/pom.xml
index 2e58102..93f64cf 100644
--- a/modules/core/plugin-container/pom.xml
+++ b/modules/core/plugin-container/pom.xml
@@ -126,6 +126,7 @@
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
+ <id>process-test-resources</id>
<phase>process-test-resources</phase>
<configuration>
<tasks>
@@ -151,7 +152,31 @@
<include name="**/lib/*" />
</fileset>
</move>
- <delete
dir="${project.build.directory}/jboss-sigar/hyperic-sigar-${sigar.version}"
/>
+ <delete
dir="${project.build.directory}/jboss-sigar/hyperic-sigar-${sigar.version}"
/>
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>process-test-classes</id>
+ <phase>process-test-classes</phase>
+ <configuration>
+ <tasks>
+ <echo>Assembling the two resource upgrade test
plugins</echo>
+ <copy
toDir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v1/META-INF">
+ <fileset
file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/v1/rhq-plugin.xml"
/>
+ </copy>
+ <jar
destfile="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-1.0.0.jar">
+ <fileset
dir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v1"
includes="*.class,**/rhq-plugin.xml" />
+ </jar>
+ <copy
toDir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v2/META-INF">
+ <fileset
file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/v2/rhq-plugin.xml"
/>
+ </copy>
+ <jar
destfile="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar">
+ <fileset
dir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v2"
includes="*.class,**/rhq-plugin.xml" />
+ </jar>
</tasks>
</configuration>
<goals>
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/DiscComponent.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/DiscComponent.java
new file mode 100644
index 0000000..5fbca32
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/DiscComponent.java
@@ -0,0 +1,22 @@
+package org.rhq.core.pc.upgrade.plugins.v1;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+
+public class DiscComponent implements ResourceDiscoveryComponent<ResourceComponent>
{
+ private static final String RESOURCE_KEY = "resource-key-v1";
+ private static final String RESOURCE_NAME = "resource-name-v1";
+ private static final String RESOURCE_DESCRIPTION =
"resource-description-v1";
+
+ public Set<DiscoveredResourceDetails>
discoverResources(ResourceDiscoveryContext<ResourceComponent> context)
+ throws InvalidPluginConfigurationException, Exception {
+ return Collections.singleton(new
DiscoveredResourceDetails(context.getResourceType(), RESOURCE_KEY,
+ RESOURCE_NAME, null, RESOURCE_DESCRIPTION,
context.getDefaultPluginConfiguration(), null));
+ }
+}
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/ResComponent.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/ResComponent.java
new file mode 100644
index 0000000..cc21fc3
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/ResComponent.java
@@ -0,0 +1,21 @@
+package org.rhq.core.pc.upgrade.plugins.v1;
+
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
+
+public class ResComponent implements ResourceComponent<ResourceComponent> {
+ public AvailabilityType getAvailability() {
+ return AvailabilityType.UP;
+ }
+
+ public void start(ResourceContext<ResourceComponent> context) {
+ LogFactory.getLog(this.getClass()).info(
+ "~~~ Starting resource upgrade test plugin v1 component: key=" +
context.getResourceKey());
+ }
+
+ public void stop() {
+ }
+}
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/rhq-plugin.xml
new file mode 100644
index 0000000..c658e0c
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/rhq-plugin.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeTest"
+ displayName="Resource Upgrade Test"
+ description="Resource Upgrade Test"
+ package="org.rhq.core.pc.upgrade.plugins.v1"
+ version="1.0.0"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <server name="Resource"
+ discovery="DiscComponent"
+ class="ResComponent"
+ singleton="true" />
+
+</plugin>
+
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/DiscComponent.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/DiscComponent.java
new file mode 100644
index 0000000..d113d1c
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/DiscComponent.java
@@ -0,0 +1,54 @@
+package org.rhq.core.pc.upgrade.plugins.v2;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Set;
+
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
+import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
+
+public class DiscComponent implements
ResourceDiscoveryComponent<ResourceComponent>,
+ ResourceUpgradeFacet<ResourceComponent> {
+ private static final String V1_RESOURCE_KEY = "resource-key-v1";
+ private static final String RESOURCE_KEY = "resource-key-v2";
+ private static final String RESOURCE_NAME = "resource-name-v2";
+ private static final String RESOURCE_DESCRIPTION =
"resource-description-v2";
+
+ public Set<DiscoveredResourceDetails>
discoverResources(ResourceDiscoveryContext<ResourceComponent> context)
+ throws InvalidPluginConfigurationException, Exception {
+ return Collections.singleton(new
DiscoveredResourceDetails(context.getResourceType(), RESOURCE_KEY,
+ RESOURCE_NAME, null, RESOURCE_DESCRIPTION,
context.getDefaultPluginConfiguration(), null));
+ }
+
+ public ResourceUpgradeReport upgrade(ResourceUpgradeContext<ResourceComponent>
inventoriedResource) {
+ if (V1_RESOURCE_KEY.equals(inventoriedResource.getResourceKey())) {
+ ResourceUpgradeReport report = new ResourceUpgradeReport();
+ report.setNewResourceKey(RESOURCE_KEY);
+ report.setNewName(RESOURCE_NAME);
+ report.setNewDescription(RESOURCE_DESCRIPTION);
+
+ File dataDir = inventoriedResource.getDataDirectory();
+
+ if (dataDir != null) {
+ if (!(dataDir.exists())) {
+ dataDir.mkdir();
+ }
+ File marker = new File(dataDir, "upgrade-succeeded");
+ try {
+ marker.createNewFile();
+ } catch (IOException localIOException) {
+ }
+ }
+ return report;
+ }
+
+ return null;
+ }
+}
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/ResComponent.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/ResComponent.java
new file mode 100644
index 0000000..83144b2
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/ResComponent.java
@@ -0,0 +1,21 @@
+package org.rhq.core.pc.upgrade.plugins.v2;
+
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
+
+public class ResComponent implements ResourceComponent<ResourceComponent> {
+ public AvailabilityType getAvailability() {
+ return AvailabilityType.UP;
+ }
+
+ public void start(ResourceContext<ResourceComponent> context) {
+ LogFactory.getLog(this.getClass()).info(
+ "~~~ Starting resource upgrade test plugin v2 component: key=" +
context.getResourceKey());
+ }
+
+ public void stop() {
+ }
+}
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/rhq-plugin.xml
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/rhq-plugin.xml
new file mode 100644
index 0000000..9f63892
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/rhq-plugin.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeTest"
+ displayName="Resource Upgrade Test"
+ description="Resource Upgrade Test"
+ package="org.rhq.core.pc.upgrade.plugins.v2"
+ version="2.0.0"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <server name="Resource"
+ discovery="DiscComponent"
+ class="ResComponent"
+ singleton="true" />
+
+</plugin>
+
diff --git
a/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-1.0.0.jar
b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-1.0.0.jar
deleted file mode 100644
index 33a79c0..0000000
Binary files
a/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-1.0.0.jar
and /dev/null differ
diff --git
a/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar
b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar
deleted file mode 100644
index 7ffc5bb..0000000
Binary files
a/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar
and /dev/null differ
commit 9edde408d4dbabbc057e5e11fdfb6c3c16d2936e
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Jul 6 16:11:44 2010 -0400
trivial - reformat some things. no need to use isDebugEnabled if you are logging a
simple string message with no string concatentation
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 5786702..a5c3d1f 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
@@ -72,8 +72,8 @@ import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceCreationDataType;
import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.domain.resource.ResourceErrorType;
-import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.domain.resource.ResourceType;
+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;
@@ -193,7 +193,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
* Handles the resource upgrade during the initialization of the inventory manager.
*/
private ResourceUpgradeDelegate resourceUpgradeDelegate;
-
+
public InventoryManager() {
super(DiscoveryAgentService.class);
}
@@ -224,7 +224,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
//discoveries.
resourceUpgradeDelegate = new ResourceUpgradeDelegate(this);
upgradeResources();
-
+
availabilityCollectors = new AvailabilityCollectorThreadPool();
availabilityCollectors.initialize();
@@ -300,7 +300,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
return results;
} catch (TimeoutException te) {
log.warn("Discovery for Resources of [" + context.getResourceType()
+ "] has been running for more than "
- + timeout + " milliseconds. This may be a plugin bug.",
te);
+ + timeout + " milliseconds. This may be a plugin bug.", te);
return null;
} catch (BlacklistedException be) {
// Discovery did not run, because the ResourceType was blacklisted during a
prior discovery scan.
@@ -333,8 +333,8 @@ public class InventoryManager extends AgentService implements
ContainerService,
return result;
} catch (TimeoutException te) {
log.warn("Manual add of Resource of type [" +
context.getResourceType() + "] with plugin configuration ["
- + pluginConfig.toString(true) + "] has been running for more
than "
- + timeout + " milliseconds. This may be a plugin bug.",
te);
+ + pluginConfig.toString(true) + "] has been running for more than
" + timeout
+ + " milliseconds. This may be a plugin bug.", te);
return null;
} catch (BlacklistedException be) {
log.debug(ThrowableUtil.getAllMessages(be));
@@ -382,11 +382,12 @@ public class InventoryManager extends AgentService implements
ContainerService,
public <T extends ResourceComponent> ResourceUpgradeReport
invokeDiscoveryComponentResourceUpgradeFacet(
ResourceType resourceType, ResourceDiscoveryComponent<T> component,
ResourceUpgradeContext<T> inventoriedResource) throws Throwable {
-
+
long timeout = getDiscoveryComponentTimeout(resourceType);
try {
@SuppressWarnings("unchecked")
- ResourceUpgradeFacet<T> proxy =
this.discoveryComponentProxyFactory.getDiscoveryComponentProxy(resourceType, component,
timeout, ResourceUpgradeFacet.class);
+ ResourceUpgradeFacet<T> proxy =
this.discoveryComponentProxyFactory.getDiscoveryComponentProxy(
+ resourceType, component, timeout, ResourceUpgradeFacet.class);
return proxy.upgrade(inventoriedResource);
} catch (BlacklistedException e) {
@@ -394,7 +395,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
return null;
}
}
-
+
public DiscoveryComponentProxyFactory getDiscoveryComponentProxyFactory() {
return this.discoveryComponentProxyFactory;
}
@@ -892,7 +893,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
public boolean handleReport(InventoryReport report) {
return handleReport(report, false);
}
-
+
/**
* Send an inventory report to the Server.
*
@@ -904,7 +905,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
if (!configuration.isInsideAgent()) {
return true;
}
-
+
if (report.getAddedRoots().isEmpty() && !forceServerRoundtrip) {
return true; // nothing to do
}
@@ -981,7 +982,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
log.debug(String.format("DONE syncing local inventory [%d]
ms.",
(System.currentTimeMillis() - startTime)));
}
-
+
// If we synced any Resources, one or more Resource components were probably
started,
// so run an avail check to report on their availabilities immediately. Also
kick off
// a service scan to scan those Resources for new child Resources. Kick both
tasks off
@@ -991,7 +992,8 @@ public class InventoryManager extends AgentService implements
ContainerService,
// inventory with the server side as well as to disallow any other
server-agent traffic during
// the upgrade phase. Not to mention the fact that no thread pools are
initialized yet by the
// time the upgrade kicks in..
- if (!resourceUpgradeDelegate.enabled() && (!syncedResources.isEmpty()
|| !unknownResourceIds.isEmpty() || !modifiedResourceIds.isEmpty())) {
+ if (!resourceUpgradeDelegate.enabled()
+ && (!syncedResources.isEmpty() || !unknownResourceIds.isEmpty()
|| !modifiedResourceIds.isEmpty())) {
performAvailabilityChecks(true);
this.inventoryThreadPoolExecutor.schedule((Callable<? extends
Object>) this.serviceScanExecutor, 5,
TimeUnit.SECONDS);
@@ -1003,7 +1005,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
throw new RuntimeException(t);
}
}
-
+
private void getAllUuids(ResourceSyncInfo syncInfo, Set<String>
allServerSideUuids) {
allServerSideUuids.add(syncInfo.getUuid());
for (ResourceSyncInfo child : syncInfo.getChildSyncInfos()) {
@@ -1181,13 +1183,13 @@ public class InventoryManager extends AgentService implements
ContainerService,
ServerServices serverServices = this.configuration.getServerServices();
if (serverServices != null) {
DiscoveryServerService discoveryServerService =
serverServices.getDiscoveryServerService();
-
+
serverUpdates = discoveryServerService.upgradeResources(upgradeReports);
}
} catch (Exception e) {
log.error("Failed to process resource upgrades on the server.",
e);
}
-
+
if (serverUpdates != null) {
for (ResourceUpgradeResponse upgradeResponse : serverUpdates) {
String resourceKey = upgradeResponse.getUpgradedResourceKey();
@@ -1202,49 +1204,50 @@ public class InventoryManager extends AgentService implements
ContainerService,
ResourceContainer existingResourceContainer =
getResourceContainer(upgradeResponse.getResourceId());
if (existingResourceContainer != null) {
Resource existingResource =
existingResourceContainer.getResource();
-
- StringBuilder logMessage = new StringBuilder("Resource
[")
- .append(existingResource.toString()).append("] upgraded
its ");
-
+
+ StringBuilder logMessage = new StringBuilder("Resource
[").append(existingResource.toString())
+ .append("] upgraded its ");
+
if (resourceKey != null) {
existingResource.setResourceKey(resourceKey);
logMessage.append("resourceKey, ");
}
-
+
if (name != null) {
existingResource.setName(name);
logMessage.append("name, ");
}
-
-// if (version != null) {
-// existingResource.setVersion(version);
-// }
-
+
+ //if (version != null) {
+ // existingResource.setVersion(version);
+ //}
+
if (description != null) {
existingResource.setDescription(description);
logMessage.append("description, ");
}
-
-// if (pluginConfiguration != null) {
-//
existingResource.setPluginConfiguration(pluginConfiguration);
-// }
-//
-// if (resourceConfiguration != null) {
-//
existingResource.setResourceConfiguration(resourceConfiguration);
-// }
-
- logMessage.replace(logMessage.length() - 1, logMessage.length(),
- "to become
[").append(existingResource.toString()).append("]");
-
+
+ //if (pluginConfiguration != null) {
+ //
existingResource.setPluginConfiguration(pluginConfiguration);
+ //}
+ //
+ //if (resourceConfiguration != null) {
+ //
existingResource.setResourceConfiguration(resourceConfiguration);
+ //}
+
+ logMessage.replace(logMessage.length() - 1, logMessage.length(),
"to become [").append(
+ existingResource.toString()).append("]");
+
log.info(logMessage.toString());
} else {
- log.error("Upgraded a resource that is not present on the
agent. This should not happen. The id of the missing resource is " +
upgradeResponse.getResourceId());
+ log.error("Upgraded a resource that is not present on the
agent. This should not happen. "
+ + "The id of the missing resource is: " +
upgradeResponse.getResourceId());
}
}
}
}
}
-
+
public Resource mergeResourceFromDiscovery(Resource resource, Resource parent) throws
PluginContainerException {
// If the Resource is already in inventory, make sure its version is up-to-date,
then simply return the
// existing Resource.
@@ -1466,7 +1469,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
}
ResourceContext context = createResourceContext(resource, parentComponent,
discoveryComponent);
-
+
container.setResourceContext(context);
// Wrap the component in a proxy that will provide locking and a timeout for
the call to start().
@@ -1513,7 +1516,8 @@ public class InventoryManager extends AgentService implements
ContainerService,
}
}
- private <T extends ResourceComponent> ResourceContext<T>
createResourceContext(Resource resource, T parentComponent,
ResourceDiscoveryComponent<T> discoveryComponent) {
+ private <T extends ResourceComponent> ResourceContext<T>
createResourceContext(Resource resource,
+ T parentComponent, ResourceDiscoveryComponent<T> discoveryComponent) {
File pluginDataDir = new File(this.configuration.getDataDirectory(),
resource.getResourceType().getPlugin());
return new ResourceContext<T>(resource, // the resource itself
@@ -1529,8 +1533,9 @@ public class InventoryManager extends AgentService implements
ContainerService,
this.availabilityCollectors, // for components that want to perform async
avail checking
this.configuration.getPluginContainerDeployment()); // helps components make
determinations of what to do
}
-
- public <T extends ResourceComponent> ResourceUpgradeContext<T>
createResourceUpgradeContext(Resource resource, T parentComponent,
ResourceDiscoveryComponent<T> discoveryComponent) {
+
+ public <T extends ResourceComponent> ResourceUpgradeContext<T>
createResourceUpgradeContext(Resource resource,
+ T parentComponent, ResourceDiscoveryComponent<T> discoveryComponent) {
File pluginDataDir = new File(this.configuration.getDataDirectory(),
resource.getResourceType().getPlugin());
return new ResourceUpgradeContext<T>(resource, // the resource itself
@@ -1546,7 +1551,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
this.availabilityCollectors, // for components that want to perform async
avail checking
this.configuration.getPluginContainerDeployment()); // helps components make
determinations of what to do
}
-
+
/**
* This will send a resource error to the server (if applicable) to indicate that the
given resource could not be
* connected to due to an invalid plugin configuration.
@@ -1789,13 +1794,13 @@ public class InventoryManager extends AgentService implements
ContainerService,
Set<DiscoveredResourceDetails> allDiscoveredPlatforms = new
HashSet<DiscoveredResourceDetails>(2);
if ((platformTypes != null) && (platformTypes.size() > 0)) {
-
+
//check for fake testing type. If the test platform type is being used, it is
always going to be
//the sole platform type available.
if (platformTypes.size() == 1 &&
platformTypes.contains(PluginMetadataManager.TEST_PLATFORM_TYPE)) {
return getTestPlatform();
}
-
+
// Go through all the platform types that are supported and see if they can
detect our platform.
for (ResourceType platformType : platformTypes) {
try {
@@ -2123,11 +2128,11 @@ public class InventoryManager extends AgentService implements
ContainerService,
@NotNull
Set<Resource> executeComponentDiscovery(ResourceType resourceType,
ResourceDiscoveryComponent discoveryComponent,
ResourceContainer parentContainer, List<ProcessScanResult>
processScanResults) {
-
+
ResourceContext parentResourceContext = parentContainer.getResourceContext();
ResourceComponent parentComponent = parentContainer.getResourceComponent();
Resource parentResource = parentContainer.getResource();
-
+
long startTime = System.currentTimeMillis();
log.debug("Executing discovery for [" + resourceType.getName() +
"] Resources...");
Set<Resource> newResources;
@@ -2578,9 +2583,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
private void upgradeResources() {
try {
- if (log.isDebugEnabled()) {
- log.debug("Executing resource upgrade.");
- }
+ log.debug("Executing resource upgrade.");
boolean syncResult = handleReport(new InventoryReport(getAgent()), true);
if (!syncResult) {
@@ -2590,27 +2593,23 @@ public class InventoryManager extends AgentService implements
ContainerService,
upgradeResource(getPlatform());
- if (log.isDebugEnabled()) {
- log.debug("Sending the upgrade requests to the server.");
- }
+ log.debug("Sending the upgrade requests to the server.");
resourceUpgradeDelegate.sendRequests();
resourceUpgradeDelegate.disable();
- if (log.isDebugEnabled()) {
- log.debug("Resource upgrade finished.");
- }
+ log.debug("Resource upgrade finished.");
} catch (Throwable t) {
log.error("Resource upgrade failed with an exception.", t);
}
}
-
+
private void upgradeResource(Resource resource) {
//only process committed resources
if (resource.getInventoryStatus() != InventoryStatus.COMMITTED) {
return;
}
-
+
ResourceContainer container = getResourceContainer(resource);
if (container != null) {
try {
@@ -2625,14 +2624,15 @@ public class InventoryManager extends AgentService implements
ContainerService,
upgradeResource(child);
}
} else {
- log.error("The resource container for resource [" + resource +
"] wasn't started during upgrade. This should not happen.");
- }
+ log.error("The resource container for resource [" + resource
+ + "] wasn't started during upgrade. This should not
happen.");
+ }
} else {
log.error("Resource container not initialized for resource [" +
resource
+ "] during upgrade. This should not happen.");
}
}
-
+
/**
* That class implements a listener that gets called when the resource got activated
* @author hrupp
commit 1e41a098af78a7d97e0a0415dba48bf0b98dba73
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Jul 6 16:03:35 2010 -0400
trivial - add comment, small reformat
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
index cb466bd..5b33fe1 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
@@ -24,6 +24,7 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+
import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
import org.rhq.core.domain.resource.Resource;
@@ -40,6 +41,11 @@ import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
* This is a helper class to {@link InventoryManager} that takes care of resource
upgrade.
* Note that this class is not thread-safe in any manner.
*
+ * This class must not call (explicitly or implicitly anywhere in its outgoing call
chain)
+ * any other plugin container manager other than the InventoryManager. This is because
+ * this delegate is called within the Inventory Manager's initialize method and
hence
+ * many other managers are not yet initialized themselves yet.
+ *
* @author Lukas Krejci
*/
public class ResourceUpgradeDelegate {
@@ -62,7 +68,7 @@ public class ResourceUpgradeDelegate {
public boolean enabled() {
return enabled;
}
-
+
/**
* Disables all future operations of the delegate.
*/
@@ -93,10 +99,10 @@ public class ResourceUpgradeDelegate {
}
}
+ @SuppressWarnings("unchecked")
private <T extends ResourceComponent> boolean
executeResourceUpgradeFacetAndStoreRequest(
ResourceContainer resourceContainer) throws PluginContainerException {
- @SuppressWarnings("unchecked")
ResourceComponent<T> parentResourceComponent =
resourceContainer.getResourceContext()
.getParentResourceComponent();
@@ -107,7 +113,6 @@ public class ResourceUpgradeDelegate {
Resource resource = resourceContainer.getResource();
- @SuppressWarnings("unchecked")
ResourceDiscoveryComponent<ResourceComponent<T>> discoveryComponent =
PluginContainer.getInstance()
.getPluginComponentFactory().getDiscoveryComponent(resource.getResourceType(),
parentResourceContainer);
@@ -146,13 +151,13 @@ public class ResourceUpgradeDelegate {
}
private String checkUpgradeValid(Resource resource, ResourceUpgradeReport
upgradeReport) {
- StringBuilder bld = new StringBuilder();
+ StringBuilder s = new StringBuilder();
if (!checkResourceKeyUniqueAmongSiblings(resource, upgradeReport)) {
- bld.append("\nAnother inventoried sibling resource of the same type
already has the proposed resource key.");
+ s.append("\nAnother inventoried sibling resource of the same type
already has the proposed resource key.");
}
- return bld.length() > 0 ? bld.toString() : null;
+ return s.length() > 0 ? s.toString() : null;
}
private boolean checkResourceKeyUniqueAmongSiblings(Resource resource,
ResourceUpgradeReport upgradeReport) {
commit fb7c05447b2b4d0f3ebf30481942f12d176f759e
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Jul 6 16:02:39 2010 -0400
trivial - remove tabs
diff --git
a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
index d122da4..915a9e7 100644
---
a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
+++
b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
@@ -35,12 +35,11 @@ import org.rhq.core.pluginapi.inventory.ResourceComponent;
* @author Lukas Krejci
*/
public interface ResourceUpgradeFacet<T extends ResourceComponent> {
-
- /**
- * Specifies what data should change on the provided resource to upgrade it to the
current version.
- *
- * @param inventoriedResource a context representing the resource to be upgraded
- * @return a report specifying what aspects of the resource should be changed or null if
there is nothing to upgrade
- */
- ResourceUpgradeReport upgrade(ResourceUpgradeContext<T> inventoriedResource);
+ /**
+ * Specifies what data should change on the provided resource to upgrade it to the
current version.
+ *
+ * @param inventoriedResource a context representing the resource to be upgraded
+ * @return a report specifying what aspects of the resource should be changed or null
if there is nothing to upgrade
+ */
+ ResourceUpgradeReport upgrade(ResourceUpgradeContext<T> inventoriedResource);
}
commit 18316510cafe27425cd1ac3cc1d08afe398d77ab
Merge: 14db66f... fac71cd...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Jul 2 17:54:08 2010 +0200
Merge branch 'release-3.0.0' into resource-upgrade
commit 14db66fe1f2774bcead24daebee947e6b52851dd
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Jul 2 17:52:12 2010 +0200
Refactoring the resource upgrade to upgrade before the discovery during
InventoryManager.initialize(). That enables us to remove all the synchronization on the
resources.
diff --git
a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
index 825a616..f055e8c 100644
---
a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
+++
b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
@@ -32,6 +32,8 @@ import org.rhq.core.domain.resource.ResourceUpgradeReport;
*/
public class ResourceUpgradeRequest extends ResourceUpgradeReport {
+ private static final long serialVersionUID = 1L;
+
private int resourceId;
public ResourceUpgradeRequest() {
@@ -52,4 +54,24 @@ public class ResourceUpgradeRequest extends ResourceUpgradeReport {
public void setResourceId(int resourceId) {
this.resourceId = resourceId;
}
+
+ @Override
+ public int hashCode() {
+ return 31 * resourceId;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ if (!(other instanceof ResourceUpgradeRequest)) {
+ return false;
+ }
+
+ ResourceUpgradeRequest r = (ResourceUpgradeRequest) other;
+
+ return r.getResourceId() == resourceId;
+ }
}
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
index 0f9db04..c2bc392 100644
---
a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
@@ -108,4 +108,14 @@ public class ResourceUpgradeReport implements Serializable {
public void setNewDescription(String newDescription) {
this.newDescription = newDescription;
}
+
+ public boolean hasSomethingToUpgrade() {
+ return newResourceKey != null ||
+ newName != null ||
+ newDescription != null;
+ }
+
+ public String toString() {
+ return "ResourceUpgradeReport[newResourceKey = '" + newResourceKey +
"', newName = '" + newName + "', newDescription = '" +
newDescription + "']";
+ }
}
diff --git
a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
index 914641c..d122da4 100644
---
a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
+++
b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
@@ -23,9 +23,6 @@
package org.rhq.core.pluginapi.upgrade;
-import java.util.Map;
-import java.util.Set;
-
import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.pluginapi.inventory.ResourceComponent;
@@ -39,19 +36,11 @@ import org.rhq.core.pluginapi.inventory.ResourceComponent;
*/
public interface ResourceUpgradeFacet<T extends ResourceComponent> {
- /**
- * This method is called on the discovery component straight after it has finished
the discovery.
- * The exact same discovery results are passed to this method along with the set of
resources
- * that already exist in the inventory.
- *
- * @param inventoriedSiblings the existing resources
- * @param parentContext the parent of both the newly discovered and existing
resources
- * @param discoveryResults the discovered resources. The resources from this set that
have
- * the same resource key as one of the inventoried siblings (after upgrade using the
results of this method) won't
- * be reported.
- * @return the mapping of old resources to the newly desired data. The keys are
instances from the
- * inventoriedSiblings set, the values are the upgrade reports detailing what the
data of the
- * corresponding siblings should be upgraded to.
- */
- Map<ResourceUpgradeContext<T>, ResourceUpgradeReport>
upgrade(Set<ResourceUpgradeContext<T>> inventoriedSiblings,
ResourceUpgradeContext<? extends ResourceComponent> parentContext,
Set<ResourceUpgradeContext<T>> discoveryResults);
+ /**
+ * Specifies what data should change on the provided resource to upgrade it to the
current version.
+ *
+ * @param inventoriedResource a context representing the resource to be upgraded
+ * @return a report specifying what aspects of the resource should be changed or null if
there is nothing to upgrade
+ */
+ ResourceUpgradeReport upgrade(ResourceUpgradeContext<T> inventoriedResource);
}
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 4d61e93..7561bf7 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
@@ -261,10 +261,6 @@ public class PluginContainer implements ContainerService {
} finally {
releaseLock(lock);
}
-
- //fire off the resource upgrade as soon as possible. It will run only once per
plugin container
- //lifetime.
- inventoryManager.fireResourceUpgrade();
return;
}
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 ee42f7d..5786702 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
@@ -33,11 +33,9 @@ import java.util.IdentityHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
-import java.util.Queue;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
-import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@@ -93,8 +91,7 @@ import org.rhq.core.pc.plugin.BlacklistedException;
import org.rhq.core.pc.plugin.CanonicalResourceKey;
import org.rhq.core.pc.plugin.PluginComponentFactory;
import org.rhq.core.pc.plugin.PluginManager;
-import org.rhq.core.pc.upgrade.ResourceUpgradeExecutor;
-import org.rhq.core.pc.upgrade.ResourceUpgradePendingRequest;
+import org.rhq.core.pc.upgrade.ResourceUpgradeDelegate;
import org.rhq.core.pc.util.DiscoveryComponentProxyFactory;
import org.rhq.core.pc.util.FacetLockType;
import org.rhq.core.pc.util.LoggingThreadFactory;
@@ -195,7 +192,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
/**
* Handles the resource upgrade during the initialization of the inventory manager.
*/
- private ResourceUpgradeExecutor resourceUpgradeExecutor;
+ private ResourceUpgradeDelegate resourceUpgradeDelegate;
public InventoryManager() {
super(DiscoveryAgentService.class);
@@ -219,12 +216,18 @@ public class InventoryManager extends AgentService implements
ContainerService,
loadFromDisk();
}
- availabilityCollectors = new AvailabilityCollectorThreadPool();
- availabilityCollectors.initialize();
-
// Discover the platform first thing.
executePlatformScan();
+ //try the resource upgrade before we have any schedulers set up
+ //so that we don't get any interventions from concurrently running
+ //discoveries.
+ resourceUpgradeDelegate = new ResourceUpgradeDelegate(this);
+ upgradeResources();
+
+ availabilityCollectors = new AvailabilityCollectorThreadPool();
+ availabilityCollectors.initialize();
+
// Never run more than one avail check at a time.
availabilityThreadPoolExecutor = new
ScheduledThreadPoolExecutor(AVAIL_THREAD_POOL_CORE_POOL_SIZE,
new LoggingThreadFactory(AVAIL_THREAD_POOL_NAME, true));
@@ -251,8 +254,6 @@ public class InventoryManager extends AgentService implements
ContainerService,
inventoryThreadPoolExecutor.scheduleWithFixedDelay(serviceScanExecutor,
configuration
.getServiceDiscoveryInitialDelay(),
configuration.getServiceDiscoveryPeriod(), TimeUnit.SECONDS);
}
-
- resourceUpgradeExecutor = new ResourceUpgradeExecutor(this);
} finally {
inventoryLock.writeLock().unlock();
}
@@ -378,20 +379,19 @@ public class InventoryManager extends AgentService implements
ContainerService,
return results;
}
- public <T extends ResourceComponent> Map<ResourceUpgradeContext<T>,
ResourceUpgradeReport> invokeDiscoveryComponentResourceUpgradeFacet(
+ public <T extends ResourceComponent> ResourceUpgradeReport
invokeDiscoveryComponentResourceUpgradeFacet(
ResourceType resourceType, ResourceDiscoveryComponent<T> component,
- Set<ResourceUpgradeContext<T>> inventoriedSiblings,
ResourceUpgradeContext<?> parent,
- Set<ResourceUpgradeContext<T>> discoveredResources) throws Throwable
{
+ ResourceUpgradeContext<T> inventoriedResource) throws Throwable {
long timeout = getDiscoveryComponentTimeout(resourceType);
try {
@SuppressWarnings("unchecked")
ResourceUpgradeFacet<T> proxy =
this.discoveryComponentProxyFactory.getDiscoveryComponentProxy(resourceType, component,
timeout, ResourceUpgradeFacet.class);
- return proxy.upgrade(inventoriedSiblings, parent, discoveredResources);
+ return proxy.upgrade(inventoriedResource);
} catch (BlacklistedException e) {
log.debug(e);
- return Collections.emptyMap();
+ return null;
}
}
@@ -518,15 +518,6 @@ public class InventoryManager extends AgentService implements
ContainerService,
}
}
- /**
- * Executes the resource upgrade asynchronously.
- */
- public void fireResourceUpgrade() {
- Thread resourceUpgradeThread = new Thread(resourceUpgradeExecutor, "Resource
Upgrade Thread");
- resourceUpgradeThread.setDaemon(true);
- resourceUpgradeThread.start();
- }
-
public InventoryReport executeServerScanImmediately() {
try {
return inventoryThreadPoolExecutor.submit((Callable<InventoryReport>)
this.serverScanExecutor).get();
@@ -914,16 +905,6 @@ public class InventoryManager extends AgentService implements
ContainerService,
return true;
}
- //finish the resource upgrade.
- //by now all the resource upgrade requests have been processed
- //by the executor, which means that the inventory report
- //we got already only contains the "correct" new resources and
- //that the executor has all the upgrade requests queued up
- //to be sent to the server in a batch.
- if (resourceUpgradeExecutor.isEnabled()) {
- resourceUpgradeExecutor.sendRequests();
- }
-
if (report.getAddedRoots().isEmpty() && !forceServerRoundtrip) {
return true; // nothing to do
}
@@ -1005,7 +986,12 @@ public class InventoryManager extends AgentService implements
ContainerService,
// so run an avail check to report on their availabilities immediately. Also
kick off
// a service scan to scan those Resources for new child Resources. Kick both
tasks off
// asynchronously.
- if (!syncedResources.isEmpty() || !unknownResourceIds.isEmpty() ||
!modifiedResourceIds.isEmpty()) {
+ // Do this only if we are finished with resource upgrade because no
availability checks
+ // or discoveries can happen during upgrade. This is to ensure maximum
consistency of the
+ // inventory with the server side as well as to disallow any other
server-agent traffic during
+ // the upgrade phase. Not to mention the fact that no thread pools are
initialized yet by the
+ // time the upgrade kicks in..
+ if (!resourceUpgradeDelegate.enabled() && (!syncedResources.isEmpty()
|| !unknownResourceIds.isEmpty() || !modifiedResourceIds.isEmpty())) {
performAvailabilityChecks(true);
this.inventoryThreadPoolExecutor.schedule((Callable<? extends
Object>) this.serviceScanExecutor, 5,
TimeUnit.SECONDS);
@@ -2180,10 +2166,6 @@ public class InventoryManager extends AgentService implements
ContainerService,
newResources.add(newResource);
}
}
-
- if (resourceUpgradeExecutor.isEnabled()) {
- resourceUpgradeExecutor.processAndQueue(new
ResourceUpgradePendingRequest(newResources, context, parentResource.getId()),
newResources);
- }
} catch (Throwable e) {
// TODO GH: Add server/parent - up/down semantics so this won't happen
just because a server is not up
long elapsedTime = System.currentTimeMillis() - startTime;
@@ -2594,6 +2576,63 @@ public class InventoryManager extends AgentService implements
ContainerService,
container.setSynchronizationState(ResourceContainer.SynchronizationState.SYNCHRONIZED);
}
+ private void upgradeResources() {
+ try {
+ if (log.isDebugEnabled()) {
+ log.debug("Executing resource upgrade.");
+ }
+
+ boolean syncResult = handleReport(new InventoryReport(getAgent()), true);
+ if (!syncResult) {
+ log.warn("Resource upgrade failed to sync up the inventory with the
server.");
+ return;
+ }
+
+ upgradeResource(getPlatform());
+
+ if (log.isDebugEnabled()) {
+ log.debug("Sending the upgrade requests to the server.");
+ }
+ resourceUpgradeDelegate.sendRequests();
+
+ resourceUpgradeDelegate.disable();
+
+ if (log.isDebugEnabled()) {
+ log.debug("Resource upgrade finished.");
+ }
+ } catch (Throwable t) {
+ log.error("Resource upgrade failed with an exception.", t);
+ }
+ }
+
+ private void upgradeResource(Resource resource) {
+ //only process committed resources
+ if (resource.getInventoryStatus() != InventoryStatus.COMMITTED) {
+ return;
+ }
+
+ ResourceContainer container = getResourceContainer(resource);
+ if (container != null) {
+ try {
+ container = getResourceContainer(resource);
+ resourceUpgradeDelegate.processAndQueue(container);
+ } catch (PluginContainerException e) {
+ log.error("Exception thrown while upgrading [" + resource +
"].");
+ }
+
+ if (container.getResourceComponentState() == ResourceComponentState.STARTED)
{
+ for (Resource child : resource.getChildResources()) {
+ upgradeResource(child);
+ }
+ } else {
+ log.error("The resource container for resource [" + resource +
"] wasn't started during upgrade. This should not happen.");
+ }
+ } else {
+ log.error("Resource container not initialized for resource [" +
resource
+ + "] during upgrade. This should not happen.");
+ }
+ }
+
/**
* That class implements a listener that gets called when the resource got activated
* @author hrupp
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
new file mode 100644
index 0000000..cb466bd
--- /dev/null
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
@@ -0,0 +1,180 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.upgrade;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.rhq.core.clientapi.agent.PluginContainerException;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
+import org.rhq.core.pc.PluginContainer;
+import org.rhq.core.pc.inventory.InventoryManager;
+import org.rhq.core.pc.inventory.ResourceContainer;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
+
+/**
+ * This is a helper class to {@link InventoryManager} that takes care of resource
upgrade.
+ * Note that this class is not thread-safe in any manner.
+ *
+ * @author Lukas Krejci
+ */
+public class ResourceUpgradeDelegate {
+
+ private static final Log log = LogFactory.getLog(ResourceUpgradeDelegate.class);
+
+ private boolean enabled = true;
+
+ private Set<ResourceUpgradeRequest> requests = new
HashSet<ResourceUpgradeRequest>();
+ private InventoryManager inventoryManager;
+
+ public ResourceUpgradeDelegate(InventoryManager inventoryManager) {
+ this.inventoryManager = inventoryManager;
+ }
+
+ /**
+ * Is the delegate enabled? In another words has the resource upgrade phase finished
in the {@link IventoryManager#initialize()}
+ * method?
+ */
+ public boolean enabled() {
+ return enabled;
+ }
+
+ /**
+ * Disables all future operations of the delegate.
+ */
+ public void disable() {
+ enabled = false;
+ }
+
+ /**
+ * Asks the resource's discovery component to upgrade the resource.
+ * @param resourceContainer
+ * @return true if the resource was queued for upgrade, false otherwise
+ * @throws PluginContainerException on error
+ */
+ public boolean processAndQueue(ResourceContainer resourceContainer) throws
PluginContainerException {
+ if (enabled) {
+ return executeResourceUpgradeFacetAndStoreRequest(resourceContainer);
+ }
+
+ return false;
+ }
+
+ public void sendRequests() {
+ if (enabled) {
+ if (requests.size() > 0) {
+ inventoryManager.mergeResourceFromUpgrade(requests);
+ requests.clear();
+ }
+ }
+ }
+
+ private <T extends ResourceComponent> boolean
executeResourceUpgradeFacetAndStoreRequest(
+ ResourceContainer resourceContainer) throws PluginContainerException {
+
+ @SuppressWarnings("unchecked")
+ ResourceComponent<T> parentResourceComponent =
resourceContainer.getResourceContext()
+ .getParentResourceComponent();
+
+ Resource parentResource = resourceContainer.getResource().getParentResource();
+
+ ResourceContainer parentResourceContainer = (parentResource != null) ?
inventoryManager
+ .getResourceContainer(resourceContainer.getResource().getParentResource()) :
null;
+
+ Resource resource = resourceContainer.getResource();
+
+ @SuppressWarnings("unchecked")
+ ResourceDiscoveryComponent<ResourceComponent<T>> discoveryComponent =
PluginContainer.getInstance()
+
.getPluginComponentFactory().getDiscoveryComponent(resource.getResourceType(),
parentResourceContainer);
+
+ if (!(discoveryComponent instanceof ResourceUpgradeFacet)) {
+ //well, there's no point in continuing if the resource doesn't
support the facet
+ return false;
+ }
+
+ ResourceUpgradeContext<ResourceComponent<T>> upgradeContext =
inventoryManager.createResourceUpgradeContext(
+ resource, parentResourceComponent, discoveryComponent);
+
+ ResourceUpgradeReport upgradeReport;
+ try {
+ upgradeReport =
inventoryManager.invokeDiscoveryComponentResourceUpgradeFacet(resource.getResourceType(),
+ discoveryComponent, upgradeContext);
+ } catch (Throwable t) {
+ log.error("ResourceUpgradeFacet threw an exception while upgrading
resource [" + resource + "]", t);
+ return false;
+ }
+
+ if (upgradeReport == null || !upgradeReport.hasSomethingToUpgrade()) {
+ return false;
+ }
+
+ String upgradeErrors = null;
+ if ((upgradeErrors = checkUpgradeValid(resource, upgradeReport)) != null) {
+ log.error("Upgrading the resource [" + resource + "] using
these updates [" + upgradeReport
+ + "] would render the inventory invalid because of the following
reasons: " + upgradeErrors);
+ return false;
+ }
+
+ //everything went ok, let's queue a upgrade request that will be sent to the
server
+ requests.add(new ResourceUpgradeRequest(resource.getId(), upgradeReport));
+
+ return true;
+ }
+
+ private String checkUpgradeValid(Resource resource, ResourceUpgradeReport
upgradeReport) {
+ StringBuilder bld = new StringBuilder();
+
+ if (!checkResourceKeyUniqueAmongSiblings(resource, upgradeReport)) {
+ bld.append("\nAnother inventoried sibling resource of the same type
already has the proposed resource key.");
+ }
+
+ return bld.length() > 0 ? bld.toString() : null;
+ }
+
+ private boolean checkResourceKeyUniqueAmongSiblings(Resource resource,
ResourceUpgradeReport upgradeReport) {
+ Resource parent = resource.getParentResource();
+ if (parent == null) {
+ return true;
+ }
+
+ for (Resource sibling : parent.getChildResources()) {
+ //we'd have a resource key conflict if there was a resource
+ //of the same type under the same parent that would have the same
+ //resource key.
+ if (upgradeReport.getNewResourceKey() != null
+ && sibling.getResourceType().equals(resource.getResourceType())
+ && !sibling.getUuid().equals(resource.getUuid())) {
+
+ if (sibling.getResourceKey().equals(upgradeReport.getNewResourceKey()))
{
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+}
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
deleted file mode 100644
index f344900..0000000
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2010 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.pc.upgrade;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.rhq.core.clientapi.agent.PluginContainerException;
-import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
-import org.rhq.core.clientapi.server.discovery.InventoryReport;
-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.resource.ResourceUpgradeReport;
-import org.rhq.core.pc.PluginContainer;
-import org.rhq.core.pc.inventory.InventoryManager;
-import org.rhq.core.pc.inventory.ResourceContainer;
-import org.rhq.core.pluginapi.inventory.ResourceComponent;
-import org.rhq.core.pluginapi.inventory.ResourceContext;
-import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
-import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
-import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
-import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
-
-/**
- * This class is responsible for performing the resource upgrade on behalf on of {@link
InventoryManager}.
- * Despite its name, it is not an {@link java.util.concurrent.Executor} implementation.
- *
- * @author Lukas Krejci
- */
-public class ResourceUpgradeExecutor implements Runnable {
- private static final Log log = LogFactory.getLog(ResourceUpgradeExecutor.class);
-
- /**
- * The upgrade runs only once in its lifetime.
- */
- private AtomicBoolean enabled = new AtomicBoolean(true);
- private AtomicBoolean started = new AtomicBoolean(false);
-
- private InventoryManager inventoryManager;
-
- private ConcurrentLinkedQueue<ResourceUpgradeRequest> requests;
-
- public ResourceUpgradeExecutor(InventoryManager inventoryManager) {
- this.inventoryManager = inventoryManager;
- requests = new ConcurrentLinkedQueue<ResourceUpgradeRequest>();
- }
-
- /**
- * This method is called from within the {@link InventoryManager} during the
- * discovery process as individual upgrade requests are generated.
- * <p>
- * This method calls the appropriate discovery component to perform the upgrade and
- * at the same time stores off the results so that they can be sent to the server
- * at the end of the discovery in one big batch.
- * <p>
- * The provided set of discovery results is updated if this method detects that an
existing
- * resource upgrade would result in a resource key collision with some of the newly
discovered
- * resources.
- *
- * @param request the upgrade request
- * @param discoveredResources the set of discovered resources that this method can
optionally remove some elements from.
- */
- public <T extends ResourceComponent> Map<ResourceUpgradeContext<T>,
ResourceUpgradeReport> processAndQueue(
- ResourceUpgradePendingRequest<T> request, Set<Resource>
discoveredResources) {
-
- return enabled.get() ? executeResourceUpgradeAndStoreRequest(request,
discoveredResources) : null;
- }
-
- /**
- * @return true if the executor is ready to perform the upgrade, false otherwise.
- */
- public boolean isEnabled() {
- return enabled.get();
- }
-
- /**
- * This method is called from within the {@link InventoryManager} once it's
collected
- * all the upgrade requests.
- */
- public void sendRequests() {
- if (enabled.get() && requests.size() > 0) {
- HashSet<ResourceUpgradeRequest> currentCopy = new
HashSet<ResourceUpgradeRequest>(requests);
- inventoryManager.mergeResourceFromUpgrade(currentCopy);
- requests.removeAll(currentCopy);
- }
- }
-
- /**
- * Performs the resource upgrade. First, a full inventory report is pulled down from
the
- * server to ensure we have an up-to-date picture of the inventory.
- * After that a full discovery is performed and both the upgrade report and discovery
report
- * are sent to the server.
- */
- public void run() {
- if (!started.getAndSet(true)) {
- if (log.isDebugEnabled()) {
- log.debug("Starting resource upgrade.");
- }
-
- try {
- //pull the inventory down from the server.
- //this will ensure that we have an up-to-date info on the
- //server inventory before we try to upgrade.
- boolean syncResult = inventoryManager.handleReport(new
InventoryReport(inventoryManager.getAgent()), true);
- if (!syncResult) {
- log.warn("Resource upgrade failed to sync up the inventory with
the server.");
- return;
- }
-
- //fire off the full discovery
- inventoryManager.executeServerScanImmediately();
- inventoryManager.executeServiceScanImmediately();
- } catch (Throwable t) {
- log.warn("Resource upgrade failed.", t);
- } finally {
- //make sure to switch off the upgrade...
- this.enabled.set(false);
-
- //clear up so that we don't hold unnecessary instances.
- requests.clear();
-
- if (log.isDebugEnabled()) {
- log.debug("Resource upgrade finished.");
- }
- }
-
- } else {
- if (log.isDebugEnabled()) {
- log.debug("ResourceUpgradeExecutor already ran before. Skipping the
execution.");
- }
- }
- }
-
- /**
- * Executes the resource upgrade request on the agent (if the appropriate discovery
component support {@link ResourceUpgradeFacet}).
- *
- * @param request the upgrade request to execute on the agent.
- * @param discoveredResources the set of the discovered resources that this method
can remove some elements from
- * @return the resulting upgrade map as reported by the plugin from {@link
ResourceUpgradeFacet#upgrade(Set, ResourceUpgradeContext, Set)} method.
- *
- * @throws PluginContainerException
- */
- private <T extends ResourceComponent> Map<ResourceUpgradeContext<T>,
ResourceUpgradeReport> executeResourceUpgradeAndStoreRequest(
- ResourceUpgradePendingRequest<T> request, Set<Resource>
discoveredResources) {
-
- ResourceDiscoveryContext<T> discoveryContext =
request.getDiscoveryContext();
- Set<Resource> newResources = request.getDiscoveredResources();
- Integer parentResourceId = request.getParentResourceId();
-
- try {
- ResourceType resourceType = discoveryContext.getResourceType();
- ResourceContainer parentResourceContainer = null;
- Resource parentResource = null;
- if (parentResourceId != null) {
- parentResourceContainer =
inventoryManager.getResourceContainer(parentResourceId);
- if (parentResourceContainer != null) {
- parentResource = parentResourceContainer.getResource();
- }
- }
-
- @SuppressWarnings("unchecked")
- ResourceDiscoveryComponent<T> discoveryComponent =
PluginContainer.getInstance()
- .getPluginComponentFactory().getDiscoveryComponent(resourceType,
parentResourceContainer);
-
- ResourceContext<?> parentResourceContext =
discoveryContext.getParentResourceContext();
-
- T parentComponent = discoveryContext.getParentResourceComponent();
-
- //check if the discovery component supports resource upgrade
- //if it does, perform the resource upgrade straight away here during the
discovery process.
- if (discoveryComponent instanceof ResourceUpgradeFacet) {
- //the siblings are the resources of the type that is currently being
discovered that are already
- //present in the inventory. These are the candidate resources for the
upgrade.
- Set<Resource> siblings = parentResource == null ?
Collections.singleton(inventoryManager.getPlatform())
- : inventoryManager.getResourcesWithType(resourceType,
parentResource.getChildResources());
-
- //filter out not committed resources
- //XXX what about uninventoried or ignored ones? is it correct to not
upgrade those?
- Iterator<Resource> siblingsIterator = siblings.iterator();
- while (siblingsIterator.hasNext()) {
- if (siblingsIterator.next().getInventoryStatus() !=
InventoryStatus.COMMITTED) {
- siblingsIterator.remove();
- }
- }
-
- //get the upgrade context of the parent resource so that it can be passed
to the upgrade method
- //of the discovery component.
- ResourceUpgradeContext<?> parentUpgradeContext = null;
-
- if (parentResource != null) {
- Resource grandParent = parentResource.getParentResource();
- ResourceContainer grandParentContainer = grandParent == null ? null :
inventoryManager
- .getResourceContainer(grandParent);
-
- @SuppressWarnings("unchecked")
- ResourceDiscoveryComponent<ResourceComponent>
parentDiscoveryComponent = PluginContainer
-
.getInstance().getPluginComponentFactory().getDiscoveryComponent(
- parentResource.getResourceType(), grandParentContainer);
-
- ResourceComponent<?> grandParentResourceComponent =
grandParentContainer == null ? null
- : grandParentContainer.getResourceComponent();
-
- parentUpgradeContext =
inventoryManager.createResourceUpgradeContext(parentResource,
- grandParentResourceComponent, parentDiscoveryComponent);
- }
-
- //convert the sibling resources into upgrade context objects so that the
plugin methods don't access the
- //domain objects directly.
- Set<ResourceUpgradeContext<T>> siblingContexts = new
HashSet<ResourceUpgradeContext<T>>(siblings.size());
-
- //but we are going to need to update the resources in the end, so map the
contexts with the resources.
- Map<ResourceUpgradeContext<T>, Resource>
siblingContextToResource = new HashMap<ResourceUpgradeContext<T>,
Resource>();
-
- for (Resource sibling : siblings) {
- ResourceUpgradeContext<T> siblingContext =
inventoryManager.createResourceUpgradeContext(sibling,
- parentComponent, discoveryComponent);
- siblingContexts.add(siblingContext);
- siblingContextToResource.put(siblingContext, sibling);
- }
-
- //convert the new resources into contexts.
- //map the resources by resource key so that we can later check for
uniqueness of the reported results.
- Set<ResourceUpgradeContext<T>> newResourceContexts = new
HashSet<ResourceUpgradeContext<T>>();
- Map<String, Resource> newResourceKeyToResource = new
HashMap<String, Resource>();
-
- for (Resource newResource : newResources) {
- ResourceUpgradeContext<T> newUpgradeContext =
inventoryManager.createResourceUpgradeContext(
- newResource, parentComponent, discoveryComponent);
- newResourceContexts.add(newUpgradeContext);
- newResourceKeyToResource.put(newResource.getResourceKey(),
newResource);
- }
-
- //ask the discovery component to upgrade the siblings.
- Map<ResourceUpgradeContext<T>, ResourceUpgradeReport>
results;
- try {
- results =
inventoryManager.invokeDiscoveryComponentResourceUpgradeFacet(resourceType,
- discoveryComponent, siblingContexts, parentUpgradeContext,
newResourceContexts);
-
- //now go through the results and create the upgrade requests.
- for (Map.Entry<ResourceUpgradeContext<T>,
ResourceUpgradeReport> upgradeEntry : results.entrySet()) {
- Resource siblingToUpgrade =
siblingContextToResource.get(upgradeEntry.getKey());
- ResourceUpgradeRequest newData = new
ResourceUpgradeRequest(siblingToUpgrade.getId(), upgradeEntry.getValue());
-
- requests.add(newData);
-
- //if there was a resource key upgrade, remove a resource with the
same resource key
- //from the discovery results. Otherwise we'd end up with 2
sibling resources with
- //the same resource key, which is illegal.
- if (newData.getNewResourceKey() != null) {
- Resource newResourceToRemove =
newResourceKeyToResource.get(newData.getNewResourceKey());
- if (newResourceToRemove != null) {
- discoveredResources.remove(newResourceToRemove);
- }
- }
- }
-
- return results;
- } catch (Throwable t) {
- log.warn("Exception in discovery component " +
discoveryComponent.getClass() + " upgrade method.",
- t);
- }
- }
- } catch (PluginContainerException e) {
- log.warn("Failed resource upgrade of children of resource id " +
parentResourceId, e);
- }
- return null;
- }
-}
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradePendingRequest.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradePendingRequest.java
deleted file mode 100644
index 1099643..0000000
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradePendingRequest.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.rhq.core.pc.upgrade;
-
-import java.util.Set;
-
-import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.pluginapi.inventory.ResourceComponent;
-import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
-
-/**
- * This class is used to store the requests for resource upgrade that originate in
- * the discovery workflow, but can only be executed after an inventory sync.
- */
-public class ResourceUpgradePendingRequest<T extends ResourceComponent> {
- private Set<Resource> discoveredResources;
- private ResourceDiscoveryContext<T> discoveryContext;
- private Integer parentResourceId;
-
- public ResourceUpgradePendingRequest(Set<Resource> discoveredResources,
ResourceDiscoveryContext<T> discoveryContext, Integer parentResourceId) {
- this.discoveredResources = discoveredResources;
- this.discoveryContext = discoveryContext;
- this.parentResourceId = parentResourceId;
- }
-
- public Set<Resource> getDiscoveredResources() {
- return discoveredResources;
- }
-
- public ResourceDiscoveryContext<T> getDiscoveryContext() {
- return discoveryContext;
- }
-
- public Integer getParentResourceId() {
- return parentResourceId;
- }
-}
\ No newline at end of file
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 087b46f..b5d571f 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -151,34 +151,8 @@ public class ResourceUpgradeTest {
}
@Test
- public void testResourceUpgradeRunsOnlyOnce() throws Exception {
- currentServerSideInventory = new FakeServerInventory();
- initialSyncAndDiscovery(InventoryStatus.COMMITTED);
-
- executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, new
TestPayload() {
- public void test(Resource discoveredResource) {
- for(int i = 0; i < 100; i++) {
-
PluginContainer.getInstance().getInventoryManager().fireResourceUpgrade();
- }
- }
-
- @SuppressWarnings("unchecked")
- public Expectations getExpectations(Mockery context) throws Exception {
- return new Expectations() {
- {
- defineDefaultExpectations(this);
-
- between(1,
4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
-
will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
-
- //even though we fire the resource upgrade 100 times above,
- //only 1 upgrade should actually occur and go up to the server.
-
oneOf(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
- will(currentServerSideInventory.upgradeResources());
- }
- };
- }
- });
+ public void testRecoveryWithServerUnavailable() throws Exception {
+ //TODO implement
}
private void initialSyncAndDiscovery(final InventoryStatus requiredInventoryStatus)
throws Exception {
diff --git
a/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar
b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar
index 412ae00..7ffc5bb 100644
Binary files
a/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar
and
b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar
differ
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 329f476..add8168 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
@@ -20,7 +20,6 @@ package org.rhq.enterprise.server.discovery;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
index 7fe7a5e..de265eb 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
@@ -1715,8 +1715,16 @@ public class ResourceManagerBean implements ResourceManagerLocal,
ResourceManage
Query query =
entityManager.createNamedQuery(Resource.QUERY_FIND_PLATFORM_BY_AGENT);
query.setParameter("category", ResourceCategory.PLATFORM);
query.setParameter("agent", agent);
- Resource platform = (Resource) query.getSingleResult();
- return platform;
+
+ try {
+ Resource platform = (Resource) query.getSingleResult();
+ return platform;
+ } catch (NoResultException e) {
+ //this means that the agent didn't send any info to us yet.
+ //this can happen during the inital resource upgrade sync between
+ //the agent and server.
+ return null;
+ }
}
@SuppressWarnings("unchecked")
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
index 327c439..faf0b11 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
@@ -376,7 +376,7 @@ public interface ResourceManagerLocal {
*
* @param agent an Agent
*
- * @return the platform Resource associated with the specified Agent
+ * @return the platform Resource associated with the specified Agent or null if the
platform for the agent is not known yet.
*/
Resource getPlatform(Agent agent);
diff --git
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
index 362a1df..c31d153 100644
---
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
+++
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
@@ -170,45 +170,40 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
return discoveredResources;
}
- public Map<ResourceUpgradeContext<PlatformComponent>,
ResourceUpgradeReport>
upgrade(Set<ResourceUpgradeContext<PlatformComponent>> inventoriedSiblings,
- ResourceUpgradeContext<?> parentContext,
Set<ResourceUpgradeContext<PlatformComponent>> discoveryResults) {
-
- Map<ResourceUpgradeContext<PlatformComponent>, ResourceUpgradeReport>
ret = new HashMap<ResourceUpgradeContext<PlatformComponent>,
ResourceUpgradeReport>();
-
- for (ResourceUpgradeContext context : inventoriedSiblings) {
- String inventoriedResourceKey = context.getResourceKey();
- File inventoriedResourceKeyAsPath = new File(inventoriedResourceKey);
-
- //the resource key we use now is a full path to the httpdconf.
- //in the old version, it was the server root.
- //so if the inventoried resource key is a path to a file,
- //we know it's a new style resource key.
- if (inventoriedResourceKeyAsPath.isFile()) {
- continue;
- }
-
- Configuration pluginConfiguration = context.getPluginConfiguration();
-
- String serverRoot =
pluginConfiguration.getSimpleValue("serverRoot", null);
- String httpdConf = pluginConfiguration.getSimpleValue("configFile",
null);
-
- String resourceKey = null;
-
- if (httpdConf != null) {
- File httpdConfFile = new File(httpdConf);
- if (!httpdConfFile.isAbsolute()) {
- httpdConfFile = new File(serverRoot, httpdConf);
- }
-
- resourceKey = httpdConfFile.getPath();
-
- ResourceUpgradeReport rep = new ResourceUpgradeReport();
- rep.setNewResourceKey(resourceKey);
-
- ret.put(context, rep);
+ public ResourceUpgradeReport upgrade(ResourceUpgradeContext<PlatformComponent>
context) {
+ String inventoriedResourceKey = context.getResourceKey();
+ File inventoriedResourceKeyAsPath = new File(inventoriedResourceKey);
+
+ //the resource key we use now is a full path to the httpd.conf.
+ //in the old version, it was the server root.
+ //so if the inventoried resource key is a path to a file,
+ //we know it's a new style resource key.
+ if (inventoriedResourceKeyAsPath.isFile()) {
+ return null;
+ }
+
+ Configuration pluginConfiguration = context.getPluginConfiguration();
+
+ String serverRoot = pluginConfiguration.getSimpleValue("serverRoot",
null);
+ String httpdConf = pluginConfiguration.getSimpleValue("configFile",
null);
+
+ String resourceKey = null;
+
+ if (httpdConf != null) {
+ File httpdConfFile = new File(httpdConf);
+ if (!httpdConfFile.isAbsolute()) {
+ httpdConfFile = new File(serverRoot, httpdConf);
}
+
+ resourceKey = httpdConfFile.getPath();
+
+ ResourceUpgradeReport rep = new ResourceUpgradeReport();
+ rep.setNewResourceKey(resourceKey);
+
+ return rep;
}
- return ret;
+
+ return null;
}
public DiscoveredResourceDetails discoverResource(Configuration pluginConfig,
commit 00b2aae2f27dd64092eee3c2d09df33e48736e10
Merge: 90ca72b... ed06919...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Jul 2 14:25:47 2010 +0200
Merge branch 'release-3.0.0' into resource-upgrade
diff --cc modules/core/dbutils/pom.xml
index 2013b3d,d536ce6..96685db
--- a/modules/core/dbutils/pom.xml
+++ b/modules/core/dbutils/pom.xml
@@@ -22,7 -22,7 +22,7 @@@
<properties>
<scm.module.path>modules/core/dbutils/</scm.module.path>
-- <db.schema.version>2.88</db.schema.version>
++ <db.schema.version>2.89</db.schema.version>
</properties>
<dependencies>
diff --cc modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
index 3ee8217,7f8f9da..20e9d2f
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@@ -2994,15 -3000,17 +3000,27 @@@
</statement>
</schema-directSQL>
</schemaSpec>
-
- <schemaSpec version="2.88">
+
+ <schemaSpec version="2.88">
+ <schema-directSQL>
+ <statement desc="Add end time index on call time data to
speed up purges">
+ CREATE INDEX RHQ_CT_DA_VA_END_TIM_IDX ON RHQ_CALLTIME_DATA_VALUE
(end_time)
+ </statement>
+ <statement desc="Add index on measurement definition numeric
type">
+ CREATE INDEX RHQ_METRIC_DEF_NT_IDX ON RHQ_MEASUREMENT_DEF
(numeric_type)
+ </statement>
+ </schema-directSQL>
+ </schemaSpec>
++
++ <schemaSpec version="2.89">
+ <schema-directSQL>
+ <statement desc="Adding 'Allow Agent Plugins To Upgrade
Generic Resource Properties' system configuration setting">
+ INSERT INTO rhq_system_config (id, property_key, property_value,
default_property_value)
+ VALUES (56, 'RESOURCE_GENERIC_PROPERTIES_UPGRADE',
'false', 'false')
+ </statement>
+ </schema-directSQL>
+ </schemaSpec>
++
</dbupgrade>
</target>
</project>
commit 90ca72b3aa73f41165ab2d616f53f12d642bef7d
Merge: 5449040... b9ca90d...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Jun 23 19:01:34 2010 +0200
Merge branch 'release-3.0.0' into resource-upgrade
commit 54490406d19753524b052beeab418af68bf68c2c
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Jun 23 15:41:36 2010 +0200
Restructuring the tests a bit, adding a test for correct reinitialization of the agent
inventory from the server inventory during the resource upgrade.
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 46d069c..087b46f 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -49,6 +49,7 @@ import org.rhq.core.clientapi.server.event.EventServerService;
import org.rhq.core.clientapi.server.inventory.ResourceFactoryServerService;
import org.rhq.core.clientapi.server.measurement.MeasurementServerService;
import org.rhq.core.clientapi.server.operation.OperationServerService;
+import org.rhq.core.domain.discovery.AvailabilityReport;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
@@ -64,6 +65,7 @@ import org.rhq.core.pc.plugin.FileSystemPluginFinder;
*
* @author Lukas Krejci
*/
+@Test(sequential = true, invocationCount = 1)
public class ResourceUpgradeTest {
private static final String PLUGIN_V1_FILENAME =
"resource-upgrade-test-plugin-1.0.0.jar";
@@ -100,7 +102,7 @@ public class ResourceUpgradeTest {
verifyPluginExists(PLUGIN_V2_FILENAME);
}
- @BeforeClass
+ @BeforeClass(dependsOnMethods = "sanityCheck")
public void init() {
tmpDir = getTmpDirectory();
pluginDir = new File(tmpDir, PLUGINS_DIR_NAME);
@@ -110,12 +112,10 @@ public class ResourceUpgradeTest {
}
@Test
- public void testInitialSyncAndDiscoveryWithoutCommit() throws Exception {
- testInitialSyncAndDiscovery(InventoryStatus.NEW);
- }
-
- @Test(dependsOnMethods = "testInitialSyncAndDiscoveryWithoutCommit")
public void testIgnoreUncommittedResources() throws Exception {
+ currentServerSideInventory = new FakeServerInventory();
+ initialSyncAndDiscovery(InventoryStatus.NEW);
+
TestPayload testNoChange = new TestPayload() {
public void test(Resource discoveredResource) {
assertEquals(discoveredResource.getResourceKey(),
"resource-key-v1");
@@ -123,17 +123,13 @@ public class ResourceUpgradeTest {
assertEquals(discoveredResource.getDescription(),
"resource-description-v1");
}
- @SuppressWarnings("unchecked")
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
- defineIgnoredExpectations(this);
+ defineDefaultExpectations(this);
between(1,
4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
-
-
allowing(currentDiscoveryServerService).getResources(with(any(Set.class)),
with(any(boolean.class)));
- will(currentServerSideInventory.getResources());
}
};
}
@@ -142,52 +138,50 @@ public class ResourceUpgradeTest {
executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false,
testNoChange);
}
- //make the tests run serially, so that they don't overwrite the
currentServerSideInventory
- //variable concurrently
- @Test(dependsOnMethods = "testIgnoreUncommittedResources")
- public void testInitialSyncAndDiscoveryWithCommit() throws Exception {
- testInitialSyncAndDiscovery(InventoryStatus.COMMITTED);
- }
-
- @Test(dependsOnMethods = "testInitialSyncAndDiscoveryWithCommit")
+ @Test
public void testUpgradeData() throws Exception {
- //we are keeping the currentServerSideInventory from the previous test
+ currentServerSideInventory = new FakeServerInventory();
+ upgradeTest(false);
+ }
+
+ @Test
+ public void testInventoryReinitializationFromServerDuringUpgrade() throws Exception
{
+ currentServerSideInventory = new FakeServerInventory();
+ upgradeTest(true);
+ }
+
+ @Test
+ public void testResourceUpgradeRunsOnlyOnce() throws Exception {
+ currentServerSideInventory = new FakeServerInventory();
+ initialSyncAndDiscovery(InventoryStatus.COMMITTED);
+
executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, new
TestPayload() {
public void test(Resource discoveredResource) {
- assertEquals(discoveredResource.getResourceKey(),
"resource-key-v2");
- assertEquals(discoveredResource.getName(),
"resource-name-v2");
- assertEquals(discoveredResource.getDescription(),
"resource-description-v2");
-
- ResourceContainer container =
PluginContainer.getInstance().getInventoryManager().getResourceContainer(discoveredResource);
- File dataDir = container.getResourceContext().getDataDirectory();
-
- File marker = new File(dataDir, "upgrade-succeeded");
-
- assertTrue(marker.exists(), "The upgrade success marker file
wasn't found. This means the upgrade didn't actually run.");
+ for(int i = 0; i < 100; i++) {
+
PluginContainer.getInstance().getInventoryManager().fireResourceUpgrade();
+ }
}
@SuppressWarnings("unchecked")
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
- defineIgnoredExpectations(this);
+ defineDefaultExpectations(this);
between(1,
4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+ //even though we fire the resource upgrade 100 times above,
+ //only 1 upgrade should actually occur and go up to the server.
oneOf(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
will(currentServerSideInventory.upgradeResources());
-
-
allowing(currentDiscoveryServerService).getResources(with(any(Set.class)),
with(any(boolean.class)));
- will(currentServerSideInventory.getResources());
}
};
}
});
}
- private void testInitialSyncAndDiscovery(final InventoryStatus
requiredInventoryStatus) throws Exception {
- currentServerSideInventory = new FakeServerInventory();
+ private void initialSyncAndDiscovery(final InventoryStatus requiredInventoryStatus)
throws Exception {
executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), true, new
TestPayload() {
public void test(Resource discoveredResource) {
assertEquals(discoveredResource.getResourceKey(),
"resource-key-v1");
@@ -195,17 +189,13 @@ public class ResourceUpgradeTest {
assertEquals(discoveredResource.getDescription(),
"resource-description-v1");
}
- @SuppressWarnings("unchecked")
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
- defineIgnoredExpectations(this);
+ defineDefaultExpectations(this);
between(1,
4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
will(currentServerSideInventory.mergeInventoryReport(requiredInventoryStatus));
-
-
allowing(currentDiscoveryServerService).getResources(with(any(Set.class)),
with(any(boolean.class)));
- will(currentServerSideInventory.getResources());
}
};
}
@@ -213,6 +203,40 @@ public class ResourceUpgradeTest {
}
+ private void upgradeTest(boolean clearInventoryDat) throws Exception {
+ initialSyncAndDiscovery(InventoryStatus.COMMITTED);
+
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME),
clearInventoryDat, new TestPayload() {
+ public void test(Resource discoveredResource) {
+ assertEquals(discoveredResource.getResourceKey(),
"resource-key-v2");
+ assertEquals(discoveredResource.getName(),
"resource-name-v2");
+ assertEquals(discoveredResource.getDescription(),
"resource-description-v2");
+
+ ResourceContainer container =
PluginContainer.getInstance().getInventoryManager().getResourceContainer(discoveredResource);
+ File dataDir = container.getResourceContext().getDataDirectory();
+
+ File marker = new File(dataDir, "upgrade-succeeded");
+
+ assertTrue(marker.exists(), "The upgrade success marker file
wasn't found. This means the upgrade didn't actually run.");
+ }
+
+ @SuppressWarnings("unchecked")
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+
+ between(1,
4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
+
will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+
+
oneOf(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
+ will(currentServerSideInventory.upgradeResources());
+ }
+ };
+ }
+ });
+ }
+
private PluginContainerConfiguration createPluginContainerConfiguration(Mockery
context) throws Exception {
PluginContainerConfiguration conf = new PluginContainerConfiguration();
@@ -223,6 +247,15 @@ public class ResourceUpgradeTest {
conf.setPluginFinder(new FileSystemPluginFinder(conf.getPluginDirectory()));
conf.setCreateResourceClassloaders(false);
+ //we're not interested in any scans happening out of our control
+ conf.setAvailabilityScanInitialDelay(Long.MAX_VALUE);
+ conf.setConfigurationDiscoveryInitialDelay(Long.MAX_VALUE);
+ conf.setContentDiscoveryInitialDelay(Long.MAX_VALUE);
+ conf.setEventSenderInitialDelay(Long.MAX_VALUE);
+ conf.setMeasurementCollectionInitialDelay(Long.MAX_VALUE);
+ conf.setServerDiscoveryInitialDelay(Long.MAX_VALUE);
+ conf.setServiceDiscoveryInitialDelay(Long.MAX_VALUE);
+
currentBundleServerService = context.mock(BundleServerService.class);
currentConfigurationServerService =
context.mock(ConfigurationServerService.class);
currentContentServerService = context.mock(ContentServerService.class);
@@ -332,7 +365,8 @@ public class ResourceUpgradeTest {
context.assertIsSatisfied();
}
- private void defineIgnoredExpectations(Expectations expectations) {
+ @SuppressWarnings("unchecked")
+ private void defineDefaultExpectations(Expectations expectations) {
expectations.ignoring(currentBundleServerService);
expectations.ignoring(currentConfigurationServerService);
expectations.ignoring(currentContentServerService);
@@ -341,5 +375,11 @@ public class ResourceUpgradeTest {
expectations.ignoring(currentMeasurementServerService);
expectations.ignoring(currentOperationServerService);
expectations.ignoring(currentResourceFactoryServerService);
+
+ //just ignore these invocations if we get a availability scan in the PC...
+
expectations.allowing(currentDiscoveryServerService).mergeAvailabilityReport(expectations.with(Expectations.any(AvailabilityReport.class)));
+
+
expectations.allowing(currentDiscoveryServerService).getResources(expectations.with(Expectations.any(Set.class)),
expectations.with(Expectations.any(boolean.class)));
+ expectations.will(currentServerSideInventory.getResources());
}
}
commit 0d5d63e1ed0825ddc0ea256b695a66c980b69e6e
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Jun 23 15:40:16 2010 +0200
Forgot to bump the db version.
diff --git a/modules/core/dbutils/pom.xml b/modules/core/dbutils/pom.xml
index 92ae1d2..2013b3d 100644
--- a/modules/core/dbutils/pom.xml
+++ b/modules/core/dbutils/pom.xml
@@ -22,7 +22,7 @@
<properties>
<scm.module.path>modules/core/dbutils/</scm.module.path>
- <db.schema.version>2.87</db.schema.version>
+ <db.schema.version>2.88</db.schema.version>
</properties>
<dependencies>
commit 7f8310f4d3648ba3386fda883563bdcc8c5d1492
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Jun 23 15:39:54 2010 +0200
Adding the server side system config property for controlling whether to allow
resource name and description upgrades.
diff --git
a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/config/SystemConfigForm.java
b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/config/SystemConfigForm.java
index 237858d..508a4ac 100644
---
a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/config/SystemConfigForm.java
+++
b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/config/SystemConfigForm.java
@@ -66,7 +66,8 @@ public class SystemConfigForm extends BaseValidatorForm {
private String ldapPassword = "";
private Boolean ldapEnabled = null;
private boolean reindex = false;
-
+ private boolean allowResourceGenericPropertiesUpgrade;
+
@Override
public String toString() {
StringBuffer buf = new StringBuffer(super.toString());
@@ -230,6 +231,8 @@ public class SystemConfigForm extends BaseValidatorForm {
String jaasProvider = prop.getProperty(RHQConstants.JAASProvider);
ldapEnabled = RHQConstants.LDAPJAASProvider.equals(jaasProvider) ? Boolean.TRUE :
null;
+ String resourceGenericPropertiesUpgradeAllowed =
prop.getProperty(RHQConstants.AllowResourceGenericPropertiesUpgrade);
+ allowResourceGenericPropertiesUpgrade =
Boolean.parseBoolean(resourceGenericPropertiesUpgradeAllowed);
}
/**
@@ -332,6 +335,8 @@ public class SystemConfigForm extends BaseValidatorForm {
prop.setProperty(RHQConstants.JAASProvider, RHQConstants.JDBCJAASProvider);
}
+ prop.setProperty(RHQConstants.AllowResourceGenericPropertiesUpgrade,
String.valueOf(allowResourceGenericPropertiesUpgrade));
+
return prop;
}
@@ -608,6 +613,14 @@ public class SystemConfigForm extends BaseValidatorForm {
public void setReindex(boolean reindex) {
this.reindex = reindex;
}
+
+ public boolean isAllowResourceGenericPropertiesUpgrade() {
+ return allowResourceGenericPropertiesUpgrade;
+ }
+
+ public void setAllowResourceGenericPropertiesUpgrade(boolean
allowResourceGenericPropertiesUpgrade) {
+ this.allowResourceGenericPropertiesUpgrade =
allowResourceGenericPropertiesUpgrade;
+ }
/* (non-Javadoc)
* @see
org.apache.struts.action.ActionForm#validate(org.apache.struts.action.ActionMapping,
diff --git
a/modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties
b/modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties
index f02efb5..83f42f0 100644
---
a/modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties
+++
b/modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties
@@ -667,6 +667,8 @@ admin.settings.ServerPluginsConfigPropTab=Server Plugins Configuration
Propertie
admin.settings.UseCAMAuth=Use ${product.shortName} Internal Authentication
admin.settings.UseLDAPAuth=Use LDAP Authentication
+admin.settings.AllowResourceGenericPropertiesUpgrade=Allow Agent Plugins To Upgrade
Generic Resource Properties
+
admin.settings.error.DeleteUnitsField=Value must be between 1 and 7 days.
admin.settings.error.InvalidSNMPTrapOID=SNMP Trap OID invalid, please enter OID in form
of 1.2.3.4.
admin.settings.error.InvalidSNMPEngineID=SNMP Engine ID is invalid, must be a valid
number.
diff --git
a/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/GeneralPropertiesConfigForm.jsp
b/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/GeneralPropertiesConfigForm.jsp
index 30df9ef..136c37c 100644
---
a/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/GeneralPropertiesConfigForm.jsp
+++
b/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/GeneralPropertiesConfigForm.jsp
@@ -86,6 +86,17 @@
</table>
</td>
</tr>
+ <tr>
+ <td class="BlockLabel"><fmt:message
key="admin.settings.AllowResourceGenericPropertiesUpgrade"/></td>
+ <td class="BlockContent">
+ <table cellpadding="0" cellspacing="4"
border="0">
+ <tr>
+ <td align="left"><html:radio
property="allowResourceGenericPropertiesUpgrade"
value="true"/><fmt:message key="yesno.true"/></td>
+ <td align="left"><html:radio
property="allowResourceGenericPropertiesUpgrade"
value="false"/><fmt:message key="yesno.false"/></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
<hq:authorization permission="superuser">
<tr>
commit 6c2472739d2df4b5a99f1e4fae22b945440dd5fd
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Jun 23 15:29:15 2010 +0200
Adding the ability of the server to alter/ignore some upgrade data.
diff --git
a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
new file mode 100644
index 0000000..825a616
--- /dev/null
+++
b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
@@ -0,0 +1,55 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.clientapi.agent.upgrade;
+
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
+
+/**
+ * Represents a request to upgrade a resource.
+ *
+ * @author Lukas Krejci
+ */
+public class ResourceUpgradeRequest extends ResourceUpgradeReport {
+
+ private int resourceId;
+
+ public ResourceUpgradeRequest() {
+
+ }
+
+ public ResourceUpgradeRequest(int resourceId, ResourceUpgradeReport report) {
+ setResourceId(resourceId);
+ setNewDescription(report.getNewDescription());
+ setNewName(report.getNewName());
+ setNewResourceKey(report.getNewResourceKey());
+ }
+
+ public int getResourceId() {
+ return resourceId;
+ }
+
+ public void setResourceId(int resourceId) {
+ this.resourceId = resourceId;
+ }
+}
diff --git
a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeResponse.java
b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeResponse.java
new file mode 100644
index 0000000..3faa9ef
--- /dev/null
+++
b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeResponse.java
@@ -0,0 +1,80 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.clientapi.agent.upgrade;
+
+import java.io.Serializable;
+
+/**
+ * Represents a response to a resource upgrade request.
+ * The upgraded* properties contain the values of the corresponding resource properties
+ * as they were stored on the server.
+ *
+ * @author Lukas Krejci
+ */
+public class ResourceUpgradeResponse implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private int resourceId;
+
+ private String upgradedResourceName;
+ private String upgradedResourceKey;
+ private String upgradedResourceDescription;
+
+ public ResourceUpgradeResponse() {
+
+ }
+
+ public int getResourceId() {
+ return resourceId;
+ }
+
+ public void setResourceId(int resourceId) {
+ this.resourceId = resourceId;
+ }
+
+ public String getUpgradedResourceName() {
+ return upgradedResourceName;
+ }
+
+ public void setUpgradedResourceName(String upgradedResourceName) {
+ this.upgradedResourceName = upgradedResourceName;
+ }
+
+ public String getUpgradedResourceKey() {
+ return upgradedResourceKey;
+ }
+
+ public void setUpgradedResourceKey(String upgradedResourceKey) {
+ this.upgradedResourceKey = upgradedResourceKey;
+ }
+
+ public String getUpgradedResourceDescription() {
+ return upgradedResourceDescription;
+ }
+
+ public void setUpgradedResourceDescription(String upgradedResourceDescription) {
+ this.upgradedResourceDescription = upgradedResourceDescription;
+ }
+}
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 61e5084..0622fc5 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
@@ -29,6 +29,8 @@ import org.rhq.core.communications.command.annotation.Asynchronous;
import org.rhq.core.communications.command.annotation.LimitedConcurrency;
import org.rhq.core.communications.command.annotation.Timeout;
import org.rhq.core.domain.discovery.AvailabilityReport;
+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;
@@ -37,7 +39,6 @@ import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.domain.resource.ResourceErrorType;
-import org.rhq.core.domain.resource.ResourceUpgradeReport;
/**
* The interface to a JON server's resource discovery subsystem.
@@ -139,11 +140,13 @@ public interface DiscoveryServerService {
/**
* Upgrades the data of the resources according to the provided reports.
+ * The server is free to ignore or modify the requests and will provide the
+ * true changes made to the resources on the server-side in the result of this
method.
*
- * @param upgradeReports contains the information about the upgrade of individual
resources.
- * @return true if the upgrade succeeded, false otherwise.
+ * @param upgradeRequests contains the information about the upgrade of individual
resources.
+ * @return details on what resources have been upgraded with what data.
*/
- boolean upgradeResources(Set<ResourceUpgradeReport> upgradeReports);
+ Set<ResourceUpgradeResponse> upgradeResources(Set<ResourceUpgradeRequest>
upgradeRequests);
/**
* Gives the server a chance to apply any necessary post-processing that's needed
for newly committed resources
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/sysconfig-data.xml
b/modules/core/dbutils/src/main/scripts/dbsetup/sysconfig-data.xml
index 26d648e..121e971 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup/sysconfig-data.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/sysconfig-data.xml
@@ -121,6 +121,9 @@
<!-- How old does availability have to be in order to get purged -->
<data ID="55" PROPERTY_KEY="AVAILABILITY_PURGE"
PROPERTY_VALUE="31536000000"
DEFAULT_PROPERTY_VALUE="31536000000"
FREAD_ONLY="FALSE"/>
+
+ <data ID="56"
PROPERTY_KEY="RESOURCE_GENERIC_PROPERTIES_UPGRADE"
PROPERTY_VALUE="false"
+ DEFAULT_PROPERTY_VALUE="false" FREAD_ONLY="FALSE"/>
</table>
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
index 71aa297..ad53803 100644
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@ -2994,6 +2994,14 @@
</schema-directSQL>
</schemaSpec>
+ <schemaSpec version="2.88">
+ <schema-directSQL>
+ <statement desc="Adding 'Allow Agent Plugins To Upgrade
Generic Resource Properties' system configuration setting">
+ INSERT INTO rhq_system_config (id, property_key, property_value,
default_property_value)
+ VALUES (56, 'RESOURCE_GENERIC_PROPERTIES_UPGRADE',
'false', 'false')
+ </statement>
+ </schema-directSQL>
+ </schemaSpec>
</dbupgrade>
</target>
</project>
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
index 979c456..0f9db04 100644
---
a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
@@ -41,7 +41,6 @@ public class ResourceUpgradeReport implements Serializable {
private static final long serialVersionUID = 1L;
- private int resourceId;
private String newResourceKey;
private String newName;
@@ -62,22 +61,6 @@ public class ResourceUpgradeReport implements Serializable {
}
- /**
- * The server-side id of the resource being upgraded.
- * The discovery components don't need to assign this value.
- */
- public int getResourceId() {
- return resourceId;
- }
-
- /**
- * The server-side id of the resource being upgraded.
- * The discovery components don't need to assign this value.
- */
- public void setResourceId(int resourceId) {
- this.resourceId = resourceId;
- }
-
public String getNewResourceKey() {
return newResourceKey;
}
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 6c3d26a..b5f5f00 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
@@ -55,6 +55,8 @@ import org.rhq.core.clientapi.agent.configuration.ConfigurationUtility;
import org.rhq.core.clientapi.agent.discovery.DiscoveryAgentService;
import org.rhq.core.clientapi.agent.discovery.InvalidPluginConfigurationClientException;
import org.rhq.core.clientapi.agent.metadata.PluginMetadataManager;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
+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;
@@ -92,7 +94,7 @@ import org.rhq.core.pc.plugin.CanonicalResourceKey;
import org.rhq.core.pc.plugin.PluginComponentFactory;
import org.rhq.core.pc.plugin.PluginManager;
import org.rhq.core.pc.upgrade.ResourceUpgradeExecutor;
-import org.rhq.core.pc.upgrade.ResourceUpgradeRequest;
+import org.rhq.core.pc.upgrade.ResourceUpgradePendingRequest;
import org.rhq.core.pc.util.DiscoveryComponentProxyFactory;
import org.rhq.core.pc.util.FacetLockType;
import org.rhq.core.pc.util.LoggingThreadFactory;
@@ -1178,31 +1180,31 @@ public class InventoryManager extends AgentService implements
ContainerService,
return resourceContainer.updateAvailability(availabilityType);
}
- public boolean mergeResourceFromUpgrade(Set<ResourceUpgradeReport>
upgradeReports) {
- boolean serverUpdated = false;
+ public void mergeResourceFromUpgrade(Set<ResourceUpgradeRequest>
upgradeReports) {
+ Set<ResourceUpgradeResponse> serverUpdates = null;
try {
ServerServices serverServices = this.configuration.getServerServices();
if (serverServices != null) {
DiscoveryServerService discoveryServerService =
serverServices.getDiscoveryServerService();
- serverUpdated = discoveryServerService.upgradeResources(upgradeReports);
+ serverUpdates = discoveryServerService.upgradeResources(upgradeReports);
}
} catch (Exception e) {
log.error("Failed to process resource upgrades on the server.",
e);
}
- if (serverUpdated) {
- for (ResourceUpgradeReport upgradeReport : upgradeReports) {
- String resourceKey = upgradeReport.getNewResourceKey();
- String name = upgradeReport.getNewName();
+ if (serverUpdates != null) {
+ for (ResourceUpgradeResponse upgradeResponse : serverUpdates) {
+ String resourceKey = upgradeResponse.getUpgradedResourceKey();
+ String name = upgradeResponse.getUpgradedResourceName();
//String version = upgradeReport.getNewVersion();
- String description = upgradeReport.getNewDescription();
+ String description = upgradeResponse.getUpgradedResourceDescription();
//Configuration pluginConfiguration =
upgradeReport.getNewPluginConfiguration();
//Configuration resourceConfiguration =
upgradeReport.getNewResourceConfiguration();
//only bother if there's something to upgrade at all on this
resource.
if (resourceKey != null || name != null || description != null) {
- ResourceContainer existingResourceContainer =
getResourceContainer(upgradeReport.getResourceId());
+ ResourceContainer existingResourceContainer =
getResourceContainer(upgradeResponse.getResourceId());
if (existingResourceContainer != null) {
Resource existingResource =
existingResourceContainer.getResource();
@@ -1241,13 +1243,11 @@ public class InventoryManager extends AgentService implements
ContainerService,
log.info(logMessage.toString());
} else {
- log.error("Upgraded a resource that is not present on the
agent. This should not happen. The id of the missing resource is " +
upgradeReport.getResourceId());
+ log.error("Upgraded a resource that is not present on the
agent. This should not happen. The id of the missing resource is " +
upgradeResponse.getResourceId());
}
}
}
}
-
- return serverUpdated;
}
public Resource mergeResourceFromDiscovery(Resource resource, Resource parent) throws
PluginContainerException {
@@ -2173,7 +2173,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
}
if (resourceUpgradeExecutor.isEnabled()) {
- resourceUpgradeExecutor.processAndQueue(new
ResourceUpgradeRequest(newResources, context, parentResource.getId()), newResources);
+ resourceUpgradeExecutor.processAndQueue(new
ResourceUpgradePendingRequest(newResources, context, parentResource.getId()),
newResources);
}
} catch (Throwable e) {
// TODO GH: Add server/parent - up/down semantics so this won't happen
just because a server is not up
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
index bb20054..f344900 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
@@ -29,7 +29,6 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -37,6 +36,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rhq.core.clientapi.agent.PluginContainerException;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
@@ -69,11 +69,11 @@ public class ResourceUpgradeExecutor implements Runnable {
private InventoryManager inventoryManager;
- private ConcurrentLinkedQueue<ResourceUpgradeReport> reports;
+ private ConcurrentLinkedQueue<ResourceUpgradeRequest> requests;
public ResourceUpgradeExecutor(InventoryManager inventoryManager) {
this.inventoryManager = inventoryManager;
- reports = new ConcurrentLinkedQueue<ResourceUpgradeReport>();
+ requests = new ConcurrentLinkedQueue<ResourceUpgradeRequest>();
}
/**
@@ -92,9 +92,9 @@ public class ResourceUpgradeExecutor implements Runnable {
* @param discoveredResources the set of discovered resources that this method can
optionally remove some elements from.
*/
public <T extends ResourceComponent> Map<ResourceUpgradeContext<T>,
ResourceUpgradeReport> processAndQueue(
- ResourceUpgradeRequest<T> request, Set<Resource> discoveredResources)
{
+ ResourceUpgradePendingRequest<T> request, Set<Resource>
discoveredResources) {
- return enabled.get() ? executeResourceUpgradeAndStoreReport(request,
discoveredResources) : null;
+ return enabled.get() ? executeResourceUpgradeAndStoreRequest(request,
discoveredResources) : null;
}
/**
@@ -109,10 +109,10 @@ public class ResourceUpgradeExecutor implements Runnable {
* all the upgrade requests.
*/
public void sendRequests() {
- if (enabled.get() && reports.size() > 0) {
- HashSet<ResourceUpgradeReport> currentCopy = new
HashSet<ResourceUpgradeReport>(reports);
+ if (enabled.get() && requests.size() > 0) {
+ HashSet<ResourceUpgradeRequest> currentCopy = new
HashSet<ResourceUpgradeRequest>(requests);
inventoryManager.mergeResourceFromUpgrade(currentCopy);
- reports.removeAll(currentCopy);
+ requests.removeAll(currentCopy);
}
}
@@ -148,7 +148,7 @@ public class ResourceUpgradeExecutor implements Runnable {
this.enabled.set(false);
//clear up so that we don't hold unnecessary instances.
- reports.clear();
+ requests.clear();
if (log.isDebugEnabled()) {
log.debug("Resource upgrade finished.");
@@ -171,8 +171,8 @@ public class ResourceUpgradeExecutor implements Runnable {
*
* @throws PluginContainerException
*/
- private <T extends ResourceComponent> Map<ResourceUpgradeContext<T>,
ResourceUpgradeReport> executeResourceUpgradeAndStoreReport(
- ResourceUpgradeRequest<T> request, Set<Resource> discoveredResources)
{
+ private <T extends ResourceComponent> Map<ResourceUpgradeContext<T>,
ResourceUpgradeReport> executeResourceUpgradeAndStoreRequest(
+ ResourceUpgradePendingRequest<T> request, Set<Resource>
discoveredResources) {
ResourceDiscoveryContext<T> discoveryContext =
request.getDiscoveryContext();
Set<Resource> newResources = request.getDiscoveredResources();
@@ -267,14 +267,12 @@ public class ResourceUpgradeExecutor implements Runnable {
results =
inventoryManager.invokeDiscoveryComponentResourceUpgradeFacet(resourceType,
discoveryComponent, siblingContexts, parentUpgradeContext,
newResourceContexts);
- //now go through the results and upgrade the resources as needed.
+ //now go through the results and create the upgrade requests.
for (Map.Entry<ResourceUpgradeContext<T>,
ResourceUpgradeReport> upgradeEntry : results.entrySet()) {
Resource siblingToUpgrade =
siblingContextToResource.get(upgradeEntry.getKey());
- ResourceUpgradeReport newData = upgradeEntry.getValue();
+ ResourceUpgradeRequest newData = new
ResourceUpgradeRequest(siblingToUpgrade.getId(), upgradeEntry.getValue());
- //upgrade the data on the server first
- newData.setResourceId(siblingToUpgrade.getId());
- reports.add(newData);
+ requests.add(newData);
//if there was a resource key upgrade, remove a resource with the
same resource key
//from the discovery results. Otherwise we'd end up with 2
sibling resources with
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradePendingRequest.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradePendingRequest.java
new file mode 100644
index 0000000..1099643
--- /dev/null
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradePendingRequest.java
@@ -0,0 +1,35 @@
+package org.rhq.core.pc.upgrade;
+
+import java.util.Set;
+
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+
+/**
+ * This class is used to store the requests for resource upgrade that originate in
+ * the discovery workflow, but can only be executed after an inventory sync.
+ */
+public class ResourceUpgradePendingRequest<T extends ResourceComponent> {
+ private Set<Resource> discoveredResources;
+ private ResourceDiscoveryContext<T> discoveryContext;
+ private Integer parentResourceId;
+
+ public ResourceUpgradePendingRequest(Set<Resource> discoveredResources,
ResourceDiscoveryContext<T> discoveryContext, Integer parentResourceId) {
+ this.discoveredResources = discoveredResources;
+ this.discoveryContext = discoveryContext;
+ this.parentResourceId = parentResourceId;
+ }
+
+ public Set<Resource> getDiscoveredResources() {
+ return discoveredResources;
+ }
+
+ public ResourceDiscoveryContext<T> getDiscoveryContext() {
+ return discoveryContext;
+ }
+
+ public Integer getParentResourceId() {
+ return parentResourceId;
+ }
+}
\ No newline at end of file
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeRequest.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeRequest.java
deleted file mode 100644
index 25178ee..0000000
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeRequest.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.rhq.core.pc.upgrade;
-
-import java.util.Set;
-
-import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.pluginapi.inventory.ResourceComponent;
-import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
-
-/**
- * This class is used to store the requests for resource upgrade that originate in
- * the discovery workflow, but can only be executed after an inventory sync.
- */
-public class ResourceUpgradeRequest<T extends ResourceComponent> {
- private Set<Resource> discoveredResources;
- private ResourceDiscoveryContext<T> discoveryContext;
- private Integer parentResourceId;
-
- public ResourceUpgradeRequest(Set<Resource> discoveredResources,
ResourceDiscoveryContext<T> discoveryContext, Integer parentResourceId) {
- this.discoveredResources = discoveredResources;
- this.discoveryContext = discoveryContext;
- this.parentResourceId = parentResourceId;
- }
-
- public Set<Resource> getDiscoveredResources() {
- return discoveredResources;
- }
-
- public ResourceDiscoveryContext<T> getDiscoveryContext() {
- return discoveryContext;
- }
-
- public Integer getParentResourceId() {
- return parentResourceId;
- }
-}
\ No newline at end of file
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
index 4341e3a..c3bdbf4 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
@@ -37,15 +37,17 @@ import java.util.Set;
import org.jmock.api.Invocation;
import org.jmock.lib.action.CustomAction;
+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.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.domain.resource.ResourceUpgradeReport;
/**
- *
+ * This class represents a server side database store of the inventory for the purposes
+ * of the ResourceUpgradeTest unit test.
*
* @author Lukas Krejci
*/
@@ -89,28 +91,36 @@ public class FakeServerInventory {
return new CustomAction("upgradeServerSideInventory") {
@SuppressWarnings({"serial", "unchecked"})
public Object invoke(Invocation invocation) throws Throwable {
- Set<ResourceUpgradeReport> reports =
(Set<ResourceUpgradeReport>) invocation.getParameter(0);
-
- for (final ResourceUpgradeReport report : reports) {
+ Set<ResourceUpgradeRequest> requests =
(Set<ResourceUpgradeRequest>) invocation.getParameter(0);
+ Set<ResourceUpgradeResponse> responses = new
HashSet<ResourceUpgradeResponse>();
+
+ for (final ResourceUpgradeRequest request : requests) {
Resource resource = findResource(platform, new Resource() {
public int getId() {
- return report.getResourceId();
+ return request.getResourceId();
}
}, ID_COMPARATOR);
if (resource != null) {
- if (report.getNewDescription() != null) {
- resource.setDescription(report.getNewDescription());
+ if (request.getNewDescription() != null) {
+ resource.setDescription(request.getNewDescription());
}
- if (report.getNewName() != null) {
- resource.setName(report.getNewName());
+ if (request.getNewName() != null) {
+ resource.setName(request.getNewName());
}
- if (report.getNewResourceKey() != null) {
- resource.setResourceKey(report.getNewResourceKey());
+ if (request.getNewResourceKey() != null) {
+ resource.setResourceKey(request.getNewResourceKey());
}
+
+ ResourceUpgradeResponse resp = new ResourceUpgradeResponse();
+ resp.setResourceId(resource.getId());
+ resp.setUpgradedResourceName(resource.getName());
+ resp.setUpgradedResourceKey(resource.getResourceKey());
+ resp.setUpgradedResourceDescription(resource.getDescription());
+ responses.add(resp);
}
}
- return true;
+ return responses;
}
};
}
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/RHQConstants.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/RHQConstants.java
index 7bb1d72..fff7872 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/RHQConstants.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/RHQConstants.java
@@ -110,5 +110,8 @@ public class RHQConstants {
// Syslog Actions enabled
public static final String SyslogActionsEnabled =
"CAM_SYSLOG_ACTIONS_ENABLED";
+
+ //allow plugin initiated resource name & description upgrades (resource key is
always upgradable)
+ public static final String AllowResourceGenericPropertiesUpgrade =
"RESOURCE_GENERIC_PROPERTIES_UPGRADE";
}
\ No newline at end of file
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 fd59590..329f476 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
@@ -20,8 +20,10 @@ package org.rhq.enterprise.server.discovery;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -43,6 +45,8 @@ import org.jetbrains.annotations.Nullable;
import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.agent.discovery.InvalidPluginConfigurationClientException;
+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.domain.auth.Subject;
@@ -75,6 +79,7 @@ import
org.rhq.enterprise.server.resource.ResourceAvailabilityManagerLocal;
import org.rhq.enterprise.server.resource.ResourceManagerLocal;
import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal;
import org.rhq.enterprise.server.resource.group.ResourceGroupManagerLocal;
+import org.rhq.enterprise.server.system.SystemManagerLocal;
/**
* SLSB that provides the interface point to the discovery subsystem for the UI layer and
the discovery server service.
@@ -107,6 +112,8 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
private SubjectManagerLocal subjectManager;
@EJB
private ProductVersionManagerLocal productVersionManager;
+ @EJB
+ private SystemManagerLocal systemManager;
public ResourceSyncInfo mergeInventoryReport(InventoryReport report) throws
InvalidInventoryReportException {
validateInventoryReport(report);
@@ -407,20 +414,19 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
}
}
- public boolean upgradeResources(Set<ResourceUpgradeReport> upgradeReports) {
- for (ResourceUpgradeReport report : upgradeReports) {
- Resource existingResource = this.entityManager.find(Resource.class,
report.getResourceId());
+ public Set<ResourceUpgradeResponse>
upgradeResources(Set<ResourceUpgradeRequest> upgradeRequests) {
+ Set<ResourceUpgradeResponse> result = new
HashSet<ResourceUpgradeResponse>();
+
+ boolean allowGenericPropertiesUpgrade =
Boolean.parseBoolean(systemManager.getSystemConfiguration().getProperty(RHQConstants.AllowResourceGenericPropertiesUpgrade,
"false"));
+
+ for (ResourceUpgradeRequest request : upgradeRequests) {
+ Resource existingResource = this.entityManager.find(Resource.class,
request.getResourceId());
if (existingResource != null) {
- boolean changed = upgradeResource(existingResource, report);
- if (changed) {
- this.entityManager.merge(existingResource);
- }
- } else {
- this.entityManager.getTransaction().setRollbackOnly();
- return false;
+ ResourceUpgradeResponse upgradedData = upgradeResource(existingResource,
request, allowGenericPropertiesUpgrade);
+ result.add(upgradedData);
}
}
- return true;
+ return result;
}
/**
@@ -471,40 +477,46 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
/**
* @param existingResource
* @param upgradeReport
+ * @param allowGenericPropertiesUpgrade name and description are only upgraded if
this is true
* @return true if the resource was changed, false otherwise
*/
- private boolean upgradeResource(Resource resource, ResourceUpgradeReport
upgradeReport) {
- if (resource != null) {
- String resourceKey = upgradeReport.getNewResourceKey();
- String name = upgradeReport.getNewName();
+ private ResourceUpgradeResponse upgradeResource(@NotNull Resource resource,
ResourceUpgradeReport upgradeReport, boolean allowGenericPropertiesUpgrade) {
+ ResourceUpgradeResponse ret = new ResourceUpgradeResponse();
+ ret.setResourceId(resource.getId());
+
+ String resourceKey = upgradeReport.getNewResourceKey();
+ String name = upgradeReport.getNewName();
// String version = upgradeReport.getNewVersion();
- String description = upgradeReport.getNewDescription();
+ String description = upgradeReport.getNewDescription();
// Configuration pluginConfiguration =
upgradeReport.getNewPluginConfiguration();
// Configuration resourceConfiguration =
upgradeReport.getNewResourceConfiguration();
+
+ if (resourceKey != null || name != null || description != null) {
+ StringBuilder logMessage = new StringBuilder("Resource [")
+ .append(resource.toString()).append("] upgraded its ");
+
+ if (needsUpgrade(resource.getResourceKey(), resourceKey)) {
+ resource.setResourceKey(resourceKey);
+ logMessage.append("resourceKey, ");
+ }
+ ret.setUpgradedResourceKey(resource.getResourceKey());
+
+ if (allowGenericPropertiesUpgrade && needsUpgrade(resource.getName(),
name)) {
+ resource.setName(name);
+ logMessage.append("name, ");
+ }
+ ret.setUpgradedResourceName(resource.getName());
- if (resourceKey != null || name != null || description != null) {
- StringBuilder logMessage = new StringBuilder("Resource [")
- .append(resource.toString()).append("] upgraded its ");
-
- if (needsUpgrade(resource.getResourceKey(), resourceKey)) {
- resource.setResourceKey(resourceKey);
- logMessage.append("resourceKey, ");
- }
-
- if (needsUpgrade(resource.getName(), name)) {
- resource.setName(name);
- logMessage.append("name, ");
- }
-
// if (version != null) {
// changed = updateResourceVersion(resource, version) || changed;
// }
-
- if (needsUpgrade(resource.getDescription(), description)) {
- resource.setDescription(description);
- logMessage.append("description, ");
- }
-
+
+ if (allowGenericPropertiesUpgrade &&
needsUpgrade(resource.getDescription(), description)) {
+ resource.setDescription(description);
+ logMessage.append("description, ");
+ }
+ ret.setUpgradedResourceDescription(resource.getDescription());
+
// if (pluginConfiguration != null) {
// if (!equalOrNull(pluginConfiguration,
resource.getPluginConfiguration())) {
// log.info("Resource [" + resource + "] upgraded
its plugin configuration from [" +
@@ -525,16 +537,13 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
// resource.setResourceConfiguration(resourceConfiguration);
// }
// }
-
- logMessage.replace(logMessage.length() - 1, logMessage.length(),
- "to become
[").append(resource.toString()).append("]");
- log.info(logMessage.toString());
-
- return true;
- }
+ logMessage.replace(logMessage.length() - 1, logMessage.length(),
+ "to become
[").append(resource.toString()).append("]");
+
+ log.info(logMessage.toString());
}
- return false;
+ return ret;
}
private void validateInventoryReport(InventoryReport report) throws
InvalidInventoryReportException {
@@ -651,9 +660,21 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
*/
ResourceType resourceType = resource.getResourceType();
Resource parent = resource;
+ Subject overlord = subjectManager.getOverlord();
while (parent != null && existingResource == null) {
parent = parent.getParentResource();
- existingResource =
resourceManager.getResourceByParentAndKey(subjectManager.getOverlord(), parent,
+ //check if the parent itself is inventoried. This might not be the case
+ //during initial sync-up for resource upgrade.
+ Resource existingParent = null;
+ if (parent != null) {
+ existingParent = entityManager.find(Resource.class, parent.getId());
+ if (existingParent == null) {
+ //well, this parent is not known to the server, so there's
no
+ //point in trying to find a child of it...
+ continue;
+ }
+ }
+ existingResource = resourceManager.getResourceByParentAndKey(overlord,
existingParent,
resource.getResourceKey(), resourceType.getPlugin(),
resourceType.getName());
}
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 af518eb..c9208fc 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
@@ -29,6 +29,8 @@ import org.jetbrains.annotations.NotNull;
import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.agent.discovery.InvalidPluginConfigurationClientException;
+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.domain.auth.Subject;
@@ -181,9 +183,11 @@ public interface DiscoveryBossLocal extends DiscoveryBossRemote {
/**
* Upgrades the data of the resources according to the provided reports.
+ * The server is free to ignore or modify the requests and will provide the
+ * true changes made to the resources on the server-side in the result of this
method.
*
- * @param upgradeReports contains the information about the upgrade of individual
resources.
- * @return true if the upgrade succeeded, false otherwise.
+ * @param upgradeRequests contains the information about the upgrade of individual
resources.
+ * @return details on what resources have been upgraded with what data.
*/
- boolean upgradeResources(Set<ResourceUpgradeReport> upgradeReports);
+ Set<ResourceUpgradeResponse> upgradeResources(Set<ResourceUpgradeRequest>
upgradeRequest);
}
\ No newline at end of file
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 0f90cdc..5dbe59a 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
@@ -25,6 +25,8 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
+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;
@@ -177,9 +179,9 @@ public class DiscoveryServerServiceImpl implements
DiscoveryServerService {
return discoveryBoss.updateResourceVersion(resourceId, version);
}
- public boolean upgradeResources(Set<ResourceUpgradeReport> upgradeReports) {
+ public Set<ResourceUpgradeResponse>
upgradeResources(Set<ResourceUpgradeRequest> upgradeRequests) {
DiscoveryBossLocal discoveryBoss = LookupUtil.getDiscoveryBoss();
- return discoveryBoss.upgradeResources(upgradeReports);
+ return discoveryBoss.upgradeResources(upgradeRequests);
}
private static Resource convertToPojoResource(Resource resource, boolean
includeDescendants) {
commit a479fd3591a15b7422b378a000f213a21b9bf750
Merge: ab45b75... f595c48...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Jun 18 21:19:23 2010 +0200
Merge branch 'release-3.0.0' into resource-upgrade
commit ab45b7518ec6b740899c694c3229746cd0490fd6
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Jun 18 20:25:56 2010 +0200
Basic unit tests of the resource upgrade workflow along with some minor changes in the
PC to handle the hardcoded test platform in a normal connected-like scenarios.
diff --git
a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/PluginMetadataManager.java
b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/PluginMetadataManager.java
index 63072db..0c5e0b6 100644
---
a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/PluginMetadataManager.java
+++
b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/PluginMetadataManager.java
@@ -55,7 +55,7 @@ public class PluginMetadataManager {
private Object typesLock = new Object();
private Map<String, PluginMetadataParser> parsersByPlugin = new
HashMap<String, PluginMetadataParser>();
-
+
public PluginMetadataManager() {
}
@@ -177,6 +177,9 @@ public class PluginMetadataManager {
@Nullable
public ResourceType getType(ResourceType resourceType) {
+ if (TEST_PLATFORM_TYPE.equals(resourceType)) {
+ return TEST_PLATFORM_TYPE;
+ }
return getType(resourceType.getName(), resourceType.getPlugin());
}
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 dbee063..1433120 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
@@ -1369,12 +1369,6 @@ public class InventoryManager extends AgentService implements
ContainerService,
resourceContainer.setSynchronizationState(ResourceContainer.SynchronizationState.SYNCHRONIZED);
}
this.resourceContainers.put(resource.getUuid(), resourceContainer);
- if (resource.getParentResource() == null) {
- // no parent - must be the top level platform - do some things needed for
unit tests
- if
(this.platform.getResourceType().equals(PluginMetadataManager.TEST_PLATFORM_TYPE)) {
-
resourceContainer.setResourceComponent(createTestPlatformComponent());
- }
- }
} else {
// container already exists, but make sure the classloader exists too
if (resourceContainer.getResourceClassLoader() == null) {
@@ -1800,6 +1794,13 @@ public class InventoryManager extends AgentService implements
ContainerService,
Set<DiscoveredResourceDetails> allDiscoveredPlatforms = new
HashSet<DiscoveredResourceDetails>(2);
if ((platformTypes != null) && (platformTypes.size() > 0)) {
+
+ //check for fake testing type. If the test platform type is being used, it is
always going to be
+ //the sole platform type available.
+ if (platformTypes.size() == 1 &&
platformTypes.contains(PluginMetadataManager.TEST_PLATFORM_TYPE)) {
+ return getTestPlatform();
+ }
+
// Go through all the platform types that are supported and see if they can
detect our platform.
for (ResourceType platformType : platformTypes) {
try {
@@ -1828,7 +1829,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
.error("Missing platform plugin(s) - falling back to dummy platform
impl; this should only occur in tests!");
// TODO: Set sysprop (e.g. rhq.test.mode=true) in integration tests,
// and throw a runtime exception here if that sysprop is not set.
- return createTestPlatform();
+ return getTestPlatform();
}
if (allDiscoveredPlatforms.isEmpty()) {
@@ -1870,9 +1871,13 @@ public class InventoryManager extends AgentService implements
ContainerService,
* resource. This is normally only used during tests.
* @return A dummy platform for testing purposes only.
*/
- private Resource createTestPlatform() {
+ private Resource getTestPlatform() {
ResourceType type =
PluginContainer.getInstance().getPluginManager().getMetadataManager().addTestPlatformType();
+ if (this.platform != null && this.platform.getResourceType() == type) {
+ return this.platform;
+ }
Resource platform = new Resource("testkey" +
configuration.getContainerName(), "testplatform", type);
+ platform.setUuid(UUID.randomUUID().toString());
platform.setAgent(this.agent);
return platform;
}
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginComponentFactory.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginComponentFactory.java
index 4176353..b9d9cf3 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginComponentFactory.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginComponentFactory.java
@@ -30,6 +30,7 @@ import org.apache.commons.logging.LogFactory;
import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.agent.metadata.PluginMetadataManager;
+import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.pc.ContainerService;
@@ -39,6 +40,7 @@ import org.rhq.core.pc.inventory.InventoryManager;
import org.rhq.core.pc.inventory.ResourceContainer;
import org.rhq.core.pluginapi.inventory.ClassLoaderFacet;
import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
/**
@@ -129,6 +131,19 @@ public class PluginComponentFactory implements ContainerService {
*/
public ResourceComponent buildResourceComponent(Resource resource) throws
PluginContainerException {
ResourceType resourceType = resource.getResourceType();
+ if (PluginMetadataManager.TEST_PLATFORM_TYPE.equals(resourceType)) {
+ return new ResourceComponent() {
+ public AvailabilityType getAvailability() {
+ return AvailabilityType.UP;
+ }
+
+ public void start(ResourceContext context) {
+ }
+
+ public void stop() {
+ }
+ };
+ }
String className =
getPluginManager().getMetadataManager().getComponentClass(resourceType);
ClassLoader resourceClassloader = getResourceClassloader(resource);
ResourceComponent component = (ResourceComponent)
instantiateClass(resourceClassloader, className);
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
new file mode 100644
index 0000000..4341e3a
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
@@ -0,0 +1,272 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.pc.upgrade;
+
+import static org.testng.Assert.fail;
+
+import java.lang.reflect.Field;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.jmock.api.Invocation;
+import org.jmock.lib.action.CustomAction;
+
+import org.rhq.core.clientapi.server.discovery.InventoryReport;
+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.domain.resource.ResourceUpgradeReport;
+
+/**
+ *
+ *
+ * @author Lukas Krejci
+ */
+public class FakeServerInventory {
+
+ private Resource platform;
+ private Map<String, Resource> resourceStore = new HashMap<String,
Resource>();
+ private int counter;
+
+ private static final Comparator<Resource> ID_COMPARATOR = new
Comparator<Resource>() {
+ public int compare(Resource o1, Resource o2) {
+ return o1.getId() - o2.getId();
+ }
+ };
+
+ private static final Comparator<Resource> RESOURCE_TYPE_COMPARATOR = new
Comparator<Resource>() {
+ public int compare(Resource o1, Resource o2) {
+ return o1.getResourceType().equals(o2.getResourceType()) ? 0 : o1.getId() -
o2.getId();
+ }
+ };
+
+ //need to synchronize, because resource upgrade is async and can overlap with
+ //resource discovery.
+ public synchronized CustomAction mergeInventoryReport(final InventoryStatus
requiredInventoryStatus) {
+ return new CustomAction("updateServerSideInventory") {
+ public Object invoke(Invocation invocation) throws Throwable {
+ InventoryReport inventoryReport = (InventoryReport)
invocation.getParameter(0);
+
+ for(Resource res : inventoryReport.getAddedRoots()) {
+ if (res.getParentResource() == Resource.ROOT) {
+ platform = fakePersist(res, requiredInventoryStatus, new
HashSet<String>());
+ break;
+ }
+ }
+ return getSyncInfo();
+ }
+ };
+ }
+
+ public synchronized CustomAction upgradeResources() {
+ return new CustomAction("upgradeServerSideInventory") {
+ @SuppressWarnings({"serial", "unchecked"})
+ public Object invoke(Invocation invocation) throws Throwable {
+ Set<ResourceUpgradeReport> reports =
(Set<ResourceUpgradeReport>) invocation.getParameter(0);
+
+ for (final ResourceUpgradeReport report : reports) {
+ Resource resource = findResource(platform, new Resource() {
+ public int getId() {
+ return report.getResourceId();
+ }
+ }, ID_COMPARATOR);
+ if (resource != null) {
+ if (report.getNewDescription() != null) {
+ resource.setDescription(report.getNewDescription());
+ }
+ if (report.getNewName() != null) {
+ resource.setName(report.getNewName());
+ }
+
+ if (report.getNewResourceKey() != null) {
+ resource.setResourceKey(report.getNewResourceKey());
+ }
+ }
+ }
+ return true;
+ }
+ };
+ }
+
+ public synchronized CustomAction getResources() {
+ return new CustomAction("getResources") {
+ @SuppressWarnings("unchecked")
+ public Object invoke(Invocation invocation) throws Throwable {
+ Set<Integer> resourceIds =
(Set<Integer>)invocation.getParameter(0);
+ boolean includeDescendants = (Boolean) invocation.getParameter(1);
+
+ return getResources(resourceIds, includeDescendants);
+ }
+ };
+ }
+
+ @SuppressWarnings("serial")
+ public synchronized Set<Resource> findResourcesByType(final ResourceType type)
{
+ Set<Resource> result = new HashSet<Resource>();
+ if (platform != null) {
+ findResources(platform, new Resource() {
+ public ResourceType getResourceType() {
+ return type;
+ }
+ }, result, RESOURCE_TYPE_COMPARATOR);
+ }
+ return result;
+ }
+
+ @SuppressWarnings("serial")
+ private Set<Resource> getResources(Set<Integer> resourceIds, boolean
includeDescendants) {
+ Set<Resource> result = new HashSet<Resource>();
+
+ for(final Integer id : resourceIds) {
+ Resource r = findResource(platform, new Resource() {
+ public int getId() {
+ return id;
+ }
+ }, ID_COMPARATOR);
+ if (r != null) {
+ result.add(r);
+
+ if (includeDescendants) {
+ for(Resource child : r.getChildResources()) {
+ result.addAll(getResources(Collections.singleton(child.getId()),
true));
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private Resource fakePersist(Resource agentSideResource, InventoryStatus
requiredInventoryStatus, Set<String> inProgressUUIds) {
+ Resource persisted = resourceStore.get(agentSideResource.getUuid());
+ if (!inProgressUUIds.add(agentSideResource.getUuid())) {
+ return persisted;
+ }
+ if (persisted == null) {
+ persisted = new Resource();
+ persisted.setId(++counter);
+ persisted.setUuid(agentSideResource.getUuid());
+ resourceStore.put(persisted.getUuid(), persisted);
+ }
+ persisted.setAgent(agentSideResource.getAgent());
+ persisted.setCurrentAvailability(agentSideResource.getCurrentAvailability());
+ persisted.setDescription(agentSideResource.getDescription());
+ persisted.setName(agentSideResource.getName());
+
persisted.setPluginConfiguration(agentSideResource.getPluginConfiguration().clone());
+
persisted.setResourceConfiguration(agentSideResource.getResourceConfiguration().clone());
+ persisted.setVersion(agentSideResource.getVersion());
+ persisted.setInventoryStatus(requiredInventoryStatus);
+ persisted.setResourceKey(agentSideResource.getResourceKey());
+ persisted.setResourceType(agentSideResource.getResourceType());
+
+ Resource parent = agentSideResource.getParentResource();
+ if (parent != null && parent != Resource.ROOT) {
+
persisted.setParentResource(fakePersist(agentSideResource.getParentResource(),
requiredInventoryStatus, inProgressUUIds));
+ } else {
+ persisted.setParentResource(parent);
+ }
+
+ Set<Resource> childResources = new HashSet<Resource>();
+ persisted.setChildResources(childResources);
+ for(Resource child : agentSideResource.getChildResources()) {
+ childResources.add(fakePersist(child, requiredInventoryStatus,
inProgressUUIds));
+ }
+
+ inProgressUUIds.remove(agentSideResource.getUuid());
+
+ return persisted;
+ }
+
+ private ResourceSyncInfo getSyncInfo() {
+ return platform != null ? convert(platform) : null;
+ }
+
+ private static ResourceSyncInfo convert(Resource root) {
+ try {
+ ResourceSyncInfo ret = new ResourceSyncInfo();
+
+ Class<ResourceSyncInfo> clazz = ResourceSyncInfo.class;
+
+ getPrivateField(clazz, "id").set(ret, root.getId());
+ getPrivateField(clazz, "uuid").set(ret, root.getUuid());
+ getPrivateField(clazz, "mtime").set(ret, root.getMtime());
+ getPrivateField(clazz, "inventoryStatus").set(ret,
root.getInventoryStatus());
+ getPrivateField(clazz, "parent").set(ret, null);
+
+ Set<ResourceSyncInfo> children = new
LinkedHashSet<ResourceSyncInfo>();
+ for(Resource child : root.getChildResources()) {
+ ResourceSyncInfo syncChild = convert(child);
+ getPrivateField(clazz, "parent").set(syncChild, ret);
+
+ children.add(convert(child));
+ }
+ getPrivateField(clazz, "childSyncInfos").set(ret, children);
+
+ return ret;
+ } catch (Exception e) {
+ fail("Failed to convert resource " + root + " to a
ResourceSyncInfo. This should not happen.", e);
+ return null;
+ }
+ }
+
+ private static Field getPrivateField(Class<?> clazz, String fieldName) throws
NoSuchFieldException {
+ Field field = clazz.getDeclaredField(fieldName);
+ if (!field.isAccessible()) {
+ field.setAccessible(true);
+ }
+
+ return field;
+ }
+
+ private static Resource findResource(Resource root, Resource template,
Comparator<Resource> comparator) {
+ if (root == null) return null;
+ if (comparator.compare(root, template) == 0) {
+ return root;
+ } else {
+ for(Resource child : root.getChildResources()) {
+ Resource found = findResource(child, template, comparator);
+ if (found != null) return found;
+ }
+ }
+
+ return null;
+ }
+
+ private static void findResources(Resource root, Resource template,
Set<Resource> result, Comparator<Resource> comparator) {
+ if (root == null) return;
+ if (comparator.compare(root, template) == 0) {
+ result.add(root);
+ } else {
+ for(Resource child : root.getChildResources()) {
+ findResources(child, template, result, comparator);
+ }
+ }
+ }
+}
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
new file mode 100644
index 0000000..46d069c
--- /dev/null
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -0,0 +1,345 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.pc.upgrade;
+
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertEquals;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Set;
+
+import org.apache.commons.io.FileUtils;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import org.rhq.core.clientapi.server.bundle.BundleServerService;
+import org.rhq.core.clientapi.server.configuration.ConfigurationServerService;
+import org.rhq.core.clientapi.server.content.ContentServerService;
+import org.rhq.core.clientapi.server.core.CoreServerService;
+import org.rhq.core.clientapi.server.discovery.DiscoveryServerService;
+import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.clientapi.server.event.EventServerService;
+import org.rhq.core.clientapi.server.inventory.ResourceFactoryServerService;
+import org.rhq.core.clientapi.server.measurement.MeasurementServerService;
+import org.rhq.core.clientapi.server.operation.OperationServerService;
+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.ServerServices;
+import org.rhq.core.pc.inventory.InventoryManager;
+import org.rhq.core.pc.inventory.ResourceContainer;
+import org.rhq.core.pc.plugin.FileSystemPluginFinder;
+
+/**
+ * Test cases for resource upgrade.
+ *
+ * @author Lukas Krejci
+ */
+public class ResourceUpgradeTest {
+
+ private static final String PLUGIN_V1_FILENAME =
"resource-upgrade-test-plugin-1.0.0.jar";
+ private static final String PLUGIN_V2_FILENAME =
"resource-upgrade-test-plugin-2.0.0.jar";
+
+ private static final String PLUGINS_DIR_NAME = "plugins";
+ private static final String DATA_DIR_NAME = "data";
+ private static final String TMP_DIR_NAME = "tmp";
+
+ private File tmpDir;
+ private File pluginDir;
+ private File dataDir;
+
+ private BundleServerService currentBundleServerService;
+ private ConfigurationServerService currentConfigurationServerService;
+ private ContentServerService currentContentServerService;
+ private CoreServerService currentCoreServerService;
+ private DiscoveryServerService currentDiscoveryServerService;
+ private EventServerService currentEventServerService;
+ private MeasurementServerService currentMeasurementServerService;
+ private OperationServerService currentOperationServerService;
+ private ResourceFactoryServerService currentResourceFactoryServerService;
+
+ private FakeServerInventory currentServerSideInventory;
+
+ @AfterClass
+ public void undeployPlugins() throws IOException {
+ FileUtils.deleteDirectory(tmpDir);
+ }
+
+ @BeforeClass
+ public void sanityCheck() {
+ verifyPluginExists(PLUGIN_V1_FILENAME);
+ verifyPluginExists(PLUGIN_V2_FILENAME);
+ }
+
+ @BeforeClass
+ public void init() {
+ tmpDir = getTmpDirectory();
+ pluginDir = new File(tmpDir, PLUGINS_DIR_NAME);
+ assertTrue(pluginDir.mkdir(), "Could not create plugin deploy
directory.");
+ dataDir = new File(tmpDir, DATA_DIR_NAME);
+ assertTrue(dataDir.mkdir(), "Could not create plugin container data
directory.");
+ }
+
+ @Test
+ public void testInitialSyncAndDiscoveryWithoutCommit() throws Exception {
+ testInitialSyncAndDiscovery(InventoryStatus.NEW);
+ }
+
+ @Test(dependsOnMethods = "testInitialSyncAndDiscoveryWithoutCommit")
+ public void testIgnoreUncommittedResources() throws Exception {
+ TestPayload testNoChange = new TestPayload() {
+ public void test(Resource discoveredResource) {
+ assertEquals(discoveredResource.getResourceKey(),
"resource-key-v1");
+ assertEquals(discoveredResource.getName(),
"resource-name-v1");
+ assertEquals(discoveredResource.getDescription(),
"resource-description-v1");
+ }
+
+ @SuppressWarnings("unchecked")
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineIgnoredExpectations(this);
+
+ between(1,
4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
+
will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+
+
allowing(currentDiscoveryServerService).getResources(with(any(Set.class)),
with(any(boolean.class)));
+ will(currentServerSideInventory.getResources());
+ }
+ };
+ }
+ };
+
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false,
testNoChange);
+ }
+
+ //make the tests run serially, so that they don't overwrite the
currentServerSideInventory
+ //variable concurrently
+ @Test(dependsOnMethods = "testIgnoreUncommittedResources")
+ public void testInitialSyncAndDiscoveryWithCommit() throws Exception {
+ testInitialSyncAndDiscovery(InventoryStatus.COMMITTED);
+ }
+
+ @Test(dependsOnMethods = "testInitialSyncAndDiscoveryWithCommit")
+ public void testUpgradeData() throws Exception {
+ //we are keeping the currentServerSideInventory from the previous test
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, new
TestPayload() {
+ public void test(Resource discoveredResource) {
+ assertEquals(discoveredResource.getResourceKey(),
"resource-key-v2");
+ assertEquals(discoveredResource.getName(),
"resource-name-v2");
+ assertEquals(discoveredResource.getDescription(),
"resource-description-v2");
+
+ ResourceContainer container =
PluginContainer.getInstance().getInventoryManager().getResourceContainer(discoveredResource);
+ File dataDir = container.getResourceContext().getDataDirectory();
+
+ File marker = new File(dataDir, "upgrade-succeeded");
+
+ assertTrue(marker.exists(), "The upgrade success marker file
wasn't found. This means the upgrade didn't actually run.");
+ }
+
+ @SuppressWarnings("unchecked")
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineIgnoredExpectations(this);
+
+ between(1,
4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
+
will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+
+
oneOf(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
+ will(currentServerSideInventory.upgradeResources());
+
+
allowing(currentDiscoveryServerService).getResources(with(any(Set.class)),
with(any(boolean.class)));
+ will(currentServerSideInventory.getResources());
+ }
+ };
+ }
+ });
+ }
+
+ private void testInitialSyncAndDiscovery(final InventoryStatus
requiredInventoryStatus) throws Exception {
+ currentServerSideInventory = new FakeServerInventory();
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), true, new
TestPayload() {
+ public void test(Resource discoveredResource) {
+ assertEquals(discoveredResource.getResourceKey(),
"resource-key-v1");
+ assertEquals(discoveredResource.getName(),
"resource-name-v1");
+ assertEquals(discoveredResource.getDescription(),
"resource-description-v1");
+ }
+
+ @SuppressWarnings("unchecked")
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineIgnoredExpectations(this);
+
+ between(1,
4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
+
will(currentServerSideInventory.mergeInventoryReport(requiredInventoryStatus));
+
+
allowing(currentDiscoveryServerService).getResources(with(any(Set.class)),
with(any(boolean.class)));
+ will(currentServerSideInventory.getResources());
+ }
+ };
+ }
+ });
+
+ }
+
+ private PluginContainerConfiguration createPluginContainerConfiguration(Mockery
context) throws Exception {
+ PluginContainerConfiguration conf = new PluginContainerConfiguration();
+
+ conf.setPluginDirectory(new File(tmpDir, PLUGINS_DIR_NAME));
+ conf.setDataDirectory(new File(tmpDir, DATA_DIR_NAME));
+ conf.setTemporaryDirectory(new File(tmpDir, TMP_DIR_NAME));
+ conf.setInsideAgent(true); //pc must think it's inside an agent so that it
persists the inventory between restarts
+ conf.setPluginFinder(new FileSystemPluginFinder(conf.getPluginDirectory()));
+ conf.setCreateResourceClassloaders(false);
+
+ currentBundleServerService = context.mock(BundleServerService.class);
+ currentConfigurationServerService =
context.mock(ConfigurationServerService.class);
+ currentContentServerService = context.mock(ContentServerService.class);
+ currentCoreServerService = context.mock(CoreServerService.class);
+ currentDiscoveryServerService = context.mock(DiscoveryServerService.class);
+ currentEventServerService = context.mock(EventServerService.class);
+ currentMeasurementServerService = context.mock(MeasurementServerService.class);
+ currentOperationServerService = context.mock(OperationServerService.class);
+ currentResourceFactoryServerService =
context.mock(ResourceFactoryServerService.class);
+
+ ServerServices serverServices = new ServerServices();
+ serverServices.setBundleServerService(currentBundleServerService);
+ serverServices.setConfigurationServerService(currentConfigurationServerService);
+ serverServices.setContentServerService(currentContentServerService);
+ serverServices.setCoreServerService(currentCoreServerService);
+ serverServices.setDiscoveryServerService(currentDiscoveryServerService);
+ serverServices.setEventServerService(currentEventServerService);
+ serverServices.setMeasurementServerService(currentMeasurementServerService);
+ serverServices.setOperationServerService(currentOperationServerService);
+
serverServices.setResourceFactoryServerService(currentResourceFactoryServerService);
+
+ conf.setServerServices(serverServices);
+
+ return conf;
+ }
+
+ /**
+ * @param pluginResourcePath
+ */
+ private void verifyPluginExists(String pluginResourcePath) {
+ URL url = getClass().getResource(pluginResourcePath);
+
+ File pluginFile = FileUtils.toFile(url);
+
+ assertTrue(pluginFile.exists(), pluginFile.getAbsoluteFile() + " plugin jar
could not be found.");
+ }
+
+ private void copyPlugin(String pluginResourcePath, File pluginDirectory) throws
IOException {
+ URL pluginUrl = getClass().getResource(pluginResourcePath);
+
+ File pluginFile = new File(pluginResourcePath);
+ String pluginFileName = pluginFile.getName();
+
+ FileUtils.copyURLToFile(pluginUrl, new File(pluginDirectory, pluginFileName));
+ }
+
+ private static File getTmpDirectory() {
+ File ret = new File(System.getProperty("java.io.tmpdir"),
"resource-upgrade-test" + System.currentTimeMillis());
+
+ while (ret.exists() || !ret.mkdir()) {
+ ret = new File(System.getProperty("java.io.tmpdir"),
"resource-upgrade-test" + System.currentTimeMillis());
+ }
+
+ return ret;
+ }
+
+ private interface TestPayload {
+ Expectations getExpectations(Mockery context) throws Exception;
+ void test(Resource resourceUpgradeTestResource);
+ }
+
+ private Set<Resource> getTestingResources() {
+ ResourceType resType =
PluginContainer.getInstance().getPluginManager().getMetadataManager().getType("Resource",
"ResourceUpgradeTest");
+
+ return currentServerSideInventory.findResourcesByType(resType);
+ }
+
+ private void executeTestWithPlugins(Set<String> pluginResourcePaths, boolean
clearInventoryDat, TestPayload test) throws Exception {
+ FileUtils.cleanDirectory(new File(tmpDir, PLUGINS_DIR_NAME));
+
+ for(String pluginResourcePath : pluginResourcePaths) {
+ copyPlugin(pluginResourcePath, pluginDir);
+ }
+
+ Mockery context = new Mockery();
+
+ PluginContainerConfiguration pcConfig =
createPluginContainerConfiguration(context);
+
+ if (clearInventoryDat) {
+ File inventoryDat = new File(pcConfig.getDataDirectory(),
"inventory.dat");
+ inventoryDat.delete();
+ }
+
+ context.checking(test.getExpectations(context));
+
+ PluginContainer.getInstance().setConfiguration(pcConfig);
+ PluginContainer.getInstance().initialize();
+
+ //give the pc the time to finish resource upgrade
+ Thread.sleep(1000);
+
+ //execute full discovery
+ InventoryManager im = PluginContainer.getInstance().getInventoryManager();
+ im.executeServerScanImmediately();
+ im.executeServiceScanImmediately();
+
+ Set<Resource> resources = getTestingResources();
+
+ assertEquals(resources.size(), 1, "There should be only a single testing
resource but " + resources + " were found.");
+
+ Resource discoveredResource = resources.iterator().next();
+
+ test.test(discoveredResource);
+
+ PluginContainer.getInstance().shutdown();
+
+ context.assertIsSatisfied();
+ }
+
+ private void defineIgnoredExpectations(Expectations expectations) {
+ expectations.ignoring(currentBundleServerService);
+ expectations.ignoring(currentConfigurationServerService);
+ expectations.ignoring(currentContentServerService);
+ expectations.ignoring(currentCoreServerService);
+ expectations.ignoring(currentEventServerService);
+ expectations.ignoring(currentMeasurementServerService);
+ expectations.ignoring(currentOperationServerService);
+ expectations.ignoring(currentResourceFactoryServerService);
+ }
+}
diff --git
a/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-1.0.0.jar
b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-1.0.0.jar
new file mode 100644
index 0000000..33a79c0
Binary files /dev/null and
b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-1.0.0.jar
differ
diff --git
a/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar
b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar
new file mode 100644
index 0000000..412ae00
Binary files /dev/null and
b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar
differ
commit 8dae62e89bc703cf2b8e16272b8d9ebc912606dd
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Jun 18 20:22:33 2010 +0200
Correctly handle the upgrade sync up when the agent is connected to the server for the
very first time.
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 54c6bcc..dbee063 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
@@ -900,7 +900,6 @@ public class InventoryManager extends AgentService implements
ContainerService,
*/
public boolean handleReport(InventoryReport report, boolean forceServerRoundtrip) {
if (!configuration.isInsideAgent()) {
- //TODO how does resource upgrade behave in the embedded scenario?
return true;
}
@@ -943,7 +942,14 @@ public class InventoryManager extends AgentService implements
ContainerService,
return false;
}
- synchInventory(syncInfo);
+ //sync info can be null if the server hasn't received a full inventory
report
+ //from us yet. This can happen if this method is being invoked from inside the
+ //resource upgrade executor to sync up with the server side inventory *JUST
AFTER*
+ //this agent registered with the server for the very first time. In that case
+ //the server hasn't received any info from us yet.
+ if (syncInfo != null) {
+ synchInventory(syncInfo);
+ }
return true;
}
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 76d6265..fd59590 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
@@ -156,7 +156,13 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
// Prepare the ResourceSyncInfo tree which contains all the info the PC needs to
sync itself up with us.
Resource platform = this.resourceManager.getPlatform(knownAgent);
- ResourceSyncInfo syncInfo = this.entityManager.find(ResourceSyncInfo.class,
platform.getId());
+
+ //the platform can be null in only one scenario.. a brand new agent has connected
to the server
+ //and that agent is currently trying to upgrade its resources. For that it asks
us to send down
+ //the current inventory on the server side. But at this point there isn't any
since that very
+ //agent just registered and is starting up for the very first time and therefore
hasn't had
+ //a chance yet to send us its full inventory report.
+ ResourceSyncInfo syncInfo = platform != null ?
this.entityManager.find(ResourceSyncInfo.class, platform.getId()) : null;
if (log.isDebugEnabled()) {
log.debug("Inventory merge completed in (" +
(System.currentTimeMillis() - start) + ")ms");
commit a9622206993586ce28df9e586206cbf981cc7c3b
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri May 28 18:09:24 2010 +0200
Filter out not-commited resources from the upgrade process.
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
index 3397e76..bb20054 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
@@ -26,6 +26,7 @@ package org.rhq.core.pc.upgrade;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -37,6 +38,7 @@ import org.apache.commons.logging.LogFactory;
import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
+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.resource.ResourceUpgradeReport;
@@ -203,6 +205,15 @@ public class ResourceUpgradeExecutor implements Runnable {
Set<Resource> siblings = parentResource == null ?
Collections.singleton(inventoryManager.getPlatform())
: inventoryManager.getResourcesWithType(resourceType,
parentResource.getChildResources());
+ //filter out not committed resources
+ //XXX what about uninventoried or ignored ones? is it correct to not
upgrade those?
+ Iterator<Resource> siblingsIterator = siblings.iterator();
+ while (siblingsIterator.hasNext()) {
+ if (siblingsIterator.next().getInventoryStatus() !=
InventoryStatus.COMMITTED) {
+ siblingsIterator.remove();
+ }
+ }
+
//get the upgrade context of the parent resource so that it can be passed
to the upgrade method
//of the discovery component.
ResourceUpgradeContext<?> parentUpgradeContext = null;
commit df4ffc41f2554332ba870eaeb69e20017ea25240
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri May 28 18:08:53 2010 +0200
Improve resource upgrade logging on both agent and server side.
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 ba5f316..54c6bcc 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
@@ -1194,36 +1194,50 @@ public class InventoryManager extends AgentService implements
ContainerService,
//Configuration pluginConfiguration =
upgradeReport.getNewPluginConfiguration();
//Configuration resourceConfiguration =
upgradeReport.getNewResourceConfiguration();
- ResourceContainer existingResourceContainer =
getResourceContainer(upgradeReport.getResourceId());
- if (existingResourceContainer != null) {
- Resource existingResource = existingResourceContainer.getResource();
- if (resourceKey != null) {
- existingResource.setResourceKey(resourceKey);
- }
-
- if (name != null) {
- existingResource.setName(name);
- }
-
-// if (version != null) {
-// existingResource.setVersion(version);
-// }
-
- if (description != null) {
- existingResource.setDescription(description);
+ //only bother if there's something to upgrade at all on this
resource.
+ if (resourceKey != null || name != null || description != null) {
+ ResourceContainer existingResourceContainer =
getResourceContainer(upgradeReport.getResourceId());
+ if (existingResourceContainer != null) {
+ Resource existingResource =
existingResourceContainer.getResource();
+
+ StringBuilder logMessage = new StringBuilder("Resource
[")
+ .append(existingResource.toString()).append("] upgraded
its ");
+
+ if (resourceKey != null) {
+ existingResource.setResourceKey(resourceKey);
+ logMessage.append("resourceKey, ");
+ }
+
+ if (name != null) {
+ existingResource.setName(name);
+ logMessage.append("name, ");
+ }
+
+// if (version != null) {
+// existingResource.setVersion(version);
+// }
+
+ if (description != null) {
+ existingResource.setDescription(description);
+ logMessage.append("description, ");
+ }
+
+// if (pluginConfiguration != null) {
+//
existingResource.setPluginConfiguration(pluginConfiguration);
+// }
+//
+// if (resourceConfiguration != null) {
+//
existingResource.setResourceConfiguration(resourceConfiguration);
+// }
+
+ logMessage.replace(logMessage.length() - 1, logMessage.length(),
+ "to become
[").append(existingResource.toString()).append("]");
+
+ log.info(logMessage.toString());
+ } else {
+ log.error("Upgraded a resource that is not present on the
agent. This should not happen. The id of the missing resource is " +
upgradeReport.getResourceId());
}
-
-// if (pluginConfiguration != null) {
-// existingResource.setPluginConfiguration(pluginConfiguration);
-// }
-//
-// if (resourceConfiguration != null) {
-//
existingResource.setResourceConfiguration(resourceConfiguration);
-// }
- } else {
- log.error("Upgraded a resource that is not present on the agent.
This should not happen. The id of the missing resource is " +
upgradeReport.getResourceId());
}
-
}
}
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 1101199..76d6265 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
@@ -465,65 +465,70 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
/**
* @param existingResource
* @param upgradeReport
- * @return
+ * @return true if the resource was changed, false otherwise
*/
private boolean upgradeResource(Resource resource, ResourceUpgradeReport
upgradeReport) {
- boolean changed = false;
if (resource != null) {
String resourceKey = upgradeReport.getNewResourceKey();
String name = upgradeReport.getNewName();
- //String version = upgradeReport.getNewVersion();
+// String version = upgradeReport.getNewVersion();
String description = upgradeReport.getNewDescription();
// Configuration pluginConfiguration =
upgradeReport.getNewPluginConfiguration();
// Configuration resourceConfiguration =
upgradeReport.getNewResourceConfiguration();
- if (needsUpgrade(resource.getResourceKey(), resourceKey)) {
- log.info("Resource [" + resource + "] upgraded its
resource key from [" +
- resource.getResourceKey() + "] to [" + resourceKey +
"]");
- changed = true;
- resource.setResourceKey(resourceKey);
- }
-
- if (needsUpgrade(resource.getName(), name)) {
- log.info("Resource [" + resource + "] upgraded its name
from [" +
- resource.getName() + "] to [" + name + "]");
- changed = true;
- resource.setName(name);
- }
-
-// if (version != null) {
-// changed = updateResourceVersion(resource, version) || changed;
-// }
-
- if (needsUpgrade(resource.getDescription(), description)) {
- log.info("Resource [" + resource + "] upgraded its
description from [" +
- resource.getDescription() + "] to [" + description +
"]");
- changed = true;
- resource.setDescription(description);
- }
-
-// if (pluginConfiguration != null) {
-// if (!equalOrNull(pluginConfiguration,
resource.getPluginConfiguration())) {
-// log.info("Resource [" + resource + "] upgraded its
plugin configuration from [" +
-// resource.getPluginConfiguration() + "] to [" +
pluginConfiguration + "]");
-// changed = true;
-// resource.setPluginConfiguration(pluginConfiguration);
+ if (resourceKey != null || name != null || description != null) {
+ StringBuilder logMessage = new StringBuilder("Resource [")
+ .append(resource.toString()).append("] upgraded its ");
+
+ if (needsUpgrade(resource.getResourceKey(), resourceKey)) {
+ resource.setResourceKey(resourceKey);
+ logMessage.append("resourceKey, ");
+ }
+
+ if (needsUpgrade(resource.getName(), name)) {
+ resource.setName(name);
+ logMessage.append("name, ");
+ }
+
+// if (version != null) {
+// changed = updateResourceVersion(resource, version) || changed;
// }
-// }
-//
-// if (resourceConfiguration != null) {
-// if (!equalOrNull(resourceConfiguration,
resource.getResourceConfiguration())) {
-// //XXX Will this create a new history entry?
-//
-// log.info("Resource [" + resource + "] upgraded its
resource configuration from [" +
-// resource.getResourceConfiguration() + "] to [" +
resourceConfiguration + "]");
-//
-// changed = true;
-// resource.setResourceConfiguration(resourceConfiguration);
+
+ if (needsUpgrade(resource.getDescription(), description)) {
+ resource.setDescription(description);
+ logMessage.append("description, ");
+ }
+
+// if (pluginConfiguration != null) {
+// if (!equalOrNull(pluginConfiguration,
resource.getPluginConfiguration())) {
+// log.info("Resource [" + resource + "] upgraded
its plugin configuration from [" +
+// resource.getPluginConfiguration() + "] to [" +
pluginConfiguration + "]");
+// changed = true;
+// resource.setPluginConfiguration(pluginConfiguration);
+// }
// }
-// }
+//
+// if (resourceConfiguration != null) {
+// if (!equalOrNull(resourceConfiguration,
resource.getResourceConfiguration())) {
+// //XXX Will this create a new history entry?
+//
+// log.info("Resource [" + resource + "] upgraded
its resource configuration from [" +
+// resource.getResourceConfiguration() + "] to [" +
resourceConfiguration + "]");
+//
+// changed = true;
+// resource.setResourceConfiguration(resourceConfiguration);
+// }
+// }
+
+ logMessage.replace(logMessage.length() - 1, logMessage.length(),
+ "to become
[").append(resource.toString()).append("]");
+
+ log.info(logMessage.toString());
+
+ return true;
+ }
}
- return changed;
+ return false;
}
private void validateInventoryReport(InventoryReport report) throws
InvalidInventoryReportException {
@@ -875,18 +880,6 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
updateInventoryStatus(subject, platforms, servers, target);
}
- private static <T> boolean equalOrNull(T a, T b) {
- if (a == null) {
- return b == null;
- } else {
- if (b == null) {
- return false;
- } else {
- return a.equals(b);
- }
- }
- }
-
private static <T> boolean needsUpgrade(T oldValue, T newValue) {
return newValue != null && (oldValue == null ||
!newValue.equals(oldValue));
}
commit d896c3792ebf8b45938972eb2ff2f45bd990be83
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri May 28 18:08:16 2010 +0200
Run a method in a new thread only if it originates in the interface that is being
proxied.
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/DiscoveryComponentProxyFactory.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/DiscoveryComponentProxyFactory.java
index f8d1267..4c68970 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/DiscoveryComponentProxyFactory.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/DiscoveryComponentProxyFactory.java
@@ -81,7 +81,7 @@ public class DiscoveryComponentProxyFactory {
// This is the handler that will actually invoke the method calls.
ResourceDiscoveryComponentInvocationHandler handler = new
ResourceDiscoveryComponentInvocationHandler(type,
- component, timeout, pluginClassLoader);
+ component, timeout, pluginClassLoader, componentInterface);
// This is the proxy that will look like the discovery component object that
the caller will use.
T proxy = (T) Proxy.newProxyInstance(pluginClassLoader, new Class<?>[]
{ componentInterface }, handler);
@@ -167,9 +167,10 @@ public class DiscoveryComponentProxyFactory {
private final long timeout;
private final ResourceType resourceType;
private final ClassLoader pluginClassLoader;
-
+ private Class<?> componentInterface;
+
public ResourceDiscoveryComponentInvocationHandler(ResourceType type,
ResourceDiscoveryComponent component,
- long timeout, ClassLoader pluginClassLoader) {
+ long timeout, ClassLoader pluginClassLoader, Class<?>
componentInterface) {
if (timeout <= 0) {
throw new IllegalArgumentException("timeout value is not
positive.");
}
@@ -181,6 +182,7 @@ public class DiscoveryComponentProxyFactory {
this.component = component;
this.timeout = timeout;
this.pluginClassLoader = pluginClassLoader;
+ this.componentInterface = componentInterface;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
@@ -189,7 +191,7 @@ public class DiscoveryComponentProxyFactory {
+ "] has been blacklisted and can no longer be invoked.");
}
- if
(method.getDeclaringClass().getPackage().getName().startsWith("org.rhq")) {
+ if (componentInterface.isAssignableFrom(method.getDeclaringClass())) {
return invokeInNewThread(method, args);
} else {
// toString(), etc.
commit 708dee442c2519ecc9d27c723e79239b14b25455
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu May 27 19:04:32 2010 +0200
Fixing a stupid bug that would cause no initial sync to happen during upgrade.
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 83743d9..ba5f316 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
@@ -883,13 +883,22 @@ public class InventoryManager extends AgentService implements
ContainerService,
}
/**
+ * @see #handleReport(InventoryReport, boolean)
+ * @param report
+ * @return
+ */
+ public boolean handleReport(InventoryReport report) {
+ return handleReport(report, false);
+ }
+
+ /**
* Send an inventory report to the Server.
*
* @param report the inventory report to be sent
- *
+ * @param forceServerRoundtrip whether to report to the server even if there are no
resources to report.
* @return true if sending the report to the Server succeeded, or false otherwise
*/
- public boolean handleReport(InventoryReport report) {
+ public boolean handleReport(InventoryReport report, boolean forceServerRoundtrip) {
if (!configuration.isInsideAgent()) {
//TODO how does resource upgrade behave in the embedded scenario?
return true;
@@ -905,7 +914,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
resourceUpgradeExecutor.sendRequests();
}
- if (report.getAddedRoots().isEmpty()) {
+ if (report.getAddedRoots().isEmpty() && !forceServerRoundtrip) {
return true; // nothing to do
}
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
index f0721cb..3397e76 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
@@ -130,7 +130,7 @@ public class ResourceUpgradeExecutor implements Runnable {
//pull the inventory down from the server.
//this will ensure that we have an up-to-date info on the
//server inventory before we try to upgrade.
- boolean syncResult = inventoryManager.handleReport(new
InventoryReport(inventoryManager.getAgent()));
+ boolean syncResult = inventoryManager.handleReport(new
InventoryReport(inventoryManager.getAgent()), true);
if (!syncResult) {
log.warn("Resource upgrade failed to sync up the inventory with
the server.");
return;
commit c9b82d93170e03e564ef2db2c50a007f4d1176dc
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu May 27 18:39:32 2010 +0200
Make the ResourceUpgradeExecutor thread safe (even though it probably shouldn't
have to be) and make sure it can only be run once.
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 21da6bc..4d61e93 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
@@ -264,7 +264,7 @@ public class PluginContainer implements ContainerService {
//fire off the resource upgrade as soon as possible. It will run only once per
plugin container
//lifetime.
- inventoryManager.executeResourceUpgradeImmediately();
+ inventoryManager.fireResourceUpgrade();
return;
}
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 7fcfd6e..83743d9 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
@@ -507,8 +507,13 @@ public class InventoryManager extends AgentService implements
ContainerService,
}
}
- public void executeResourceUpgradeImmediately() {
- resourceUpgradeExecutor.execute();
+ /**
+ * Executes the resource upgrade asynchronously.
+ */
+ public void fireResourceUpgrade() {
+ Thread resourceUpgradeThread = new Thread(resourceUpgradeExecutor, "Resource
Upgrade Thread");
+ resourceUpgradeThread.setDaemon(true);
+ resourceUpgradeThread.start();
}
public InventoryReport executeServerScanImmediately() {
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
index d15a1c2..f0721cb 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
@@ -27,9 +27,10 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
-import java.util.Queue;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -55,21 +56,22 @@ import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
*
* @author Lukas Krejci
*/
-public class ResourceUpgradeExecutor {
+public class ResourceUpgradeExecutor implements Runnable {
private static final Log log = LogFactory.getLog(ResourceUpgradeExecutor.class);
/**
* The upgrade runs only once in its lifetime.
*/
- private boolean enabled = true;
-
+ private AtomicBoolean enabled = new AtomicBoolean(true);
+ private AtomicBoolean started = new AtomicBoolean(false);
+
private InventoryManager inventoryManager;
- private Set<ResourceUpgradeReport> reports;
+ private ConcurrentLinkedQueue<ResourceUpgradeReport> reports;
public ResourceUpgradeExecutor(InventoryManager inventoryManager) {
this.inventoryManager = inventoryManager;
- reports = new HashSet<ResourceUpgradeReport>();
+ reports = new ConcurrentLinkedQueue<ResourceUpgradeReport>();
}
/**
@@ -90,14 +92,14 @@ public class ResourceUpgradeExecutor {
public <T extends ResourceComponent> Map<ResourceUpgradeContext<T>,
ResourceUpgradeReport> processAndQueue(
ResourceUpgradeRequest<T> request, Set<Resource> discoveredResources)
{
- return enabled ? executeResourceUpgradeAndStoreReport(request,
discoveredResources) : null;
+ return enabled.get() ? executeResourceUpgradeAndStoreReport(request,
discoveredResources) : null;
}
/**
* @return true if the executor is ready to perform the upgrade, false otherwise.
*/
public boolean isEnabled() {
- return enabled;
+ return enabled.get();
}
/**
@@ -105,9 +107,10 @@ public class ResourceUpgradeExecutor {
* all the upgrade requests.
*/
public void sendRequests() {
- if (enabled && reports.size() > 0) {
- inventoryManager.mergeResourceFromUpgrade(reports);
- reports.clear();
+ if (enabled.get() && reports.size() > 0) {
+ HashSet<ResourceUpgradeReport> currentCopy = new
HashSet<ResourceUpgradeReport>(reports);
+ inventoryManager.mergeResourceFromUpgrade(currentCopy);
+ reports.removeAll(currentCopy);
}
}
@@ -117,8 +120,8 @@ public class ResourceUpgradeExecutor {
* After that a full discovery is performed and both the upgrade report and discovery
report
* are sent to the server.
*/
- public void execute() {
- if (enabled) {
+ public void run() {
+ if (!started.getAndSet(true)) {
if (log.isDebugEnabled()) {
log.debug("Starting resource upgrade.");
}
@@ -140,7 +143,7 @@ public class ResourceUpgradeExecutor {
log.warn("Resource upgrade failed.", t);
} finally {
//make sure to switch off the upgrade...
- this.enabled = false;
+ this.enabled.set(false);
//clear up so that we don't hold unnecessary instances.
reports.clear();
commit 760871c264eca5adf2cf322a48614b3cd68a3640
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu May 27 18:11:49 2010 +0200
Avoid deadlock by invoking the resource upgrade only after all services are
initialized, removing the ability to perform plugin/resource configuration upgrades,
generally made stuff work.
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
index bfeba0d..979c456 100644
---
a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
@@ -44,9 +44,18 @@ public class ResourceUpgradeReport implements Serializable {
private int resourceId;
private String newResourceKey;
private String newName;
- private String newVersion;
- private Configuration newPluginConfiguration;
- private Configuration newResourceConfiguration;
+
+// version changes are handled differently.
+// private String newVersion;
+
+// upgrading configurations would have large consequences.
+// it would be difficult to synchronize the upgrade process
+// with the agent or server initiated configuration updates.
+// It could also be difficult for the UI to reflect more complicated
+// structural changes as currently, it is assumed that
+// the configurations are kept backwards compatible.
+// private Configuration newPluginConfiguration;
+// private Configuration newResourceConfiguration;
private String newDescription;
public ResourceUpgradeReport() {
@@ -85,29 +94,29 @@ public class ResourceUpgradeReport implements Serializable {
this.newName = newName;
}
- public String getNewVersion() {
- return newVersion;
- }
-
- public void setNewVersion(String newVersion) {
- this.newVersion = newVersion;
- }
-
- public Configuration getNewPluginConfiguration() {
- return newPluginConfiguration;
- }
-
- public void setNewPluginConfiguration(Configuration newPluginConfiguration) {
- this.newPluginConfiguration = newPluginConfiguration;
- }
-
- public Configuration getNewResourceConfiguration() {
- return newResourceConfiguration;
- }
-
- public void setNewResourceConfiguration(Configuration newResourceConfiguration) {
- this.newResourceConfiguration = newResourceConfiguration;
- }
+// public String getNewVersion() {
+// return newVersion;
+// }
+//
+// public void setNewVersion(String newVersion) {
+// this.newVersion = newVersion;
+// }
+//
+// public Configuration getNewPluginConfiguration() {
+// return newPluginConfiguration;
+// }
+//
+// public void setNewPluginConfiguration(Configuration newPluginConfiguration) {
+// this.newPluginConfiguration = newPluginConfiguration;
+// }
+//
+// public Configuration getNewResourceConfiguration() {
+// return newResourceConfiguration;
+// }
+//
+// public void setNewResourceConfiguration(Configuration newResourceConfiguration) {
+// this.newResourceConfiguration = newResourceConfiguration;
+// }
public String getNewDescription() {
return newDescription;
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 8970404..21da6bc 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
@@ -262,6 +262,10 @@ public class PluginContainer implements ContainerService {
releaseLock(lock);
}
+ //fire off the resource upgrade as soon as possible. It will run only once per
plugin container
+ //lifetime.
+ inventoryManager.executeResourceUpgradeImmediately();
+
return;
}
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 044aa25..7fcfd6e 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
@@ -250,16 +250,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
.getServiceDiscoveryInitialDelay(),
configuration.getServiceDiscoveryPeriod(), TimeUnit.SECONDS);
}
- //try to perform the full resource upgrade now.
- //The initialization time is ideal for this because inventory manager
- //is the first plugin container service to start and hence we can
- //be sure that no under concurrent updates to the resources are happening.
- //Because PC doesn't support online updates of plugins and needs to be
restarted
- //in order to pick up the changed plugins, we can be sure that running the
- //upgrade only once at the PC start up is enough for the lifetime of
- //plugin container (and hence this instance of InventoryManager).
resourceUpgradeExecutor = new ResourceUpgradeExecutor(this);
- resourceUpgradeExecutor.execute();
} finally {
inventoryLock.writeLock().unlock();
}
@@ -516,6 +507,10 @@ public class InventoryManager extends AgentService implements
ContainerService,
}
}
+ public void executeResourceUpgradeImmediately() {
+ resourceUpgradeExecutor.execute();
+ }
+
public InventoryReport executeServerScanImmediately() {
try {
return inventoryThreadPoolExecutor.submit((Callable<InventoryReport>)
this.serverScanExecutor).get();
@@ -1180,10 +1175,10 @@ public class InventoryManager extends AgentService implements
ContainerService,
for (ResourceUpgradeReport upgradeReport : upgradeReports) {
String resourceKey = upgradeReport.getNewResourceKey();
String name = upgradeReport.getNewName();
- String version = upgradeReport.getNewVersion();
+ //String version = upgradeReport.getNewVersion();
String description = upgradeReport.getNewDescription();
- Configuration pluginConfiguration =
upgradeReport.getNewPluginConfiguration();
- Configuration resourceConfiguration =
upgradeReport.getNewResourceConfiguration();
+ //Configuration pluginConfiguration =
upgradeReport.getNewPluginConfiguration();
+ //Configuration resourceConfiguration =
upgradeReport.getNewResourceConfiguration();
ResourceContainer existingResourceContainer =
getResourceContainer(upgradeReport.getResourceId());
if (existingResourceContainer != null) {
@@ -1196,21 +1191,21 @@ public class InventoryManager extends AgentService implements
ContainerService,
existingResource.setName(name);
}
- if (version != null) {
- existingResource.setVersion(version);
- }
+// if (version != null) {
+// existingResource.setVersion(version);
+// }
if (description != null) {
existingResource.setDescription(description);
}
- if (pluginConfiguration != null) {
- existingResource.setPluginConfiguration(pluginConfiguration);
- }
-
- if (resourceConfiguration != null) {
-
existingResource.setResourceConfiguration(resourceConfiguration);
- }
+// if (pluginConfiguration != null) {
+// existingResource.setPluginConfiguration(pluginConfiguration);
+// }
+//
+// if (resourceConfiguration != null) {
+//
existingResource.setResourceConfiguration(resourceConfiguration);
+// }
} else {
log.error("Upgraded a resource that is not present on the agent.
This should not happen. The id of the missing resource is " +
upgradeReport.getResourceId());
}
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
index b00dfd4..d15a1c2 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
@@ -69,6 +69,7 @@ public class ResourceUpgradeExecutor {
public ResourceUpgradeExecutor(InventoryManager inventoryManager) {
this.inventoryManager = inventoryManager;
+ reports = new HashSet<ResourceUpgradeReport>();
}
/**
@@ -104,8 +105,9 @@ public class ResourceUpgradeExecutor {
* all the upgrade requests.
*/
public void sendRequests() {
- if (enabled) {
+ if (enabled && reports.size() > 0) {
inventoryManager.mergeResourceFromUpgrade(reports);
+ reports.clear();
}
}
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 44f79a2..1101199 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
@@ -472,67 +472,56 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
if (resource != null) {
String resourceKey = upgradeReport.getNewResourceKey();
String name = upgradeReport.getNewName();
- String version = upgradeReport.getNewVersion();
+ //String version = upgradeReport.getNewVersion();
String description = upgradeReport.getNewDescription();
- Configuration pluginConfiguration =
upgradeReport.getNewPluginConfiguration();
- Configuration resourceConfiguration =
upgradeReport.getNewResourceConfiguration();
+// Configuration pluginConfiguration =
upgradeReport.getNewPluginConfiguration();
+// Configuration resourceConfiguration =
upgradeReport.getNewResourceConfiguration();
- if (resourceKey != null) {
- if (!equalOrNull(resourceKey, resource.getResourceKey())) {
- log.info("Resource [" + resource + "] upgraded its
resource key from [" +
- resource.getResourceKey() + "] to [" + resourceKey +
"]");
- changed = true;
- resource.setResourceKey(resourceKey);
- }
- }
-
- if (name != null) {
- if (!equalOrNull(name, resource.getName())) {
- log.info("Resource [" + resource + "] upgraded its
name from [" +
- resource.getName() + "] to [" + name + "]");
- changed = true;
- resource.setName(name);
- }
- }
-
- if (version != null) {
- changed = updateResourceVersion(resource, version) || changed;
+ if (needsUpgrade(resource.getResourceKey(), resourceKey)) {
+ log.info("Resource [" + resource + "] upgraded its
resource key from [" +
+ resource.getResourceKey() + "] to [" + resourceKey +
"]");
+ changed = true;
+ resource.setResourceKey(resourceKey);
}
- if (description != null) {
- if (!equalOrNull(description, resource.getDescription())) {
- log.info("Resource [" + resource + "] upgraded its
description from [" +
- resource.getDescription() + "] to [" + description +
"]");
- changed = true;
- resource.setDescription(description);
- }
+ if (needsUpgrade(resource.getName(), name)) {
+ log.info("Resource [" + resource + "] upgraded its name
from [" +
+ resource.getName() + "] to [" + name + "]");
+ changed = true;
+ resource.setName(name);
}
- if (pluginConfiguration != null) {
- if (!equalOrNull(pluginConfiguration, resource.getPluginConfiguration()))
{
- log.info("Resource [" + resource + "] upgraded its
plugin configuration from [" +
- resource.getPluginConfiguration() + "] to [" +
pluginConfiguration + "]");
- changed = true;
- resource.setPluginConfiguration(pluginConfiguration);
- }
- }
+// if (version != null) {
+// changed = updateResourceVersion(resource, version) || changed;
+// }
- if (resourceConfiguration != null) {
- if (!equalOrNull(resourceConfiguration,
resource.getResourceConfiguration())) {
- //XXX Will this create a new history entry?
-
- log.info("Resource [" + resource + "] upgraded its
resource configuration from [" +
- resource.getResourceConfiguration() + "] to [" +
resourceConfiguration + "]");
-
- changed = true;
- resource.setResourceConfiguration(resourceConfiguration);
- }
+ if (needsUpgrade(resource.getDescription(), description)) {
+ log.info("Resource [" + resource + "] upgraded its
description from [" +
+ resource.getDescription() + "] to [" + description +
"]");
+ changed = true;
+ resource.setDescription(description);
}
- // If the resource was marked as deleted, reactivate it again.
- if (resource.getInventoryStatus() == InventoryStatus.DELETED) {
- resource.setInventoryStatus(InventoryStatus.COMMITTED);
- }
+// if (pluginConfiguration != null) {
+// if (!equalOrNull(pluginConfiguration,
resource.getPluginConfiguration())) {
+// log.info("Resource [" + resource + "] upgraded its
plugin configuration from [" +
+// resource.getPluginConfiguration() + "] to [" +
pluginConfiguration + "]");
+// changed = true;
+// resource.setPluginConfiguration(pluginConfiguration);
+// }
+// }
+//
+// if (resourceConfiguration != null) {
+// if (!equalOrNull(resourceConfiguration,
resource.getResourceConfiguration())) {
+// //XXX Will this create a new history entry?
+//
+// log.info("Resource [" + resource + "] upgraded its
resource configuration from [" +
+// resource.getResourceConfiguration() + "] to [" +
resourceConfiguration + "]");
+//
+// changed = true;
+// resource.setResourceConfiguration(resourceConfiguration);
+// }
+// }
}
return changed;
}
@@ -897,4 +886,8 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
}
}
}
+
+ private static <T> boolean needsUpgrade(T oldValue, T newValue) {
+ return newValue != null && (oldValue == null ||
!newValue.equals(oldValue));
+ }
}
\ No newline at end of file
commit 1fe97fb0bb997c5e6c023adca8bb94da0fca7c79
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu May 27 16:18:21 2010 +0200
Actually call out back to inv manager to perform the upgrade.
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
index f0f2b43..b00dfd4 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
@@ -105,7 +105,7 @@ public class ResourceUpgradeExecutor {
*/
public void sendRequests() {
if (enabled) {
- //TODO implement
+ inventoryManager.mergeResourceFromUpgrade(reports);
}
}
commit d0d2e582e00344b1720ee9d01a730fa1d1c3cb46
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu May 27 15:58:35 2010 +0200
reimplemented the upgrade process on the agent to happen only at init time. the server
receives a full batch of upgrades, not one upgrade after another.
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 cfa2459..61e5084 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
@@ -138,13 +138,12 @@ public interface DiscoveryServerService {
boolean updateResourceVersion(int resourceId, String version);
/**
- * Upgrades the data of the resource according to the provided report.
+ * Upgrades the data of the resources according to the provided reports.
*
- * @param resourceId the id of the resource to be upgraded
- * @param upgradeReport contains the information about the upgrade
+ * @param upgradeReports contains the information about the upgrade of individual
resources.
* @return true if the upgrade succeeded, false otherwise.
*/
- boolean upgradeResource(int resourceId, ResourceUpgradeReport upgradeReport);
+ boolean upgradeResources(Set<ResourceUpgradeReport> upgradeReports);
/**
* Gives the server a chance to apply any necessary post-processing that's needed
for newly committed resources
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
index 52acf09..bfeba0d 100644
---
a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
@@ -41,6 +41,7 @@ public class ResourceUpgradeReport implements Serializable {
private static final long serialVersionUID = 1L;
+ private int resourceId;
private String newResourceKey;
private String newName;
private String newVersion;
@@ -52,6 +53,22 @@ public class ResourceUpgradeReport implements Serializable {
}
+ /**
+ * The server-side id of the resource being upgraded.
+ * The discovery components don't need to assign this value.
+ */
+ public int getResourceId() {
+ return resourceId;
+ }
+
+ /**
+ * The server-side id of the resource being upgraded.
+ * The discovery components don't need to assign this value.
+ */
+ public void setResourceId(int resourceId) {
+ this.resourceId = resourceId;
+ }
+
public String getNewResourceKey() {
return newResourceKey;
}
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 032256b..044aa25 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
@@ -33,9 +33,11 @@ import java.util.IdentityHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
+import java.util.Queue;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@@ -89,6 +91,8 @@ import org.rhq.core.pc.plugin.BlacklistedException;
import org.rhq.core.pc.plugin.CanonicalResourceKey;
import org.rhq.core.pc.plugin.PluginComponentFactory;
import org.rhq.core.pc.plugin.PluginManager;
+import org.rhq.core.pc.upgrade.ResourceUpgradeExecutor;
+import org.rhq.core.pc.upgrade.ResourceUpgradeRequest;
import org.rhq.core.pc.util.DiscoveryComponentProxyFactory;
import org.rhq.core.pc.util.FacetLockType;
import org.rhq.core.pc.util.LoggingThreadFactory;
@@ -186,6 +190,11 @@ public class InventoryManager extends AgentService implements
ContainerService,
*/
private AvailabilityCollectorThreadPool availabilityCollectors;
+ /**
+ * Handles the resource upgrade during the initialization of the inventory manager.
+ */
+ private ResourceUpgradeExecutor resourceUpgradeExecutor;
+
public InventoryManager() {
super(DiscoveryAgentService.class);
}
@@ -240,6 +249,17 @@ public class InventoryManager extends AgentService implements
ContainerService,
inventoryThreadPoolExecutor.scheduleWithFixedDelay(serviceScanExecutor,
configuration
.getServiceDiscoveryInitialDelay(),
configuration.getServiceDiscoveryPeriod(), TimeUnit.SECONDS);
}
+
+ //try to perform the full resource upgrade now.
+ //The initialization time is ideal for this because inventory manager
+ //is the first plugin container service to start and hence we can
+ //be sure that no under concurrent updates to the resources are happening.
+ //Because PC doesn't support online updates of plugins and needs to be
restarted
+ //in order to pick up the changed plugins, we can be sure that running the
+ //upgrade only once at the PC start up is enough for the lifetime of
+ //plugin container (and hence this instance of InventoryManager).
+ resourceUpgradeExecutor = new ResourceUpgradeExecutor(this);
+ resourceUpgradeExecutor.execute();
} finally {
inventoryLock.writeLock().unlock();
}
@@ -356,6 +376,23 @@ public class InventoryManager extends AgentService implements
ContainerService,
return results;
}
+ public <T extends ResourceComponent> Map<ResourceUpgradeContext<T>,
ResourceUpgradeReport> invokeDiscoveryComponentResourceUpgradeFacet(
+ ResourceType resourceType, ResourceDiscoveryComponent<T> component,
+ Set<ResourceUpgradeContext<T>> inventoriedSiblings,
ResourceUpgradeContext<?> parent,
+ Set<ResourceUpgradeContext<T>> discoveredResources) throws Throwable
{
+
+ long timeout = getDiscoveryComponentTimeout(resourceType);
+ try {
+ @SuppressWarnings("unchecked")
+ ResourceUpgradeFacet<T> proxy =
this.discoveryComponentProxyFactory.getDiscoveryComponentProxy(resourceType, component,
timeout, ResourceUpgradeFacet.class);
+
+ return proxy.upgrade(inventoriedSiblings, parent, discoveredResources);
+ } catch (BlacklistedException e) {
+ log.debug(e);
+ return Collections.emptyMap();
+ }
+ }
+
public DiscoveryComponentProxyFactory getDiscoveryComponentProxyFactory() {
return this.discoveryComponentProxyFactory;
}
@@ -854,8 +891,20 @@ public class InventoryManager extends AgentService implements
ContainerService,
*/
public boolean handleReport(InventoryReport report) {
if (!configuration.isInsideAgent()) {
+ //TODO how does resource upgrade behave in the embedded scenario?
return true;
}
+
+ //finish the resource upgrade.
+ //by now all the resource upgrade requests have been processed
+ //by the executor, which means that the inventory report
+ //we got already only contains the "correct" new resources and
+ //that the executor has all the upgrade requests queued up
+ //to be sent to the server in a batch.
+ if (resourceUpgradeExecutor.isEnabled()) {
+ resourceUpgradeExecutor.sendRequests();
+ }
+
if (report.getAddedRoots().isEmpty()) {
return true; // nothing to do
}
@@ -925,6 +974,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
log.debug(String.format("DONE syncing local inventory [%d]
ms.",
(System.currentTimeMillis() - startTime)));
}
+
// If we synced any Resources, one or more Resource components were probably
started,
// so run an avail check to report on their availabilities immediately. Also
kick off
// a service scan to scan those Resources for new child Resources. Kick both
tasks off
@@ -941,7 +991,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
throw new RuntimeException(t);
}
}
-
+
private void getAllUuids(ResourceSyncInfo syncInfo, Set<String>
allServerSideUuids) {
allServerSideUuids.add(syncInfo.getUuid());
for (ResourceSyncInfo child : syncInfo.getChildSyncInfos()) {
@@ -1113,49 +1163,58 @@ public class InventoryManager extends AgentService implements
ContainerService,
return resourceContainer.updateAvailability(availabilityType);
}
- private boolean mergeResourceFromUpgrade(Resource existingResource,
ResourceUpgradeReport upgradeReport) {
- String resourceKey = upgradeReport.getNewResourceKey();
- String name = upgradeReport.getNewName();
- String version = upgradeReport.getNewVersion();
- String description = upgradeReport.getNewDescription();
- Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
- Configuration resourceConfiguration =
upgradeReport.getNewResourceConfiguration();
-
+ public boolean mergeResourceFromUpgrade(Set<ResourceUpgradeReport>
upgradeReports) {
boolean serverUpdated = false;
try {
ServerServices serverServices = this.configuration.getServerServices();
if (serverServices != null) {
DiscoveryServerService discoveryServerService =
serverServices.getDiscoveryServerService();
- serverUpdated =
discoveryServerService.upgradeResource(existingResource.getId(), upgradeReport);
+ serverUpdated = discoveryServerService.upgradeResources(upgradeReports);
}
} catch (Exception e) {
- log.error("Failed to upgrade the resource [" + existingResource +
"] on the server.", e);
+ log.error("Failed to process resource upgrades on the server.",
e);
}
if (serverUpdated) {
- if (resourceKey != null) {
- existingResource.setResourceKey(resourceKey);
- }
-
- if (name != null) {
- existingResource.setName(name);
- }
-
- if (version != null) {
- existingResource.setVersion(version);
- }
-
- if (description != null) {
- existingResource.setDescription(description);
- }
-
- if (pluginConfiguration != null) {
- existingResource.setPluginConfiguration(pluginConfiguration);
- }
-
- if (resourceConfiguration != null) {
- existingResource.setResourceConfiguration(resourceConfiguration);
+ for (ResourceUpgradeReport upgradeReport : upgradeReports) {
+ String resourceKey = upgradeReport.getNewResourceKey();
+ String name = upgradeReport.getNewName();
+ String version = upgradeReport.getNewVersion();
+ String description = upgradeReport.getNewDescription();
+ Configuration pluginConfiguration =
upgradeReport.getNewPluginConfiguration();
+ Configuration resourceConfiguration =
upgradeReport.getNewResourceConfiguration();
+
+ ResourceContainer existingResourceContainer =
getResourceContainer(upgradeReport.getResourceId());
+ if (existingResourceContainer != null) {
+ Resource existingResource = existingResourceContainer.getResource();
+ if (resourceKey != null) {
+ existingResource.setResourceKey(resourceKey);
+ }
+
+ if (name != null) {
+ existingResource.setName(name);
+ }
+
+ if (version != null) {
+ existingResource.setVersion(version);
+ }
+
+ if (description != null) {
+ existingResource.setDescription(description);
+ }
+
+ if (pluginConfiguration != null) {
+ existingResource.setPluginConfiguration(pluginConfiguration);
+ }
+
+ if (resourceConfiguration != null) {
+
existingResource.setResourceConfiguration(resourceConfiguration);
+ }
+ } else {
+ log.error("Upgraded a resource that is not present on the agent.
This should not happen. The id of the missing resource is " +
upgradeReport.getResourceId());
+ }
+
}
}
@@ -1453,6 +1512,23 @@ public class InventoryManager extends AgentService implements
ContainerService,
this.configuration.getPluginContainerDeployment()); // helps components make
determinations of what to do
}
+ public <T extends ResourceComponent> ResourceUpgradeContext<T>
createResourceUpgradeContext(Resource resource, T parentComponent,
ResourceDiscoveryComponent<T> discoveryComponent) {
+ File pluginDataDir = new File(this.configuration.getDataDirectory(),
resource.getResourceType().getPlugin());
+
+ return new ResourceUpgradeContext<T>(resource, // the resource itself
+ parentComponent, // its parent component
+ discoveryComponent, // the discovery component (this is actually the proxy to
it)
+ SystemInfoFactory.createSystemInfo(), // for native access
+ this.configuration.getTemporaryDirectory(), // location for plugin to write
temp files
+ pluginDataDir, // location for plugin to write data files
+ this.configuration.getContainerName(), // the name of the agent/PC
+ getEventContext(resource), // for event access
+ getOperationContext(resource), // for operation manager access
+ getContentContext(resource), // for content manager access
+ this.availabilityCollectors, // for components that want to perform async
avail checking
+ this.configuration.getPluginContainerDeployment()); // helps components make
determinations of what to do
+ }
+
/**
* This will send a resource error to the server (if applicable) to indicate that the
given resource could not be
* connected to due to an invalid plugin configuration.
@@ -1536,7 +1612,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
return getResourcesWithType(serverType, this.platform.getChildResources());
}
- private Set<Resource> getResourcesWithType(ResourceType serverType,
Set<Resource> resources) {
+ public Set<Resource> getResourcesWithType(ResourceType serverType,
Set<Resource> resources) {
Set<Resource> servers = new HashSet<Resource>();
if (resources == null) {
@@ -2061,76 +2137,10 @@ public class InventoryManager extends AgentService implements
ContainerService,
newResources.add(newResource);
}
}
-
- //check if the discovery component supports resource upgrade
- //if it does, perform the resource upgrade straight away here during the
discovery process.
- if (discoveryComponent instanceof ResourceUpgradeFacet) {
- ResourceUpgradeFacet resourceUpgrade = (ResourceUpgradeFacet)
discoveryComponent;
-
- //the siblings are the resources of the type that is currently being
discovered that are already
- //present in the inventory. These are the candidate resources for the
upgrade.
- Set<Resource> siblings = getResourcesWithType(resourceType,
parentResource.getChildResources());
-
- ResourceUpgradeContext<?> parentUpgradeContext = null;
-
- //get the upgrade context of the parent resource so that it can be passed
to the upgrade method
- //of the discovery component.
- if (parentResource != null) {
- Resource grandParent = parentResource.getParentResource();
- ResourceContainer grandParentContainer = grandParent == null ? null :
getResourceContainer(grandParent);
- ResourceDiscoveryComponent parentDiscoveryComponent =
PluginContainer.getInstance().getPluginComponentFactory()
- .getDiscoveryComponent(parentResource.getResourceType(),
grandParentContainer);
-
- parentUpgradeContext = new ResourceUpgradeContext(parentResource,
parentDiscoveryComponent, parentResourceContext, availabilityCollectors);
- }
-
- //convert the sibling resources into upgrade context objects so that the
plugin methods don't access the
- //domain objects directly.
- Set<ResourceUpgradeContext> siblingContexts = new
HashSet<ResourceUpgradeContext>(siblings.size());
-
- //but we are going to need to update the resources in the end, so map the
contexts with the resources.
- Map<ResourceUpgradeContext, Resource> siblingContextToResource =
new HashMap<ResourceUpgradeContext, Resource>();
-
- for (Resource sibling : siblings) {
- ResourceUpgradeContext siblingContext = new
ResourceUpgradeContext(sibling, discoveryComponent,
getResourceContainer(sibling).getResourceContext(), availabilityCollectors);
- siblingContexts.add(siblingContext);
- siblingContextToResource.put(siblingContext, sibling);
- }
-
- //covert the new resources into contexts.
- //map the resources by resource key so that we can later check for
uniqueness of the reported results.
- Set<ResourceUpgradeContext> newResourceContexts = new
HashSet<ResourceUpgradeContext>();
- Map<String, Resource> newResourceKeyToResource = new
HashMap<String, Resource>();
-
- for (Resource newResource : newResources) {
- ResourceUpgradeContext newUpgradeContext = new
ResourceUpgradeContext(newResource, discoveryComponent, createResourceContext(newResource,
parentComponent, discoveryComponent), availabilityCollectors);
- newResourceContexts.add(newUpgradeContext);
- newResourceKeyToResource.put(newResource.getResourceKey(),
newResource);
- }
-
- //ask the discovery component to upgrade the siblings.
- Map<ResourceUpgradeContext, ResourceUpgradeReport> results =
resourceUpgrade.upgrade(siblingContexts, parentUpgradeContext, newResourceContexts);
-
- //now go through the results and upgrade the resources as needed.
- for(Map.Entry<ResourceUpgradeContext, ResourceUpgradeReport>
upgradeEntry : results.entrySet()) {
- Resource siblingToUpgrade =
siblingContextToResource.get(upgradeEntry.getKey());
- ResourceUpgradeReport newData = upgradeEntry.getValue();
-
- //upgrade the data on the server first
- mergeResourceFromUpgrade(siblingToUpgrade, newData);
-
- //if there was a resource key upgrade, remove a resource with the
same resource key
- //from the discovery results. Otherwise we'd end up with 2
sibling resources with
- //the same resource key, which is illegal.
- if (newData.getNewResourceKey() != null) {
- Resource newResourceToRemove =
newResourceKeyToResource.get(newData.getNewResourceKey());
- if (newResourceToRemove != null) {
- newResources.remove(newResourceToRemove);
- }
- }
- }
- }
+ if (resourceUpgradeExecutor.isEnabled()) {
+ resourceUpgradeExecutor.processAndQueue(new
ResourceUpgradeRequest(newResources, context, parentResource.getId()), newResources);
+ }
} catch (Throwable e) {
// TODO GH: Add server/parent - up/down semantics so this won't happen
just because a server is not up
long elapsedTime = System.currentTimeMillis() - startTime;
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
new file mode 100644
index 0000000..f0f2b43
--- /dev/null
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
@@ -0,0 +1,285 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.pc.upgrade;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.clientapi.agent.PluginContainerException;
+import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
+import org.rhq.core.pc.PluginContainer;
+import org.rhq.core.pc.inventory.InventoryManager;
+import org.rhq.core.pc.inventory.ResourceContainer;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
+
+/**
+ * This class is responsible for performing the resource upgrade on behalf on of {@link
InventoryManager}.
+ * Despite its name, it is not an {@link java.util.concurrent.Executor} implementation.
+ *
+ * @author Lukas Krejci
+ */
+public class ResourceUpgradeExecutor {
+ private static final Log log = LogFactory.getLog(ResourceUpgradeExecutor.class);
+
+ /**
+ * The upgrade runs only once in its lifetime.
+ */
+ private boolean enabled = true;
+
+ private InventoryManager inventoryManager;
+
+ private Set<ResourceUpgradeReport> reports;
+
+ public ResourceUpgradeExecutor(InventoryManager inventoryManager) {
+ this.inventoryManager = inventoryManager;
+ }
+
+ /**
+ * This method is called from within the {@link InventoryManager} during the
+ * discovery process as individual upgrade requests are generated.
+ * <p>
+ * This method calls the appropriate discovery component to perform the upgrade and
+ * at the same time stores off the results so that they can be sent to the server
+ * at the end of the discovery in one big batch.
+ * <p>
+ * The provided set of discovery results is updated if this method detects that an
existing
+ * resource upgrade would result in a resource key collision with some of the newly
discovered
+ * resources.
+ *
+ * @param request the upgrade request
+ * @param discoveredResources the set of discovered resources that this method can
optionally remove some elements from.
+ */
+ public <T extends ResourceComponent> Map<ResourceUpgradeContext<T>,
ResourceUpgradeReport> processAndQueue(
+ ResourceUpgradeRequest<T> request, Set<Resource> discoveredResources)
{
+
+ return enabled ? executeResourceUpgradeAndStoreReport(request,
discoveredResources) : null;
+ }
+
+ /**
+ * @return true if the executor is ready to perform the upgrade, false otherwise.
+ */
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ /**
+ * This method is called from within the {@link InventoryManager} once it's
collected
+ * all the upgrade requests.
+ */
+ public void sendRequests() {
+ if (enabled) {
+ //TODO implement
+ }
+ }
+
+ /**
+ * Performs the resource upgrade. First, a full inventory report is pulled down from
the
+ * server to ensure we have an up-to-date picture of the inventory.
+ * After that a full discovery is performed and both the upgrade report and discovery
report
+ * are sent to the server.
+ */
+ public void execute() {
+ if (enabled) {
+ if (log.isDebugEnabled()) {
+ log.debug("Starting resource upgrade.");
+ }
+
+ try {
+ //pull the inventory down from the server.
+ //this will ensure that we have an up-to-date info on the
+ //server inventory before we try to upgrade.
+ boolean syncResult = inventoryManager.handleReport(new
InventoryReport(inventoryManager.getAgent()));
+ if (!syncResult) {
+ log.warn("Resource upgrade failed to sync up the inventory with
the server.");
+ return;
+ }
+
+ //fire off the full discovery
+ inventoryManager.executeServerScanImmediately();
+ inventoryManager.executeServiceScanImmediately();
+ } catch (Throwable t) {
+ log.warn("Resource upgrade failed.", t);
+ } finally {
+ //make sure to switch off the upgrade...
+ this.enabled = false;
+
+ //clear up so that we don't hold unnecessary instances.
+ reports.clear();
+
+ if (log.isDebugEnabled()) {
+ log.debug("Resource upgrade finished.");
+ }
+ }
+
+ } else {
+ if (log.isDebugEnabled()) {
+ log.debug("ResourceUpgradeExecutor already ran before. Skipping the
execution.");
+ }
+ }
+ }
+
+ /**
+ * Executes the resource upgrade request on the agent (if the appropriate discovery
component support {@link ResourceUpgradeFacet}).
+ *
+ * @param request the upgrade request to execute on the agent.
+ * @param discoveredResources the set of the discovered resources that this method
can remove some elements from
+ * @return the resulting upgrade map as reported by the plugin from {@link
ResourceUpgradeFacet#upgrade(Set, ResourceUpgradeContext, Set)} method.
+ *
+ * @throws PluginContainerException
+ */
+ private <T extends ResourceComponent> Map<ResourceUpgradeContext<T>,
ResourceUpgradeReport> executeResourceUpgradeAndStoreReport(
+ ResourceUpgradeRequest<T> request, Set<Resource> discoveredResources)
{
+
+ ResourceDiscoveryContext<T> discoveryContext =
request.getDiscoveryContext();
+ Set<Resource> newResources = request.getDiscoveredResources();
+ Integer parentResourceId = request.getParentResourceId();
+
+ try {
+ ResourceType resourceType = discoveryContext.getResourceType();
+ ResourceContainer parentResourceContainer = null;
+ Resource parentResource = null;
+ if (parentResourceId != null) {
+ parentResourceContainer =
inventoryManager.getResourceContainer(parentResourceId);
+ if (parentResourceContainer != null) {
+ parentResource = parentResourceContainer.getResource();
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ ResourceDiscoveryComponent<T> discoveryComponent =
PluginContainer.getInstance()
+ .getPluginComponentFactory().getDiscoveryComponent(resourceType,
parentResourceContainer);
+
+ ResourceContext<?> parentResourceContext =
discoveryContext.getParentResourceContext();
+
+ T parentComponent = discoveryContext.getParentResourceComponent();
+
+ //check if the discovery component supports resource upgrade
+ //if it does, perform the resource upgrade straight away here during the
discovery process.
+ if (discoveryComponent instanceof ResourceUpgradeFacet) {
+ //the siblings are the resources of the type that is currently being
discovered that are already
+ //present in the inventory. These are the candidate resources for the
upgrade.
+ Set<Resource> siblings = parentResource == null ?
Collections.singleton(inventoryManager.getPlatform())
+ : inventoryManager.getResourcesWithType(resourceType,
parentResource.getChildResources());
+
+ //get the upgrade context of the parent resource so that it can be passed
to the upgrade method
+ //of the discovery component.
+ ResourceUpgradeContext<?> parentUpgradeContext = null;
+
+ if (parentResource != null) {
+ Resource grandParent = parentResource.getParentResource();
+ ResourceContainer grandParentContainer = grandParent == null ? null :
inventoryManager
+ .getResourceContainer(grandParent);
+
+ @SuppressWarnings("unchecked")
+ ResourceDiscoveryComponent<ResourceComponent>
parentDiscoveryComponent = PluginContainer
+
.getInstance().getPluginComponentFactory().getDiscoveryComponent(
+ parentResource.getResourceType(), grandParentContainer);
+
+ ResourceComponent<?> grandParentResourceComponent =
grandParentContainer == null ? null
+ : grandParentContainer.getResourceComponent();
+
+ parentUpgradeContext =
inventoryManager.createResourceUpgradeContext(parentResource,
+ grandParentResourceComponent, parentDiscoveryComponent);
+ }
+
+ //convert the sibling resources into upgrade context objects so that the
plugin methods don't access the
+ //domain objects directly.
+ Set<ResourceUpgradeContext<T>> siblingContexts = new
HashSet<ResourceUpgradeContext<T>>(siblings.size());
+
+ //but we are going to need to update the resources in the end, so map the
contexts with the resources.
+ Map<ResourceUpgradeContext<T>, Resource>
siblingContextToResource = new HashMap<ResourceUpgradeContext<T>,
Resource>();
+
+ for (Resource sibling : siblings) {
+ ResourceUpgradeContext<T> siblingContext =
inventoryManager.createResourceUpgradeContext(sibling,
+ parentComponent, discoveryComponent);
+ siblingContexts.add(siblingContext);
+ siblingContextToResource.put(siblingContext, sibling);
+ }
+
+ //convert the new resources into contexts.
+ //map the resources by resource key so that we can later check for
uniqueness of the reported results.
+ Set<ResourceUpgradeContext<T>> newResourceContexts = new
HashSet<ResourceUpgradeContext<T>>();
+ Map<String, Resource> newResourceKeyToResource = new
HashMap<String, Resource>();
+
+ for (Resource newResource : newResources) {
+ ResourceUpgradeContext<T> newUpgradeContext =
inventoryManager.createResourceUpgradeContext(
+ newResource, parentComponent, discoveryComponent);
+ newResourceContexts.add(newUpgradeContext);
+ newResourceKeyToResource.put(newResource.getResourceKey(),
newResource);
+ }
+
+ //ask the discovery component to upgrade the siblings.
+ Map<ResourceUpgradeContext<T>, ResourceUpgradeReport>
results;
+ try {
+ results =
inventoryManager.invokeDiscoveryComponentResourceUpgradeFacet(resourceType,
+ discoveryComponent, siblingContexts, parentUpgradeContext,
newResourceContexts);
+
+ //now go through the results and upgrade the resources as needed.
+ for (Map.Entry<ResourceUpgradeContext<T>,
ResourceUpgradeReport> upgradeEntry : results.entrySet()) {
+ Resource siblingToUpgrade =
siblingContextToResource.get(upgradeEntry.getKey());
+ ResourceUpgradeReport newData = upgradeEntry.getValue();
+
+ //upgrade the data on the server first
+ newData.setResourceId(siblingToUpgrade.getId());
+ reports.add(newData);
+
+ //if there was a resource key upgrade, remove a resource with the
same resource key
+ //from the discovery results. Otherwise we'd end up with 2
sibling resources with
+ //the same resource key, which is illegal.
+ if (newData.getNewResourceKey() != null) {
+ Resource newResourceToRemove =
newResourceKeyToResource.get(newData.getNewResourceKey());
+ if (newResourceToRemove != null) {
+ discoveredResources.remove(newResourceToRemove);
+ }
+ }
+ }
+
+ return results;
+ } catch (Throwable t) {
+ log.warn("Exception in discovery component " +
discoveryComponent.getClass() + " upgrade method.",
+ t);
+ }
+ }
+ } catch (PluginContainerException e) {
+ log.warn("Failed resource upgrade of children of resource id " +
parentResourceId, e);
+ }
+ return null;
+ }
+}
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeRequest.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeRequest.java
new file mode 100644
index 0000000..25178ee
--- /dev/null
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeRequest.java
@@ -0,0 +1,35 @@
+package org.rhq.core.pc.upgrade;
+
+import java.util.Set;
+
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+
+/**
+ * This class is used to store the requests for resource upgrade that originate in
+ * the discovery workflow, but can only be executed after an inventory sync.
+ */
+public class ResourceUpgradeRequest<T extends ResourceComponent> {
+ private Set<Resource> discoveredResources;
+ private ResourceDiscoveryContext<T> discoveryContext;
+ private Integer parentResourceId;
+
+ public ResourceUpgradeRequest(Set<Resource> discoveredResources,
ResourceDiscoveryContext<T> discoveryContext, Integer parentResourceId) {
+ this.discoveredResources = discoveredResources;
+ this.discoveryContext = discoveryContext;
+ this.parentResourceId = parentResourceId;
+ }
+
+ public Set<Resource> getDiscoveredResources() {
+ return discoveredResources;
+ }
+
+ public ResourceDiscoveryContext<T> getDiscoveryContext() {
+ return discoveryContext;
+ }
+
+ public Integer getParentResourceId() {
+ return parentResourceId;
+ }
+}
\ No newline at end of file
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/DiscoveryComponentProxyFactory.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/DiscoveryComponentProxyFactory.java
index 57b9874..f8d1267 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/DiscoveryComponentProxyFactory.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/DiscoveryComponentProxyFactory.java
@@ -189,7 +189,7 @@ public class DiscoveryComponentProxyFactory {
+ "] has been blacklisted and can no longer be invoked.");
}
- if (method.getDeclaringClass().equals(ResourceDiscoveryComponent.class)) {
+ if
(method.getDeclaringClass().getPackage().getName().startsWith("org.rhq")) {
return invokeInNewThread(method, args);
} else {
// toString(), etc.
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 2d3e9e6..44f79a2 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
@@ -401,17 +401,20 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
}
}
- public boolean upgradeResource(int resourceId, ResourceUpgradeReport upgradeReport)
{
- Resource existingResource = this.entityManager.find(Resource.class, resourceId);
- if (existingResource != null) {
- boolean changed = upgradeResource(existingResource, upgradeReport);
- if (changed) {
- this.entityManager.merge(existingResource);
+ public boolean upgradeResources(Set<ResourceUpgradeReport> upgradeReports) {
+ for (ResourceUpgradeReport report : upgradeReports) {
+ Resource existingResource = this.entityManager.find(Resource.class,
report.getResourceId());
+ if (existingResource != null) {
+ boolean changed = upgradeResource(existingResource, report);
+ if (changed) {
+ this.entityManager.merge(existingResource);
+ }
+ } else {
+ this.entityManager.getTransaction().setRollbackOnly();
+ return false;
}
- return true;
- } else {
- return false;
}
+ return true;
}
/**
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 4e60ffb..af518eb 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
@@ -21,6 +21,7 @@ package org.rhq.enterprise.server.discovery;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import javax.ejb.Local;
@@ -179,11 +180,10 @@ public interface DiscoveryBossLocal extends DiscoveryBossRemote {
boolean updateResourceVersion(int resourceId, String version);
/**
- * Upgrades the data of the resource according to the provided report.
+ * Upgrades the data of the resources according to the provided reports.
*
- * @param resourceId the id of the resource to be upgraded
- * @param upgradeReport contains the information about the upgrade
+ * @param upgradeReports contains the information about the upgrade of individual
resources.
* @return true if the upgrade succeeded, false otherwise.
*/
- boolean upgradeResource(int resourceId, ResourceUpgradeReport upgradeReport);
+ boolean upgradeResources(Set<ResourceUpgradeReport> upgradeReports);
}
\ No newline at end of file
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 720465e..0f90cdc 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
@@ -177,9 +177,9 @@ public class DiscoveryServerServiceImpl implements
DiscoveryServerService {
return discoveryBoss.updateResourceVersion(resourceId, version);
}
- public boolean upgradeResource(int resourceId, ResourceUpgradeReport upgradeReport)
{
+ public boolean upgradeResources(Set<ResourceUpgradeReport> upgradeReports) {
DiscoveryBossLocal discoveryBoss = LookupUtil.getDiscoveryBoss();
- return discoveryBoss.upgradeResource(resourceId, upgradeReport);
+ return discoveryBoss.upgradeResources(upgradeReports);
}
private static Resource convertToPojoResource(Resource resource, boolean
includeDescendants) {
diff --git
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
index fc001f9..2f3431b 100644
---
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
+++
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
@@ -170,10 +170,10 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
return discoveredResources;
}
- public Map<ResourceUpgradeContext, ResourceUpgradeReport>
upgrade(Set<ResourceUpgradeContext> inventoriedSiblings,
- ResourceUpgradeContext<PlatformComponent> parentContext,
Set<ResourceUpgradeContext> discoveryResults) {
+ public Map<ResourceUpgradeContext<PlatformComponent>,
ResourceUpgradeReport>
upgrade(Set<ResourceUpgradeContext<PlatformComponent>> inventoriedSiblings,
+ ResourceUpgradeContext<?> parentContext,
Set<ResourceUpgradeContext<PlatformComponent>> discoveryResults) {
- Map<ResourceUpgradeContext, ResourceUpgradeReport> ret = new
HashMap<ResourceUpgradeContext, ResourceUpgradeReport>();
+ Map<ResourceUpgradeContext<PlatformComponent>, ResourceUpgradeReport>
ret = new HashMap<ResourceUpgradeContext<PlatformComponent>,
ResourceUpgradeReport>();
for (ResourceUpgradeContext context : inventoriedSiblings) {
String inventoriedResourceKey = context.getResourceKey();
commit 15ee2d7c543480cb636eb0b2c68a773d0728fe78
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu May 27 12:11:54 2010 +0200
Small interface correction.
diff --git
a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
index cea777a..914641c 100644
---
a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
+++
b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
@@ -37,7 +37,6 @@ import org.rhq.core.pluginapi.inventory.ResourceComponent;
*
* @author Lukas Krejci
*/
-@SuppressWarnings("unchecked")
public interface ResourceUpgradeFacet<T extends ResourceComponent> {
/**
@@ -54,5 +53,5 @@ public interface ResourceUpgradeFacet<T extends ResourceComponent>
{
* inventoriedSiblings set, the values are the upgrade reports detailing what the
data of the
* corresponding siblings should be upgraded to.
*/
- Map<ResourceUpgradeContext, ResourceUpgradeReport>
upgrade(Set<ResourceUpgradeContext> inventoriedSiblings,
ResourceUpgradeContext<T> parentContext, Set<ResourceUpgradeContext>
discoveryResults);
+ Map<ResourceUpgradeContext<T>, ResourceUpgradeReport>
upgrade(Set<ResourceUpgradeContext<T>> inventoriedSiblings,
ResourceUpgradeContext<? extends ResourceComponent> parentContext,
Set<ResourceUpgradeContext<T>> discoveryResults);
}
commit df9228b55e6fdd293be1b1b030a00fb109fd649c
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed May 26 15:06:37 2010 +0200
added some comments, fixed typos and one possible NPE.
diff --git
a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
index b68b5df..cea777a 100644
---
a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
+++
b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
@@ -45,7 +45,7 @@ public interface ResourceUpgradeFacet<T extends ResourceComponent>
{
* The exact same discovery results are passed to this method along with the set of
resources
* that already exist in the inventory.
*
- * @param inventoriedSimblings the existing resources
+ * @param inventoriedSiblings the existing resources
* @param parentContext the parent of both the newly discovered and existing
resources
* @param discoveryResults the discovered resources. The resources from this set that
have
* the same resource key as one of the inventoried siblings (after upgrade using the
results of this method) won't
@@ -54,5 +54,5 @@ public interface ResourceUpgradeFacet<T extends ResourceComponent>
{
* inventoriedSiblings set, the values are the upgrade reports detailing what the
data of the
* corresponding siblings should be upgraded to.
*/
- Map<ResourceUpgradeContext, ResourceUpgradeReport>
upgrade(Set<ResourceUpgradeContext> inventoriedSimblings,
ResourceUpgradeContext<T> parentContext, Set<ResourceUpgradeContext>
discoveryResults);
+ Map<ResourceUpgradeContext, ResourceUpgradeReport>
upgrade(Set<ResourceUpgradeContext> inventoriedSiblings,
ResourceUpgradeContext<T> parentContext, Set<ResourceUpgradeContext>
discoveryResults);
}
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 866fd79..032256b 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
@@ -2062,21 +2062,33 @@ public class InventoryManager extends AgentService implements
ContainerService,
}
}
- //check for upgrade support
+ //check if the discovery component supports resource upgrade
+ //if it does, perform the resource upgrade straight away here during the
discovery process.
if (discoveryComponent instanceof ResourceUpgradeFacet) {
ResourceUpgradeFacet resourceUpgrade = (ResourceUpgradeFacet)
discoveryComponent;
+ //the siblings are the resources of the type that is currently being
discovered that are already
+ //present in the inventory. These are the candidate resources for the
upgrade.
Set<Resource> siblings = getResourcesWithType(resourceType,
parentResource.getChildResources());
- Resource grandParent = parentResource.getParentResource();
- ResourceContainer grandParentContainer = grandParent == null ? null :
getResourceContainer(grandParent);
- ResourceDiscoveryComponent parentDiscoveryComponent =
PluginContainer.getInstance().getPluginComponentFactory()
- .getDiscoveryComponent(parentResource.getResourceType(),
grandParentContainer);
-
- ResourceUpgradeContext<?> parentUpgradeContext = new
ResourceUpgradeContext(parentResource, parentDiscoveryComponent, parentResourceContext,
availabilityCollectors);
+ ResourceUpgradeContext<?> parentUpgradeContext = null;
+
+ //get the upgrade context of the parent resource so that it can be passed
to the upgrade method
+ //of the discovery component.
+ if (parentResource != null) {
+ Resource grandParent = parentResource.getParentResource();
+ ResourceContainer grandParentContainer = grandParent == null ? null :
getResourceContainer(grandParent);
+ ResourceDiscoveryComponent parentDiscoveryComponent =
PluginContainer.getInstance().getPluginComponentFactory()
+ .getDiscoveryComponent(parentResource.getResourceType(),
grandParentContainer);
+
+ parentUpgradeContext = new ResourceUpgradeContext(parentResource,
parentDiscoveryComponent, parentResourceContext, availabilityCollectors);
+ }
+ //convert the sibling resources into upgrade context objects so that the
plugin methods don't access the
+ //domain objects directly.
Set<ResourceUpgradeContext> siblingContexts = new
HashSet<ResourceUpgradeContext>(siblings.size());
+ //but we are going to need to update the resources in the end, so map the
contexts with the resources.
Map<ResourceUpgradeContext, Resource> siblingContextToResource =
new HashMap<ResourceUpgradeContext, Resource>();
for (Resource sibling : siblings) {
@@ -2085,6 +2097,8 @@ public class InventoryManager extends AgentService implements
ContainerService,
siblingContextToResource.put(siblingContext, sibling);
}
+ //covert the new resources into contexts.
+ //map the resources by resource key so that we can later check for
uniqueness of the reported results.
Set<ResourceUpgradeContext> newResourceContexts = new
HashSet<ResourceUpgradeContext>();
Map<String, Resource> newResourceKeyToResource = new
HashMap<String, Resource>();
@@ -2094,12 +2108,15 @@ public class InventoryManager extends AgentService implements
ContainerService,
newResourceKeyToResource.put(newResource.getResourceKey(),
newResource);
}
+ //ask the discovery component to upgrade the siblings.
Map<ResourceUpgradeContext, ResourceUpgradeReport> results =
resourceUpgrade.upgrade(siblingContexts, parentUpgradeContext, newResourceContexts);
+ //now go through the results and upgrade the resources as needed.
for(Map.Entry<ResourceUpgradeContext, ResourceUpgradeReport>
upgradeEntry : results.entrySet()) {
Resource siblingToUpgrade =
siblingContextToResource.get(upgradeEntry.getKey());
ResourceUpgradeReport newData = upgradeEntry.getValue();
+ //upgrade the data on the server first
mergeResourceFromUpgrade(siblingToUpgrade, newData);
//if there was a resource key upgrade, remove a resource with the
same resource key
diff --git
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
index 45887f6..fc001f9 100644
---
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
+++
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
@@ -170,12 +170,12 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
return discoveredResources;
}
- public Map<ResourceUpgradeContext, ResourceUpgradeReport>
upgrade(Set<ResourceUpgradeContext> inventoriedSimblings,
+ public Map<ResourceUpgradeContext, ResourceUpgradeReport>
upgrade(Set<ResourceUpgradeContext> inventoriedSiblings,
ResourceUpgradeContext<PlatformComponent> parentContext,
Set<ResourceUpgradeContext> discoveryResults) {
Map<ResourceUpgradeContext, ResourceUpgradeReport> ret = new
HashMap<ResourceUpgradeContext, ResourceUpgradeReport>();
- for (ResourceUpgradeContext context : inventoriedSimblings) {
+ for (ResourceUpgradeContext context : inventoriedSiblings) {
String inventoriedResourceKey = context.getResourceKey();
File inventoriedResourceKeyAsPath = new File(inventoriedResourceKey);
commit 3c7d8241ea85fdceb317049664886b204f4d9cba
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed May 26 14:49:03 2010 +0200
renamed the org.rhq.core.pluginapi.migration package to org.rhq.core.pluginapi.upgrade
to make it use the "upgrade" notion used by the classes in it.
diff --git
a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeContext.java
b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeContext.java
deleted file mode 100644
index e8c5f03..0000000
---
a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeContext.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2010 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.pluginapi.migration;
-
-import java.io.File;
-import java.util.concurrent.Executor;
-
-import org.rhq.core.domain.configuration.Configuration;
-import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.pluginapi.content.ContentContext;
-import org.rhq.core.pluginapi.event.EventContext;
-import org.rhq.core.pluginapi.inventory.PluginContainerDeployment;
-import org.rhq.core.pluginapi.inventory.ResourceComponent;
-import org.rhq.core.pluginapi.inventory.ResourceContext;
-import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
-import org.rhq.core.pluginapi.operation.OperationContext;
-import org.rhq.core.system.SystemInfo;
-
-/**
- * Represents a resource during the resource upgrade phase of discovery.
- *
- * @see ResourceUpgradeFacet
- *
- * @author Lukas Krejci
- */
-@SuppressWarnings("unchecked")
-public class ResourceUpgradeContext<T extends ResourceComponent> extends
ResourceContext<T> {
-
- private final Configuration resourceConfiguration;
- private final String name;
- private final String description;
-
- /**
- * @see ResourceContext#ResourceContext(Resource, ResourceComponent,
ResourceDiscoveryComponent, SystemInfo, File, File, String, EventContext,
OperationContext, ContentContext, Executor, PluginContainerDeployment)
- */
- public ResourceUpgradeContext(Resource resource, T parentResourceComponent,
- ResourceDiscoveryComponent resourceDiscoveryComponent, SystemInfo systemInfo,
File temporaryDirectory,
- File dataDirectory, String pluginContainerName, EventContext eventContext,
OperationContext operationContext,
- ContentContext contentContext, Executor availCollectorThreadPool,
- PluginContainerDeployment pluginContainerDeployment) {
-
- super(resource, parentResourceComponent, resourceDiscoveryComponent, systemInfo,
temporaryDirectory, dataDirectory,
- pluginContainerName, eventContext, operationContext, contentContext,
availCollectorThreadPool,
- pluginContainerDeployment);
-
- this.resourceConfiguration = resource.getResourceConfiguration();
- this.name = resource.getName();
- this.description = resource.getDescription();
- }
-
- public ResourceUpgradeContext(Resource resource, ResourceDiscoveryComponent
discoveryComponent, ResourceContext<T> context, Executor availCollectorThreadPool)
{
- this(resource, context.getParentResourceComponent(), discoveryComponent,
context.getSystemInformation(), context.getTemporaryDirectory(),
- context.getDataDirectory(), context.getPluginContainerName(),
context.getEventContext(), context.getOperationContext(),
- context.getContentContext(), availCollectorThreadPool,
context.getPluginContainerDeployment());
- }
-
- public Configuration getResourceConfiguration() {
- return resourceConfiguration;
- }
-
- public String getName() {
- return name;
- }
-
- public String getDescription() {
- return description;
- }
-}
diff --git
a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeFacet.java
b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeFacet.java
deleted file mode 100644
index df372bf..0000000
---
a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeFacet.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2010 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.pluginapi.migration;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.rhq.core.domain.resource.ResourceUpgradeReport;
-import org.rhq.core.pluginapi.inventory.ResourceComponent;
-
-/**
- * This interface is to be implemented by discovery classes if they want to support
- * upgrading the existing resources to a new format needed by an updated resource
component.
- * This is useful for example in the case when a new version of plugin redefined a
resource
- * key generation algorithm and wants to upgrade the legacy resources to use the new
format.
- *
- * @author Lukas Krejci
- */
-@SuppressWarnings("unchecked")
-public interface ResourceUpgradeFacet<T extends ResourceComponent> {
-
- /**
- * This method is called on the discovery component straight after it has finished
the discovery.
- * The exact same discovery results are passed to this method along with the set of
resources
- * that already exist in the inventory.
- *
- * @param inventoriedSimblings the existing resources
- * @param parentContext the parent of both the newly discovered and existing
resources
- * @param discoveryResults the discovered resources. The resources from this set that
have
- * the same resource key as one of the inventoried siblings (after upgrade using the
results of this method) won't
- * be reported.
- * @return the mapping of old resources to the newly desired data. The keys are
instances from the
- * inventoriedSiblings set, the values are the upgrade reports detailing what the
data of the
- * corresponding siblings should be upgraded to.
- */
- Map<ResourceUpgradeContext, ResourceUpgradeReport>
upgrade(Set<ResourceUpgradeContext> inventoriedSimblings,
ResourceUpgradeContext<T> parentContext, Set<ResourceUpgradeContext>
discoveryResults);
-}
diff --git
a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeContext.java
b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeContext.java
new file mode 100644
index 0000000..35f5029
--- /dev/null
+++
b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeContext.java
@@ -0,0 +1,89 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.pluginapi.upgrade;
+
+import java.io.File;
+import java.util.concurrent.Executor;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.pluginapi.content.ContentContext;
+import org.rhq.core.pluginapi.event.EventContext;
+import org.rhq.core.pluginapi.inventory.PluginContainerDeployment;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.operation.OperationContext;
+import org.rhq.core.system.SystemInfo;
+
+/**
+ * Represents a resource during the resource upgrade phase of discovery.
+ *
+ * @see ResourceUpgradeFacet
+ *
+ * @author Lukas Krejci
+ */
+@SuppressWarnings("unchecked")
+public class ResourceUpgradeContext<T extends ResourceComponent> extends
ResourceContext<T> {
+
+ private final Configuration resourceConfiguration;
+ private final String name;
+ private final String description;
+
+ /**
+ * @see ResourceContext#ResourceContext(Resource, ResourceComponent,
ResourceDiscoveryComponent, SystemInfo, File, File, String, EventContext,
OperationContext, ContentContext, Executor, PluginContainerDeployment)
+ */
+ public ResourceUpgradeContext(Resource resource, T parentResourceComponent,
+ ResourceDiscoveryComponent resourceDiscoveryComponent, SystemInfo systemInfo,
File temporaryDirectory,
+ File dataDirectory, String pluginContainerName, EventContext eventContext,
OperationContext operationContext,
+ ContentContext contentContext, Executor availCollectorThreadPool,
+ PluginContainerDeployment pluginContainerDeployment) {
+
+ super(resource, parentResourceComponent, resourceDiscoveryComponent, systemInfo,
temporaryDirectory, dataDirectory,
+ pluginContainerName, eventContext, operationContext, contentContext,
availCollectorThreadPool,
+ pluginContainerDeployment);
+
+ this.resourceConfiguration = resource.getResourceConfiguration();
+ this.name = resource.getName();
+ this.description = resource.getDescription();
+ }
+
+ public ResourceUpgradeContext(Resource resource, ResourceDiscoveryComponent
discoveryComponent, ResourceContext<T> context, Executor availCollectorThreadPool)
{
+ this(resource, context.getParentResourceComponent(), discoveryComponent,
context.getSystemInformation(), context.getTemporaryDirectory(),
+ context.getDataDirectory(), context.getPluginContainerName(),
context.getEventContext(), context.getOperationContext(),
+ context.getContentContext(), availCollectorThreadPool,
context.getPluginContainerDeployment());
+ }
+
+ public Configuration getResourceConfiguration() {
+ return resourceConfiguration;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+}
diff --git
a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
new file mode 100644
index 0000000..b68b5df
--- /dev/null
+++
b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
@@ -0,0 +1,58 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.pluginapi.upgrade;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+
+/**
+ * This interface is to be implemented by discovery classes if they want to support
+ * upgrading the existing resources to a new format needed by an updated resource
component.
+ * This is useful for example in the case when a new version of plugin redefined a
resource
+ * key generation algorithm and wants to upgrade the legacy resources to use the new
format.
+ *
+ * @author Lukas Krejci
+ */
+@SuppressWarnings("unchecked")
+public interface ResourceUpgradeFacet<T extends ResourceComponent> {
+
+ /**
+ * This method is called on the discovery component straight after it has finished
the discovery.
+ * The exact same discovery results are passed to this method along with the set of
resources
+ * that already exist in the inventory.
+ *
+ * @param inventoriedSimblings the existing resources
+ * @param parentContext the parent of both the newly discovered and existing
resources
+ * @param discoveryResults the discovered resources. The resources from this set that
have
+ * the same resource key as one of the inventoried siblings (after upgrade using the
results of this method) won't
+ * be reported.
+ * @return the mapping of old resources to the newly desired data. The keys are
instances from the
+ * inventoriedSiblings set, the values are the upgrade reports detailing what the
data of the
+ * corresponding siblings should be upgraded to.
+ */
+ Map<ResourceUpgradeContext, ResourceUpgradeReport>
upgrade(Set<ResourceUpgradeContext> inventoriedSimblings,
ResourceUpgradeContext<T> parentContext, Set<ResourceUpgradeContext>
discoveryResults);
+}
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 feb2d81..866fd79 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
@@ -105,10 +105,10 @@ import org.rhq.core.pluginapi.inventory.ResourceComponent;
import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
-import org.rhq.core.pluginapi.migration.ResourceUpgradeContext;
-import org.rhq.core.pluginapi.migration.ResourceUpgradeFacet;
import org.rhq.core.pluginapi.operation.OperationContext;
import org.rhq.core.pluginapi.operation.OperationServices;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
import org.rhq.core.system.SystemInfo;
import org.rhq.core.system.SystemInfoFactory;
import org.rhq.core.util.exception.ThrowableUtil;
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/RuntimeDiscoveryExecutor.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/RuntimeDiscoveryExecutor.java
index c60d4a8..e31ffda 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/RuntimeDiscoveryExecutor.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/RuntimeDiscoveryExecutor.java
@@ -46,8 +46,8 @@ import org.rhq.core.pc.plugin.PluginComponentFactory;
import org.rhq.core.pluginapi.inventory.ProcessScanResult;
import org.rhq.core.pluginapi.inventory.ResourceComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
-import org.rhq.core.pluginapi.migration.ResourceUpgradeContext;
-import org.rhq.core.pluginapi.migration.ResourceUpgradeFacet;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
import org.rhq.core.util.exception.ExceptionPackage;
import org.rhq.core.util.exception.Severity;
diff --git
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
index 4d80ac1..45887f6 100644
---
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
+++
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
@@ -46,8 +46,8 @@ import org.rhq.core.pluginapi.inventory.ProcessScanResult;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
import org.rhq.core.pluginapi.inventory.ManualAddFacet;
-import org.rhq.core.pluginapi.migration.ResourceUpgradeContext;
-import org.rhq.core.pluginapi.migration.ResourceUpgradeFacet;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
import org.rhq.core.pluginapi.util.FileUtils;
import org.rhq.core.system.ProcessInfo;
import org.rhq.plugins.apache.parser.ApacheConfigReader;
commit 15bea470c93d5a59c69cd8bea3dc0f0c2a728a37
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue May 25 18:17:02 2010 +0200
Update the resource with upgrade data only if the upgrade data is not null.
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 8cc5280..feb2d81 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
@@ -1134,12 +1134,29 @@ public class InventoryManager extends AgentService implements
ContainerService,
}
if (serverUpdated) {
- existingResource.setResourceKey(resourceKey);
- existingResource.setName(name);
- existingResource.setVersion(version);
- existingResource.setDescription(description);
- existingResource.setPluginConfiguration(pluginConfiguration);
- existingResource.setResourceConfiguration(resourceConfiguration);
+ if (resourceKey != null) {
+ existingResource.setResourceKey(resourceKey);
+ }
+
+ if (name != null) {
+ existingResource.setName(name);
+ }
+
+ if (version != null) {
+ existingResource.setVersion(version);
+ }
+
+ if (description != null) {
+ existingResource.setDescription(description);
+ }
+
+ if (pluginConfiguration != null) {
+ existingResource.setPluginConfiguration(pluginConfiguration);
+ }
+
+ if (resourceConfiguration != null) {
+ existingResource.setResourceConfiguration(resourceConfiguration);
+ }
}
return serverUpdated;
commit 5c77f642a72f50fcb0c89613def447c39fcd1308
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue May 25 14:10:02 2010 +0200
First version of plugin-driven resource upgrade.
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 f542f57..cfa2459 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
@@ -37,6 +37,7 @@ import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.domain.resource.ResourceErrorType;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
/**
* The interface to a JON server's resource discovery subsystem.
@@ -137,6 +138,15 @@ public interface DiscoveryServerService {
boolean updateResourceVersion(int resourceId, String version);
/**
+ * Upgrades the data of the resource according to the provided report.
+ *
+ * @param resourceId the id of the resource to be upgraded
+ * @param upgradeReport contains the information about the upgrade
+ * @return true if the upgrade succeeded, false otherwise.
+ */
+ boolean upgradeResource(int resourceId, ResourceUpgradeReport upgradeReport);
+
+ /**
* Gives the server a chance to apply any necessary post-processing that's needed
for newly committed resources
* that have been successfully synchronized on the agent.
*
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
new file mode 100644
index 0000000..52acf09
--- /dev/null
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
@@ -0,0 +1,102 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.io.Serializable;
+
+import org.rhq.core.domain.configuration.Configuration;
+
+/**
+ * Represents the changes that should be applied to the existing resource
+ * in order to upgrade it to conform to the new requirements set by the
+ * changed resource component.
+ * <p>
+ * Null values of the properties mean no change, non-null values represent
+ * the desired new values.
+ *
+ * @author Lukas Krejci
+ */
+public class ResourceUpgradeReport implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private String newResourceKey;
+ private String newName;
+ private String newVersion;
+ private Configuration newPluginConfiguration;
+ private Configuration newResourceConfiguration;
+ private String newDescription;
+
+ public ResourceUpgradeReport() {
+
+ }
+
+ public String getNewResourceKey() {
+ return newResourceKey;
+ }
+
+ public void setNewResourceKey(String newResourceKey) {
+ this.newResourceKey = newResourceKey;
+ }
+
+ public String getNewName() {
+ return newName;
+ }
+
+ public void setNewName(String newName) {
+ this.newName = newName;
+ }
+
+ public String getNewVersion() {
+ return newVersion;
+ }
+
+ public void setNewVersion(String newVersion) {
+ this.newVersion = newVersion;
+ }
+
+ public Configuration getNewPluginConfiguration() {
+ return newPluginConfiguration;
+ }
+
+ public void setNewPluginConfiguration(Configuration newPluginConfiguration) {
+ this.newPluginConfiguration = newPluginConfiguration;
+ }
+
+ public Configuration getNewResourceConfiguration() {
+ return newResourceConfiguration;
+ }
+
+ public void setNewResourceConfiguration(Configuration newResourceConfiguration) {
+ this.newResourceConfiguration = newResourceConfiguration;
+ }
+
+ public String getNewDescription() {
+ return newDescription;
+ }
+
+ public void setNewDescription(String newDescription) {
+ this.newDescription = newDescription;
+ }
+}
diff --git
a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeContext.java
b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeContext.java
new file mode 100644
index 0000000..e8c5f03
--- /dev/null
+++
b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeContext.java
@@ -0,0 +1,89 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.pluginapi.migration;
+
+import java.io.File;
+import java.util.concurrent.Executor;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.pluginapi.content.ContentContext;
+import org.rhq.core.pluginapi.event.EventContext;
+import org.rhq.core.pluginapi.inventory.PluginContainerDeployment;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.operation.OperationContext;
+import org.rhq.core.system.SystemInfo;
+
+/**
+ * Represents a resource during the resource upgrade phase of discovery.
+ *
+ * @see ResourceUpgradeFacet
+ *
+ * @author Lukas Krejci
+ */
+@SuppressWarnings("unchecked")
+public class ResourceUpgradeContext<T extends ResourceComponent> extends
ResourceContext<T> {
+
+ private final Configuration resourceConfiguration;
+ private final String name;
+ private final String description;
+
+ /**
+ * @see ResourceContext#ResourceContext(Resource, ResourceComponent,
ResourceDiscoveryComponent, SystemInfo, File, File, String, EventContext,
OperationContext, ContentContext, Executor, PluginContainerDeployment)
+ */
+ public ResourceUpgradeContext(Resource resource, T parentResourceComponent,
+ ResourceDiscoveryComponent resourceDiscoveryComponent, SystemInfo systemInfo,
File temporaryDirectory,
+ File dataDirectory, String pluginContainerName, EventContext eventContext,
OperationContext operationContext,
+ ContentContext contentContext, Executor availCollectorThreadPool,
+ PluginContainerDeployment pluginContainerDeployment) {
+
+ super(resource, parentResourceComponent, resourceDiscoveryComponent, systemInfo,
temporaryDirectory, dataDirectory,
+ pluginContainerName, eventContext, operationContext, contentContext,
availCollectorThreadPool,
+ pluginContainerDeployment);
+
+ this.resourceConfiguration = resource.getResourceConfiguration();
+ this.name = resource.getName();
+ this.description = resource.getDescription();
+ }
+
+ public ResourceUpgradeContext(Resource resource, ResourceDiscoveryComponent
discoveryComponent, ResourceContext<T> context, Executor availCollectorThreadPool)
{
+ this(resource, context.getParentResourceComponent(), discoveryComponent,
context.getSystemInformation(), context.getTemporaryDirectory(),
+ context.getDataDirectory(), context.getPluginContainerName(),
context.getEventContext(), context.getOperationContext(),
+ context.getContentContext(), availCollectorThreadPool,
context.getPluginContainerDeployment());
+ }
+
+ public Configuration getResourceConfiguration() {
+ return resourceConfiguration;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+}
diff --git
a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeFacet.java
b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeFacet.java
new file mode 100644
index 0000000..df372bf
--- /dev/null
+++
b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeFacet.java
@@ -0,0 +1,58 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.pluginapi.migration;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+
+/**
+ * This interface is to be implemented by discovery classes if they want to support
+ * upgrading the existing resources to a new format needed by an updated resource
component.
+ * This is useful for example in the case when a new version of plugin redefined a
resource
+ * key generation algorithm and wants to upgrade the legacy resources to use the new
format.
+ *
+ * @author Lukas Krejci
+ */
+@SuppressWarnings("unchecked")
+public interface ResourceUpgradeFacet<T extends ResourceComponent> {
+
+ /**
+ * This method is called on the discovery component straight after it has finished
the discovery.
+ * The exact same discovery results are passed to this method along with the set of
resources
+ * that already exist in the inventory.
+ *
+ * @param inventoriedSimblings the existing resources
+ * @param parentContext the parent of both the newly discovered and existing
resources
+ * @param discoveryResults the discovered resources. The resources from this set that
have
+ * the same resource key as one of the inventoried siblings (after upgrade using the
results of this method) won't
+ * be reported.
+ * @return the mapping of old resources to the newly desired data. The keys are
instances from the
+ * inventoriedSiblings set, the values are the upgrade reports detailing what the
data of the
+ * corresponding siblings should be upgraded to.
+ */
+ Map<ResourceUpgradeContext, ResourceUpgradeReport>
upgrade(Set<ResourceUpgradeContext> inventoriedSimblings,
ResourceUpgradeContext<T> parentContext, Set<ResourceUpgradeContext>
discoveryResults);
+}
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AutoDiscoveryExecutor.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AutoDiscoveryExecutor.java
index b84cdbc..e8abbbf 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AutoDiscoveryExecutor.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AutoDiscoveryExecutor.java
@@ -183,7 +183,7 @@ public class AutoDiscoveryExecutor implements Runnable,
Callable<InventoryReport
List<ProcessScanResult> scanResults =
performProcessScans(processInfos, serverType);
Set<Resource> discoveredServers =
this.inventoryManager.executeComponentDiscovery(serverType,
- component, platformComponent, platformContainer.getResourceContext(),
scanResults);
+ component, platformContainer, scanResults);
for (Resource discoveredServer : discoveredServers) {
log.debug("Detected server " + discoveredServer);
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 8944b99..8cc5280 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
@@ -70,6 +70,7 @@ import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceCreationDataType;
import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.domain.resource.ResourceErrorType;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.pc.ContainerService;
import org.rhq.core.pc.PluginContainer;
@@ -104,6 +105,8 @@ import org.rhq.core.pluginapi.inventory.ResourceComponent;
import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+import org.rhq.core.pluginapi.migration.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.migration.ResourceUpgradeFacet;
import org.rhq.core.pluginapi.operation.OperationContext;
import org.rhq.core.pluginapi.operation.OperationServices;
import org.rhq.core.system.SystemInfo;
@@ -1110,6 +1113,38 @@ public class InventoryManager extends AgentService implements
ContainerService,
return resourceContainer.updateAvailability(availabilityType);
}
+ private boolean mergeResourceFromUpgrade(Resource existingResource,
ResourceUpgradeReport upgradeReport) {
+ String resourceKey = upgradeReport.getNewResourceKey();
+ String name = upgradeReport.getNewName();
+ String version = upgradeReport.getNewVersion();
+ String description = upgradeReport.getNewDescription();
+ Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
+ Configuration resourceConfiguration =
upgradeReport.getNewResourceConfiguration();
+
+ boolean serverUpdated = false;
+ try {
+ ServerServices serverServices = this.configuration.getServerServices();
+ if (serverServices != null) {
+ DiscoveryServerService discoveryServerService =
serverServices.getDiscoveryServerService();
+
+ serverUpdated =
discoveryServerService.upgradeResource(existingResource.getId(), upgradeReport);
+ }
+ } catch (Exception e) {
+ log.error("Failed to upgrade the resource [" + existingResource +
"] on the server.", e);
+ }
+
+ if (serverUpdated) {
+ existingResource.setResourceKey(resourceKey);
+ existingResource.setName(name);
+ existingResource.setVersion(version);
+ existingResource.setDescription(description);
+ existingResource.setPluginConfiguration(pluginConfiguration);
+ existingResource.setResourceConfiguration(resourceConfiguration);
+ }
+
+ return serverUpdated;
+ }
+
public Resource mergeResourceFromDiscovery(Resource resource, Resource parent) throws
PluginContainerException {
// If the Resource is already in inventory, make sure its version is up-to-date,
then simply return the
// existing Resource.
@@ -1336,20 +1371,8 @@ public class InventoryManager extends AgentService implements
ContainerService,
parentComponent = getResourceComponent(resource.getParentResource());
}
- File pluginDataDir = new File(this.configuration.getDataDirectory(),
resource.getResourceType().getPlugin());
-
- ResourceContext context = new ResourceContext(resource, // the resource
itself
- parentComponent, // its parent component
- discoveryComponent, // the discovery component (this is actually the
proxy to it)
- SystemInfoFactory.createSystemInfo(), // for native access
- this.configuration.getTemporaryDirectory(), // location for plugin to
write temp files
- pluginDataDir, // location for plugin to write data files
- this.configuration.getContainerName(), // the name of the agent/PC
- getEventContext(resource), // for event access
- getOperationContext(resource), // for operation manager access
- getContentContext(resource), // for content manager access
- this.availabilityCollectors, // for components that want to perform async
avail checking
- this.configuration.getPluginContainerDeployment()); // helps components
make determinations of what to do
+ ResourceContext context = createResourceContext(resource, parentComponent,
discoveryComponent);
+
container.setResourceContext(context);
// Wrap the component in a proxy that will provide locking and a timeout for
the call to start().
@@ -1396,6 +1419,23 @@ public class InventoryManager extends AgentService implements
ContainerService,
}
}
+ private <T extends ResourceComponent> ResourceContext<T>
createResourceContext(Resource resource, T parentComponent,
ResourceDiscoveryComponent<T> discoveryComponent) {
+ File pluginDataDir = new File(this.configuration.getDataDirectory(),
resource.getResourceType().getPlugin());
+
+ return new ResourceContext<T>(resource, // the resource itself
+ parentComponent, // its parent component
+ discoveryComponent, // the discovery component (this is actually the proxy to
it)
+ SystemInfoFactory.createSystemInfo(), // for native access
+ this.configuration.getTemporaryDirectory(), // location for plugin to write
temp files
+ pluginDataDir, // location for plugin to write data files
+ this.configuration.getContainerName(), // the name of the agent/PC
+ getEventContext(resource), // for event access
+ getOperationContext(resource), // for operation manager access
+ getContentContext(resource), // for content manager access
+ this.availabilityCollectors, // for components that want to perform async
avail checking
+ this.configuration.getPluginContainerDeployment()); // helps components make
determinations of what to do
+ }
+
/**
* This will send a resource error to the server (if applicable) to indicate that the
given resource could not be
* connected to due to an invalid plugin configuration.
@@ -1960,8 +2000,12 @@ public class InventoryManager extends AgentService implements
ContainerService,
@NotNull
Set<Resource> executeComponentDiscovery(ResourceType resourceType,
ResourceDiscoveryComponent discoveryComponent,
- ResourceComponent parentComponent, ResourceContext parentResourceContext,
- List<ProcessScanResult> processScanResults) {
+ ResourceContainer parentContainer, List<ProcessScanResult>
processScanResults) {
+
+ ResourceContext parentResourceContext = parentContainer.getResourceContext();
+ ResourceComponent parentComponent = parentContainer.getResourceComponent();
+ Resource parentResource = parentContainer.getResource();
+
long startTime = System.currentTimeMillis();
log.debug("Executing discovery for [" + resourceType.getName() +
"] Resources...");
Set<Resource> newResources;
@@ -2000,6 +2044,59 @@ public class InventoryManager extends AgentService implements
ContainerService,
newResources.add(newResource);
}
}
+
+ //check for upgrade support
+ if (discoveryComponent instanceof ResourceUpgradeFacet) {
+ ResourceUpgradeFacet resourceUpgrade = (ResourceUpgradeFacet)
discoveryComponent;
+
+ Set<Resource> siblings = getResourcesWithType(resourceType,
parentResource.getChildResources());
+
+ Resource grandParent = parentResource.getParentResource();
+ ResourceContainer grandParentContainer = grandParent == null ? null :
getResourceContainer(grandParent);
+ ResourceDiscoveryComponent parentDiscoveryComponent =
PluginContainer.getInstance().getPluginComponentFactory()
+ .getDiscoveryComponent(parentResource.getResourceType(),
grandParentContainer);
+
+ ResourceUpgradeContext<?> parentUpgradeContext = new
ResourceUpgradeContext(parentResource, parentDiscoveryComponent, parentResourceContext,
availabilityCollectors);
+
+ Set<ResourceUpgradeContext> siblingContexts = new
HashSet<ResourceUpgradeContext>(siblings.size());
+
+ Map<ResourceUpgradeContext, Resource> siblingContextToResource =
new HashMap<ResourceUpgradeContext, Resource>();
+
+ for (Resource sibling : siblings) {
+ ResourceUpgradeContext siblingContext = new
ResourceUpgradeContext(sibling, discoveryComponent,
getResourceContainer(sibling).getResourceContext(), availabilityCollectors);
+ siblingContexts.add(siblingContext);
+ siblingContextToResource.put(siblingContext, sibling);
+ }
+
+ Set<ResourceUpgradeContext> newResourceContexts = new
HashSet<ResourceUpgradeContext>();
+ Map<String, Resource> newResourceKeyToResource = new
HashMap<String, Resource>();
+
+ for (Resource newResource : newResources) {
+ ResourceUpgradeContext newUpgradeContext = new
ResourceUpgradeContext(newResource, discoveryComponent, createResourceContext(newResource,
parentComponent, discoveryComponent), availabilityCollectors);
+ newResourceContexts.add(newUpgradeContext);
+ newResourceKeyToResource.put(newResource.getResourceKey(),
newResource);
+ }
+
+ Map<ResourceUpgradeContext, ResourceUpgradeReport> results =
resourceUpgrade.upgrade(siblingContexts, parentUpgradeContext, newResourceContexts);
+
+ for(Map.Entry<ResourceUpgradeContext, ResourceUpgradeReport>
upgradeEntry : results.entrySet()) {
+ Resource siblingToUpgrade =
siblingContextToResource.get(upgradeEntry.getKey());
+ ResourceUpgradeReport newData = upgradeEntry.getValue();
+
+ mergeResourceFromUpgrade(siblingToUpgrade, newData);
+
+ //if there was a resource key upgrade, remove a resource with the
same resource key
+ //from the discovery results. Otherwise we'd end up with 2
sibling resources with
+ //the same resource key, which is illegal.
+ if (newData.getNewResourceKey() != null) {
+ Resource newResourceToRemove =
newResourceKeyToResource.get(newData.getNewResourceKey());
+ if (newResourceToRemove != null) {
+ newResources.remove(newResourceToRemove);
+ }
+ }
+ }
+ }
+
} catch (Throwable e) {
// TODO GH: Add server/parent - up/down semantics so this won't happen
just because a server is not up
long elapsedTime = System.currentTimeMillis() - startTime;
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/RuntimeDiscoveryExecutor.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/RuntimeDiscoveryExecutor.java
index c16ba56..c60d4a8 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/RuntimeDiscoveryExecutor.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/RuntimeDiscoveryExecutor.java
@@ -43,8 +43,11 @@ import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.pc.PluginContainer;
import org.rhq.core.pc.PluginContainerConfiguration;
import org.rhq.core.pc.plugin.PluginComponentFactory;
+import org.rhq.core.pluginapi.inventory.ProcessScanResult;
import org.rhq.core.pluginapi.inventory.ResourceComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.migration.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.migration.ResourceUpgradeFacet;
import org.rhq.core.util.exception.ExceptionPackage;
import org.rhq.core.util.exception.Severity;
@@ -237,8 +240,8 @@ public class RuntimeDiscoveryExecutor implements Runnable,
Callable<InventoryRep
+ childResourceType + "]");
}
Set<Resource> childResources =
this.inventoryManager.executeComponentDiscovery(childResourceType,
- discoveryComponent, parentComponent,
parentContainer.getResourceContext(), Collections.EMPTY_LIST);
-
+ discoveryComponent, parentContainer,
Collections.<ProcessScanResult>emptyList());
+
// For each discovered resource, update it in the inventory manager and
recursively discover its child resources
Map<String, Resource> mergedResources = new HashMap<String,
Resource>();
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 cded63b..2d3e9e6 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
@@ -56,6 +56,7 @@ import org.rhq.core.domain.resource.ProductVersion;
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.ResourceUpgradeReport;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.domain.util.PageOrdering;
@@ -400,6 +401,19 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
}
}
+ public boolean upgradeResource(int resourceId, ResourceUpgradeReport upgradeReport)
{
+ Resource existingResource = this.entityManager.find(Resource.class, resourceId);
+ if (existingResource != null) {
+ boolean changed = upgradeResource(existingResource, upgradeReport);
+ if (changed) {
+ this.entityManager.merge(existingResource);
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
/**
* Convienence method that looks at <code>resource</code> and if its
version is not
* the same as <code>newVersion</code>, its version string will be set to
it. If
@@ -445,6 +459,81 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
return versionChanged;
}
+ /**
+ * @param existingResource
+ * @param upgradeReport
+ * @return
+ */
+ private boolean upgradeResource(Resource resource, ResourceUpgradeReport
upgradeReport) {
+ boolean changed = false;
+ if (resource != null) {
+ String resourceKey = upgradeReport.getNewResourceKey();
+ String name = upgradeReport.getNewName();
+ String version = upgradeReport.getNewVersion();
+ String description = upgradeReport.getNewDescription();
+ Configuration pluginConfiguration =
upgradeReport.getNewPluginConfiguration();
+ Configuration resourceConfiguration =
upgradeReport.getNewResourceConfiguration();
+
+ if (resourceKey != null) {
+ if (!equalOrNull(resourceKey, resource.getResourceKey())) {
+ log.info("Resource [" + resource + "] upgraded its
resource key from [" +
+ resource.getResourceKey() + "] to [" + resourceKey +
"]");
+ changed = true;
+ resource.setResourceKey(resourceKey);
+ }
+ }
+
+ if (name != null) {
+ if (!equalOrNull(name, resource.getName())) {
+ log.info("Resource [" + resource + "] upgraded its
name from [" +
+ resource.getName() + "] to [" + name + "]");
+ changed = true;
+ resource.setName(name);
+ }
+ }
+
+ if (version != null) {
+ changed = updateResourceVersion(resource, version) || changed;
+ }
+
+ if (description != null) {
+ if (!equalOrNull(description, resource.getDescription())) {
+ log.info("Resource [" + resource + "] upgraded its
description from [" +
+ resource.getDescription() + "] to [" + description +
"]");
+ changed = true;
+ resource.setDescription(description);
+ }
+ }
+
+ if (pluginConfiguration != null) {
+ if (!equalOrNull(pluginConfiguration, resource.getPluginConfiguration()))
{
+ log.info("Resource [" + resource + "] upgraded its
plugin configuration from [" +
+ resource.getPluginConfiguration() + "] to [" +
pluginConfiguration + "]");
+ changed = true;
+ resource.setPluginConfiguration(pluginConfiguration);
+ }
+ }
+
+ if (resourceConfiguration != null) {
+ if (!equalOrNull(resourceConfiguration,
resource.getResourceConfiguration())) {
+ //XXX Will this create a new history entry?
+
+ log.info("Resource [" + resource + "] upgraded its
resource configuration from [" +
+ resource.getResourceConfiguration() + "] to [" +
resourceConfiguration + "]");
+
+ changed = true;
+ resource.setResourceConfiguration(resourceConfiguration);
+ }
+ }
+
+ // If the resource was marked as deleted, reactivate it again.
+ if (resource.getInventoryStatus() == InventoryStatus.DELETED) {
+ resource.setInventoryStatus(InventoryStatus.COMMITTED);
+ }
+ }
+ return changed;
+ }
+
private void validateInventoryReport(InventoryReport report) throws
InvalidInventoryReportException {
for (Resource root : report.getAddedRoots()) {
validateResource(root);
@@ -793,4 +882,16 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
updateInventoryStatus(subject, platforms, servers, target);
}
+
+ private static <T> boolean equalOrNull(T a, T b) {
+ if (a == null) {
+ return b == null;
+ } else {
+ if (b == null) {
+ return false;
+ } else {
+ return a.equals(b);
+ }
+ }
+ }
}
\ No newline at end of file
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 01394b9..4e60ffb 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
@@ -38,6 +38,7 @@ import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
@@ -176,4 +177,13 @@ public interface DiscoveryBossLocal extends DiscoveryBossRemote {
* <code>false</code> if the Resource was not in inventory
*/
boolean updateResourceVersion(int resourceId, String version);
+
+ /**
+ * Upgrades the data of the resource according to the provided report.
+ *
+ * @param resourceId the id of the resource to be upgraded
+ * @param upgradeReport contains the information about the upgrade
+ * @return true if the upgrade succeeded, false otherwise.
+ */
+ boolean upgradeResource(int resourceId, ResourceUpgradeReport upgradeReport);
}
\ No newline at end of file
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 d692ad8..720465e 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
@@ -37,6 +37,7 @@ import org.rhq.core.domain.resource.Agent;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceError;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.util.collection.ArrayUtils;
import org.rhq.core.util.exception.ThrowableUtil;
import org.rhq.enterprise.server.alert.AlertDefinitionCreationException;
@@ -176,6 +177,11 @@ public class DiscoveryServerServiceImpl implements
DiscoveryServerService {
return discoveryBoss.updateResourceVersion(resourceId, version);
}
+ public boolean upgradeResource(int resourceId, ResourceUpgradeReport upgradeReport)
{
+ DiscoveryBossLocal discoveryBoss = LookupUtil.getDiscoveryBoss();
+ return discoveryBoss.upgradeResource(resourceId, upgradeReport);
+ }
+
private static Resource convertToPojoResource(Resource resource, boolean
includeDescendants) {
Resource pojoResource = new Resource(resource.getId());
pojoResource.setUuid(resource.getUuid());
diff --git
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
index 8f6deb7..4d80ac1 100644
---
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
+++
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
@@ -21,8 +21,10 @@ package org.rhq.plugins.apache;
import java.io.File;
import java.io.IOException;
import java.net.URI;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
@@ -36,12 +38,16 @@ import org.rhq.augeas.util.GlobFilter;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.Property;
import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
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.ProcessScanResult;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+import org.rhq.core.pluginapi.inventory.ManualAddFacet;
+import org.rhq.core.pluginapi.migration.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.migration.ResourceUpgradeFacet;
import org.rhq.core.pluginapi.util.FileUtils;
import org.rhq.core.system.ProcessInfo;
import org.rhq.plugins.apache.parser.ApacheConfigReader;
@@ -63,7 +69,8 @@ import
org.rhq.rhqtransform.impl.PluginDescriptorBasedAugeasConfiguration;
* @author Ian Springer
* @author Lukas Krejci
*/
-public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponent<PlatformComponent>,
ManualAddFacet<PlatformComponent> {
+public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponent<PlatformComponent>,
ManualAddFacet<PlatformComponent>,
+ ResourceUpgradeFacet<PlatformComponent> {
private static final String PRODUCT_DESCRIPTION = "Apache Web Server";
private static final Log log =
LogFactory.getLog(ApacheServerDiscoveryComponent.class);
@@ -163,7 +170,46 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
return discoveredResources;
}
-
+ public Map<ResourceUpgradeContext, ResourceUpgradeReport>
upgrade(Set<ResourceUpgradeContext> inventoriedSimblings,
+ ResourceUpgradeContext<PlatformComponent> parentContext,
Set<ResourceUpgradeContext> discoveryResults) {
+
+ Map<ResourceUpgradeContext, ResourceUpgradeReport> ret = new
HashMap<ResourceUpgradeContext, ResourceUpgradeReport>();
+
+ for (ResourceUpgradeContext context : inventoriedSimblings) {
+ String inventoriedResourceKey = context.getResourceKey();
+ File inventoriedResourceKeyAsPath = new File(inventoriedResourceKey);
+
+ //the resource key we use now is a full path to the httpdconf.
+ //in the old version, it was the server root.
+ //so if the inventoried resource key is a path to a file,
+ //we know it's a new style resource key.
+ if (inventoriedResourceKeyAsPath.isFile()) {
+ continue;
+ }
+
+ Configuration pluginConfiguration = context.getPluginConfiguration();
+
+ String serverRoot =
pluginConfiguration.getSimpleValue("serverRoot", null);
+ String httpdConf = pluginConfiguration.getSimpleValue("configFile",
null);
+
+ String resourceKey = null;
+
+ if (httpdConf != null) {
+ File httpdConfFile = new File(httpdConf);
+ if (!httpdConfFile.isAbsolute()) {
+ httpdConfFile = new File(serverRoot, httpdConf);
+ }
+
+ resourceKey = httpdConfFile.getPath();
+
+ ResourceUpgradeReport rep = new ResourceUpgradeReport();
+ rep.setNewResourceKey(resourceKey);
+
+ ret.put(context, rep);
+ }
+ }
+ return ret;
+ }
public DiscoveredResourceDetails discoverResource(Configuration pluginConfig,
ResourceDiscoveryContext<PlatformComponent> discoveryContext)