summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Mazzitelli <mazz@redhat.com>2009-12-03 15:07:22 -0500
committerJohn Mazzitelli <mazz@redhat.com>2009-12-03 15:07:22 -0500
commitcaf869ff17ba3db281f566c630bc7a629e7cc3ff (patch)
tree19e69abddeaf7e82e218672dc893465c11fddcab
parent53bf8a99306b88c55fc782e748ad5f7801299341 (diff)
downloadmazzrepo-caf869ff17ba3db281f566c630bc7a629e7cc3ff.tar.gz
mazzrepo-caf869ff17ba3db281f566c630bc7a629e7cc3ff.tar.xz
mazzrepo-caf869ff17ba3db281f566c630bc7a629e7cc3ff.zip
this is a patch that is a proof-of-concept to get RHQ to support configuration remediationHEADmaster
-rw-r--r--rhq-config-remediation-patch.txt552
1 files changed, 552 insertions, 0 deletions
diff --git a/rhq-config-remediation-patch.txt b/rhq-config-remediation-patch.txt
new file mode 100644
index 0000000..dbb5935
--- /dev/null
+++ b/rhq-config-remediation-patch.txt
@@ -0,0 +1,552 @@
+From 6aeb74f8938a2f8d390cbe8062b7a55a70cdd5a6 Mon Sep 17 00:00:00 2001
+From: John Mazzitelli <mazz@redhat.com>
+Date: Tue, 1 Dec 2009 13:17:12 -0500
+Subject: [PATCH 1/3] first attempt at config freeze
+
+---
+ .../src/main/scripts/dbsetup/inventory-schema.xml | 1 +
+ .../core/domain/configuration/Configuration.java | 16 +++---
+ .../org/rhq/core/domain/resource/Resource.java | 15 ++++++
+ .../history/ListConfigurationUpdateUIBean.java | 50 ++++++++++++++++++++
+ .../rhq/resource/configuration/history.xhtml | 14 ++++-
+ .../configuration/ConfigurationManagerBean.java | 48 ++++++++++++++++++-
+ .../configuration/ConfigurationManagerLocal.java | 22 +++++++--
+ .../ConfigurationServerServiceImpl.java | 24 ++++++++-
+ 8 files changed, 168 insertions(+), 22 deletions(-)
+
+diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/inventory-schema.xml b/modules/core/dbutils/src/main/scripts/dbsetup/inventory-schema.xml
+index 2f25ff1..6c4eba6 100644
+--- a/modules/core/dbutils/src/main/scripts/dbsetup/inventory-schema.xml
++++ b/modules/core/dbutils/src/main/scripts/dbsetup/inventory-schema.xml
+@@ -93,6 +93,7 @@
+ <column name="CTIME" type="LONG"/>
+ <column name="MTIME" type="LONG"/>
+ <column name="ITIME" type="LONG"/>
++ <column name="FROZEN_RES_CONFIG_ID" type="INTEGER" references="RHQ_CONFIG"/>
+ <column name="RES_CONFIGURATION_ID" type="INTEGER" references="RHQ_CONFIG"/>
+ <column name="PLUGIN_CONFIGURATION_ID" type="INTEGER" references="RHQ_CONFIG"/>
+ <column name="MODIFIED_BY" required="false" type="INTEGER"/>
+diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java
+index 62bd8ce..530ec65 100644
+--- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java
++++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/Configuration.java
+@@ -32,10 +32,10 @@ import java.io.ObjectOutput;
+ import java.io.ObjectOutputStream;
+ import java.util.Collection;
+ import java.util.HashMap;
++import java.util.HashSet;
+ import java.util.LinkedHashMap;
+ import java.util.Map;
+ import java.util.Set;
+-import java.util.HashSet;
+
+ import javax.persistence.Column;
+ import javax.persistence.Entity;
+@@ -104,6 +104,8 @@ import org.rhq.core.domain.util.serial.HibernateUtil;
+ + "select r.pluginConfiguration from Resource r where r.id = :resourceId"),
+ @NamedQuery(name = Configuration.QUERY_GET_RESOURCE_CONFIG_BY_RESOURCE_ID, query = "" //
+ + "select r.resourceConfiguration from Resource r where r.id = :resourceId"),
++ @NamedQuery(name = Configuration.QUERY_GET_FROZEN_RESOURCE_CONFIG_BY_RESOURCE_ID, query = "" //
++ + "select r.frozenResourceConfiguration from Resource r where r.id = :resourceId"),
+ @NamedQuery(name = Configuration.QUERY_GET_RESOURCE_CONFIG_MAP_BY_GROUP_ID, query = "" //
+ + "SELECT r.id, r.resourceConfiguration " //
+ + " FROM ResourceGroup rg " //
+@@ -137,6 +139,7 @@ public class Configuration implements Externalizable, Cloneable, AbstractPropert
+
+ public static final String QUERY_GET_PLUGIN_CONFIG_BY_RESOURCE_ID = "Configuration.getPluginConfigByResourceId";
+ public static final String QUERY_GET_RESOURCE_CONFIG_BY_RESOURCE_ID = "Configuration.getResourceConfigByResourceId";
++ public static final String QUERY_GET_FROZEN_RESOURCE_CONFIG_BY_RESOURCE_ID = "Configuration.getFrozenResourceConfigByResourceId";
+ public static final String QUERY_GET_RESOURCE_CONFIG_MAP_BY_GROUP_ID = "Configuration.getResourceConfigMapByGroupId";
+ public static final String QUERY_GET_PLUGIN_CONFIG_MAP_BY_GROUP_ID = "Configuration.getPluginConfigMapByGroupId";
+ public static final String QUERY_GET_RESOURCE_CONFIG_MAP_BY_GROUP_UPDATE_ID = "Configuration.getResourceConfigMapByGroupUpdateId";
+@@ -157,7 +160,7 @@ public class Configuration implements Externalizable, Cloneable, AbstractPropert
+ private Map<String, Property> properties = new LinkedHashMap<String, Property>();
+
+ @OneToMany(mappedBy = "configuration", fetch = FetchType.EAGER)
+- @Cascade({CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DELETE_ORPHAN})
++ @Cascade( { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DELETE_ORPHAN })
+ private Set<RawConfiguration> rawConfigurations = new HashSet<RawConfiguration>();
+
+ @Column(name = "NOTES")
+@@ -581,11 +584,7 @@ public class Configuration implements Externalizable, Cloneable, AbstractPropert
+ builder.append("], rawConfigurations[");
+
+ for (RawConfiguration rawConfig : rawConfigurations) {
+- builder.append("[")
+- .append(rawConfig.getPath())
+- .append(", ")
+- .append(rawConfig.getSha256())
+- .append("]");
++ builder.append("[").append(rawConfig.getPath()).append(", ").append(rawConfig.getSha256()).append("]");
+ }
+ builder.append("]");
+ }
+@@ -650,7 +649,8 @@ public class Configuration implements Externalizable, Cloneable, AbstractPropert
+ out.writeLong(ctime);
+ out.writeLong(mtime);
+ }
+- // Explicitly do not send the history relationship
++
++ // Explicitly do not send the history relationship
+ private Map<String, Property> createDeepCopyOfMap() {
+ Map<String, Property> copy = new HashMap<String, Property>();
+ for (Map.Entry<String, Property> entry : this.properties.entrySet()) {
+diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/Resource.java b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/Resource.java
+index 0c4b284..f9fa6cc 100644
+--- a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/Resource.java
++++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/Resource.java
+@@ -89,6 +89,15 @@ import org.rhq.core.domain.util.serial.ExternalizableStrategy;
+ */
+ @Entity
+ @NamedQueries( {
++
++ @NamedQuery(name = Resource.UPDATE_SET_FROZEN_RES_CONFIG, query = "" //
++ + "UPDATE Resource r "
++ + " SET r.frozenResourceConfiguration = (SELECT ch.configuration FROM ResourceConfigurationUpdate ch WHERE ch.id = :configUpdateId)"
++ + " WHERE r.id=:id"),
++ @NamedQuery(name = Resource.UPDATE_UNSET_FROZEN_RES_CONFIG, query = "" //
++ + "UPDATE Resource r " //
++ + " SET r.frozenResourceConfiguration = NULL" //
++ + " WHERE r.id=:id"),
+ @NamedQuery(name = Resource.QUERY_FIND_PROBLEM_RESOURCES_ALERT_ADMIN, query = "" //
+ + " SELECT DISTINCT new org.rhq.core.domain.resource.composite.ProblemResourceComposite"
+ + " ( "
+@@ -852,6 +861,8 @@ public class Resource implements Comparable<Resource>, Externalizable {
+
+ public static final String QUERY_RESOURCE_REPORT = "Resource.findResourceReport";
+ public static final String QUERY_RESOURCE_VERSION_REPORT = "Resource.findResourceVersionReport";
++ public static final String UPDATE_SET_FROZEN_RES_CONFIG = "Resource.updateSetFrozenResourceConfig";
++ public static final String UPDATE_UNSET_FROZEN_RES_CONFIG = "Resource.updateUnsetFrozenResourceConfig";
+
+ private static final long serialVersionUID = 1L;
+
+@@ -922,6 +933,10 @@ public class Resource implements Comparable<Resource>, Externalizable {
+ @XmlTransient
+ private Resource parentResource;
+
++ @JoinColumn(name = "FROZEN_RES_CONFIG_ID", referencedColumnName = "ID")
++ @OneToOne(cascade = {}, fetch = FetchType.LAZY)
++ private Configuration frozenResourceConfiguration = null;
++
+ @JoinColumn(name = "RES_CONFIGURATION_ID", referencedColumnName = "ID")
+ @OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY)
+ private Configuration resourceConfiguration = new Configuration();
+diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/history/ListConfigurationUpdateUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/history/ListConfigurationUpdateUIBean.java
+index b3839fc..ab03167 100644
+--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/history/ListConfigurationUpdateUIBean.java
++++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/history/ListConfigurationUpdateUIBean.java
+@@ -59,6 +59,56 @@ public class ListConfigurationUpdateUIBean extends PagedDataTableUIBean {
+ return dataModel;
+ }
+
++ public String unfreeze() {
++ try {
++ Subject subject = EnterpriseFacesContextUtility.getSubject();
++ Resource resource = EnterpriseFacesContextUtility.getResource();
++ ConfigurationManagerLocal manager = LookupUtil.getConfigurationManager();
++
++ manager.unfreezeResourceConfiguration(subject, resource.getId());
++
++ FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Unfroze resource configuration");
++ } catch (Exception e) {
++ FacesContextUtility
++ .addMessage(FacesMessage.SEVERITY_ERROR,
++ "Failed to unfreeze resource configuration to version. Cause: "
++ + ThrowableUtil.getAllMessages(e, true));
++ }
++
++ return "success";
++ }
++
++ public String freeze() {
++ String rollbackTo = null;
++
++ try {
++ rollbackTo = FacesContextUtility.getRequest().getParameter("selectedItems");
++
++ Subject subject = EnterpriseFacesContextUtility.getSubject();
++ Resource resource = EnterpriseFacesContextUtility.getResource();
++ ConfigurationManagerLocal manager = LookupUtil.getConfigurationManager();
++
++ manager.rollbackResourceConfiguration(subject, resource.getId(), Integer.parseInt(rollbackTo));
++
++ // We've just updated the current Configuration, so clear the current Configuration that is cached in the
++ // Session, so the config view/edit pages will not display a stale version of the Configuration.
++ ExistingResourceConfigurationUIBean configUIBean = FacesContextUtility
++ .getManagedBean(ExistingResourceConfigurationUIBean.class);
++ configUIBean.clearConfiguration();
++
++ manager.freezeResourceConfiguration(subject, resource.getId(), Integer.parseInt(rollbackTo));
++
++ FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO,
++ "Rolled back and froze resource configuration to version " + rollbackTo);
++ } catch (Exception e) {
++ FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR,
++ "Failed to rollback resource configuration to version " + rollbackTo + ". Cause: "
++ + ThrowableUtil.getAllMessages(e, true));
++ }
++
++ return "success";
++ }
++
+ public String rollback() {
+ String rollbackTo = null;
+
+diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/history.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/history.xhtml
+index ac824f8..0b126bf 100644
+--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/history.xhtml
++++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/history.xhtml
+@@ -186,14 +186,22 @@
+ <rich:columnGroup>
+ <rich:column colspan="#{ResourceUIBean.permissions.configure ? 7 : 6}" width="100%">
+ <onc:selectCommandButton action="#{ListConfigurationUpdateUIBean.delete}"
+- value="DELETE SELECTED" target="selectedItems"
++ value="DELETE" target="selectedItems"
+ styleClass="on-pager-button buttonsmall"
+ rendered="${ResourceUIBean.permissions.configure}"/>
+ <onc:selectCommandButton action="#{ListConfigurationUpdateUIBean.compare}"
+- value="COMPARE SELECTED" low="2" high="2" target="selectedItems"
++ value="COMPARE" low="2" high="2" target="selectedItems"
+ styleClass="on-pager-button buttonsmall" rendered="false"/>
+ <onc:selectCommandButton action="#{ListConfigurationUpdateUIBean.rollback}"
+- value="ROLLBACK TO SELECTED" high="1" target="selectedItems"
++ value="ROLLBACK" high="1" target="selectedItems"
++ styleClass="on-pager-button buttonsmall"
++ rendered="${ResourceUIBean.permissions.configure}"/>
++ <onc:selectCommandButton action="#{ListConfigurationUpdateUIBean.freeze}"
++ value="FREEZE" low="1" high="1" target="selectedItems"
++ styleClass="on-pager-button buttonsmall"
++ rendered="${ResourceUIBean.permissions.configure}"/>
++ <h:commandButton action="#{ListConfigurationUpdateUIBean.unfreeze}"
++ value="UNFREEZE"
+ styleClass="on-pager-button buttonsmall"
+ rendered="${ResourceUIBean.permissions.configure}"/>
+
+diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java
+index 6a7d327..b61a522 100644
+--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java
++++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java
+@@ -20,12 +20,12 @@ package org.rhq.enterprise.server.configuration;
+
+ import java.util.ArrayList;
+ import java.util.Calendar;
++import java.util.Collection;
++import java.util.Collections;
+ import java.util.HashMap;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.Set;
+-import java.util.Collections;
+-import java.util.Collection;
+
+ import javax.ejb.EJB;
+ import javax.ejb.Stateless;
+@@ -57,8 +57,8 @@ import org.rhq.core.domain.configuration.Configuration;
+ import org.rhq.core.domain.configuration.ConfigurationUpdateStatus;
+ import org.rhq.core.domain.configuration.PluginConfigurationUpdate;
+ import org.rhq.core.domain.configuration.Property;
+-import org.rhq.core.domain.configuration.ResourceConfigurationUpdate;
+ import org.rhq.core.domain.configuration.RawConfiguration;
++import org.rhq.core.domain.configuration.ResourceConfigurationUpdate;
+ import org.rhq.core.domain.configuration.composite.ConfigurationUpdateComposite;
+ import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
+ import org.rhq.core.domain.configuration.group.AbstractGroupConfigurationUpdate;
+@@ -135,6 +135,29 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf
+ @EJB
+ private SubjectManagerLocal subjectManager;
+
++ @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
++ public void freezeResourceConfiguration(Subject subject, int resourceId, int configUpdateId) {
++ Query q = entityManager.createNamedQuery(Resource.UPDATE_SET_FROZEN_RES_CONFIG);
++ q.setParameter("id", resourceId);
++ q.setParameter("configUpdateId", configUpdateId);
++ int rows = q.executeUpdate();
++ if (rows != 1) {
++ throw new RuntimeException("Failed to freeze configuration for resource " + resourceId);
++ }
++ return;
++ }
++
++ @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
++ public void unfreezeResourceConfiguration(Subject subject, int resourceId) {
++ Query q = entityManager.createNamedQuery(Resource.UPDATE_UNSET_FROZEN_RES_CONFIG);
++ q.setParameter("id", resourceId);
++ int rows = q.executeUpdate();
++ if (rows != 1) {
++ throw new RuntimeException("Failed to unfreeze configuration for resource " + resourceId);
++ }
++ return;
++ }
++
+ @Nullable
+ public @XmlJavaTypeAdapter(ConfigurationAdapter.class)
+ Configuration getPluginConfiguration(Subject subject, int resourceId) {
+@@ -292,6 +315,25 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf
+ return result;
+ }
+
++ // Use new transaction because this only works if the resource in question has not
++ // yet been loaded by Hibernate. We want the query to return a non-proxied configuration,
++ // this is critical for remote API use.
++ @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
++ public Configuration getFrozenResourceConfiguration(int resourceId) {
++ // Ensure that we return a non-proxied Configuration object that can survive after the
++ // Hibernate session goes away.
++ Query query = entityManager.createNamedQuery(Configuration.QUERY_GET_FROZEN_RESOURCE_CONFIG_BY_RESOURCE_ID);
++ query.setParameter("resourceId", resourceId);
++ Configuration result;
++ try {
++ result = (Configuration) query.getSingleResult();
++ } catch (NoResultException nre) {
++ result = null;
++ }
++
++ return result;
++ }
++
+ @Nullable
+ public ResourceConfigurationUpdate getLatestResourceConfigurationUpdate(Subject subject, int resourceId) {
+ log.debug("Getting current resource configuration for resource [" + resourceId + "]");
+diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java
+index f96a454..6c48837 100644
+--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java
++++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java
+@@ -18,8 +18,15 @@
+ */
+ package org.rhq.enterprise.server.configuration;
+
++import java.util.Collection;
++import java.util.List;
++import java.util.Map;
++
++import javax.ejb.Local;
++
+ import org.jetbrains.annotations.Nullable;
+ import org.quartz.SchedulerException;
++
+ import org.rhq.core.clientapi.server.configuration.ConfigurationUpdateResponse;
+ import org.rhq.core.domain.auth.Subject;
+ import org.rhq.core.domain.configuration.AbstractResourceConfigurationUpdate;
+@@ -41,11 +48,6 @@ import org.rhq.core.domain.util.PageList;
+ import org.rhq.enterprise.server.configuration.job.GroupPluginConfigurationUpdateJob;
+ import org.rhq.enterprise.server.resource.ResourceNotFoundException;
+
+-import javax.ejb.Local;
+-import java.util.Collection;
+-import java.util.List;
+-import java.util.Map;
+-
+ /**
+ * The configuration manager which allows you to request resource configuration changes, view current resource
+ * configuration and previous update history and view/edit plugin configuration.
+@@ -56,6 +58,10 @@ import java.util.Map;
+ @Local
+ public interface ConfigurationManagerLocal {
+
++ void freezeResourceConfiguration(Subject subject, int resourceId, int configUpdateId);
++
++ void unfreezeResourceConfiguration(Subject subject, int resourceId);
++
+ /**
+ * Updates the plugin configuration used to connect and communicate with the resource using the information in the
+ * passed {@link PluginConfigurationUpdate} object. This update object will be changed to reflect the result of the
+@@ -80,6 +86,12 @@ public interface ConfigurationManagerLocal {
+ */
+ Configuration getResourceConfiguration(int resourceId);
+
++ /** This does not perform permission checks and should be used internally only. In general, use
++ * {@link #getCurrentResourceConfiguration}.
++ * @throws FetchException TODO
++ */
++ Configuration getFrozenResourceConfiguration(int resourceId);
++
+ /**
+ * Get the currently live resource configuration for the {@link Resource} with the given id. This actually asks for
+ * the up-to-date configuration directly from the agent. An exception will be thrown if communications with the
+diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationServerServiceImpl.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationServerServiceImpl.java
+index 8932607..91dc3fa 100644
+--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationServerServiceImpl.java
++++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationServerServiceImpl.java
+@@ -64,11 +64,11 @@ public class ConfigurationServerServiceImpl implements ConfigurationServerServic
+ }
+
+ public void persistUpdatedResourceConfiguration(int resourceId, Configuration resourceConfiguration) {
+- ConfigurationManagerLocal configurationManager = LookupUtil.getConfigurationManager();
++ final ConfigurationManagerLocal configurationManager = LookupUtil.getConfigurationManager();
+ SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
+ ResourceManagerLocal resourceManager = LookupUtil.getResourceManager();
+
+- Subject overlord = subjectManager.getOverlord();
++ final Subject overlord = subjectManager.getOverlord();
+ ResourceConfigurationUpdate update = configurationManager.persistNewResourceConfigurationUpdateHistory(
+ overlord, resourceId, resourceConfiguration, ConfigurationUpdateStatus.SUCCESS, null, false);
+
+@@ -80,8 +80,26 @@ public class ConfigurationServerServiceImpl implements ConfigurationServerServic
+ }
+ }
+
+- Resource resource = update.getResource();
++ final Resource resource = update.getResource();
+ resource.setResourceConfiguration(update.getConfiguration().deepCopy(false));
+ resourceManager.updateResource(overlord, resource);
++
++ final Configuration frozen = configurationManager.getFrozenResourceConfiguration(resourceId);
++ if (frozen != null && !frozen.equals(resourceConfiguration)) {
++ // this resource has been frozen and the agent is trying to change it! revert back immediately!
++ new Thread(new Runnable() {
++ public void run() {
++ try {
++ Thread.sleep(5000L);
++ } catch (InterruptedException e) {
++ }
++ try {
++ configurationManager.updateResourceConfiguration(overlord, resource.getId(), frozen);
++ } catch (Exception e) {
++ LOG.error("cannot revert configuration back to its frozen state for resource : " + resource);
++ }
++ }
++ }, "RHQ Revert To Frozen Config For Resource " + resourceId).start();
++ }
+ }
+ }
+\ No newline at end of file
+--
+1.6.2.5
+
+
+From 2e23715078139c5110439c5b9f2abbfaac05a834 Mon Sep 17 00:00:00 2001
+From: John Mazzitelli <mazz@redhat.com>
+Date: Tue, 1 Dec 2009 16:14:05 -0500
+Subject: [PATCH 2/3] get frozen config to take effect if we view live config and its different than the frozen config
+
+---
+ .../configuration/ConfigurationManagerBean.java | 23 ++++++++++++++++++++
+ 1 files changed, 23 insertions(+), 0 deletions(-)
+
+diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java
+index b61a522..b87ac56 100644
+--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java
++++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java
+@@ -426,6 +426,29 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf
+ this.subjectManager.getOverlord(), resource.getId(), liveConfig, ConfigurationUpdateStatus.SUCCESS, null,
+ false);
+ resource.setResourceConfiguration(liveConfig.deepCopy(false));
++
++ Configuration frozen = getFrozenResourceConfiguration(resource.getId());
++ if (frozen != null && !frozen.equals(resource.getResourceConfiguration())) {
++ try {
++ Subject overlord = subjectManager.getOverlord();
++ update = persistNewResourceConfigurationUpdateHistory(overlord, resource.getId(), frozen,
++ ConfigurationUpdateStatus.INPROGRESS, overlord.getName(), false);
++ resource.setResourceConfiguration(frozen);
++ final ResourceConfigurationUpdate updateToPush = update;
++ new Thread(new Runnable() {
++ public void run() {
++ try {
++ Thread.sleep(5000L);
++ } catch (InterruptedException e) {
++ }
++ executeResourceConfigurationUpdate(updateToPush);
++ }
++ }, "RHQ Frozen Config Revert For Resource " + resource.getName()).start();
++ } catch (Exception e) {
++ log.error("cannot revert configuration back to its frozen state for resource : " + resource);
++ }
++ }
++
+ return update;
+ }
+
+--
+1.6.2.5
+
+
+From 3e380264a1220ba6e5270fb807f54117742a5348 Mon Sep 17 00:00:00 2001
+From: John Mazzitelli <mazz@redhat.com>
+Date: Tue, 1 Dec 2009 16:14:44 -0500
+Subject: [PATCH 3/3] more frozen config changes
+
+---
+ .../GetLatestConfigurationUpdateUIBean.java | 16 ++++++++++++++++
+ .../rhq/resource/configuration/history.xhtml | 2 ++
+ .../ConfigurationServerServiceImpl.java | 4 ++--
+ 3 files changed, 20 insertions(+), 2 deletions(-)
+
+diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/history/GetLatestConfigurationUpdateUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/history/GetLatestConfigurationUpdateUIBean.java
+index fb397a2..892b74b 100644
+--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/history/GetLatestConfigurationUpdateUIBean.java
++++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/history/GetLatestConfigurationUpdateUIBean.java
+@@ -20,6 +20,7 @@ package org.rhq.enterprise.gui.configuration.history;
+
+ import org.rhq.core.domain.auth.Subject;
+ import org.rhq.core.domain.configuration.AbstractResourceConfigurationUpdate;
++import org.rhq.core.domain.configuration.Configuration;
+ import org.rhq.core.domain.resource.Resource;
+ import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility;
+ import org.rhq.enterprise.server.configuration.ConfigurationManagerLocal;
+@@ -27,6 +28,8 @@ import org.rhq.enterprise.server.util.LookupUtil;
+
+ public class GetLatestConfigurationUpdateUIBean {
+ private AbstractResourceConfigurationUpdate latestConfigurationUpdate = null;
++ private Configuration frozenConfiguration = null;
++ private Boolean frozenConfigurationIsNull = null;
+
+ public AbstractResourceConfigurationUpdate getLatestConfigurationUpdate() {
+ if (latestConfigurationUpdate == null) {
+@@ -39,4 +42,17 @@ public class GetLatestConfigurationUpdateUIBean {
+
+ return latestConfigurationUpdate;
+ }
++
++ public Configuration getFrozenConfiguration() {
++ if (frozenConfiguration == null) {
++ // TODO need a frozeConfigurationIsNull check
++ Resource resource = EnterpriseFacesContextUtility.getResource();
++ ConfigurationManagerLocal manager = LookupUtil.getConfigurationManager();
++
++ frozenConfiguration = manager.getFrozenResourceConfiguration(resource.getId());
++ frozenConfigurationIsNull = Boolean.valueOf(frozenConfiguration == null);
++ }
++
++ return frozenConfiguration;
++ }
+ }
+\ No newline at end of file
+diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/history.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/history.xhtml
+index 0b126bf..89522ed 100644
+--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/history.xhtml
++++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/history.xhtml
+@@ -21,6 +21,7 @@
+ <ui:define name="content">
+
+ <ui:param name="latestConfig" value="#{GetLatestConfigurationUpdateUIBean.latestConfigurationUpdate}"/>
++<ui:param name="frozenConfig" value="#{GetLatestConfigurationUpdateUIBean.frozenConfiguration}"/>
+
+ <h:form id="historyForm">
+ <input type="hidden" name="id" value="${ResourceUIBean.id}"/>
+@@ -113,6 +114,7 @@
+ <f:param name="configId" value="#{item.id}"/>
+ <h:outputText value="#{item.id}"/>
+ <h:outputText value="*" rendered="#{latestConfig.id == item.id}"/>
++ <h:outputText value="+" rendered="#{not empty item.configuration and item.configuration.id == frozenConfig.id}"/>
+ <h:outputText value=" (selected)"
+ rendered="#{!empty param.configId and param.configId == item.id}"/>
+ </h:outputLink>
+diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationServerServiceImpl.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationServerServiceImpl.java
+index 91dc3fa..c8b8ce6 100644
+--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationServerServiceImpl.java
++++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationServerServiceImpl.java
+@@ -72,8 +72,8 @@ public class ConfigurationServerServiceImpl implements ConfigurationServerServic
+ ResourceConfigurationUpdate update = configurationManager.persistNewResourceConfigurationUpdateHistory(
+ overlord, resourceId, resourceConfiguration, ConfigurationUpdateStatus.SUCCESS, null, false);
+
+- if (LOG.isDebugEnabled()) {
+- if (update == null) {
++ if (update == null) {
++ if (LOG.isDebugEnabled()) {
+ LOG.debug("Not persisting Configuration " + resourceConfiguration
+ + ", since it is identical to the current revision.");
+ return;
+--
+1.6.2.5
+