diff --git a/etc/samples/mbeans-on-as7-plugin/pom.xml b/etc/samples/mbeans-on-as7-plugin/pom.xml index 38c87d23a70..0643057a74e 100644 --- a/etc/samples/mbeans-on-as7-plugin/pom.xml +++ b/etc/samples/mbeans-on-as7-plugin/pom.xml @@ -46,7 +46,7 @@ org.rhq.maven.plugins rhq-agent-plugin-plugin - 0.6 + 1.0-SNAPSHOT true @@ -65,13 +65,16 @@ ${buildTime} + ${rhq.version} 127.0.0.1 7080 rhqadmin rhqadmin - true + false + true false - ${rhq.version} + false + 300 diff --git a/modules/core/arquillian-integration/container/src/main/java/org/rhq/test/arquillian/FakeServerInventory.java b/modules/core/arquillian-integration/container/src/main/java/org/rhq/test/arquillian/FakeServerInventory.java index 8c56ff1b270..e2fd9df96f1 100644 --- a/modules/core/arquillian-integration/container/src/main/java/org/rhq/test/arquillian/FakeServerInventory.java +++ b/modules/core/arquillian-integration/container/src/main/java/org/rhq/test/arquillian/FakeServerInventory.java @@ -395,6 +395,11 @@ public int getId() { resp.setUpgradedResourceDescription(resource.getDescription()); } + if (request.getNewVersion() != null) { + resource.setVersion(request.getNewVersion()); + resp.setUpgradedResourceVersion(resource.getVersion()); + } + if (request.getNewName() != null) { resource.setName(request.getNewName()); resp.setUpgradedResourceName(resource.getName()); diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/discovery/DiscoveryAgentService.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/discovery/DiscoveryAgentService.java index 042ed49335c..8ed8674bb31 100644 --- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/discovery/DiscoveryAgentService.java +++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/discovery/DiscoveryAgentService.java @@ -33,9 +33,7 @@ import org.rhq.core.domain.discovery.MergeResourceResponse; import org.rhq.core.domain.discovery.PlatformSyncInfo; import org.rhq.core.domain.discovery.ResourceSyncInfo; -import org.rhq.core.domain.measurement.AvailabilityType; import org.rhq.core.domain.resource.Resource; -import org.rhq.core.domain.resource.ResourceError; import org.rhq.core.domain.resource.ResourceType; /** @@ -129,13 +127,13 @@ void updatePluginConfiguration(int resourceId, Configuration newPluginConfigurat AvailabilityReport executeAvailabilityScanImmediately(boolean changedOnlyReport); /** - * Returns the current availability for the specified resource. + * Return an availability report for the specified root resource and its descendants. *

- * This call returns an availability report (rather just a simple availability of a single resource) - * because it also scans for the changes in availability in the child resources. Notice that the returned report may - * contain no results if {@code changesOnly} is set to true. If it is false, the report will always contain - * the availability of the supplied resource but can also additionally contain the availabilities of some of its - * child resources, if they were eligible for availability collection at the time of calling this method. + * The returned report may contain no results if {@code changesOnly} is set to true. Otherwise it will return + * the availability of the root resource and its descendants. Note, a live availability check (i.e. a call + * to getAvailability()) is always performed on the root resource. Only descendants normally eligible for + * availability collection at the time of this call will also have live availability. Others will report their + * most recently reported availability. *

* Also note that the availability types of the resources in the report may have any of the following values from * the {@link AvailabilityType} enum - it may happen that the availability of the resource is @@ -146,13 +144,10 @@ void updatePluginConfiguration(int resourceId, Configuration newPluginConfigurat * correctly handle the report within the server. * * @param resource the resource to return the availability of. - * @param changesOnly if true, only changes in availability will be reported, if false the report will contain - * the availabilities of all resources eligible for collection at the time of the call regardless - * of whether their availability changed or not. - * @return an availability report containing at least the availability of the supplied resource + possibly avails - * of some of the child resources that were eligible for avail collection at the time. The rest of the - * children are scheduled for availability collection in the next collector run (which happens - * approximately 30 seconds after this call). + * @param changesOnly if true, only changes in availability will be reported. if false the report will contain + * the availabilities of the root resource and all descendants, whether their availability + * changed or not. + * @return an availability report populated as described in the above options. */ @NotNull AvailabilityReport getCurrentAvailability(Resource resource, boolean changesOnly); 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 bc26a1efff4..3d99a890b41 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 @@ -31,7 +31,7 @@ /** * Represents a request to upgrade a resource. - * + * * @author Lukas Krejci */ public class ResourceUpgradeRequest extends ResourceUpgradeReport { @@ -119,6 +119,8 @@ public void fillInFromReport(ResourceUpgradeReport report) { setNewName(report.getNewName()); setNewResourceKey(report.getNewResourceKey()); setNewPluginConfiguration(report.getNewPluginConfiguration()); + setNewVersion(report.getNewVersion()); + setForceGenericPropertyUpgrade(report.isForceGenericPropertyUpgrade()); } public void fillInFromResource(Resource resource) { @@ -126,6 +128,7 @@ public void fillInFromResource(Resource resource) { setNewName(resource.getName()); setNewResourceKey(resource.getResourceKey()); setNewPluginConfiguration(resource.getPluginConfiguration()); + setNewVersion(resource.getVersion()); } public void updateResource(Resource resource) { @@ -144,6 +147,10 @@ public void updateResource(Resource resource) { if (getNewPluginConfiguration() != null) { resource.setPluginConfiguration(getNewPluginConfiguration()); } + + if (getNewVersion() != null) { + resource.setVersion(getNewVersion()); + } } /** @@ -154,6 +161,8 @@ public void clearUpgradeData() { setNewName(null); setNewResourceKey(null); setNewPluginConfiguration(null); + setNewVersion(null); + setForceGenericPropertyUpgrade(false); } @Override @@ -183,9 +192,8 @@ public boolean equals(Object other) { @Override public String toString() { - return "ResourceUpgradeRequest[resourceId = '" + resourceId + "', newResourceKey = '" + getNewResourceKey() - + "', newName = '" + getNewName() + "', newDescription = '" + getNewDescription() - + "', hasNewPluginConfig = '" + (null != getNewPluginConfiguration()) + "', upgradeErrorMessage = '" - + upgradeErrorMessage + "', upgradeErrorStackTrace = '" + upgradeErrorStackTrace + "']"; + return "ResourceUpgradeRequest [resourceId=" + resourceId + ", upgradeErrorMessage=" + upgradeErrorMessage + + ", upgradeErrorStackTrace=" + upgradeErrorStackTrace + ", timestamp=" + timestamp + ", toString()=" + + super.toString() + "]"; } } 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 index b4cd1cfb520..7adb05c0c1b 100644 --- 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 @@ -31,22 +31,22 @@ * 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 = 2L; + private static final long serialVersionUID = 3L; private int resourceId; - + private String upgradedResourceName; private String upgradedResourceKey; private String upgradedResourceDescription; + private String upgradedResourceVersion; private Configuration upgradedResourcePluginConfiguration; - + public ResourceUpgradeResponse() { - } public int getResourceId() { @@ -85,6 +85,14 @@ public void setUpgradedResourceDescription(String upgradedResourceDescription) { this.upgradedResourceDescription = upgradedResourceDescription; } + public String getUpgradedResourceVersion() { + return upgradedResourceVersion; + } + + public void setUpgradedResourceVersion(String upgradedResourceVersion) { + this.upgradedResourceVersion = upgradedResourceVersion; + } + public void setUpgradedResourcePluginConfiguration(Configuration upgradedResourcePluginConfiguration) { this.upgradedResourcePluginConfiguration = upgradedResourcePluginConfiguration; } diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/configuration/ConfigurationServerService.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/configuration/ConfigurationServerService.java index e9e5b36c449..c5aa87e90ee 100644 --- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/configuration/ConfigurationServerService.java +++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/configuration/ConfigurationServerService.java @@ -25,8 +25,6 @@ import org.rhq.core.communications.command.annotation.Asynchronous; import org.rhq.core.communications.command.annotation.LimitedConcurrency; import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.ConfigurationUpdateStatus; -import org.rhq.core.domain.configuration.Property; /** * Interface that allows an agent to provide information about a resource's configuration. @@ -71,4 +69,18 @@ public interface ConfigurationServerService { @LimitedConcurrency(CONCURRENCY_LIMIT_CONFIG_UPDATE) void persistUpdatedResourceConfiguration(int resourceId, Configuration resourceConfiguration); + /** + * This is for when the agent needs to notify the server that a new Plugin configuration has been + * discovered on the agent side. This happens when resource discovery discovers a new version of a resource. + * The properties set by discovery are merged into the existing config, and need to be updated + * server-side. + * + * @param resourceId the resourceId to update + * @param resourceConfiguration the newly detected configuration + * + * @return The persisted plugin configuration + */ + @LimitedConcurrency(CONCURRENCY_LIMIT_CONFIG_UPDATE) + Configuration persistUpdatedPluginConfiguration(int resourceId, Configuration pluginConfiguration); + } \ No newline at end of file diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/AlertCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/AlertCriteria.java index 3bd12bb11d5..7023b0cafff 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/AlertCriteria.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/AlertCriteria.java @@ -60,6 +60,7 @@ public class AlertCriteria extends Criteria { private List filterPriorities; // requires overrides private String filterResourceTypeId; // requires overrides private String filterResourceTypeName; // requires overrides + private String filterPluginName; // requires overrides private List filterResourceIds; // requires overrides private List filterResourceGroupIds; // requires overrides private List filterAlertDefinitionIds; // requires overrides @@ -88,6 +89,7 @@ public AlertCriteria() { filterOverrides.put("priorities", "alertDefinition.priority IN ( ? )"); filterOverrides.put("resourceTypeId", "alertDefinition.resource.resourceType.id = ?"); filterOverrides.put("resourceTypeName", "alertDefinition.resource.resourceType.name like ?"); + filterOverrides.put("pluginName", "alertDefinition.resource.resourceType.plugin like ?"); filterOverrides.put("resourceIds", "alertDefinition.resource.id IN ( ? )"); filterOverrides.put("resourceGroupIds", "alertDefinition.resource.id IN " // + "( SELECT res.id " // @@ -143,6 +145,10 @@ public void addFilterResourceTypeName(String filterResourceTypeName) { this.filterResourceTypeName = filterResourceTypeName; } + public void addFilterPluginName(String filterPluginName) { + this.filterPluginName = filterPluginName; + } + public void addFilterEntityContext(EntityContext filterEntityContext) { if (filterEntityContext.getType() == EntityContext.Type.Resource) { addFilterResourceIds(filterEntityContext.getResourceId()); diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/MeasurementDefinitionCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/MeasurementDefinitionCriteria.java index c0d0045b637..0455f7541da 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/MeasurementDefinitionCriteria.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/MeasurementDefinitionCriteria.java @@ -45,6 +45,7 @@ public class MeasurementDefinitionCriteria extends Criteria { private String filterDisplayName; private String filterDescription; private String filterResourceTypeName; // requires overrides + private String filterPluginName; // requires overrides private Integer filterResourceTypeId; // requires overrides private MeasurementCategory filterCategory; private MeasurementUnits filterUnits; @@ -69,6 +70,7 @@ public class MeasurementDefinitionCriteria extends Criteria { public MeasurementDefinitionCriteria() { filterOverrides.put("resourceTypeName", "resourceType.name like ?"); + filterOverrides.put("pluginName", "resourceType.plugin like ?"); filterOverrides.put("resourceTypeId", "resourceType.id = ?"); sortOverrides.put("resourceTypeName", "resourceType.name"); @@ -95,6 +97,10 @@ public void addFilterResourceTypeName(String filterResourceTypeName) { this.filterResourceTypeName = filterResourceTypeName; } + public void addFilterPluginName(String filterPluginName) { + this.filterPluginName = filterPluginName; + } + public void addFilterResourceTypeId(Integer filterResourceTypeId) { this.filterResourceTypeId = filterResourceTypeId; } 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 a47d86ae0a2..2619a20b43c 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 @@ -28,8 +28,8 @@ 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 + * 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. *

* Null values of the properties mean no change, non-null values represent @@ -38,30 +38,31 @@ * Configuration updates are limited to only changing values for existing * properties. The Configuration must still reflect the types configuration * definition. Also, updates must be judicious as config values can also - * be updated by users. - * + * be updated by users. + * * @author Lukas Krejci */ public class ResourceUpgradeReport implements Serializable { - private static final long serialVersionUID = 2L; + private static final long serialVersionUID = 3L; private String newResourceKey; private String newName; - - // version changes are handled differently. - // private String newVersion; - + // version changes are typically handled differently, but in certain cases may be done here. + private String newVersion; + private String newDescription; // Plugin configuration changes must still conform to the configuration definition. private Configuration newPluginConfiguration; // Is resource config update useful? Wouldn't resource config change discovery handle this? // private Configuration newResourceConfiguration; - private String newDescription; + // In some cases assume the plugin knows best, and let it force upgrade of what we call "generic" resource + // properties (name, description). If set to true by the plugin code the server will obey, + // regardless of the value of SystemSetting.ALLOW_RESOURCE_GENERIC_PROPERTIES_UPGRADE. + private boolean forceGenericPropertyUpgrade = false; public ResourceUpgradeReport() { - } public String getNewResourceKey() { @@ -80,13 +81,14 @@ public void setNewName(String newName) { this.newName = newName; } - // public String getNewVersion() { - // return newVersion; - // } - // - // public void setNewVersion(String newVersion) { - // this.newVersion = newVersion; - // } + public String getNewVersion() { + return newVersion; + } + + public void setNewVersion(String newVersion) { + this.newVersion = newVersion; + } + // // public Configuration getNewResourceConfiguration() { // return newResourceConfiguration; @@ -109,18 +111,38 @@ public Configuration getNewPluginConfiguration() { } /** - * See class javadoc for restrictions. + * See class javadoc for restrictions. */ public void setNewPluginConfiguration(Configuration newPluginConfiguration) { this.newPluginConfiguration = newPluginConfiguration; } + public boolean isForceGenericPropertyUpgrade() { + return forceGenericPropertyUpgrade; + } + + /** + * In some cases assume the plugin knows best. Set true (with care) to force upgrade of what we call "generic" + * resource properties (name, description). If set to true by the plugin code the server will obey, + * regardless of the value of SystemSetting.ALLOW_RESOURCE_GENERIC_PROPERTIES_UPGRADE, which is false by default + * in order to protect hand-edited resource names. + * + * @param forceGenericPropertyUpgrade + */ + public void setForceGenericPropertyUpgrade(boolean forceGenericPropertyUpgrade) { + this.forceGenericPropertyUpgrade = forceGenericPropertyUpgrade; + } + public boolean hasSomethingToUpgrade() { - return newResourceKey != null || newName != null || newDescription != null || newPluginConfiguration != null; + return newResourceKey != null || newName != null || newVersion != null || newDescription != null + || newPluginConfiguration != null; } + @Override public String toString() { - return "ResourceUpgradeReport[newResourceKey = '" + newResourceKey + "', newName = '" + newName - + "', newDescription = '" + newDescription + "']"; + return "ResourceUpgradeReport [newResourceKey=" + newResourceKey + ", newName=" + newName + ", newVersion=" + + newVersion + ", newDescription=" + newDescription + ", newPluginConfiguration=" + newPluginConfiguration + + ", forceGenericPropertyUpgrade=" + forceGenericPropertyUpgrade + "]"; } + } 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 index c4056866dbd..5b309232411 100644 --- 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 @@ -46,6 +46,7 @@ public class ResourceUpgradeContext> extends Reso private final Configuration resourceConfiguration; private final String name; private final String description; + private final String version; /** * @see ResourceContext#ResourceContext(org.rhq.core.domain.resource.Resource, org.rhq.core.pluginapi.inventory.ResourceComponent, org.rhq.core.pluginapi.inventory.ResourceContext, org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent, org.rhq.core.system.SystemInfo, java.io.File, java.io.File, String, org.rhq.core.pluginapi.event.EventContext, org.rhq.core.pluginapi.operation.OperationContext, org.rhq.core.pluginapi.content.ContentContext, org.rhq.core.pluginapi.availability.AvailabilityContext, org.rhq.core.pluginapi.inventory.InventoryContext, org.rhq.core.pluginapi.inventory.PluginContainerDeployment) @@ -65,11 +66,10 @@ public ResourceUpgradeContext(Resource resource, ResourceContext parentResour this.resourceConfiguration = resource.getResourceConfiguration(); this.name = resource.getName(); this.description = resource.getDescription(); + this.version = resource.getVersion(); } /** - * Returns the context of the Resource component's parent Resource component. - * * @return the context of the Resource component's parent Resource component * * @since 4.0 @@ -91,4 +91,8 @@ public String getDescription() { return description; } + public String getVersion() { + return version; + } + } 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 9a7d685f305..6d395cab167 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 @@ -61,6 +61,7 @@ import org.rhq.core.clientapi.agent.metadata.ResourceTypeNotEnabledException; import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest; import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeResponse; +import org.rhq.core.clientapi.server.configuration.ConfigurationServerService; import org.rhq.core.clientapi.server.discovery.DiscoveryServerService; import org.rhq.core.clientapi.server.discovery.InvalidInventoryReportException; import org.rhq.core.clientapi.server.discovery.InventoryReport; @@ -68,6 +69,7 @@ import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.ConfigurationUtility; import org.rhq.core.domain.configuration.Property; +import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.discovery.AvailabilityReport; import org.rhq.core.domain.discovery.MergeInventoryReportResults; import org.rhq.core.domain.discovery.MergeInventoryReportResults.ResourceTypeFlyweight; @@ -1692,16 +1694,18 @@ public void mergeResourcesFromUpgrade(Set upgradeRequest String resourceKey = upgradeResponse.getUpgradedResourceKey(); String name = upgradeResponse.getUpgradedResourceName(); String description = upgradeResponse.getUpgradedResourceDescription(); + String version = upgradeResponse.getUpgradedResourceVersion(); Configuration pluginConfig = upgradeResponse.getUpgradedResourcePluginConfiguration(); //only bother if there's something to upgrade at all on this resource. - if (resourceKey != null || name != null || description != null || pluginConfig != null) { + if (resourceKey != null || name != null || version != null || description != null + || pluginConfig != null) { ResourceContainer existingResourceContainer = getResourceContainer(upgradeResponse.getResourceId()); if (existingResourceContainer != null) { Resource existingResource = existingResourceContainer.getResource(); StringBuilder logMessage = new StringBuilder("Resource [").append(existingResource.toString()) - .append("] upgraded its "); + .append("] upgraded ["); if (resourceKey != null) { existingResource.setResourceKey(resourceKey); @@ -1713,6 +1717,11 @@ public void mergeResourcesFromUpgrade(Set upgradeRequest logMessage.append("name, "); } + if (version != null) { + existingResource.setVersion(version); + logMessage.append("version, "); + } + if (description != null) { existingResource.setDescription(description); logMessage.append("description, "); @@ -1723,7 +1732,7 @@ public void mergeResourcesFromUpgrade(Set upgradeRequest logMessage.append("pluginConfiguration, "); } - logMessage.replace(logMessage.length() - 1, logMessage.length(), "to become [") + logMessage.replace(logMessage.length() - 1, logMessage.length(), "] to become [") .append(existingResource.toString()).append("]"); log.info(logMessage.toString()); @@ -1737,11 +1746,21 @@ public void mergeResourcesFromUpgrade(Set upgradeRequest } 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. + // If the Resource is already in inventory, make sure its version is up to date. If the version + // has been updated make sure the plugin config is up-to-date. Then simply return the existing Resource. Resource existingResource = findMatchingChildResource(resource, parent); if (existingResource != null) { - updateResourceVersion(existingResource, resource.getVersion()); + if (mergeExistingResource(existingResource, resource)) { + try { + refreshResourceComponentState(getResourceContainer(existingResource), true); + } catch (Exception e) { + log.warn( + "Failed to refresh resource component after version change. Resource=" + + existingResource + + ". Will continue with old container. The resource may not perform as expected until after a plugin container restart.", + e); + } + } return existingResource; } @@ -1804,6 +1823,130 @@ public Resource mergeResourceFromDiscovery(Resource resource, Resource parent) t return resource; } + /** + * @param existingResource Current resource for reskey X + * @param discoveredResource Discovered resource for reskey X + * @return true if the version (and possibly pluginConfig) have been updated in the existing resource. Otherwise false. + */ + private boolean mergeExistingResource(Resource existingResource, Resource discoveredResource) { + String existingVersion = existingResource.getVersion(); + String discoveredVersion = discoveredResource.getVersion(); + boolean versionChanged = (existingVersion != null) ? !existingVersion.equals(discoveredVersion) + : discoveredVersion != null && !discoveredVersion.isEmpty(); + if (versionChanged) { + if (log.isDebugEnabled()) { + log.debug("Discovery reported that version of [" + existingResource + "] changed from [" + + existingVersion + "] to [" + discoveredVersion + "]"); + } + + boolean versionUpdated = existingResource.getInventoryStatus() != InventoryStatus.COMMITTED + || mergeExistingResourceVersionOnServer(existingResource, discoveredVersion); + + // If the version has been updated make sure we also update the plugin config if it has been updated. + if (versionUpdated) { + Configuration mergedPluginConfiguration = mergeExistingResourcePluginConfiguration(existingResource, + discoveredResource.getPluginConfiguration()); + + // Only update the version in local inventory if the server syncs succeeded, otherwise we won't know + // to try again the next time this method is called. + // TODO: It would be safer to combine the two possible server syncs into one server/transaction + if (null != mergedPluginConfiguration) { + existingResource.setVersion(discoveredVersion); + existingResource.setPluginConfiguration(mergedPluginConfiguration); + log.info("Version of [" + existingResource + "] changed from [" + existingVersion + "] to [" + + discoveredVersion + "]"); + + return true; + } + } + } + + return false; + } + + private boolean mergeExistingResourceVersionOnServer(Resource resource, String newVersion) { + boolean versionUpdated = false; + ServerServices serverServices = this.configuration.getServerServices(); + if (serverServices != null) { + try { + DiscoveryServerService discoveryServerService = serverServices.getDiscoveryServerService(); + discoveryServerService.updateResourceVersion(resource.getId(), newVersion); + // Only update the version in local inventory if the server sync succeeded, otherwise we won't know + // to try again the next time this method is called. + versionUpdated = true; + if (log.isDebugEnabled()) { + log.debug("New version for [" + resource + "] (" + newVersion + + ") was successfully synced to the Server."); + } + } catch (Exception e) { + log.error("Failed to sync-to-Server new version for [" + resource + "]"); + } + } else { + if (log.isDebugEnabled()) { + log.debug("Sync-to-Server of new version for [" + resource + + "] cannot be done, because Plugin Container is not connected to Server."); + } + } + return versionUpdated; + } + + private Configuration mergeExistingResourcePluginConfiguration(Resource resource, Configuration pluginConfig) { + + // If there is no update necessary just return the current plugin config of the existing resource + Configuration result = resource.getPluginConfiguration(); + + ConfigurationDefinition configDef = resource.getResourceType().getPluginConfigurationDefinition(); + if (null == configDef) { + return result; + } + + Configuration existingPluginConfig = resource.getPluginConfiguration().deepCopy(false); + Configuration defaultPluginConfig = ConfigurationUtility.createDefaultConfiguration(configDef); + boolean configChanged = false; + + // for each property, update the existing plugin config if discovery has set a non-default value + for (String propertyName : pluginConfig.getAllProperties().keySet()) { + Property discoveredProp = pluginConfig.get(propertyName); + Property defaultProp = defaultPluginConfig.get(propertyName); + if (!discoveredProp.equals(defaultProp)) { + if (log.isDebugEnabled()) { + log.debug("Discovery reported a new version of " + resource + ". Updating value of config property" + + " from [" + existingPluginConfig.get(propertyName) + "] to [" + discoveredProp + "]."); + } + existingPluginConfig.put(discoveredProp); + configChanged = true; + } + } + + if (configChanged) { + result = mergeExistingResourcePluginConfigurationOnServer(resource, existingPluginConfig); + } + + return result; + } + + private Configuration mergeExistingResourcePluginConfigurationOnServer(Resource resource, + Configuration updatedPluginConfig) { + + Configuration result = null; + ServerServices serverServices = this.configuration.getServerServices(); + + if (serverServices != null) { + try { + ConfigurationServerService configServerService = serverServices.getConfigurationServerService(); + result = configServerService.persistUpdatedPluginConfiguration(resource.getId(), updatedPluginConfig); + } catch (Exception e) { + log.error("Failed to sync-to-Server new plugin configuration for [" + resource + "]"); + } + } else { + if (log.isDebugEnabled()) { + log.debug("Sync-to-Server of new plugin configuration for [" + resource + + "] cannot be done, because Plugin Container is not connected to Server."); + } + } + return result; + } + /** * During initialization time, the inventory manager will active resources after loading them * from disk. Any other manager that starts up and is initialized after the Inventory Manager @@ -2936,51 +3079,6 @@ private InventoryContext getInventoryContext(Resource resource) { return inventoryContext; } - private void updateResourceVersion(Resource resource, String version) { - String existingVersion = resource.getVersion(); - boolean versionChanged = (existingVersion != null) ? !existingVersion.equals(version) : version != null - && !version.isEmpty(); - if (versionChanged) { - if (log.isDebugEnabled()) { - log.debug("Discovery reported that version of [" + resource + "] changed from [" + existingVersion - + "] to [" + version + "]"); - } - boolean versionShouldBeUpdated = resource.getInventoryStatus() != InventoryStatus.COMMITTED - || updateResourceVersionOnServer(resource, version); - if (versionShouldBeUpdated) { - resource.setVersion(version); - log.info("Version of [" + resource + "] changed from [" + existingVersion + "] to [" + version + "]"); - } - } - } - - private boolean updateResourceVersionOnServer(Resource resource, String newVersion) { - boolean versionUpdated = false; - ServerServices serverServices = this.configuration.getServerServices(); - if (serverServices != null) { - try { - DiscoveryServerService discoveryServerService = serverServices.getDiscoveryServerService(); - discoveryServerService.updateResourceVersion(resource.getId(), newVersion); - // Only update the version in local inventory if the server sync succeeded, otherwise we won't know - // to try again the next time this method is called. - versionUpdated = true; - if (log.isDebugEnabled()) { - log.debug("New version for [" + resource + "] (" + newVersion - + ") was successfully synced to the Server."); - } - } catch (Exception e) { - log.error("Failed to sync-to-Server new version for [" + resource + "]"); - } - // TODO: It would be cool to publish a Resource-version-changed Event here. (ips, 02/29/08) - } else { - if (log.isDebugEnabled()) { - log.debug("Sync-to-Server of new version for [" + resource - + "] cannot be done, because Plugin Container is not connected to Server."); - } - } - return versionUpdated; - } - private void processSyncInfo(Collection syncInfos, Set syncedResources, Set unknownResourceSyncInfos, Set modifiedResourceIds, Set deletedResourceIds, Set newlyCommittedResources, Set ignoredResources) { 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 f5ebb5d3634..9963adcf8aa 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 @@ -209,6 +209,11 @@ public int getId() { resp.setUpgradedResourceDescription(resource.getDescription()); } + if (request.getNewVersion() != null) { + resource.setVersion(request.getNewVersion()); + resp.setUpgradedResourceVersion(resource.getVersion()); + } + if (request.getNewName() != null) { resource.setName(request.getNewName()); resp.setUpgradedResourceName(resource.getName()); diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/RhqManager.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/RhqManager.java index 95cdf228952..3831cbb6b80 100644 --- a/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/RhqManager.java +++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/RhqManager.java @@ -28,6 +28,7 @@ import org.rhq.enterprise.server.configuration.ConfigurationManagerRemote; import org.rhq.enterprise.server.content.ContentManagerRemote; import org.rhq.enterprise.server.content.RepoManagerRemote; +import org.rhq.enterprise.server.core.AgentManagerRemote; import org.rhq.enterprise.server.discovery.DiscoveryBossRemote; import org.rhq.enterprise.server.drift.DriftManagerRemote; import org.rhq.enterprise.server.drift.DriftTemplateManagerRemote; @@ -40,6 +41,7 @@ import org.rhq.enterprise.server.measurement.MeasurementDefinitionManagerRemote; import org.rhq.enterprise.server.measurement.MeasurementScheduleManagerRemote; import org.rhq.enterprise.server.operation.OperationManagerRemote; +import org.rhq.enterprise.server.plugin.ServerPluginsRemote; import org.rhq.enterprise.server.report.DataAccessManagerRemote; import org.rhq.enterprise.server.resource.ResourceFactoryManagerRemote; import org.rhq.enterprise.server.resource.ResourceManagerRemote; @@ -60,6 +62,10 @@ * @author Greg Hinkle */ public enum RhqManager { + /** + * @since 4.12 + */ + AgentManager(AgentManagerRemote.class, "${AgentManager}"), // AlertManager(AlertManagerRemote.class, "${AlertManager}"), // AlertDefinitionManager(AlertDefinitionManagerRemote.class, "${AlertDefinitionManager}"), // AvailabilityManager(AvailabilityManagerRemote.class, "${AvailabilityManager}"), // @@ -79,18 +85,20 @@ public enum RhqManager { MeasurementDefinitionManager(MeasurementDefinitionManagerRemote.class, "${MeasurementDefinitionManager}"), // MeasurementScheduleManager(MeasurementScheduleManagerRemote.class, "${MeasurementScheduleManager}"), // OperationManager(OperationManagerRemote.class, "${OperationManager}"), // - /** * @since 4.11 */ PluginManager(PluginManagerRemote.class, "${PluginManagerRemote}"), // - ResourceManager(ResourceManagerRemote.class, "${ResourceManager}"), // ResourceFactoryManager(ResourceFactoryManagerRemote.class, "${ResourceFactoryManager}"), // ResourceGroupManager(ResourceGroupManagerRemote.class, "${ResourceGroupManager}"), // ResourceTypeManager(ResourceTypeManagerRemote.class, "${ResourceTypeManager}"), // RoleManager(RoleManagerRemote.class, "${RoleManager}"), // SavedSearchManager(SavedSearchManagerRemote.class, "${SavedSearchManager}"), // + /** + * @since 4.12 + */ + ServerPluginManager(ServerPluginsRemote.class, "${ServerPluginManager}"), // StorageNodeManager(StorageNodeManagerRemote.class, "${StorageNodeManager}"), // SubjectManager(SubjectManagerRemote.class, "${SubjectManager}"), // SupportManager(SupportManagerRemote.class, "${SupportManager}"), // diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/menu/MenuBarView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/menu/MenuBarView.java index c8d5f9f72ea..4d4c173c200 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/menu/MenuBarView.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/menu/MenuBarView.java @@ -285,7 +285,9 @@ private String createBarContent() { +"" +"" +"" - +"" + + "" +"" +"" +"