[rhq] modules/plugins
by Heiko W. Rupp
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java | 5 -
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/LoggerComponent.java | 20 ++++
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ModClusterComponent.java | 41 ++++++++++
modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml | 17 +++-
4 files changed, 76 insertions(+), 7 deletions(-)
New commits:
commit 92720a0332994653d44f773e4685d0b6ea6384ba
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Mon Nov 7 13:09:29 2011 +0100
BZ 736481 - Fix the missing ':' errors.
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
index 0ad794c..0aba2d3 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
@@ -429,8 +429,9 @@ public class BaseComponent<T extends ResourceComponent<?>> implements ResourceCo
Configuration parameters) throws InterruptedException, Exception {
if (!name.contains(":")) {
- OperationResult badName = new OperationResult("Operation name did not contain a ':'");
- badName.setErrorMessage("Operation name did not contain a ':'");
+ String simpleResult = "Operation with name [" + name + "] did not contain a ':'";
+ OperationResult badName = new OperationResult(simpleResult);
+ badName.setErrorMessage(simpleResult);
return badName;
}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/LoggerComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/LoggerComponent.java
index 67df4d9..f9ff8a3 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/LoggerComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/LoggerComponent.java
@@ -18,6 +18,8 @@
*/
package org.rhq.modules.plugins.jbossas7;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
@@ -25,6 +27,7 @@ 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.PropertySimple;
import org.rhq.core.pluginapi.operation.OperationResult;
import org.rhq.modules.plugins.jbossas7.json.ComplexResult;
@@ -46,8 +49,19 @@ public class LoggerComponent extends BaseComponent {
Map<String,Property> propertyMap = parameters.getAllProperties();
for (Map.Entry<String,Property> entry : propertyMap.entrySet()) {
- PropertySimple ps = (PropertySimple) entry.getValue();
- op.addAdditionalProperty(entry.getKey(),ps.getStringValue());
+ if (entry.getValue() instanceof PropertySimple) {
+ PropertySimple ps = (PropertySimple) entry.getValue();
+ op.addAdditionalProperty(entry.getKey(),ps.getStringValue());
+ } else if (entry.getValue() instanceof PropertyList) {
+ PropertyList pl = (PropertyList) entry.getValue();
+ List<Property> props = pl.getList();
+ List<String> objects = new ArrayList<String>(props.size());
+ for (Property p : props) {
+ PropertySimple ps = (PropertySimple) p;
+ objects.add(ps.getStringValue());
+ }
+ op.addAdditionalProperty(entry.getKey(),objects);
+ }
}
@@ -59,7 +73,7 @@ public class LoggerComponent extends BaseComponent {
}
else {
OperationResult failure = new OperationResult();
- failure.setErrorMessage(result.getFailureDescription().toString());
+ failure.setErrorMessage(result.getFailureDescription());
return failure;
}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ModClusterComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ModClusterComponent.java
new file mode 100644
index 0000000..83987e3
--- /dev/null
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ModClusterComponent.java
@@ -0,0 +1,41 @@
+package org.rhq.modules.plugins.jbossas7;
+
+import java.util.Map;
+
+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.pluginapi.operation.OperationFacet;
+import org.rhq.core.pluginapi.operation.OperationResult;
+import org.rhq.modules.plugins.jbossas7.json.Operation;
+import org.rhq.modules.plugins.jbossas7.json.Result;
+
+/**
+ * Component class for ModCluster
+ * @author Heiko W. Rupp
+ */
+public class ModClusterComponent extends BaseComponent implements OperationFacet {
+
+ @Override
+ public OperationResult invokeOperation(String name,
+ Configuration parameters) throws Exception {
+
+ Operation op = new Operation(name,getAddress());
+ Result result = getASConnection().execute(op);
+
+ Map<String,Property> propertyMap = parameters.getAllProperties();
+ for (Map.Entry<String,Property> entry : propertyMap.entrySet()) {
+ PropertySimple ps = (PropertySimple) entry.getValue();
+ op.addAdditionalProperty(entry.getKey(),ps.getStringValue());
+ }
+
+ OperationResult operationResult = new OperationResult();
+ if (result.isSuccess()) {
+ operationResult.setSimpleResult(result.getResult().toString());
+ }
+ else {
+ operationResult.setErrorMessage(result.getFailureDescription());
+ }
+ return operationResult;
+ }
+}
diff --git a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
index abd6fe3..ffc40bd 100644
--- a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
@@ -1304,7 +1304,7 @@
<server name="Logging"
discovery="SubsystemDiscovery"
- class="BaseComponent"
+ class="LoggerComponent"
singleton="true"
>
@@ -1331,9 +1331,15 @@
</c:property-options>
</c:simple-property>
</parameters>
+ <results>
+ <c:simple-property name="operationResult"/>
+ </results>
</operation>
<operation name="remove-root-logger" description="Remove the root logger.">
+ <results>
+ <c:simple-property name="operationResult"/>
+ </results>
</operation>
<operation name="set-root-logger" description="Set the root logger.">
@@ -1355,6 +1361,9 @@
<c:simple-property name="handler" type="string"/>
</c:list-property>
</parameters>
+ <results>
+ <c:simple-property name="operationResult"/>
+ </results>
</operation>
<resource-configuration>
@@ -1842,7 +1851,7 @@ working area for individual server instances</li></ul>"/>
</server>
<server name="ModCluster"
- class="BaseComponent"
+ class="ModClusterComponent"
discovery="SubsystemDiscovery"
description="Mod_cluster support"
singleton="true"
@@ -1858,6 +1867,10 @@ working area for individual server instances</li></ul>"/>
</plugin-configuration>
<operation name="list-proxies" description="Read the list of httpd connected to the nodes.">
+ <results>
+ <c:simple-property name="operationResult"/>
+ </results>
+
</operation>
<resource-configuration>
12 years, 7 months
[rhq] Branch 'release_jon3.x' - modules/plugins
by Heiko W. Rupp
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java | 5 -
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/LoggerComponent.java | 20 ++++
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ModClusterComponent.java | 41 ++++++++++
modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml | 17 +++-
4 files changed, 76 insertions(+), 7 deletions(-)
New commits:
commit cca4cadd6a0b39fddd6fb51b2f8ec32e5db3215c
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Mon Nov 7 13:14:45 2011 +0100
BZ 736481 - Fix the missing ':' errors.(cherry picked from commit e1ae664a1474a18a74f02f720c21aa016bbb0fae)
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
index 0ad794c..0aba2d3 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
@@ -429,8 +429,9 @@ public class BaseComponent<T extends ResourceComponent<?>> implements ResourceCo
Configuration parameters) throws InterruptedException, Exception {
if (!name.contains(":")) {
- OperationResult badName = new OperationResult("Operation name did not contain a ':'");
- badName.setErrorMessage("Operation name did not contain a ':'");
+ String simpleResult = "Operation with name [" + name + "] did not contain a ':'";
+ OperationResult badName = new OperationResult(simpleResult);
+ badName.setErrorMessage(simpleResult);
return badName;
}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/LoggerComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/LoggerComponent.java
index 67df4d9..f9ff8a3 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/LoggerComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/LoggerComponent.java
@@ -18,6 +18,8 @@
*/
package org.rhq.modules.plugins.jbossas7;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
@@ -25,6 +27,7 @@ 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.PropertySimple;
import org.rhq.core.pluginapi.operation.OperationResult;
import org.rhq.modules.plugins.jbossas7.json.ComplexResult;
@@ -46,8 +49,19 @@ public class LoggerComponent extends BaseComponent {
Map<String,Property> propertyMap = parameters.getAllProperties();
for (Map.Entry<String,Property> entry : propertyMap.entrySet()) {
- PropertySimple ps = (PropertySimple) entry.getValue();
- op.addAdditionalProperty(entry.getKey(),ps.getStringValue());
+ if (entry.getValue() instanceof PropertySimple) {
+ PropertySimple ps = (PropertySimple) entry.getValue();
+ op.addAdditionalProperty(entry.getKey(),ps.getStringValue());
+ } else if (entry.getValue() instanceof PropertyList) {
+ PropertyList pl = (PropertyList) entry.getValue();
+ List<Property> props = pl.getList();
+ List<String> objects = new ArrayList<String>(props.size());
+ for (Property p : props) {
+ PropertySimple ps = (PropertySimple) p;
+ objects.add(ps.getStringValue());
+ }
+ op.addAdditionalProperty(entry.getKey(),objects);
+ }
}
@@ -59,7 +73,7 @@ public class LoggerComponent extends BaseComponent {
}
else {
OperationResult failure = new OperationResult();
- failure.setErrorMessage(result.getFailureDescription().toString());
+ failure.setErrorMessage(result.getFailureDescription());
return failure;
}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ModClusterComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ModClusterComponent.java
new file mode 100644
index 0000000..83987e3
--- /dev/null
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ModClusterComponent.java
@@ -0,0 +1,41 @@
+package org.rhq.modules.plugins.jbossas7;
+
+import java.util.Map;
+
+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.pluginapi.operation.OperationFacet;
+import org.rhq.core.pluginapi.operation.OperationResult;
+import org.rhq.modules.plugins.jbossas7.json.Operation;
+import org.rhq.modules.plugins.jbossas7.json.Result;
+
+/**
+ * Component class for ModCluster
+ * @author Heiko W. Rupp
+ */
+public class ModClusterComponent extends BaseComponent implements OperationFacet {
+
+ @Override
+ public OperationResult invokeOperation(String name,
+ Configuration parameters) throws Exception {
+
+ Operation op = new Operation(name,getAddress());
+ Result result = getASConnection().execute(op);
+
+ Map<String,Property> propertyMap = parameters.getAllProperties();
+ for (Map.Entry<String,Property> entry : propertyMap.entrySet()) {
+ PropertySimple ps = (PropertySimple) entry.getValue();
+ op.addAdditionalProperty(entry.getKey(),ps.getStringValue());
+ }
+
+ OperationResult operationResult = new OperationResult();
+ if (result.isSuccess()) {
+ operationResult.setSimpleResult(result.getResult().toString());
+ }
+ else {
+ operationResult.setErrorMessage(result.getFailureDescription());
+ }
+ return operationResult;
+ }
+}
diff --git a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
index abd6fe3..ffc40bd 100644
--- a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
@@ -1304,7 +1304,7 @@
<server name="Logging"
discovery="SubsystemDiscovery"
- class="BaseComponent"
+ class="LoggerComponent"
singleton="true"
>
@@ -1331,9 +1331,15 @@
</c:property-options>
</c:simple-property>
</parameters>
+ <results>
+ <c:simple-property name="operationResult"/>
+ </results>
</operation>
<operation name="remove-root-logger" description="Remove the root logger.">
+ <results>
+ <c:simple-property name="operationResult"/>
+ </results>
</operation>
<operation name="set-root-logger" description="Set the root logger.">
@@ -1355,6 +1361,9 @@
<c:simple-property name="handler" type="string"/>
</c:list-property>
</parameters>
+ <results>
+ <c:simple-property name="operationResult"/>
+ </results>
</operation>
<resource-configuration>
@@ -1842,7 +1851,7 @@ working area for individual server instances</li></ul>"/>
</server>
<server name="ModCluster"
- class="BaseComponent"
+ class="ModClusterComponent"
discovery="SubsystemDiscovery"
description="Mod_cluster support"
singleton="true"
@@ -1858,6 +1867,10 @@ working area for individual server instances</li></ul>"/>
</plugin-configuration>
<operation name="list-proxies" description="Read the list of httpd connected to the nodes.">
+ <results>
+ <c:simple-property name="operationResult"/>
+ </results>
+
</operation>
<resource-configuration>
12 years, 7 months
[rhq] Branch 'release_jon3.x' - modules/core modules/enterprise
by lkrejci
modules/core/domain/src/main/java/org/rhq/core/domain/sync/ImportReport.java | 44 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/MetricTemplateSynchronizer.java | 17
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerBean.java | 173 ++++--
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerLocal.java | 16
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerRemote.java | 9
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizedEntity.java | 10
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizerFactory.java | 42 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SystemSettingsSynchronizer.java | 3
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/Importer.java | 15
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/MetricTemplateImporter.java | 56 ++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/SystemSettingsImporter.java | 14
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/ConsistencyValidator.java | 36 -
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/DeployedAgentPluginsValidator.java | 14
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/EntityValidator.java | 52 ++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/MaxCountValidator.java | 52 ++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/MetricTemplateValidator.java | 121 ----
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/SystemSettingsValidator.java | 48 -
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/UniquenessValidator.java | 50 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java | 5
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/DeployedAgentPluginsValidatorTest.java | 3
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/ExportingInputStreamTest.java | 9
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MaxCountValidatorTest.java | 52 ++
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateExporterTest.java | 17
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateImporterTest.java | 42 +
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateValidatorTest.java | 161 ------
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SynchronizationManagerBeanTest.java | 253 ++++++++--
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SystemSettingsImporterTest.java | 1
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SystemSettingsValidatorTest.java | 22
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/UniquenessValidatorTest.java | 51 ++
29 files changed, 855 insertions(+), 533 deletions(-)
New commits:
commit 7fbb3fcdadbec68b5fe1dc4b1fec66954fce9c88
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Nov 7 12:06:01 2011 +0100
[BZ 749126] - Loosening validation requirements on import.
This commit is quite big due to the refactoring but does only
a couple of simple things:
1) The SynchronizationManagerRemote.importAllSubsystems now returns
an ImportReport which contains the notes from subsystem importers about
"interesting" events during the import. This is used to report warnings
or other info to the caller of the import.
Namely the MetricTemplateImporter now reports all the metric templates
from the export file that were not present in the target database
(which basically means that source and target RHQ install had different
plugins installed).
2) Import is lenient about unknown validator classes (this is to not choke
on "old" import files that still may be perfectly valid).
3) The former ConsistencyValidator has been split into 2 separate concepts:
ConsistencyValidator - persists its config into the export file, checks
the consistency of the target RHQ install as a whole.
EntityValidator - configured by the importer, does NOT persist anything
into the export file, used to validate individual entities in the export
file before the import begins.
4) Some new unit tests and a couple of simple changes in the code to
support better testability.
5) DeployedAgentPluginsValidator was "decommissioned" but left in
the codebase as an example implementation.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/sync/ImportReport.java b/modules/core/domain/src/main/java/org/rhq/core/domain/sync/ImportReport.java
new file mode 100644
index 0000000..d9baab7
--- /dev/null
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/sync/ImportReport.java
@@ -0,0 +1,44 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 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.domain.sync;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *
+ *
+ * @author Lukas Krejci
+ */
+public class ImportReport implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private Map<String, String> importerNotes;
+
+ public Map<String, String> getImporterNotes() {
+ if (importerNotes == null) {
+ importerNotes = new HashMap<String, String>();
+ }
+
+ return importerNotes;
+ }
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/MetricTemplateSynchronizer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/MetricTemplateSynchronizer.java
index 913c981..1dcdd9c 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/MetricTemplateSynchronizer.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/MetricTemplateSynchronizer.java
@@ -19,6 +19,7 @@
package org.rhq.enterprise.server.sync;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@@ -36,7 +37,7 @@ import org.rhq.enterprise.server.sync.importers.Importer;
import org.rhq.enterprise.server.sync.importers.MetricTemplateImporter;
import org.rhq.enterprise.server.sync.validators.ConsistencyValidator;
import org.rhq.enterprise.server.sync.validators.DeployedAgentPluginsValidator;
-import org.rhq.enterprise.server.sync.validators.MetricTemplateValidator;
+import org.rhq.enterprise.server.sync.validators.UniquenessValidator;
import org.rhq.enterprise.server.util.LookupUtil;
/**
@@ -50,17 +51,15 @@ public class MetricTemplateSynchronizer implements Synchronizer<MeasurementDefin
private EntityManager entityManager;
private MeasurementDefinitionManagerLocal measurementDefinitionManager;
private MeasurementScheduleManagerLocal measurementScheduleManager;
- private PluginManagerLocal pluginManager;
public MetricTemplateSynchronizer() {
- this(LookupUtil.getMeasurementDefinitionManager(), LookupUtil.getMeasurementScheduleManager(), LookupUtil.getPluginManager());
+ this(LookupUtil.getMeasurementDefinitionManager(), LookupUtil.getMeasurementScheduleManager());
}
public MetricTemplateSynchronizer(MeasurementDefinitionManagerLocal measurementDefinitionManager,
- MeasurementScheduleManagerLocal measurementScheduleManager, PluginManagerLocal pluginManager) {
+ MeasurementScheduleManagerLocal measurementScheduleManager) {
this.measurementDefinitionManager = measurementDefinitionManager;
this.measurementScheduleManager = measurementScheduleManager;
- this.pluginManager = pluginManager;
}
@Override
@@ -69,19 +68,19 @@ public class MetricTemplateSynchronizer implements Synchronizer<MeasurementDefin
this.entityManager = entityManager;
}
+ @Override
public Exporter<MeasurementDefinition, MetricTemplate> getExporter() {
return new MetricTemplateExporter(subject, measurementDefinitionManager);
}
+ @Override
public Importer<MeasurementDefinition, MetricTemplate> getImporter() {
return new MetricTemplateImporter(subject, entityManager, measurementScheduleManager);
}
+ @Override
public Set<ConsistencyValidator> getRequiredValidators() {
- HashSet<ConsistencyValidator> ret = new HashSet<ConsistencyValidator>();
- ret.add(new DeployedAgentPluginsValidator(pluginManager));
- ret.add(new MetricTemplateValidator());
- return ret;
+ return Collections.emptySet();
}
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerBean.java
index af848b1..992687e 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerBean.java
@@ -30,6 +30,7 @@ import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -54,7 +55,6 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.auth.Subject;
-import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.sync.ConsistencyValidatorFailureReport;
import org.rhq.core.domain.sync.ExportReport;
@@ -62,12 +62,13 @@ import org.rhq.core.domain.sync.ExportWrapper;
import org.rhq.core.domain.sync.ExporterMessages;
import org.rhq.core.domain.sync.ImportConfiguration;
import org.rhq.core.domain.sync.ImportConfigurationDefinition;
+import org.rhq.core.domain.sync.ImportReport;
import org.rhq.core.util.stream.StreamUtil;
import org.rhq.enterprise.server.RHQConstants;
-import org.rhq.enterprise.server.authz.RequiredPermission;
import org.rhq.enterprise.server.sync.importers.ExportedEntityMatcher;
import org.rhq.enterprise.server.sync.importers.Importer;
import org.rhq.enterprise.server.sync.validators.ConsistencyValidator;
+import org.rhq.enterprise.server.sync.validators.EntityValidator;
import org.rhq.enterprise.server.sync.validators.InconsistentStateException;
import org.rhq.enterprise.server.xmlschema.ConfigurationInstanceDescriptorUtil;
@@ -85,18 +86,25 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
private EntityManager entityManager;
private JAXBContext defaultImportConfigurationJAXBContext;
+
+ private SynchronizerFactory synchronizerFactory = new SynchronizerFactory();
public SynchronizationManagerBean() {
try {
- defaultImportConfigurationJAXBContext = JAXBContext.newInstance(DefaultImportConfigurationDescriptor.class);
+ defaultImportConfigurationJAXBContext = JAXBContext.newInstance(DefaultImportConfigurationDescriptor.class);
} catch (JAXBException e) {
throw new IllegalStateException("Failed to create DefaultImportConfigurationDescriptor unmarshaller. This should never happen.");
}
}
+ //for test purposes
+ @Override
+ public void setSynchronizerFactory(SynchronizerFactory factory) {
+ this.synchronizerFactory = factory;
+ }
+
@Override
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
- @RequiredPermission(Permission.MANAGE_INVENTORY)
public ExportReport exportAllSubsystems(Subject subject) {
ExportWrapper localExport = exportAllSubsystemsLocally(subject);
@@ -131,17 +139,10 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
@Override
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
- @RequiredPermission(Permission.MANAGE_INVENTORY)
public ExportWrapper exportAllSubsystemsLocally(Subject subject) {
- Set<Synchronizer<?, ?>> allSynchronizers = new HashSet<Synchronizer<?, ?>>();
+ Set<Synchronizer<?, ?>> allSynchronizers = getInitializedSynchronizers(subject);
Map<String, ExporterMessages> messages = new HashMap<String, ExporterMessages>();
- for (SynchronizedEntity e : SynchronizedEntity.values()) {
- Synchronizer<?, ?> synchronizer = e.getSynchronizer();
- synchronizer.initialize(subject, entityManager);
- allSynchronizers.add(synchronizer);
- }
-
try {
return new ExportWrapper(messages, new ExportingInputStream(allSynchronizers, messages));
} catch (IOException e) {
@@ -150,8 +151,7 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
}
@Override
- @RequiredPermission(Permission.MANAGE_INVENTORY)
- public void importAllSubsystems(Subject subject, InputStream exportFile, List<ImportConfiguration> configurations)
+ public ImportReport importAllSubsystems(Subject subject, InputStream exportFile, List<ImportConfiguration> configurations)
throws ValidationException, ImportException {
File tmpFile = null;
@@ -170,13 +170,15 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
}
InputStream in = null;
- try {
+ try {
+ Map<String, Configuration> configsPerImports = getConfigPerImporter(configurations);
+
in = new GZIPInputStream(new BufferedInputStream(new FileInputStream(tmpFile)));
- validateExport(subject, in);
+ validateExport(subject, in, configsPerImports);
in.close();
in = new GZIPInputStream(new BufferedInputStream(new FileInputStream(tmpFile)));
- importExportFile(subject, in, getConfigPerImporter(configurations));
+ return importExportFile(subject, in, configsPerImports);
} catch (XMLStreamException e) {
throw new ImportException("Failed import due to XML parsing error.", e);
} catch (IOException e) {
@@ -188,24 +190,21 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
}
@Override
- @RequiredPermission(Permission.MANAGE_INVENTORY)
- public void importAllSubsystems(Subject subject, byte[] exportFile, List<ImportConfiguration> configurations)
+ public ImportReport importAllSubsystems(Subject subject, byte[] exportFile, List<ImportConfiguration> configurations)
throws ValidationException, ImportException {
- importAllSubsystems(subject, new ByteArrayInputStream(exportFile), configurations);
+ return importAllSubsystems(subject, new ByteArrayInputStream(exportFile), configurations);
}
@Override
- @RequiredPermission(Permission.MANAGE_INVENTORY)
public void validate(Subject subject, InputStream exportFile) throws ValidationException {
try {
- validateExport(subject, exportFile);
+ validateExport(subject, exportFile, Collections.<String, Configuration>emptyMap());
} catch (XMLStreamException e) {
throw new ValidationException("Failed to parse the export file.", e);
}
}
@Override
- @RequiredPermission(Permission.MANAGE_INVENTORY)
public void validate(Subject subject, byte[] exportFile) throws ValidationException {
validate(subject, new ByteArrayInputStream(exportFile));
}
@@ -235,8 +234,7 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
public List<ImportConfigurationDefinition> getImportConfigurationDefinitionOfAllSynchronizers() {
List<ImportConfigurationDefinition> ret = new ArrayList<ImportConfigurationDefinition>();
- for (SynchronizedEntity e : SynchronizedEntity.values()) {
- Synchronizer<?, ?> syn = e.getSynchronizer();
+ for (Synchronizer<?, ?> syn : synchronizerFactory.getAllSynchronizers()) {
ret.add(new ImportConfigurationDefinition(syn.getClass().getName(), syn.getImporter()
.getImportConfigurationDefinition()));
}
@@ -244,12 +242,12 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
return ret;
}
- private void validateExport(Subject subject, InputStream exportFile) throws ValidationException, XMLStreamException {
+ private void validateExport(Subject subject, InputStream exportFile, Map<String, Configuration> importConfigs) throws ValidationException, XMLStreamException {
XMLStreamReader rdr = XMLInputFactory.newInstance().createXMLStreamReader(exportFile);
try {
Set<ConsistencyValidatorFailureReport> failures = new HashSet<ConsistencyValidatorFailureReport>();
- Set<ConsistencyValidator> executedValidators = new HashSet<ConsistencyValidator>();
+ Set<ConsistencyValidator> consistencyValidators = new HashSet<ConsistencyValidator>();
while (rdr.hasNext()) {
switch (rdr.next()) {
@@ -258,6 +256,11 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
if (SynchronizationConstants.VALIDATOR_ELEMENT.equals(tagName)) {
ConsistencyValidator validator = null;
String validatorClass = rdr.getAttributeValue(null, SynchronizationConstants.CLASS_ATTRIBUTE);
+ if (!isConsistencyValidatorClass(validatorClass)) {
+ LOG.info("The export file contains an unknown consistency validator: " + validatorClass + ". Ignoring.");
+ continue;
+ }
+
try {
validator = validateSingle(rdr, subject);
} catch (Exception e) {
@@ -265,14 +268,12 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
printExceptionToString(e)));
}
if (validator != null) {
- executedValidators.add(validator);
+ consistencyValidators.add(validator);
}
} else if (SynchronizationConstants.ENTITIES_EXPORT_ELEMENT.equals(tagName)) {
- //all the validators preceed the importers in the export file so we can now check if the
- //validator was already run
String synchronizerClass = rdr.getAttributeValue(null, SynchronizationConstants.ID_ATTRIBUTE);
try {
- failures.addAll(validateEntities(rdr, subject, executedValidators));
+ failures.addAll(validateEntities(rdr, subject, consistencyValidators, importConfigs));
} catch (Exception e) {
throw new ValidationException(
"Validation failed unexpectedly while processing the entities exported by the synchronizer '"
@@ -290,24 +291,38 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
}
}
- private Set<ConsistencyValidatorFailureReport> validateEntities(XMLStreamReader rdr, Subject subject,
- Set<ConsistencyValidator> executedValidators) throws Exception {
+ /**
+ * @param validatorClass
+ * @return
+ */
+ private boolean isConsistencyValidatorClass(String validatorClass) {
+ try {
+ Class<?> cls = Class.forName(validatorClass);
+
+ return ConsistencyValidator.class.isAssignableFrom(cls);
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ private <E, X> Set<ConsistencyValidatorFailureReport> validateEntities(XMLStreamReader rdr, Subject subject,
+ Set<ConsistencyValidator> consistencyValidators, Map<String, Configuration> importConfigurations) throws Exception {
String synchronizerClass = rdr.getAttributeValue(null, SynchronizationConstants.ID_ATTRIBUTE);
HashSet<ConsistencyValidatorFailureReport> ret = new HashSet<ConsistencyValidatorFailureReport>();
- Synchronizer<?, ?> synchronizer = instantiate(synchronizerClass, Synchronizer.class,
+ @SuppressWarnings("unchecked")
+ Synchronizer<E, X> synchronizer = instantiate(synchronizerClass, Synchronizer.class,
"The id attribute of entities doesn't correspond to a class implementing the Synchronizer interface.");
synchronizer.initialize(subject, entityManager);
- Importer<?, ?> importer = synchronizer.getImporter();
+ Importer<E, X> importer = synchronizer.getImporter();
- //pre-init the validators so that we can reuse them in the loop below
- Set<ConsistencyValidator> validators = synchronizer.getRequiredValidators();
- for(ConsistencyValidator v : validators) {
- v.initialize(subject, entityManager);
-
- if (!executedValidators.contains(v)) {
+ Set<ConsistencyValidator> requriedConsistencyValidators = synchronizer.getRequiredValidators();
+
+ //check that all the required consistency validators were run
+ for(ConsistencyValidator v : requriedConsistencyValidators) {
+ if (!consistencyValidators.contains(v)) {
ret.add(new ConsistencyValidatorFailureReport(v.getClass().getName(), "The validator '"
+ v.getClass().getName() + "' is required by the synchronizer '" + synchronizerClass
+ "' but was not found in the export file."));
@@ -319,29 +334,48 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
return ret;
}
+ boolean configured = false;
+ Configuration importConfiguration = importConfigurations.get(synchronizerClass);
+
+ Set<EntityValidator<X>> validators = null;
+
+ //the passed in configuration has precedence over the default one inlined in
+ //the config file.
+ if (importConfiguration != null) {
+ importer.configure(importConfiguration);
+ validators = importer.getEntityValidators();
+ for(EntityValidator<X> v : validators) {
+ v.initialize(subject, entityManager);
+ }
+ configured = true;
+ }
+
while (rdr.hasNext()) {
boolean bailout = false;
switch (rdr.next()) {
case XMLStreamConstants.START_ELEMENT:
- if (SynchronizationConstants.DATA_ELEMENT.equals(rdr.getName().getLocalPart())) {
- rdr.nextTag();
- Object exportedEntity = importer.unmarshallExportedEntity(new ExportReader(rdr));
- Class<?> exportedEntityClass = exportedEntity.getClass();
+ if (SynchronizationConstants.DEFAULT_CONFIGURATION_ELEMENT.equals(rdr.getName().getLocalPart())) {
+ if (!configured) {
+ importConfiguration = getDefaultConfiguration(rdr);
+ }
+ } else if (SynchronizationConstants.DATA_ELEMENT.equals(rdr.getName().getLocalPart())) {
- for (ConsistencyValidator validator : validators) {
- boolean shouldCheck = false;
- for (Class<?> cls : validator.getValidatedEntityTypes()) {
- if (cls.isAssignableFrom(exportedEntityClass)) {
- shouldCheck = true;
- break;
- }
- }
-
- if (!shouldCheck) {
- //ok, this validator doesn't want to validate this type of entity
- continue;
+ //first check if the configure method has been called
+ if (!configured) {
+ importer.configure(importConfiguration);
+ validators = importer.getEntityValidators();
+ for(EntityValidator<X> v : validators) {
+ v.initialize(subject, entityManager);
}
+ configured = true;
+ }
+
+ //now do the validation
+ rdr.nextTag();
+ X exportedEntity = importer.unmarshallExportedEntity(new ExportReader(rdr));
+
+ for (EntityValidator<X> validator : validators) {
try {
validator.validateExportedEntity(exportedEntity);
} catch (Exception e) {
@@ -367,17 +401,23 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
return ret;
}
- private void importExportFile(Subject subject, InputStream exportFile,
+ private ImportReport importExportFile(Subject subject, InputStream exportFile,
Map<String, Configuration> importerConfigs) throws ImportException, XMLStreamException {
XMLStreamReader rdr = XMLInputFactory.newInstance().createXMLStreamReader(exportFile);
+ ImportReport report = new ImportReport();
+
while (rdr.hasNext()) {
switch (rdr.next()) {
case XMLStreamReader.START_ELEMENT:
String tagName = rdr.getName().getLocalPart();
if (SynchronizationConstants.ENTITIES_EXPORT_ELEMENT.equals(tagName)) {
try {
- importSingle(subject, importerConfigs, rdr);
+ String synchronizer = rdr.getAttributeValue(null, SynchronizationConstants.ID_ATTRIBUTE);
+ String notes = importSingle(subject, importerConfigs, rdr);
+ if (notes != null) {
+ report.getImporterNotes().put(synchronizer, notes);
+ }
} catch (Exception e) {
//fail fast on the import errors... This runs in a single transaction
//so all imports done so far will get rolled-back.
@@ -390,6 +430,8 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
break;
}
}
+
+ return report;
}
private ConsistencyValidator validateSingle(XMLStreamReader rdr, Subject subject) throws InstantiationException,
@@ -410,7 +452,7 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
return validator;
}
- private <E, X> void importSingle(Subject subject, Map<String, Configuration> importConfigs, XMLStreamReader rdr)
+ private <E, X> String importSingle(Subject subject, Map<String, Configuration> importConfigs, XMLStreamReader rdr)
throws Exception {
String synchronizerClassName = rdr.getAttributeValue(null, SynchronizationConstants.ID_ATTRIBUTE);
@@ -477,7 +519,7 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
importer.configure(importConfiguration);
}
- importer.finishImport();
+ return importer.finishImport();
}
private static String printExceptionToString(Throwable t) {
@@ -499,6 +541,15 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
return desiredClass.cast(instance);
}
+ private Set<Synchronizer<?, ?>> getInitializedSynchronizers(Subject subject) {
+ Set<Synchronizer<?, ?>> ret = synchronizerFactory.getAllSynchronizers();
+ for(Synchronizer<?, ?> s : ret) {
+ s.initialize(subject, entityManager);
+ }
+
+ return ret;
+ }
+
private Map<String, Configuration> getConfigPerImporter(List<ImportConfiguration> list) {
Map<String, Configuration> ret = new HashMap<String, Configuration>();
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerLocal.java
index e391f25..fd4d425 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerLocal.java
@@ -31,6 +31,7 @@ import org.rhq.core.domain.sync.ExportReport;
import org.rhq.core.domain.sync.ExportWrapper;
import org.rhq.core.domain.sync.ImportConfiguration;
import org.rhq.core.domain.sync.ImportConfigurationDefinition;
+import org.rhq.core.domain.sync.ImportReport;
/**
*
@@ -60,7 +61,18 @@ public interface SynchronizationManagerLocal {
void validate(Subject subject, InputStream exportFile) throws ValidationException;
- void importAllSubsystems(Subject subject, InputStream exportFile, List<ImportConfiguration> importerConfigurations) throws ValidationException, ImportException;
+ ImportReport importAllSubsystems(Subject subject, InputStream exportFile, List<ImportConfiguration> importerConfigurations) throws ValidationException, ImportException;
+
+ /**
+ * <b>Provided for testability reasons. DON'T USE OUTSIDE TESTS.</b>
+ * <p>
+ * Using this method one can provide a custom factory
+ * for {@link Synchronizer}s. This way one can export/import different types of entities
+ * than by default.
+ *
+ * @param factory
+ */
+ void setSynchronizerFactory(SynchronizerFactory factory);
//-------- THE FOLLOWING METHODS ARE SHARED WITH THE REMOTE INTERFACE ------------
@@ -93,5 +105,5 @@ public interface SynchronizationManagerLocal {
/**
* @see SynchronizationManagerRemote#importAllSubsystems(Subject, byte[], Set)
*/
- void importAllSubsystems(Subject subject, byte[] exportFile, List<ImportConfiguration> importerConfigurations) throws ValidationException, ImportException;
+ ImportReport importAllSubsystems(Subject subject, byte[] exportFile, List<ImportConfiguration> importerConfigurations) throws ValidationException, ImportException;
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerRemote.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerRemote.java
index 0cefd8c..eb6b5c9 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerRemote.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerRemote.java
@@ -28,6 +28,7 @@ import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.sync.ExportReport;
import org.rhq.core.domain.sync.ImportConfiguration;
import org.rhq.core.domain.sync.ImportConfigurationDefinition;
+import org.rhq.core.domain.sync.ImportReport;
/**
*
@@ -75,9 +76,11 @@ public interface SynchronizationManagerRemote {
*
* @param subject the authenticated user
* @param exportFile the contents of the export file
- * @param importerConfigurations the configurations of individual importers to be used when importing
+ * @param importerConfigurations the configurations of individual importers to be used when importing or null
+ * if the default configurations should be used for all the importers.
*
- * @return the report describing the result of the export
+ * @return the report describing the result of the import
*/
- void importAllSubsystems(Subject subject, byte[] exportFile, List<ImportConfiguration> importerConfigurations) throws ValidationException, ImportException;
+ ImportReport importAllSubsystems(Subject subject, byte[] exportFile,
+ List<ImportConfiguration> importerConfigurations) throws ValidationException, ImportException;
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizedEntity.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizedEntity.java
index 21e15b0..6668947 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizedEntity.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizedEntity.java
@@ -19,16 +19,12 @@
package org.rhq.enterprise.server.sync;
-import org.rhq.enterprise.server.sync.exporters.Exporter;
-import org.rhq.enterprise.server.sync.exporters.MetricTemplateExporter;
-import org.rhq.enterprise.server.sync.exporters.SystemSettingsExporter;
-import org.rhq.enterprise.server.sync.importers.Importer;
-import org.rhq.enterprise.server.sync.importers.MetricTemplateImporter;
-import org.rhq.enterprise.server.sync.importers.SystemSettingsImporter;
/**
* The enum of all possible synchronized entities.
- *
+ * This is used in the {@link SynchronizerFactory#getAllSynchronizers()} to provide
+ * the synchronizers to the rest of the config sync machinery.
+ *
* @author Lukas Krejci
*/
public enum SynchronizedEntity {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizerFactory.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizerFactory.java
new file mode 100644
index 0000000..2ffada1
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizerFactory.java
@@ -0,0 +1,42 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 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.server.sync;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+/**
+ * A factory for obtaining synchronizers.
+ * This is mainly useful for test purposes where this class can be subclassed
+ * and passed to the {@link SynchronizationManagerBean}.
+ *
+ * @author Lukas Krejci
+ */
+public class SynchronizerFactory {
+
+ public Set<Synchronizer<?, ?>> getAllSynchronizers() {
+ LinkedHashSet<Synchronizer<?, ?>> ret = new LinkedHashSet<Synchronizer<?,?>>();
+ for (SynchronizedEntity e : SynchronizedEntity.values()) {
+ ret.add(e.getSynchronizer());
+ }
+
+ return ret;
+ }
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SystemSettingsSynchronizer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SystemSettingsSynchronizer.java
index da0b0e7..dc62060 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SystemSettingsSynchronizer.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SystemSettingsSynchronizer.java
@@ -31,7 +31,6 @@ import org.rhq.enterprise.server.sync.exporters.SystemSettingsExporter;
import org.rhq.enterprise.server.sync.importers.Importer;
import org.rhq.enterprise.server.sync.importers.SystemSettingsImporter;
import org.rhq.enterprise.server.sync.validators.ConsistencyValidator;
-import org.rhq.enterprise.server.sync.validators.SystemSettingsValidator;
import org.rhq.enterprise.server.system.SystemManagerLocal;
import org.rhq.enterprise.server.util.LookupUtil;
@@ -67,7 +66,7 @@ public class SystemSettingsSynchronizer implements Synchronizer<NoSingleEntity,
}
public Set<ConsistencyValidator> getRequiredValidators() {
- return Collections.<ConsistencyValidator>singleton(new SystemSettingsValidator(systemManager));
+ return Collections.emptySet();
}
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/Importer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/Importer.java
index b61777d..a29e099 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/Importer.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/Importer.java
@@ -19,11 +19,14 @@
package org.rhq.enterprise.server.sync.importers;
+import java.util.Set;
+
import javax.xml.stream.XMLStreamException;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.enterprise.server.sync.ExportReader;
+import org.rhq.enterprise.server.sync.validators.EntityValidator;
/**
* Implementations of this interface are used to import entities into the database.
@@ -58,6 +61,12 @@ public interface Importer<Entity, ExportedType> {
ExportedEntityMatcher<Entity, ExportedType> getExportedEntityMatcher();
/**
+ * The set of entity validators that should be called on each entity before
+ * the import actually starts.
+ */
+ Set<EntityValidator<ExportedType>> getEntityValidators();
+
+ /**
* Updates the entity with the data from the export.
* <p>
* This method is responsible for persisting the entity in the database
@@ -84,6 +93,10 @@ public interface Importer<Entity, ExportedType> {
* have been {@link #update(Object, Object) updated}.
* <p>
* This is useful for importers that need to batch the updates to the database.
+ *
+ * @return notes that should be transfered to the user. These should be any warnings and other
+ * messages that are not errors (which should throw an exception) but are deemed
+ * important for the (human) caller to be aware of.
*/
- void finishImport() throws Exception;
+ String finishImport() throws Exception;
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/MetricTemplateImporter.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/MetricTemplateImporter.java
index 78eea09..f4fa3f5 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/MetricTemplateImporter.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/MetricTemplateImporter.java
@@ -21,9 +21,13 @@ package org.rhq.enterprise.server.sync.importers;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
import javax.persistence.EntityManager;
import javax.persistence.Query;
@@ -51,6 +55,8 @@ import org.rhq.core.domain.measurement.MeasurementDefinition;
import org.rhq.core.domain.sync.entity.MetricTemplate;
import org.rhq.enterprise.server.measurement.MeasurementScheduleManagerLocal;
import org.rhq.enterprise.server.sync.ExportReader;
+import org.rhq.enterprise.server.sync.validators.EntityValidator;
+import org.rhq.enterprise.server.sync.validators.UniquenessValidator;
import org.rhq.enterprise.server.util.LookupUtil;
/**
@@ -71,6 +77,8 @@ public class MetricTemplateImporter implements Importer<MeasurementDefinition, M
public static final String METRIC_UPDATE_OVERRIDES_PROPERTY = "metricUpdateOverrides";
public static final String METRIC_UPDATE_OVERRIDE_PROPERTY = "metricUpdateOverride";
+ private static final String IMPORT_NOTES_PROLOGUE = "The following metric templates were not imported because they do not correspond to any metric defined by the existing resource types:\n";
+
private static class UpdateKey {
public final long collectionInterval;
public final boolean updateSchedules;
@@ -104,6 +112,26 @@ public class MetricTemplateImporter implements Importer<MeasurementDefinition, M
}
}
+ private static final Comparator<MetricTemplate> METRIC_TEMPLATE_COMPARATOR = new Comparator<MetricTemplate>() {
+
+ @Override
+ public int compare(MetricTemplate o1, MetricTemplate o2) {
+ //sort by plugin, type name, and metric name in that order
+
+ int ret = o1.getResourceTypePlugin().compareTo(o2.getResourceTypePlugin());
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = o1.getResourceTypeName().compareTo(o2.getResourceTypeName());
+ if (ret != 0) {
+ return ret;
+ }
+
+ return o1.getMetricName().compareTo(o2.getMetricName());
+ }
+ };
+
private Subject subject;
private EntityManager entityManager;
private Map<UpdateKey, List<MeasurementDefinition>> definitionsByUpdateKey =
@@ -111,7 +139,8 @@ public class MetricTemplateImporter implements Importer<MeasurementDefinition, M
private Configuration importConfiguration;
private Unmarshaller unmarshaller;
private MeasurementScheduleManagerLocal measurementScheduleManager;
-
+ private Set<MetricTemplate> unmatchedTemplates = new TreeSet<MetricTemplate>(METRIC_TEMPLATE_COMPARATOR);
+
public MetricTemplateImporter(Subject subject, EntityManager entityManager) {
this(subject, entityManager, LookupUtil.getMeasurementScheduleManager());
}
@@ -215,8 +244,14 @@ public class MetricTemplateImporter implements Importer<MeasurementDefinition, M
}
@Override
+ public Set<EntityValidator<MetricTemplate>> getEntityValidators() {
+ return Collections.<EntityValidator<MetricTemplate>>singleton(new UniquenessValidator<MetricTemplate>());
+ }
+
+ @Override
public void update(MeasurementDefinition entity, MetricTemplate exportedEntity) {
if (entity == null) {
+ unmatchedTemplates.add(exportedEntity);
return;
}
@@ -233,7 +268,7 @@ public class MetricTemplateImporter implements Importer<MeasurementDefinition, M
}
@Override
- public void finishImport() {
+ public String finishImport() {
for (Map.Entry<UpdateKey, List<MeasurementDefinition>> e : definitionsByUpdateKey.entrySet()) {
int[] ids = getIdsFromDefs(e.getValue());
boolean enable = e.getKey().enable;
@@ -243,8 +278,25 @@ public class MetricTemplateImporter implements Importer<MeasurementDefinition, M
measurementScheduleManager.updateDefaultCollectionIntervalAndEnablementForMeasurementDefinitions(subject,
ids, collectionInterval, enable, updateSchedules);
}
+
+ if (unmatchedTemplates.isEmpty()) {
+ return null;
+ } else {
+ return getUnmatchedMetricTemplatesReport(unmatchedTemplates);
+ }
}
+ //public for testability
+ public static String getUnmatchedMetricTemplatesReport(Set<MetricTemplate> metricTemplates) {
+ StringBuilder bld = new StringBuilder(IMPORT_NOTES_PROLOGUE);
+
+ for(MetricTemplate t : metricTemplates) {
+ bld.append(t).append("\n");
+ }
+
+ return bld.toString();
+ }
+
private static int[] getIdsFromDefs(Collection<MeasurementDefinition> defs) {
int[] ids = new int[defs.size()];
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/SystemSettingsImporter.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/SystemSettingsImporter.java
index 604196a..089746b 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/SystemSettingsImporter.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/SystemSettingsImporter.java
@@ -39,6 +39,9 @@ import org.rhq.core.domain.configuration.definition.PropertySimpleType;
import org.rhq.core.domain.sync.entity.SystemSettings;
import org.rhq.enterprise.server.sync.ExportReader;
import org.rhq.enterprise.server.sync.NoSingleEntity;
+import org.rhq.enterprise.server.sync.validators.EntityValidator;
+import org.rhq.enterprise.server.sync.validators.MaxCountValidator;
+import org.rhq.enterprise.server.sync.validators.SystemSettingsValidator;
import org.rhq.enterprise.server.system.SystemManagerLocal;
/**
@@ -100,6 +103,14 @@ public class SystemSettingsImporter implements Importer<NoSingleEntity, SystemSe
}
@Override
+ public Set<EntityValidator<SystemSettings>> getEntityValidators() {
+ HashSet<EntityValidator<SystemSettings>> ret = new HashSet<EntityValidator<SystemSettings>>();
+ ret.add(new SystemSettingsValidator());
+ ret.add(new MaxCountValidator<SystemSettings>(1));
+ return ret;
+ }
+
+ @Override
public void update(NoSingleEntity entity, SystemSettings exportedEntity) throws Exception {
Properties props = exportedEntity.toProperties();
@@ -131,7 +142,8 @@ public class SystemSettingsImporter implements Importer<NoSingleEntity, SystemSe
}
@Override
- public void finishImport() {
+ public String finishImport() {
+ return null;
}
private Set<String> getSettingNamesConfiguredForImport(Configuration importConfiguration) {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/ConsistencyValidator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/ConsistencyValidator.java
index 2b42f5a..30d2cd5 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/ConsistencyValidator.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/ConsistencyValidator.java
@@ -19,8 +19,6 @@
package org.rhq.enterprise.server.sync.validators;
-import java.util.Set;
-
import javax.persistence.EntityManager;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
@@ -28,7 +26,6 @@ import javax.xml.stream.XMLStreamReader;
import org.rhq.core.domain.auth.Subject;
import org.rhq.enterprise.server.sync.ExportReader;
import org.rhq.enterprise.server.sync.ExportWriter;
-import org.rhq.enterprise.server.sync.ValidationException;
/**
* Implementations of this interface can export a state and validate that
@@ -90,37 +87,4 @@ public interface ConsistencyValidator {
* @throws InconsistentStateException in case of failed consistency check
*/
void validateExportedState() throws InconsistentStateException;
-
- /**
- * Returns the types of exported entities this validator can validate before export.
- * This set can be empty, which would mean it can only validate the current state.
- */
- Set<Class<?>> getValidatedEntityTypes();
-
- /**
- * Validates a single entity before it is imported.
- * The supplied entity has one of the types returned by {@link #getValidatedEntityTypes()}.
- *
- * @param entity
- */
- void validateExportedEntity(Object entity) throws ValidationException;
-
- /**
- * Implementations of the consistency validator interface should reimplement the
- * {@link Object#equals(Object)} method so that two identically configured
- * validators are equal to each other.
- *
- * @param other
- * @return
- */
- boolean equals(Object other);
-
- /**
- * The {@link ConsistencyValidator} interface mandates a certain behavior of
- * the {@link #equals(Object)} method and therefore the <code>hashCode</code>
- * should be reimplemented accordingly.
- *
- * @return
- */
- int hashCode();
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/DeployedAgentPluginsValidator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/DeployedAgentPluginsValidator.java
index 2ec3f54..94fb4c3 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/DeployedAgentPluginsValidator.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/DeployedAgentPluginsValidator.java
@@ -20,7 +20,6 @@
package org.rhq.enterprise.server.sync.validators;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -35,13 +34,15 @@ import org.rhq.core.domain.plugin.PluginDeploymentType;
import org.rhq.enterprise.server.resource.metadata.PluginManagerLocal;
import org.rhq.enterprise.server.sync.ExportReader;
import org.rhq.enterprise.server.sync.ExportWriter;
-import org.rhq.enterprise.server.sync.ValidationException;
import org.rhq.enterprise.server.util.LookupUtil;
/**
* This implementation checks that the two installations
* have the exact same plugins deployed.
*
+ * Note that this class is currently not used by any synchronizer but
+ * exists for "demo" purposes.
+ *
* @author Lukas Krejci
*/
public class DeployedAgentPluginsValidator implements ConsistencyValidator {
@@ -173,15 +174,6 @@ public class DeployedAgentPluginsValidator implements ConsistencyValidator {
}
@Override
- public Set<Class<?>> getValidatedEntityTypes() {
- return Collections.emptySet();
- }
-
- @Override
- public void validateExportedEntity(Object entity) throws ValidationException {
- }
-
- @Override
public int hashCode() {
//all the deployed plugins validators are equal
return 0;
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/EntityValidator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/EntityValidator.java
new file mode 100644
index 0000000..1555f6f
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/EntityValidator.java
@@ -0,0 +1,52 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 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.server.sync.validators;
+
+import javax.persistence.EntityManager;
+
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.enterprise.server.sync.ValidationException;
+
+/**
+ * Entity validators are declared by importers to validate the entities in the export
+ * file before it gets imported.
+ *
+ * @author Lukas Krejci
+ */
+public interface EntityValidator<T> {
+
+ /**
+ * Initializes the validator with the current authentication info and access to database.
+ * This method is only called during import.
+ *
+ * @param subject the currently authenticated user
+ * @param entityManager the entity manager that can be used to access the database if the
+ * validator needs to do so.
+ */
+ void initialize(Subject subject, EntityManager entityManager);
+
+ /**
+ * Validates a single entity before it is imported.
+ * The supplied entity has one of the types returned by {@link #getValidatedEntityTypes()}.
+ *
+ * @param entity
+ */
+ void validateExportedEntity(T entity) throws ValidationException;
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/MaxCountValidator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/MaxCountValidator.java
new file mode 100644
index 0000000..3dfb5ec
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/MaxCountValidator.java
@@ -0,0 +1,52 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 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.server.sync.validators;
+
+import javax.persistence.EntityManager;
+
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.enterprise.server.sync.ValidationException;
+
+/**
+ *
+ *
+ * @author Lukas Krejci
+ */
+public class MaxCountValidator<T> implements EntityValidator<T> {
+
+ private int max;
+ private int cnt;
+
+ public MaxCountValidator(int max) {
+ this.max = max;
+ }
+
+ @Override
+ public void initialize(Subject subject, EntityManager entityManager) {
+ cnt = 0;
+ }
+
+ @Override
+ public void validateExportedEntity(T entity) throws ValidationException {
+ if (++cnt > max) {
+ throw new ValidationException("Entity " + entity + " is unexpected in the export file. At most " + max + " entites of this type are expected.");
+ }
+ }
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/MetricTemplateValidator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/MetricTemplateValidator.java
deleted file mode 100644
index eddddf7..0000000
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/MetricTemplateValidator.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2011 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.server.sync.validators;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
-import javax.xml.stream.XMLStreamException;
-
-import org.rhq.core.domain.auth.Subject;
-import org.rhq.core.domain.measurement.MeasurementDefinition;
-import org.rhq.core.domain.sync.entity.MetricTemplate;
-import org.rhq.enterprise.server.sync.ExportReader;
-import org.rhq.enterprise.server.sync.ExportWriter;
-import org.rhq.enterprise.server.sync.ValidationException;
-
-/**
- *
- *
- * @author Lukas Krejci
- */
-public class MetricTemplateValidator implements ConsistencyValidator {
-
- private EntityManager entityManager;
- private Set<MetricTemplate> allMeasurementDefinitions;
- private Set<MetricTemplate> alreadyCheckedTemplates;
- private boolean dataInitialized = false;
-
- @Override
- public void initialize(Subject subject, EntityManager entityManager) {
- this.entityManager = entityManager;
- }
-
- @Override
- public void exportState(ExportWriter writer) throws XMLStreamException {
- }
-
- @Override
- public void initializeExportedStateValidation(ExportReader reader) throws XMLStreamException {
- }
-
- @Override
- public void validateExportedState() throws InconsistentStateException {
- }
-
- @Override
- public Set<Class<?>> getValidatedEntityTypes() {
- return Collections.<Class<?>> singleton(MetricTemplate.class);
- }
-
- @Override
- public void validateExportedEntity(Object entity) throws ValidationException {
- initializeData();
-
- MetricTemplate template = (MetricTemplate) entity;
-
- if (!allMeasurementDefinitions.contains(template)) {
- throw new ValidationException(
- "The metric template "
- + template
- + " does not have any corresponding metric template in the database. This either means that the source of the export had different plugins installed, the export file has been manually edited to contain this inconsistency or that the database is corrupted.");
- }
-
- if (!alreadyCheckedTemplates.add(template)) {
- throw new ValidationException("Was the export file manually updated? The metric template " + template + " has been seen multiple times.");
- }
- }
-
- private void initializeData() {
- if (dataInitialized) {
- return;
- }
-
- allMeasurementDefinitions = new HashSet<MetricTemplate>();
- alreadyCheckedTemplates = new HashSet<MetricTemplate>();
-
- Query q = entityManager.createQuery("SELECT md FROM MeasurementDefinition md");
-
- for (Object r : q.getResultList()) {
- MeasurementDefinition md = (MeasurementDefinition) r;
-
- allMeasurementDefinitions.add(new MetricTemplate(md));
- }
-
- dataInitialized = true;
- }
-
- @Override
- public int hashCode() {
- return 0;
- }
-
- @Override
- public boolean equals(Object other) {
- if (this == other) {
- return true;
- }
-
- return other instanceof MetricTemplateValidator;
- }
-}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/SystemSettingsValidator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/SystemSettingsValidator.java
index 1d34516..0698aa7 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/SystemSettingsValidator.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/SystemSettingsValidator.java
@@ -19,16 +19,10 @@
package org.rhq.enterprise.server.sync.validators;
-import java.util.Collections;
-import java.util.Set;
-
import javax.persistence.EntityManager;
-import javax.xml.stream.XMLStreamException;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.sync.entity.SystemSettings;
-import org.rhq.enterprise.server.sync.ExportReader;
-import org.rhq.enterprise.server.sync.ExportWriter;
import org.rhq.enterprise.server.sync.ValidationException;
import org.rhq.enterprise.server.system.SystemManagerLocal;
import org.rhq.enterprise.server.util.LookupUtil;
@@ -38,7 +32,7 @@ import org.rhq.enterprise.server.util.LookupUtil;
*
* @author Lukas Krejci
*/
-public class SystemSettingsValidator implements ConsistencyValidator {
+public class SystemSettingsValidator implements EntityValidator<SystemSettings> {
private Subject subject;
private SystemManagerLocal systemManager;
@@ -57,41 +51,11 @@ public class SystemSettingsValidator implements ConsistencyValidator {
}
@Override
- public void exportState(ExportWriter writer) throws XMLStreamException {
- }
-
- @Override
- public void initializeExportedStateValidation(ExportReader reader) throws XMLStreamException {
- }
-
- @Override
- public void validateExportedState() throws InconsistentStateException {
- }
-
- @Override
- public Set<Class<?>> getValidatedEntityTypes() {
- return Collections.<Class<?>>singleton(SystemSettings.class);
- }
-
- @Override
- public void validateExportedEntity(Object entity) throws ValidationException {
- if (entity instanceof SystemSettings) {
- try {
- systemManager.validateSystemConfiguration(subject, ((SystemSettings)entity).toProperties());
- } catch (Exception e) {
- throw new ValidationException("The system settings failed to validate: " + e.getMessage(), e);
- }
+ public void validateExportedEntity(SystemSettings entity) throws ValidationException {
+ try {
+ systemManager.validateSystemConfiguration(subject, ((SystemSettings)entity).toProperties());
+ } catch (Exception e) {
+ throw new ValidationException("The system settings failed to validate: " + e.getMessage(), e);
}
}
-
- @Override
- public int hashCode() {
- return 0; //all system settings validators are equal
- }
-
- @Override
- public boolean equals(Object obj) {
- //all system settings validators are equal
- return obj instanceof SystemSettingsValidator;
- }
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/UniquenessValidator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/UniquenessValidator.java
new file mode 100644
index 0000000..7fc56f5
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/UniquenessValidator.java
@@ -0,0 +1,50 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 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.server.sync.validators;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.persistence.EntityManager;
+
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.enterprise.server.sync.ValidationException;
+
+/**
+ * This validator merely checks that there are no duplicates in the export file.
+ *
+ * @author Lukas Krejci
+ */
+public class UniquenessValidator<T> implements EntityValidator<T> {
+
+ private Set<T> alreadyCheckedEntities;
+
+ @Override
+ public void initialize(Subject subject, EntityManager entityManager) {
+ alreadyCheckedEntities = new HashSet<T>();
+ }
+
+ @Override
+ public void validateExportedEntity(T entity) throws ValidationException {
+ if (!alreadyCheckedEntities.add(entity)) {
+ throw new ValidationException("Was the export file manually updated? The entity " + entity + " has been seen multiple times.");
+ }
+ }
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
index aef8879..1cb14b2 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
@@ -125,6 +125,7 @@ import org.rhq.core.domain.resource.group.composite.ResourceGroupComposite;
import org.rhq.core.domain.sync.ExportReport;
import org.rhq.core.domain.sync.ImportConfiguration;
import org.rhq.core.domain.sync.ImportConfigurationDefinition;
+import org.rhq.core.domain.sync.ImportReport;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.alert.AlertDefinitionManagerLocal;
@@ -1222,9 +1223,9 @@ public class WebservicesManagerBean implements WebservicesRemote {
return synchronizationManager.getImportConfigurationDefinition(importerClass);
}
- public void importAllSubsystems(Subject subject, byte[] exportFile, List<ImportConfiguration> importerConfigurations)
+ public ImportReport importAllSubsystems(Subject subject, byte[] exportFile, List<ImportConfiguration> importerConfigurations)
throws ValidationException, ImportException {
- synchronizationManager.importAllSubsystems(subject, exportFile, importerConfigurations);
+ return synchronizationManager.importAllSubsystems(subject, exportFile, importerConfigurations);
}
//SYNCHRONIZATIONMANANGER: END -------------------------
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/DeployedAgentPluginsValidatorTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/DeployedAgentPluginsValidatorTest.java
index 133750d..061d803 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/DeployedAgentPluginsValidatorTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/DeployedAgentPluginsValidatorTest.java
@@ -54,7 +54,8 @@ import org.rhq.test.JMockTest;
*
* @author Lukas Krejci
*/
-@Test
+//@Test - switching this off for now because this validator is no longer used in any
+//of the default synchronizers
public class DeployedAgentPluginsValidatorTest extends JMockTest {
private static final Log LOG = LogFactory.getLog(DeployedAgentPluginsValidator.class);
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/ExportingInputStreamTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/ExportingInputStreamTest.java
index 975e6d3..6d56969 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/ExportingInputStreamTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/ExportingInputStreamTest.java
@@ -65,6 +65,7 @@ import org.rhq.enterprise.server.sync.exporters.ExportingIterator;
import org.rhq.enterprise.server.sync.importers.ExportedEntityMatcher;
import org.rhq.enterprise.server.sync.importers.Importer;
import org.rhq.enterprise.server.sync.validators.ConsistencyValidator;
+import org.rhq.enterprise.server.sync.validators.EntityValidator;
import org.rhq.test.JMockTest;
/**
@@ -140,7 +141,13 @@ public class ExportingInputStreamTest extends JMockTest {
}
@Override
- public void finishImport() throws Exception {
+ public String finishImport() throws Exception {
+ return null;
+ }
+
+ @Override
+ public Set<EntityValidator<T>> getEntityValidators() {
+ return Collections.emptySet();
}
}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MaxCountValidatorTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MaxCountValidatorTest.java
new file mode 100644
index 0000000..b18662b
--- /dev/null
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MaxCountValidatorTest.java
@@ -0,0 +1,52 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 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.server.sync.test;
+
+import static org.testng.Assert.fail;
+
+import org.testng.annotations.Test;
+
+import org.rhq.enterprise.server.sync.ValidationException;
+import org.rhq.enterprise.server.sync.validators.MaxCountValidator;
+
+/**
+ *
+ *
+ * @author Lukas Krejci
+ */
+@Test
+public class MaxCountValidatorTest {
+
+ public void testThrowsValidationExceptionAfterMaxEntitiesValidated() {
+ MaxCountValidator<String> validator = new MaxCountValidator<String>(3);
+
+ validator.initialize(null, null);
+
+ validator.validateExportedEntity("1");
+ validator.validateExportedEntity("2");
+ validator.validateExportedEntity("3");
+ try {
+ validator.validateExportedEntity("4");
+ fail("The max count validator shouldn't have accepted the 4th entry.");
+ } catch (ValidationException e) {
+ //expected
+ }
+ }
+}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateExporterTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateExporterTest.java
index 34de39e..6987001 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateExporterTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateExporterTest.java
@@ -22,13 +22,10 @@ package org.rhq.enterprise.server.sync.test;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
-import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -49,7 +46,6 @@ import org.w3c.dom.NodeList;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.criteria.MeasurementDefinitionCriteria;
import org.rhq.core.domain.measurement.MeasurementDefinition;
-import org.rhq.core.domain.plugin.Plugin;
import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.sync.ExporterMessages;
@@ -57,7 +53,6 @@ import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.measurement.MeasurementDefinitionManagerLocal;
import org.rhq.enterprise.server.measurement.MeasurementScheduleManagerLocal;
-import org.rhq.enterprise.server.resource.metadata.PluginManagerLocal;
import org.rhq.enterprise.server.sync.ExportingInputStream;
import org.rhq.enterprise.server.sync.MetricTemplateSynchronizer;
import org.rhq.enterprise.server.sync.SynchronizationConstants;
@@ -77,19 +72,15 @@ public class MetricTemplateExporterTest extends JMockTest {
public void testCanExport() throws Exception {
final MeasurementDefinitionManagerLocal measurementDefinitionManager = context.mock(MeasurementDefinitionManagerLocal.class);
- final PluginManagerLocal pluginManager = context.mock(PluginManagerLocal.class);
final MeasurementScheduleManagerLocal measurementScheduleManager = context.mock(MeasurementScheduleManagerLocal.class);
context.checking(new Expectations() {
{
allowing(measurementDefinitionManager).findMeasurementDefinitionsByCriteria(with(any(Subject.class)), with(any(MeasurementDefinitionCriteria.class)));
will(returnValue(getFakeMeasurementDefinitions()));
-
- allowing(pluginManager).getInstalledPlugins();
- will(returnValue(getFakeInstalledPlugins()));
}
});
- MetricTemplateSynchronizer exporter = new MetricTemplateSynchronizer(measurementDefinitionManager, measurementScheduleManager, pluginManager);
+ MetricTemplateSynchronizer exporter = new MetricTemplateSynchronizer(measurementDefinitionManager, measurementScheduleManager);
Set<Synchronizer<?, ?>> exporters = new HashSet<Synchronizer<?, ?>>();
exporters.add(exporter);
@@ -227,10 +218,4 @@ public class MetricTemplateExporterTest extends JMockTest {
return new PageList<MeasurementDefinition>(ret, PageControl.getUnlimitedInstance());
}
-
- private static List<Plugin> getFakeInstalledPlugins() {
- Plugin p = new Plugin("fakePlugin", null, "12345");
- p.setVersion("1.0.0.test");
- return Collections.singletonList(p);
- }
}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateImporterTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateImporterTest.java
index 7b50340..8c615b4 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateImporterTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateImporterTest.java
@@ -21,6 +21,7 @@ package org.rhq.enterprise.server.sync.test;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertSame;
+import static org.testng.Assert.assertEquals;
import java.util.Arrays;
import java.util.Collections;
@@ -98,7 +99,6 @@ public class MetricTemplateImporterTest extends JMockTest {
private static final ResourceType FAKE_RESOURCE_TYPE = new ResourceType("fake", "fake", ResourceCategory.PLATFORM,
null);
- @SuppressWarnings("unchecked")
public void testNonMatchingMeasurementDefinitionsAreIgnored() {
final TestPrerequisities prereqs = new TestPrerequisities(context);
@@ -156,7 +156,6 @@ public class MetricTemplateImporterTest extends JMockTest {
importer.finishImport();
}
- @SuppressWarnings("unchecked")
public void testCanUpdateEnablements() {
MeasurementDefinition defToEnable = new MeasurementDefinition(FAKE_RESOURCE_TYPE, "enabled");
MeasurementDefinition defToDisable = new MeasurementDefinition(FAKE_RESOURCE_TYPE, "disable");
@@ -210,7 +209,6 @@ public class MetricTemplateImporterTest extends JMockTest {
}
- @SuppressWarnings("unchecked")
public void testCanUpdateSchedules() {
MeasurementDefinition def = new MeasurementDefinition(FAKE_RESOURCE_TYPE, "def");
def.setId(1);
@@ -253,7 +251,6 @@ public class MetricTemplateImporterTest extends JMockTest {
importer.finishImport();
}
- @SuppressWarnings("unchecked")
public void testPerMetricUpdateScheduleOverrides() {
MeasurementDefinition updatedDef = new MeasurementDefinition(FAKE_RESOURCE_TYPE, "def");
updatedDef.setId(1);
@@ -325,7 +322,6 @@ public class MetricTemplateImporterTest extends JMockTest {
testNonMatchingMeasurementDefinitionsAreIgnored();
}
- @SuppressWarnings("unchecked")
public void testDistinguishingBetweenNormalAndPerMinuteTemplates() {
MeasurementDefinition normalDef = new MeasurementDefinition(FAKE_RESOURCE_TYPE, "def");
MeasurementDefinition perMinuteDef = new MeasurementDefinition(FAKE_RESOURCE_TYPE, "def");
@@ -377,4 +373,40 @@ public class MetricTemplateImporterTest extends JMockTest {
//correctly by the importer.
importer.finishImport();
}
+
+ public void testNotifiesAboutIgnoredMetricTemplates() throws Exception {
+ final TestPrerequisities prereqs = new TestPrerequisities(context);
+ prereqs.setMeasurementDefinitions(Collections.<MeasurementDefinition>emptyList());
+
+ context.checking(new Expectations() {
+ {
+ prereqs.addExpectations(this);
+ }
+ });
+
+ MetricTemplateImporter importer =
+ new MetricTemplateImporter(null, prereqs.getEntityManager(), prereqs.getMeasurementScheduleManager());
+
+ importer.configure(null);
+
+ importer.configure(null);
+
+ MetricTemplate unmatched = new MetricTemplate();
+ unmatched.setMetricName("made-up");
+ unmatched.setResourceTypeName("made-up");
+ unmatched.setResourceTypePlugin("made-up");
+
+ ExportedEntityMatcher<MeasurementDefinition, MetricTemplate> matcher = importer.getExportedEntityMatcher();
+
+ assertNull(matcher.findMatch(unmatched));
+
+ importer.update(null, unmatched);
+
+ String notes = importer.finishImport();
+
+ String expectedNotes =
+ MetricTemplateImporter.getUnmatchedMetricTemplatesReport(Collections.singleton(unmatched));
+
+ assertEquals(notes, expectedNotes);
+ }
}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateValidatorTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateValidatorTest.java
deleted file mode 100644
index 3afe29f..0000000
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateValidatorTest.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2011 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.server.sync.test;
-
-import static org.testng.Assert.*;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
-
-import org.jmock.Expectations;
-import org.testng.annotations.Test;
-
-import org.rhq.core.domain.measurement.MeasurementDefinition;
-import org.rhq.core.domain.measurement.NumericType;
-import org.rhq.core.domain.resource.ResourceCategory;
-import org.rhq.core.domain.resource.ResourceType;
-import org.rhq.core.domain.sync.entity.MetricTemplate;
-import org.rhq.enterprise.server.sync.ValidationException;
-import org.rhq.enterprise.server.sync.validators.MetricTemplateValidator;
-import org.rhq.test.JMockTest;
-
-/**
- *
- *
- * @author Lukas Krejci
- */
-@Test
-public class MetricTemplateValidatorTest extends JMockTest {
-
- private static final ResourceType FAKE_RESOURCE_TYPE = new ResourceType("fake", "fake", ResourceCategory.PLATFORM, null);
-
- public void testAllValidatorsEqual() {
- MetricTemplateValidator v1 = new MetricTemplateValidator();
- MetricTemplateValidator v2 = new MetricTemplateValidator();
- MetricTemplateValidator v3 = new MetricTemplateValidator();
-
- assertEquals(v1, v2);
- assertEquals(v2, v3);
- assertEquals(v1, v3);
- }
-
- public void testDetectsUnknownTemplates() throws Exception {
- final EntityManager entityManager = context.mock(EntityManager.class);
- final Query q = context.mock(Query.class);
-
- final List<MeasurementDefinition> allDefs = new ArrayList<MeasurementDefinition>();
-
- context.checking(new Expectations() {
- {
- //make the entity manager return the test data
- allowing(entityManager).createQuery(with(any(String.class)));
- will(returnValue(q));
-
- allowing(q).getResultList();
- will(returnValue(allDefs));
- }
- });
-
- //add some test data
- allDefs.add(createMeasurementDefinition("m1", false));
- allDefs.add(createMeasurementDefinition("m1", true));
- allDefs.add(createMeasurementDefinition("m2", false));
- allDefs.add(createMeasurementDefinition("m3", false));
-
- MetricTemplateValidator validator = new MetricTemplateValidator();
-
- validator.initialize(null, entityManager);
- validator.initializeExportedStateValidation(null);
-
- //check that all the defined measurement defs pass
- for(MeasurementDefinition md : allDefs) {
- validator.validateExportedEntity(new MetricTemplate(md));
- }
-
- //now let's create an "unknown" metric template
- MetricTemplate unknown = new MetricTemplate();
- unknown.setMetricName("unknown");
- unknown.setResourceTypeName("some");
- unknown.setResourceTypePlugin("other");
-
- try {
- validator.validateExportedEntity(unknown);
- fail("Validating a metric template " + unknown + " should have failed.");
- } catch (ValidationException e) {
- //expected
- }
- }
-
- public void testDetectsDuplicitEntries() throws Exception {
- final EntityManager entityManager = context.mock(EntityManager.class);
- final Query q = context.mock(Query.class);
-
- final List<MeasurementDefinition> allDefs = new ArrayList<MeasurementDefinition>();
-
- context.checking(new Expectations() {
- {
- //make the entity manager return the test data
- allowing(entityManager).createQuery(with(any(String.class)));
- will(returnValue(q));
-
- allowing(q).getResultList();
- will(returnValue(allDefs));
- }
- });
-
- //add some test data
- allDefs.add(createMeasurementDefinition("m1", false));
- allDefs.add(createMeasurementDefinition("m1", true));
- allDefs.add(createMeasurementDefinition("m2", false));
- allDefs.add(createMeasurementDefinition("m3", false));
-
- MetricTemplateValidator validator = new MetricTemplateValidator();
-
- validator.initialize(null, entityManager);
- validator.initializeExportedStateValidation(null);
-
- //check that all the defined measurement defs pass
- for(MeasurementDefinition md : allDefs) {
- validator.validateExportedEntity(new MetricTemplate(md));
- }
-
- //now let's try and validate the first test data again.
- //this simulates the duplicate entries in the export file
- try {
- MetricTemplate duplicate = new MetricTemplate(allDefs.get(0));
- validator.validateExportedEntity(duplicate);
- fail("Validating a duplicate metric template " + duplicate + " should have failed.");
- } catch (ValidationException e) {
- //expected
- }
- }
-
- private static MeasurementDefinition createMeasurementDefinition(String name, boolean perMinute) {
- MeasurementDefinition ret = new MeasurementDefinition(FAKE_RESOURCE_TYPE, name);
- if (perMinute) {
- ret.setRawNumericType(NumericType.TRENDSUP);
- }
-
- return ret;
- }
-}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SynchronizationManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SynchronizationManagerBeanTest.java
index c5a0b2e..41f9a56 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SynchronizationManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SynchronizationManagerBeanTest.java
@@ -27,7 +27,9 @@ import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
@@ -37,6 +39,8 @@ import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import javax.persistence.EntityManager;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.stream.XMLStreamException;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
@@ -56,6 +60,8 @@ import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.domain.criteria.MeasurementDefinitionCriteria;
import org.rhq.core.domain.criteria.ResourceCriteria;
import org.rhq.core.domain.measurement.DataType;
@@ -76,10 +82,22 @@ import org.rhq.enterprise.server.authz.PermissionException;
import org.rhq.enterprise.server.measurement.MeasurementDefinitionManagerLocal;
import org.rhq.enterprise.server.measurement.MeasurementScheduleManagerLocal;
import org.rhq.enterprise.server.resource.ResourceManagerLocal;
+import org.rhq.enterprise.server.sync.ExportReader;
+import org.rhq.enterprise.server.sync.ExportWriter;
import org.rhq.enterprise.server.sync.MetricTemplateSynchronizer;
+import org.rhq.enterprise.server.sync.NoSingleEntity;
import org.rhq.enterprise.server.sync.SynchronizationConstants;
import org.rhq.enterprise.server.sync.SynchronizationManagerLocal;
+import org.rhq.enterprise.server.sync.Synchronizer;
+import org.rhq.enterprise.server.sync.SynchronizerFactory;
import org.rhq.enterprise.server.sync.SystemSettingsSynchronizer;
+import org.rhq.enterprise.server.sync.ValidationException;
+import org.rhq.enterprise.server.sync.exporters.Exporter;
+import org.rhq.enterprise.server.sync.exporters.ExportingIterator;
+import org.rhq.enterprise.server.sync.importers.ExportedEntityMatcher;
+import org.rhq.enterprise.server.sync.importers.Importer;
+import org.rhq.enterprise.server.sync.validators.ConsistencyValidator;
+import org.rhq.enterprise.server.sync.validators.EntityValidator;
import org.rhq.enterprise.server.system.SystemManagerLocal;
import org.rhq.enterprise.server.test.AbstractEJB3Test;
import org.rhq.enterprise.server.test.TestServerPluginService;
@@ -108,12 +126,142 @@ public class SynchronizationManagerBeanTest extends AbstractEJB3Test {
public TestServerPluginService testServerPluginService;
}
+ //this can't be mocked out because the config sync machinery has to be able to
+ //instantiate this class
+ public static class ImportConfigurationCheckingSynchronizer implements Synchronizer<NoSingleEntity, String> {
+
+ public static boolean importerConfigured;
+ public static boolean importValidatorsObtainedAfterConfiguration;
+
+ public static void reset() {
+ importerConfigured = false;
+ importValidatorsObtainedAfterConfiguration = false;
+ }
+
+ @Override
+ public void initialize(Subject subject, EntityManager entityManager) {
+ }
+
+ @Override
+ public Exporter<NoSingleEntity, String> getExporter() {
+ return new Exporter<NoSingleEntity, String>() {
+
+ @Override
+ public ExportingIterator<String> getExportingIterator() {
+ return new ExportingIterator<String>() {
+ boolean ran = false;
+
+ @Override
+ public boolean hasNext() {
+ if (ran) {
+ return false;
+ }
+
+ ran = true;
+ return true;
+ }
+
+ @Override
+ public String next() {
+ return null;
+ }
+
+ @Override
+ public void remove() {
+ }
+
+ @Override
+ public void export(ExportWriter output) throws XMLStreamException {
+ output.writeStartElement("my-entity");
+ output.writeCharacters("value");
+ output.writeEndElement();
+ }
+
+ @Override
+ public String getNotes() {
+ return null;
+ }
+
+ };
+ }
+
+ @Override
+ public String getNotes() {
+ return null;
+ }
+
+ };
+ }
+
+ @Override
+ public Importer<NoSingleEntity, String> getImporter() {
+ return new Importer<NoSingleEntity, String>() {
+
+ @Override
+ public ConfigurationDefinition getImportConfigurationDefinition() {
+ return new ConfigurationDefinition("fake", null);
+ }
+
+ @Override
+ public void configure(Configuration importConfiguration) {
+ importerConfigured = true;
+ }
+
+ @Override
+ public ExportedEntityMatcher<NoSingleEntity, String> getExportedEntityMatcher() {
+ return null;
+ }
+
+ @Override
+ public Set<EntityValidator<String>> getEntityValidators() {
+ EntityValidator<String> v = new EntityValidator<String>() {
+
+ @Override
+ public void validateExportedEntity(String entity) throws ValidationException {
+ }
+
+ @Override
+ public void initialize(Subject subject, EntityManager entityManager) {
+ }
+ };
+
+ if (importerConfigured) {
+ importValidatorsObtainedAfterConfiguration = true;
+ }
+
+ return Collections.singleton(v);
+ }
+
+ @Override
+ public void update(NoSingleEntity entity, String exportedEntity) throws Exception {
+ }
+
+ @Override
+ public String unmarshallExportedEntity(ExportReader reader) throws XMLStreamException {
+ return reader.getElementText();
+ }
+
+ @Override
+ public String finishImport() throws Exception {
+ return null;
+ }
+
+ };
+ }
+
+ @Override
+ public Set<ConsistencyValidator> getRequiredValidators() {
+ return Collections.emptySet();
+ }
+
+ }
+
private TestData testData;
//I just don't get why this can't be a @BeforeTest
//but when it was declared as such (together with tearDown() being an @AfterTest)
//no tests would work. I have no idea why...
- private void setup() throws Exception {
+ private void setup(boolean createExport) throws Exception {
testData = new TestData();
getTransactionManager().begin();
try {
@@ -154,7 +302,7 @@ public class SynchronizationManagerBeanTest extends AbstractEJB3Test {
testData.testServerPluginService = new TestServerPluginService();
prepareCustomServerPluginService(testData.testServerPluginService);
testData.testServerPluginService.startMasterPluginContainer();
-
+
synchronizationManager = LookupUtil.getSynchronizationManager();
SystemManagerLocal systemManager = LookupUtil.getSystemManager();
@@ -162,7 +310,10 @@ public class SynchronizationManagerBeanTest extends AbstractEJB3Test {
systemManager.loadSystemConfigurationCache();
testData.systemSettings = systemManager.getSystemConfiguration(freshUser());
- export = synchronizationManager.exportAllSubsystems(freshUser());
+
+ if (createExport) {
+ export = synchronizationManager.exportAllSubsystems(freshUser());
+ }
}
private void tearDown() throws Exception {
@@ -183,7 +334,7 @@ public class SynchronizationManagerBeanTest extends AbstractEJB3Test {
em.remove(attachedType);
em.flush();
-
+
getTransactionManager().commit();
} catch (Exception e) {
getTransactionManager().rollback();
@@ -192,14 +343,14 @@ public class SynchronizationManagerBeanTest extends AbstractEJB3Test {
unprepareServerPluginService();
testData.testServerPluginService.stopMasterPluginContainer();
-
+
export = null;
testData = null;
synchronizationManager = null;
}
public void testExport() throws Exception {
- setup();
+ setup(true);
try {
assertNull("Export shouldn't generate an error message.", export.getErrorMessage());
assertTrue("The export should contain some data.", export.getExportFile().length > 0);
@@ -209,7 +360,7 @@ public class SynchronizationManagerBeanTest extends AbstractEJB3Test {
}
public void testImportWithDefaultConfiguration() throws Exception {
- setup();
+ setup(true);
try {
SystemManagerLocal systemManager = LookupUtil.getSystemManager();
@@ -247,7 +398,7 @@ public class SynchronizationManagerBeanTest extends AbstractEJB3Test {
}
public void testImportWithRedefinedConfigurationInExportFile() throws Exception {
- setup();
+ setup(true);
try {
String exportXML = getExportData();
@@ -255,15 +406,7 @@ public class SynchronizationManagerBeanTest extends AbstractEJB3Test {
exportXML = updateSystemSettingsImportConfiguration(exportXML);
exportXML = updateMetricTemplatesImportConfiguration(exportXML);
- ByteArrayOutputStream compressed = new ByteArrayOutputStream();
- OutputStreamWriter wrt = new OutputStreamWriter(new GZIPOutputStream(compressed), "UTF-8");
- try {
- wrt.write(exportXML);
- } finally {
- wrt.close();
- }
-
- InputStream exportData = new ByteArrayInputStream(compressed.toByteArray());
+ InputStream exportData = createCompressedStream(exportXML);
try {
synchronizationManager.importAllSubsystems(freshUser(), exportData, null);
@@ -317,7 +460,7 @@ public class SynchronizationManagerBeanTest extends AbstractEJB3Test {
}
public void testManuallyPassedImportConfigurationHasPrecendenceOverTheInlinedOne() throws Exception {
- setup();
+ setup(true);
try {
//let's read the original values from the database, so that we know what to compare against
@@ -342,15 +485,7 @@ public class SynchronizationManagerBeanTest extends AbstractEJB3Test {
exportXML = updateSystemSettingsImportConfiguration(exportXML);
exportXML = updateMetricTemplatesImportConfiguration(exportXML);
- ByteArrayOutputStream compressed = new ByteArrayOutputStream();
- OutputStreamWriter wrt = new OutputStreamWriter(new GZIPOutputStream(compressed), "UTF-8");
- try {
- wrt.write(exportXML);
- } finally {
- wrt.close();
- }
-
- InputStream exportData = new ByteArrayInputStream(compressed.toByteArray());
+ InputStream exportData = createCompressedStream(exportXML);
//let's just use the default configs so that we don't apply the changes suggested in
//the changed default configs created above
@@ -408,6 +543,58 @@ public class SynchronizationManagerBeanTest extends AbstractEJB3Test {
}
}
+ public void testUnknownValidatorsAreIgnored() throws Exception {
+ setup(true);
+
+ try {
+ String export = getExportData();
+
+ Document xml =
+ DocumentBuilderFactory.newInstance().newDocumentBuilder()
+ .parse(new InputSource(new StringReader(export)));
+
+ Element unknownValidator = xml.createElement("validator");
+ unknownValidator.setAttribute(SynchronizationConstants.CLASS_ATTRIBUTE, "org.nothing.UnknownValidator");
+
+ xml.getDocumentElement().insertBefore(unknownValidator, xml.getDocumentElement().getFirstChild());
+
+ export = documentToString(xml);
+
+ InputStream exportStream = createCompressedStream(export);
+
+ synchronizationManager.importAllSubsystems(freshUser(), exportStream, null);
+ } finally {
+ tearDown();
+ }
+ }
+
+ public void testImporterConfiguredBeforeValidatorsObtained() throws Exception {
+ setup(false);
+
+ try {
+ ImportConfigurationCheckingSynchronizer.reset();
+
+ synchronizationManager.setSynchronizerFactory(new SynchronizerFactory() {
+ @Override
+ public Set<Synchronizer<?, ?>> getAllSynchronizers() {
+ return Collections.<Synchronizer<?, ?>>singleton(new ImportConfigurationCheckingSynchronizer());
+ }
+ });
+
+ export = synchronizationManager.exportAllSubsystems(freshUser());
+
+ //and import it back again, so that we actually invoke the import validation
+ synchronizationManager.importAllSubsystems(freshUser(), export.getExportFile(), null);
+
+ assertTrue(ImportConfigurationCheckingSynchronizer.importerConfigured);
+ assertTrue(ImportConfigurationCheckingSynchronizer.importValidatorsObtainedAfterConfiguration);
+ } finally {
+ //reset the factory so that other tests work w/ the default syncers
+ synchronizationManager.setSynchronizerFactory(new SynchronizerFactory());
+ tearDown();
+ }
+ }
+
private String getExportData() throws IOException {
InputStreamReader str =
new InputStreamReader(new GZIPInputStream(new ByteArrayInputStream(export.getExportFile())), "UTF-8");
@@ -543,4 +730,16 @@ public class SynchronizationManagerBeanTest extends AbstractEJB3Test {
user = subjectManager.getOverlord();
return user;
}
+
+ private InputStream createCompressedStream(String exportData) throws UnsupportedEncodingException, IOException {
+ ByteArrayOutputStream compressed = new ByteArrayOutputStream();
+ OutputStreamWriter wrt = new OutputStreamWriter(new GZIPOutputStream(compressed), "UTF-8");
+ try {
+ wrt.write(exportData);
+ } finally {
+ wrt.close();
+ }
+
+ return new ByteArrayInputStream(compressed.toByteArray());
+ }
}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SystemSettingsImporterTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SystemSettingsImporterTest.java
index 5b94450..711fb75 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SystemSettingsImporterTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SystemSettingsImporterTest.java
@@ -20,7 +20,6 @@
package org.rhq.enterprise.server.sync.test;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Properties;
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SystemSettingsValidatorTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SystemSettingsValidatorTest.java
index c00cb07..0966080 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SystemSettingsValidatorTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SystemSettingsValidatorTest.java
@@ -19,9 +19,6 @@
package org.rhq.enterprise.server.sync.test;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-
import java.util.Properties;
import org.jmock.Expectations;
@@ -58,22 +55,5 @@ public class SystemSettingsValidatorTest extends JMockTest {
});
validator.validateExportedEntity(importedSettings);
- }
-
- public void testAllValidatorsAreEqual() {
- SystemManagerLocal systemManager = context.mock(SystemManagerLocal.class);
-
- SystemSettingsValidator v1 = new SystemSettingsValidator(systemManager);
- SystemSettingsValidator v2 = new SystemSettingsValidator(systemManager);
- SystemSettingsValidator v3 = new SystemSettingsValidator(systemManager);
- Object o = new Object();
-
- assertEquals(v1, v2);
- assertEquals(v1, v3);
- assertEquals(v2, v3);
-
- assertFalse(v1.equals(o));
- assertFalse(v2.equals(o));
- assertFalse(v3.equals(o));
- }
+ }
}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/UniquenessValidatorTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/UniquenessValidatorTest.java
new file mode 100644
index 0000000..33a0207
--- /dev/null
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/UniquenessValidatorTest.java
@@ -0,0 +1,51 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 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.server.sync.test;
+
+import static org.testng.Assert.fail;
+
+import org.testng.annotations.Test;
+
+import org.rhq.enterprise.server.sync.ValidationException;
+import org.rhq.enterprise.server.sync.validators.UniquenessValidator;
+
+/**
+ *
+ *
+ * @author Lukas Krejci
+ */
+@Test
+public class UniquenessValidatorTest {
+
+ public void testDetectsDuplicitEntries() throws Exception {
+ UniquenessValidator<String> validator = new UniquenessValidator<String>();
+
+ validator.initialize(null, null);
+
+ validator.validateExportedEntity("1");
+ validator.validateExportedEntity("2");
+ try {
+ validator.validateExportedEntity("1");
+ fail("Uniqueness validator should have detected a duplicate entry.");
+ } catch (ValidationException e) {
+ //expected
+ }
+ }
+}
12 years, 7 months
[rhq] modules/core modules/enterprise
by lkrejci
modules/core/domain/src/main/java/org/rhq/core/domain/sync/ImportReport.java | 44 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/MetricTemplateSynchronizer.java | 17
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerBean.java | 173 ++++--
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerLocal.java | 16
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerRemote.java | 9
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizedEntity.java | 10
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizerFactory.java | 42 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SystemSettingsSynchronizer.java | 3
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/Importer.java | 15
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/MetricTemplateImporter.java | 56 ++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/SystemSettingsImporter.java | 14
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/ConsistencyValidator.java | 36 -
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/DeployedAgentPluginsValidator.java | 14
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/EntityValidator.java | 52 ++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/MaxCountValidator.java | 52 ++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/MetricTemplateValidator.java | 121 ----
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/SystemSettingsValidator.java | 48 -
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/UniquenessValidator.java | 50 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java | 5
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/DeployedAgentPluginsValidatorTest.java | 3
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/ExportingInputStreamTest.java | 9
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MaxCountValidatorTest.java | 52 ++
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateExporterTest.java | 17
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateImporterTest.java | 42 +
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateValidatorTest.java | 161 ------
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SynchronizationManagerBeanTest.java | 253 ++++++++--
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SystemSettingsImporterTest.java | 1
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SystemSettingsValidatorTest.java | 22
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/UniquenessValidatorTest.java | 51 ++
29 files changed, 855 insertions(+), 533 deletions(-)
New commits:
commit f3f7a0535ce7f62bd1c0ddd85bd1d24a835fc446
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Nov 7 12:06:01 2011 +0100
[BZ 749126] - Loosening validation requirements on import.
This commit is quite big due to the refactoring but does only
a couple of simple things:
1) The SynchronizationManagerRemote.importAllSubsystems now returns
an ImportReport which contains the notes from subsystem importers about
"interesting" events during the import. This is used to report warnings
or other info to the caller of the import.
Namely the MetricTemplateImporter now reports all the metric templates
from the export file that were not present in the target database
(which basically means that source and target RHQ install had different
plugins installed).
2) Import is lenient about unknown validator classes (this is to not choke
on "old" import files that still may be perfectly valid).
3) The former ConsistencyValidator has been split into 2 separate concepts:
ConsistencyValidator - persists its config into the export file, checks
the consistency of the target RHQ install as a whole.
EntityValidator - configured by the importer, does NOT persist anything
into the export file, used to validate individual entities in the export
file before the import begins.
4) Some new unit tests and a couple of simple changes in the code to
support better testability.
5) DeployedAgentPluginsValidator was "decommissioned" but left in
the codebase as an example implementation.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/sync/ImportReport.java b/modules/core/domain/src/main/java/org/rhq/core/domain/sync/ImportReport.java
new file mode 100644
index 0000000..d9baab7
--- /dev/null
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/sync/ImportReport.java
@@ -0,0 +1,44 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 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.domain.sync;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *
+ *
+ * @author Lukas Krejci
+ */
+public class ImportReport implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private Map<String, String> importerNotes;
+
+ public Map<String, String> getImporterNotes() {
+ if (importerNotes == null) {
+ importerNotes = new HashMap<String, String>();
+ }
+
+ return importerNotes;
+ }
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/MetricTemplateSynchronizer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/MetricTemplateSynchronizer.java
index 913c981..1dcdd9c 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/MetricTemplateSynchronizer.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/MetricTemplateSynchronizer.java
@@ -19,6 +19,7 @@
package org.rhq.enterprise.server.sync;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@@ -36,7 +37,7 @@ import org.rhq.enterprise.server.sync.importers.Importer;
import org.rhq.enterprise.server.sync.importers.MetricTemplateImporter;
import org.rhq.enterprise.server.sync.validators.ConsistencyValidator;
import org.rhq.enterprise.server.sync.validators.DeployedAgentPluginsValidator;
-import org.rhq.enterprise.server.sync.validators.MetricTemplateValidator;
+import org.rhq.enterprise.server.sync.validators.UniquenessValidator;
import org.rhq.enterprise.server.util.LookupUtil;
/**
@@ -50,17 +51,15 @@ public class MetricTemplateSynchronizer implements Synchronizer<MeasurementDefin
private EntityManager entityManager;
private MeasurementDefinitionManagerLocal measurementDefinitionManager;
private MeasurementScheduleManagerLocal measurementScheduleManager;
- private PluginManagerLocal pluginManager;
public MetricTemplateSynchronizer() {
- this(LookupUtil.getMeasurementDefinitionManager(), LookupUtil.getMeasurementScheduleManager(), LookupUtil.getPluginManager());
+ this(LookupUtil.getMeasurementDefinitionManager(), LookupUtil.getMeasurementScheduleManager());
}
public MetricTemplateSynchronizer(MeasurementDefinitionManagerLocal measurementDefinitionManager,
- MeasurementScheduleManagerLocal measurementScheduleManager, PluginManagerLocal pluginManager) {
+ MeasurementScheduleManagerLocal measurementScheduleManager) {
this.measurementDefinitionManager = measurementDefinitionManager;
this.measurementScheduleManager = measurementScheduleManager;
- this.pluginManager = pluginManager;
}
@Override
@@ -69,19 +68,19 @@ public class MetricTemplateSynchronizer implements Synchronizer<MeasurementDefin
this.entityManager = entityManager;
}
+ @Override
public Exporter<MeasurementDefinition, MetricTemplate> getExporter() {
return new MetricTemplateExporter(subject, measurementDefinitionManager);
}
+ @Override
public Importer<MeasurementDefinition, MetricTemplate> getImporter() {
return new MetricTemplateImporter(subject, entityManager, measurementScheduleManager);
}
+ @Override
public Set<ConsistencyValidator> getRequiredValidators() {
- HashSet<ConsistencyValidator> ret = new HashSet<ConsistencyValidator>();
- ret.add(new DeployedAgentPluginsValidator(pluginManager));
- ret.add(new MetricTemplateValidator());
- return ret;
+ return Collections.emptySet();
}
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerBean.java
index af848b1..992687e 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerBean.java
@@ -30,6 +30,7 @@ import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -54,7 +55,6 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.auth.Subject;
-import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.sync.ConsistencyValidatorFailureReport;
import org.rhq.core.domain.sync.ExportReport;
@@ -62,12 +62,13 @@ import org.rhq.core.domain.sync.ExportWrapper;
import org.rhq.core.domain.sync.ExporterMessages;
import org.rhq.core.domain.sync.ImportConfiguration;
import org.rhq.core.domain.sync.ImportConfigurationDefinition;
+import org.rhq.core.domain.sync.ImportReport;
import org.rhq.core.util.stream.StreamUtil;
import org.rhq.enterprise.server.RHQConstants;
-import org.rhq.enterprise.server.authz.RequiredPermission;
import org.rhq.enterprise.server.sync.importers.ExportedEntityMatcher;
import org.rhq.enterprise.server.sync.importers.Importer;
import org.rhq.enterprise.server.sync.validators.ConsistencyValidator;
+import org.rhq.enterprise.server.sync.validators.EntityValidator;
import org.rhq.enterprise.server.sync.validators.InconsistentStateException;
import org.rhq.enterprise.server.xmlschema.ConfigurationInstanceDescriptorUtil;
@@ -85,18 +86,25 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
private EntityManager entityManager;
private JAXBContext defaultImportConfigurationJAXBContext;
+
+ private SynchronizerFactory synchronizerFactory = new SynchronizerFactory();
public SynchronizationManagerBean() {
try {
- defaultImportConfigurationJAXBContext = JAXBContext.newInstance(DefaultImportConfigurationDescriptor.class);
+ defaultImportConfigurationJAXBContext = JAXBContext.newInstance(DefaultImportConfigurationDescriptor.class);
} catch (JAXBException e) {
throw new IllegalStateException("Failed to create DefaultImportConfigurationDescriptor unmarshaller. This should never happen.");
}
}
+ //for test purposes
+ @Override
+ public void setSynchronizerFactory(SynchronizerFactory factory) {
+ this.synchronizerFactory = factory;
+ }
+
@Override
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
- @RequiredPermission(Permission.MANAGE_INVENTORY)
public ExportReport exportAllSubsystems(Subject subject) {
ExportWrapper localExport = exportAllSubsystemsLocally(subject);
@@ -131,17 +139,10 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
@Override
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
- @RequiredPermission(Permission.MANAGE_INVENTORY)
public ExportWrapper exportAllSubsystemsLocally(Subject subject) {
- Set<Synchronizer<?, ?>> allSynchronizers = new HashSet<Synchronizer<?, ?>>();
+ Set<Synchronizer<?, ?>> allSynchronizers = getInitializedSynchronizers(subject);
Map<String, ExporterMessages> messages = new HashMap<String, ExporterMessages>();
- for (SynchronizedEntity e : SynchronizedEntity.values()) {
- Synchronizer<?, ?> synchronizer = e.getSynchronizer();
- synchronizer.initialize(subject, entityManager);
- allSynchronizers.add(synchronizer);
- }
-
try {
return new ExportWrapper(messages, new ExportingInputStream(allSynchronizers, messages));
} catch (IOException e) {
@@ -150,8 +151,7 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
}
@Override
- @RequiredPermission(Permission.MANAGE_INVENTORY)
- public void importAllSubsystems(Subject subject, InputStream exportFile, List<ImportConfiguration> configurations)
+ public ImportReport importAllSubsystems(Subject subject, InputStream exportFile, List<ImportConfiguration> configurations)
throws ValidationException, ImportException {
File tmpFile = null;
@@ -170,13 +170,15 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
}
InputStream in = null;
- try {
+ try {
+ Map<String, Configuration> configsPerImports = getConfigPerImporter(configurations);
+
in = new GZIPInputStream(new BufferedInputStream(new FileInputStream(tmpFile)));
- validateExport(subject, in);
+ validateExport(subject, in, configsPerImports);
in.close();
in = new GZIPInputStream(new BufferedInputStream(new FileInputStream(tmpFile)));
- importExportFile(subject, in, getConfigPerImporter(configurations));
+ return importExportFile(subject, in, configsPerImports);
} catch (XMLStreamException e) {
throw new ImportException("Failed import due to XML parsing error.", e);
} catch (IOException e) {
@@ -188,24 +190,21 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
}
@Override
- @RequiredPermission(Permission.MANAGE_INVENTORY)
- public void importAllSubsystems(Subject subject, byte[] exportFile, List<ImportConfiguration> configurations)
+ public ImportReport importAllSubsystems(Subject subject, byte[] exportFile, List<ImportConfiguration> configurations)
throws ValidationException, ImportException {
- importAllSubsystems(subject, new ByteArrayInputStream(exportFile), configurations);
+ return importAllSubsystems(subject, new ByteArrayInputStream(exportFile), configurations);
}
@Override
- @RequiredPermission(Permission.MANAGE_INVENTORY)
public void validate(Subject subject, InputStream exportFile) throws ValidationException {
try {
- validateExport(subject, exportFile);
+ validateExport(subject, exportFile, Collections.<String, Configuration>emptyMap());
} catch (XMLStreamException e) {
throw new ValidationException("Failed to parse the export file.", e);
}
}
@Override
- @RequiredPermission(Permission.MANAGE_INVENTORY)
public void validate(Subject subject, byte[] exportFile) throws ValidationException {
validate(subject, new ByteArrayInputStream(exportFile));
}
@@ -235,8 +234,7 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
public List<ImportConfigurationDefinition> getImportConfigurationDefinitionOfAllSynchronizers() {
List<ImportConfigurationDefinition> ret = new ArrayList<ImportConfigurationDefinition>();
- for (SynchronizedEntity e : SynchronizedEntity.values()) {
- Synchronizer<?, ?> syn = e.getSynchronizer();
+ for (Synchronizer<?, ?> syn : synchronizerFactory.getAllSynchronizers()) {
ret.add(new ImportConfigurationDefinition(syn.getClass().getName(), syn.getImporter()
.getImportConfigurationDefinition()));
}
@@ -244,12 +242,12 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
return ret;
}
- private void validateExport(Subject subject, InputStream exportFile) throws ValidationException, XMLStreamException {
+ private void validateExport(Subject subject, InputStream exportFile, Map<String, Configuration> importConfigs) throws ValidationException, XMLStreamException {
XMLStreamReader rdr = XMLInputFactory.newInstance().createXMLStreamReader(exportFile);
try {
Set<ConsistencyValidatorFailureReport> failures = new HashSet<ConsistencyValidatorFailureReport>();
- Set<ConsistencyValidator> executedValidators = new HashSet<ConsistencyValidator>();
+ Set<ConsistencyValidator> consistencyValidators = new HashSet<ConsistencyValidator>();
while (rdr.hasNext()) {
switch (rdr.next()) {
@@ -258,6 +256,11 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
if (SynchronizationConstants.VALIDATOR_ELEMENT.equals(tagName)) {
ConsistencyValidator validator = null;
String validatorClass = rdr.getAttributeValue(null, SynchronizationConstants.CLASS_ATTRIBUTE);
+ if (!isConsistencyValidatorClass(validatorClass)) {
+ LOG.info("The export file contains an unknown consistency validator: " + validatorClass + ". Ignoring.");
+ continue;
+ }
+
try {
validator = validateSingle(rdr, subject);
} catch (Exception e) {
@@ -265,14 +268,12 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
printExceptionToString(e)));
}
if (validator != null) {
- executedValidators.add(validator);
+ consistencyValidators.add(validator);
}
} else if (SynchronizationConstants.ENTITIES_EXPORT_ELEMENT.equals(tagName)) {
- //all the validators preceed the importers in the export file so we can now check if the
- //validator was already run
String synchronizerClass = rdr.getAttributeValue(null, SynchronizationConstants.ID_ATTRIBUTE);
try {
- failures.addAll(validateEntities(rdr, subject, executedValidators));
+ failures.addAll(validateEntities(rdr, subject, consistencyValidators, importConfigs));
} catch (Exception e) {
throw new ValidationException(
"Validation failed unexpectedly while processing the entities exported by the synchronizer '"
@@ -290,24 +291,38 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
}
}
- private Set<ConsistencyValidatorFailureReport> validateEntities(XMLStreamReader rdr, Subject subject,
- Set<ConsistencyValidator> executedValidators) throws Exception {
+ /**
+ * @param validatorClass
+ * @return
+ */
+ private boolean isConsistencyValidatorClass(String validatorClass) {
+ try {
+ Class<?> cls = Class.forName(validatorClass);
+
+ return ConsistencyValidator.class.isAssignableFrom(cls);
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ private <E, X> Set<ConsistencyValidatorFailureReport> validateEntities(XMLStreamReader rdr, Subject subject,
+ Set<ConsistencyValidator> consistencyValidators, Map<String, Configuration> importConfigurations) throws Exception {
String synchronizerClass = rdr.getAttributeValue(null, SynchronizationConstants.ID_ATTRIBUTE);
HashSet<ConsistencyValidatorFailureReport> ret = new HashSet<ConsistencyValidatorFailureReport>();
- Synchronizer<?, ?> synchronizer = instantiate(synchronizerClass, Synchronizer.class,
+ @SuppressWarnings("unchecked")
+ Synchronizer<E, X> synchronizer = instantiate(synchronizerClass, Synchronizer.class,
"The id attribute of entities doesn't correspond to a class implementing the Synchronizer interface.");
synchronizer.initialize(subject, entityManager);
- Importer<?, ?> importer = synchronizer.getImporter();
+ Importer<E, X> importer = synchronizer.getImporter();
- //pre-init the validators so that we can reuse them in the loop below
- Set<ConsistencyValidator> validators = synchronizer.getRequiredValidators();
- for(ConsistencyValidator v : validators) {
- v.initialize(subject, entityManager);
-
- if (!executedValidators.contains(v)) {
+ Set<ConsistencyValidator> requriedConsistencyValidators = synchronizer.getRequiredValidators();
+
+ //check that all the required consistency validators were run
+ for(ConsistencyValidator v : requriedConsistencyValidators) {
+ if (!consistencyValidators.contains(v)) {
ret.add(new ConsistencyValidatorFailureReport(v.getClass().getName(), "The validator '"
+ v.getClass().getName() + "' is required by the synchronizer '" + synchronizerClass
+ "' but was not found in the export file."));
@@ -319,29 +334,48 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
return ret;
}
+ boolean configured = false;
+ Configuration importConfiguration = importConfigurations.get(synchronizerClass);
+
+ Set<EntityValidator<X>> validators = null;
+
+ //the passed in configuration has precedence over the default one inlined in
+ //the config file.
+ if (importConfiguration != null) {
+ importer.configure(importConfiguration);
+ validators = importer.getEntityValidators();
+ for(EntityValidator<X> v : validators) {
+ v.initialize(subject, entityManager);
+ }
+ configured = true;
+ }
+
while (rdr.hasNext()) {
boolean bailout = false;
switch (rdr.next()) {
case XMLStreamConstants.START_ELEMENT:
- if (SynchronizationConstants.DATA_ELEMENT.equals(rdr.getName().getLocalPart())) {
- rdr.nextTag();
- Object exportedEntity = importer.unmarshallExportedEntity(new ExportReader(rdr));
- Class<?> exportedEntityClass = exportedEntity.getClass();
+ if (SynchronizationConstants.DEFAULT_CONFIGURATION_ELEMENT.equals(rdr.getName().getLocalPart())) {
+ if (!configured) {
+ importConfiguration = getDefaultConfiguration(rdr);
+ }
+ } else if (SynchronizationConstants.DATA_ELEMENT.equals(rdr.getName().getLocalPart())) {
- for (ConsistencyValidator validator : validators) {
- boolean shouldCheck = false;
- for (Class<?> cls : validator.getValidatedEntityTypes()) {
- if (cls.isAssignableFrom(exportedEntityClass)) {
- shouldCheck = true;
- break;
- }
- }
-
- if (!shouldCheck) {
- //ok, this validator doesn't want to validate this type of entity
- continue;
+ //first check if the configure method has been called
+ if (!configured) {
+ importer.configure(importConfiguration);
+ validators = importer.getEntityValidators();
+ for(EntityValidator<X> v : validators) {
+ v.initialize(subject, entityManager);
}
+ configured = true;
+ }
+
+ //now do the validation
+ rdr.nextTag();
+ X exportedEntity = importer.unmarshallExportedEntity(new ExportReader(rdr));
+
+ for (EntityValidator<X> validator : validators) {
try {
validator.validateExportedEntity(exportedEntity);
} catch (Exception e) {
@@ -367,17 +401,23 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
return ret;
}
- private void importExportFile(Subject subject, InputStream exportFile,
+ private ImportReport importExportFile(Subject subject, InputStream exportFile,
Map<String, Configuration> importerConfigs) throws ImportException, XMLStreamException {
XMLStreamReader rdr = XMLInputFactory.newInstance().createXMLStreamReader(exportFile);
+ ImportReport report = new ImportReport();
+
while (rdr.hasNext()) {
switch (rdr.next()) {
case XMLStreamReader.START_ELEMENT:
String tagName = rdr.getName().getLocalPart();
if (SynchronizationConstants.ENTITIES_EXPORT_ELEMENT.equals(tagName)) {
try {
- importSingle(subject, importerConfigs, rdr);
+ String synchronizer = rdr.getAttributeValue(null, SynchronizationConstants.ID_ATTRIBUTE);
+ String notes = importSingle(subject, importerConfigs, rdr);
+ if (notes != null) {
+ report.getImporterNotes().put(synchronizer, notes);
+ }
} catch (Exception e) {
//fail fast on the import errors... This runs in a single transaction
//so all imports done so far will get rolled-back.
@@ -390,6 +430,8 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
break;
}
}
+
+ return report;
}
private ConsistencyValidator validateSingle(XMLStreamReader rdr, Subject subject) throws InstantiationException,
@@ -410,7 +452,7 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
return validator;
}
- private <E, X> void importSingle(Subject subject, Map<String, Configuration> importConfigs, XMLStreamReader rdr)
+ private <E, X> String importSingle(Subject subject, Map<String, Configuration> importConfigs, XMLStreamReader rdr)
throws Exception {
String synchronizerClassName = rdr.getAttributeValue(null, SynchronizationConstants.ID_ATTRIBUTE);
@@ -477,7 +519,7 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
importer.configure(importConfiguration);
}
- importer.finishImport();
+ return importer.finishImport();
}
private static String printExceptionToString(Throwable t) {
@@ -499,6 +541,15 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
return desiredClass.cast(instance);
}
+ private Set<Synchronizer<?, ?>> getInitializedSynchronizers(Subject subject) {
+ Set<Synchronizer<?, ?>> ret = synchronizerFactory.getAllSynchronizers();
+ for(Synchronizer<?, ?> s : ret) {
+ s.initialize(subject, entityManager);
+ }
+
+ return ret;
+ }
+
private Map<String, Configuration> getConfigPerImporter(List<ImportConfiguration> list) {
Map<String, Configuration> ret = new HashMap<String, Configuration>();
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerLocal.java
index e391f25..fd4d425 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerLocal.java
@@ -31,6 +31,7 @@ import org.rhq.core.domain.sync.ExportReport;
import org.rhq.core.domain.sync.ExportWrapper;
import org.rhq.core.domain.sync.ImportConfiguration;
import org.rhq.core.domain.sync.ImportConfigurationDefinition;
+import org.rhq.core.domain.sync.ImportReport;
/**
*
@@ -60,7 +61,18 @@ public interface SynchronizationManagerLocal {
void validate(Subject subject, InputStream exportFile) throws ValidationException;
- void importAllSubsystems(Subject subject, InputStream exportFile, List<ImportConfiguration> importerConfigurations) throws ValidationException, ImportException;
+ ImportReport importAllSubsystems(Subject subject, InputStream exportFile, List<ImportConfiguration> importerConfigurations) throws ValidationException, ImportException;
+
+ /**
+ * <b>Provided for testability reasons. DON'T USE OUTSIDE TESTS.</b>
+ * <p>
+ * Using this method one can provide a custom factory
+ * for {@link Synchronizer}s. This way one can export/import different types of entities
+ * than by default.
+ *
+ * @param factory
+ */
+ void setSynchronizerFactory(SynchronizerFactory factory);
//-------- THE FOLLOWING METHODS ARE SHARED WITH THE REMOTE INTERFACE ------------
@@ -93,5 +105,5 @@ public interface SynchronizationManagerLocal {
/**
* @see SynchronizationManagerRemote#importAllSubsystems(Subject, byte[], Set)
*/
- void importAllSubsystems(Subject subject, byte[] exportFile, List<ImportConfiguration> importerConfigurations) throws ValidationException, ImportException;
+ ImportReport importAllSubsystems(Subject subject, byte[] exportFile, List<ImportConfiguration> importerConfigurations) throws ValidationException, ImportException;
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerRemote.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerRemote.java
index 0cefd8c..eb6b5c9 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerRemote.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerRemote.java
@@ -28,6 +28,7 @@ import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.sync.ExportReport;
import org.rhq.core.domain.sync.ImportConfiguration;
import org.rhq.core.domain.sync.ImportConfigurationDefinition;
+import org.rhq.core.domain.sync.ImportReport;
/**
*
@@ -75,9 +76,11 @@ public interface SynchronizationManagerRemote {
*
* @param subject the authenticated user
* @param exportFile the contents of the export file
- * @param importerConfigurations the configurations of individual importers to be used when importing
+ * @param importerConfigurations the configurations of individual importers to be used when importing or null
+ * if the default configurations should be used for all the importers.
*
- * @return the report describing the result of the export
+ * @return the report describing the result of the import
*/
- void importAllSubsystems(Subject subject, byte[] exportFile, List<ImportConfiguration> importerConfigurations) throws ValidationException, ImportException;
+ ImportReport importAllSubsystems(Subject subject, byte[] exportFile,
+ List<ImportConfiguration> importerConfigurations) throws ValidationException, ImportException;
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizedEntity.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizedEntity.java
index 21e15b0..6668947 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizedEntity.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizedEntity.java
@@ -19,16 +19,12 @@
package org.rhq.enterprise.server.sync;
-import org.rhq.enterprise.server.sync.exporters.Exporter;
-import org.rhq.enterprise.server.sync.exporters.MetricTemplateExporter;
-import org.rhq.enterprise.server.sync.exporters.SystemSettingsExporter;
-import org.rhq.enterprise.server.sync.importers.Importer;
-import org.rhq.enterprise.server.sync.importers.MetricTemplateImporter;
-import org.rhq.enterprise.server.sync.importers.SystemSettingsImporter;
/**
* The enum of all possible synchronized entities.
- *
+ * This is used in the {@link SynchronizerFactory#getAllSynchronizers()} to provide
+ * the synchronizers to the rest of the config sync machinery.
+ *
* @author Lukas Krejci
*/
public enum SynchronizedEntity {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizerFactory.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizerFactory.java
new file mode 100644
index 0000000..2ffada1
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizerFactory.java
@@ -0,0 +1,42 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 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.server.sync;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+/**
+ * A factory for obtaining synchronizers.
+ * This is mainly useful for test purposes where this class can be subclassed
+ * and passed to the {@link SynchronizationManagerBean}.
+ *
+ * @author Lukas Krejci
+ */
+public class SynchronizerFactory {
+
+ public Set<Synchronizer<?, ?>> getAllSynchronizers() {
+ LinkedHashSet<Synchronizer<?, ?>> ret = new LinkedHashSet<Synchronizer<?,?>>();
+ for (SynchronizedEntity e : SynchronizedEntity.values()) {
+ ret.add(e.getSynchronizer());
+ }
+
+ return ret;
+ }
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SystemSettingsSynchronizer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SystemSettingsSynchronizer.java
index da0b0e7..dc62060 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SystemSettingsSynchronizer.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SystemSettingsSynchronizer.java
@@ -31,7 +31,6 @@ import org.rhq.enterprise.server.sync.exporters.SystemSettingsExporter;
import org.rhq.enterprise.server.sync.importers.Importer;
import org.rhq.enterprise.server.sync.importers.SystemSettingsImporter;
import org.rhq.enterprise.server.sync.validators.ConsistencyValidator;
-import org.rhq.enterprise.server.sync.validators.SystemSettingsValidator;
import org.rhq.enterprise.server.system.SystemManagerLocal;
import org.rhq.enterprise.server.util.LookupUtil;
@@ -67,7 +66,7 @@ public class SystemSettingsSynchronizer implements Synchronizer<NoSingleEntity,
}
public Set<ConsistencyValidator> getRequiredValidators() {
- return Collections.<ConsistencyValidator>singleton(new SystemSettingsValidator(systemManager));
+ return Collections.emptySet();
}
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/Importer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/Importer.java
index b61777d..a29e099 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/Importer.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/Importer.java
@@ -19,11 +19,14 @@
package org.rhq.enterprise.server.sync.importers;
+import java.util.Set;
+
import javax.xml.stream.XMLStreamException;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.enterprise.server.sync.ExportReader;
+import org.rhq.enterprise.server.sync.validators.EntityValidator;
/**
* Implementations of this interface are used to import entities into the database.
@@ -58,6 +61,12 @@ public interface Importer<Entity, ExportedType> {
ExportedEntityMatcher<Entity, ExportedType> getExportedEntityMatcher();
/**
+ * The set of entity validators that should be called on each entity before
+ * the import actually starts.
+ */
+ Set<EntityValidator<ExportedType>> getEntityValidators();
+
+ /**
* Updates the entity with the data from the export.
* <p>
* This method is responsible for persisting the entity in the database
@@ -84,6 +93,10 @@ public interface Importer<Entity, ExportedType> {
* have been {@link #update(Object, Object) updated}.
* <p>
* This is useful for importers that need to batch the updates to the database.
+ *
+ * @return notes that should be transfered to the user. These should be any warnings and other
+ * messages that are not errors (which should throw an exception) but are deemed
+ * important for the (human) caller to be aware of.
*/
- void finishImport() throws Exception;
+ String finishImport() throws Exception;
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/MetricTemplateImporter.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/MetricTemplateImporter.java
index 78eea09..f4fa3f5 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/MetricTemplateImporter.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/MetricTemplateImporter.java
@@ -21,9 +21,13 @@ package org.rhq.enterprise.server.sync.importers;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
import javax.persistence.EntityManager;
import javax.persistence.Query;
@@ -51,6 +55,8 @@ import org.rhq.core.domain.measurement.MeasurementDefinition;
import org.rhq.core.domain.sync.entity.MetricTemplate;
import org.rhq.enterprise.server.measurement.MeasurementScheduleManagerLocal;
import org.rhq.enterprise.server.sync.ExportReader;
+import org.rhq.enterprise.server.sync.validators.EntityValidator;
+import org.rhq.enterprise.server.sync.validators.UniquenessValidator;
import org.rhq.enterprise.server.util.LookupUtil;
/**
@@ -71,6 +77,8 @@ public class MetricTemplateImporter implements Importer<MeasurementDefinition, M
public static final String METRIC_UPDATE_OVERRIDES_PROPERTY = "metricUpdateOverrides";
public static final String METRIC_UPDATE_OVERRIDE_PROPERTY = "metricUpdateOverride";
+ private static final String IMPORT_NOTES_PROLOGUE = "The following metric templates were not imported because they do not correspond to any metric defined by the existing resource types:\n";
+
private static class UpdateKey {
public final long collectionInterval;
public final boolean updateSchedules;
@@ -104,6 +112,26 @@ public class MetricTemplateImporter implements Importer<MeasurementDefinition, M
}
}
+ private static final Comparator<MetricTemplate> METRIC_TEMPLATE_COMPARATOR = new Comparator<MetricTemplate>() {
+
+ @Override
+ public int compare(MetricTemplate o1, MetricTemplate o2) {
+ //sort by plugin, type name, and metric name in that order
+
+ int ret = o1.getResourceTypePlugin().compareTo(o2.getResourceTypePlugin());
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = o1.getResourceTypeName().compareTo(o2.getResourceTypeName());
+ if (ret != 0) {
+ return ret;
+ }
+
+ return o1.getMetricName().compareTo(o2.getMetricName());
+ }
+ };
+
private Subject subject;
private EntityManager entityManager;
private Map<UpdateKey, List<MeasurementDefinition>> definitionsByUpdateKey =
@@ -111,7 +139,8 @@ public class MetricTemplateImporter implements Importer<MeasurementDefinition, M
private Configuration importConfiguration;
private Unmarshaller unmarshaller;
private MeasurementScheduleManagerLocal measurementScheduleManager;
-
+ private Set<MetricTemplate> unmatchedTemplates = new TreeSet<MetricTemplate>(METRIC_TEMPLATE_COMPARATOR);
+
public MetricTemplateImporter(Subject subject, EntityManager entityManager) {
this(subject, entityManager, LookupUtil.getMeasurementScheduleManager());
}
@@ -215,8 +244,14 @@ public class MetricTemplateImporter implements Importer<MeasurementDefinition, M
}
@Override
+ public Set<EntityValidator<MetricTemplate>> getEntityValidators() {
+ return Collections.<EntityValidator<MetricTemplate>>singleton(new UniquenessValidator<MetricTemplate>());
+ }
+
+ @Override
public void update(MeasurementDefinition entity, MetricTemplate exportedEntity) {
if (entity == null) {
+ unmatchedTemplates.add(exportedEntity);
return;
}
@@ -233,7 +268,7 @@ public class MetricTemplateImporter implements Importer<MeasurementDefinition, M
}
@Override
- public void finishImport() {
+ public String finishImport() {
for (Map.Entry<UpdateKey, List<MeasurementDefinition>> e : definitionsByUpdateKey.entrySet()) {
int[] ids = getIdsFromDefs(e.getValue());
boolean enable = e.getKey().enable;
@@ -243,8 +278,25 @@ public class MetricTemplateImporter implements Importer<MeasurementDefinition, M
measurementScheduleManager.updateDefaultCollectionIntervalAndEnablementForMeasurementDefinitions(subject,
ids, collectionInterval, enable, updateSchedules);
}
+
+ if (unmatchedTemplates.isEmpty()) {
+ return null;
+ } else {
+ return getUnmatchedMetricTemplatesReport(unmatchedTemplates);
+ }
}
+ //public for testability
+ public static String getUnmatchedMetricTemplatesReport(Set<MetricTemplate> metricTemplates) {
+ StringBuilder bld = new StringBuilder(IMPORT_NOTES_PROLOGUE);
+
+ for(MetricTemplate t : metricTemplates) {
+ bld.append(t).append("\n");
+ }
+
+ return bld.toString();
+ }
+
private static int[] getIdsFromDefs(Collection<MeasurementDefinition> defs) {
int[] ids = new int[defs.size()];
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/SystemSettingsImporter.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/SystemSettingsImporter.java
index 604196a..089746b 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/SystemSettingsImporter.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/importers/SystemSettingsImporter.java
@@ -39,6 +39,9 @@ import org.rhq.core.domain.configuration.definition.PropertySimpleType;
import org.rhq.core.domain.sync.entity.SystemSettings;
import org.rhq.enterprise.server.sync.ExportReader;
import org.rhq.enterprise.server.sync.NoSingleEntity;
+import org.rhq.enterprise.server.sync.validators.EntityValidator;
+import org.rhq.enterprise.server.sync.validators.MaxCountValidator;
+import org.rhq.enterprise.server.sync.validators.SystemSettingsValidator;
import org.rhq.enterprise.server.system.SystemManagerLocal;
/**
@@ -100,6 +103,14 @@ public class SystemSettingsImporter implements Importer<NoSingleEntity, SystemSe
}
@Override
+ public Set<EntityValidator<SystemSettings>> getEntityValidators() {
+ HashSet<EntityValidator<SystemSettings>> ret = new HashSet<EntityValidator<SystemSettings>>();
+ ret.add(new SystemSettingsValidator());
+ ret.add(new MaxCountValidator<SystemSettings>(1));
+ return ret;
+ }
+
+ @Override
public void update(NoSingleEntity entity, SystemSettings exportedEntity) throws Exception {
Properties props = exportedEntity.toProperties();
@@ -131,7 +142,8 @@ public class SystemSettingsImporter implements Importer<NoSingleEntity, SystemSe
}
@Override
- public void finishImport() {
+ public String finishImport() {
+ return null;
}
private Set<String> getSettingNamesConfiguredForImport(Configuration importConfiguration) {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/ConsistencyValidator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/ConsistencyValidator.java
index 2b42f5a..30d2cd5 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/ConsistencyValidator.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/ConsistencyValidator.java
@@ -19,8 +19,6 @@
package org.rhq.enterprise.server.sync.validators;
-import java.util.Set;
-
import javax.persistence.EntityManager;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
@@ -28,7 +26,6 @@ import javax.xml.stream.XMLStreamReader;
import org.rhq.core.domain.auth.Subject;
import org.rhq.enterprise.server.sync.ExportReader;
import org.rhq.enterprise.server.sync.ExportWriter;
-import org.rhq.enterprise.server.sync.ValidationException;
/**
* Implementations of this interface can export a state and validate that
@@ -90,37 +87,4 @@ public interface ConsistencyValidator {
* @throws InconsistentStateException in case of failed consistency check
*/
void validateExportedState() throws InconsistentStateException;
-
- /**
- * Returns the types of exported entities this validator can validate before export.
- * This set can be empty, which would mean it can only validate the current state.
- */
- Set<Class<?>> getValidatedEntityTypes();
-
- /**
- * Validates a single entity before it is imported.
- * The supplied entity has one of the types returned by {@link #getValidatedEntityTypes()}.
- *
- * @param entity
- */
- void validateExportedEntity(Object entity) throws ValidationException;
-
- /**
- * Implementations of the consistency validator interface should reimplement the
- * {@link Object#equals(Object)} method so that two identically configured
- * validators are equal to each other.
- *
- * @param other
- * @return
- */
- boolean equals(Object other);
-
- /**
- * The {@link ConsistencyValidator} interface mandates a certain behavior of
- * the {@link #equals(Object)} method and therefore the <code>hashCode</code>
- * should be reimplemented accordingly.
- *
- * @return
- */
- int hashCode();
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/DeployedAgentPluginsValidator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/DeployedAgentPluginsValidator.java
index 2ec3f54..94fb4c3 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/DeployedAgentPluginsValidator.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/DeployedAgentPluginsValidator.java
@@ -20,7 +20,6 @@
package org.rhq.enterprise.server.sync.validators;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -35,13 +34,15 @@ import org.rhq.core.domain.plugin.PluginDeploymentType;
import org.rhq.enterprise.server.resource.metadata.PluginManagerLocal;
import org.rhq.enterprise.server.sync.ExportReader;
import org.rhq.enterprise.server.sync.ExportWriter;
-import org.rhq.enterprise.server.sync.ValidationException;
import org.rhq.enterprise.server.util.LookupUtil;
/**
* This implementation checks that the two installations
* have the exact same plugins deployed.
*
+ * Note that this class is currently not used by any synchronizer but
+ * exists for "demo" purposes.
+ *
* @author Lukas Krejci
*/
public class DeployedAgentPluginsValidator implements ConsistencyValidator {
@@ -173,15 +174,6 @@ public class DeployedAgentPluginsValidator implements ConsistencyValidator {
}
@Override
- public Set<Class<?>> getValidatedEntityTypes() {
- return Collections.emptySet();
- }
-
- @Override
- public void validateExportedEntity(Object entity) throws ValidationException {
- }
-
- @Override
public int hashCode() {
//all the deployed plugins validators are equal
return 0;
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/EntityValidator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/EntityValidator.java
new file mode 100644
index 0000000..1555f6f
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/EntityValidator.java
@@ -0,0 +1,52 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 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.server.sync.validators;
+
+import javax.persistence.EntityManager;
+
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.enterprise.server.sync.ValidationException;
+
+/**
+ * Entity validators are declared by importers to validate the entities in the export
+ * file before it gets imported.
+ *
+ * @author Lukas Krejci
+ */
+public interface EntityValidator<T> {
+
+ /**
+ * Initializes the validator with the current authentication info and access to database.
+ * This method is only called during import.
+ *
+ * @param subject the currently authenticated user
+ * @param entityManager the entity manager that can be used to access the database if the
+ * validator needs to do so.
+ */
+ void initialize(Subject subject, EntityManager entityManager);
+
+ /**
+ * Validates a single entity before it is imported.
+ * The supplied entity has one of the types returned by {@link #getValidatedEntityTypes()}.
+ *
+ * @param entity
+ */
+ void validateExportedEntity(T entity) throws ValidationException;
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/MaxCountValidator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/MaxCountValidator.java
new file mode 100644
index 0000000..3dfb5ec
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/MaxCountValidator.java
@@ -0,0 +1,52 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 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.server.sync.validators;
+
+import javax.persistence.EntityManager;
+
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.enterprise.server.sync.ValidationException;
+
+/**
+ *
+ *
+ * @author Lukas Krejci
+ */
+public class MaxCountValidator<T> implements EntityValidator<T> {
+
+ private int max;
+ private int cnt;
+
+ public MaxCountValidator(int max) {
+ this.max = max;
+ }
+
+ @Override
+ public void initialize(Subject subject, EntityManager entityManager) {
+ cnt = 0;
+ }
+
+ @Override
+ public void validateExportedEntity(T entity) throws ValidationException {
+ if (++cnt > max) {
+ throw new ValidationException("Entity " + entity + " is unexpected in the export file. At most " + max + " entites of this type are expected.");
+ }
+ }
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/MetricTemplateValidator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/MetricTemplateValidator.java
deleted file mode 100644
index eddddf7..0000000
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/MetricTemplateValidator.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2011 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.server.sync.validators;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
-import javax.xml.stream.XMLStreamException;
-
-import org.rhq.core.domain.auth.Subject;
-import org.rhq.core.domain.measurement.MeasurementDefinition;
-import org.rhq.core.domain.sync.entity.MetricTemplate;
-import org.rhq.enterprise.server.sync.ExportReader;
-import org.rhq.enterprise.server.sync.ExportWriter;
-import org.rhq.enterprise.server.sync.ValidationException;
-
-/**
- *
- *
- * @author Lukas Krejci
- */
-public class MetricTemplateValidator implements ConsistencyValidator {
-
- private EntityManager entityManager;
- private Set<MetricTemplate> allMeasurementDefinitions;
- private Set<MetricTemplate> alreadyCheckedTemplates;
- private boolean dataInitialized = false;
-
- @Override
- public void initialize(Subject subject, EntityManager entityManager) {
- this.entityManager = entityManager;
- }
-
- @Override
- public void exportState(ExportWriter writer) throws XMLStreamException {
- }
-
- @Override
- public void initializeExportedStateValidation(ExportReader reader) throws XMLStreamException {
- }
-
- @Override
- public void validateExportedState() throws InconsistentStateException {
- }
-
- @Override
- public Set<Class<?>> getValidatedEntityTypes() {
- return Collections.<Class<?>> singleton(MetricTemplate.class);
- }
-
- @Override
- public void validateExportedEntity(Object entity) throws ValidationException {
- initializeData();
-
- MetricTemplate template = (MetricTemplate) entity;
-
- if (!allMeasurementDefinitions.contains(template)) {
- throw new ValidationException(
- "The metric template "
- + template
- + " does not have any corresponding metric template in the database. This either means that the source of the export had different plugins installed, the export file has been manually edited to contain this inconsistency or that the database is corrupted.");
- }
-
- if (!alreadyCheckedTemplates.add(template)) {
- throw new ValidationException("Was the export file manually updated? The metric template " + template + " has been seen multiple times.");
- }
- }
-
- private void initializeData() {
- if (dataInitialized) {
- return;
- }
-
- allMeasurementDefinitions = new HashSet<MetricTemplate>();
- alreadyCheckedTemplates = new HashSet<MetricTemplate>();
-
- Query q = entityManager.createQuery("SELECT md FROM MeasurementDefinition md");
-
- for (Object r : q.getResultList()) {
- MeasurementDefinition md = (MeasurementDefinition) r;
-
- allMeasurementDefinitions.add(new MetricTemplate(md));
- }
-
- dataInitialized = true;
- }
-
- @Override
- public int hashCode() {
- return 0;
- }
-
- @Override
- public boolean equals(Object other) {
- if (this == other) {
- return true;
- }
-
- return other instanceof MetricTemplateValidator;
- }
-}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/SystemSettingsValidator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/SystemSettingsValidator.java
index 1d34516..0698aa7 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/SystemSettingsValidator.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/SystemSettingsValidator.java
@@ -19,16 +19,10 @@
package org.rhq.enterprise.server.sync.validators;
-import java.util.Collections;
-import java.util.Set;
-
import javax.persistence.EntityManager;
-import javax.xml.stream.XMLStreamException;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.sync.entity.SystemSettings;
-import org.rhq.enterprise.server.sync.ExportReader;
-import org.rhq.enterprise.server.sync.ExportWriter;
import org.rhq.enterprise.server.sync.ValidationException;
import org.rhq.enterprise.server.system.SystemManagerLocal;
import org.rhq.enterprise.server.util.LookupUtil;
@@ -38,7 +32,7 @@ import org.rhq.enterprise.server.util.LookupUtil;
*
* @author Lukas Krejci
*/
-public class SystemSettingsValidator implements ConsistencyValidator {
+public class SystemSettingsValidator implements EntityValidator<SystemSettings> {
private Subject subject;
private SystemManagerLocal systemManager;
@@ -57,41 +51,11 @@ public class SystemSettingsValidator implements ConsistencyValidator {
}
@Override
- public void exportState(ExportWriter writer) throws XMLStreamException {
- }
-
- @Override
- public void initializeExportedStateValidation(ExportReader reader) throws XMLStreamException {
- }
-
- @Override
- public void validateExportedState() throws InconsistentStateException {
- }
-
- @Override
- public Set<Class<?>> getValidatedEntityTypes() {
- return Collections.<Class<?>>singleton(SystemSettings.class);
- }
-
- @Override
- public void validateExportedEntity(Object entity) throws ValidationException {
- if (entity instanceof SystemSettings) {
- try {
- systemManager.validateSystemConfiguration(subject, ((SystemSettings)entity).toProperties());
- } catch (Exception e) {
- throw new ValidationException("The system settings failed to validate: " + e.getMessage(), e);
- }
+ public void validateExportedEntity(SystemSettings entity) throws ValidationException {
+ try {
+ systemManager.validateSystemConfiguration(subject, ((SystemSettings)entity).toProperties());
+ } catch (Exception e) {
+ throw new ValidationException("The system settings failed to validate: " + e.getMessage(), e);
}
}
-
- @Override
- public int hashCode() {
- return 0; //all system settings validators are equal
- }
-
- @Override
- public boolean equals(Object obj) {
- //all system settings validators are equal
- return obj instanceof SystemSettingsValidator;
- }
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/UniquenessValidator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/UniquenessValidator.java
new file mode 100644
index 0000000..7fc56f5
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/validators/UniquenessValidator.java
@@ -0,0 +1,50 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 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.server.sync.validators;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.persistence.EntityManager;
+
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.enterprise.server.sync.ValidationException;
+
+/**
+ * This validator merely checks that there are no duplicates in the export file.
+ *
+ * @author Lukas Krejci
+ */
+public class UniquenessValidator<T> implements EntityValidator<T> {
+
+ private Set<T> alreadyCheckedEntities;
+
+ @Override
+ public void initialize(Subject subject, EntityManager entityManager) {
+ alreadyCheckedEntities = new HashSet<T>();
+ }
+
+ @Override
+ public void validateExportedEntity(T entity) throws ValidationException {
+ if (!alreadyCheckedEntities.add(entity)) {
+ throw new ValidationException("Was the export file manually updated? The entity " + entity + " has been seen multiple times.");
+ }
+ }
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
index aef8879..1cb14b2 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
@@ -125,6 +125,7 @@ import org.rhq.core.domain.resource.group.composite.ResourceGroupComposite;
import org.rhq.core.domain.sync.ExportReport;
import org.rhq.core.domain.sync.ImportConfiguration;
import org.rhq.core.domain.sync.ImportConfigurationDefinition;
+import org.rhq.core.domain.sync.ImportReport;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.alert.AlertDefinitionManagerLocal;
@@ -1222,9 +1223,9 @@ public class WebservicesManagerBean implements WebservicesRemote {
return synchronizationManager.getImportConfigurationDefinition(importerClass);
}
- public void importAllSubsystems(Subject subject, byte[] exportFile, List<ImportConfiguration> importerConfigurations)
+ public ImportReport importAllSubsystems(Subject subject, byte[] exportFile, List<ImportConfiguration> importerConfigurations)
throws ValidationException, ImportException {
- synchronizationManager.importAllSubsystems(subject, exportFile, importerConfigurations);
+ return synchronizationManager.importAllSubsystems(subject, exportFile, importerConfigurations);
}
//SYNCHRONIZATIONMANANGER: END -------------------------
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/DeployedAgentPluginsValidatorTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/DeployedAgentPluginsValidatorTest.java
index 133750d..061d803 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/DeployedAgentPluginsValidatorTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/DeployedAgentPluginsValidatorTest.java
@@ -54,7 +54,8 @@ import org.rhq.test.JMockTest;
*
* @author Lukas Krejci
*/
-@Test
+//@Test - switching this off for now because this validator is no longer used in any
+//of the default synchronizers
public class DeployedAgentPluginsValidatorTest extends JMockTest {
private static final Log LOG = LogFactory.getLog(DeployedAgentPluginsValidator.class);
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/ExportingInputStreamTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/ExportingInputStreamTest.java
index 975e6d3..6d56969 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/ExportingInputStreamTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/ExportingInputStreamTest.java
@@ -65,6 +65,7 @@ import org.rhq.enterprise.server.sync.exporters.ExportingIterator;
import org.rhq.enterprise.server.sync.importers.ExportedEntityMatcher;
import org.rhq.enterprise.server.sync.importers.Importer;
import org.rhq.enterprise.server.sync.validators.ConsistencyValidator;
+import org.rhq.enterprise.server.sync.validators.EntityValidator;
import org.rhq.test.JMockTest;
/**
@@ -140,7 +141,13 @@ public class ExportingInputStreamTest extends JMockTest {
}
@Override
- public void finishImport() throws Exception {
+ public String finishImport() throws Exception {
+ return null;
+ }
+
+ @Override
+ public Set<EntityValidator<T>> getEntityValidators() {
+ return Collections.emptySet();
}
}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MaxCountValidatorTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MaxCountValidatorTest.java
new file mode 100644
index 0000000..b18662b
--- /dev/null
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MaxCountValidatorTest.java
@@ -0,0 +1,52 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 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.server.sync.test;
+
+import static org.testng.Assert.fail;
+
+import org.testng.annotations.Test;
+
+import org.rhq.enterprise.server.sync.ValidationException;
+import org.rhq.enterprise.server.sync.validators.MaxCountValidator;
+
+/**
+ *
+ *
+ * @author Lukas Krejci
+ */
+@Test
+public class MaxCountValidatorTest {
+
+ public void testThrowsValidationExceptionAfterMaxEntitiesValidated() {
+ MaxCountValidator<String> validator = new MaxCountValidator<String>(3);
+
+ validator.initialize(null, null);
+
+ validator.validateExportedEntity("1");
+ validator.validateExportedEntity("2");
+ validator.validateExportedEntity("3");
+ try {
+ validator.validateExportedEntity("4");
+ fail("The max count validator shouldn't have accepted the 4th entry.");
+ } catch (ValidationException e) {
+ //expected
+ }
+ }
+}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateExporterTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateExporterTest.java
index 34de39e..6987001 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateExporterTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateExporterTest.java
@@ -22,13 +22,10 @@ package org.rhq.enterprise.server.sync.test;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
-import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -49,7 +46,6 @@ import org.w3c.dom.NodeList;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.criteria.MeasurementDefinitionCriteria;
import org.rhq.core.domain.measurement.MeasurementDefinition;
-import org.rhq.core.domain.plugin.Plugin;
import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.sync.ExporterMessages;
@@ -57,7 +53,6 @@ import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.measurement.MeasurementDefinitionManagerLocal;
import org.rhq.enterprise.server.measurement.MeasurementScheduleManagerLocal;
-import org.rhq.enterprise.server.resource.metadata.PluginManagerLocal;
import org.rhq.enterprise.server.sync.ExportingInputStream;
import org.rhq.enterprise.server.sync.MetricTemplateSynchronizer;
import org.rhq.enterprise.server.sync.SynchronizationConstants;
@@ -77,19 +72,15 @@ public class MetricTemplateExporterTest extends JMockTest {
public void testCanExport() throws Exception {
final MeasurementDefinitionManagerLocal measurementDefinitionManager = context.mock(MeasurementDefinitionManagerLocal.class);
- final PluginManagerLocal pluginManager = context.mock(PluginManagerLocal.class);
final MeasurementScheduleManagerLocal measurementScheduleManager = context.mock(MeasurementScheduleManagerLocal.class);
context.checking(new Expectations() {
{
allowing(measurementDefinitionManager).findMeasurementDefinitionsByCriteria(with(any(Subject.class)), with(any(MeasurementDefinitionCriteria.class)));
will(returnValue(getFakeMeasurementDefinitions()));
-
- allowing(pluginManager).getInstalledPlugins();
- will(returnValue(getFakeInstalledPlugins()));
}
});
- MetricTemplateSynchronizer exporter = new MetricTemplateSynchronizer(measurementDefinitionManager, measurementScheduleManager, pluginManager);
+ MetricTemplateSynchronizer exporter = new MetricTemplateSynchronizer(measurementDefinitionManager, measurementScheduleManager);
Set<Synchronizer<?, ?>> exporters = new HashSet<Synchronizer<?, ?>>();
exporters.add(exporter);
@@ -227,10 +218,4 @@ public class MetricTemplateExporterTest extends JMockTest {
return new PageList<MeasurementDefinition>(ret, PageControl.getUnlimitedInstance());
}
-
- private static List<Plugin> getFakeInstalledPlugins() {
- Plugin p = new Plugin("fakePlugin", null, "12345");
- p.setVersion("1.0.0.test");
- return Collections.singletonList(p);
- }
}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateImporterTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateImporterTest.java
index 7b50340..8c615b4 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateImporterTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateImporterTest.java
@@ -21,6 +21,7 @@ package org.rhq.enterprise.server.sync.test;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertSame;
+import static org.testng.Assert.assertEquals;
import java.util.Arrays;
import java.util.Collections;
@@ -98,7 +99,6 @@ public class MetricTemplateImporterTest extends JMockTest {
private static final ResourceType FAKE_RESOURCE_TYPE = new ResourceType("fake", "fake", ResourceCategory.PLATFORM,
null);
- @SuppressWarnings("unchecked")
public void testNonMatchingMeasurementDefinitionsAreIgnored() {
final TestPrerequisities prereqs = new TestPrerequisities(context);
@@ -156,7 +156,6 @@ public class MetricTemplateImporterTest extends JMockTest {
importer.finishImport();
}
- @SuppressWarnings("unchecked")
public void testCanUpdateEnablements() {
MeasurementDefinition defToEnable = new MeasurementDefinition(FAKE_RESOURCE_TYPE, "enabled");
MeasurementDefinition defToDisable = new MeasurementDefinition(FAKE_RESOURCE_TYPE, "disable");
@@ -210,7 +209,6 @@ public class MetricTemplateImporterTest extends JMockTest {
}
- @SuppressWarnings("unchecked")
public void testCanUpdateSchedules() {
MeasurementDefinition def = new MeasurementDefinition(FAKE_RESOURCE_TYPE, "def");
def.setId(1);
@@ -253,7 +251,6 @@ public class MetricTemplateImporterTest extends JMockTest {
importer.finishImport();
}
- @SuppressWarnings("unchecked")
public void testPerMetricUpdateScheduleOverrides() {
MeasurementDefinition updatedDef = new MeasurementDefinition(FAKE_RESOURCE_TYPE, "def");
updatedDef.setId(1);
@@ -325,7 +322,6 @@ public class MetricTemplateImporterTest extends JMockTest {
testNonMatchingMeasurementDefinitionsAreIgnored();
}
- @SuppressWarnings("unchecked")
public void testDistinguishingBetweenNormalAndPerMinuteTemplates() {
MeasurementDefinition normalDef = new MeasurementDefinition(FAKE_RESOURCE_TYPE, "def");
MeasurementDefinition perMinuteDef = new MeasurementDefinition(FAKE_RESOURCE_TYPE, "def");
@@ -377,4 +373,40 @@ public class MetricTemplateImporterTest extends JMockTest {
//correctly by the importer.
importer.finishImport();
}
+
+ public void testNotifiesAboutIgnoredMetricTemplates() throws Exception {
+ final TestPrerequisities prereqs = new TestPrerequisities(context);
+ prereqs.setMeasurementDefinitions(Collections.<MeasurementDefinition>emptyList());
+
+ context.checking(new Expectations() {
+ {
+ prereqs.addExpectations(this);
+ }
+ });
+
+ MetricTemplateImporter importer =
+ new MetricTemplateImporter(null, prereqs.getEntityManager(), prereqs.getMeasurementScheduleManager());
+
+ importer.configure(null);
+
+ importer.configure(null);
+
+ MetricTemplate unmatched = new MetricTemplate();
+ unmatched.setMetricName("made-up");
+ unmatched.setResourceTypeName("made-up");
+ unmatched.setResourceTypePlugin("made-up");
+
+ ExportedEntityMatcher<MeasurementDefinition, MetricTemplate> matcher = importer.getExportedEntityMatcher();
+
+ assertNull(matcher.findMatch(unmatched));
+
+ importer.update(null, unmatched);
+
+ String notes = importer.finishImport();
+
+ String expectedNotes =
+ MetricTemplateImporter.getUnmatchedMetricTemplatesReport(Collections.singleton(unmatched));
+
+ assertEquals(notes, expectedNotes);
+ }
}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateValidatorTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateValidatorTest.java
deleted file mode 100644
index 3afe29f..0000000
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateValidatorTest.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2011 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.server.sync.test;
-
-import static org.testng.Assert.*;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
-
-import org.jmock.Expectations;
-import org.testng.annotations.Test;
-
-import org.rhq.core.domain.measurement.MeasurementDefinition;
-import org.rhq.core.domain.measurement.NumericType;
-import org.rhq.core.domain.resource.ResourceCategory;
-import org.rhq.core.domain.resource.ResourceType;
-import org.rhq.core.domain.sync.entity.MetricTemplate;
-import org.rhq.enterprise.server.sync.ValidationException;
-import org.rhq.enterprise.server.sync.validators.MetricTemplateValidator;
-import org.rhq.test.JMockTest;
-
-/**
- *
- *
- * @author Lukas Krejci
- */
-@Test
-public class MetricTemplateValidatorTest extends JMockTest {
-
- private static final ResourceType FAKE_RESOURCE_TYPE = new ResourceType("fake", "fake", ResourceCategory.PLATFORM, null);
-
- public void testAllValidatorsEqual() {
- MetricTemplateValidator v1 = new MetricTemplateValidator();
- MetricTemplateValidator v2 = new MetricTemplateValidator();
- MetricTemplateValidator v3 = new MetricTemplateValidator();
-
- assertEquals(v1, v2);
- assertEquals(v2, v3);
- assertEquals(v1, v3);
- }
-
- public void testDetectsUnknownTemplates() throws Exception {
- final EntityManager entityManager = context.mock(EntityManager.class);
- final Query q = context.mock(Query.class);
-
- final List<MeasurementDefinition> allDefs = new ArrayList<MeasurementDefinition>();
-
- context.checking(new Expectations() {
- {
- //make the entity manager return the test data
- allowing(entityManager).createQuery(with(any(String.class)));
- will(returnValue(q));
-
- allowing(q).getResultList();
- will(returnValue(allDefs));
- }
- });
-
- //add some test data
- allDefs.add(createMeasurementDefinition("m1", false));
- allDefs.add(createMeasurementDefinition("m1", true));
- allDefs.add(createMeasurementDefinition("m2", false));
- allDefs.add(createMeasurementDefinition("m3", false));
-
- MetricTemplateValidator validator = new MetricTemplateValidator();
-
- validator.initialize(null, entityManager);
- validator.initializeExportedStateValidation(null);
-
- //check that all the defined measurement defs pass
- for(MeasurementDefinition md : allDefs) {
- validator.validateExportedEntity(new MetricTemplate(md));
- }
-
- //now let's create an "unknown" metric template
- MetricTemplate unknown = new MetricTemplate();
- unknown.setMetricName("unknown");
- unknown.setResourceTypeName("some");
- unknown.setResourceTypePlugin("other");
-
- try {
- validator.validateExportedEntity(unknown);
- fail("Validating a metric template " + unknown + " should have failed.");
- } catch (ValidationException e) {
- //expected
- }
- }
-
- public void testDetectsDuplicitEntries() throws Exception {
- final EntityManager entityManager = context.mock(EntityManager.class);
- final Query q = context.mock(Query.class);
-
- final List<MeasurementDefinition> allDefs = new ArrayList<MeasurementDefinition>();
-
- context.checking(new Expectations() {
- {
- //make the entity manager return the test data
- allowing(entityManager).createQuery(with(any(String.class)));
- will(returnValue(q));
-
- allowing(q).getResultList();
- will(returnValue(allDefs));
- }
- });
-
- //add some test data
- allDefs.add(createMeasurementDefinition("m1", false));
- allDefs.add(createMeasurementDefinition("m1", true));
- allDefs.add(createMeasurementDefinition("m2", false));
- allDefs.add(createMeasurementDefinition("m3", false));
-
- MetricTemplateValidator validator = new MetricTemplateValidator();
-
- validator.initialize(null, entityManager);
- validator.initializeExportedStateValidation(null);
-
- //check that all the defined measurement defs pass
- for(MeasurementDefinition md : allDefs) {
- validator.validateExportedEntity(new MetricTemplate(md));
- }
-
- //now let's try and validate the first test data again.
- //this simulates the duplicate entries in the export file
- try {
- MetricTemplate duplicate = new MetricTemplate(allDefs.get(0));
- validator.validateExportedEntity(duplicate);
- fail("Validating a duplicate metric template " + duplicate + " should have failed.");
- } catch (ValidationException e) {
- //expected
- }
- }
-
- private static MeasurementDefinition createMeasurementDefinition(String name, boolean perMinute) {
- MeasurementDefinition ret = new MeasurementDefinition(FAKE_RESOURCE_TYPE, name);
- if (perMinute) {
- ret.setRawNumericType(NumericType.TRENDSUP);
- }
-
- return ret;
- }
-}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SynchronizationManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SynchronizationManagerBeanTest.java
index c5a0b2e..41f9a56 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SynchronizationManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SynchronizationManagerBeanTest.java
@@ -27,7 +27,9 @@ import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
@@ -37,6 +39,8 @@ import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import javax.persistence.EntityManager;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.stream.XMLStreamException;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
@@ -56,6 +60,8 @@ import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.domain.criteria.MeasurementDefinitionCriteria;
import org.rhq.core.domain.criteria.ResourceCriteria;
import org.rhq.core.domain.measurement.DataType;
@@ -76,10 +82,22 @@ import org.rhq.enterprise.server.authz.PermissionException;
import org.rhq.enterprise.server.measurement.MeasurementDefinitionManagerLocal;
import org.rhq.enterprise.server.measurement.MeasurementScheduleManagerLocal;
import org.rhq.enterprise.server.resource.ResourceManagerLocal;
+import org.rhq.enterprise.server.sync.ExportReader;
+import org.rhq.enterprise.server.sync.ExportWriter;
import org.rhq.enterprise.server.sync.MetricTemplateSynchronizer;
+import org.rhq.enterprise.server.sync.NoSingleEntity;
import org.rhq.enterprise.server.sync.SynchronizationConstants;
import org.rhq.enterprise.server.sync.SynchronizationManagerLocal;
+import org.rhq.enterprise.server.sync.Synchronizer;
+import org.rhq.enterprise.server.sync.SynchronizerFactory;
import org.rhq.enterprise.server.sync.SystemSettingsSynchronizer;
+import org.rhq.enterprise.server.sync.ValidationException;
+import org.rhq.enterprise.server.sync.exporters.Exporter;
+import org.rhq.enterprise.server.sync.exporters.ExportingIterator;
+import org.rhq.enterprise.server.sync.importers.ExportedEntityMatcher;
+import org.rhq.enterprise.server.sync.importers.Importer;
+import org.rhq.enterprise.server.sync.validators.ConsistencyValidator;
+import org.rhq.enterprise.server.sync.validators.EntityValidator;
import org.rhq.enterprise.server.system.SystemManagerLocal;
import org.rhq.enterprise.server.test.AbstractEJB3Test;
import org.rhq.enterprise.server.test.TestServerPluginService;
@@ -108,12 +126,142 @@ public class SynchronizationManagerBeanTest extends AbstractEJB3Test {
public TestServerPluginService testServerPluginService;
}
+ //this can't be mocked out because the config sync machinery has to be able to
+ //instantiate this class
+ public static class ImportConfigurationCheckingSynchronizer implements Synchronizer<NoSingleEntity, String> {
+
+ public static boolean importerConfigured;
+ public static boolean importValidatorsObtainedAfterConfiguration;
+
+ public static void reset() {
+ importerConfigured = false;
+ importValidatorsObtainedAfterConfiguration = false;
+ }
+
+ @Override
+ public void initialize(Subject subject, EntityManager entityManager) {
+ }
+
+ @Override
+ public Exporter<NoSingleEntity, String> getExporter() {
+ return new Exporter<NoSingleEntity, String>() {
+
+ @Override
+ public ExportingIterator<String> getExportingIterator() {
+ return new ExportingIterator<String>() {
+ boolean ran = false;
+
+ @Override
+ public boolean hasNext() {
+ if (ran) {
+ return false;
+ }
+
+ ran = true;
+ return true;
+ }
+
+ @Override
+ public String next() {
+ return null;
+ }
+
+ @Override
+ public void remove() {
+ }
+
+ @Override
+ public void export(ExportWriter output) throws XMLStreamException {
+ output.writeStartElement("my-entity");
+ output.writeCharacters("value");
+ output.writeEndElement();
+ }
+
+ @Override
+ public String getNotes() {
+ return null;
+ }
+
+ };
+ }
+
+ @Override
+ public String getNotes() {
+ return null;
+ }
+
+ };
+ }
+
+ @Override
+ public Importer<NoSingleEntity, String> getImporter() {
+ return new Importer<NoSingleEntity, String>() {
+
+ @Override
+ public ConfigurationDefinition getImportConfigurationDefinition() {
+ return new ConfigurationDefinition("fake", null);
+ }
+
+ @Override
+ public void configure(Configuration importConfiguration) {
+ importerConfigured = true;
+ }
+
+ @Override
+ public ExportedEntityMatcher<NoSingleEntity, String> getExportedEntityMatcher() {
+ return null;
+ }
+
+ @Override
+ public Set<EntityValidator<String>> getEntityValidators() {
+ EntityValidator<String> v = new EntityValidator<String>() {
+
+ @Override
+ public void validateExportedEntity(String entity) throws ValidationException {
+ }
+
+ @Override
+ public void initialize(Subject subject, EntityManager entityManager) {
+ }
+ };
+
+ if (importerConfigured) {
+ importValidatorsObtainedAfterConfiguration = true;
+ }
+
+ return Collections.singleton(v);
+ }
+
+ @Override
+ public void update(NoSingleEntity entity, String exportedEntity) throws Exception {
+ }
+
+ @Override
+ public String unmarshallExportedEntity(ExportReader reader) throws XMLStreamException {
+ return reader.getElementText();
+ }
+
+ @Override
+ public String finishImport() throws Exception {
+ return null;
+ }
+
+ };
+ }
+
+ @Override
+ public Set<ConsistencyValidator> getRequiredValidators() {
+ return Collections.emptySet();
+ }
+
+ }
+
private TestData testData;
//I just don't get why this can't be a @BeforeTest
//but when it was declared as such (together with tearDown() being an @AfterTest)
//no tests would work. I have no idea why...
- private void setup() throws Exception {
+ private void setup(boolean createExport) throws Exception {
testData = new TestData();
getTransactionManager().begin();
try {
@@ -154,7 +302,7 @@ public class SynchronizationManagerBeanTest extends AbstractEJB3Test {
testData.testServerPluginService = new TestServerPluginService();
prepareCustomServerPluginService(testData.testServerPluginService);
testData.testServerPluginService.startMasterPluginContainer();
-
+
synchronizationManager = LookupUtil.getSynchronizationManager();
SystemManagerLocal systemManager = LookupUtil.getSystemManager();
@@ -162,7 +310,10 @@ public class SynchronizationManagerBeanTest extends AbstractEJB3Test {
systemManager.loadSystemConfigurationCache();
testData.systemSettings = systemManager.getSystemConfiguration(freshUser());
- export = synchronizationManager.exportAllSubsystems(freshUser());
+
+ if (createExport) {
+ export = synchronizationManager.exportAllSubsystems(freshUser());
+ }
}
private void tearDown() throws Exception {
@@ -183,7 +334,7 @@ public class SynchronizationManagerBeanTest extends AbstractEJB3Test {
em.remove(attachedType);
em.flush();
-
+
getTransactionManager().commit();
} catch (Exception e) {
getTransactionManager().rollback();
@@ -192,14 +343,14 @@ public class SynchronizationManagerBeanTest extends AbstractEJB3Test {
unprepareServerPluginService();
testData.testServerPluginService.stopMasterPluginContainer();
-
+
export = null;
testData = null;
synchronizationManager = null;
}
public void testExport() throws Exception {
- setup();
+ setup(true);
try {
assertNull("Export shouldn't generate an error message.", export.getErrorMessage());
assertTrue("The export should contain some data.", export.getExportFile().length > 0);
@@ -209,7 +360,7 @@ public class SynchronizationManagerBeanTest extends AbstractEJB3Test {
}
public void testImportWithDefaultConfiguration() throws Exception {
- setup();
+ setup(true);
try {
SystemManagerLocal systemManager = LookupUtil.getSystemManager();
@@ -247,7 +398,7 @@ public class SynchronizationManagerBeanTest extends AbstractEJB3Test {
}
public void testImportWithRedefinedConfigurationInExportFile() throws Exception {
- setup();
+ setup(true);
try {
String exportXML = getExportData();
@@ -255,15 +406,7 @@ public class SynchronizationManagerBeanTest extends AbstractEJB3Test {
exportXML = updateSystemSettingsImportConfiguration(exportXML);
exportXML = updateMetricTemplatesImportConfiguration(exportXML);
- ByteArrayOutputStream compressed = new ByteArrayOutputStream();
- OutputStreamWriter wrt = new OutputStreamWriter(new GZIPOutputStream(compressed), "UTF-8");
- try {
- wrt.write(exportXML);
- } finally {
- wrt.close();
- }
-
- InputStream exportData = new ByteArrayInputStream(compressed.toByteArray());
+ InputStream exportData = createCompressedStream(exportXML);
try {
synchronizationManager.importAllSubsystems(freshUser(), exportData, null);
@@ -317,7 +460,7 @@ public class SynchronizationManagerBeanTest extends AbstractEJB3Test {
}
public void testManuallyPassedImportConfigurationHasPrecendenceOverTheInlinedOne() throws Exception {
- setup();
+ setup(true);
try {
//let's read the original values from the database, so that we know what to compare against
@@ -342,15 +485,7 @@ public class SynchronizationManagerBeanTest extends AbstractEJB3Test {
exportXML = updateSystemSettingsImportConfiguration(exportXML);
exportXML = updateMetricTemplatesImportConfiguration(exportXML);
- ByteArrayOutputStream compressed = new ByteArrayOutputStream();
- OutputStreamWriter wrt = new OutputStreamWriter(new GZIPOutputStream(compressed), "UTF-8");
- try {
- wrt.write(exportXML);
- } finally {
- wrt.close();
- }
-
- InputStream exportData = new ByteArrayInputStream(compressed.toByteArray());
+ InputStream exportData = createCompressedStream(exportXML);
//let's just use the default configs so that we don't apply the changes suggested in
//the changed default configs created above
@@ -408,6 +543,58 @@ public class SynchronizationManagerBeanTest extends AbstractEJB3Test {
}
}
+ public void testUnknownValidatorsAreIgnored() throws Exception {
+ setup(true);
+
+ try {
+ String export = getExportData();
+
+ Document xml =
+ DocumentBuilderFactory.newInstance().newDocumentBuilder()
+ .parse(new InputSource(new StringReader(export)));
+
+ Element unknownValidator = xml.createElement("validator");
+ unknownValidator.setAttribute(SynchronizationConstants.CLASS_ATTRIBUTE, "org.nothing.UnknownValidator");
+
+ xml.getDocumentElement().insertBefore(unknownValidator, xml.getDocumentElement().getFirstChild());
+
+ export = documentToString(xml);
+
+ InputStream exportStream = createCompressedStream(export);
+
+ synchronizationManager.importAllSubsystems(freshUser(), exportStream, null);
+ } finally {
+ tearDown();
+ }
+ }
+
+ public void testImporterConfiguredBeforeValidatorsObtained() throws Exception {
+ setup(false);
+
+ try {
+ ImportConfigurationCheckingSynchronizer.reset();
+
+ synchronizationManager.setSynchronizerFactory(new SynchronizerFactory() {
+ @Override
+ public Set<Synchronizer<?, ?>> getAllSynchronizers() {
+ return Collections.<Synchronizer<?, ?>>singleton(new ImportConfigurationCheckingSynchronizer());
+ }
+ });
+
+ export = synchronizationManager.exportAllSubsystems(freshUser());
+
+ //and import it back again, so that we actually invoke the import validation
+ synchronizationManager.importAllSubsystems(freshUser(), export.getExportFile(), null);
+
+ assertTrue(ImportConfigurationCheckingSynchronizer.importerConfigured);
+ assertTrue(ImportConfigurationCheckingSynchronizer.importValidatorsObtainedAfterConfiguration);
+ } finally {
+ //reset the factory so that other tests work w/ the default syncers
+ synchronizationManager.setSynchronizerFactory(new SynchronizerFactory());
+ tearDown();
+ }
+ }
+
private String getExportData() throws IOException {
InputStreamReader str =
new InputStreamReader(new GZIPInputStream(new ByteArrayInputStream(export.getExportFile())), "UTF-8");
@@ -543,4 +730,16 @@ public class SynchronizationManagerBeanTest extends AbstractEJB3Test {
user = subjectManager.getOverlord();
return user;
}
+
+ private InputStream createCompressedStream(String exportData) throws UnsupportedEncodingException, IOException {
+ ByteArrayOutputStream compressed = new ByteArrayOutputStream();
+ OutputStreamWriter wrt = new OutputStreamWriter(new GZIPOutputStream(compressed), "UTF-8");
+ try {
+ wrt.write(exportData);
+ } finally {
+ wrt.close();
+ }
+
+ return new ByteArrayInputStream(compressed.toByteArray());
+ }
}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SystemSettingsImporterTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SystemSettingsImporterTest.java
index 5b94450..711fb75 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SystemSettingsImporterTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SystemSettingsImporterTest.java
@@ -20,7 +20,6 @@
package org.rhq.enterprise.server.sync.test;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Properties;
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SystemSettingsValidatorTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SystemSettingsValidatorTest.java
index c00cb07..0966080 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SystemSettingsValidatorTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SystemSettingsValidatorTest.java
@@ -19,9 +19,6 @@
package org.rhq.enterprise.server.sync.test;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-
import java.util.Properties;
import org.jmock.Expectations;
@@ -58,22 +55,5 @@ public class SystemSettingsValidatorTest extends JMockTest {
});
validator.validateExportedEntity(importedSettings);
- }
-
- public void testAllValidatorsAreEqual() {
- SystemManagerLocal systemManager = context.mock(SystemManagerLocal.class);
-
- SystemSettingsValidator v1 = new SystemSettingsValidator(systemManager);
- SystemSettingsValidator v2 = new SystemSettingsValidator(systemManager);
- SystemSettingsValidator v3 = new SystemSettingsValidator(systemManager);
- Object o = new Object();
-
- assertEquals(v1, v2);
- assertEquals(v1, v3);
- assertEquals(v2, v3);
-
- assertFalse(v1.equals(o));
- assertFalse(v2.equals(o));
- assertFalse(v3.equals(o));
- }
+ }
}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/UniquenessValidatorTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/UniquenessValidatorTest.java
new file mode 100644
index 0000000..33a0207
--- /dev/null
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/UniquenessValidatorTest.java
@@ -0,0 +1,51 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 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.server.sync.test;
+
+import static org.testng.Assert.fail;
+
+import org.testng.annotations.Test;
+
+import org.rhq.enterprise.server.sync.ValidationException;
+import org.rhq.enterprise.server.sync.validators.UniquenessValidator;
+
+/**
+ *
+ *
+ * @author Lukas Krejci
+ */
+@Test
+public class UniquenessValidatorTest {
+
+ public void testDetectsDuplicitEntries() throws Exception {
+ UniquenessValidator<String> validator = new UniquenessValidator<String>();
+
+ validator.initialize(null, null);
+
+ validator.validateExportedEntity("1");
+ validator.validateExportedEntity("2");
+ try {
+ validator.validateExportedEntity("1");
+ fail("Uniqueness validator should have detected a duplicate entry.");
+ } catch (ValidationException e) {
+ //expected
+ }
+ }
+}
12 years, 7 months
[rhq] 2 commits - modules/core modules/enterprise pom.xml
by Heiko W. Rupp
modules/core/domain/pom.xml | 9 -
modules/core/gui/pom.xml | 11 --
modules/enterprise/gui/coregui/pom.xml | 9 -
modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties | 52 +++++-----
pom.xml | 11 ++
5 files changed, 41 insertions(+), 51 deletions(-)
New commits:
commit 9c1b74690daba959f513d895474a00155d296fb6
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Mon Nov 7 10:25:39 2011 +0100
Add the deprecated-repo of the nexus to the root pom, as this is needed in many places when the old repo.j.org/maven2 repo is not available.
diff --git a/modules/core/domain/pom.xml b/modules/core/domain/pom.xml
index 1ebf5b0..164f5ad 100644
--- a/modules/core/domain/pom.xml
+++ b/modules/core/domain/pom.xml
@@ -527,15 +527,6 @@
</snapshots>
</repository>
- <repository>
- <id>jboss-deprecated-items-group</id>
- <name>JBoss Public Repository Group</name>
- <url>https://repository.jboss.org/nexus/content/repositories/deprecated/</url>
- <snapshots>
- <enabled>false</enabled>
- </snapshots>
- </repository>
-
</repositories>
</project>
diff --git a/modules/core/gui/pom.xml b/modules/core/gui/pom.xml
index 72b7bf8..1d1572a 100644
--- a/modules/core/gui/pom.xml
+++ b/modules/core/gui/pom.xml
@@ -206,15 +206,4 @@
</profiles>
- <repositories>
- <repository>
- <id>jboss-deprecated-items-group</id>
- <name>JBoss Public Repository Group</name>
- <url>https://repository.jboss.org/nexus/content/repositories/deprecated/</url>
- <snapshots>
- <enabled>false</enabled>
- </snapshots>
- </repository>
- </repositories>
-
</project>
diff --git a/modules/enterprise/gui/coregui/pom.xml b/modules/enterprise/gui/coregui/pom.xml
index b8a1f59..9e4e8c4 100644
--- a/modules/enterprise/gui/coregui/pom.xml
+++ b/modules/enterprise/gui/coregui/pom.xml
@@ -517,15 +517,6 @@
</snapshots>
</repository>
- <repository>
- <id>jboss-deprecated-items-group</id>
- <name>JBoss Public Repository Group</name>
- <url>https://repository.jboss.org/nexus/content/repositories/deprecated/</url>
- <snapshots>
- <enabled>false</enabled>
- </snapshots>
- </repository>
-
</repositories>
</project>
diff --git a/pom.xml b/pom.xml
index c5dd88b..1a37703 100644
--- a/pom.xml
+++ b/pom.xml
@@ -968,6 +968,17 @@
</snapshots>
</repository>
+ <!-- jboss-deprecated-repo above is only available inside Red Hat, so we need this as fallback: -->
+ <repository>
+ <id>jboss-deprecated-items-group</id>
+ <name>JBoss Public Repository Group</name>
+ <url>https://repository.jboss.org/nexus/content/repositories/deprecated/</url>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </repository>
+
+
</repositories>
<pluginRepositories>
commit 836f255c91f16e8b7102b8683a4ee4d4074141fa
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Fri Nov 4 17:04:33 2011 +0100
Add some more translations.
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties
index be8be01..79b0b31 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties
@@ -181,7 +181,7 @@ common_title_port = Port
common_title_recent_alerts = Kürzlich ausgelöste Alarme
common_title_recent_bundle_deployments = Kürzliche Bundle-Deployments
common_title_recent_configuration_updates = Frische Konfigurationsaktualisierungen
-##common_title_recent_drifts = Recent Drift
+common_title_recent_drifts = Kürzlich aufgetretener Drift
common_title_recent_event_counts = Anzahl frischer Ereignisse
common_title_recent_measurements = Frische Messwerte
common_title_recent_oob_metrics = Kürzlich aus dem Ruder gelaufene Metriken
@@ -369,7 +369,7 @@ util_rpcManager_activeRequests = {0} Aktive Anfragen
util_userSession_loadFailSubject = UserSessionManager: Konnte das 'Subject' des Benutzers nicht laden.
util_userSession_logoutFail = Ausloggen fehlgeschlagen
util_widgetsField_unlimited = Unbeschränkt
-##view_aboutBox_allRightsReserved = All Rights Reserved.
+view_aboutBox_allRightsReserved = Alle Rechte vorbehalten
view_aboutBox_buildNumber = Build-Nummer:
view_aboutBox_failedToLoad = Kann die Produktinformation nicht laden
view_aboutBox_homepage = Homepage
@@ -386,8 +386,8 @@ view_adminConfig_systemSettings = Systemeinstellungen
view_adminRoles_assignedGroups = Zugewiesene Ressourcen-Gruppen
view_adminRoles_assignedSubjects = Zugewisene Benutzer
view_adminRoles_failLdap = Konnte nicht ermitteln, ob LDAP konfiguriert ist - gehe von keiner LDAP-Konfiguration aus.
-##view_adminRoles_failLdapGroups = Failed to retrieve available LDAP groups - assuming no LDAP groups.
-##view_adminRoles_failLdapGroupsRole = Failed to load LDAP groups available for role.
+view_adminRoles_failLdapGroups = Konnte de LDAP-Gruppen nicht laden. Annahme ist, dass es keine gibt.
+view_adminRoles_failLdapGroupsRole = Konnte die LDAP-Gruppen für die Rolle nicht laden.
view_adminRoles_failRoles = Konnte die Rollen nicht laden.
view_adminRoles_globalPerms = Applikationsweite Rechte
view_adminRoles_ldapGroups = LDAP-Gruppen
@@ -452,8 +452,8 @@ view_adminTemplates_enabledTemplates = Aktive Vorlagen
view_adminTemplates_platforms = Platformen
view_adminTemplates_pluginTemplates = Vorlagen für Plugins Plugins
view_adminTemplates_servers = Server
-##view_adminTemplates_userTemplates = User Templates
-##view_adminTopology_affinityGroups = Affinity Groups
+view_adminTemplates_userTemplates = Nutzers-spezifische Vorlagen
+view_adminTopology_affinityGroups = Affinitätsgruppen
view_adminTopology_agents = Agenten
view_adminTopology_partitionEvents = Partitionierungs-Ereignisse
view_adminTopology_remoteAgentInstall = Installation entfernter Agenten
@@ -484,7 +484,7 @@ view_admin_landing = In dieser Sektion können die globalen Einstellungen für R
##view_admin_plugins_enabledAgentPluginsFailure = Failed to enable agent plugins.
##view_admin_plugins_enabledServerPlugins = Enabled server plugins: {0}
##view_admin_plugins_enabledServerPluginsFailure = Failed to enable server plugins.
-##view_admin_plugins_hideDeleted = Hide Deleted
+view_admin_plugins_hideDeleted = Gelöschte verbergen
##view_admin_plugins_hideUndeployed = Hide Undeployed
##view_admin_plugins_loadFailure = Failed to load plugin data
##view_admin_plugins_purgedAgentPlugins = Preparing to purge agent plugins {0}. This may take a few minutes since all type definitions from the plugins must first be purged from the system. The plugins will still be visible on this page until they have been purged. Please note that you must not re-install the plugin while the purge is running, otherwise failures will occur. Therefore, please wait before attempting to re-install the plugin into the system until this purge is complete.
@@ -508,12 +508,12 @@ view_admin_plugins_server = Server
##view_admin_plugins_serverControls_clickForError = Click for the error message
##view_admin_plugins_serverControls_invokeFailure = Failed to invoke the control
##view_admin_plugins_serverControls_name = Control
-##view_admin_plugins_serverControls_parameters = Parameters
-##view_admin_plugins_serverControls_results = Results
+view_admin_plugins_serverControls_parameters = Parameter
+view_admin_plugins_serverControls_results = Ergebnisse
##view_admin_plugins_serverDisableConfirm = <b>Warning!</b><br/>\nThe following server plugins are about to be disabled:<br/>\n{0}<br/>\nAre you sure you want to disable these?
##view_admin_plugins_serverScheduleJobs = Scheduled Jobs
##view_admin_plugins_serverUndeployConfirm = <b>Warning!</b><br/>\nThe following server plugins are about to be undeployed:<br/>\n{0}<br/>\nAre you sure you want to undeploy these?
-##view_admin_plugins_showDeleted = Show Deleted
+view_admin_plugins_showDeleted = Gelöschte anzeigen
##view_admin_plugins_showUndeployed = Show Undeployed
##view_admin_plugins_undeploy = Undeploy
##view_admin_plugins_undeployedServerPlugins = Undeployed server plugins: {0}
@@ -1246,11 +1246,11 @@ view_inventory_summary_agent_last_title = Zeitpunkt des letzten Verfügbarkeitsb
view_inventory_summary_agent_status_title = Status der Kommunikation mit dem Agent
view_inventory_summary_agent_title = Agent, der diese Ressource managt
view_inventory_unavailableServers = Nichtverfügbare Server
-##view_leftNav_unknownPage = Unknown page name [{0}] for section [{1}] - URL is invalid.
+view_leftNav_unknownPage = Unbekannter Seitenname [{0}] für Abschnitt [{1}] - die URL ist ungültig.
view_login_invalidEmail = Ungültige E-Mail-Adresse
view_login_login = Einloggen
view_login_logout = Auslogen
-##view_login_noBackend = The backend datasource is unavailable.
+view_login_noBackend = Die Datenbank ist nicht verfügbar
##view_login_noLdap = Note: Optional retrieval of ldap details unsuccessful. Manual entry is required.
##view_login_noUser = The username or password provided does not match our records.
view_login_prompt = Bitte loggen Sie sich ein
@@ -1328,7 +1328,7 @@ view_operationCreateWizard_schedulingStep_name = Zeitplan
view_operationCreateWizard_title = Operationen-Assistent
view_operationHistoryDetails_dateCompleted = Erledigungszeitpunkt
view_operationHistoryDetails_dateSubmitted = Absendezeitpunkt
-##view_operationHistoryDetails_error_fetchFailure = Failure loading operation history.
+view_operationHistoryDetails_error_fetchFailure = Konnte den Verlauf der Operationen nicht laden
view_operationHistoryDetails_noResults = Diese Operation liefert keine Ergebnisse zurück.
view_operationHistoryDetails_operation = Operation
view_operationHistoryDetails_parameters = Parameter
@@ -1345,6 +1345,14 @@ view_operationScheduleDetails_noParameters = Diese Operation benötigt keine Par
##view_portlet_autodiscovery_config_platform_selection = Number of platforms to display
##view_portlet_autodiscovery_help_msg = This portlet offers the ability to import newly discovered resources into the inventory for monitoring and management or to ignore them from further action.
view_portlet_autodiscovery_title = Discovery-Warteschlange
+view_portlet_defaultName_inventorySummary=Inventarübersicht
+## view_portlet_defaultName_mashup = Mashup
+view_portlet_defaultName_message = Nachricht
+view_portlet_defaultName_operations = Kürzlich ausgeführte Operationen
+view_portlet_defaultName_platformSummary = Platformauslastung
+view_portlet_defaultName_problemResources = Nicht verfügbare Resourcen oder mit Alarmen
+view_portlet_defaultName_recentAlerts = Kürzlich ausgelöste Alarme
+view_portlet_defaultName_recentlyAddedResources = Zuletzt hinzugefügte Ressourcen
view_portlet_favoriteResources_msg = Dieses Potlet zeigt Ihre gemerkten Ressourcen
view_portlet_favoriteResources_title = Gemerkete Resourcen
view_portlet_generic_help = Für dieses Portlet liegt keine Hilfe vor
@@ -1416,8 +1424,8 @@ view_remoteAgentInstall_error_4 = Konnte den Agent nicht installieren
view_remoteAgentInstall_error_5 = Konnte den Agent nicht starten
view_remoteAgentInstall_error_6 = Konnte den Agent nicht stoppen
view_remoteAgentInstall_installAgent = Agent installieren
-##view_remoteAgentInstall_installInfo = Agent Installation Information
-##view_remoteAgentInstall_installPath = Agent Install Path
+view_remoteAgentInstall_installInfo = Informationen zur Agent-Installation
+view_remoteAgentInstall_installPath = Pfad der Agent-Installation
view_remoteAgentInstall_owner = Eigentümer
##view_remoteAgentInstall_promptHost = The host where the agent is or will be installed
##view_remoteAgentInstall_promptInstallPath = Where the agent is or will be installed. If you aren''t sure where an agent is installed, enter a parent directory and click the ''Find Agent'' button to scan that directory and below. If you enter an empty path, common locations are searched on the host for an agent install.
@@ -1478,11 +1486,11 @@ view_resource_title_tagUpdateFailed = Fehler beim Aktualisieren der Ressourcen-T
##view_searchGUI_loginStatus = Unable to determine login status, check server status
view_selector_assigned = Zugewiesen {0}
view_selector_available = Verfügbar {0}
-##view_subTab_error_disabled = Cannot select disabled subTab [{0}].
+view_subTab_error_disabled = Kann den deaktivierten Unter-Reiter [{0}] nicht anwählen.
##view_summaryOverviewForm_error_descriptionChangeFailure = Failed to change description of Resource with id {0} from [{1}] to [{2}].
##view_summaryOverviewForm_error_locationChangeFailure = Failed to change location of Resource with id {0} from [{1}] to [{2}].
##view_summaryOverviewForm_error_nameChangeFailure = Failed to change name of Resource with id {0} from [{1}] to [{2}].
-##view_summaryOverviewForm_error_traitsLoadFailure = Failed to load traits for {0}.
+view_summaryOverviewForm_error_traitsLoadFailure = Konnte die Traits für {0} nicht laden.
view_summaryOverviewForm_field_description = Beschreibung
view_summaryOverviewForm_field_location = Ort
view_summaryOverviewForm_field_name = Name
@@ -1496,10 +1504,10 @@ view_summaryOverviewForm_label_plugin = Plugin:
##view_summaryOverviewForm_message_nameChangeSuccess = "Name of Resource with id {0} was changed from [{1}] to [{2}].
##view_summaryOverview_header_detectedErrors = Detected Errors
view_summaryOverview_title_errorDetailsWindow = Fehler-Details
-##view_summaryOverview_tooltip_detectedErrors = Click on the rows to see the error details.
+view_summaryOverview_tooltip_detectedErrors = Klicken Sie auf eine Reihe, um die Fehler-Details zu sehen.
view_tableSection_backButton = Zurück zur Liste
-##view_tableSection_error_badId = Can not show detail for [{0}]. Illegal 'id': [{1}]. Please report this bug
-##view_tableSection_error_noId = Table [{0}] record is missing 'id' attribute - please report this bug.
+view_tableSection_error_badId = Kann das Detail für [{0}] nicht anzeigen. Ungültige 'id': [{1}]. Bitte berichten Sie diesen Fehler
+view_tableSection_error_noId = Dem Datensatz für die Tabelle [{0}] fehlt das 'id' Attribut - Bitte berichten Sie diesen Fehler
view_table_drawFail = Konnte die Tabelle [{0}] nicht zeichnen.
view_table_matchingRows = Zutreffende Zeilen: {0} (ausgewählt: {1})
view_table_totalRows = Anzahl Einträge: {0} Ausgewählt: {1}
@@ -1545,8 +1553,8 @@ view_tags_tooltip_2 = Klicken um die Tags zu bearbeiten
view_tags_tooltip_3 = Geben Sie ein Tag in folgenem Format ein: (namespace:)(semantic=)tagname (z.B. it:env=QA, oder owner=John)
##view_testTop_description = This section contains pages for testing various GUI components.
view_testTop_title = Test
-##view_titleBar_common_addedFav = You have added [{0}] as a favorite
-##view_titleBar_common_addedFavFailure = Failed to add [{0}] as a favorite
+view_titleBar_common_addedFav = Sie haben [{0}] als Lesezeichen hinzugefügt
+view_titleBar_common_addedFavFailure = Konnte [{0}] nicht als Lesezeichen hinzufügen
##view_titleBar_common_clickToAddFav = Click to add this as a favorite
##view_titleBar_common_clickToRemoveFav = Click to remove this as a favorite
##view_titleBar_common_loadTagsFailure = Failed to load the tags for [{0}]
12 years, 7 months
[rhq] Branch 'feature/rest' - modules/enterprise
by Heiko W. Rupp
modules/enterprise/gui/rest-war/src/main/webapp/WEB-INF/web.xml | 4
modules/enterprise/server/container/src/main/resources/jbossas/server/default/deploy/rhq-cache-service.xml | 170 +++++++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java | 135 +++++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerBean.java | 80 ++-
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerLocal.java | 4
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/OperationsHandlerBean.java | 236 ++++++++++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/OperationsHandlerLocal.java | 76 +++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java | 140 ++++-
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerLocal.java | 35 -
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/OperationDefinitionRest.java | 52 ++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/OperationRest.java | 117 ++++
modules/enterprise/server/jar/src/main/resources/rest_templates/metricSchedule.ftl | 9
12 files changed, 989 insertions(+), 69 deletions(-)
New commits:
commit e23db61ad37d962ce5ba746a2864854d1ce4fc78
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Sat Nov 5 21:40:57 2011 +0100
More REST work, consisting of:
Introduce a cache (at the moment for schedules) to reduce database load.
Map the cache int JNDI and have it injected by the container.
Check the caller when accessing cache entries, so that only entries are returned that the caller has access to.
Clean up some methods, add support for links to operation definitions for resources.
First cut at triggering operations.
diff --git a/modules/enterprise/gui/rest-war/src/main/webapp/WEB-INF/web.xml b/modules/enterprise/gui/rest-war/src/main/webapp/WEB-INF/web.xml
index 9652232..5d39d99 100644
--- a/modules/enterprise/gui/rest-war/src/main/webapp/WEB-INF/web.xml
+++ b/modules/enterprise/gui/rest-war/src/main/webapp/WEB-INF/web.xml
@@ -7,7 +7,7 @@
<context-param>
<param-name>resteasy.jndi.resources</param-name>
- <param-value>rhq/ResourceHandlerBean/local,rhq/MetricHandlerBean/local,rhq/UserHandlerBean/local,rhq/StatusHandlerBean/local,rhq/AlertHandlerBean/local</param-value>
+ <param-value>rhq/ResourceHandlerBean/local,rhq/MetricHandlerBean/local,rhq/UserHandlerBean/local,rhq/StatusHandlerBean/local,rhq/AlertHandlerBean/local,rhq/OperationsHandlerBean/local</param-value>
<description>List of jndi names of EJBs local interfaces that define REST stuff</description>
</context-param>
<context-param>
@@ -64,6 +64,7 @@
<web-resource-collection>
<web-resource-name>REST</web-resource-name>
<url-pattern>/*</url-pattern>
+<!--
<http-method>DELETE</http-method>
<http-method>PUT</http-method>
<http-method>HEAD</http-method>
@@ -71,6 +72,7 @@
<http-method>TRACE</http-method>
<http-method>GET</http-method>
<http-method>POST</http-method>
+-->
</web-resource-collection>
<auth-constraint>
<role-name>all</role-name>
diff --git a/modules/enterprise/server/container/src/main/resources/jbossas/server/default/deploy/rhq-cache-service.xml b/modules/enterprise/server/container/src/main/resources/jbossas/server/default/deploy/rhq-cache-service.xml
new file mode 100644
index 0000000..f458a8e
--- /dev/null
+++ b/modules/enterprise/server/container/src/main/resources/jbossas/server/default/deploy/rhq-cache-service.xml
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<server>
+
+ <mbean code="org.jboss.cache.TreeCache"
+ name="rhq.cache:service=cache">
+ <depends>jboss:service=TransactionManager</depends>
+
+ <!-- Configure the TransactionManager -->
+ <attribute name="TransactionManagerLookupClass">org.jboss.cache.JBossTransactionManagerLookup</attribute>
+
+ <!-- Isolation level : SERIALIZABLE
+ REPEATABLE_READ (default)
+ READ_COMMITTED
+ READ_UNCOMMITTED
+ NONE
+ -->
+ <attribute name="IsolationLevel">REPEATABLE_READ</attribute>
+
+ <!--
+ Node locking scheme:
+ OPTIMISTIC
+ PESSIMISTIC (default)
+ -->
+ <attribute name="NodeLockingScheme">OPTIMISTIC</attribute>
+
+ <!-- Valid modes are LOCAL, REPL_ASYNC and REPL_SYNC -->
+ <attribute name="CacheMode">REPL_ASYNC</attribute>
+
+ <!-- Just used for async repl: use a replication queue -->
+ <attribute name="UseReplQueue">false</attribute>
+
+ <!-- Replication interval for replication queue (in ms) -->
+ <attribute name="ReplQueueInterval">100</attribute>
+
+ <!-- Max number of elements which trigger replication -->
+ <attribute name="ReplQueueMaxElements">10</attribute>
+
+
+ <!-- Name of cluster. Needs to be the same for all clusters, in order
+ to find each other
+ -->
+ <attribute name="ClusterName">${jboss.partition.name:DefaultPartition}-RHQ-Cache</attribute>
+
+ <!-- JGroups protocol stack properties. Can also be a URL,
+ e.g. file:/home/bela/default.xml
+ <attribute name="ClusterProperties"></attribute>
+ -->
+ <attribute name="ClusterConfig">
+
+ <config>
+ <!-- UDP: if you have a multihomed machine,
+ set the bind_addr attribute to the appropriate NIC IP address, e.g bind_addr="192.168.0.2"
+ -->
+ <!-- UDP: On Windows machines, because of the media sense feature
+ being broken with multicast (even after disabling media sense)
+ set the loopback attribute to true
+
+ TODO need to parametrize and add to installer
+
+ -->
+ <UDP
+ mcast_addr="${jgroups.udp.mcast_addr:230.1.2.3}"
+ mcast_port="${jboss.alertcachepartition.mcast_port:48899}"
+ ip_ttl="${jgroups.udp.ip_ttl:2}"
+ bind_addr="${jgroups.bind_addr}"
+ ip_mcast="true"
+ tos="8"
+ mcast_send_buf_size="150000"
+ mcast_recv_buf_size="80000"
+ ucast_send_buf_size="150000"
+ ucast_recv_buf_size="80000"
+ loopback="${rhq.server.startup.partition.udpLoopback:false}" />
+ <PING timeout="2000"
+ num_initial_members="3"
+ up_thread="false"
+ down_thread="false" />
+ <MERGE2 min_interval="10000"
+ max_interval="20000" />
+ <FD_SOCK />
+ <VERIFY_SUSPECT timeout="1500"
+ up_thread="false"
+ down_thread="false" />
+ <pbcast.NAKACK gc_lag="50"
+ retransmit_timeout="600,1200,2400,4800"
+ max_xmit_size="8192"
+ up_thread="false"
+ down_thread="false" />
+ <UNICAST timeout="600,1200,2400"
+ down_thread="false" />
+ <pbcast.STABLE desired_avg_gossip="20000"
+ up_thread="false"
+ down_thread="false" />
+ <FRAG frag_size="8192" down_thread="false"
+ up_thread="false" />
+ <pbcast.GMS join_timeout="5000" join_retry_timeout="2000"
+ shun="true" print_local_addr="true" />
+ <pbcast.STATE_TRANSFER up_thread="true" down_thread="true" />
+ </config>
+ </attribute>
+
+ <!-- Whether or not to fetch state on joining a cluster -->
+ <attribute name="FetchStateOnStartup">true</attribute>
+
+ <!-- The max amount of time (in milliseconds) we wait until the
+ initial state (ie. the contents of the cache) are retrieved from
+ existing members in a clustered environment
+
+ -->
+ <attribute name="InitialStateRetrievalTimeout">5000</attribute>
+
+ <!-- Number of milliseconds to wait until all responses for a
+ synchronous call have been received.
+ -->
+ <attribute name="SyncReplTimeout">15000</attribute>
+
+ <!-- Max number of milliseconds to wait for a lock acquisition -->
+ <attribute name="LockAcquisitionTimeout">10000</attribute>
+
+ <attribute name="EvictionPolicyClass">org.jboss.cache.eviction.LRUPolicy</attribute>
+ <!-- Specific eviction policy configurations. This is LRU -->
+ <attribute name="EvictionPolicyConfig">
+ <config>
+ <attribute name="wakeUpIntervalSeconds">5</attribute>
+ <!-- Cache wide default -->
+ <region name="/_default_">
+ <attribute name="maxNodes">5000</attribute>
+ <attribute name="timeToLiveSeconds">1000</attribute>
+ </region>
+ <region name="/schedules">
+ <attribute name="maxNodes">5000</attribute>
+ <attribute name="timeToLiveSeconds">1000</attribute>
+ </region>
+ <region name="/org/jboss/test/data">
+ <attribute name="maxNodes">5</attribute>
+ <attribute name="timeToLiveSeconds">4</attribute>
+ </region>
+ <region name="/test/">
+ <attribute name="maxNodes">10000</attribute>
+ <attribute name="timeToLiveSeconds">5</attribute>
+ </region>
+ <region name="/maxAgeTest/">
+ <attribute name="maxNodes">10000</attribute>
+ <attribute name="timeToLiveSeconds">8</attribute>
+ <attribute name="maxAgeSeconds">10</attribute>
+ </region>
+ </config>
+ </attribute>
+ </mbean>
+
+
+ <!-- Map the cache into JNDI -->
+ <mbean
+ code="org.jboss.invocation.jrmp.server.JRMPProxyFactory"
+ name="mydomain:service=proxyFactory,type=jrmp,target=factory">
+ <attribute name="InvokerName">jboss:service=invoker,type=jrmp</attribute>
+ <attribute name="TargetName">rhq.cache:service=cache</attribute>
+ <attribute name="JndiName">RhqCache</attribute>
+ <attribute name="InvokeTargetMethod">true</attribute>
+ <attribute name="ExportedInterface">org.jboss.cache.TreeCacheMBean</attribute>
+ <attribute name="ClientInterceptors">
+ <iterceptors>
+ <interceptor>org.jboss.proxy.ClientMethodInterceptor</interceptor>
+ <interceptor>org.jboss.proxy.SecurityInterceptor</interceptor>
+ <interceptor>org.jboss.invocation.InvokerInterceptor</interceptor>
+ </iterceptors>
+ </attribute>
+ <depends>jboss:service=invoker,type=jrmp</depends>
+ <depends>rhq.cache:service=cache</depends>
+ </mbean>
+</server>
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java
index d1d3c89..124e12f 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java
@@ -25,7 +25,12 @@ package org.rhq.enterprise.server.rest;
import java.io.IOException;
import java.io.StringWriter;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.Resource;
+import javax.ejb.Stateless;
import freemarker.cache.ClassTemplateLoader;
import freemarker.cache.MultiTemplateLoader;
@@ -37,12 +42,20 @@ import freemarker.template.TemplateException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.CacheException;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.Node;
+import org.jboss.cache.TreeCacheMBean;
+
import org.rhq.core.domain.auth.Subject;
/**
* Abstract base class for EJB classes that implement REST methods.
+ * For the cache and its evicion policies see rhq-cache-service.xml
* @author Heiko W. Rupp
*/
+@Stateless
+@Resource(name="cache",type= TreeCacheMBean.class,mappedName = "RhqCache")
public class AbstractRestBean {
Log log = LogFactory.getLog(getClass().getName());
@@ -50,6 +63,10 @@ public class AbstractRestBean {
/** Subject of the caller that gets injected via {@link SetCallerInterceptor} */
Subject caller;
+ /** The cache to use */
+ @Resource(name="cache")
+ TreeCacheMBean treeCache;
+
/**
* Renders the passed object with the help of a freemarker template into a string. Freemarket templates
* are searched in the class path in a directory called "/rest_templates". In the usual Maven tree structure,
@@ -92,4 +109,122 @@ public class AbstractRestBean {
}
return null;
}
+
+ /**
+ * Retrieve an object from the cache. This is identified by its class and id
+ * @param id Id of the object to load.
+ * @param clazz Wanted return type
+ * @return Object if found and the caller has access to it.
+ * @see #getFqn(int, Class)
+ */
+ protected <T>T getFromCache(int id,Class<T> clazz) {
+ Fqn fqn = getFqn(id, clazz);
+ return getFromCache(fqn,clazz);
+ }
+
+
+ /**
+ * Retrieve an object from the cache if present or null otherwise.
+ * We need to be careful here as we must not return objects the current
+ * caller has no access to. We do this by checking the "readers" attribute
+ * of the selected node to see if the caller has put the object there
+ * @param fqn FullyQualified name (=path in cache) ot the object to retrieve
+ * @param clazz Return type
+ * @return The desired object if found and valid for the current caller. Null otherwise.
+ * @see #putToCache(org.jboss.cache.Fqn, Object)
+ */
+ @SuppressWarnings("unchecked")
+ protected <T>T getFromCache(Fqn fqn,Class<T> clazz) {
+ Object o=null;
+ if (treeCache.exists(fqn)) {
+ log.info("Hit for " + fqn.toString());
+ try{
+ Node n = treeCache.get(fqn);
+ Set<Integer> readers= (Set<Integer>) n.get("readers");
+ if (readers.contains(caller.getId())) {
+ o = n.get("item");
+ }
+ else {
+ log.info("No object for caller " +caller.toString() + " found");
+ }
+ } catch (CacheException e) {
+ e.printStackTrace(); // TODO: Customise this generated block
+ log.info("Miss for " + fqn.toString());
+ }
+ }
+ return (T)o;
+ }
+
+ /**
+ * Put an object into the cache. We need to record the caller so that we can later
+ * check if the caller can access that object or not.
+ * @param fqn Fully qualified name (=path to object)
+ * @param o Object to put
+ * @return true if put was successful
+ * @see #getFromCache(org.jboss.cache.Fqn, Class)
+ */
+ @SuppressWarnings("unchecked")
+ protected <T>boolean putToCache(Fqn fqn,T o) {
+ boolean success = false;
+ try {
+ Set<Integer> readers;
+ if (treeCache.exists(fqn)) {
+ Node n = treeCache.get(fqn);
+ readers = (Set<Integer>) n.get("readers");
+ } else {
+ readers = new HashSet<Integer>();
+ }
+ readers.add(caller.getId());
+ treeCache.put(fqn,"readers",readers);
+ treeCache.put(fqn,"item",o);
+ success = true;
+ log.info("Put " + fqn);
+ } catch (CacheException e) {
+ e.printStackTrace(); // TODO: Customise this generated block
+ }
+ return success;
+ }
+
+ /**
+ * Put an object into the cache identified by its type and id
+ * @param id Id of the object to put
+ * @param clazz Type to put in
+ * @param o Object to put
+ * @return true if put was successful
+ * @see #putToCache(org.jboss.cache.Fqn, Object)
+ */
+ protected <T>boolean putToCache(int id,Class<T> clazz,T o) {
+ Fqn fqn = getFqn(id, clazz);
+ return putToCache(fqn,o);
+ }
+
+ /**
+ * Construct a Fqn object from the passed data
+ * @param id Id of the target object
+ * @param clazz Type of object for that node
+ * @return Fqn object
+ */
+ protected <T> Fqn getFqn(int id, Class<T> clazz) {
+ return new Fqn(new Object[]{clazz.getName(), String.valueOf(id)});
+ }
+
+ /**
+ * Remove an item from the cache
+ * @param operationId Id of the item
+ * @param clazz Type of object for that node
+ * @return true if object is no longer in cache
+ */
+ protected <T> boolean removeFromCache(int operationId, Class<T> clazz) {
+ Fqn fqn = getFqn(operationId,clazz);
+ if (treeCache.exists(fqn)) {
+ try {
+ treeCache.remove(fqn);
+ log.info("Cancel " + fqn);
+ return true;
+ } catch (CacheException e) {
+ return false;
+ }
+ }
+ return true;
+ }
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerBean.java
index 9908b7d..f21a90c 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerBean.java
@@ -36,6 +36,8 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
+import org.jboss.cache.Fqn;
+
import org.rhq.core.domain.measurement.DataType;
import org.rhq.core.domain.measurement.MeasurementDefinition;
import org.rhq.core.domain.measurement.MeasurementSchedule;
@@ -80,7 +82,17 @@ public class MetricHandlerBean extends AbstractRestBean implements MetricHandle
}
- MeasurementSchedule schedule = scheduleManager.getScheduleById(caller,scheduleId);
+ MeasurementSchedule schedule;
+ schedule = getFromCache(scheduleId,MeasurementSchedule.class);
+ if (schedule==null) {
+ schedule = scheduleManager.getScheduleById(caller,scheduleId);
+ if (schedule==null) {
+ throw new StuffNotFoundException("Schedule with id " + scheduleId);
+ }
+ else
+ putToCache(scheduleId,MeasurementSchedule.class,schedule);
+ }
+
if (schedule.getDefinition().getDataType()!= DataType.MEASUREMENT)
throw new IllegalArgumentException("Schedule [" + scheduleId + "] is not a (numerical) metric");
@@ -140,14 +152,43 @@ public class MetricHandlerBean extends AbstractRestBean implements MetricHandle
* @param scheduleId ID of the schedule
* @param request the REST request - injected by the REST framework
* @param headers the REST request http headers - injected by the REST framework
- * @param uriInfo
+ * @param uriInfo info about the called uri to build links
* @return Schedule with respective headers
*/
public Response getSchedule(int scheduleId, Request request, HttpHeaders headers, UriInfo uriInfo) {
- MeasurementSchedule schedule = scheduleManager.getScheduleById(caller, scheduleId);
- if (schedule==null)
- throw new StuffNotFoundException("Schedule with id " + scheduleId);
+ MeasurementSchedule schedule=null;
+ Response.ResponseBuilder builder=null;
+
+ // Create a cache control
+ CacheControl cc = new CacheControl();
+ cc.setMaxAge(300); // Schedules are valid for 5 mins
+ cc.setPrivate(false); // Proxies may cache this
+
+
+ Fqn fqn = getFqn(scheduleId,MeasurementSchedule.class);
+ schedule = getFromCache(fqn,MeasurementSchedule.class);
+ if (schedule!=null) {
+ // If it is on cache, quickly return if match
+ long tim = schedule.getMtime() != null ? schedule.getMtime() : 0;
+ EntityTag eTag = new EntityTag(Long.toOctalString(schedule.hashCode()+tim)); // factor in mtime in etag
+ builder = request.evaluatePreconditions(new Date(tim),eTag);
+
+ if (builder!=null) {
+ builder.cacheControl(cc);
+ return builder.build();
+ }
+
+
+ }
+
+ if (schedule==null) {
+ schedule = scheduleManager.getScheduleById(caller, scheduleId);
+ if (schedule==null)
+ throw new StuffNotFoundException("Schedule with id " + scheduleId);
+ else
+ putToCache(fqn,schedule);
+ }
MeasurementDefinition definition = schedule.getDefinition();
MetricSchedule metricSchedule = new MetricSchedule(schedule.getId(), definition.getName(),
@@ -157,14 +198,14 @@ public class MetricHandlerBean extends AbstractRestBean implements MetricHandle
if (schedule.getMtime()!=null)
metricSchedule.setMtime(schedule.getMtime());
- // What media type does the user request?
- MediaType mediaType = headers.getAcceptableMediaTypes().get(0);
- // Check for conditional get
+ // Check for conditional get again
// Interestingly computing the hashCode of the original schedule is slower, as it also
// pulls in data from the definition and the resource
- EntityTag eTag = new EntityTag(Integer.toOctalString(metricSchedule.hashCode()));
- Response.ResponseBuilder builder = request.evaluatePreconditions(new Date(metricSchedule.getMtime()),eTag);
+ long tim = schedule.getMtime() != null ? schedule.getMtime() : 0;
+ EntityTag eTag = new EntityTag(Long.toOctalString(schedule.hashCode()+tim));
+ builder = request.evaluatePreconditions(new Date(tim),eTag); // factor in mtime in etag
+
if (builder==null) {
// preconditions not met, we need to send the resource
@@ -173,16 +214,24 @@ public class MetricHandlerBean extends AbstractRestBean implements MetricHandle
UriBuilder uriBuilder = uriInfo.getBaseUriBuilder();
uriBuilder.path("metric/data/" + scheduleId);
URI uri = uriBuilder.build();
-
Link link = new Link("metrics",uri.toString());
metricSchedule.addLink(link);
+ // create link to the resource
+ uriBuilder = uriInfo.getBaseUriBuilder();
+ uriBuilder.path("resource/" + schedule.getResource().getId());
+ uri = uriBuilder.build();
+ link = new Link("resource",uri.toString());
+ metricSchedule.addLink(link);
+
// Link for updates
uriBuilder = uriInfo.getAbsolutePathBuilder();
uri = uriBuilder.build();
Link updateLink = new Link("edit",uri.toString());
metricSchedule.addLink(updateLink);
+ // What media type does the user request?
+ MediaType mediaType = headers.getAcceptableMediaTypes().get(0);
if (mediaType.equals(MediaType.TEXT_HTML_TYPE)) {
builder = Response.ok(renderTemplate("metricSchedule", metricSchedule), mediaType);
@@ -192,10 +241,6 @@ public class MetricHandlerBean extends AbstractRestBean implements MetricHandle
}
}
- // Create a cache control
- CacheControl cc = new CacheControl();
- cc.setMaxAge(300); // Schedules are valid for 5 mins
- cc.setPrivate(false); // Proxies may cache this
builder.cacheControl(cc);
builder.tag(eTag);
@@ -208,6 +253,9 @@ public class MetricHandlerBean extends AbstractRestBean implements MetricHandle
List<MeasurementSchedule> schedules = scheduleManager.findSchedulesForResourceAndType(caller,
resourceId, DataType.MEASUREMENT, null,false);
+ for (MeasurementSchedule sched: schedules) {
+ putToCache(sched.getId(),MeasurementSchedule.class,sched);
+ }
List<MetricAggregate> ret = new ArrayList<MetricAggregate>(schedules.size());
long now = System.currentTimeMillis();
@@ -239,6 +287,8 @@ public class MetricHandlerBean extends AbstractRestBean implements MetricHandle
scheduleManager.updateSchedule(caller, schedule);
schedule = scheduleManager.getScheduleById(caller,scheduleId);
+ Fqn fqn = getFqn(scheduleId,MeasurementSchedule.class);
+ putToCache(fqn,schedule);
MeasurementDefinition def = schedule.getDefinition();
MetricSchedule ret = new MetricSchedule(scheduleId,def.getName(),def.getDisplayName(),
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerLocal.java
index 76c3f9d..368ef36 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerLocal.java
@@ -73,8 +73,8 @@ public interface MetricHandlerLocal {
@PUT
@Path("/schedule/{id}")
- @Consumes(MediaType.APPLICATION_JSON)
- @Produces(MediaType.APPLICATION_JSON)
+ @Consumes({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
+ @Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
MetricSchedule updateSchedule(@PathParam("id") int scheduleId, MetricSchedule in);
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/OperationsHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/OperationsHandlerBean.java
new file mode 100644
index 0000000..2a4f7df
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/OperationsHandlerBean.java
@@ -0,0 +1,236 @@
+package org.rhq.enterprise.server.rest;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import javax.ejb.EJB;
+import javax.ejb.Stateless;
+import javax.interceptor.Interceptors;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.CacheControl;
+import javax.ws.rs.core.EntityTag;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Request;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+
+import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
+import org.rhq.core.domain.configuration.definition.PropertyDefinition;
+import org.rhq.core.domain.operation.OperationDefinition;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.enterprise.server.operation.OperationManagerLocal;
+import org.rhq.enterprise.server.resource.ResourceManagerLocal;
+import org.rhq.enterprise.server.rest.domain.Link;
+import org.rhq.enterprise.server.rest.domain.OperationDefinitionRest;
+import org.rhq.enterprise.server.rest.domain.OperationRest;
+
+/**
+ * Deal with operations
+ * @author Heiko W. Rupp
+ */
+@Stateless
+(a)Interceptors(SetCallerInterceptor.class)
+public class OperationsHandlerBean extends AbstractRestBean implements OperationsHandlerLocal {
+
+ @EJB
+ OperationManagerLocal opsManager;
+
+ @EJB
+ ResourceManagerLocal resourceManager;
+
+ @Override
+ public Response getOperationDefinition(int definitionId,
+ Integer resourceId,
+ UriInfo uriInfo,
+ Request request, HttpHeaders httpHeaders) {
+
+
+
+ OperationDefinition def;
+ def = getFromCache(definitionId, OperationDefinition.class);
+ if (def==null) {
+ def = opsManager.getOperationDefinition(caller,definitionId);
+ if (def==null)
+ throw new StuffNotFoundException("OperationDefinition with id " + definitionId);
+ else
+ putToCache(definitionId,OperationDefinition.class,def);
+ }
+
+ EntityTag eTag = new EntityTag(Integer.toHexString(def.hashCode()));
+ Response.ResponseBuilder builder = request.evaluatePreconditions(eTag);
+ if (builder==null) {
+
+ OperationDefinitionRest odr = new OperationDefinitionRest();
+ odr.setId(def.getId());
+ odr.setName(def.getName());
+
+ builder=Response.ok(odr);
+
+ // Add some links
+ if (resourceId!=null) {
+ UriBuilder uriBuilder = uriInfo.getBaseUriBuilder();
+ uriBuilder.path("/operation/definition/{id}");
+ uriBuilder.queryParam("resourceId",resourceId);
+ Link createLink = new Link("create",uriBuilder.build(definitionId).toString());
+ odr.addLink(createLink);
+ }
+
+ }
+
+ CacheControl cc = new CacheControl();
+ cc.setMaxAge(1200); // Definitions are very stable, so caching for 20mins is ok
+ cc.setPrivate(false);
+ builder.tag(eTag);
+ builder.cacheControl(cc);
+
+ return builder.build();
+
+ }
+
+ @Override
+ // TODO find out why a return type of Response lets this fail for XML (even with @Wrapped annotation
+ public List<OperationDefinitionRest> getOperationDefinitions(Integer resourceId, UriInfo uriInfo, Request request) {
+
+ if (resourceId == null)
+ throw new ParameterMissingException("resourceId");
+
+ Resource res =resourceManager.getResource(caller,resourceId);
+ if(res==null)
+ throw new StuffNotFoundException("resource with id " + resourceId);
+
+ ResourceType resourceType = res.getResourceType();
+
+/*
+ EntityTag eTag = new EntityTag(Integer.toHexString(resourceType.hashCode()));
+ Response.ResponseBuilder builder = request.evaluatePreconditions(eTag);
+ if (builder==null) {
+*/
+
+ Set<OperationDefinition> opDefList = resourceType.getOperationDefinitions();
+ List<OperationDefinitionRest> resultList = new ArrayList<OperationDefinitionRest>(opDefList.size());
+
+ for (OperationDefinition def : opDefList) {
+ OperationDefinitionRest odr = new OperationDefinitionRest();
+ odr.setId(def.getId());
+ odr.setName(def.getName());
+ UriBuilder uriBuilder = uriInfo.getBaseUriBuilder();
+ uriBuilder.path("/operation/definition/{id}");
+ uriBuilder.queryParam("resourceId",resourceId);
+ Link createLink = new Link("create",uriBuilder.build(def.getId()).toString());
+ odr.addLink(createLink);
+
+ resultList.add(odr);
+ }
+ return resultList;
+
+/*
+
+ builder = Response.ok(resultList);
+ }
+
+ CacheControl cc = new CacheControl();
+ cc.setMaxAge(1200); // Definitions are very stable, so caching for 20mins is ok
+ cc.setPrivate(false);
+ builder.tag(eTag);
+ builder.cacheControl(cc);
+
+ return builder.build();
+*/
+
+ }
+
+ @Override
+ public Response createOperation(@PathParam("id") int definitionId,
+ @QueryParam("resourceId") Integer resourceId,
+ UriInfo uriInfo) {
+
+ if (resourceId == null)
+ throw new ParameterMissingException("resourceId");
+
+ Resource res =resourceManager.getResource(caller,resourceId);
+ if(res==null)
+ throw new StuffNotFoundException("resource with id " + resourceId);
+
+
+ OperationDefinition opDef = opsManager.getOperationDefinition(caller,definitionId);
+ if (opDef==null) {
+ throw new StuffNotFoundException("Operation definition with id " + definitionId);
+ }
+ OperationRest operationRest = new OperationRest(resourceId,definitionId);
+ operationRest.setId((int)System.currentTimeMillis()); // TODO better id (?)(we need one for pUT later on)
+ operationRest.setState("creating");
+ operationRest.setName(opDef.getName());
+ ConfigurationDefinition paramDefinition = opDef.getParametersConfigurationDefinition();
+ if (paramDefinition != null) {
+ for (PropertyDefinition propDefs : paramDefinition.getNonGroupedProperties()) { // TODO extend to all properties ?
+ operationRest.getParams().put(propDefs.getName(),"TODO"); // TODO type and value of the value
+ }
+ }
+
+ UriBuilder uriBuilder = uriInfo.getBaseUriBuilder();
+ uriBuilder.path("/operation/{id}");
+ URI uri = uriBuilder.build(operationRest.getId());
+ Link editLink = new Link("edit",uri.toString());
+ operationRest.addLink(editLink);
+ Response.ResponseBuilder builder = Response.ok(operationRest);
+
+ putToCache(operationRest.getId(),OperationRest.class,operationRest);
+
+ return builder.build();
+
+ }
+
+ @Override
+ public Response getOperation(@PathParam("id") int operationId) {
+ OperationRest op = getFromCache(operationId,OperationRest.class);
+ if (op==null)
+ throw new StuffNotFoundException("Operation with id " + operationId);
+
+ return Response.ok(op).build();
+ }
+
+ @Override
+ public Response updateOperation(@PathParam("id") int operationId, OperationRest operation, UriInfo uriInfo) {
+
+ if (operation.getState().equals("creating") && operation.getDefinitionId()>0 && !operation.getName().isEmpty()) {
+ // TODO check all the required parameters for persence before allowing to submit
+ Link link = new Link("submit","TODO");
+ operation.addLink(link);
+
+ }
+ UriBuilder uriBuilder = uriInfo.getBaseUriBuilder();
+ uriBuilder.path("/operation/{id}");
+ URI uri = uriBuilder.build(operation.getId());
+ Link editLink = new Link("edit",uri.toString());
+ operation.addLink(editLink);
+
+ // Update item in cache
+ putToCache(operation.getId(),OperationRest.class,operation);
+
+ Response.ResponseBuilder builder = Response.ok(operation);
+ return builder.build();
+ }
+
+ @Override
+ @DELETE
+ @Path("{id}")
+ @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+ public Response cancelOperation(@PathParam("id") int operationId) {
+
+ log.info("Cancel called");
+
+ removeFromCache(operationId,OperationRest.class);
+
+ return null; // TODO: Customise this generated block
+ }
+
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/OperationsHandlerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/OperationsHandlerLocal.java
new file mode 100644
index 0000000..46a7f86
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/OperationsHandlerLocal.java
@@ -0,0 +1,76 @@
+package org.rhq.enterprise.server.rest;
+
+import java.util.List;
+
+import javax.ejb.Local;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Request;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import org.jboss.resteasy.annotations.providers.jaxb.Wrapped;
+
+import org.rhq.enterprise.server.rest.domain.OperationDefinitionRest;
+import org.rhq.enterprise.server.rest.domain.OperationRest;
+
+/**
+ * Service that deals with operations
+ * @author Heiko W. Rupp
+ */
+@Local
+@Path("/operation")
+public interface OperationsHandlerLocal {
+
+
+ @GET
+ @Path("definition/{id}")
+ @Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
+ public Response getOperationDefinition(@PathParam("id") int definitionId,
+ @QueryParam("resourceId") Integer resourceId,
+ @Context UriInfo uriInfo,
+ @Context Request request,
+ @Context HttpHeaders httpHeaders);
+
+ @GET
+ @Path("definitions")
+ @Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
+ public List<OperationDefinitionRest> getOperationDefinitions(@QueryParam("resourceId") Integer resourceId,
+ @Context UriInfo uriInfo,
+ @Context Request request
+ );
+
+ @POST
+ @Path("definition/{id}")
+ @Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
+ public Response createOperation(@PathParam("id") int definitionId,
+ @QueryParam("resourceId") Integer resourceId,
+ @Context UriInfo uriInfo);
+
+ @GET
+ @Path("{id}")
+ @Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
+ public Response getOperation(@PathParam("id") int operationId);
+
+ @PUT
+ @Path("{id}")
+ @Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
+ @Consumes({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
+ public Response updateOperation(@PathParam("id") int operationId, OperationRest operation, @Context UriInfo uriInfo);
+
+ @DELETE
+ @Path("{id}")
+ @Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
+ public Response cancelOperation(@PathParam("id") int operationId);
+
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java
index 368efc0..e656c24 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java
@@ -24,12 +24,20 @@ package org.rhq.enterprise.server.rest;
import java.net.URI;
import java.util.ArrayList;
+import java.util.Date;
import java.util.List;
import java.util.Set;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.interceptor.Interceptors;
+import javax.ws.rs.core.CacheControl;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.EntityTag;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Request;
+import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
@@ -71,44 +79,88 @@ public class ResourceHandlerBean extends AbstractRestBean implements ResourceHan
AlertManagerLocal alertManager;
@Override
- public ResourceWithType getResource(int id) {
+ public Response getResource(int id, @Context Request request, @Context HttpHeaders headers,
+ @Context UriInfo uriInfo) {
- Resource res = resMgr.getResource(caller, id);
+ // Create a cache control
+ CacheControl cc = new CacheControl();
+ cc.setMaxAge(300); // Resources are valid for 5 mins
+ cc.setPrivate(false); // Proxies may cache this
- ResourceWithType rwt = fillRWT(res);
+ Resource res;
+ res = getFromCache(id,Resource.class);
+ if (res==null) {
+ res = resMgr.getResource(caller, id);
+ if (res!=null)
+ putToCache(id, Resource.class,res);
+ else
+ throw new StuffNotFoundException("Resource with id " + id);
+ }
- return rwt;
- }
+ Response.ResponseBuilder builder=null;
- @Override
- public String getResourceHtml(int id) {
- ResourceWithType rwt = getResource(id);
- return renderTemplate("resourceWithType.ftl", rwt);
+ long mtime = res.getMtime();
+ EntityTag eTag = new EntityTag(Long.toOctalString(res.hashCode()+ mtime)); // factor in mtime in etag
+ builder = request.evaluatePreconditions(new Date(mtime),eTag);
+
+ if (builder!=null) {
+ builder.cacheControl(cc);
+ return builder.build();
+ }
+
+
+ ResourceWithType rwt = fillRWT(res, uriInfo);
+
+ // What media type does the user request?
+ MediaType mediaType = headers.getAcceptableMediaTypes().get(0);
+
+ if (mediaType.equals(MediaType.TEXT_HTML_TYPE)) {
+ builder = Response.ok(renderTemplate("resourceWithType", rwt), mediaType);
+ }
+ else {
+ builder = Response.ok(rwt);
+ }
+
+ return builder.build();
}
+
@Override
- public List<ResourceWithType> getPlatforms() {
+ public Response getPlatforms(@Context Request request, @Context HttpHeaders headers,
+ @Context UriInfo uriInfo) {
PageControl pc = new PageControl();
List<Resource> ret = resMgr.findResourcesByCategory(caller, ResourceCategory.PLATFORM, InventoryStatus.COMMITTED, pc) ;
List<ResourceWithType> rwtList = new ArrayList<ResourceWithType>(ret.size());
for (Resource r: ret) {
- ResourceWithType rwt = fillRWT(r);
+ putToCache(r.getId(),Resource.class,r);
+ ResourceWithType rwt = fillRWT(r, uriInfo);
rwtList.add(rwt);
}
- return rwtList;
- }
+ // What media type does the user request?
+ MediaType mediaType = headers.getAcceptableMediaTypes().get(0);
+ Response.ResponseBuilder builder;
- @Override
- public String getPlatformsHtml() {
- List<ResourceWithType> list = getPlatforms();
- return renderTemplate("listResourceWithType", list);
+ if (mediaType.equals(MediaType.TEXT_HTML_TYPE)) {
+ builder = Response.ok(renderTemplate("listResourceWithType", rwtList), mediaType);
+ }
+ else {
+ builder = Response.ok(rwtList);
+ }
+
+ return builder.build();
}
@Override
public ResourceWithChildren getHierarchy(int baseResourceId) {
// TODO optimize to do less recursion
- Resource start = resMgr.getResource(caller,baseResourceId);
+ Resource start;
+ start = getFromCache(baseResourceId,Resource.class);
+ if (start==null) {
+ start = resMgr.getResource(caller,baseResourceId);
+ if (start!=null)
+ putToCache(start.getId(),Resource.class,start);
+ }
ResourceWithChildren rwc = getHierarchy(start);
/*new ResourceWithChildren(""+start.getId(),start.getName());
@@ -135,6 +187,7 @@ public class ResourceHandlerBean extends AbstractRestBean implements ResourceHan
for (Resource res : ret) {
ResourceWithChildren child = getHierarchy(res);
resList.add(child);
+ putToCache(res.getId(),Resource.class,res);
}
if (!resList.isEmpty())
rwc.setChildren(resList);
@@ -151,7 +204,7 @@ public class ResourceHandlerBean extends AbstractRestBean implements ResourceHan
return availabilityRest;
}
- private ResourceWithType fillRWT(Resource res) {
+ private ResourceWithType fillRWT(Resource res, UriInfo uriInfo) {
ResourceType resourceType = res.getResourceType();
ResourceWithType rwt = new ResourceWithType(res.getName(),res.getId());
rwt.setTypeName(resourceType.getName());
@@ -161,6 +214,13 @@ public class ResourceHandlerBean extends AbstractRestBean implements ResourceHan
if (parent!=null) {
rwt.setParentId(parent.getId());
}
+ UriBuilder uriBuilder = uriInfo.getBaseUriBuilder();
+ uriBuilder.path("/operation/definitions");
+ uriBuilder.queryParam("resourceId",res.getId());
+ URI uri = uriBuilder.build();
+ Link link = new Link("operationDefinitions",uri.toString());
+ rwt.addLink(link);
+
return rwt;
}
@@ -171,6 +231,7 @@ public class ResourceHandlerBean extends AbstractRestBean implements ResourceHan
Set<MeasurementSchedule> schedules = res.getSchedules();
List<MetricSchedule> ret = new ArrayList<MetricSchedule>(schedules.size());
for (MeasurementSchedule schedule : schedules) {
+ putToCache(schedule.getId(),MeasurementSchedule.class,schedule);
MeasurementDefinition definition = schedule.getDefinition();
MetricSchedule ms = new MetricSchedule(schedule.getId(), definition.getName(), definition.getDisplayName(),
schedule.isEnabled(),schedule.getInterval(), definition.getUnits().toString(),
@@ -180,6 +241,13 @@ public class ResourceHandlerBean extends AbstractRestBean implements ResourceHan
URI uri = uriBuilder.build(schedule.getId());
Link metricLink = new Link("metric",uri.toString());
ms.addLink(metricLink);
+ // create link to the resource
+ uriBuilder = uriInfo.getBaseUriBuilder();
+ uriBuilder.path("resource/" + schedule.getResource().getId());
+ uri = uriBuilder.build();
+ Link link = new Link("resource",uri.toString());
+ ms.addLink(link);
+
ret.add(ms);
}
@@ -192,24 +260,42 @@ public class ResourceHandlerBean extends AbstractRestBean implements ResourceHan
}
@Override
- public List<ResourceWithType> getChildren(int id) {
+ public Response getChildren(int id, @Context Request request, @Context HttpHeaders headers,
+ @Context UriInfo uriInfo) {
PageControl pc = new PageControl();
- Resource parent = resMgr.getResource(caller,id);
+ Resource parent;
+ parent = getFromCache(id,Resource.class);
+ if (parent==null) {
+ parent = resMgr.getResource(caller,id);
+ if (parent==null)
+ throw new StuffNotFoundException("Resource with id " + id);
+ else
+ putToCache(id,Resource.class,parent);
+ }
List<Resource> ret = resMgr.findResourceByParentAndInventoryStatus(caller,parent,InventoryStatus.COMMITTED,pc);
List<ResourceWithType> rwtList = new ArrayList<ResourceWithType>(ret.size());
for (Resource r: ret) {
- ResourceWithType rwt = fillRWT(r);
+ putToCache(r.getId(),Resource.class,r);
+ ResourceWithType rwt = fillRWT(r, uriInfo);
rwtList.add(rwt);
}
- return rwtList;
- }
+ // What media type does the user request?
+ MediaType mediaType = headers.getAcceptableMediaTypes().get(0);
+ Response.ResponseBuilder builder;
+
+ if (mediaType.equals(MediaType.TEXT_HTML_TYPE)) {
+ builder = Response.ok(renderTemplate("listResourceWithType", rwtList), mediaType);
+ }
+ else {
+ builder = Response.ok(rwtList);
+ }
+
+ return builder.build();
- public String getChildrenHtml(int id) {
- List<ResourceWithType> list = getChildren(id);
- return renderTemplate("listResourceWithType", list);
}
+
@Override
public List<Link> getAlertsForResource(int resourceId) {
AlertCriteria criteria = new AlertCriteria();
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerLocal.java
index c2e8698..d1cb0f2 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerLocal.java
@@ -26,6 +26,10 @@ import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Request;
+import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import org.jboss.resteasy.links.AddLinks;
@@ -53,23 +57,15 @@ public interface ResourceHandlerLocal {
})
@GET
@Path("/{id}")
- @Produces({"application/json","application/xml"})
- ResourceWithType getResource(@PathParam("id") int id);
-
- @GET
- @Path("/{id}")
- @Produces("text/html")
- String getResourceHtml(@PathParam("id") int id);
+ @Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML,MediaType.TEXT_HTML})
+ Response getResource(@PathParam("id") int id, @Context Request request, @Context HttpHeaders headers,
+ @Context UriInfo uriInfo);
@GET
@Path("/platforms")
- @Produces({"application/json","application/xml"})
- List<ResourceWithType> getPlatforms();
-
- @GET
- @Path("/platforms")
- @Produces("text/html")
- String getPlatformsHtml();
+ @Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML,MediaType.TEXT_HTML})
+ Response getPlatforms(@Context Request request, @Context HttpHeaders headers,
+ @Context UriInfo uriInfo);
@GET
@@ -93,20 +89,17 @@ public interface ResourceHandlerLocal {
@Path("/{id}/schedules")
@Produces("text/html")
@LinkResource(rel="schedules",value = MetricSchedule.class)
+ // TODO move to ScheduleManager, link from resource and pass the resource as query param
String getSchedulesHtml(@PathParam("id") int resourceId,
@Context UriInfo uriInfo);
@GET
@Path("/{id}/children")
- @Produces({"application/json","application/xml"})
+ @Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML,MediaType.TEXT_HTML})
@LinkResource(rel="children", value = ResourceWithType.class)
- List<ResourceWithType> getChildren(@PathParam("id") int id);
+ Response getChildren(@PathParam("id") int id, @Context Request request, @Context HttpHeaders headers,
+ @Context UriInfo uriInfo);
- @GET
- @Path("/{id}/children")
- @Produces("text/html")
- @LinkResource(rel="children", value = ResourceWithType.class)
- String getChildrenHtml(@PathParam("id") int id);
@AddLinks
@GET
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/OperationDefinitionRest.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/OperationDefinitionRest.java
new file mode 100644
index 0000000..70f1a97
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/OperationDefinitionRest.java
@@ -0,0 +1,52 @@
+package org.rhq.enterprise.server.rest.domain;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlElementRef;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * @author Heiko W. Rupp
+ */
+@XmlRootElement
+public class OperationDefinitionRest {
+
+ public OperationDefinitionRest() {
+ }
+
+ String name;
+ int id;
+ List<Link> links = new ArrayList<Link>();
+ // TODO add parameters
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ @XmlElementRef
+ public List<Link> getLinks() {
+ return links;
+ }
+
+ public void setLinks(List<Link> links) {
+ this.links = links;
+ }
+
+ public void addLink(Link link) {
+ links.add(link);
+ }
+
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/OperationRest.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/OperationRest.java
new file mode 100644
index 0000000..50332ae
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/OperationRest.java
@@ -0,0 +1,117 @@
+package org.rhq.enterprise.server.rest.domain;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.bind.annotation.XmlElementRef;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * @author Heiko W. Rupp
+ */
+@XmlRootElement
+public class OperationRest {
+
+ int id;
+ String name;
+ String state; // TODO Convert to enum
+ int resourceId;
+ int definitionId;
+ Map<String,Object> params = new HashMap<String, Object>();
+ List<Link> links = new ArrayList<Link>();
+
+ public OperationRest() {
+ }
+
+ public OperationRest(int resourceId, int definitionId) {
+ this.resourceId = resourceId;
+ this.definitionId = definitionId;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getState() {
+ return state;
+ }
+
+ public void setState(String state) {
+ this.state = state;
+ }
+
+ public int getResourceId() {
+ return resourceId;
+ }
+
+ public void setResourceId(int resourceId) {
+ this.resourceId = resourceId;
+ }
+
+ public int getDefinitionId() {
+ return definitionId;
+ }
+
+ public void setDefinitionId(int definitionId) {
+ this.definitionId = definitionId;
+ }
+
+ public Map<String, Object> getParams() {
+ return params;
+ }
+
+ public void setParams(Map<String, Object> params) {
+ this.params = params;
+ }
+
+ @XmlElementRef
+ public List<Link> getLinks() {
+ return links;
+ }
+
+ public void setLinks(List<Link> links) {
+ this.links = links;
+ }
+
+ public void addLink(Link link) {
+ links.add(link);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ OperationRest that = (OperationRest) o;
+
+ if (definitionId != that.definitionId) return false;
+ if (id != that.id) return false;
+ if (resourceId != that.resourceId) return false;
+ if (name != null ? !name.equals(that.name) : that.name != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = (int) (id ^ (id >>> 32));
+ result = 31 * result + (name != null ? name.hashCode() : 0);
+ result = 31 * result + resourceId;
+ result = 31 * result + definitionId;
+ return result;
+ }
+}
diff --git a/modules/enterprise/server/jar/src/main/resources/rest_templates/metricSchedule.ftl b/modules/enterprise/server/jar/src/main/resources/rest_templates/metricSchedule.ftl
index 26360e5..0a0f187 100644
--- a/modules/enterprise/server/jar/src/main/resources/rest_templates/metricSchedule.ftl
+++ b/modules/enterprise/server/jar/src/main/resources/rest_templates/metricSchedule.ftl
@@ -46,7 +46,10 @@
<td>Units</td><td>${var.unit}</td>
</tr>
</table>
- <a href="/rest/1/metric/data/${var.scheduleId}.html">Metric data</a>
- <br/>
-
+ Links<br/>
+ <ul>
+ <#list var.links as link>
+ <li><a href="${link.href}.html">${link.rel}</a> </li>
+ </#list>
+ </ul>
</html>
\ No newline at end of file
12 years, 7 months
[rhq] Branch 'release_jon3.x' - modules/plugins
by mazz
modules/plugins/jmx/src/main/resources/META-INF/rhq-plugin.xml | 34 +++++-----
1 file changed, 20 insertions(+), 14 deletions(-)
New commits:
commit 570a73c42ab563aaa2be114038b0d79601d4032e
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Nov 4 19:55:10 2011 -0400
[BZ 747925] revert the changes that BZ 741331 made to the JMX plugin rhq-plugin.xml that materially affects the metadata.
once 747925 is fixed, we must undo this commit and put this file back the way we wanted it (which is what it looked like immediately prior to this commit)
diff --git a/modules/plugins/jmx/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/jmx/src/main/resources/META-INF/rhq-plugin.xml
index 41e031b..5572bf0 100644
--- a/modules/plugins/jmx/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/jmx/src/main/resources/META-INF/rhq-plugin.xml
@@ -120,9 +120,9 @@
createDeletePolicy="neither" singleton="true">
<plugin-configuration>
- <c:simple-property name="objectName" readOnly="true" default="java.lang:type=OperatingSystem"/>
- <c:simple-property name="nameTemplate" readOnly="true" default="Operating system information"/>
- <c:simple-property name="descriptionTemplate" readOnly="true" default="Operating system information provided by the JVM."/>
+ <c:simple-property name="objectName" default="java.lang:type=OperatingSystem"/>
+ <c:simple-property name="nameTemplate" default="Operating system information"/>
+ <c:simple-property name="descriptionTemplate" default="Operating system information provided by the JVM."/>
</plugin-configuration>
<metric displayName="Free Physical Memory"
@@ -146,6 +146,7 @@
measurementType="trendsup"
units="nanoseconds"/>
<metric displayName="Committed Virtual Memory"
+ defaultOn="true"
category="utilization"
property="CommittedVirtualMemorySize"
description="Size of virtual memory used by this process"
@@ -159,7 +160,7 @@
<plugin-configuration>
<c:simple-property name="objectName" readOnly="true" default="java.lang:type=Threading"/>
- <c:simple-property name="nameTemplate" readOnly="true" default="Threading"/>
+ <c:simple-property name="nameTemplate" default="Threading"/>
</plugin-configuration>
<operation displayName="Reset Peak Thread Metrics" name="resetPeakThreadCount"
@@ -210,12 +211,15 @@
property="ThreadCount"
description="Number of active threads in the system"/>
<metric displayName="Peak Thread Count"
+ defaultOn="true"
property="PeakThreadCount"
description="Peak count of active threads in the system"/>
<metric displayName="Total Started Thread Count"
+ defaultOn="true"
property="TotalStartedThreadCount"
description="Count of threads started since system start"/>
<metric displayName="Daemon Thread Count"
+ defaultOn="true"
property="DaemonThreadCount"
description="Count of threads marked as daemons in the system"/>
<metric property="SuspendedThreadCount"
@@ -237,13 +241,14 @@
<plugin-configuration>
<c:simple-property name="objectName" readOnly="true" default="java.lang:type=Memory"/>
- <c:simple-property name="nameTemplate" readOnly="true" default="Memory Subsystem"/>
+ <c:simple-property name="nameTemplate" default="Memory Subsystem"/>
</plugin-configuration>
<operation name="gc" displayName="Run Garbage Collection" description="Runs the garbage collector."/>
<metric displayName="Heap Usage"
property="{HeapMemoryUsage.used}"
+ displayType="summary"
description="Current heap memory usage"
units="bytes"/>
<metric displayName="Heap Committed"
@@ -253,6 +258,7 @@
units="bytes"/>
<metric displayName="Non-Heap Usage"
property="{NonHeapMemoryUsage.used}"
+ displayType="summary"
description="Current memory usage outside the heap"
units="bytes"/>
<metric displayName="Non-Heap Committed"
@@ -297,9 +303,9 @@
<plugin-configuration>
<c:simple-property name="objectName" readOnly="true" default="java.lang:type=MemoryPool,name=%name%"/>
- <c:simple-property name="nameTemplate" readOnly="true" default="{name}"/>
- <c:simple-property name="descriptionTemplate" readOnly="true" default="The {name} memory pool for this VM."/>
- <c:simple-property name="name" type="string" readOnly="true" description="The memory pool's name"/>
+ <c:simple-property name="nameTemplate" default="{name}"/>
+ <c:simple-property name="descriptionTemplate" default="The {name} memory pool for this VM."/>
+ <c:simple-property name="name" type="string" description="The memory pool's name"/>
</plugin-configuration>
<metric displayName="Used"
@@ -340,9 +346,9 @@
<plugin-configuration>
<c:simple-property name="objectName" readOnly="true" default="java.lang:type=GarbageCollector,name=%name%"/>
- <c:simple-property name="nameTemplate" readOnly="true" default="{name}"/>
- <c:simple-property name="descriptionTemplate" readOnly="true" default="The {name} Garbage Collector for this VM."/>
- <c:simple-property name="name" type="string" readOnly="true" description="The garbage collector's name"/>
+ <c:simple-property name="nameTemplate" default="{name}"/>
+ <c:simple-property name="descriptionTemplate" default="The {name} Garbage Collector for this VM."/>
+ <c:simple-property name="name" type="string" description="The garbage collector's name"/>
</plugin-configuration>
<metric property="CollectionCount"
@@ -369,7 +375,7 @@
<plugin-configuration>
<c:simple-property name="objectName" readOnly="true" default="java.lang:type=Compilation"/>
- <c:simple-property name="nameTemplate" readOnly="true" default="Compilation"/>
+ <c:simple-property name="nameTemplate" default="Compilation"/>
</plugin-configuration>
<metric property="TotalCompilationTime"
@@ -385,7 +391,7 @@
<plugin-configuration>
<c:simple-property name="objectName" readOnly="true" default="java.lang:type=ClassLoading"/>
- <c:simple-property name="nameTemplate" readOnly="true" default="Class Loading"/>
+ <c:simple-property name="nameTemplate" default="Class Loading"/>
</plugin-configuration>
<metric displayName="Loaded Classes"
@@ -413,7 +419,7 @@
<plugin-configuration>
<c:simple-property name="objectName" readOnly="true" default="java.util.logging:type=Logging"/>
- <c:simple-property name="nameTemplate" readOnly="true" default="Logging"/>
+ <c:simple-property name="nameTemplate" default="Logging"/>
<c:simple-property name="configManagementEnabled" type="boolean" default="false" description="When false, configuration reading for this resource will fail."/>
</plugin-configuration>
12 years, 7 months
[rhq] modules/plugins
by mazz
modules/plugins/jmx/src/main/resources/META-INF/rhq-plugin.xml | 34 +++++-----
1 file changed, 20 insertions(+), 14 deletions(-)
New commits:
commit cb8ad66fa52b6078d39a3beebaf92ee2cfc2788a
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Nov 4 19:55:10 2011 -0400
[BZ 747925] revert the changes that BZ 741331 made to the JMX plugin rhq-plugin.xml that materially affects the metadata.
once 747925 is fixed, we must undo this commit and put this file back the way we wanted it (which is what it looked like immediately prior to this commit)
diff --git a/modules/plugins/jmx/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/jmx/src/main/resources/META-INF/rhq-plugin.xml
index 41e031b..5572bf0 100644
--- a/modules/plugins/jmx/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/jmx/src/main/resources/META-INF/rhq-plugin.xml
@@ -120,9 +120,9 @@
createDeletePolicy="neither" singleton="true">
<plugin-configuration>
- <c:simple-property name="objectName" readOnly="true" default="java.lang:type=OperatingSystem"/>
- <c:simple-property name="nameTemplate" readOnly="true" default="Operating system information"/>
- <c:simple-property name="descriptionTemplate" readOnly="true" default="Operating system information provided by the JVM."/>
+ <c:simple-property name="objectName" default="java.lang:type=OperatingSystem"/>
+ <c:simple-property name="nameTemplate" default="Operating system information"/>
+ <c:simple-property name="descriptionTemplate" default="Operating system information provided by the JVM."/>
</plugin-configuration>
<metric displayName="Free Physical Memory"
@@ -146,6 +146,7 @@
measurementType="trendsup"
units="nanoseconds"/>
<metric displayName="Committed Virtual Memory"
+ defaultOn="true"
category="utilization"
property="CommittedVirtualMemorySize"
description="Size of virtual memory used by this process"
@@ -159,7 +160,7 @@
<plugin-configuration>
<c:simple-property name="objectName" readOnly="true" default="java.lang:type=Threading"/>
- <c:simple-property name="nameTemplate" readOnly="true" default="Threading"/>
+ <c:simple-property name="nameTemplate" default="Threading"/>
</plugin-configuration>
<operation displayName="Reset Peak Thread Metrics" name="resetPeakThreadCount"
@@ -210,12 +211,15 @@
property="ThreadCount"
description="Number of active threads in the system"/>
<metric displayName="Peak Thread Count"
+ defaultOn="true"
property="PeakThreadCount"
description="Peak count of active threads in the system"/>
<metric displayName="Total Started Thread Count"
+ defaultOn="true"
property="TotalStartedThreadCount"
description="Count of threads started since system start"/>
<metric displayName="Daemon Thread Count"
+ defaultOn="true"
property="DaemonThreadCount"
description="Count of threads marked as daemons in the system"/>
<metric property="SuspendedThreadCount"
@@ -237,13 +241,14 @@
<plugin-configuration>
<c:simple-property name="objectName" readOnly="true" default="java.lang:type=Memory"/>
- <c:simple-property name="nameTemplate" readOnly="true" default="Memory Subsystem"/>
+ <c:simple-property name="nameTemplate" default="Memory Subsystem"/>
</plugin-configuration>
<operation name="gc" displayName="Run Garbage Collection" description="Runs the garbage collector."/>
<metric displayName="Heap Usage"
property="{HeapMemoryUsage.used}"
+ displayType="summary"
description="Current heap memory usage"
units="bytes"/>
<metric displayName="Heap Committed"
@@ -253,6 +258,7 @@
units="bytes"/>
<metric displayName="Non-Heap Usage"
property="{NonHeapMemoryUsage.used}"
+ displayType="summary"
description="Current memory usage outside the heap"
units="bytes"/>
<metric displayName="Non-Heap Committed"
@@ -297,9 +303,9 @@
<plugin-configuration>
<c:simple-property name="objectName" readOnly="true" default="java.lang:type=MemoryPool,name=%name%"/>
- <c:simple-property name="nameTemplate" readOnly="true" default="{name}"/>
- <c:simple-property name="descriptionTemplate" readOnly="true" default="The {name} memory pool for this VM."/>
- <c:simple-property name="name" type="string" readOnly="true" description="The memory pool's name"/>
+ <c:simple-property name="nameTemplate" default="{name}"/>
+ <c:simple-property name="descriptionTemplate" default="The {name} memory pool for this VM."/>
+ <c:simple-property name="name" type="string" description="The memory pool's name"/>
</plugin-configuration>
<metric displayName="Used"
@@ -340,9 +346,9 @@
<plugin-configuration>
<c:simple-property name="objectName" readOnly="true" default="java.lang:type=GarbageCollector,name=%name%"/>
- <c:simple-property name="nameTemplate" readOnly="true" default="{name}"/>
- <c:simple-property name="descriptionTemplate" readOnly="true" default="The {name} Garbage Collector for this VM."/>
- <c:simple-property name="name" type="string" readOnly="true" description="The garbage collector's name"/>
+ <c:simple-property name="nameTemplate" default="{name}"/>
+ <c:simple-property name="descriptionTemplate" default="The {name} Garbage Collector for this VM."/>
+ <c:simple-property name="name" type="string" description="The garbage collector's name"/>
</plugin-configuration>
<metric property="CollectionCount"
@@ -369,7 +375,7 @@
<plugin-configuration>
<c:simple-property name="objectName" readOnly="true" default="java.lang:type=Compilation"/>
- <c:simple-property name="nameTemplate" readOnly="true" default="Compilation"/>
+ <c:simple-property name="nameTemplate" default="Compilation"/>
</plugin-configuration>
<metric property="TotalCompilationTime"
@@ -385,7 +391,7 @@
<plugin-configuration>
<c:simple-property name="objectName" readOnly="true" default="java.lang:type=ClassLoading"/>
- <c:simple-property name="nameTemplate" readOnly="true" default="Class Loading"/>
+ <c:simple-property name="nameTemplate" default="Class Loading"/>
</plugin-configuration>
<metric displayName="Loaded Classes"
@@ -413,7 +419,7 @@
<plugin-configuration>
<c:simple-property name="objectName" readOnly="true" default="java.util.logging:type=Logging"/>
- <c:simple-property name="nameTemplate" readOnly="true" default="Logging"/>
+ <c:simple-property name="nameTemplate" default="Logging"/>
<c:simple-property name="configManagementEnabled" type="boolean" default="false" description="When false, configuration reading for this resource will fail."/>
</plugin-configuration>
12 years, 7 months
[rhq] Branch 'release_jon3.x' - 2 commits - modules/core modules/enterprise
by John Sanda
modules/core/dbutils/pom.xml | 2
modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml | 1
modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml | 10 ++
modules/core/domain/src/main/java/org/rhq/core/domain/drift/DriftComplianceStatus.java | 37 ++++++++++
modules/core/domain/src/main/java/org/rhq/core/domain/drift/DriftDefinition.java | 12 +++
modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java | 2
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftDefinitionDataSource.java | 25 ++++++
modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties | 3
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerBean.java | 37 +++++++++-
9 files changed, 126 insertions(+), 3 deletions(-)
New commits:
commit cac994d7f026b03df8c8abf3b8209157489af7f7
Author: John Sanda <jsanda(a)redhat.com>
Date: Fri Nov 4 17:41:17 2011 -0400
[BZ 7517474] Adding compliance field to drift definitions view
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/drift/DriftComplianceStatus.java b/modules/core/domain/src/main/java/org/rhq/core/domain/drift/DriftComplianceStatus.java
index bc12b24..8cf1d61 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/drift/DriftComplianceStatus.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/drift/DriftComplianceStatus.java
@@ -25,4 +25,13 @@ public enum DriftComplianceStatus {
OUT_OF_COMPLIANCE_NO_BASEDIR,
OUT_OF_COMPLIANCE_DRIFT;
+
+ public static DriftComplianceStatus fromCode(int code) {
+ switch (code) {
+ case 0: return IN_COMPLIANCE;
+ case 1: return OUT_OF_COMPLIANCE_NO_BASEDIR;
+ case 2: return OUT_OF_COMPLIANCE_DRIFT;
+ default: throw new IllegalArgumentException(code + " is not a DriftComplianceStatus code");
+ }
+ }
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftDefinitionDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftDefinitionDataSource.java
index 3bb7161..e740da5 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftDefinitionDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftDefinitionDataSource.java
@@ -39,6 +39,7 @@ import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
import org.rhq.core.domain.common.EntityContext;
import org.rhq.core.domain.criteria.DriftDefinitionCriteria;
import org.rhq.core.domain.drift.DriftChangeSet;
+import org.rhq.core.domain.drift.DriftComplianceStatus;
import org.rhq.core.domain.drift.DriftDefinition;
import org.rhq.core.domain.drift.DriftDefinitionComposite;
import org.rhq.core.domain.drift.DriftConfigurationDefinition.DriftHandlingMode;
@@ -73,6 +74,8 @@ public class DriftDefinitionDataSource extends RPCDataSource<DriftDefinitionComp
public static final String ATTR_IS_PINNED = "isPinned";
public static final String ATTR_CHANGE_SET_CTIME = "changesetTime";
public static final String ATTR_CHANGE_SET_VERSION = "changesetVersion";
+ public static final String ATTR_COMPLIANCE = "compliance";
+ public static final String ATTR_COMPLIANCE_ICON = "complianceIcon";
public static final String DRIFT_HANDLING_MODE_NORMAL = MSG.view_drift_table_driftHandlingMode_normal();
public static final String DRIFT_HANDLING_MODE_PLANNED = MSG.view_drift_table_driftHandlingMode_plannedChanges();
@@ -144,6 +147,24 @@ public class DriftDefinitionDataSource extends RPCDataSource<DriftDefinitionComp
enabledField.setAlign(Alignment.CENTER);
fields.add(enabledField);
+ ListGridField inComplianceField = new ListGridField(ATTR_COMPLIANCE_ICON, MSG.common_title_in_compliance());
+ inComplianceField.setType(ListGridFieldType.IMAGE);
+ inComplianceField.setAlign(Alignment.CENTER);
+ inComplianceField.setShowHover(true);
+ inComplianceField.setHoverCustomizer(new HoverCustomizer() {
+ @Override
+ public String hoverHTML(Object o, ListGridRecord record, int row, int column) {
+ int complianceCode = record.getAttributeAsInt(ATTR_COMPLIANCE);
+ DriftComplianceStatus complianceStatus = DriftComplianceStatus.fromCode(complianceCode);
+ switch (complianceStatus) {
+ case OUT_OF_COMPLIANCE_NO_BASEDIR: return MSG.view_drift_table_out_of_compliance_no_basedir();
+ case OUT_OF_COMPLIANCE_DRIFT: return MSG.view_drift_table_out_of_compliance_drift();
+ default: return "";
+ }
+ }
+ });
+ fields.add(inComplianceField);
+
ListGridField driftHandlingModeField = new ListGridField(ATTR_DRIFT_HANDLING_MODE, MSG
.view_drift_table_driftHandlingMode());
fields.add(driftHandlingModeField);
@@ -218,6 +239,7 @@ public class DriftDefinitionDataSource extends RPCDataSource<DriftDefinitionComp
changeSetField.setWidth(70);
changeSetTimeField.setWidth(100);
enabledField.setWidth(60);
+ inComplianceField.setWidth(60);
driftHandlingModeField.setWidth("15%");
intervalField.setWidth(70);
baseDirField.setWidth("*");
@@ -336,6 +358,9 @@ public class DriftDefinitionDataSource extends RPCDataSource<DriftDefinitionComp
record.setAttribute(ATTR_BASE_DIR_STRING, getBaseDirString(def.getBasedir()));
record.setAttribute(ATTR_IS_ENABLED, String.valueOf(def.isEnabled()));
record.setAttribute(ATTR_IS_ENABLED_ICON, ImageManager.getAvailabilityIcon(def.isEnabled()));
+ record.setAttribute(ATTR_COMPLIANCE, def.getComplianceStatus().ordinal());
+ record.setAttribute(ATTR_COMPLIANCE_ICON, ImageManager.getAvailabilityIcon(
+ def.getComplianceStatus() == DriftComplianceStatus.IN_COMPLIANCE));
// fixed value, just the edit icon
record.setAttribute(ATTR_EDIT, ImageManager.getEditIcon());
record.setAttribute(ATTR_IS_PINNED, def.isPinned() ? ImageManager.getPinnedIcon() : ImageManager
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties
index 32db3fc..da21776 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties
@@ -138,6 +138,7 @@ common_title_duration = Duration
common_title_edit = Edit?
common_title_edit_mode = Edit Mode
common_title_enabled = Enabled?
+common_title_in_compliance = In Compliance?
common_title_end = End
common_title_generalProp = General Properties
common_title_group = Group
@@ -1202,6 +1203,8 @@ view_drift_table_baseDir = Base Directory
view_drift_table_driftHandlingMode = Drift Handling
view_drift_table_driftHandlingMode_normal = normal
view_drift_table_driftHandlingMode_plannedChanges = planned changes
+view_drift_table_out_of_compliance_drift = There is drift
+view_drift_table_out_of_compliance_no_basedir = The base directory does not exist
view_drift_table_hover_defNotPinned = The drift definition is not pinned Click to view the initial snapshot.
view_drift_table_hover_defPinned = The drift definition is pinned to its initial snapshot. Click to view the initial snapshot.
view_drift_table_hover_edit = Click to view or edit the drift definition or template properties.
commit f88649eec05ffa86504264df237756bf4000cf05
Author: John Sanda <jsanda(a)redhat.com>
Date: Fri Nov 4 16:36:02 2011 -0400
[BZ 7517474] Initial support for tracking compliance
This commit adds a complianceStatus field to DriftDefinition. There are
corresponding dbsetup and dbupgrade changes. DriftManagerBean has been
updated to set the complianceStatus field if the definition is pinned
when the agent reports a change set.
diff --git a/modules/core/dbutils/pom.xml b/modules/core/dbutils/pom.xml
index 28aacea..1602109 100644
--- a/modules/core/dbutils/pom.xml
+++ b/modules/core/dbutils/pom.xml
@@ -16,7 +16,7 @@
</scm>
<properties>
<scm.module.path>modules/core/dbutils/</scm.module.path>
- <db.schema.version>2.114</db.schema.version>
+ <db.schema.version>2.115</db.schema.version>
<rhq.ds.type-mapping>${rhq.test.ds.type-mapping}</rhq.ds.type-mapping>
<rhq.ds.db-name>${rhq.test.ds.db-name}</rhq.ds.db-name>
<rhq.ds.connection-url>${rhq.test.ds.connection-url}</rhq.ds.connection-url>
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml b/modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml
index d6975d5..7986a51 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml
@@ -702,6 +702,7 @@
<column name="DRIFT_HANDLING_MODE" type="VARCHAR2" size="20" required="true"/>
<column name="IS_PINNED" type="BOOLEAN" required="true"/>
<column name="IS_ATTACHED" type="BOOLEAN" required="true"/>
+ <column name="COMPLIANCE_STATUS" type="INTEGER" required="true"/>
</table>
<table name="RHQ_DRIFT_SET">
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 9221532..c7edf53 100644
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@ -3684,6 +3684,16 @@
</schema-directSQL>
</schemaSpec>
+ <schemaSpec version="2.115">
+ <schema-addColumn table="RHQ_DRIFT_DEFINITION" column="COMPLIANCE_STATUS" columnType="INTEGER"/>
+ <schema-directSQL>
+ <statement desc="RHQ_DRIFT_DEFINITION: set compliance_status column for existing definitions">
+ UPDATE RHQ_DRIFT_DEFINITION SET COMPLIANCE_STATUS = 0
+ </statement>
+ </schema-directSQL>
+ <schema-alterColumn table="RHQ_DRIFT_DEFINITION" column="COMPLIANCE_STATUS" nullable="FALSE"/>
+ </schemaSpec>
+
</dbupgrade>
</target>
</project>
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/drift/DriftComplianceStatus.java b/modules/core/domain/src/main/java/org/rhq/core/domain/drift/DriftComplianceStatus.java
new file mode 100644
index 0000000..bc12b24
--- /dev/null
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/drift/DriftComplianceStatus.java
@@ -0,0 +1,28 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2011 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.domain.drift;
+
+public enum DriftComplianceStatus {
+ IN_COMPLIANCE,
+
+ OUT_OF_COMPLIANCE_NO_BASEDIR,
+
+ OUT_OF_COMPLIANCE_DRIFT;
+}
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/drift/DriftDefinition.java b/modules/core/domain/src/main/java/org/rhq/core/domain/drift/DriftDefinition.java
index efb9ac2..08f2f3f 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/drift/DriftDefinition.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/drift/DriftDefinition.java
@@ -111,6 +111,10 @@ public class DriftDefinition implements Serializable {
@Column(name = "IS_ATTACHED", nullable = false)
private boolean attached = true;
+ @Column(name = "COMPLIANCE_STATUS", nullable = false)
+ @Enumerated(EnumType.ORDINAL)
+ private DriftComplianceStatus complianceStatus = DriftComplianceStatus.IN_COMPLIANCE;
+
// required for jaxb/web services stuff
protected DriftDefinition() {
}
@@ -259,6 +263,14 @@ public class DriftDefinition implements Serializable {
this.template = template;
}
+ public DriftComplianceStatus getComplianceStatus() {
+ return complianceStatus;
+ }
+
+ public void setComplianceStatus(DriftComplianceStatus complianceStatus) {
+ this.complianceStatus = complianceStatus;
+ }
+
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
index 09bedef..95f0090 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
@@ -268,7 +268,7 @@ public class DriftDetector implements Runnable {
// the current snapshot to match the pinned snapshot. Note though
// that we increment the snapshot version in order to let the server
// know about the state change.
- if (schedule.getDriftDefinition().isPinned()) {
+ if (schedule.getDriftDefinition().isPinned() && newVersion > 1) {
currentSnapshot.delete();
File newSnapshot = updateCurrentSnapshot(schedule, snapshotEntries, newVersion);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerBean.java
index 2fb8d51..bb67fa8 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerBean.java
@@ -22,6 +22,8 @@ import static java.util.Arrays.asList;
import static javax.ejb.TransactionAttributeType.NOT_SUPPORTED;
import static javax.ejb.TransactionAttributeType.REQUIRES_NEW;
import static org.rhq.core.domain.drift.DriftChangeSetCategory.COVERAGE;
+import static org.rhq.core.domain.drift.DriftComplianceStatus.OUT_OF_COMPLIANCE_DRIFT;
+import static org.rhq.core.domain.drift.DriftComplianceStatus.IN_COMPLIANCE;
import java.io.File;
import java.io.InputStream;
@@ -516,16 +518,49 @@ public class DriftManagerBean implements DriftManagerLocal, DriftManagerRemote {
}
@Override
- @TransactionAttribute(NOT_SUPPORTED)
+ @TransactionAttribute(REQUIRES_NEW)
public DriftChangeSetSummary saveChangeSet(Subject subject, int resourceId, File changeSetZip) throws Exception {
DriftServerPluginFacet driftServerPlugin = getServerPlugin();
DriftChangeSetSummary summary = driftServerPlugin.saveChangeSet(subject, resourceId, changeSetZip);
+
if (DriftHandlingMode.plannedChanges != summary.getDriftHandlingMode()) {
notifyAlertConditionCacheManager("saveChangeSet", summary);
}
+
+ DriftDefinitionCriteria criteria = new DriftDefinitionCriteria();
+ criteria.addFilterName(summary.getDriftDefinitionName());
+ criteria.addFilterResourceIds(resourceId);
+ PageList<DriftDefinition> definitions = findDriftDefinitionsByCriteria(subject, criteria);
+
+ if (definitions.isEmpty()) {
+ log.warn("Could not find drift definition for [resourceId: " + resourceId + ", driftDefinitionName: " +
+ summary.getDriftDefinitionName() + "]. Will not be able check compliance for thiis drift definition");
+ } else {
+ updateCompliance(definitions.get(0), summary);
+ }
+
return summary;
}
+ private void updateCompliance(DriftDefinition definition, DriftChangeSetSummary changeSetSummary) {
+ if (!definition.isPinned()) {
+ return;
+ }
+
+ boolean updateNeeded = false;
+ if (changeSetSummary.getDriftPathnames().isEmpty()) {
+ updateNeeded = definition.getComplianceStatus() != IN_COMPLIANCE;
+ definition.setComplianceStatus(IN_COMPLIANCE);
+ } else {
+ updateNeeded = definition.getComplianceStatus() == IN_COMPLIANCE;
+ definition.setComplianceStatus(OUT_OF_COMPLIANCE_DRIFT);
+ }
+
+ if (updateNeeded) {
+ updateDriftDefinition(definition);
+ }
+ }
+
@Override
@TransactionAttribute(NOT_SUPPORTED)
public void saveChangeSetFiles(Subject subject, File changeSetFilesZip) throws Exception {
12 years, 7 months