[rhq] modules/core
by lkrejci
modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ResourceErrorTest.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
New commits:
commit c5e222dff6d8c10b906d04d3847a8a9e3c6941b0
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Oct 5 15:34:45 2010 +0200
fixing the compilation failure in tests
diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ResourceErrorTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ResourceErrorTest.java
index 6630d4b..8fdc2f7 100644
--- a/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ResourceErrorTest.java
+++ b/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ResourceErrorTest.java
@@ -92,7 +92,7 @@ public class ResourceErrorTest extends AbstractEJB3Test {
q.setParameter("resourceId", newResource.getId());
assert q.getResultList().size() == 2;
- q = em.createNamedQuery(ResourceError.QUERY_FIND_BY_RESOURCE_ID_AND_ERROR_TYPES);
+ q = em.createNamedQuery(ResourceError.QUERY_FIND_BY_RESOURCE_ID_AND_ERROR_TYPE);
q.setParameter("resourceId", newResource.getId());
q.setParameter("errorType", ResourceErrorType.INVALID_PLUGIN_CONFIGURATION);
assert q.getResultList().size() == 2;
@@ -129,7 +129,7 @@ public class ResourceErrorTest extends AbstractEJB3Test {
assert errors.get(0).getDetail().equals("test detail");
assert errors.get(0).getTimeOccurred() == 12345;
- q = em.createNamedQuery(ResourceError.QUERY_FIND_BY_RESOURCE_ID_AND_ERROR_TYPES);
+ q = em.createNamedQuery(ResourceError.QUERY_FIND_BY_RESOURCE_ID_AND_ERROR_TYPE);
q.setParameter("resourceId", newResource.getId());
q.setParameter("errorType", ResourceErrorType.INVALID_PLUGIN_CONFIGURATION);
errors = q.getResultList();
13 years, 7 months
[rhq] Branch 'resource-upgrade' - modules/core
by lkrejci
modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ResourceErrorTest.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
New commits:
commit c5e222dff6d8c10b906d04d3847a8a9e3c6941b0
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Oct 5 15:34:45 2010 +0200
fixing the compilation failure in tests
diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ResourceErrorTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ResourceErrorTest.java
index 6630d4b..8fdc2f7 100644
--- a/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ResourceErrorTest.java
+++ b/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ResourceErrorTest.java
@@ -92,7 +92,7 @@ public class ResourceErrorTest extends AbstractEJB3Test {
q.setParameter("resourceId", newResource.getId());
assert q.getResultList().size() == 2;
- q = em.createNamedQuery(ResourceError.QUERY_FIND_BY_RESOURCE_ID_AND_ERROR_TYPES);
+ q = em.createNamedQuery(ResourceError.QUERY_FIND_BY_RESOURCE_ID_AND_ERROR_TYPE);
q.setParameter("resourceId", newResource.getId());
q.setParameter("errorType", ResourceErrorType.INVALID_PLUGIN_CONFIGURATION);
assert q.getResultList().size() == 2;
@@ -129,7 +129,7 @@ public class ResourceErrorTest extends AbstractEJB3Test {
assert errors.get(0).getDetail().equals("test detail");
assert errors.get(0).getTimeOccurred() == 12345;
- q = em.createNamedQuery(ResourceError.QUERY_FIND_BY_RESOURCE_ID_AND_ERROR_TYPES);
+ q = em.createNamedQuery(ResourceError.QUERY_FIND_BY_RESOURCE_ID_AND_ERROR_TYPE);
q.setParameter("resourceId", newResource.getId());
q.setParameter("errorType", ResourceErrorType.INVALID_PLUGIN_CONFIGURATION);
errors = q.getResultList();
13 years, 7 months
[rhq] Branch 'perftest' - modules/enterprise modules/helpers
by Heiko W. Rupp
modules/enterprise/server/jar/pom.xml | 6
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/performance/test/AvailabilityInsertPurgeTest.java | 3
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/AbstractEJB3PerformanceTest.java | 20 +
modules/helpers/perftest-support/pom.xml | 8
modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/reporting/ExcelExporter.java | 153 ++++++++++
modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/reporting/PerformanceReportExporter.java | 36 ++
modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/testng/PerformanceReporting.java | 22 +
7 files changed, 241 insertions(+), 7 deletions(-)
New commits:
commit efcc6caf0f8bfb0c42bbafab7cec36fd76f58c9d
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Tue Oct 5 15:23:46 2010 +0200
Write performance reports to Excel files.
Needs some more work to support showing detail data.
diff --git a/modules/enterprise/server/jar/pom.xml b/modules/enterprise/server/jar/pom.xml
index 5c94154..1f05256 100644
--- a/modules/enterprise/server/jar/pom.xml
+++ b/modules/enterprise/server/jar/pom.xml
@@ -408,12 +408,6 @@
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>net.sourceforge.jexcelapi</groupId>
- <artifactId>jxl</artifactId>
- <version>2.6.8</version>
- <scope>test</scope>
- </dependency>
<dependency>
<groupId>commons-jxpath</groupId>
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/performance/test/AvailabilityInsertPurgeTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/performance/test/AvailabilityInsertPurgeTest.java
index f0d2a5d..a0d27f0 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/performance/test/AvailabilityInsertPurgeTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/performance/test/AvailabilityInsertPurgeTest.java
@@ -35,8 +35,10 @@ import org.rhq.enterprise.server.resource.ResourceManagerLocal;
import org.rhq.enterprise.server.system.SystemManagerLocal;
import org.rhq.enterprise.server.test.AbstractEJB3PerformanceTest;
import org.rhq.enterprise.server.util.LookupUtil;
+import org.rhq.helpers.perftest.support.reporting.ExcelExporter;
import org.rhq.helpers.perftest.support.testng.DatabaseSetupInterceptor;
import org.rhq.helpers.perftest.support.testng.DatabaseState;
+import org.rhq.helpers.perftest.support.testng.PerformanceReporting;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Listeners;
@@ -50,6 +52,7 @@ import org.testng.annotations.Test;
*/
@Test(groups = "PERF")
@Listeners({ DatabaseSetupInterceptor.class })
+(a)PerformanceReporting(exporter=ExcelExporter.class)
public class AvailabilityInsertPurgeTest extends AbstractEJB3PerformanceTest {
ResourceManagerLocal resourceManager;
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/AbstractEJB3PerformanceTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/AbstractEJB3PerformanceTest.java
index 057b6c7..5a79853 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/AbstractEJB3PerformanceTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/AbstractEJB3PerformanceTest.java
@@ -20,6 +20,8 @@ package org.rhq.enterprise.server.test;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.rhq.helpers.perftest.support.reporting.PerformanceReportExporter;
+import org.rhq.helpers.perftest.support.testng.PerformanceReporting;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
@@ -96,9 +98,27 @@ public class AbstractEJB3PerformanceTest extends AbstractEJB3Test {
protected void reportTimings(ITestResult result, Method meth) {
printTimings(meth.getName());
+ Class clazz = meth.getDeclaringClass();
+ PerformanceReporting pr = (PerformanceReporting) clazz.getAnnotation(PerformanceReporting.class);
+ if (pr != null) {
+ String file = pr.baseFilename();
+ Class<? extends PerformanceReportExporter> exporterClazz = pr.exporter();
+ try {
+ PerformanceReportExporter exporter = exporterClazz.newInstance();
+ exporter.setBaseFile(file);
+ exporter.export(timings,result);
+ }
+ catch (Exception e) {
+ // TODO fix this
+ e.printStackTrace();
+ }
+
+ }
+
timings.clear();
startTime.clear();
+
}
@BeforeMethod
diff --git a/modules/helpers/perftest-support/pom.xml b/modules/helpers/perftest-support/pom.xml
index b8b26af..35c1cd2 100644
--- a/modules/helpers/perftest-support/pom.xml
+++ b/modules/helpers/perftest-support/pom.xml
@@ -80,6 +80,12 @@
<type>jar</type>
<scope>compile</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.poi</groupId>
+ <artifactId>poi</artifactId>
+ <version>3.6</version>
+ </dependency>
+
</dependencies>
<build>
<plugins>
@@ -110,4 +116,4 @@
</plugins>
</build>
-</project>
\ No newline at end of file
+</project>
diff --git a/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/reporting/ExcelExporter.java b/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/reporting/ExcelExporter.java
new file mode 100644
index 0000000..aabeb23
--- /dev/null
+++ b/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/reporting/ExcelExporter.java
@@ -0,0 +1,153 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.helpers.perftest.support.reporting;
+
+import org.apache.poi.hssf.usermodel.HSSFCellStyle;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.*;
+import org.testng.ITestResult;
+
+import java.io.*;
+import java.util.Map;
+
+
+/**
+ * Export data to an excel sheet
+ *
+ * @author Heiko W. Rupp
+ */
+public class ExcelExporter implements PerformanceReportExporter {
+
+ private static final String DOT_XLS = ".xls";
+ String baseFileName ;
+
+ @Override
+ public void setBaseFile(String fileName) {
+ if (!fileName.endsWith(DOT_XLS))
+ baseFileName = fileName + DOT_XLS;
+ else
+ baseFileName = fileName;
+ }
+
+ @Override
+ public void export(Map<String, Long> timings, ITestResult result) {
+
+
+ Workbook wb;
+ InputStream inp = null;
+ CellStyle integerStyle;
+ // Check if Workbook is present - otherwise create it
+ try {
+ inp = new FileInputStream(baseFileName);
+ wb = new HSSFWorkbook(inp);
+ } catch (Exception e) {
+ wb = new HSSFWorkbook();
+ }
+ // Now write to it
+ try {
+ // Check if we have our sheet, otherwise create
+ if (wb.getNumberOfSheets()==0) {
+ wb.createSheet("Overview");
+
+ }
+ Sheet sheet = wb.getSheetAt(0);
+
+ DataFormat df = wb.createDataFormat();
+ integerStyle = wb.createCellStyle();
+ integerStyle.setDataFormat(df.getFormat("#######0"));
+
+
+ createHeaderIfNeeded(sheet);
+
+ // Test name
+ Row row = appendRow(sheet);
+ Cell cell = row.createCell(0);
+ cell.setCellType(Cell.CELL_TYPE_STRING);
+ cell.setCellValue(result.getName());
+
+ // success ?
+ cell = row.createCell(1);
+ cell.setCellType(Cell.CELL_TYPE_BOOLEAN);
+ cell.setCellValue(result.isSuccess());
+
+ // timing from TestNG
+ cell = row.createCell(2);
+ cell.setCellType(Cell.CELL_TYPE_NUMERIC);
+ cell.setCellStyle(integerStyle);
+ cell.setCellValue(result.getEndMillis()-result.getStartMillis());
+
+ // timing of our business logic
+ long time = getTotalTime(timings);
+ cell = row.createCell(3);
+ cell.setCellType(Cell.CELL_TYPE_NUMERIC);
+ cell.setCellStyle(integerStyle);
+ cell.setCellValue(time);
+
+
+ // Write the output to a file
+ FileOutputStream fileOut = new FileOutputStream(baseFileName);
+ wb.write(fileOut);
+ fileOut.close();
+ if (inp!=null)
+ inp.close();
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void createHeaderIfNeeded(Sheet sheet) {
+ Row row = sheet.getRow(0);
+ if (row==null)
+ row = sheet.createRow(0);
+ Cell cell = row.createCell(0);
+ cell.setCellValue("Name");
+ cell = row.createCell(1);
+ cell.setCellValue("Success");
+ cell = row.createCell(2);
+ cell.setCellValue("TestNG timing");
+ cell = row.createCell(3);
+ cell.setCellValue("Perf timing");
+
+ sheet.autoSizeColumn(0);
+ sheet.autoSizeColumn(2);
+ sheet.autoSizeColumn(3);
+
+ }
+
+ private long getTotalTime(Map<String, Long> timings) {
+ long summaryTime = 0L;
+ for (Map.Entry<String,Long> item : timings.entrySet()) {
+ System.out.println(":| " + item.getKey() + " => " + item.getValue());
+ summaryTime += item.getValue();
+ }
+ return summaryTime;
+ }
+
+ /**
+ * Append a row to the sheet
+ * @param sheet Sheet to append a new empty row to
+ * @return the newly created row
+ */
+ private Row appendRow(Sheet sheet) {
+ int lastRow = sheet.getLastRowNum();
+ Row ret = sheet.createRow(lastRow+1);
+ return ret;
+ }
+}
diff --git a/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/reporting/PerformanceReportExporter.java b/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/reporting/PerformanceReportExporter.java
new file mode 100644
index 0000000..537da7e
--- /dev/null
+++ b/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/reporting/PerformanceReportExporter.java
@@ -0,0 +1,36 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.helpers.perftest.support.reporting;
+
+import org.testng.ITestResult;
+
+import java.util.Map;
+
+/**
+ * Define a reporter, that can be used to export
+ * performance test results with.
+ *
+ * @author Heiko W. Rupp
+ */
+public interface PerformanceReportExporter {
+
+ public void setBaseFile(String fileName);
+
+ public void export(Map<String,Long> timings, ITestResult result);
+}
diff --git a/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/testng/PerformanceReporting.java b/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/testng/PerformanceReporting.java
new file mode 100644
index 0000000..6673d5b
--- /dev/null
+++ b/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/testng/PerformanceReporting.java
@@ -0,0 +1,22 @@
+package org.rhq.helpers.perftest.support.testng;
+
+import org.rhq.helpers.perftest.support.reporting.PerformanceReportExporter;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Define were to export performance test results to
+ *
+ * @author Heiko W. Rupp
+ */
+(a)Retention(RetentionPolicy.RUNTIME)
+(a)Target(ElementType.TYPE)
+public @interface PerformanceReporting {
+
+ String baseFilename() default "performance-report";
+
+ Class<? extends PerformanceReportExporter> exporter() ;
+}
13 years, 7 months
[rhq] 63 commits - modules/core modules/enterprise modules/plugins
by lkrejci
modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/PluginMetadataManager.java | 5
modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java | 154 +++
modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeResponse.java | 80 +
modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java | 12
modules/core/dbutils/src/main/scripts/dbsetup/sysconfig-data.xml | 3
modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceErrorType.java | 7
modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java | 121 ++
modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ResourceErrorTest.java | 4
modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeContext.java | 89 +
modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java | 45
modules/core/plugin-container/pom.xml | 146 ++
modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java | 2
modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AutoDiscoveryExecutor.java | 2
modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java | 470 +++++++--
modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/RuntimeDiscoveryExecutor.java | 7
modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginComponentFactory.java | 15
modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/DiscoverySuspendedException.java | 50 +
modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java | 267 +++++
modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/DiscoveryComponentProxyFactory.java | 10
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java | 352 +++++++
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ForwardingProxy.java | 72 +
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java | 493 ++++++++++
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java | 331 ++++++
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java | 413 ++++++++
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/DiscComponent.java | 70 +
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/ResComponent.java | 46
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/rhq-plugin.xml | 18
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseDiscoveryComponent.java | 80 +
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponent.java | 118 ++
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponentInterface.java | 36
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java | 68 +
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/NothingDiscoveringDiscoveryComponent.java | 42
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/rhq-plugin.xml | 39
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/rhq-plugin.xml | 32
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/rhq-plugin.xml | 31
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml | 32
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml | 31
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/root/rhq-plugin.xml | 25
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml | 28
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml | 25
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml | 45
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml | 43
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/DiscComponent.java | 22
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/ResComponent.java | 21
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/rhq-plugin.xml | 18
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/DiscComponent.java | 54 +
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/ResComponent.java | 21
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/rhq-plugin.xml | 18
modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java | 42
modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/i18n/AgentI18NResourceKeys.java | 3
modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/promptcmd/DiscoveryPromptCommand.java | 2
modules/enterprise/agent/src/test/java/org/rhq/enterprise/agent/PluginContainerConditionalRestart.java | 31
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java | 5
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewForm.java | 299 ++++++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java | 327 +-----
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ResourceErrorsDataSource.java | 100 ++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java | 5
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java | 9
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/config/SystemConfigForm.java | 15
modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties | 2
modules/enterprise/gui/portal-war/src/main/webapp/admin/config/GeneralPropertiesConfigForm.jsp | 104 --
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/RHQConstants.java | 3
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java | 111 ++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java | 14
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java | 8
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java | 34
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java | 13
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java | 152 +--
68 files changed, 4835 insertions(+), 557 deletions(-)
New commits:
commit 4969aa53cf7f5ff45fbb1510d2f110560f3f6a8f
Merge: 065319e... 1b86f3a...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Oct 5 14:18:01 2010 +0200
Merge branch '_resource-upgrade' into resource-upgrade
commit 1b86f3abaf44ebb4e0d62cb75a559b130500cd9f
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Oct 5 14:17:46 2010 +0200
BZ 593270 - the new style resource key for apache is <server-root>||<httpd-conf>. Implemented the ResourceUpgradeFacet to upgrade existing resources to that new format.
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
index 660f727..ca8f972 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
@@ -170,38 +170,24 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
public ResourceUpgradeReport upgrade(ResourceUpgradeContext<PlatformComponent> context) {
String inventoriedResourceKey = context.getResourceKey();
- File inventoriedResourceKeyAsPath = new File(inventoriedResourceKey);
- //the resource key we use now is a full path to the httpd.conf.
- //in the old version, it was the server root.
- //so if the inventoried resource key is a path to a file,
- //we know it's a new style resource key.
- if (inventoriedResourceKeyAsPath.isFile()) {
+ //check if the inventoried resource has the old format of the resource key.
+ //the old format was "server-root", while the new format
+ //is "server-root||httpd-conf". Checking for "||" in the resource key is therefore
+ //enough.
+ if (inventoriedResourceKey.contains("||")) {
return null;
}
+
+ //all the information we need for the new style resource key is
+ //actually present in the plugin configuration of the existing resource
+ //already, so let's just generate the new style resource key from it.
+ String resourceKey = formatResourceKey(context.getPluginConfiguration());
- Configuration pluginConfiguration = context.getPluginConfiguration();
+ ResourceUpgradeReport rep = new ResourceUpgradeReport();
+ rep.setNewResourceKey(resourceKey);
- String serverRoot = pluginConfiguration.getSimpleValue("serverRoot", null);
- String httpdConf = pluginConfiguration.getSimpleValue("configFile", null);
-
- String resourceKey = null;
-
- if (httpdConf != null) {
- File httpdConfFile = new File(httpdConf);
- if (!httpdConfFile.isAbsolute()) {
- httpdConfFile = new File(serverRoot, httpdConf);
- }
-
- resourceKey = httpdConfFile.getPath();
-
- ResourceUpgradeReport rep = new ResourceUpgradeReport();
- rep.setNewResourceKey(resourceKey);
-
- return rep;
- }
-
- return null;
+ return rep;
}
public DiscoveredResourceDetails discoverResource(Configuration pluginConfig,
@@ -256,15 +242,7 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
name = uri.getHost() + ":" + uri.getPort();
}
- String serverRoot = pluginConfig.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_SERVER_ROOT)
- .getStringValue();
-
- String key = FileUtils.getCanonicalPath(serverRoot);
-
- //BZ 612189 - reverting to the serverRoot as the resource key temporarily until we have the resource
- //upgrade functionality ready (BZ 592038). Uncommenting the line below will make the resource key totally unique
- //(see BZ 593270).
- //key += "|" + httpdConf;
+ String key = formatResourceKey(pluginConfig);
DiscoveredResourceDetails resourceDetails = new DiscoveredResourceDetails(discoveryContext.getResourceType(),
key, name, version, PRODUCT_DESCRIPTION, pluginConfig, processInfo);
@@ -455,4 +433,14 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
}
return null;
}
+
+ private static String formatResourceKey(Configuration pluginConfiguration) {
+ String serverRoot = pluginConfiguration.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_SERVER_ROOT).getStringValue();
+ String httpdConf = pluginConfiguration.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_HTTPD_CONF).getStringValue();
+
+ serverRoot = FileUtils.getCanonicalPath(serverRoot);
+ httpdConf = FileUtils.getCanonicalPath(httpdConf);
+
+ return serverRoot + "||" + httpdConf;
+ }
}
commit a0edcceda8b63f23cc6570fb1da34251f245f3c0
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Oct 5 13:35:57 2010 +0200
code formatting
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
index c305ec4..660f727 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
@@ -21,18 +21,14 @@ package org.rhq.plugins.apache;
import java.io.File;
import java.io.IOException;
import java.net.URI;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.rhq.augeas.node.AugeasNode;
-import org.rhq.augeas.tree.AugeasTree;
import org.rhq.augeas.util.Glob;
import org.rhq.augeas.util.GlobFilter;
import org.rhq.core.domain.configuration.Configuration;
@@ -45,7 +41,6 @@ import org.rhq.core.pluginapi.inventory.ManualAddFacet;
import org.rhq.core.pluginapi.inventory.ProcessScanResult;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
-import org.rhq.core.pluginapi.inventory.ManualAddFacet;
import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
import org.rhq.core.pluginapi.util.FileUtils;
@@ -58,8 +53,8 @@ import org.rhq.plugins.apache.parser.ApacheParserImpl;
import org.rhq.plugins.apache.util.ApacheBinaryInfo;
import org.rhq.plugins.apache.util.AugeasNodeValueUtil;
import org.rhq.plugins.apache.util.HttpdAddressUtility;
-import org.rhq.plugins.apache.util.OsProcessUtility;
import org.rhq.plugins.apache.util.HttpdAddressUtility.Address;
+import org.rhq.plugins.apache.util.OsProcessUtility;
import org.rhq.plugins.platform.PlatformComponent;
import org.rhq.rhqtransform.impl.PluginDescriptorBasedAugeasConfiguration;
@@ -69,13 +64,14 @@ import org.rhq.rhqtransform.impl.PluginDescriptorBasedAugeasConfiguration;
* @author Ian Springer
* @author Lukas Krejci
*/
-public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponent<PlatformComponent>, ManualAddFacet<PlatformComponent>,
- ResourceUpgradeFacet<PlatformComponent> {
+public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponent<PlatformComponent>,
+ ManualAddFacet<PlatformComponent>, ResourceUpgradeFacet<PlatformComponent> {
private static final String PRODUCT_DESCRIPTION = "Apache Web Server";
private static final Log log = LogFactory.getLog(ApacheServerDiscoveryComponent.class);
- public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext<PlatformComponent> discoveryContext) throws Exception {
+ public Set<DiscoveredResourceDetails>
+ discoverResources(ResourceDiscoveryContext<PlatformComponent> discoveryContext) throws Exception {
Set<DiscoveredResourceDetails> discoveredResources = new HashSet<DiscoveredResourceDetails>();
// Process any PC-discovered OS processes...
@@ -89,16 +85,16 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
continue;
}
if (!executablePath.isAbsolute()) {
- log.error("Executable path (" + executablePath + ") is not absolute for Apache [" +
- process.getProcessInfo() + "]." +
- "Please restart Apache specifying an absolute path for the executable.");
+ log.error("Executable path (" + executablePath + ") is not absolute for Apache ["
+ + process.getProcessInfo() + "]."
+ + "Please restart Apache specifying an absolute path for the executable.");
continue;
}
log.debug("Apache executable path: " + executablePath);
ApacheBinaryInfo binaryInfo;
try {
- binaryInfo = ApacheBinaryInfo.getInfo(executablePath.getPath(),
- discoveryContext.getSystemInformation());
+ binaryInfo = ApacheBinaryInfo
+ .getInfo(executablePath.getPath(), discoveryContext.getSystemInformation());
} catch (Exception e) {
log.error("'" + executablePath + "' is not a valid Apache executable (" + e + ").");
continue;
@@ -130,38 +126,40 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
PropertySimple configFile = new PropertySimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_HTTPD_CONF,
serverConfigFile);
pluginConfig.put(configFile);
-
- PropertySimple inclusionGlobs = new PropertySimple(PluginDescriptorBasedAugeasConfiguration.INCLUDE_GLOBS_PROP, serverConfigFile);
+
+ PropertySimple inclusionGlobs = new PropertySimple(
+ PluginDescriptorBasedAugeasConfiguration.INCLUDE_GLOBS_PROP, serverConfigFile);
pluginConfig.put(inclusionGlobs);
-
- ApacheDirectiveTree serverConfig = loadParser(serverConfigFile.getAbsolutePath(),serverRoot);
-
+
+ ApacheDirectiveTree serverConfig = loadParser(serverConfigFile.getAbsolutePath(), serverRoot);
+
String serverUrl = null;
String vhostsGlobInclude = null;
-
+
//now check if the httpd.conf doesn't redefine the ServerRoot
List<ApacheDirective> serverRoots = serverConfig.search("/ServerRoot");
if (!serverRoots.isEmpty()) {
serverRoot = AugeasNodeValueUtil.unescape(serverRoots.get(0).getValuesAsString());
serverRootProp.setValue(serverRoot);
- }
+ }
+
+ serverUrl = getUrl(serverConfig, binaryInfo.getVersion());
+ vhostsGlobInclude = scanForGlobInclude(serverConfig);
- serverUrl = getUrl(serverConfig, binaryInfo.getVersion());
- vhostsGlobInclude = scanForGlobInclude(serverConfig);
-
if (serverUrl != null) {
Property urlProp = new PropertySimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_URL, serverUrl);
- pluginConfig.put(urlProp);
+ pluginConfig.put(urlProp);
}
-
+
if (vhostsGlobInclude != null) {
- pluginConfig.put(new PropertySimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_VHOST_FILES_MASK, vhostsGlobInclude));
- }else
- {
+ pluginConfig.put(new PropertySimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_VHOST_FILES_MASK,
+ vhostsGlobInclude));
+ } else {
if (serverConfigFile.exists())
- pluginConfig.put(new PropertySimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_VHOST_FILES_MASK, serverConfigFile.getParent()+File.separator+"*"));
+ pluginConfig.put(new PropertySimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_VHOST_FILES_MASK,
+ serverConfigFile.getParent() + File.separator + "*"));
}
-
+
discoveredResources.add(createResourceDetails(discoveryContext, pluginConfig, process.getProcessInfo(),
binaryInfo));
}
@@ -202,18 +200,16 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
return rep;
}
-
+
return null;
}
public DiscoveredResourceDetails discoverResource(Configuration pluginConfig,
- ResourceDiscoveryContext<PlatformComponent> discoveryContext)
- throws InvalidPluginConfigurationException {
+ ResourceDiscoveryContext<PlatformComponent> discoveryContext) throws InvalidPluginConfigurationException {
validateServerRootAndServerConfigFile(pluginConfig);
- String executablePath = pluginConfig
- .getSimpleValue(ApacheServerComponent.PLUGIN_CONFIG_PROP_EXECUTABLE_PATH,
- ApacheServerComponent.DEFAULT_EXECUTABLE_PATH);
+ String executablePath = pluginConfig.getSimpleValue(ApacheServerComponent.PLUGIN_CONFIG_PROP_EXECUTABLE_PATH,
+ ApacheServerComponent.DEFAULT_EXECUTABLE_PATH);
String absoluteExecutablePath = ApacheServerComponent.resolvePathRelativeToServerRoot(pluginConfig,
executablePath).getPath();
ApacheBinaryInfo binaryInfo;
@@ -222,13 +218,12 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
} catch (Exception e) {
throw new InvalidPluginConfigurationException("'" + absoluteExecutablePath
+ "' is not a valid Apache executable (" + e + "). Please make sure the '"
- + ApacheServerComponent.PLUGIN_CONFIG_PROP_EXECUTABLE_PATH
- + "' connection property is set correctly.");
+ + ApacheServerComponent.PLUGIN_CONFIG_PROP_EXECUTABLE_PATH + "' connection property is set correctly.");
}
if (!isSupportedVersion(binaryInfo.getVersion())) {
- throw new InvalidPluginConfigurationException("Version of Apache executable ("
- + binaryInfo.getVersion() + ") is not a supported version; supported versions are 1.3.x and 2.x.");
+ throw new InvalidPluginConfigurationException("Version of Apache executable (" + binaryInfo.getVersion()
+ + ") is not a supported version; supported versions are 1.3.x and 2.x.");
}
ProcessInfo processInfo = null;
@@ -236,8 +231,7 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
DiscoveredResourceDetails resourceDetails = createResourceDetails(discoveryContext, pluginConfig,
processInfo, binaryInfo);
return resourceDetails;
- }
- catch (Exception e) {
+ } catch (Exception e) {
throw new RuntimeException("Failed to create resource details during manual add.");
}
}
@@ -247,8 +241,9 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
return (version != null) && (version.startsWith("1.3") || version.startsWith("2."));
}
- private DiscoveredResourceDetails createResourceDetails(ResourceDiscoveryContext<PlatformComponent> discoveryContext,
- Configuration pluginConfig, ProcessInfo processInfo, ApacheBinaryInfo binaryInfo) throws Exception {
+ private DiscoveredResourceDetails createResourceDetails(
+ ResourceDiscoveryContext<PlatformComponent> discoveryContext, Configuration pluginConfig,
+ ProcessInfo processInfo, ApacheBinaryInfo binaryInfo) throws Exception {
String httpdConf = pluginConfig.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_HTTPD_CONF).getStringValue();
String version = binaryInfo.getVersion();
String serverUrl = pluginConfig.getSimpleValue(ApacheServerComponent.PLUGIN_CONFIG_PROP_URL, null);
@@ -258,19 +253,19 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
name = httpdConf;
} else {
URI uri = new URI(serverUrl);
- name = uri.getHost() + ":" + uri.getPort();
+ name = uri.getHost() + ":" + uri.getPort();
}
String serverRoot = pluginConfig.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_SERVER_ROOT)
.getStringValue();
-
+
String key = FileUtils.getCanonicalPath(serverRoot);
//BZ 612189 - reverting to the serverRoot as the resource key temporarily until we have the resource
//upgrade functionality ready (BZ 592038). Uncommenting the line below will make the resource key totally unique
//(see BZ 593270).
//key += "|" + httpdConf;
-
+
DiscoveredResourceDetails resourceDetails = new DiscoveredResourceDetails(discoveryContext.getResourceType(),
key, name, version, PRODUCT_DESCRIPTION, pluginConfig, processInfo);
log.debug("Apache Server resource details created: " + resourceDetails);
@@ -290,7 +285,6 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
return addr == null ? null : "http://" + addr.host + ":" + addr.port + "/";
}
-
@Nullable
private String getServerRoot(@NotNull ApacheBinaryInfo binaryInfo, @NotNull ProcessInfo processInfo) {
// First see if -d was specified on the httpd command line.
@@ -315,12 +309,12 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
currentWorkingDir = processInfo.getCurrentWorkingDirectory();
} catch (Exception e) {
log.error("Unable to determine current working directory of Apache process [" + processInfo
- + "], which is needed to determine the server root of the Apache instance.", e);
+ + "], which is needed to determine the server root of the Apache instance.", e);
return null;
}
if (currentWorkingDir == null) {
log.error("Unable to determine current working directory of Apache process [" + processInfo
- + "], which is needed to determine the server root of the Apache instance.");
+ + "], which is needed to determine the server root of the Apache instance.");
return null;
} else {
rootFile = new File(currentWorkingDir, root);
@@ -396,12 +390,12 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
}
private static void validateServerRootAndServerConfigFile(Configuration pluginConfig) {
- String serverRoot = pluginConfig.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_SERVER_ROOT).getStringValue();
+ String serverRoot = pluginConfig.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_SERVER_ROOT)
+ .getStringValue();
File serverRootFile;
try {
serverRootFile = new File(serverRoot).getCanonicalFile(); // this will resolve symlinks
- }
- catch (IOException e) {
+ } catch (IOException e) {
serverRootFile = null;
}
if (serverRootFile == null || !serverRootFile.isDirectory()) {
@@ -413,8 +407,7 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
File httpdConfFile;
try {
httpdConfFile = new File(httpdConf).getCanonicalFile(); // this will resolve symlinks
- }
- catch (IOException e) {
+ } catch (IOException e) {
httpdConfFile = null;
}
if (httpdConfFile == null || !httpdConfFile.isFile()) {
@@ -423,15 +416,15 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
+ ApacheServerComponent.PLUGIN_CONFIG_PROP_HTTPD_CONF + "' connection property is set correctly.");
}
}
-
- private static ApacheDirectiveTree loadParser(String path,String serverRoot) throws Exception{
+
+ private static ApacheDirectiveTree loadParser(String path, String serverRoot) throws Exception {
ApacheDirectiveTree tree = new ApacheDirectiveTree();
- ApacheParser parser = new ApacheParserImpl(tree,serverRoot);
+ ApacheParser parser = new ApacheParserImpl(tree, serverRoot);
ApacheConfigReader.buildTree(path, parser);
return tree;
}
-
+
public static String scanForGlobInclude(ApacheDirectiveTree tree) {
try {
List<ApacheDirective> includes = tree.search("/Include");
@@ -440,9 +433,9 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
if (Glob.isWildcard(include)) {
//we only take the '*.something' into account here
//so that we have a useful mask to base the file names on.
-
+
//the only special glob character allowed is *.
- for(char specialChar : GlobFilter.WILDCARD_CHARS) {
+ for (char specialChar : GlobFilter.WILDCARD_CHARS) {
if (specialChar == '*') {
if (include.indexOf(specialChar) != include.lastIndexOf(specialChar)) {
//more than 1 star... that's too much
@@ -462,4 +455,4 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
}
return null;
}
-}
\ No newline at end of file
+}
commit 065319e2048376d93509e31dd526789b26947b4f
Merge: 98a4d17... 297cc73...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Oct 5 12:49:38 2010 +0200
Merge branch 'master' into resource-upgrade
commit 98a4d17665d0fed83e0fd2c28770545178b00150
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Oct 5 12:48:12 2010 +0200
making the getResourcesWithType(ResourceType, Set<Resource>) private again.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index c5004dd..351f751 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -1668,7 +1668,7 @@ public class InventoryManager extends AgentService implements ContainerService,
return getResourcesWithType(serverType, this.platform.getChildResources());
}
- public Set<Resource> getResourcesWithType(ResourceType serverType, Set<Resource> resources) {
+ private Set<Resource> getResourcesWithType(ResourceType serverType, Set<Resource> resources) {
Set<Resource> servers = new HashSet<Resource>();
if (resources == null) {
commit 98ab21b9a9348520b30fae149d67d39af7553373
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Oct 4 18:58:14 2010 +0200
Getting the InventoryManager.handleReport(InventoryReport) inline with the version in master, updating the upgrade tests to accommodate for the changed behavior.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index ec40b0c..c5004dd 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -932,30 +932,16 @@ public class InventoryManager extends AgentService implements ContainerService,
}
/**
- * @see #handleReport(InventoryReport, boolean)
- * @param report
- * @return
- */
- public boolean handleReport(InventoryReport report) {
- return handleReport(report, false);
- }
-
- /**
* Send an inventory report to the Server.
*
* @param report the inventory report to be sent
- * @param forceServerRoundtrip whether to report to the server even if there are no resources to report.
* @return true if sending the report to the Server succeeded, or false otherwise
*/
- public boolean handleReport(InventoryReport report, boolean forceServerRoundtrip) {
+ public boolean handleReport(InventoryReport report) {
if (!configuration.isInsideAgent()) {
return true;
}
- if (report.getAddedRoots().isEmpty() && !forceServerRoundtrip) {
- return true; // nothing to do
- }
-
ResourceSyncInfo syncInfo;
try {
String reportType = (report.isRuntimeReport()) ? "runtime" : "server";
@@ -2659,7 +2645,7 @@ public class InventoryManager extends AgentService implements ContainerService,
log.debug("Executing resource upgrade.");
- boolean syncResult = handleReport(new InventoryReport(getAgent()), true);
+ boolean syncResult = handleReport(new InventoryReport(getAgent()));
if (!syncResult) {
log.warn("Resource upgrade failed to sync up the inventory with the server.");
return;
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
index ebb73be..ab1cd2b 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
@@ -342,10 +342,6 @@ public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase
expectations.allowing(getCurrentDiscoveryServerService()).upgradeResources(
expectations.with(Expectations.any(Set.class)));
expectations.will(getCurrentServerSideInventory().upgradeResources());
-
- expectations.allowing(getCurrentDiscoveryServerService()).postProcessNewlyCommittedResources(
- expectations.with(Expectations.any(Set.class)));
-
} catch (InvalidInventoryReportException e) {
//this is not going to happen because we're mocking the invocation
}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 8b966c3..e2a8a84 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -93,7 +93,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
{
defineDefaultExpectations(this);
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ allowing(getCurrentDiscoveryServerService()).mergeInventoryReport(
with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
@@ -144,7 +144,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
{
defineDefaultExpectations(this);
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ allowing(getCurrentDiscoveryServerService()).mergeInventoryReport(
with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
@@ -197,7 +197,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
//the rest of the inventory merges are executed by discoveries, so let's import the
//discovered stuff into the server-side inventory.
- between(1, 3).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ allowing(getCurrentDiscoveryServerService()).mergeInventoryReport(
with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
@@ -242,7 +242,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
{
defineDefaultExpectations(this);
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ allowing(getCurrentDiscoveryServerService()).mergeInventoryReport(
with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
@@ -276,7 +276,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
{
defineDefaultExpectations(this);
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ allowing(getCurrentDiscoveryServerService()).mergeInventoryReport(
with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(requiredInventoryStatus));
}
@@ -317,7 +317,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
{
defineDefaultExpectations(this);
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ allowing(getCurrentDiscoveryServerService()).mergeInventoryReport(
with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
index 0aefafd..c299cce 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
@@ -402,6 +402,9 @@ public abstract class ResourceUpgradeTestBase {
expectations.allowing(getCurrentDiscoveryServerService()).getResources(
expectations.with(Expectations.any(Set.class)), expectations.with(Expectations.any(boolean.class)));
expectations.will(getCurrentServerSideInventory().getResources());
+
+ expectations.allowing(getCurrentDiscoveryServerService()).postProcessNewlyCommittedResources(
+ expectations.with(Expectations.any(Set.class)));
}
protected void cleanDataDir() throws IOException {
commit 65c3b23735a092f9675cb2e878b79039b5ab9c93
Merge: e7fb6ed... ebd4ec6...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Oct 4 18:37:55 2010 +0200
Merge branch 'master' into resource-upgrade
diff --cc modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
index 150a692,4e14b75..a004680
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
@@@ -238,11 -274,11 +275,15 @@@ public class ResourceGWTServiceImpl ext
}
public void unignoreResources(Integer[] resourceIds) {
- discoveryBoss.unignoreResources(getSessionSubject(), resourceIds);
+ try {
+ discoveryBoss.unignoreResources(getSessionSubject(), resourceIds);
+ } catch (Exception e) {
+ throw new RuntimeException(ThrowableUtil.getAllMessages(e));
+ }
}
-
-}
+
+ public List<ResourceError> findResourceErrors(int resourceId) {
+ return SerialUtility.prepare(resourceManager.findResourceErrors(getSessionSubject(), resourceId),
+ "ResourceService.getResourceErrors");
+ }
+}
commit e7fb6edacd4c172a236cfc39b19096f03cef85ee
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Oct 4 18:34:25 2010 +0200
Discovery now recurses to child resource types of the existing resources even if the discovery of the existing resources' type is disallowed due to upgrade failure.
This means that no new siblings will be discovered but the existing resources "contents" will be up-to-date with the plugin version.
Added tests for this behaviour and updated the existing to reflect the changes.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 99a0513..ec40b0c 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -91,6 +91,7 @@ import org.rhq.core.pc.plugin.BlacklistedException;
import org.rhq.core.pc.plugin.CanonicalResourceKey;
import org.rhq.core.pc.plugin.PluginComponentFactory;
import org.rhq.core.pc.plugin.PluginManager;
+import org.rhq.core.pc.upgrade.DiscoverySuspendedException;
import org.rhq.core.pc.upgrade.ResourceUpgradeDelegate;
import org.rhq.core.pc.util.DiscoveryComponentProxyFactory;
import org.rhq.core.pc.util.FacetLockType;
@@ -289,18 +290,22 @@ public class InventoryManager extends AgentService implements ContainerService,
* @param context the context for use by the discovery component
* @return the details of all discovered resources, may be empty or <code>null</code>
*
+ * @throws DiscoverySuspendedException if the discovery is suspended due to a resource upgrade failure
* @throws Exception if the discovery component threw an exception
*/
public Set<DiscoveredResourceDetails> invokeDiscoveryComponent(ResourceContainer parentResourceContainer,
- ResourceDiscoveryComponent component, ResourceDiscoveryContext context) throws Exception {
+ ResourceDiscoveryComponent component, ResourceDiscoveryContext context) throws DiscoverySuspendedException, Exception {
Resource parentResource = parentResourceContainer == null ? null : parentResourceContainer.getResource();
if (resourceUpgradeDelegate.hasUpgradeFailedInChildren(parentResource, context.getResourceType())) {
- log.debug("Discovery of [" + context.getResourceType() + "] has been disallowed under "
- + (parentResource == null ? " the platform " : parentResource)
- + " because some of its siblings failed to upgrade.");
- return null;
+ String message = "Discovery of [" + context.getResourceType() + "] has been suspended under "
+ + (parentResource == null ? " the platform " : parentResource)
+ + " because some of its siblings failed to upgrade.";
+
+ log.debug(message);
+
+ throw new DiscoverySuspendedException(message);
}
long timeout = getDiscoveryComponentTimeout(context.getResourceType());
@@ -699,19 +704,29 @@ public class InventoryManager extends AgentService implements ContainerService,
// Ask the plugin's discovery component to find the new resource, throwing exceptions if it cannot be
// found at all.
- Set<DiscoveredResourceDetails> discoveredResources = invokeDiscoveryComponent(parentResourceContainer,
- discoveryComponent, discoveryContext);
- if ((discoveredResources == null) || discoveredResources.isEmpty()) {
- log.info("Plugin Error: During manual add, discovery component method ["
- + discoveryComponent.getClass().getName() + ".discoverResources()] returned "
- + discoveredResources + " when passed a single plugin configuration "
- + "(either the resource type was blacklisted or the plugin developer "
- + "did not implement support for manually discovered resources correctly).");
- throw new PluginContainerException("The [" + resourceType.getPlugin()
- + "] plugin does not properly support manual addition of [" + resourceType.getName()
- + "] resources.");
+ try {
+ Set<DiscoveredResourceDetails> discoveredResources = invokeDiscoveryComponent(parentResourceContainer,
+ discoveryComponent, discoveryContext);
+ if ((discoveredResources == null) || discoveredResources.isEmpty()) {
+ log.info("Plugin Error: During manual add, discovery component method ["
+ + discoveryComponent.getClass().getName() + ".discoverResources()] returned "
+ + discoveredResources + " when passed a single plugin configuration "
+ + "(either the resource type was blacklisted or the plugin developer "
+ + "did not implement support for manually discovered resources correctly).");
+ throw new PluginContainerException("The [" + resourceType.getPlugin()
+ + "] plugin does not properly support manual addition of [" + resourceType.getName()
+ + "] resources.");
+ }
+ discoveredResourceDetails = discoveredResources.iterator().next();
+ } catch (DiscoverySuspendedException e) {
+ String message = "The discovery class [" + discoveryComponent.getClass().getName() + "]" +
+ " uses a legacy implementation of \"manual add\" functionality. Some of the child resources" +
+ " with the resource type [" + resourceType + "] under the parent resource [" + parentResourceContainer.getResource() + "]" +
+ " failed to upgrade, which makes it impossible to support the legacy manual-add implementation. Either upgrade the plugin [" +
+ resourceType.getPlugin() + "] to successfully upgrade all resources or consider implementing the ManuallAdd facet.";
+ log.info(message);
+ throw new PluginContainerException(message, e);
}
- discoveredResourceDetails = discoveredResources.iterator().next();
}
// Create the new Resource and add it to inventory if it isn't already there.
@@ -1844,6 +1859,8 @@ public class InventoryManager extends AgentService implements ContainerService,
try {
discoveredResources = invokeDiscoveryComponent(null, component, context);
+ } catch (DiscoverySuspendedException e) {
+ log.error("Discovery seems to be suspended for platforms due to upgrade error.", e);
} catch (Throwable e) {
log.warn("Platform plugin discovery failed - skipping", e);
}
@@ -2179,35 +2196,47 @@ public class InventoryManager extends AgentService implements ContainerService,
parentResourceContext, SystemInfoFactory.createSystemInfo(), processScanResults,
Collections.EMPTY_LIST, this.configuration.getContainerName(),
this.configuration.getPluginContainerDeployment());
- Set<DiscoveredResourceDetails> discoveredResources = invokeDiscoveryComponent(parentContainer,
- discoveryComponent, context);
newResources = new HashSet<Resource>();
- if ((discoveredResources != null) && (!discoveredResources.isEmpty())) {
- IdentityHashMap<Configuration, DiscoveredResourceDetails> pluginConfigObjects = new IdentityHashMap<Configuration, DiscoveredResourceDetails>();
- for (DiscoveredResourceDetails discoveredResource : discoveredResources) {
- if (discoveredResource == null) {
- throw new IllegalStateException("Plugin error: Discovery class "
- + discoveryComponent.getClass().getName()
- + " returned a Set containing one or more null items.");
- }
- if (!discoveredResource.getResourceType().equals(resourceType)) {
- throw new IllegalStateException("Plugin error: Discovery class "
- + discoveryComponent.getClass().getName()
- + " returned a DiscoveredResourceDetails with an incorrect ResourceType (was "
- + discoveredResource.getResourceType().getName() + " but should have been "
- + resourceType.getName());
+ try {
+ Set<DiscoveredResourceDetails> discoveredResources = invokeDiscoveryComponent(parentContainer,
+ discoveryComponent, context);
+ if ((discoveredResources != null) && (!discoveredResources.isEmpty())) {
+ IdentityHashMap<Configuration, DiscoveredResourceDetails> pluginConfigObjects = new IdentityHashMap<Configuration, DiscoveredResourceDetails>();
+ for (DiscoveredResourceDetails discoveredResource : discoveredResources) {
+ if (discoveredResource == null) {
+ throw new IllegalStateException("Plugin error: Discovery class "
+ + discoveryComponent.getClass().getName()
+ + " returned a Set containing one or more null items.");
+ }
+ if (!discoveredResource.getResourceType().equals(resourceType)) {
+ throw new IllegalStateException("Plugin error: Discovery class "
+ + discoveryComponent.getClass().getName()
+ + " returned a DiscoveredResourceDetails with an incorrect ResourceType (was "
+ + discoveredResource.getResourceType().getName() + " but should have been "
+ + resourceType.getName());
+ }
+ if (null != pluginConfigObjects
+ .put(discoveredResource.getPluginConfiguration(), discoveredResource)) {
+ throw new IllegalStateException("The plugin component "
+ + discoveryComponent.getClass().getName()
+ + " returned multiple resources that point to the same plugin configuration object on the "
+ + "resource type [" + resourceType + "]. This is not allowed, please use "
+ + "ResoureDiscoveryContext.getDefaultPluginConfiguration() "
+ + "for each discovered resource.");
+ }
+ Resource newResource = InventoryManager.createNewResource(discoveredResource);
+ newResources.add(newResource);
}
- if (null != pluginConfigObjects
- .put(discoveredResource.getPluginConfiguration(), discoveredResource)) {
- throw new IllegalStateException("The plugin component "
- + discoveryComponent.getClass().getName()
- + " returned multiple resources that point to the same plugin configuration object on the "
- + "resource type [" + resourceType + "]. This is not allowed, please use "
- + "ResoureDiscoveryContext.getDefaultPluginConfiguration() "
- + "for each discovered resource.");
+ }
+ } catch (DiscoverySuspendedException e) {
+ //ok, the discovery is suspended for this resource type under this parent.
+ //but we can continue the discovery in the child resource types of the existing resources.
+ //we can therefore pretend that the discovery returned the existing resources so that
+ //we can recurse into their children up in the call-chain.
+ for(Resource existingResource : parentResource.getChildResources()) {
+ if (resourceType.equals(existingResource.getResourceType())) {
+ newResources.add(existingResource);
}
- Resource newResource = InventoryManager.createNewResource(discoveredResource);
- newResources.add(newResource);
}
}
} catch (Throwable e) {
@@ -2654,14 +2683,14 @@ public class InventoryManager extends AgentService implements ContainerService,
if (container != null) {
if (container.getResourceComponentState() == ResourceComponentState.STARTED) {
try {
- resourceUpgradeDelegate.processAndQueue(container);
+ if (resourceUpgradeDelegate.processAndQueue(container)) {
+ for (Resource child : resource.getChildResources()) {
+ upgradeResource(child);
+ }
+ }
} catch (PluginContainerException e) {
log.error("Exception thrown while upgrading [" + resource + "].", e);
}
-
- for (Resource child : resource.getChildResources()) {
- upgradeResource(child);
- }
} else {
String message = "The resource container for resource [" + resource
+ "] wasn't started while upgrading.";
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/DiscoverySuspendedException.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/DiscoverySuspendedException.java
new file mode 100644
index 0000000..5cb695d
--- /dev/null
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/DiscoverySuspendedException.java
@@ -0,0 +1,50 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.core.pc.upgrade;
+
+import org.rhq.core.pc.inventory.InventoryManager;
+
+/**
+ * This exception is thrown from the {@link InventoryManager#invokeDiscoveryComponent(org.rhq.core.pc.inventory.ResourceContainer, org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent, org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext)} if the
+ * discovery is suspended for given resource type due to a resource upgrade failure.
+ *
+ * @author Lukas Krejci
+ */
+public class DiscoverySuspendedException extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+ public DiscoverySuspendedException() {
+ super();
+ }
+
+ public DiscoverySuspendedException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public DiscoverySuspendedException(String message) {
+ super(message);
+ }
+
+ public DiscoverySuspendedException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
index 98a897e..06d2cd0 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
@@ -26,6 +26,7 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+
import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
import org.rhq.core.domain.resource.Resource;
@@ -61,7 +62,7 @@ public class ResourceUpgradeDelegate {
private Set<Resource> failedResources = new HashSet<Resource>();
private Map<Resource, Set<ResourceType>> failedResourceTypesPerParent = new HashMap<Resource, Set<ResourceType>>();
private boolean mergeFailed;
-
+
public ResourceUpgradeDelegate(InventoryManager inventoryManager) {
this.inventoryManager = inventoryManager;
}
@@ -84,13 +85,17 @@ public class ResourceUpgradeDelegate {
/**
* Asks the resource's discovery component to upgrade the resource.
* @param resourceContainer
- * @return true if the resource was queued for upgrade, false otherwise
+ * @return true if the resource was queued for upgrade with no problems,
+ * false if there was some problem upgrading and the resource container was deactivated as
+ * a results of that.
* @throws PluginContainerException on error
*/
- public void processAndQueue(ResourceContainer resourceContainer) throws PluginContainerException {
+ public boolean processAndQueue(ResourceContainer resourceContainer) throws PluginContainerException {
if (enabled) {
- executeResourceUpgradeFacetAndStoreRequest(resourceContainer);
+ return executeResourceUpgradeFacetAndStoreRequest(resourceContainer);
}
+
+ return true;
}
/**
@@ -99,7 +104,7 @@ public class ResourceUpgradeDelegate {
public boolean hasUpgradeMergeFailed() {
return mergeFailed;
}
-
+
/**
* Tells whether given resource had a upgrade failure during the {@link #processAndQueue(ResourceContainer)} invocation.
*
@@ -109,7 +114,7 @@ public class ResourceUpgradeDelegate {
public boolean hasUpgradeFailed(Resource resource) {
return mergeFailed || failedResources.contains(resource);
}
-
+
/**
* Tells whether at least one of the children with given resource type of the given parent resource
* had an upgrade failure during {@link #processAndQueue(ResourceContainer)} invocation.
@@ -120,35 +125,35 @@ public class ResourceUpgradeDelegate {
if (mergeFailed) {
return true;
}
-
+
Set<ResourceType> failedTypes = failedResourceTypesPerParent.get(parentResource);
-
+
return failedTypes != null && failedTypes.contains(childrenResourceType);
}
-
+
public void sendRequests() throws Throwable {
if (enabled && requests.size() > 0) {
try {
inventoryManager.mergeResourcesFromUpgrade(requests);
} catch (Throwable t) {
mergeFailed = true;
-
+
//deactivate all the resources to be upgraded. We might have a problem
//because they have not been upgraded because the merge failed.
- for(ResourceUpgradeRequest request : requests) {
+ for (ResourceUpgradeRequest request : requests) {
ResourceContainer container = inventoryManager.getResourceContainer(request.getResourceId());
if (container != null) {
inventoryManager.deactivateResource(container.getResource());
}
}
-
+
throw t;
}
}
}
@SuppressWarnings("unchecked")
- private <T extends ResourceComponent> void executeResourceUpgradeFacetAndStoreRequest(
+ private <T extends ResourceComponent> boolean executeResourceUpgradeFacetAndStoreRequest(
ResourceContainer resourceContainer) throws PluginContainerException {
ResourceComponent<T> parentResourceComponent = resourceContainer.getResourceContext()
@@ -166,16 +171,16 @@ public class ResourceUpgradeDelegate {
if (!(discoveryComponent instanceof ResourceUpgradeFacet)) {
//well, there's no point in continuing if the resource doesn't support the facet
- return;
+ return true;
}
ResourceUpgradeContext<ResourceComponent<T>> upgradeContext = inventoryManager.createResourceUpgradeContext(
resource, parentResourceComponent, discoveryComponent);
ResourceUpgradeRequest request = new ResourceUpgradeRequest(resource.getId());
-
+
request.setTimestamp(System.currentTimeMillis());
-
+
ResourceUpgradeReport upgradeReport = null;
try {
upgradeReport = inventoryManager.invokeDiscoveryComponentResourceUpgradeFacet(resource.getResourceType(),
@@ -189,13 +194,13 @@ public class ResourceUpgradeDelegate {
String upgradeErrors = null;
if ((upgradeErrors = checkUpgradeValid(resource, upgradeReport)) != null) {
String errorString = "Upgrading the resource [" + resource + "] using these updates [" + upgradeReport
- + "] would render the inventory invalid because of the following reasons: " + upgradeErrors;
-
+ + "] would render the inventory invalid because of the following reasons: " + upgradeErrors;
+
log.error(errorString);
-
+
IllegalStateException ex = new IllegalStateException(errorString);
ex.fillInStackTrace();
-
+
request.setErrorProperties(ex);
} else {
request.fillInFromReport(upgradeReport);
@@ -207,20 +212,24 @@ public class ResourceUpgradeDelegate {
if (request.hasSomethingToUpgrade()) {
requests.add(request);
}
-
+
if (request.getUpgradeErrorMessage() != null) {
failedResources.add(resource);
-
+
Set<ResourceType> failedResourceTypesInParent = failedResourceTypesPerParent.get(parentResource);
if (failedResourceTypesInParent == null) {
failedResourceTypesInParent = new HashSet<ResourceType>();
failedResourceTypesPerParent.put(parentResource, failedResourceTypesInParent);
}
-
+
failedResourceTypesInParent.add(resource.getResourceType());
-
+
inventoryManager.deactivateResource(resource);
+
+ return false;
}
+
+ return true;
}
private String checkUpgradeValid(Resource resource, ResourceUpgradeReport upgradeReport) {
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
index 7eafafc..ebb73be 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
@@ -156,9 +156,9 @@ public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase
//check that the resources are upgraded
checkResourcesUpgraded(resources.get(PARENT_DEP_SIBLING_TYPE), 1);
- checkResourcesUpgraded(resources.get(PARENT_TYPE), 2);
- checkResourcesUpgraded(resources.get(SIBLING_TYPE), 30);
- checkResourcesUpgraded(resources.get(TEST_TYPE), 30);
+ checkResourcesUpgraded(resources.get(PARENT_TYPE), 3);
+ checkResourcesUpgraded(resources.get(SIBLING_TYPE), 45);
+ checkResourcesUpgraded(resources.get(TEST_TYPE), 45);
}
public Expectations getExpectations(Mockery context) throws Exception {
@@ -206,19 +206,24 @@ public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase
checkNumberOfResources(resources, ROOT_TYPE, 1);
checkNumberOfResources(resources, PARENT_DEP_TYPE, 1);
- checkNumberOfResources(resources, PARENT_TYPE, 2);
- checkResourcesUpgraded(resources.get(PARENT_TYPE), 2);
+ checkResourcesUpgraded(resources.get(PARENT_TYPE), 3);
checkResourcesUpgraded(resources.get(PARENT_DEP_SIBLING_TYPE), 1);
Resource parent0 = findResourceWithOrdinal(PARENT_TYPE, 0);
Resource parent1 = findResourceWithOrdinal(PARENT_TYPE, 1);
-
- Set<Resource> siblingsUnderParent0 = filterResources(parent0.getChildResources(), SIBLING_TYPE);
+ Resource parent2 = findResourceWithOrdinal(PARENT_TYPE, 2);
+
Set<Resource> testsUnderParent0 = filterResources(parent0.getChildResources(), TEST_TYPE);
- Set<Resource> siblingsUnderParent1 = filterResources(parent1.getChildResources(), SIBLING_TYPE);
+ Set<Resource> siblingsUnderParent0 = filterResources(parent0.getChildResources(), SIBLING_TYPE);
Set<Resource> testsUnderParent1 = filterResources(parent1.getChildResources(), TEST_TYPE);
-
+ Set<Resource> siblingsUnderParent1 = filterResources(parent1.getChildResources(), SIBLING_TYPE);
+ Set<Resource> testsUnderParent2 = filterResources(parent2.getChildResources(), TEST_TYPE);
+ Set<Resource> siblingsUnderParent2 = filterResources(parent2.getChildResources(), SIBLING_TYPE);
+
+ //first check for the successful upgrades
+ checkResourcesUpgraded(testsUnderParent2, 15);
+ checkResourcesUpgraded(siblingsUnderParent2, 15);
checkResourcesUpgraded(siblingsUnderParent0, 15);
checkResourcesUpgraded(testsUnderParent1, 15);
@@ -257,10 +262,72 @@ public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase
}
@Test
- public void testFailureOnDependencies() {
- //TODO implement
- //check that stuff works if there is an upgrade failure on some of the resources
- //in the plugin some "in the middle" of the plugin dep graph
+ public void testFailureOnDependencies() throws Exception {
+ setCurrentServerSideInventory(new FakeServerInventory());
+
+ executeTestWithPlugins(getAllDepsFor(TEST_V1_PLUGIN_NAME, PARENT_SIBLING_V1_PLUGIN_NAME),
+ new AbstractTestPayload(true, Collections.<ResType> emptyList()) {
+ public void test(Map<ResType, Set<Resource>> resourceUpgradeTestResources) {
+ //in here we set up the failures that are going to happen when
+ //the v2 plugins are run
+
+ Resource parent = findResourceWithOrdinal(PARENT_DEP_TYPE, 0);
+ assertNotNull(parent, "Failed to find the parent to setup the failures for.");
+
+ addChildrenToFail(parent, PARENT_TYPE, 0);
+ }
+
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+ }
+ };
+ }
+ });
+
+ executeTestWithPlugins(getAllDepsFor(TEST_V2_PLUGIN_NAME, PARENT_SIBLING_V2_PLUGIN_NAME),
+ new AbstractTestPayload(false, ALL_TYPES) {
+ public void test(Map<ResType, Set<Resource>> resources) {
+ checkPresenceOfResourceTypes(resources, getExpectedResourceTypes());
+
+ checkNumberOfResources(resources, ROOT_TYPE, 1);
+ checkNumberOfResources(resources, PARENT_DEP_TYPE, 1);
+ checkResourcesUpgraded(resources.get(PARENT_DEP_SIBLING_TYPE), 1);
+
+ //check that the failed resources have the error attached to them
+ //we find the resource instance from the map provided to this method
+ //because that map contains the resources as found on the server-side
+ //(i.e. they include error objects).
+ Resource parent0 = getEqualFrom(resources.get(PARENT_TYPE), findResourceWithOrdinal(PARENT_TYPE, 0));
+ Resource parent1 = getEqualFrom(resources.get(PARENT_TYPE), findResourceWithOrdinal(PARENT_TYPE, 1));
+
+ //v2 plugin discovers 3 resources but because parent0 failed to upgrade,
+ //the discovery shouldn't have occurred leaving us with the 2 already existing resources.
+ checkNumberOfResources(resources, PARENT_TYPE, 2);
+ checkResourceFailedUpgrade(parent0);
+ checkOthersUpgraded(resources.get(PARENT_TYPE), parent0);
+
+ //parent1 upgraded ok, so discovering its children should have executed.
+ //this is v2, so we should find 15 of each.
+ checkResourcesUpgraded(filterResources(parent1.getChildResources(), TEST_TYPE), 15);
+ checkResourcesUpgraded(filterResources(parent1.getChildResources(), SIBLING_TYPE), 15);
+
+ //these shouldn't have been upgraded. in v1 we had 10 resources of TEST_TYPE
+ //and 10 resources of SIBLING_TYPE and that's what we should be seeing
+ //now.
+ checkResourcesNotUpgraded(filterResources(parent0.getChildResources(), TEST_TYPE), 10);
+ checkResourcesNotUpgraded(filterResources(parent0.getChildResources(), SIBLING_TYPE), 10);
+ }
+
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+ }
+ };
+ }
+ });
}
@SuppressWarnings("unchecked")
@@ -317,6 +384,22 @@ public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase
}
}
+ private static void checkResourcesNotUpgraded(Set<Resource> resources, int expectedSize) {
+ assertEquals(resources.size(), expectedSize, "The set of resources has unexpected size.");
+ for(Resource res : resources) {
+ assertFalse(res.getResourceKey().startsWith(UPGRADED_RESOURCE_KEY_PREFIX), "Resource " + res
+ + " seems to be upgraded even though it shouldn't.");
+
+ ResourceContainer rc = PluginContainer.getInstance().getInventoryManager().getResourceContainer(res);
+
+ assertEquals(rc.getResourceComponentState(), ResourceComponentState.STOPPED,
+ "A resource that has not been upgraded due to upgrade error in parent should be stopped.");
+
+ //recurse, since the whole subtree under the failed resource should be not upgraded and stopped.
+ checkResourcesNotUpgraded(res.getChildResources(), res.getChildResources().size());
+ }
+ }
+
private static void checkResourceFailedUpgrade(Resource resource) {
assertFalse(resource.getResourceKey().startsWith(UPGRADED_RESOURCE_KEY_PREFIX), "Resource " + resource
+ " seems to be upgraded even though it shouldn't.");
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
index 3d709b0..0f6671b 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
@@ -21,7 +21,7 @@
</runs-inside>
<plugin-configuration>
- <c:simple-property name="count" default="2" />
+ <c:simple-property name="count" default="3" />
<c:simple-property name="key" default="UPGRADED-test-resource-parent-%n,parent-%p" />
</plugin-configuration>
commit 9533fc2898f18af7262f513049d7261516787f4f
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Oct 4 14:50:49 2010 +0200
Upgrade even the non-commited resources to prevent duplication of resources in the auto-discovery queue
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index c6f1169..99a0513 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -2650,11 +2650,6 @@ public class InventoryManager extends AgentService implements ContainerService,
}
private void upgradeResource(Resource resource) {
- //only process committed resources
- if (resource.getInventoryStatus() != InventoryStatus.COMMITTED) {
- return;
- }
-
ResourceContainer container = getResourceContainer(resource);
if (container != null) {
if (container.getResourceComponentState() == ResourceComponentState.STARTED) {
@@ -2668,8 +2663,17 @@ public class InventoryManager extends AgentService implements ContainerService,
upgradeResource(child);
}
} else {
- log.error("The resource container for resource [" + resource
- + "] wasn't started during upgrade. This should not happen.");
+ String message = "The resource container for resource [" + resource
+ + "] wasn't started while upgrading.";
+
+ if (resource.getChildResources().isEmpty()) {
+ log.info(message
+ + " If this is the first time the plugin container starts up and has completely empty inventory, you can ignore this message.");
+ } else {
+ log.error(message
+ + " This can potentially cause the discovery to find resources logically equivalent to already "
+ + "existing resources if the corresponding plugins support upgrade for that particular resource type.");
+ }
}
} else {
log.error("Resource container not initialized for resource [" + resource
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
index 39597ee..0dd3459 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
@@ -80,8 +80,6 @@ public class FakeServerInventory {
this.failing = failing;
}
- //need to synchronize, because resource upgrade is async and can overlap with
- //resource discovery.
public synchronized CustomAction mergeInventoryReport(final InventoryStatus requiredInventoryStatus) {
return new CustomAction("updateServerSideInventory") {
public Object invoke(Invocation invocation) throws Throwable {
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 04858c6..8b966c3 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -71,7 +71,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
}
@Test
- public void testIgnoreUncommittedResources() throws Exception {
+ public void testIncludeUncommittedResources() throws Exception {
setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.NEW);
@@ -82,11 +82,12 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
Resource discoveredResource = discoveredResources.get(SINGLETON_TYPE).iterator().next();
- assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
- assertEquals(discoveredResource.getName(), "resource-name-v1");
- assertEquals(discoveredResource.getDescription(), "resource-description-v1");
+ assertEquals(discoveredResource.getResourceKey(), "resource-key-v2");
+ assertEquals(discoveredResource.getName(), "resource-name-v2");
+ assertEquals(discoveredResource.getDescription(), "resource-description-v2");
}
+ @SuppressWarnings("unchecked")
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
@@ -95,6 +96,9 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
+
+ oneOf(getCurrentDiscoveryServerService()).upgradeResources(with(any(Set.class)));
+ will(getCurrentServerSideInventory().upgradeResources());
}
};
}
commit 8ecbe7dec08b0e2e1f86ad8e1e56efd9f651cc7e
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Oct 4 14:32:55 2010 +0200
code formatting
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index de52cd8..c6f1169 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -242,16 +242,19 @@ public class InventoryManager extends AgentService implements ContainerService,
// inside EmbJopr).
if (configuration.isInsideAgent()) {
// After an initial delay (5s by default), periodically run an availability check (every 1m by default).
- availabilityThreadPoolExecutor.scheduleWithFixedDelay(availabilityExecutor, configuration
- .getAvailabilityScanInitialDelay(), configuration.getAvailabilityScanPeriod(), TimeUnit.SECONDS);
+ availabilityThreadPoolExecutor.scheduleWithFixedDelay(availabilityExecutor,
+ configuration.getAvailabilityScanInitialDelay(), configuration.getAvailabilityScanPeriod(),
+ TimeUnit.SECONDS);
// After an initial delay (10s by default), periodically run a server discovery scan (every 15m by default).
- inventoryThreadPoolExecutor.scheduleWithFixedDelay(serverScanExecutor, configuration
- .getServerDiscoveryInitialDelay(), configuration.getServerDiscoveryPeriod(), TimeUnit.SECONDS);
+ inventoryThreadPoolExecutor.scheduleWithFixedDelay(serverScanExecutor,
+ configuration.getServerDiscoveryInitialDelay(), configuration.getServerDiscoveryPeriod(),
+ TimeUnit.SECONDS);
// After an initial delay (20s by default), periodically run a service discovery scan (every 1d by default).
- inventoryThreadPoolExecutor.scheduleWithFixedDelay(serviceScanExecutor, configuration
- .getServiceDiscoveryInitialDelay(), configuration.getServiceDiscoveryPeriod(), TimeUnit.SECONDS);
+ inventoryThreadPoolExecutor.scheduleWithFixedDelay(serviceScanExecutor,
+ configuration.getServiceDiscoveryInitialDelay(), configuration.getServiceDiscoveryPeriod(),
+ TimeUnit.SECONDS);
}
} finally {
inventoryLock.writeLock().unlock();
@@ -288,22 +291,23 @@ public class InventoryManager extends AgentService implements ContainerService,
*
* @throws Exception if the discovery component threw an exception
*/
- public Set<DiscoveredResourceDetails> invokeDiscoveryComponent(ResourceContainer parentResourceContainer, ResourceDiscoveryComponent component,
- ResourceDiscoveryContext context) throws Exception {
+ public Set<DiscoveredResourceDetails> invokeDiscoveryComponent(ResourceContainer parentResourceContainer,
+ ResourceDiscoveryComponent component, ResourceDiscoveryContext context) throws Exception {
Resource parentResource = parentResourceContainer == null ? null : parentResourceContainer.getResource();
-
+
if (resourceUpgradeDelegate.hasUpgradeFailedInChildren(parentResource, context.getResourceType())) {
- log.debug("Discovery of [" + context.getResourceType() + "] has been disallowed under " + (parentResource == null ? " the platform " : parentResource) +
- " because some of its siblings failed to upgrade.");
+ log.debug("Discovery of [" + context.getResourceType() + "] has been disallowed under "
+ + (parentResource == null ? " the platform " : parentResource)
+ + " because some of its siblings failed to upgrade.");
return null;
}
-
+
long timeout = getDiscoveryComponentTimeout(context.getResourceType());
try {
- ResourceDiscoveryComponent proxy = this.discoveryComponentProxyFactory.getDiscoveryComponentProxy(context
- .getResourceType(), component, timeout);
+ ResourceDiscoveryComponent proxy = this.discoveryComponentProxyFactory.getDiscoveryComponentProxy(
+ context.getResourceType(), component, timeout);
Set<DiscoveredResourceDetails> results = proxy.discoverResources(context);
return results;
} catch (TimeoutException te) {
@@ -335,8 +339,8 @@ public class InventoryManager extends AgentService implements ContainerService,
long timeout = getDiscoveryComponentTimeout(context.getResourceType());
try {
- ManualAddFacet proxy = this.discoveryComponentProxyFactory.getDiscoveryComponentProxy(context
- .getResourceType(), component, timeout, ManualAddFacet.class);
+ ManualAddFacet proxy = this.discoveryComponentProxyFactory.getDiscoveryComponentProxy(
+ context.getResourceType(), component, timeout, ManualAddFacet.class);
DiscoveredResourceDetails result = proxy.discoverResource(pluginConfig, context);
return result;
} catch (TimeoutException te) {
@@ -375,8 +379,8 @@ public class InventoryManager extends AgentService implements ContainerService,
component, timeout, ClassLoaderFacet.class);
ResourceDiscoveryContext discoveryContext = new ResourceDiscoveryContext(resourceType, parentComponent,
- parentResourceContext, SystemInfoFactory.createSystemInfo(), null, null, this.configuration
- .getContainerName(), this.configuration.getPluginContainerDeployment());
+ parentResourceContext, SystemInfoFactory.createSystemInfo(), null, null,
+ this.configuration.getContainerName(), this.configuration.getPluginContainerDeployment());
// Configurations are not immutable, so clone the plugin config, so the plugin will not be able to change the
// actual PC-managed plugin config.
@@ -384,8 +388,7 @@ public class InventoryManager extends AgentService implements ContainerService,
// TODO (ips): Clone the ResourceType too for the same reason.
DiscoveredResourceDetails details = new DiscoveredResourceDetails(resourceType, resource.getResourceKey(),
- resource.getName(), resource.getVersion(), resource.getDescription(), pluginConfigClone,
- null); // TODO: I have a feeling we'll need process info, how to get it??
+ resource.getName(), resource.getVersion(), resource.getDescription(), pluginConfigClone, null); // TODO: I have a feeling we'll need process info, how to get it??
List<URL> results = proxy.getAdditionalClasspathUrls(discoveryContext, details);
@@ -592,7 +595,8 @@ public class InventoryManager extends AgentService implements ContainerService,
@NotNull
// TODO (ips): Perhaps refactor this so that it shares code with AvailablityExecutor.checkInventory().
- public Availability getCurrentAvailability(Resource resource) {
+ public
+ Availability getCurrentAvailability(Resource resource) {
AvailabilityType availType = null; // i.e. UNKNOWN;
ResourceContainer resourceContainer = getResourceContainer(resource);
if (resourceContainer != null) {
@@ -665,8 +669,8 @@ public class InventoryManager extends AgentService implements ContainerService,
ResourceDiscoveryContext<ResourceComponent> discoveryContext = new ResourceDiscoveryContext<ResourceComponent>(
resourceType, parentResourceComponent, parentResourceContainer.getResourceContext(),
SystemInfoFactory.createSystemInfo(), new ArrayList<ProcessScanResult>(0),
- new ArrayList<Configuration>(0), this.configuration.getContainerName(), this.configuration
- .getPluginContainerDeployment());
+ new ArrayList<Configuration>(0), this.configuration.getContainerName(),
+ this.configuration.getPluginContainerDeployment());
// Ask the plugin's discovery component to find the new resource, throwing exceptions if it cannot be
// found at all.
@@ -695,8 +699,8 @@ public class InventoryManager extends AgentService implements ContainerService,
// Ask the plugin's discovery component to find the new resource, throwing exceptions if it cannot be
// found at all.
- Set<DiscoveredResourceDetails> discoveredResources = invokeDiscoveryComponent(parentResourceContainer, discoveryComponent,
- discoveryContext);
+ Set<DiscoveredResourceDetails> discoveredResources = invokeDiscoveryComponent(parentResourceContainer,
+ discoveryComponent, discoveryContext);
if ((discoveredResources == null) || discoveredResources.isEmpty()) {
log.info("Plugin Error: During manual add, discovery component method ["
+ discoveryComponent.getClass().getName() + ".discoverResources()] returned "
@@ -850,8 +854,7 @@ public class InventoryManager extends AgentService implements ContainerService,
if ((this.platform != null) && (this.platform.getInventoryStatus() == InventoryStatus.NEW)
&& newPlatformWasDeletedRecently) {
// let's make sure we are registered; its probable that our platform was deleted and we need to re-register
- log
- .info("No committed resources to send in our availability report - the platform/agent was deleted, let's re-register again");
+ log.info("No committed resources to send in our availability report - the platform/agent was deleted, let's re-register again");
registerWithServer();
newPlatformWasDeletedRecently = false; // we've tried to recover from our platform being deleted, let's not do it again
}
@@ -891,8 +894,8 @@ public class InventoryManager extends AgentService implements ContainerService,
log.debug("Availability report content: " + report.toString(log.isTraceEnabled()));
}
- boolean ok = configuration.getServerServices().getDiscoveryServerService().mergeAvailabilityReport(
- report);
+ boolean ok = configuration.getServerServices().getDiscoveryServerService()
+ .mergeAvailabilityReport(report);
if (!ok) {
// I guess I could immediately call executeAvailabilityScanImmediately and pass its results to
// mergeAvailabilityReport again right now, but what happens if we've queued up a bunch of
@@ -955,8 +958,7 @@ public class InventoryManager extends AgentService implements ContainerService,
if ((this.platform != null) && (this.platform.getInventoryStatus() == InventoryStatus.NEW)
&& newPlatformWasDeletedRecently) {
// let's make sure we are registered; its probable that our platform was deleted and we need to re-register
- log
- .info("The inventory report was invalid probably because the platform/Agent was deleted; let's re-register...");
+ log.info("The inventory report was invalid probably because the platform/Agent was deleted; let's re-register...");
registerWithServer();
newPlatformWasDeletedRecently = false; // we've tried to recover from our platform being deleted, let's not do it again
}
@@ -974,8 +976,8 @@ public class InventoryManager extends AgentService implements ContainerService,
if (syncInfo != null) {
synchInventory(syncInfo);
} else {
- purgeObsoleteResources(Collections.<String>emptySet());
-
+ purgeObsoleteResources(Collections.<String> emptySet());
+
//can't live without a platform, but we just deleted it. Let's rediscover it.
discoverPlatform();
}
@@ -1113,7 +1115,7 @@ public class InventoryManager extends AgentService implements ContainerService,
return;
}
boolean scan = removeResourceAndIndicateIfScanIsNeeded(resourceContainer.getResource());
-
+
//only actually schedule the scanning when we are finished with resource upgrade. The resource upgrade
//happens before any scanning infrastructure is established.
if (!resourceUpgradeDelegate.enabled() && scan) {
@@ -1152,8 +1154,8 @@ public class InventoryManager extends AgentService implements ContainerService,
parent.removeChildResource(resource);
}
- PluginContainer.getInstance().getMeasurementManager().unscheduleCollection(
- Collections.singleton(resource.getId()));
+ PluginContainer.getInstance().getMeasurementManager()
+ .unscheduleCollection(Collections.singleton(resource.getId()));
if (this.resourceContainers.remove(resource.getUuid()) == null) {
if (log.isDebugEnabled()) {
@@ -1258,8 +1260,8 @@ public class InventoryManager extends AgentService implements ContainerService,
logMessage.append("description, ");
}
- logMessage.replace(logMessage.length() - 1, logMessage.length(), "to become [").append(
- existingResource.toString()).append("]");
+ logMessage.replace(logMessage.length() - 1, logMessage.length(), "to become [")
+ .append(existingResource.toString()).append("]");
log.info(logMessage.toString());
} else {
@@ -1429,7 +1431,7 @@ public class InventoryManager extends AgentService implements ContainerService,
}
return;
}
-
+
ResourceComponent component = container.getResourceComponent();
// if the component already exists and is started, and the resource's plugin config has not changed, there is
@@ -1490,8 +1492,8 @@ public class InventoryManager extends AgentService implements ContainerService,
log.warn("Cannot give activated resource its discovery component. Cause: " + e);
}
- ConfigurationUtility.normalizeConfiguration(resource.getPluginConfiguration(), type
- .getPluginConfigurationDefinition());
+ ConfigurationUtility.normalizeConfiguration(resource.getPluginConfiguration(),
+ type.getPluginConfigurationDefinition());
ResourceComponent parentComponent = null;
if (resource.getParentResource() != null) {
@@ -1855,8 +1857,7 @@ public class InventoryManager extends AgentService implements ContainerService,
}
} else {
// This is very strange - there are no platform types - we should never be missing the built-in platform plugin.
- log
- .error("Missing platform plugin(s) - falling back to dummy platform impl; this should only occur in tests!");
+ log.error("Missing platform plugin(s) - falling back to dummy platform impl; this should only occur in tests!");
// TODO: Set sysprop (e.g. rhq.test.mode=true) in integration tests,
// and throw a runtime exception here if that sysprop is not set.
return getTestPlatform();
@@ -2049,7 +2050,7 @@ public class InventoryManager extends AgentService implements ContainerService,
public boolean hasUpgradeMergeFailed() {
return resourceUpgradeDelegate.hasUpgradeMergeFailed();
}
-
+
/**
* Always use this before accessing the event listeners because this ensures
* thread safety.
@@ -2176,9 +2177,10 @@ public class InventoryManager extends AgentService implements ContainerService,
try {
ResourceDiscoveryContext context = new ResourceDiscoveryContext(resourceType, parentComponent,
parentResourceContext, SystemInfoFactory.createSystemInfo(), processScanResults,
- Collections.EMPTY_LIST, this.configuration.getContainerName(), this.configuration
- .getPluginContainerDeployment());
- Set<DiscoveredResourceDetails> discoveredResources = invokeDiscoveryComponent(parentContainer, discoveryComponent, context);
+ Collections.EMPTY_LIST, this.configuration.getContainerName(),
+ this.configuration.getPluginContainerDeployment());
+ Set<DiscoveredResourceDetails> discoveredResources = invokeDiscoveryComponent(parentContainer,
+ discoveryComponent, context);
newResources = new HashSet<Resource>();
if ((discoveredResources != null) && (!discoveredResources.isEmpty())) {
IdentityHashMap<Configuration, DiscoveredResourceDetails> pluginConfigObjects = new IdentityHashMap<Configuration, DiscoveredResourceDetails>();
@@ -2403,8 +2405,8 @@ public class InventoryManager extends AgentService implements ContainerService,
if (log.isDebugEnabled()) {
log.debug("Merging [" + modifiedResourceIds.size() + "] modified Resources into local inventory...");
}
- Set<Resource> modifiedResources = configuration.getServerServices().getDiscoveryServerService().getResources(
- modifiedResourceIds, false);
+ Set<Resource> modifiedResources = configuration.getServerServices().getDiscoveryServerService()
+ .getResources(modifiedResourceIds, false);
syncSchedules(modifiedResources); // RHQ-792, mtime is the indicator that schedules should be sync'ed too
for (Resource modifiedResource : modifiedResources) {
mergeResource(modifiedResource);
@@ -2620,12 +2622,12 @@ public class InventoryManager extends AgentService implements ContainerService,
private void upgradeResources() {
try {
-
+
if (!configuration.isInsideAgent()) {
log.debug("Skipping resource upgrade in embedded mode.");
return;
}
-
+
log.debug("Executing resource upgrade.");
boolean syncResult = handleReport(new InventoryReport(getAgent()), true);
@@ -2635,7 +2637,7 @@ public class InventoryManager extends AgentService implements ContainerService,
}
upgradeResource(getPlatform());
-
+
log.debug("Sending the upgrade requests to the server.");
resourceUpgradeDelegate.sendRequests();
commit 9050f4bfab5114ff31e19cb9c04b2d087dba2bff
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Oct 4 14:04:52 2010 +0200
Adding the test for handling the failure to upgrade some of the resources on the leaf of the plugin dependency graph.
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ForwardingProxy.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ForwardingProxy.java
new file mode 100644
index 0000000..7c7d277
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ForwardingProxy.java
@@ -0,0 +1,72 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.core.pc.upgrade;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+/**
+ * This class provides a simple proxy that just forwards the calls to the
+ * actual object.
+ * <p>
+ * This seemingly pointless behavior is useful when dealing with the classes
+ * loaded in different classloaders.
+ * <p>
+ * The arguments passed to the method invocations of the proxy must unfortunately be "understandable"
+ * both in the "current" classloader and in the context of the classloader that loaded the target object.
+ * I don't know about a generic solution to this problem.
+ * A partial solution would be to serialize the arguments and deserialize them in the context
+ * of the target classloader but that doesn't cut it for non-serializable classes obviously.
+ *
+ * @author Lukas Krejci
+ */
+public class ForwardingProxy {
+
+ private static class ForwardingHandler implements InvocationHandler {
+ private Object target;
+
+ public ForwardingHandler(Object target) {
+ this.target = target;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ Method targetMethod = findMethodOnTarget(method);
+
+ return targetMethod.invoke(target, args);
+ }
+
+ private Method findMethodOnTarget(Method method) throws SecurityException, NoSuchMethodException {
+ Class<?>[] origParamTypes = method.getParameterTypes();
+
+ return target.getClass().getMethod(method.getName(), origParamTypes);
+ }
+ }
+
+ public static <T> T forward(Object target, Class<T> targetInterface, Class<?>... additionalInterfaces) {
+ Class<?>[] interfaces = new Class<?>[additionalInterfaces.length + 1];
+ interfaces[0] = targetInterface;
+ System.arraycopy(additionalInterfaces, 0, interfaces, 1, additionalInterfaces.length);
+
+ Object proxy = Proxy.newProxyInstance(targetInterface.getClassLoader(), interfaces, new ForwardingHandler(target));
+ return targetInterface.cast(proxy);
+ }
+}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
index 5949b76..7eafafc 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
@@ -20,14 +20,17 @@
package org.rhq.core.pc.upgrade;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -36,10 +39,20 @@ import org.jmock.Expectations;
import org.jmock.Mockery;
import org.testng.annotations.Test;
+import org.rhq.core.clientapi.agent.PluginContainerException;
+import org.rhq.core.clientapi.agent.discovery.InvalidPluginConfigurationClientException;
import org.rhq.core.clientapi.server.discovery.InvalidInventoryReportException;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceErrorType;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.pc.PluginContainer;
+import org.rhq.core.pc.inventory.InventoryManager;
+import org.rhq.core.pc.inventory.ResourceContainer;
+import org.rhq.core.pc.inventory.ResourceContainer.ResourceComponentState;
+import org.rhq.core.pc.upgrade.plugins.multi.base.BaseResourceComponentInterface;
import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
/**
@@ -76,7 +89,7 @@ public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase
private static final String TEST_V2_PLUGIN_NAME = "/resource-upgrade-test-plugin-multi-test-2.0.0.jar";
private static final String UPGRADED_RESOURCE_KEY_PREFIX = "UPGRADED";
-
+
private static final HashMap<String, List<String>> DEPS;
static {
@@ -100,9 +113,12 @@ public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase
private static final ResType SIBLING_TYPE = new ResType("TestResourceSibling", "test");
private static final ResType PARENT_TYPE = new ResType("TestResourceParent", "test");
private static final ResType PARENT_DEP_TYPE = new ResType("ParentDependency", "parentdep");
- private static final ResType PARENT_SIBLING_TYPE = new ResType("ParentDepSibling", "parentsibling");
+ private static final ResType PARENT_DEP_SIBLING_TYPE = new ResType("ParentDepSibling", "parentsibling");
private static final ResType ROOT_TYPE = new ResType("Root", "root");
+ private static List<ResType> ALL_TYPES = Arrays.asList(TEST_TYPE, SIBLING_TYPE, PARENT_TYPE, PARENT_DEP_TYPE,
+ PARENT_DEP_SIBLING_TYPE, ROOT_TYPE);
+
protected Collection<String> getRequiredPlugins() {
return Arrays.asList(BASE_PLUGIN_NAME, PARENT_DEP_V1_PLUGIN_NAME, PARENT_DEP_V2_PLUGIN_NAME,
PARENT_SIBLING_V1_PLUGIN_NAME, PARENT_SIBLING_V2_PLUGIN_NAME, ROOT_PLUGIN_NAME, SIBLING_V1_PLUGIN_NAME,
@@ -129,26 +145,20 @@ public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase
});
//now let's run with v2 plugins and check the layout of the inventory
- executeTestWithPlugins(
- getAllDepsFor(TEST_V2_PLUGIN_NAME, PARENT_SIBLING_V2_PLUGIN_NAME),
- new AbstractTestPayload(false, Arrays.asList(TEST_TYPE, SIBLING_TYPE, PARENT_TYPE, PARENT_DEP_TYPE,
- PARENT_SIBLING_TYPE, ROOT_TYPE)) {
+ executeTestWithPlugins(getAllDepsFor(TEST_V2_PLUGIN_NAME, PARENT_SIBLING_V2_PLUGIN_NAME),
+ new AbstractTestPayload(false, ALL_TYPES) {
public void test(Map<ResType, Set<Resource>> resources) {
checkPresenceOfResourceTypes(resources, getExpectedResourceTypes());
checkNumberOfResources(resources, ROOT_TYPE, 1);
checkNumberOfResources(resources, PARENT_DEP_TYPE, 1);
- checkNumberOfResources(resources, PARENT_SIBLING_TYPE, 1);
- checkNumberOfResources(resources, PARENT_TYPE, 2);
- checkNumberOfResources(resources, SIBLING_TYPE, 30);
- checkNumberOfResources(resources, TEST_TYPE, 30);
-
+
//check that the resources are upgraded
- checkResourcesUpgraded(resources.get(PARENT_SIBLING_TYPE));
- checkResourcesUpgraded(resources.get(PARENT_TYPE));
- checkResourcesUpgraded(resources.get(SIBLING_TYPE));
- checkResourcesUpgraded(resources.get(TEST_TYPE));
+ checkResourcesUpgraded(resources.get(PARENT_DEP_SIBLING_TYPE), 1);
+ checkResourcesUpgraded(resources.get(PARENT_TYPE), 2);
+ checkResourcesUpgraded(resources.get(SIBLING_TYPE), 30);
+ checkResourcesUpgraded(resources.get(TEST_TYPE), 30);
}
public Expectations getExpectations(Mockery context) throws Exception {
@@ -162,10 +172,88 @@ public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase
}
@Test
- public void testFailureOnLeaf() {
- //TODO implement
- //check that the system behaves correctly if there is an upgrade failure
- //at the leaf node of the plugin dep graph
+ public void testFailureOnLeaf() throws Exception {
+ setCurrentServerSideInventory(new FakeServerInventory());
+
+ executeTestWithPlugins(getAllDepsFor(TEST_V1_PLUGIN_NAME, PARENT_SIBLING_V1_PLUGIN_NAME),
+ new AbstractTestPayload(true, Collections.<ResType> emptyList()) {
+ public void test(Map<ResType, Set<Resource>> resourceUpgradeTestResources) {
+ //in here we set up the failures that are going to happen when
+ //the v2 plugins are run
+
+ Resource parent0 = findResourceWithOrdinal(PARENT_TYPE, 0);
+ assertNotNull(parent0, "Failed to find the parent to setup the failures for.");
+ Resource parent1 = findResourceWithOrdinal(PARENT_TYPE, 1);
+ assertNotNull(parent1, "Failed to find the parent to setup the failures for.");
+
+ addChildrenToFail(parent0, TEST_TYPE, 1, 2);
+ addChildrenToFail(parent1, SIBLING_TYPE, 1);
+ }
+
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+ }
+ };
+ }
+ });
+
+ executeTestWithPlugins(getAllDepsFor(TEST_V2_PLUGIN_NAME, PARENT_SIBLING_V2_PLUGIN_NAME),
+ new AbstractTestPayload(false, ALL_TYPES) {
+ public void test(Map<ResType, Set<Resource>> resources) {
+ checkPresenceOfResourceTypes(resources, getExpectedResourceTypes());
+
+ checkNumberOfResources(resources, ROOT_TYPE, 1);
+ checkNumberOfResources(resources, PARENT_DEP_TYPE, 1);
+ checkNumberOfResources(resources, PARENT_TYPE, 2);
+
+ checkResourcesUpgraded(resources.get(PARENT_TYPE), 2);
+ checkResourcesUpgraded(resources.get(PARENT_DEP_SIBLING_TYPE), 1);
+
+ Resource parent0 = findResourceWithOrdinal(PARENT_TYPE, 0);
+ Resource parent1 = findResourceWithOrdinal(PARENT_TYPE, 1);
+
+ Set<Resource> siblingsUnderParent0 = filterResources(parent0.getChildResources(), SIBLING_TYPE);
+ Set<Resource> testsUnderParent0 = filterResources(parent0.getChildResources(), TEST_TYPE);
+ Set<Resource> siblingsUnderParent1 = filterResources(parent1.getChildResources(), SIBLING_TYPE);
+ Set<Resource> testsUnderParent1 = filterResources(parent1.getChildResources(), TEST_TYPE);
+
+ checkResourcesUpgraded(siblingsUnderParent0, 15);
+ checkResourcesUpgraded(testsUnderParent1, 15);
+
+ //there should be no newly discovered sibling resources of the failed ones
+ assertEquals(testsUnderParent0.size(), 10);
+ assertEquals(siblingsUnderParent1.size(), 10);
+
+ //check that the failed resources have the error attached to them
+ //we find the resource instance from the map provided to this method
+ //because that map contains the resources as found on the server-side
+ //(i.e. they include error objects).
+ Resource failedTest1 = getEqualFrom(resources.get(TEST_TYPE),
+ findResourceWithOrdinal(testsUnderParent0, 1));
+ Resource failedTest2 = getEqualFrom(resources.get(TEST_TYPE),
+ findResourceWithOrdinal(testsUnderParent0, 2));
+
+ checkResourceFailedUpgrade(failedTest1);
+ checkResourceFailedUpgrade(failedTest2);
+ checkOthersUpgraded(testsUnderParent0, failedTest1, failedTest2);
+
+ Resource failedSibling = getEqualFrom(resources.get(SIBLING_TYPE),
+ findResourceWithOrdinal(siblingsUnderParent1, 1));
+
+ checkResourceFailedUpgrade(failedSibling);
+ checkOthersUpgraded(siblingsUnderParent1, failedSibling);
+ }
+
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+ }
+ };
+ }
+ });
}
@Test
@@ -180,13 +268,14 @@ public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase
protected void defineDefaultExpectations(Expectations expectations) {
super.defineDefaultExpectations(expectations);
try {
- expectations.allowing(getCurrentDiscoveryServerService())
- .mergeInventoryReport(expectations.with(Expectations.any(InventoryReport.class)));
+ expectations.allowing(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ expectations.with(Expectations.any(InventoryReport.class)));
expectations.will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
- expectations.allowing(getCurrentDiscoveryServerService()).upgradeResources(expectations.with(Expectations.any(Set.class)));
+ expectations.allowing(getCurrentDiscoveryServerService()).upgradeResources(
+ expectations.with(Expectations.any(Set.class)));
expectations.will(getCurrentServerSideInventory().upgradeResources());
-
+
expectations.allowing(getCurrentDiscoveryServerService()).postProcessNewlyCommittedResources(
expectations.with(Expectations.any(Set.class)));
@@ -214,10 +303,112 @@ public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase
private static void checkNumberOfResources(Map<ResType, Set<Resource>> resources, ResType type, int count) {
assertEquals(resources.get(type).size(), count, "Unexpected number of " + type + " discovered.");
}
-
- private static void checkResourcesUpgraded(Set<Resource> resources) {
- for(Resource res : resources) {
- assertTrue(res.getResourceKey().startsWith(UPGRADED_RESOURCE_KEY_PREFIX), "Resource " + res + " doesn't seem to be upgraded even though it should.");
+
+ private static void checkResourcesUpgraded(Set<Resource> resources, int expectedSize) {
+ assertEquals(resources.size(), expectedSize, "The set of resources has unexpected size.");
+ for (Resource res : resources) {
+ assertTrue(res.getResourceKey().startsWith(UPGRADED_RESOURCE_KEY_PREFIX), "Resource " + res
+ + " doesn't seem to be upgraded even though it should.");
+
+ ResourceContainer rc = PluginContainer.getInstance().getInventoryManager().getResourceContainer(res);
+
+ assertEquals(rc.getResourceComponentState(), ResourceComponentState.STARTED,
+ "A resource that successfully upgraded should be started.");
+ }
+ }
+
+ private static void checkResourceFailedUpgrade(Resource resource) {
+ assertFalse(resource.getResourceKey().startsWith(UPGRADED_RESOURCE_KEY_PREFIX), "Resource " + resource
+ + " seems to be upgraded even though it shouldn't.");
+ assertTrue(resource.getResourceErrors(ResourceErrorType.UPGRADE).size() == 1,
+ "The failed resource should have an error associated with it.");
+
+ ResourceContainer rc = PluginContainer.getInstance().getInventoryManager().getResourceContainer(resource);
+
+ assertEquals(rc.getResourceComponentState(), ResourceComponentState.STOPPED,
+ "A resource that failed to upgrade should be stopped.");
+ }
+
+ private static void checkOthersUpgraded(Set<Resource> resources, Resource... failedResource) {
+ Set<Resource> others = new HashSet<Resource>(resources);
+ others.removeAll(Arrays.asList(failedResource));
+ checkResourcesUpgraded(others, others.size());
+ }
+
+ private void addChildrenToFail(Resource parent, ResType childResType, int... childrenOrdinals) {
+ InventoryManager inventoryManager = PluginContainer.getInstance().getInventoryManager();
+ ResourceContainer parentContainer = inventoryManager.getResourceContainer(parent);
+ BaseResourceComponentInterface parentComponent = (BaseResourceComponentInterface) parentContainer
+ .getResourceComponent();
+
+ Map<String, Set<Integer>> childrenToFail = new HashMap<String, Set<Integer>>();
+ Set<Integer> ordinals = new HashSet<Integer>();
+ for (int i = 0; i < childrenOrdinals.length; ++i) {
+ ordinals.add(childrenOrdinals[i]);
+ }
+
+ childrenToFail.put(childResType.getResourceTypeName(), ordinals);
+
+ Configuration newPluginConfig = parentComponent.createPluginConfigurationWithMarkedFailures(childrenToFail);
+
+ try {
+ int resourceId = parent.getId();
+ inventoryManager.updatePluginConfiguration(resourceId, newPluginConfig);
+ } catch (InvalidPluginConfigurationClientException e) {
+ fail("Updating plugin configuration failed.", e);
+ } catch (PluginContainerException e) {
+ fail("Updating plugin configuration failed.", e);
+ }
+ }
+
+ private Resource findResourceWithOrdinal(ResType resType, int ordinal) {
+ ResourceType resourceType = PluginContainer.getInstance().getPluginManager().getMetadataManager()
+ .getType(resType.getResourceTypeName(), resType.getResourceTypePluginName());
+
+ InventoryManager inventoryManager = PluginContainer.getInstance().getInventoryManager();
+ Set<Resource> resources = inventoryManager.getResourcesWithType(resourceType);
+
+ return findResourceWithOrdinal(resources, ordinal);
+ }
+
+ private Resource findResourceWithOrdinal(Set<Resource> resources, int ordinal) {
+ for (Resource r : resources) {
+ Configuration pluginConfig = r.getPluginConfiguration();
+ String ordinalString = pluginConfig.getSimpleValue("ordinal", null);
+
+ if (ordinalString != null && Integer.parseInt(ordinalString) == ordinal) {
+ return r;
+ }
+ }
+
+ return null;
+ }
+
+ private Set<Resource> filterResources(Set<Resource> resources, ResType resType) {
+ Set<Resource> ret = new HashSet<Resource>(resources);
+
+ Iterator<Resource> it = ret.iterator();
+
+ while (it.hasNext()) {
+ ResourceType resourceType = it.next().getResourceType();
+
+ if (!resourceType.getName().equals(resType.getResourceTypeName())
+ || !resourceType.getPlugin().equals(resType.getResourceTypePluginName())) {
+
+ it.remove();
+ }
}
+
+ return ret;
+ }
+
+ private static <T> T getEqualFrom(Collection<? extends T> collection, T object) {
+ for (T other : collection) {
+ if (object.equals(other)) {
+ return other;
+ }
+ }
+
+ return null;
}
}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index d47d00c..04858c6 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -37,12 +37,13 @@ import java.util.Set;
import org.jmock.Expectations;
import org.jmock.Mockery;
+import org.testng.annotations.Test;
+
import org.rhq.core.clientapi.server.discovery.InventoryReport;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.pc.PluginContainer;
import org.rhq.core.pc.inventory.ResourceContainer;
-import org.testng.annotations.Test;
/**
* Test cases for resource upgrade.
@@ -55,234 +56,255 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
private static final String PLUGIN_V1_FILENAME = "/resource-upgrade-test-plugin-1.0.0.jar";
private static final String PLUGIN_V2_FILENAME = "/resource-upgrade-test-plugin-2.0.0.jar";
private static final String FAILING_PLUGIN_FILE_NAME = "/resource-upgrade-test-plugin-3.0.0.jar";
-
+
private static final String SINGLETON_RESOURCE_TYPE_NAME = "Resource";
private static final String SINGLETON_RESOURCE_TYPE_PLUGIN_NAME = "ResourceUpgradeTest";
- private static final ResType SINGLETON_TYPE = new ResType(SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME);
-
+ private static final ResType SINGLETON_TYPE = new ResType(SINGLETON_RESOURCE_TYPE_NAME,
+ SINGLETON_RESOURCE_TYPE_PLUGIN_NAME);
+
private static List<ResType> getMyExpectedTypes() {
return Arrays.asList(SINGLETON_TYPE);
}
-
+
protected Collection<String> getRequiredPlugins() {
return Arrays.asList(PLUGIN_V1_FILENAME, PLUGIN_V2_FILENAME, FAILING_PLUGIN_FILE_NAME);
}
-
+
@Test
public void testIgnoreUncommittedResources() throws Exception {
setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.NEW);
-
- TestPayload testNoChange = new AbstractTestPayload(false, getMyExpectedTypes()) {
+
+ TestPayload testNoChange = new AbstractTestPayload(false, getMyExpectedTypes()) {
public void test(Map<ResType, Set<Resource>> discoveredResources) {
- assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
-
+ assertEquals(discoveredResources.get(SINGLETON_TYPE).size(), 1,
+ "Expected single test resource but multiple found.");
+
Resource discoveredResource = discoveredResources.get(SINGLETON_TYPE).iterator().next();
assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
assertEquals(discoveredResource.getName(), "resource-name-v1");
assertEquals(discoveredResource.getDescription(), "resource-description-v1");
}
-
+
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
defineDefaultExpectations(this);
-
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+
+ between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
}
};
}
};
-
+
executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), testNoChange);
}
-
+
@Test
public void testUpgradeData() throws Exception {
setCurrentServerSideInventory(new FakeServerInventory());
upgradeTest(false);
}
-
+
@Test
public void testInventoryReinitializationFromServerDuringUpgrade() throws Exception {
setCurrentServerSideInventory(new FakeServerInventory());
upgradeTest(true);
}
-
+
@Test
public void testSkipUpgradeWhenServerUnavailable() throws Exception {
setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
-
+
getCurrentServerSideInventory().setFailing(true);
- TestPayload test = new AbstractTestPayload(false, getMyExpectedTypes()) {
+ TestPayload test = new AbstractTestPayload(false, getMyExpectedTypes()) {
public void test(Map<ResType, Set<Resource>> discoveredResources) {
- assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
-
+ assertEquals(discoveredResources.get(SINGLETON_TYPE).size(), 1,
+ "Expected single test resource but multiple found.");
+
Resource discoveredResource = discoveredResources.get(SINGLETON_TYPE).iterator().next();
-
+
assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
assertEquals(discoveredResource.getName(), "resource-name-v1");
assertEquals(discoveredResource.getDescription(), "resource-description-v1");
}
-
+
@SuppressWarnings("unchecked")
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
defineDefaultExpectations(this);
-
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+
+ between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
-
+
never(getCurrentDiscoveryServerService()).upgradeResources(with(any(Set.class)));
}
};
}
};
-
+
executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), test);
}
-
+
@Test
public void testUpgradeWithPlatformDeletedOnServer() throws Exception {
setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
-
- TestPayload test = new AbstractTestPayload(false, getMyExpectedTypes()) {
+
+ TestPayload test = new AbstractTestPayload(false, getMyExpectedTypes()) {
public void test(Map<ResType, Set<Resource>> discoveredResources) {
- assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
-
+ assertEquals(discoveredResources.get(SINGLETON_TYPE).size(), 1,
+ "Expected single test resource but multiple found.");
+
Resource discoveredResource = discoveredResources.get(SINGLETON_TYPE).iterator().next();
-
+
assertEquals(discoveredResource.getResourceKey(), "resource-key-v2");
assertEquals(discoveredResource.getName(), "resource-name-v2");
assertEquals(discoveredResource.getDescription(), "resource-description-v2");
- ResourceContainer container = PluginContainer.getInstance().getInventoryManager().getResourceContainer(discoveredResource);
+ ResourceContainer container = PluginContainer.getInstance().getInventoryManager()
+ .getResourceContainer(discoveredResource);
File dataDir = container.getResourceContext().getDataDirectory();
-
+
File marker = new File(dataDir, "upgrade-succeeded");
-
- assertFalse(marker.exists(), "The upgrade seems to have occured even though there shouldn't have been a resource to upgrade.");
+
+ assertFalse(marker.exists(),
+ "The upgrade seems to have occured even though there shouldn't have been a resource to upgrade.");
}
-
+
@SuppressWarnings("unchecked")
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
defineDefaultExpectations(this);
-
+
//the first merge will be triggered from within the upgrade process and we are
//going to report null sync.
- oneOf(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+ oneOf(getCurrentDiscoveryServerService())
+ .mergeInventoryReport(with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().clearPlatform());
-
+
//the rest of the inventory merges are executed by discoveries, so let's import the
//discovered stuff into the server-side inventory.
- between(1, 3).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+ between(1, 3).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
-
+
never(getCurrentDiscoveryServerService()).upgradeResources(with(any(Set.class)));
}
};
}
};
-
+
executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), test);
}
-
+
@Test
public void testUpgradeFailureHandling() throws Exception {
setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
-
- TestPayload test = new AbstractTestPayload(false, getMyExpectedTypes()) {
+
+ TestPayload test = new AbstractTestPayload(false, getMyExpectedTypes()) {
public void test(Map<ResType, Set<Resource>> resourceUpgradeTestResources) {
- assertEquals(resourceUpgradeTestResources.size(), 1, "Expected single test resource but multiple found.");
-
+ assertEquals(resourceUpgradeTestResources.get(SINGLETON_TYPE).size(), 1,
+ "Expected single test resource but multiple found.");
+
Resource discoveredResource = resourceUpgradeTestResources.get(SINGLETON_TYPE).iterator().next();
-
- assertTrue(discoveredResource.getResourceErrors().size() > 0, "There should be upgrade errors persisted on the server side.");
-
+
+ assertTrue(discoveredResource.getResourceErrors().size() > 0,
+ "There should be upgrade errors persisted on the server side.");
+
//the discovery of the failed resource mustn't have run
- ResourceContainer container = PluginContainer.getInstance().getInventoryManager().getResourceContainer(discoveredResource);
+ ResourceContainer container = PluginContainer.getInstance().getInventoryManager()
+ .getResourceContainer(discoveredResource);
File dataDir = container.getResourceContext().getDataDirectory();
-
+
File marker = new File(dataDir, "failing-discovery-ran");
-
- assertFalse(marker.exists(), "The discovery of the resource type with a failed upgraded resource must not be executed but it was.");
+
+ assertFalse(marker.exists(),
+ "The discovery of the resource type with a failed upgraded resource must not be executed but it was.");
}
-
+
@SuppressWarnings("unchecked")
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
defineDefaultExpectations(this);
-
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+
+ between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
-
+
oneOf(getCurrentDiscoveryServerService()).upgradeResources(with(any(Set.class)));
will(getCurrentServerSideInventory().upgradeResources());
}
};
}
};
-
+
executeTestWithPlugins(Collections.singleton(FAILING_PLUGIN_FILE_NAME), test);
}
-
+
private void initialSyncAndDiscovery(final InventoryStatus requiredInventoryStatus) throws Exception {
cleanDataDir();
- executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), new AbstractTestPayload(true, getMyExpectedTypes()) {
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), new AbstractTestPayload(true,
+ getMyExpectedTypes()) {
public void test(Map<ResType, Set<Resource>> discoveredResources) {
- assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
-
+ assertEquals(discoveredResources.get(SINGLETON_TYPE).size(), 1,
+ "Expected single test resource but multiple found.");
+
Resource discoveredResource = discoveredResources.get(SINGLETON_TYPE).iterator().next();
-
+
assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
assertEquals(discoveredResource.getName(), "resource-name-v1");
assertEquals(discoveredResource.getDescription(), "resource-description-v1");
}
-
+
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
defineDefaultExpectations(this);
-
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+
+ between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(requiredInventoryStatus));
}
};
}
- });
-
+ });
+
}
-
private void upgradeTest(boolean clearInventoryDat) throws Exception {
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
-
- executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), new AbstractTestPayload(clearInventoryDat, getMyExpectedTypes()) {
+
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), new AbstractTestPayload(clearInventoryDat,
+ getMyExpectedTypes()) {
public void test(Map<ResType, Set<Resource>> discoveredResources) {
- assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
-
+ assertEquals(discoveredResources.get(SINGLETON_TYPE).size(), 1,
+ "Expected single test resource but multiple found.");
+
Resource discoveredResource = discoveredResources.get(SINGLETON_TYPE).iterator().next();
-
+
assertEquals(discoveredResource.getResourceKey(), "resource-key-v2");
assertEquals(discoveredResource.getName(), "resource-name-v2");
assertEquals(discoveredResource.getDescription(), "resource-description-v2");
-
- ResourceContainer container = PluginContainer.getInstance().getInventoryManager().getResourceContainer(discoveredResource);
+
+ ResourceContainer container = PluginContainer.getInstance().getInventoryManager()
+ .getResourceContainer(discoveredResource);
File dataDir = container.getResourceContext().getDataDirectory();
-
+
File marker = new File(dataDir, "upgrade-succeeded");
-
- assertTrue(marker.exists(), "The upgrade success marker file wasn't found. This means the upgrade didn't actually run.");
+
+ assertTrue(marker.exists(),
+ "The upgrade success marker file wasn't found. This means the upgrade didn't actually run.");
}
@SuppressWarnings("unchecked")
@@ -290,10 +312,11 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
return new Expectations() {
{
defineDefaultExpectations(this);
-
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+
+ between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
-
+
oneOf(getCurrentDiscoveryServerService()).upgradeResources(with(any(Set.class)));
will(getCurrentServerSideInventory().upgradeResources());
}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponent.java
index c5bbf3a..04d3767 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponent.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponent.java
@@ -19,11 +19,18 @@
package org.rhq.core.pc.upgrade.plugins.multi.base;
-import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.Property;
+import org.rhq.core.domain.configuration.PropertyList;
+import org.rhq.core.domain.configuration.PropertyMap;
+import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
import org.rhq.core.pluginapi.inventory.ResourceComponent;
@@ -33,13 +40,11 @@ import org.rhq.core.pluginapi.inventory.ResourceContext;
*
* @author Lukas Krejci
*/
-public class BaseResourceComponent<T extends ResourceComponent> implements ResourceComponent<T> {
+public class BaseResourceComponent<T extends ResourceComponent> implements ResourceComponent<T>, BaseResourceComponentInterface {
private ResourceContext<T> context;
private final Log log = LogFactory.getLog(getClass());
- private Set<Integer> childrenToFailUpgrade;
-
public AvailabilityType getAvailability() {
return AvailabilityType.UP;
}
@@ -57,11 +62,57 @@ public class BaseResourceComponent<T extends ResourceComponent> implements Resou
return context.getPluginConfiguration().getSimple("ordinal").getIntegerValue();
}
- public Set<Integer> getChildrenToFailUpgrade() {
- return childrenToFailUpgrade == null ? Collections.<Integer>emptySet() : childrenToFailUpgrade;
+ public Map<String, Set<Integer>> getChildrenToFailUpgrade() {
+
+ Map<String, Set<Integer>> ret = new HashMap<String, Set<Integer>>();
+
+ Configuration pluginConfig = context.getPluginConfiguration();
+ PropertyList childrenToFail = pluginConfig.getList("childrenToFail");
+
+ if (childrenToFail != null) {
+ for(Property p : childrenToFail.getList()) {
+ PropertyMap entry = (PropertyMap) p;
+
+ String type = entry.getSimpleValue("type", null);
+
+ PropertyList typeList = entry.getList("children");
+
+ if (type != null && typeList != null) {
+ Set<Integer> ordinals = new HashSet<Integer>();
+
+ for(Property pp : typeList.getList()) {
+ ordinals.add(((PropertySimple)pp).getIntegerValue());
+ }
+
+ ret.put(type, ordinals);
+ }
+ }
+ }
+
+ return ret;
}
- public void setChildrenToFailUpgrade(Set<Integer> childrenToFailUpgrade) {
- this.childrenToFailUpgrade = childrenToFailUpgrade;
+ public Configuration createPluginConfigurationWithMarkedFailures(Map<String, Set<Integer>> childrenToFailUpgrade) {
+ Configuration ret = context.getPluginConfiguration().clone();
+ PropertyList list = new PropertyList("childrenToFail");
+
+ for(Map.Entry<String, Set<Integer>> entry : childrenToFailUpgrade.entrySet()) {
+ PropertyMap configEntry = new PropertyMap("childrenInType");
+ configEntry.put(new PropertySimple("type", entry.getKey()));
+
+ PropertyList typeList = new PropertyList("children");
+
+ for(Integer childOrdinal : entry.getValue()) {
+ typeList.add(new PropertySimple("ordinal", childOrdinal));
+ }
+
+ configEntry.put(typeList);
+
+ list.add(configEntry);
+ }
+
+ ret.put(list);
+
+ return ret;
}
}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponentInterface.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponentInterface.java
new file mode 100644
index 0000000..1c9bef0
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponentInterface.java
@@ -0,0 +1,36 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.core.pc.upgrade.plugins.multi.base;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.rhq.core.domain.configuration.Configuration;
+
+/**
+ * This is to support proxying to required methods from the tests.
+ *
+ * @author Lukas Krejci
+ */
+public interface BaseResourceComponentInterface {
+
+ Configuration createPluginConfigurationWithMarkedFailures(Map<String, Set<Integer>> childrenToFailUpgrade);
+
+}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java
index ec1cb20..5b8af94 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java
@@ -19,6 +19,8 @@
package org.rhq.core.pc.upgrade.plugins.multi.base;
+import java.util.Set;
+
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
@@ -41,7 +43,10 @@ public class BaseUpgradingDiscoveryComponent<T extends BaseResourceComponent> ex
boolean fail = Boolean.getBoolean(pluginConfig.getSimpleValue("failUpgrade", "false"));
if (!fail && parent != null) {
- fail = parent.getChildrenToFailUpgrade().contains(Integer.valueOf(ordinal));
+ String typeName = inventoriedResource.getResourceType().getName();
+ Set<Integer> failingOrdinals = parent.getChildrenToFailUpgrade().get(typeName);
+
+ fail = failingOrdinals != null && failingOrdinals.contains(Integer.valueOf(ordinal));
}
if (fail) {
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/NothingDiscoveringDiscoveryComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/NothingDiscoveringDiscoveryComponent.java
new file mode 100644
index 0000000..b6189e5
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/NothingDiscoveringDiscoveryComponent.java
@@ -0,0 +1,42 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.core.pc.upgrade.plugins.multi.base;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+
+/**
+ *
+ * @author Lukas Krejci
+ */
+public class NothingDiscoveringDiscoveryComponent<T extends ResourceComponent> implements ResourceDiscoveryComponent<T> {
+
+ public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext<T> context)
+ throws InvalidPluginConfigurationException, Exception {
+
+ return Collections.emptySet();
+ }
+}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
index d3ea7b7..e3b4f9b 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
@@ -11,7 +11,7 @@
<depends plugin="base" useClasses="true"/>
- <server name="Bogus" class="BaseDiscoveryComponent">
+ <server name="Bogus" class="BaseDiscoveryComponent" discovery="NothingDiscoveringDiscoveryComponent">
<!-- This service is put in the type hierarchy in the v1/v2 test plugins -->
<service name="TestResourceSibling"
discovery="BaseDiscoveryComponent"
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
index f7f7a2c..e7792b9 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
@@ -10,7 +10,7 @@
<depends plugin="base" useClasses="true"/>
- <server name="Bogus" class="BaseDiscoveryComponent">
+ <server name="Bogus" class="BaseDiscoveryComponent" discovery="NothingDiscoveringDiscoveryComponent">
<!-- This service is put in the type hierarchy in the v1/v2 test plugins -->
<service name="TestResourceSibling"
discovery="BaseUpgradingDiscoveryComponent"
commit e6dd8c2618a009053b06c3f63fff808fc5e64dbf
Merge: 14fd25e... 3c5a00e...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Oct 1 12:58:36 2010 +0200
Merge branch 'master' into resource-upgrade
commit 14fd25e86c1a4013c1047c343f3860720a3f9c68
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Oct 1 12:55:37 2010 +0200
Adapted the resource upgrade test infrastructure to work with the new requirements of the failure handling tests and added the first round of the failure handling tests.
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
index adb3989..39597ee 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
@@ -59,68 +59,69 @@ public class FakeServerInventory {
private Map<String, Resource> resourceStore = new HashMap<String, Resource>();
private int counter;
private boolean failing;
-
+
private static final Comparator<Resource> ID_COMPARATOR = new Comparator<Resource>() {
public int compare(Resource o1, Resource o2) {
return o1.getId() - o2.getId();
}
};
-
+
private static final Comparator<Resource> RESOURCE_TYPE_COMPARATOR = new Comparator<Resource>() {
public int compare(Resource o1, Resource o2) {
return o1.getResourceType().equals(o2.getResourceType()) ? 0 : o1.getId() - o2.getId();
}
};
-
+
public FakeServerInventory() {
this(false);
}
-
+
public FakeServerInventory(boolean failing) {
this.failing = failing;
}
-
+
//need to synchronize, because resource upgrade is async and can overlap with
//resource discovery.
public synchronized CustomAction mergeInventoryReport(final InventoryStatus requiredInventoryStatus) {
return new CustomAction("updateServerSideInventory") {
public Object invoke(Invocation invocation) throws Throwable {
throwIfFailing();
-
+
InventoryReport inventoryReport = (InventoryReport) invocation.getParameter(0);
-
- for(Resource res : inventoryReport.getAddedRoots()) {
+
+ for (Resource res : inventoryReport.getAddedRoots()) {
+ Resource persisted = fakePersist(res, requiredInventoryStatus, new HashSet<String>());
+
if (res.getParentResource() == Resource.ROOT) {
- platform = fakePersist(res, requiredInventoryStatus, new HashSet<String>());
- break;
+ platform = persisted;
}
}
return getSyncInfo();
- }
+ }
};
}
-
+
public synchronized CustomAction clearPlatform() {
return new CustomAction("updateServerSideInventory - report platform deleted on the server") {
public Object invoke(Invocation invocation) throws Throwable {
throwIfFailing();
-
+
platform = null;
-
+
return getSyncInfo();
}
};
}
-
+
public synchronized CustomAction upgradeResources() {
return new CustomAction("upgradeServerSideInventory") {
- @SuppressWarnings({"serial", "unchecked"})
+ @SuppressWarnings({ "serial", "unchecked" })
public Object invoke(Invocation invocation) throws Throwable {
throwIfFailing();
-
+
Set<ResourceUpgradeRequest> requests = (Set<ResourceUpgradeRequest>) invocation.getParameter(0);
Set<ResourceUpgradeResponse> responses = new HashSet<ResourceUpgradeResponse>();
-
+
for (final ResourceUpgradeRequest request : requests) {
Resource resource = findResource(platform, new Resource() {
public int getId() {
@@ -134,16 +135,18 @@ public class FakeServerInventory {
if (request.getNewName() != null) {
resource.setName(request.getNewName());
}
-
+
if (request.getNewResourceKey() != null) {
resource.setResourceKey(request.getNewResourceKey());
}
-
+
if (request.getUpgradeErrorMessage() != null) {
- ResourceError error = new ResourceError(resource, ResourceErrorType.UPGRADE, request.getUpgradeErrorMessage(), request.getUpgradeErrorStackTrace(), request.getTimestamp());
+ ResourceError error = new ResourceError(resource, ResourceErrorType.UPGRADE,
+ request.getUpgradeErrorMessage(), request.getUpgradeErrorStackTrace(),
+ request.getTimestamp());
resource.getResourceErrors().add(error);
}
-
+
ResourceUpgradeResponse resp = new ResourceUpgradeResponse();
resp.setResourceId(resource.getId());
resp.setUpgradedResourceName(resource.getName());
@@ -156,21 +159,21 @@ public class FakeServerInventory {
}
};
}
-
+
public synchronized CustomAction getResources() {
return new CustomAction("getResources") {
@SuppressWarnings("unchecked")
public Object invoke(Invocation invocation) throws Throwable {
throwIfFailing();
-
- Set<Integer> resourceIds = (Set<Integer>)invocation.getParameter(0);
+
+ Set<Integer> resourceIds = (Set<Integer>) invocation.getParameter(0);
boolean includeDescendants = (Boolean) invocation.getParameter(1);
-
+
return getResources(resourceIds, includeDescendants);
}
- };
+ };
}
-
+
public boolean isFailing() {
return failing;
}
@@ -191,12 +194,12 @@ public class FakeServerInventory {
}
return result;
}
-
+
@SuppressWarnings("serial")
- private Set<Resource> getResources(Set<Integer> resourceIds, boolean includeDescendants) {
+ private Set<Resource> getResources(Set<Integer> resourceIds, boolean includeDescendants) {
Set<Resource> result = new HashSet<Resource>();
-
- for(final Integer id : resourceIds) {
+
+ for (final Integer id : resourceIds) {
Resource r = findResource(platform, new Resource() {
public int getId() {
return id;
@@ -204,19 +207,20 @@ public class FakeServerInventory {
}, ID_COMPARATOR);
if (r != null) {
result.add(r);
-
+
if (includeDescendants) {
- for(Resource child : r.getChildResources()) {
+ for (Resource child : r.getChildResources()) {
result.addAll(getResources(Collections.singleton(child.getId()), true));
}
}
}
}
-
+
return result;
}
-
- private Resource fakePersist(Resource agentSideResource, InventoryStatus requiredInventoryStatus, Set<String> inProgressUUIds) {
+
+ private Resource fakePersist(Resource agentSideResource, InventoryStatus requiredInventoryStatus,
+ Set<String> inProgressUUIds) {
Resource persisted = resourceStore.get(agentSideResource.getUuid());
if (!inProgressUUIds.add(agentSideResource.getUuid())) {
return persisted;
@@ -237,94 +241,114 @@ public class FakeServerInventory {
persisted.setInventoryStatus(requiredInventoryStatus);
persisted.setResourceKey(agentSideResource.getResourceKey());
persisted.setResourceType(agentSideResource.getResourceType());
-
+
Resource parent = agentSideResource.getParentResource();
if (parent != null && parent != Resource.ROOT) {
- persisted.setParentResource(fakePersist(agentSideResource.getParentResource(), requiredInventoryStatus, inProgressUUIds));
+ persisted.setParentResource(fakePersist(agentSideResource.getParentResource(), requiredInventoryStatus,
+ inProgressUUIds));
} else {
persisted.setParentResource(parent);
}
Set<Resource> childResources = new HashSet<Resource>();
persisted.setChildResources(childResources);
- for(Resource child : agentSideResource.getChildResources()) {
+ for (Resource child : agentSideResource.getChildResources()) {
childResources.add(fakePersist(child, requiredInventoryStatus, inProgressUUIds));
}
-
+
inProgressUUIds.remove(agentSideResource.getUuid());
-
+
return persisted;
}
-
+
private ResourceSyncInfo getSyncInfo() {
return platform != null ? convert(platform) : null;
}
-
+
private void throwIfFailing() {
if (failing) {
throw new RuntimeException("Fake server inventory is in the failing mode.");
}
}
-
+
private static ResourceSyncInfo convert(Resource root) {
+ return convertInternal(root, new HashMap<String, ResourceSyncInfo>());
+ }
+
+ private static ResourceSyncInfo convertInternal(Resource root, Map<String, ResourceSyncInfo> intermediateResults) {
+ ResourceSyncInfo ret = intermediateResults.get(root.getUuid());
+
+ if (ret != null) {
+ return ret;
+ }
+
try {
- ResourceSyncInfo ret = new ResourceSyncInfo();
-
+ ret = new ResourceSyncInfo();
+
+ intermediateResults.put(root.getUuid(), ret);
+
Class<ResourceSyncInfo> clazz = ResourceSyncInfo.class;
getPrivateField(clazz, "id").set(ret, root.getId());
getPrivateField(clazz, "uuid").set(ret, root.getUuid());
getPrivateField(clazz, "mtime").set(ret, root.getMtime());
getPrivateField(clazz, "inventoryStatus").set(ret, root.getInventoryStatus());
- getPrivateField(clazz, "parent").set(ret, null);
-
+
+ ResourceSyncInfo parent = root.getParentResource() == null ? null : convertInternal(
+ root.getParentResource(), intermediateResults);
+
+ getPrivateField(clazz, "parent").set(ret, parent);
+
Set<ResourceSyncInfo> children = new LinkedHashSet<ResourceSyncInfo>();
- for(Resource child : root.getChildResources()) {
- ResourceSyncInfo syncChild = convert(child);
- getPrivateField(clazz, "parent").set(syncChild, ret);
-
- children.add(convert(child));
- }
+ for (Resource child : root.getChildResources()) {
+ ResourceSyncInfo syncChild = convertInternal(child, intermediateResults);
+
+ children.add(syncChild);
+ }
getPrivateField(clazz, "childSyncInfos").set(ret, children);
-
+
return ret;
} catch (Exception e) {
fail("Failed to convert resource " + root + " to a ResourceSyncInfo. This should not happen.", e);
return null;
}
- }
-
+ }
+
private static Field getPrivateField(Class<?> clazz, String fieldName) throws NoSuchFieldException {
Field field = clazz.getDeclaredField(fieldName);
if (!field.isAccessible()) {
field.setAccessible(true);
}
-
+
return field;
}
-
+
private static Resource findResource(Resource root, Resource template, Comparator<Resource> comparator) {
- if (root == null) return null;
+ if (root == null)
+ return null;
if (comparator.compare(root, template) == 0) {
return root;
} else {
- for(Resource child : root.getChildResources()) {
+ for (Resource child : root.getChildResources()) {
Resource found = findResource(child, template, comparator);
- if (found != null) return found;
+ if (found != null)
+ return found;
}
}
-
+
return null;
- }
-
- private static void findResources(Resource root, Resource template, Set<Resource> result, Comparator<Resource> comparator) {
- if (root == null) return;
+ }
+
+ private static void findResources(Resource root, Resource template, Set<Resource> result,
+ Comparator<Resource> comparator) {
+ if (root == null)
+ return;
if (comparator.compare(root, template) == 0) {
result.add(root);
} else {
- for(Resource child : root.getChildResources()) {
+ for (Resource child : root.getChildResources()) {
findResources(child, template, result, comparator);
}
- }
+ }
}
}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
index 25eca30..5949b76 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
@@ -19,11 +19,29 @@
package org.rhq.core.pc.upgrade;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
import org.testng.annotations.Test;
+import org.rhq.core.clientapi.server.discovery.InvalidInventoryReportException;
+import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.domain.resource.InventoryStatus;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
+
/**
* The plugins and their resource types form the following dependency structure:
* <pre>
@@ -35,6 +53,10 @@ import org.testng.annotations.Test;
* </pre>
* The dependencies in the above "chart" are formed using either the <code><runs-inside></code>
* or <code>sourcePlugin/sourceType</code> approaches just to test that both are handled correctly.
+ * <p>
+ * The <code>parentdep</code>, <code>parentsibling</code>, <code>test</code> and <code>sibling</code> plugins are present
+ * in two versions and support the {@link ResourceUpgradeFacet}, while the rest of the plugins is
+ * present only in single version.
*
* @author Lukas Krejci
*/
@@ -53,29 +75,149 @@ public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase
private static final String TEST_V1_PLUGIN_NAME = "/resource-upgrade-test-plugin-multi-test-1.0.0.jar";
private static final String TEST_V2_PLUGIN_NAME = "/resource-upgrade-test-plugin-multi-test-2.0.0.jar";
+ private static final String UPGRADED_RESOURCE_KEY_PREFIX = "UPGRADED";
+
+ private static final HashMap<String, List<String>> DEPS;
+
+ static {
+ DEPS = new HashMap<String, List<String>>();
+
+ DEPS.put(BASE_PLUGIN_NAME, Collections.<String> emptyList());
+ DEPS.put(PARENT_DEP_V1_PLUGIN_NAME, Arrays.asList(BASE_PLUGIN_NAME, ROOT_PLUGIN_NAME));
+ DEPS.put(PARENT_DEP_V2_PLUGIN_NAME, DEPS.get(PARENT_DEP_V1_PLUGIN_NAME));
+ DEPS.put(PARENT_SIBLING_V1_PLUGIN_NAME, Arrays.asList(BASE_PLUGIN_NAME, ROOT_PLUGIN_NAME));
+ DEPS.put(PARENT_SIBLING_V2_PLUGIN_NAME, DEPS.get(PARENT_SIBLING_V1_PLUGIN_NAME));
+ DEPS.put(ROOT_PLUGIN_NAME, Arrays.asList(BASE_PLUGIN_NAME));
+ DEPS.put(SIBLING_V1_PLUGIN_NAME, Arrays.asList(BASE_PLUGIN_NAME, ROOT_PLUGIN_NAME, PARENT_DEP_V1_PLUGIN_NAME));
+ DEPS.put(SIBLING_V2_PLUGIN_NAME, Arrays.asList(BASE_PLUGIN_NAME, ROOT_PLUGIN_NAME, PARENT_DEP_V2_PLUGIN_NAME));
+ DEPS.put(TEST_V1_PLUGIN_NAME,
+ Arrays.asList(BASE_PLUGIN_NAME, ROOT_PLUGIN_NAME, PARENT_DEP_V1_PLUGIN_NAME, SIBLING_V1_PLUGIN_NAME));
+ DEPS.put(TEST_V2_PLUGIN_NAME,
+ Arrays.asList(BASE_PLUGIN_NAME, ROOT_PLUGIN_NAME, PARENT_DEP_V1_PLUGIN_NAME, SIBLING_V2_PLUGIN_NAME));
+ }
+
+ private static final ResType TEST_TYPE = new ResType("TestResource", "test");
+ private static final ResType SIBLING_TYPE = new ResType("TestResourceSibling", "test");
+ private static final ResType PARENT_TYPE = new ResType("TestResourceParent", "test");
+ private static final ResType PARENT_DEP_TYPE = new ResType("ParentDependency", "parentdep");
+ private static final ResType PARENT_SIBLING_TYPE = new ResType("ParentDepSibling", "parentsibling");
+ private static final ResType ROOT_TYPE = new ResType("Root", "root");
+
protected Collection<String> getRequiredPlugins() {
return Arrays.asList(BASE_PLUGIN_NAME, PARENT_DEP_V1_PLUGIN_NAME, PARENT_DEP_V2_PLUGIN_NAME,
PARENT_SIBLING_V1_PLUGIN_NAME, PARENT_SIBLING_V2_PLUGIN_NAME, ROOT_PLUGIN_NAME, SIBLING_V1_PLUGIN_NAME,
SIBLING_V2_PLUGIN_NAME, TEST_V1_PLUGIN_NAME, TEST_V2_PLUGIN_NAME);
}
-
+
@Test
- public void testSuccess() {
- //TODO implement
- //check that all the stuff is properly upgraded on success
+ public void testSuccess() throws Exception {
+ setCurrentServerSideInventory(new FakeServerInventory());
+
+ //let it all run in v1
+ executeTestWithPlugins(getAllDepsFor(TEST_V1_PLUGIN_NAME, PARENT_SIBLING_V1_PLUGIN_NAME),
+ new AbstractTestPayload(true, Collections.<ResType> emptyList()) {
+ public void test(Map<ResType, Set<Resource>> resourceUpgradeTestResources) {
+ }
+
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+ }
+ };
+ }
+ });
+
+ //now let's run with v2 plugins and check the layout of the inventory
+ executeTestWithPlugins(
+ getAllDepsFor(TEST_V2_PLUGIN_NAME, PARENT_SIBLING_V2_PLUGIN_NAME),
+ new AbstractTestPayload(false, Arrays.asList(TEST_TYPE, SIBLING_TYPE, PARENT_TYPE, PARENT_DEP_TYPE,
+ PARENT_SIBLING_TYPE, ROOT_TYPE)) {
+
+ public void test(Map<ResType, Set<Resource>> resources) {
+ checkPresenceOfResourceTypes(resources, getExpectedResourceTypes());
+
+ checkNumberOfResources(resources, ROOT_TYPE, 1);
+ checkNumberOfResources(resources, PARENT_DEP_TYPE, 1);
+ checkNumberOfResources(resources, PARENT_SIBLING_TYPE, 1);
+ checkNumberOfResources(resources, PARENT_TYPE, 2);
+ checkNumberOfResources(resources, SIBLING_TYPE, 30);
+ checkNumberOfResources(resources, TEST_TYPE, 30);
+
+ //check that the resources are upgraded
+ checkResourcesUpgraded(resources.get(PARENT_SIBLING_TYPE));
+ checkResourcesUpgraded(resources.get(PARENT_TYPE));
+ checkResourcesUpgraded(resources.get(SIBLING_TYPE));
+ checkResourcesUpgraded(resources.get(TEST_TYPE));
+ }
+
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+ }
+ };
+ }
+ });
}
-
+
@Test
public void testFailureOnLeaf() {
//TODO implement
//check that the system behaves correctly if there is an upgrade failure
//at the leaf node of the plugin dep graph
}
-
+
@Test
public void testFailureOnDependencies() {
//TODO implement
//check that stuff works if there is an upgrade failure on some of the resources
//in the plugin some "in the middle" of the plugin dep graph
}
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void defineDefaultExpectations(Expectations expectations) {
+ super.defineDefaultExpectations(expectations);
+ try {
+ expectations.allowing(getCurrentDiscoveryServerService())
+ .mergeInventoryReport(expectations.with(Expectations.any(InventoryReport.class)));
+ expectations.will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
+
+ expectations.allowing(getCurrentDiscoveryServerService()).upgradeResources(expectations.with(Expectations.any(Set.class)));
+ expectations.will(getCurrentServerSideInventory().upgradeResources());
+
+ expectations.allowing(getCurrentDiscoveryServerService()).postProcessNewlyCommittedResources(
+ expectations.with(Expectations.any(Set.class)));
+
+ } catch (InvalidInventoryReportException e) {
+ //this is not going to happen because we're mocking the invocation
+ }
+ }
+
+ private Set<String> getAllDepsFor(String... plugins) {
+ HashSet<String> deps = new HashSet<String>();
+ for (String plugin : plugins) {
+ deps.add(plugin);
+ deps.addAll(DEPS.get(plugin));
+ }
+
+ return deps;
+ }
+
+ private static void checkPresenceOfResourceTypes(Map<ResType, Set<Resource>> resources, Set<ResType> expectedTypes) {
+ for (ResType resType : expectedTypes) {
+ assertNotNull(resources.get(resType), "Expecting some resources of type " + resType);
+ }
+ }
+
+ private static void checkNumberOfResources(Map<ResType, Set<Resource>> resources, ResType type, int count) {
+ assertEquals(resources.get(type).size(), count, "Unexpected number of " + type + " discovered.");
+ }
+
+ private static void checkResourcesUpgraded(Set<Resource> resources) {
+ for(Resource res : resources) {
+ assertTrue(res.getResourceKey().startsWith(UPGRADED_RESOURCE_KEY_PREFIX), "Resource " + res + " doesn't seem to be upgraded even though it should.");
+ }
+ }
}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 8cfec36..d47d00c 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -31,6 +31,8 @@ import java.io.File;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.jmock.Expectations;
@@ -54,8 +56,13 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
private static final String PLUGIN_V2_FILENAME = "/resource-upgrade-test-plugin-2.0.0.jar";
private static final String FAILING_PLUGIN_FILE_NAME = "/resource-upgrade-test-plugin-3.0.0.jar";
- static final String SINGLETON_RESOURCE_TYPE_NAME = "Resource";
- static final String SINGLETON_RESOURCE_TYPE_PLUGIN_NAME = "ResourceUpgradeTest";
+ private static final String SINGLETON_RESOURCE_TYPE_NAME = "Resource";
+ private static final String SINGLETON_RESOURCE_TYPE_PLUGIN_NAME = "ResourceUpgradeTest";
+ private static final ResType SINGLETON_TYPE = new ResType(SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME);
+
+ private static List<ResType> getMyExpectedTypes() {
+ return Arrays.asList(SINGLETON_TYPE);
+ }
protected Collection<String> getRequiredPlugins() {
return Arrays.asList(PLUGIN_V1_FILENAME, PLUGIN_V2_FILENAME, FAILING_PLUGIN_FILE_NAME);
@@ -66,11 +73,11 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.NEW);
- TestPayload testNoChange = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
- public void test(Set<Resource> discoveredResources) {
+ TestPayload testNoChange = new AbstractTestPayload(false, getMyExpectedTypes()) {
+ public void test(Map<ResType, Set<Resource>> discoveredResources) {
assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
- Resource discoveredResource = discoveredResources.iterator().next();
+ Resource discoveredResource = discoveredResources.get(SINGLETON_TYPE).iterator().next();
assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
assertEquals(discoveredResource.getName(), "resource-name-v1");
@@ -111,11 +118,11 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
getCurrentServerSideInventory().setFailing(true);
- TestPayload test = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
- public void test(Set<Resource> discoveredResources) {
+ TestPayload test = new AbstractTestPayload(false, getMyExpectedTypes()) {
+ public void test(Map<ResType, Set<Resource>> discoveredResources) {
assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
- Resource discoveredResource = discoveredResources.iterator().next();
+ Resource discoveredResource = discoveredResources.get(SINGLETON_TYPE).iterator().next();
assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
assertEquals(discoveredResource.getName(), "resource-name-v1");
@@ -145,11 +152,11 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
- TestPayload test = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
- public void test(Set<Resource> discoveredResources) {
+ TestPayload test = new AbstractTestPayload(false, getMyExpectedTypes()) {
+ public void test(Map<ResType, Set<Resource>> discoveredResources) {
assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
- Resource discoveredResource = discoveredResources.iterator().next();
+ Resource discoveredResource = discoveredResources.get(SINGLETON_TYPE).iterator().next();
assertEquals(discoveredResource.getResourceKey(), "resource-key-v2");
assertEquals(discoveredResource.getName(), "resource-name-v2");
@@ -193,11 +200,11 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
- TestPayload test = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
- public void test(Set<Resource> resourceUpgradeTestResources) {
+ TestPayload test = new AbstractTestPayload(false, getMyExpectedTypes()) {
+ public void test(Map<ResType, Set<Resource>> resourceUpgradeTestResources) {
assertEquals(resourceUpgradeTestResources.size(), 1, "Expected single test resource but multiple found.");
- Resource discoveredResource = resourceUpgradeTestResources.iterator().next();
+ Resource discoveredResource = resourceUpgradeTestResources.get(SINGLETON_TYPE).iterator().next();
assertTrue(discoveredResource.getResourceErrors().size() > 0, "There should be upgrade errors persisted on the server side.");
@@ -231,11 +238,11 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
private void initialSyncAndDiscovery(final InventoryStatus requiredInventoryStatus) throws Exception {
cleanDataDir();
- executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), new AbstractTestPayload(true, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
- public void test(Set<Resource> discoveredResources) {
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), new AbstractTestPayload(true, getMyExpectedTypes()) {
+ public void test(Map<ResType, Set<Resource>> discoveredResources) {
assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
- Resource discoveredResource = discoveredResources.iterator().next();
+ Resource discoveredResource = discoveredResources.get(SINGLETON_TYPE).iterator().next();
assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
assertEquals(discoveredResource.getName(), "resource-name-v1");
@@ -260,11 +267,11 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
private void upgradeTest(boolean clearInventoryDat) throws Exception {
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
- executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), new AbstractTestPayload(clearInventoryDat, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
- public void test(Set<Resource> discoveredResources) {
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), new AbstractTestPayload(clearInventoryDat, getMyExpectedTypes()) {
+ public void test(Map<ResType, Set<Resource>> discoveredResources) {
assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
- Resource discoveredResource = discoveredResources.iterator().next();
+ Resource discoveredResource = discoveredResources.get(SINGLETON_TYPE).iterator().next();
assertEquals(discoveredResource.getResourceKey(), "resource-key-v2");
assertEquals(discoveredResource.getName(), "resource-name-v2");
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
index 3aa772b..0aefafd 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
@@ -25,6 +25,9 @@ import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import org.apache.commons.io.FileUtils;
@@ -73,6 +76,78 @@ public abstract class ResourceUpgradeTestBase {
private ResourceFactoryServerService currentResourceFactoryServerService;
private FakeServerInventory currentServerSideInventory;
+ protected static class ResType {
+ private String resourceTypeName;
+ private String resourceTypePluginName;
+
+ public ResType(String resourceTypeName, String resourceTypePluginName) {
+ super();
+ this.resourceTypeName = resourceTypeName;
+ this.resourceTypePluginName = resourceTypePluginName;
+ }
+
+ public String getResourceTypeName() {
+ return resourceTypeName;
+ }
+
+ public String getResourceTypePluginName() {
+ return resourceTypePluginName;
+ }
+
+ @Override
+ public int hashCode() {
+ return resourceTypeName.hashCode() * resourceTypePluginName.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ if (!(other instanceof ResType)) {
+ return false;
+ }
+
+ ResType o = (ResType)other;
+
+ return resourceTypeName.equals(o.getResourceTypeName()) && resourceTypePluginName.equals(o.getResourceTypePluginName());
+ }
+
+ @Override
+ public String toString() {
+ return "ResType[name='" + resourceTypeName + "', plugin='" + resourceTypePluginName + "']";
+ }
+ }
+
+ protected interface TestPayload {
+ Expectations getExpectations(Mockery context) throws Exception;
+
+ void test(Map<ResType,Set<Resource>> resourceUpgradeTestResources);
+
+ boolean isClearInventoryDat();
+
+ Set<ResType> getExpectedResourceTypes();
+ }
+
+ protected static abstract class AbstractTestPayload implements TestPayload {
+ private boolean clearInventoryDat;
+ private Set<ResType> resourceTypes;
+
+ public AbstractTestPayload(boolean clearInventoryDat, Collection<ResType> resourceTypes) {
+ this.clearInventoryDat = clearInventoryDat;
+ this.resourceTypes = new HashSet<ResType>(resourceTypes);
+ }
+
+ public boolean isClearInventoryDat() {
+ return clearInventoryDat;
+ }
+
+ public Set<ResType> getExpectedResourceTypes() {
+ return resourceTypes;
+ }
+ }
+
@BeforeClass
public void init() {
tmpDir = getTmpDirectory();
@@ -81,21 +156,21 @@ public abstract class ResourceUpgradeTestBase {
dataDir = new File(tmpDir, DATA_DIR_NAME);
assertTrue(dataDir.mkdir(), "Could not create plugin container data directory.");
}
-
+
@BeforeClass
public void verifyPluginsExist() {
for (String plugin : getRequiredPlugins()) {
verifyPluginExists(plugin);
}
}
-
+
@AfterClass
public void undeployPlugins() throws IOException {
FileUtils.deleteDirectory(tmpDir);
}
-
+
protected abstract Collection<String> getRequiredPlugins();
-
+
protected void setCurrentServerSideInventory(FakeServerInventory currentServerSideInventory) {
this.currentServerSideInventory = currentServerSideInventory;
}
@@ -103,8 +178,9 @@ public abstract class ResourceUpgradeTestBase {
protected FakeServerInventory getCurrentServerSideInventory() {
return currentServerSideInventory;
}
-
- protected void setCurrentResourceFactoryServerService(ResourceFactoryServerService currentResourceFactoryServerService) {
+
+ protected void setCurrentResourceFactoryServerService(
+ ResourceFactoryServerService currentResourceFactoryServerService) {
this.currentResourceFactoryServerService = currentResourceFactoryServerService;
}
@@ -178,24 +254,24 @@ public abstract class ResourceUpgradeTestBase {
protected static File getTmpDirectory() {
File ret = new File(System.getProperty("java.io.tmpdir"), "resource-upgrade-test" + System.currentTimeMillis());
-
+
while (ret.exists() || !ret.mkdir()) {
ret = new File(System.getProperty("java.io.tmpdir"), "resource-upgrade-test" + System.currentTimeMillis());
}
-
+
return ret;
}
private PluginContainerConfiguration createPluginContainerConfiguration(Mockery context) throws Exception {
PluginContainerConfiguration conf = new PluginContainerConfiguration();
-
+
conf.setPluginDirectory(new File(tmpDir, PLUGINS_DIR_NAME));
conf.setDataDirectory(new File(tmpDir, DATA_DIR_NAME));
conf.setTemporaryDirectory(new File(tmpDir, TMP_DIR_NAME));
conf.setInsideAgent(true); //pc must think it's inside an agent so that it persists the inventory between restarts
conf.setPluginFinder(new FileSystemPluginFinder(conf.getPluginDirectory()));
- conf.setCreateResourceClassloaders(false);
-
+ conf.setCreateResourceClassloaders(false);
+
//we're not interested in any scans happening out of our control
conf.setAvailabilityScanInitialDelay(Long.MAX_VALUE);
conf.setConfigurationDiscoveryInitialDelay(Long.MAX_VALUE);
@@ -204,7 +280,7 @@ public abstract class ResourceUpgradeTestBase {
conf.setMeasurementCollectionInitialDelay(Long.MAX_VALUE);
conf.setServerDiscoveryInitialDelay(Long.MAX_VALUE);
conf.setServiceDiscoveryInitialDelay(Long.MAX_VALUE);
-
+
setCurrentBundleServerService(context.mock(BundleServerService.class));
setCurrentConfigurationServerService(context.mock(ConfigurationServerService.class));
setCurrentContentServerService(context.mock(ContentServerService.class));
@@ -214,7 +290,7 @@ public abstract class ResourceUpgradeTestBase {
setCurrentMeasurementServerService(context.mock(MeasurementServerService.class));
setCurrentOperationServerService(context.mock(OperationServerService.class));
setCurrentResourceFactoryServerService(context.mock(ResourceFactoryServerService.class));
-
+
ServerServices serverServices = new ServerServices();
serverServices.setBundleServerService(getCurrentBundleServerService());
serverServices.setConfigurationServerService(getCurrentConfigurationServerService());
@@ -225,9 +301,9 @@ public abstract class ResourceUpgradeTestBase {
serverServices.setMeasurementServerService(getCurrentMeasurementServerService());
serverServices.setOperationServerService(getCurrentOperationServerService());
serverServices.setResourceFactoryServerService(getCurrentResourceFactoryServerService());
-
+
conf.setServerServices(serverServices);
-
+
return conf;
}
@@ -236,104 +312,76 @@ public abstract class ResourceUpgradeTestBase {
*/
protected void verifyPluginExists(String pluginResourcePath) {
URL url = getClass().getResource(pluginResourcePath);
-
+
File pluginFile = FileUtils.toFile(url);
-
+
assertTrue(pluginFile.exists(), pluginFile.getAbsoluteFile() + " plugin jar could not be found.");
}
private void copyPlugin(String pluginResourcePath, File pluginDirectory) throws IOException {
URL pluginUrl = getClass().getResource(pluginResourcePath);
-
+
File pluginFile = new File(pluginResourcePath);
String pluginFileName = pluginFile.getName();
-
- FileUtils.copyURLToFile(pluginUrl, new File(pluginDirectory, pluginFileName));
- }
-
- protected interface TestPayload {
- Expectations getExpectations(Mockery context) throws Exception;
- void test(Set<Resource> resourceUpgradeTestResources);
- boolean isClearInventoryDat();
- String getResourceTypeName();
- String getResourceTypePluginName();
- }
-
- protected static abstract class AbstractTestPayload implements TestPayload {
- private boolean clearInventoryDat;
- private String resourceTypeName;
- private String resourceTypePluginName;
-
- public AbstractTestPayload(boolean clearInventoryDat, String resourceTypeName, String resourceTypePluginName) {
- this.clearInventoryDat = clearInventoryDat;
- this.resourceTypeName = resourceTypeName;
- this.resourceTypePluginName = resourceTypePluginName;
- }
-
- public boolean isClearInventoryDat() {
- return clearInventoryDat;
- }
-
- public String getResourceTypeName() {
- return resourceTypeName;
- }
-
- public String getResourceTypePluginName() {
- return resourceTypePluginName;
- }
- }
- /**
- *
- */
- public ResourceUpgradeTestBase() {
- super();
+ FileUtils.copyURLToFile(pluginUrl, new File(pluginDirectory, pluginFileName));
}
private Set<Resource> getTestingResources(String resourceTypeName, String resourceTypePluginName) {
- ResourceType resType = PluginContainer.getInstance().getPluginManager().getMetadataManager().getType(resourceTypeName, resourceTypePluginName);
-
+ ResourceType resType = PluginContainer.getInstance().getPluginManager().getMetadataManager()
+ .getType(resourceTypeName, resourceTypePluginName);
+
return getCurrentServerSideInventory().findResourcesByType(resType);
}
protected void executeTestWithPlugins(Set<String> pluginResourcePaths, TestPayload test) throws Exception {
FileUtils.cleanDirectory(new File(tmpDir, PLUGINS_DIR_NAME));
-
- for(String pluginResourcePath : pluginResourcePaths) {
+
+ for (String pluginResourcePath : pluginResourcePaths) {
copyPlugin(pluginResourcePath, pluginDir);
}
-
+
Mockery context = new Mockery();
-
+
PluginContainerConfiguration pcConfig = createPluginContainerConfiguration(context);
-
+
if (test.isClearInventoryDat()) {
File inventoryDat = new File(pcConfig.getDataDirectory(), "inventory.dat");
inventoryDat.delete();
}
-
+
context.checking(test.getExpectations(context));
-
+
PluginContainer.getInstance().setConfiguration(pcConfig);
PluginContainer.getInstance().initialize();
-
+
try {
//give the pc the time to finish resource upgrade
Thread.sleep(1000);
-
+
//execute full discovery
InventoryManager im = PluginContainer.getInstance().getInventoryManager();
im.executeServerScanImmediately();
- im.executeServiceScanImmediately();
-
- Set<Resource> resources = getTestingResources(test.getResourceTypeName(), test.getResourceTypePluginName());
-
+
+ //do the service scan a couple of times so that we can commit
+ //the resources deep in the type hierarchy
+ for(int i = 0; i < 10; ++i) {
+ im.executeServiceScanImmediately();
+ }
+
+ Map<ResType, Set<Resource>> resources = new HashMap<ResType, Set<Resource>>();
+
+ for(ResType type : test.getExpectedResourceTypes()) {
+ Set<Resource> rs = getTestingResources(type.getResourceTypeName(), type.getResourceTypePluginName());
+ resources.put(type, rs);
+ }
+
test.test(resources);
-
+
context.assertIsSatisfied();
} finally {
- PluginContainer.getInstance().shutdown();
- }
+ PluginContainer.getInstance().shutdown();
+ }
}
@SuppressWarnings("unchecked")
@@ -346,11 +394,13 @@ public abstract class ResourceUpgradeTestBase {
expectations.ignoring(getCurrentMeasurementServerService());
expectations.ignoring(getCurrentOperationServerService());
expectations.ignoring(getCurrentResourceFactoryServerService());
-
+
//just ignore these invocations if we get a availability scan in the PC...
- expectations.allowing(getCurrentDiscoveryServerService()).mergeAvailabilityReport(expectations.with(Expectations.any(AvailabilityReport.class)));
-
- expectations.allowing(getCurrentDiscoveryServerService()).getResources(expectations.with(Expectations.any(Set.class)), expectations.with(Expectations.any(boolean.class)));
+ expectations.allowing(getCurrentDiscoveryServerService()).mergeAvailabilityReport(
+ expectations.with(Expectations.any(AvailabilityReport.class)));
+
+ expectations.allowing(getCurrentDiscoveryServerService()).getResources(
+ expectations.with(Expectations.any(Set.class)), expectations.with(Expectations.any(boolean.class)));
expectations.will(getCurrentServerSideInventory().getResources());
}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseDiscoveryComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseDiscoveryComponent.java
index 61d4fe0..a03dff5 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseDiscoveryComponent.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseDiscoveryComponent.java
@@ -46,15 +46,25 @@ public class BaseDiscoveryComponent<T extends ResourceComponent> implements Reso
String keyTemplate = pluginConfig.getSimpleValue("key", null);
int count = pluginConfig.getSimple("count").getIntegerValue();
- int parentN = context.getParentResourceContext().getPluginConfiguration().getSimple("ordinal")
- .getIntegerValue();
+ int parentN = 0;
+
+ if (context.getParentResourceContext() != null) {
+ PropertySimple parentOrdinalProperty = context.getParentResourceContext().getPluginConfiguration()
+ .getSimple("ordinal");
+
+ if (parentOrdinalProperty != null) {
+ parentN = parentOrdinalProperty.getIntegerValue();
+ }
+ }
for (int i = 0; i < count; ++i) {
String key = getResourceKey(keyTemplate, i, parentN);
+ pluginConfig = context.getDefaultPluginConfiguration();
+
pluginConfig.put(new PropertySimple("ordinal", i));
-
+
DiscoveredResourceDetails detail = new DiscoveredResourceDetails(context.getResourceType(), key, key, null,
null, pluginConfig, null);
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java
index beb36db..ec1cb20 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java
@@ -28,34 +28,36 @@ import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
*
* @author Lukas Krejci
*/
-public class BaseUpgradingDiscoveryComponent<T extends BaseResourceComponent> extends BaseDiscoveryComponent<T> implements ResourceUpgradeFacet<T> {
+public class BaseUpgradingDiscoveryComponent<T extends BaseResourceComponent> extends BaseDiscoveryComponent<T>
+ implements ResourceUpgradeFacet<T> {
public ResourceUpgradeReport upgrade(ResourceUpgradeContext<T> inventoriedResource) {
Configuration pluginConfig = inventoriedResource.getPluginConfiguration();
-
+
BaseResourceComponent<?> parent = inventoriedResource.getParentResourceComponent();
int ordinal = pluginConfig.getSimple("ordinal").getIntegerValue();
int parentOrdinal = parent == null ? 0 : parent.getOrdinal();
-
+
boolean fail = Boolean.getBoolean(pluginConfig.getSimpleValue("failUpgrade", "false"));
-
+
if (!fail && parent != null) {
fail = parent.getChildrenToFailUpgrade().contains(Integer.valueOf(ordinal));
}
-
+
if (fail) {
throw new RuntimeException("Failing the resource upgrade purposefully.");
}
-
+
String newKey = pluginConfig.getSimpleValue("upgradedKey", null);
-
+
if (newKey == null) {
return null;
}
-
+
ResourceUpgradeReport report = new ResourceUpgradeReport();
-
+
report.setNewResourceKey(getResourceKey(newKey, ordinal, parentOrdinal));
- return null;
+
+ return report;
}
}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml
index f5e6920..608793c 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml
@@ -22,8 +22,8 @@
<plugin-configuration>
<c:simple-property name="count" default="1" />
- <c:simple-property name="key" default="test-resource-parent-sibling-%n,parent-%p" />
- <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-parent-sibling-%n,parent-%p" />
+ <c:simple-property name="key" default="test-resource-parent-dep-sibling-%n,parent-%p" />
+ <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-parent-dep-sibling-%n,parent-%p" />
</plugin-configuration>
</server>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml
index d138066..ddda11a 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml
@@ -22,7 +22,7 @@
<plugin-configuration>
<c:simple-property name="count" default="1" />
- <c:simple-property name="key" default="UPGRADED-test-resource-parent-sibling-%n,parent-%p" />
+ <c:simple-property name="key" default="UPGRADED-test-resource-parent-dep-sibling-%n,parent-%p" />
</plugin-configuration>
</server>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
index 44a1033..d3ea7b7 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
@@ -11,10 +11,18 @@
<depends plugin="base" useClasses="true"/>
- <!-- This service is put in the type hierarchy in the v1/v2 test plugins -->
- <service name="TestResourceSibling"
- discovery="BaseDiscoveryComponent"
- class="BaseResourceComponent" />
+ <server name="Bogus" class="BaseDiscoveryComponent">
+ <!-- This service is put in the type hierarchy in the v1/v2 test plugins -->
+ <service name="TestResourceSibling"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+ <plugin-configuration>
+ <c:simple-property name="count" default="10" />
+ <c:simple-property name="key" default="test-resource-sibling-%n,parent-%p" />
+ <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-sibling-%n,parent-%p" />
+ </plugin-configuration>
+ </service>
+ </server>
</plugin>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
index aeab68f..f7f7a2c 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
@@ -10,10 +10,16 @@
<depends plugin="base" useClasses="true"/>
+ <server name="Bogus" class="BaseDiscoveryComponent">
<!-- This service is put in the type hierarchy in the v1/v2 test plugins -->
<service name="TestResourceSibling"
discovery="BaseUpgradingDiscoveryComponent"
- class="BaseResourceComponent" />
-
+ class="BaseResourceComponent">
+ <plugin-configuration>
+ <c:simple-property name="count" default="15" /> <!-- This intentionally differs from v1 -->
+ <c:simple-property name="key" default="UPGRADED-test-resource-sibling-%n,parent-%p" />
+ </plugin-configuration>
+ </service>
+ </server>
</plugin>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml
index e934494..ebe9793 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml
@@ -37,13 +37,8 @@
</plugin-configuration>
</service>
- <service name="TestResourceSibling" sourcePlugin="sibling" sourceType="TestResourceSibling">
- <plugin-configuration>
- <c:simple-property name="count" default="10" />
- <c:simple-property name="key" default="test-resource-sibling-%n,parent-%p" />
- <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-sibling-%n,parent-%p" />
- </plugin-configuration>
- </service>
+ <service name="TestResourceSibling" sourcePlugin="sibling" sourceType="TestResourceSibling"
+ class="BaseResourceComponent" discovery="BaseDiscoveryComponent" />
</server>
</plugin>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
index 96658e3..3d709b0 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
@@ -26,7 +26,7 @@
</plugin-configuration>
<service name="TestResource"
- discovery="BaseDiscoveryComponent"
+ discovery="BaseUpgradingDiscoveryComponent"
class="BaseResourceComponent">
<plugin-configuration>
<c:simple-property name="count" default="15" /> <!-- This intentionally differs from v1 -->
@@ -35,13 +35,8 @@
</service>
- <service name="TestResourceSibling" sourcePlugin="sibling" sourceType="TestResourceSibling">
- <plugin-configuration>
- <c:simple-property name="count" default="15" /> <!-- This intentionally differs from v1 -->
- <c:simple-property name="key" default="UPGRADED-test-resource-sibling-%n,parent-%p" />
- </plugin-configuration>
- </service>
-
+ <service name="TestResourceSibling" sourcePlugin="sibling" sourceType="TestResourceSibling"
+ class="BaseResourceComponent" discovery="BaseUpgradingDiscoveryComponent" />
</server>
</plugin>
commit c99d68dd036f243a2f28e000e10385d27bbdb785
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Sep 29 13:53:45 2010 +0200
Adding a skeleton of what will need to be tested for upgrade failure handling.
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
new file mode 100644
index 0000000..25eca30
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
@@ -0,0 +1,81 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.core.pc.upgrade;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.testng.annotations.Test;
+
+/**
+ * The plugins and their resource types form the following dependency structure:
+ * <pre>
+ * Root(root)
+ * / \
+ * ParentDependency(parentdep) ParentDepSibling(parentsibling)
+ * / \
+ * TestResource(test) TestResourceSibling(sibling)
+ * </pre>
+ * The dependencies in the above "chart" are formed using either the <code><runs-inside></code>
+ * or <code>sourcePlugin/sourceType</code> approaches just to test that both are handled correctly.
+ *
+ * @author Lukas Krejci
+ */
+@Test(sequential = true, invocationCount = 1)
+public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase {
+
+ //plugin names
+ private static final String BASE_PLUGIN_NAME = "/resource-upgrade-test-plugin-multi-base-1.0.0.jar";
+ private static final String PARENT_DEP_V1_PLUGIN_NAME = "/resource-upgrade-test-plugin-multi-parentdep-1.0.0.jar";
+ private static final String PARENT_DEP_V2_PLUGIN_NAME = "/resource-upgrade-test-plugin-multi-parentdep-2.0.0.jar";
+ private static final String PARENT_SIBLING_V1_PLUGIN_NAME = "/resource-upgrade-test-plugin-multi-parentsibling-1.0.0.jar";
+ private static final String PARENT_SIBLING_V2_PLUGIN_NAME = "/resource-upgrade-test-plugin-multi-parentsibling-2.0.0.jar";
+ private static final String ROOT_PLUGIN_NAME = "/resource-upgrade-test-plugin-multi-root-1.0.0.jar";
+ private static final String SIBLING_V1_PLUGIN_NAME = "/resource-upgrade-test-plugin-multi-sibling-1.0.0.jar";
+ private static final String SIBLING_V2_PLUGIN_NAME = "/resource-upgrade-test-plugin-multi-sibling-2.0.0.jar";
+ private static final String TEST_V1_PLUGIN_NAME = "/resource-upgrade-test-plugin-multi-test-1.0.0.jar";
+ private static final String TEST_V2_PLUGIN_NAME = "/resource-upgrade-test-plugin-multi-test-2.0.0.jar";
+
+ protected Collection<String> getRequiredPlugins() {
+ return Arrays.asList(BASE_PLUGIN_NAME, PARENT_DEP_V1_PLUGIN_NAME, PARENT_DEP_V2_PLUGIN_NAME,
+ PARENT_SIBLING_V1_PLUGIN_NAME, PARENT_SIBLING_V2_PLUGIN_NAME, ROOT_PLUGIN_NAME, SIBLING_V1_PLUGIN_NAME,
+ SIBLING_V2_PLUGIN_NAME, TEST_V1_PLUGIN_NAME, TEST_V2_PLUGIN_NAME);
+ }
+
+ @Test
+ public void testSuccess() {
+ //TODO implement
+ //check that all the stuff is properly upgraded on success
+ }
+
+ @Test
+ public void testFailureOnLeaf() {
+ //TODO implement
+ //check that the system behaves correctly if there is an upgrade failure
+ //at the leaf node of the plugin dep graph
+ }
+
+ @Test
+ public void testFailureOnDependencies() {
+ //TODO implement
+ //check that stuff works if there is an upgrade failure on some of the resources
+ //in the plugin some "in the middle" of the plugin dep graph
+ }
+}
commit 4f504f582fc9040bcf5ed7f7dd24cfd3bc2adbad
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Sep 29 13:49:24 2010 +0200
some more minor changes to class structure and plugin names.
diff --git a/modules/core/plugin-container/pom.xml b/modules/core/plugin-container/pom.xml
index 035bf36..4d6e753 100644
--- a/modules/core/plugin-container/pom.xml
+++ b/modules/core/plugin-container/pom.xml
@@ -281,7 +281,7 @@
<!-- <copy toDir="${project.build.testOutputDirectory}/tmp/multi/v1/org/rhq/core/pc/upgrade/plugins/multi/v1">
<fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/v1/*.class" />
</copy> -->
- <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-1.0.0.jar">
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-test-1.0.0.jar">
<fileset dir="${project.build.testOutputDirectory}/tmp/multi/v1" includes="**/*.class,**/rhq-plugin.xml" />
</jar>
@@ -291,7 +291,7 @@
<!-- <copy toDir="${project.build.testOutputDirectory}/tmp/multi/v2/org/rhq/core/pc/upgrade/plugins/multi/v2">
<fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/v2/*.class" />
</copy> -->
- <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-2.0.0.jar">
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-test-2.0.0.jar">
<fileset dir="${project.build.testOutputDirectory}/tmp/multi/v2" includes="**/*.class,**/rhq-plugin.xml" />
</jar>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index e13ea3d..8cfec36 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -28,6 +28,8 @@ import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import java.io.File;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.Set;
@@ -38,7 +40,6 @@ import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.pc.PluginContainer;
import org.rhq.core.pc.inventory.ResourceContainer;
-import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
@@ -56,11 +57,8 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
static final String SINGLETON_RESOURCE_TYPE_NAME = "Resource";
static final String SINGLETON_RESOURCE_TYPE_PLUGIN_NAME = "ResourceUpgradeTest";
- @BeforeClass
- public void sanityCheck() {
- verifyPluginExists(PLUGIN_V1_FILENAME);
- verifyPluginExists(PLUGIN_V2_FILENAME);
- verifyPluginExists(FAILING_PLUGIN_FILE_NAME);
+ protected Collection<String> getRequiredPlugins() {
+ return Arrays.asList(PLUGIN_V1_FILENAME, PLUGIN_V2_FILENAME, FAILING_PLUGIN_FILE_NAME);
}
@Test
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
index f03f2a4..3aa772b 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
@@ -24,6 +24,7 @@ import static org.testng.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import java.net.URL;
+import java.util.Collection;
import java.util.Set;
import org.apache.commons.io.FileUtils;
@@ -53,7 +54,7 @@ import org.testng.annotations.BeforeClass;
*
* @author Lukas Krejci
*/
-public class ResourceUpgradeTestBase {
+public abstract class ResourceUpgradeTestBase {
private static final String PLUGINS_DIR_NAME = "plugins";
private static final String DATA_DIR_NAME = "data";
@@ -81,11 +82,20 @@ public class ResourceUpgradeTestBase {
assertTrue(dataDir.mkdir(), "Could not create plugin container data directory.");
}
+ @BeforeClass
+ public void verifyPluginsExist() {
+ for (String plugin : getRequiredPlugins()) {
+ verifyPluginExists(plugin);
+ }
+ }
+
@AfterClass
public void undeployPlugins() throws IOException {
FileUtils.deleteDirectory(tmpDir);
}
+ protected abstract Collection<String> getRequiredPlugins();
+
protected void setCurrentServerSideInventory(FakeServerInventory currentServerSideInventory) {
this.currentServerSideInventory = currentServerSideInventory;
}
commit b97e79bcbd5c557fba29030f7aa0f8b4c629c56f
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Sep 29 13:48:28 2010 +0200
Simplify plugin names, declare correct discovery components for upgrade failure test plugins.
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/rhq-plugin.xml
index 7edfba1..d262c75 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/rhq-plugin.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTestBase"
+<plugin name="base"
displayName=""
description=""
package="org.rhq.core.pc.upgrade.plugins.multi.base"
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/rhq-plugin.xml
index 3612974..8cadc84 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/rhq-plugin.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTestParentDep"
+<plugin name="parentdep"
displayName="Resource Upgrade Multi Test"
description="Resource Upgrade Multi Test"
package="org.rhq.core.pc.upgrade.plugins.multi.base"
@@ -9,15 +9,15 @@
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
- <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
- <depends plugin="ResourceUpgradeMultiTestRoot"/>
+ <depends plugin="base" useClasses="true"/>
+ <depends plugin="root"/>
<server name="ParentDependency"
discovery="BaseDiscoveryComponent"
class="BaseResourceComponent">
<runs-inside>
- <parent-resource-type name="Root" plugin="ResourceUpgradeMultiTestRoot"/>
+ <parent-resource-type name="Root" plugin="root"/>
</runs-inside>
<plugin-configuration>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/rhq-plugin.xml
index 6b95114..8169122 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/rhq-plugin.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTestParentDep"
+<plugin name="parentdep"
displayName="Resource Upgrade Multi Test"
description="Resource Upgrade Multi Test"
package="org.rhq.core.pc.upgrade.plugins.multi.base"
@@ -9,15 +9,15 @@
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
- <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
- <depends plugin="ResourceUpgradeMultiTestRoot"/>
+ <depends plugin="base" useClasses="true"/>
+ <depends plugin="root"/>
<server name="ParentDependency"
- discovery="BaseDiscoveryComponent"
+ discovery="BaseUpgradingDiscoveryComponent"
class="BaseResourceComponent">
<runs-inside>
- <parent-resource-type name="Root" plugin="ResourceUpgradeMultiTestRoot"/>
+ <parent-resource-type name="Root" plugin="root"/>
</runs-inside>
<plugin-configuration>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml
index fbade54..f5e6920 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTestParentSibling"
+<plugin name="parentsibling"
displayName="Resource Upgrade Multi Test"
description="Resource Upgrade Multi Test"
package="org.rhq.core.pc.upgrade.plugins.multi.base"
@@ -9,15 +9,15 @@
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
- <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
- <depends plugin="ResourceUpgradeMultiTestRoot"/>
+ <depends plugin="base" useClasses="true"/>
+ <depends plugin="root"/>
<server name="ParentDepSibling"
discovery="BaseDiscoveryComponent"
class="BaseResourceComponent">
<runs-inside>
- <parent-resource-type name="Root" plugin="ResourceUpgradeMultiTestRoot"/>
+ <parent-resource-type name="Root" plugin="root"/>
</runs-inside>
<plugin-configuration>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml
index f16d526..d138066 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTestParentSibling"
+<plugin name="parentsibling"
displayName="Resource Upgrade Multi Test"
description="Resource Upgrade Multi Test"
package="org.rhq.core.pc.upgrade.plugins.multi.base"
@@ -9,15 +9,15 @@
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
- <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
- <depends plugin="ResourceUpgradeMultiTestRoot"/>
+ <depends plugin="base" useClasses="true"/>
+ <depends plugin="root"/>
<server name="ParentDepSibling"
- discovery="BaseDiscoveryComponent"
+ discovery="BaseUpgradingDiscoveryComponent"
class="BaseResourceComponent">
<runs-inside>
- <parent-resource-type name="Root" plugin="ResourceUpgradeMultiTestRoot"/>
+ <parent-resource-type name="Root" plugin="root"/>
</runs-inside>
<plugin-configuration>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/root/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/root/rhq-plugin.xml
index b5efbb1..e95c9bd 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/root/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/root/rhq-plugin.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTestRoot"
+<plugin name="root"
displayName=""
description=""
package="org.rhq.core.pc.upgrade.plugins.multi.base"
@@ -9,6 +9,8 @@
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
+ <depends plugin="base" useClasses="true"/>
+
<server name="Root"
discovery="BaseDiscoveryComponent"
class="BaseResourceComponent">
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
index f87ef4d..44a1033 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTestSibling"
+<plugin name="sibling"
displayName="Resource Upgrade Multi Test"
description="Resource Upgrade Multi Test"
package="org.rhq.core.pc.upgrade.plugins.multi.base"
@@ -9,30 +9,12 @@
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
- <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
- <depends plugin="ResourceUpgradeMultiTestParentDep"/>
+ <depends plugin="base" useClasses="true"/>
- <server name="TestResourceParentSibling"
- discovery="BaseDiscoveryComponent"
- class="BaseResourceComponent">
-
- <plugin-configuration>
- <c:simple-property name="count" default="2" />
- <c:simple-property name="key" default="test-resource-parent-sibling-%n,parent-%p" />
- <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-parent-sibling-%n,parent-%p" />
- </plugin-configuration>
-
- <service name="TestResourceSibling"
+ <!-- This service is put in the type hierarchy in the v1/v2 test plugins -->
+ <service name="TestResourceSibling"
discovery="BaseDiscoveryComponent"
- class="BaseResourceComponent">
- <plugin-configuration>
- <c:simple-property name="count" default="10" />
- <c:simple-property name="key" default="test-resource-sibling-%n,parent-%p" />
- <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-sibling-%n,parent-%p" />
- </plugin-configuration>
-
- </service>
- </server>
+ class="BaseResourceComponent" />
</plugin>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
index e6ab95f..aeab68f 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTestSibling"
+<plugin name="sibling"
displayName="Resource Upgrade Multi Test"
description="Resource Upgrade Multi Test"
package="org.rhq.core.pc.upgrade.plugins.multi.base"
@@ -8,34 +8,12 @@
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
- <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
- <depends plugin="ResourceUpgradeMultiTestParentDep"/>
+ <depends plugin="base" useClasses="true"/>
- <server name="TestResourceParentSibling"
- discovery="BaseUpgradingDiscoveryComponent"
- class="BaseResourceComponent">
-
- <runs-inside>
- <parent-resource-type name="ParentDependency" plugin="ResourceUpgradeMultiTestParentDep"/>
- </runs-inside>
-
- <plugin-configuration>
- <c:simple-property name="count" default="2" />
- <c:simple-property name="key" default="UPGRADED-test-resource-parent-sibling-%n,parent-%p" />
- </plugin-configuration>
-
- <service name="TestResourceSibling"
- discovery="BaseDiscoveryComponent"
- class="BaseResourceComponent">
- <plugin-configuration>
- <c:simple-property name="count" default="15" />
- <c:simple-property name="key" default="UPGRADED-test-resource-sibling-%n,parent-%p" />
- </plugin-configuration>
-
- </service>
-
-
- </server>
+ <!-- This service is put in the type hierarchy in the v1/v2 test plugins -->
+ <service name="TestResourceSibling"
+ discovery="BaseUpgradingDiscoveryComponent"
+ class="BaseResourceComponent" />
</plugin>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml
index 32ad438..e934494 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTest"
+<plugin name="test"
displayName="Resource Upgrade Multi Test"
description="Resource Upgrade Multi Test"
package="org.rhq.core.pc.upgrade.plugins.multi.base"
@@ -9,15 +9,16 @@
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
- <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
- <depends plugin="ResourceUpgradeMultiTestParentDep"/>
+ <depends plugin="base" useClasses="true"/>
+ <depends plugin="parentdep"/>
+ <depends plugin="sibling" />
<server name="TestResourceParent"
discovery="BaseDiscoveryComponent"
class="BaseResourceComponent">
<runs-inside>
- <parent-resource-type name="ParentDependency" plugin="ResourceUpgradeMultiTestParentDep"/>
+ <parent-resource-type name="ParentDependency" plugin="parentdep"/>
</runs-inside>
<plugin-configuration>
@@ -29,13 +30,20 @@
<service name="TestResource"
discovery="BaseDiscoveryComponent"
class="BaseResourceComponent">
- <plugin-configuration>
- <c:simple-property name="count" default="10" />
- <c:simple-property name="key" default="test-resource-%n,parent-%p" />
- <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-%n,parent-%p" />
- </plugin-configuration>
-
- </service>
+ <plugin-configuration>
+ <c:simple-property name="count" default="10" />
+ <c:simple-property name="key" default="test-resource-%n,parent-%p" />
+ <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-%n,parent-%p" />
+ </plugin-configuration>
+ </service>
+
+ <service name="TestResourceSibling" sourcePlugin="sibling" sourceType="TestResourceSibling">
+ <plugin-configuration>
+ <c:simple-property name="count" default="10" />
+ <c:simple-property name="key" default="test-resource-sibling-%n,parent-%p" />
+ <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-sibling-%n,parent-%p" />
+ </plugin-configuration>
+ </service>
</server>
</plugin>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
index 824d3fe..96658e3 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTest"
+<plugin name="test"
displayName="Resource Upgrade Multi Test"
description="Resource Upgrade Multi Test"
package="org.rhq.core.pc.upgrade.plugins.multi.base"
@@ -8,15 +8,16 @@
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
- <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
- <depends plugin="ResourceUpgradeMultiTestParentDep"/>
+ <depends plugin="base" useClasses="true"/>
+ <depends plugin="parentdep"/>
+ <depends plugin="sibling"/>
<server name="TestResourceParent"
discovery="BaseUpgradingDiscoveryComponent"
class="BaseResourceComponent">
<runs-inside>
- <parent-resource-type name="ParentDependency" plugin="ResourceUpgradeMultiTestParentDep"/>
+ <parent-resource-type name="ParentDependency" plugin="parentdep"/>
</runs-inside>
<plugin-configuration>
@@ -27,13 +28,19 @@
<service name="TestResource"
discovery="BaseDiscoveryComponent"
class="BaseResourceComponent">
- <plugin-configuration>
- <c:simple-property name="count" default="15" />
- <c:simple-property name="key" default="UPGRADED-test-resource-%n,parent-%p" />
- </plugin-configuration>
+ <plugin-configuration>
+ <c:simple-property name="count" default="15" /> <!-- This intentionally differs from v1 -->
+ <c:simple-property name="key" default="UPGRADED-test-resource-%n,parent-%p" />
+ </plugin-configuration>
</service>
+ <service name="TestResourceSibling" sourcePlugin="sibling" sourceType="TestResourceSibling">
+ <plugin-configuration>
+ <c:simple-property name="count" default="15" /> <!-- This intentionally differs from v1 -->
+ <c:simple-property name="key" default="UPGRADED-test-resource-sibling-%n,parent-%p" />
+ </plugin-configuration>
+ </service>
</server>
commit 097f744dec27c5584cf6203bbaff6fc041753b26
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Sep 29 13:12:09 2010 +0200
Extracted a base class from the upgrade test in preparation for adding another round of tests.
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 0a2a660..e13ea3d 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -23,43 +23,23 @@
package org.rhq.core.pc.upgrade;
-import static org.testng.Assert.assertTrue;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
import java.io.File;
-import java.io.IOException;
-import java.net.URL;
import java.util.Collections;
import java.util.Set;
-import org.apache.commons.io.FileUtils;
import org.jmock.Expectations;
import org.jmock.Mockery;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
-import org.rhq.core.clientapi.server.bundle.BundleServerService;
-import org.rhq.core.clientapi.server.configuration.ConfigurationServerService;
-import org.rhq.core.clientapi.server.content.ContentServerService;
-import org.rhq.core.clientapi.server.core.CoreServerService;
-import org.rhq.core.clientapi.server.discovery.DiscoveryServerService;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
-import org.rhq.core.clientapi.server.event.EventServerService;
-import org.rhq.core.clientapi.server.inventory.ResourceFactoryServerService;
-import org.rhq.core.clientapi.server.measurement.MeasurementServerService;
-import org.rhq.core.clientapi.server.operation.OperationServerService;
-import org.rhq.core.domain.discovery.AvailabilityReport;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.pc.PluginContainer;
-import org.rhq.core.pc.PluginContainerConfiguration;
-import org.rhq.core.pc.ServerServices;
-import org.rhq.core.pc.inventory.InventoryManager;
import org.rhq.core.pc.inventory.ResourceContainer;
-import org.rhq.core.pc.plugin.FileSystemPluginFinder;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
/**
* Test cases for resource upgrade.
@@ -67,39 +47,14 @@ import org.rhq.core.pc.plugin.FileSystemPluginFinder;
* @author Lukas Krejci
*/
@Test(sequential = true, invocationCount = 1)
-public class ResourceUpgradeTest {
+public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
private static final String PLUGIN_V1_FILENAME = "/resource-upgrade-test-plugin-1.0.0.jar";
private static final String PLUGIN_V2_FILENAME = "/resource-upgrade-test-plugin-2.0.0.jar";
private static final String FAILING_PLUGIN_FILE_NAME = "/resource-upgrade-test-plugin-3.0.0.jar";
- private static final String PLUGINS_DIR_NAME = "plugins";
- private static final String DATA_DIR_NAME = "data";
- private static final String TMP_DIR_NAME = "tmp";
-
- private static final String SINGLETON_RESOURCE_TYPE_NAME = "Resource";
- private static final String SINGLETON_RESOURCE_TYPE_PLUGIN_NAME = "ResourceUpgradeTest";
-
- private File tmpDir;
- private File pluginDir;
- private File dataDir;
-
- private BundleServerService currentBundleServerService;
- private ConfigurationServerService currentConfigurationServerService;
- private ContentServerService currentContentServerService;
- private CoreServerService currentCoreServerService;
- private DiscoveryServerService currentDiscoveryServerService;
- private EventServerService currentEventServerService;
- private MeasurementServerService currentMeasurementServerService;
- private OperationServerService currentOperationServerService;
- private ResourceFactoryServerService currentResourceFactoryServerService;
-
- private FakeServerInventory currentServerSideInventory;
-
- @AfterClass
- public void undeployPlugins() throws IOException {
- FileUtils.deleteDirectory(tmpDir);
- }
+ static final String SINGLETON_RESOURCE_TYPE_NAME = "Resource";
+ static final String SINGLETON_RESOURCE_TYPE_PLUGIN_NAME = "ResourceUpgradeTest";
@BeforeClass
public void sanityCheck() {
@@ -108,18 +63,9 @@ public class ResourceUpgradeTest {
verifyPluginExists(FAILING_PLUGIN_FILE_NAME);
}
- @BeforeClass(dependsOnMethods = "sanityCheck")
- public void init() {
- tmpDir = getTmpDirectory();
- pluginDir = new File(tmpDir, PLUGINS_DIR_NAME);
- assertTrue(pluginDir.mkdir(), "Could not create plugin deploy directory.");
- dataDir = new File(tmpDir, DATA_DIR_NAME);
- assertTrue(dataDir.mkdir(), "Could not create plugin container data directory.");
- }
-
@Test
public void testIgnoreUncommittedResources() throws Exception {
- currentServerSideInventory = new FakeServerInventory();
+ setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.NEW);
TestPayload testNoChange = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
@@ -138,8 +84,8 @@ public class ResourceUpgradeTest {
{
defineDefaultExpectations(this);
- between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
- will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+ between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
}
};
}
@@ -150,22 +96,22 @@ public class ResourceUpgradeTest {
@Test
public void testUpgradeData() throws Exception {
- currentServerSideInventory = new FakeServerInventory();
+ setCurrentServerSideInventory(new FakeServerInventory());
upgradeTest(false);
}
@Test
public void testInventoryReinitializationFromServerDuringUpgrade() throws Exception {
- currentServerSideInventory = new FakeServerInventory();
+ setCurrentServerSideInventory(new FakeServerInventory());
upgradeTest(true);
}
@Test
public void testSkipUpgradeWhenServerUnavailable() throws Exception {
- currentServerSideInventory = new FakeServerInventory();
+ setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
- currentServerSideInventory.setFailing(true);
+ getCurrentServerSideInventory().setFailing(true);
TestPayload test = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
public void test(Set<Resource> discoveredResources) {
@@ -184,10 +130,10 @@ public class ResourceUpgradeTest {
{
defineDefaultExpectations(this);
- between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
- will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+ between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
- never(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
+ never(getCurrentDiscoveryServerService()).upgradeResources(with(any(Set.class)));
}
};
}
@@ -198,7 +144,7 @@ public class ResourceUpgradeTest {
@Test
public void testUpgradeWithPlatformDeletedOnServer() throws Exception {
- currentServerSideInventory = new FakeServerInventory();
+ setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
TestPayload test = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
@@ -227,15 +173,15 @@ public class ResourceUpgradeTest {
//the first merge will be triggered from within the upgrade process and we are
//going to report null sync.
- oneOf(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
- will(currentServerSideInventory.clearPlatform());
+ oneOf(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(getCurrentServerSideInventory().clearPlatform());
//the rest of the inventory merges are executed by discoveries, so let's import the
//discovered stuff into the server-side inventory.
- between(1, 3).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
- will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+ between(1, 3).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
- never(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
+ never(getCurrentDiscoveryServerService()).upgradeResources(with(any(Set.class)));
}
};
}
@@ -246,7 +192,7 @@ public class ResourceUpgradeTest {
@Test
public void testUpgradeFailureHandling() throws Exception {
- currentServerSideInventory = new FakeServerInventory();
+ setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
TestPayload test = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
@@ -272,11 +218,11 @@ public class ResourceUpgradeTest {
{
defineDefaultExpectations(this);
- between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
- will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+ between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
- oneOf(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
- will(currentServerSideInventory.upgradeResources());
+ oneOf(getCurrentDiscoveryServerService()).upgradeResources(with(any(Set.class)));
+ will(getCurrentServerSideInventory().upgradeResources());
}
};
}
@@ -297,20 +243,21 @@ public class ResourceUpgradeTest {
assertEquals(discoveredResource.getName(), "resource-name-v1");
assertEquals(discoveredResource.getDescription(), "resource-description-v1");
}
-
+
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
defineDefaultExpectations(this);
- between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
- will(currentServerSideInventory.mergeInventoryReport(requiredInventoryStatus));
+ between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(getCurrentServerSideInventory().mergeInventoryReport(requiredInventoryStatus));
}
};
}
});
}
+
private void upgradeTest(boolean clearInventoryDat) throws Exception {
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
@@ -339,189 +286,14 @@ public class ResourceUpgradeTest {
{
defineDefaultExpectations(this);
- between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
- will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+ between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
- oneOf(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
- will(currentServerSideInventory.upgradeResources());
+ oneOf(getCurrentDiscoveryServerService()).upgradeResources(with(any(Set.class)));
+ will(getCurrentServerSideInventory().upgradeResources());
}
};
}
});
}
-
- private PluginContainerConfiguration createPluginContainerConfiguration(Mockery context) throws Exception {
- PluginContainerConfiguration conf = new PluginContainerConfiguration();
-
- conf.setPluginDirectory(new File(tmpDir, PLUGINS_DIR_NAME));
- conf.setDataDirectory(new File(tmpDir, DATA_DIR_NAME));
- conf.setTemporaryDirectory(new File(tmpDir, TMP_DIR_NAME));
- conf.setInsideAgent(true); //pc must think it's inside an agent so that it persists the inventory between restarts
- conf.setPluginFinder(new FileSystemPluginFinder(conf.getPluginDirectory()));
- conf.setCreateResourceClassloaders(false);
-
- //we're not interested in any scans happening out of our control
- conf.setAvailabilityScanInitialDelay(Long.MAX_VALUE);
- conf.setConfigurationDiscoveryInitialDelay(Long.MAX_VALUE);
- conf.setContentDiscoveryInitialDelay(Long.MAX_VALUE);
- conf.setEventSenderInitialDelay(Long.MAX_VALUE);
- conf.setMeasurementCollectionInitialDelay(Long.MAX_VALUE);
- conf.setServerDiscoveryInitialDelay(Long.MAX_VALUE);
- conf.setServiceDiscoveryInitialDelay(Long.MAX_VALUE);
-
- currentBundleServerService = context.mock(BundleServerService.class);
- currentConfigurationServerService = context.mock(ConfigurationServerService.class);
- currentContentServerService = context.mock(ContentServerService.class);
- currentCoreServerService = context.mock(CoreServerService.class);
- currentDiscoveryServerService = context.mock(DiscoveryServerService.class);
- currentEventServerService = context.mock(EventServerService.class);
- currentMeasurementServerService = context.mock(MeasurementServerService.class);
- currentOperationServerService = context.mock(OperationServerService.class);
- currentResourceFactoryServerService = context.mock(ResourceFactoryServerService.class);
-
- ServerServices serverServices = new ServerServices();
- serverServices.setBundleServerService(currentBundleServerService);
- serverServices.setConfigurationServerService(currentConfigurationServerService);
- serverServices.setContentServerService(currentContentServerService);
- serverServices.setCoreServerService(currentCoreServerService);
- serverServices.setDiscoveryServerService(currentDiscoveryServerService);
- serverServices.setEventServerService(currentEventServerService);
- serverServices.setMeasurementServerService(currentMeasurementServerService);
- serverServices.setOperationServerService(currentOperationServerService);
- serverServices.setResourceFactoryServerService(currentResourceFactoryServerService);
-
- conf.setServerServices(serverServices);
-
- return conf;
- }
-
- /**
- * @param pluginResourcePath
- */
- private void verifyPluginExists(String pluginResourcePath) {
- URL url = getClass().getResource(pluginResourcePath);
-
- File pluginFile = FileUtils.toFile(url);
-
- assertTrue(pluginFile.exists(), pluginFile.getAbsoluteFile() + " plugin jar could not be found.");
- }
-
- private void copyPlugin(String pluginResourcePath, File pluginDirectory) throws IOException {
- URL pluginUrl = getClass().getResource(pluginResourcePath);
-
- File pluginFile = new File(pluginResourcePath);
- String pluginFileName = pluginFile.getName();
-
- FileUtils.copyURLToFile(pluginUrl, new File(pluginDirectory, pluginFileName));
- }
-
- private static File getTmpDirectory() {
- File ret = new File(System.getProperty("java.io.tmpdir"), "resource-upgrade-test" + System.currentTimeMillis());
-
- while (ret.exists() || !ret.mkdir()) {
- ret = new File(System.getProperty("java.io.tmpdir"), "resource-upgrade-test" + System.currentTimeMillis());
- }
-
- return ret;
- }
-
- private interface TestPayload {
- Expectations getExpectations(Mockery context) throws Exception;
- void test(Set<Resource> resourceUpgradeTestResources);
- boolean isClearInventoryDat();
- String getResourceTypeName();
- String getResourceTypePluginName();
- }
-
- private static abstract class AbstractTestPayload implements TestPayload {
- private boolean clearInventoryDat;
- private String resourceTypeName;
- private String resourceTypePluginName;
-
- public AbstractTestPayload(boolean clearInventoryDat, String resourceTypeName, String resourceTypePluginName) {
- this.clearInventoryDat = clearInventoryDat;
- this.resourceTypeName = resourceTypeName;
- this.resourceTypePluginName = resourceTypePluginName;
- }
-
- public boolean isClearInventoryDat() {
- return clearInventoryDat;
- }
-
- public String getResourceTypeName() {
- return resourceTypeName;
- }
-
- public String getResourceTypePluginName() {
- return resourceTypePluginName;
- }
- }
-
- private Set<Resource> getTestingResources(String resourceTypeName, String resourceTypePluginName) {
- ResourceType resType = PluginContainer.getInstance().getPluginManager().getMetadataManager().getType(resourceTypeName, resourceTypePluginName);
-
- return currentServerSideInventory.findResourcesByType(resType);
- }
-
- private void executeTestWithPlugins(Set<String> pluginResourcePaths, TestPayload test) throws Exception {
- FileUtils.cleanDirectory(new File(tmpDir, PLUGINS_DIR_NAME));
-
- for(String pluginResourcePath : pluginResourcePaths) {
- copyPlugin(pluginResourcePath, pluginDir);
- }
-
- Mockery context = new Mockery();
-
- PluginContainerConfiguration pcConfig = createPluginContainerConfiguration(context);
-
- if (test.isClearInventoryDat()) {
- File inventoryDat = new File(pcConfig.getDataDirectory(), "inventory.dat");
- inventoryDat.delete();
- }
-
- context.checking(test.getExpectations(context));
-
- PluginContainer.getInstance().setConfiguration(pcConfig);
- PluginContainer.getInstance().initialize();
-
- try {
- //give the pc the time to finish resource upgrade
- Thread.sleep(1000);
-
- //execute full discovery
- InventoryManager im = PluginContainer.getInstance().getInventoryManager();
- im.executeServerScanImmediately();
- im.executeServiceScanImmediately();
-
- Set<Resource> resources = getTestingResources(test.getResourceTypeName(), test.getResourceTypePluginName());
-
- test.test(resources);
-
- context.assertIsSatisfied();
- } finally {
- PluginContainer.getInstance().shutdown();
- }
- }
-
- @SuppressWarnings("unchecked")
- private void defineDefaultExpectations(Expectations expectations) {
- expectations.ignoring(currentBundleServerService);
- expectations.ignoring(currentConfigurationServerService);
- expectations.ignoring(currentContentServerService);
- expectations.ignoring(currentCoreServerService);
- expectations.ignoring(currentEventServerService);
- expectations.ignoring(currentMeasurementServerService);
- expectations.ignoring(currentOperationServerService);
- expectations.ignoring(currentResourceFactoryServerService);
-
- //just ignore these invocations if we get a availability scan in the PC...
- expectations.allowing(currentDiscoveryServerService).mergeAvailabilityReport(expectations.with(Expectations.any(AvailabilityReport.class)));
-
- expectations.allowing(currentDiscoveryServerService).getResources(expectations.with(Expectations.any(Set.class)), expectations.with(Expectations.any(boolean.class)));
- expectations.will(currentServerSideInventory.getResources());
- }
-
- private void cleanDataDir() throws IOException {
- FileUtils.cleanDirectory(new File(tmpDir, DATA_DIR_NAME));
- }
}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
new file mode 100644
index 0000000..f03f2a4
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
@@ -0,0 +1,350 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.core.pc.upgrade;
+
+import static org.testng.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Set;
+
+import org.apache.commons.io.FileUtils;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.rhq.core.clientapi.server.bundle.BundleServerService;
+import org.rhq.core.clientapi.server.configuration.ConfigurationServerService;
+import org.rhq.core.clientapi.server.content.ContentServerService;
+import org.rhq.core.clientapi.server.core.CoreServerService;
+import org.rhq.core.clientapi.server.discovery.DiscoveryServerService;
+import org.rhq.core.clientapi.server.event.EventServerService;
+import org.rhq.core.clientapi.server.inventory.ResourceFactoryServerService;
+import org.rhq.core.clientapi.server.measurement.MeasurementServerService;
+import org.rhq.core.clientapi.server.operation.OperationServerService;
+import org.rhq.core.domain.discovery.AvailabilityReport;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.pc.PluginContainer;
+import org.rhq.core.pc.PluginContainerConfiguration;
+import org.rhq.core.pc.ServerServices;
+import org.rhq.core.pc.inventory.InventoryManager;
+import org.rhq.core.pc.plugin.FileSystemPluginFinder;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+
+/**
+ *
+ * @author Lukas Krejci
+ */
+public class ResourceUpgradeTestBase {
+
+ private static final String PLUGINS_DIR_NAME = "plugins";
+ private static final String DATA_DIR_NAME = "data";
+ private static final String TMP_DIR_NAME = "tmp";
+ private File tmpDir;
+ private File pluginDir;
+ private File dataDir;
+ private BundleServerService currentBundleServerService;
+ private ConfigurationServerService currentConfigurationServerService;
+ private ContentServerService currentContentServerService;
+ private CoreServerService currentCoreServerService;
+ private DiscoveryServerService currentDiscoveryServerService;
+ private EventServerService currentEventServerService;
+ private MeasurementServerService currentMeasurementServerService;
+ private OperationServerService currentOperationServerService;
+ private ResourceFactoryServerService currentResourceFactoryServerService;
+ private FakeServerInventory currentServerSideInventory;
+
+ @BeforeClass
+ public void init() {
+ tmpDir = getTmpDirectory();
+ pluginDir = new File(tmpDir, PLUGINS_DIR_NAME);
+ assertTrue(pluginDir.mkdir(), "Could not create plugin deploy directory.");
+ dataDir = new File(tmpDir, DATA_DIR_NAME);
+ assertTrue(dataDir.mkdir(), "Could not create plugin container data directory.");
+ }
+
+ @AfterClass
+ public void undeployPlugins() throws IOException {
+ FileUtils.deleteDirectory(tmpDir);
+ }
+
+ protected void setCurrentServerSideInventory(FakeServerInventory currentServerSideInventory) {
+ this.currentServerSideInventory = currentServerSideInventory;
+ }
+
+ protected FakeServerInventory getCurrentServerSideInventory() {
+ return currentServerSideInventory;
+ }
+
+ protected void setCurrentResourceFactoryServerService(ResourceFactoryServerService currentResourceFactoryServerService) {
+ this.currentResourceFactoryServerService = currentResourceFactoryServerService;
+ }
+
+ protected ResourceFactoryServerService getCurrentResourceFactoryServerService() {
+ return currentResourceFactoryServerService;
+ }
+
+ protected void setCurrentOperationServerService(OperationServerService currentOperationServerService) {
+ this.currentOperationServerService = currentOperationServerService;
+ }
+
+ protected OperationServerService getCurrentOperationServerService() {
+ return currentOperationServerService;
+ }
+
+ protected void setCurrentMeasurementServerService(MeasurementServerService currentMeasurementServerService) {
+ this.currentMeasurementServerService = currentMeasurementServerService;
+ }
+
+ protected MeasurementServerService getCurrentMeasurementServerService() {
+ return currentMeasurementServerService;
+ }
+
+ protected void setCurrentEventServerService(EventServerService currentEventServerService) {
+ this.currentEventServerService = currentEventServerService;
+ }
+
+ protected EventServerService getCurrentEventServerService() {
+ return currentEventServerService;
+ }
+
+ protected void setCurrentDiscoveryServerService(DiscoveryServerService currentDiscoveryServerService) {
+ this.currentDiscoveryServerService = currentDiscoveryServerService;
+ }
+
+ protected DiscoveryServerService getCurrentDiscoveryServerService() {
+ return currentDiscoveryServerService;
+ }
+
+ protected void setCurrentCoreServerService(CoreServerService currentCoreServerService) {
+ this.currentCoreServerService = currentCoreServerService;
+ }
+
+ protected CoreServerService getCurrentCoreServerService() {
+ return currentCoreServerService;
+ }
+
+ protected void setCurrentContentServerService(ContentServerService currentContentServerService) {
+ this.currentContentServerService = currentContentServerService;
+ }
+
+ protected ContentServerService getCurrentContentServerService() {
+ return currentContentServerService;
+ }
+
+ protected void setCurrentConfigurationServerService(ConfigurationServerService currentConfigurationServerService) {
+ this.currentConfigurationServerService = currentConfigurationServerService;
+ }
+
+ protected ConfigurationServerService getCurrentConfigurationServerService() {
+ return currentConfigurationServerService;
+ }
+
+ protected void setCurrentBundleServerService(BundleServerService currentBundleServerService) {
+ this.currentBundleServerService = currentBundleServerService;
+ }
+
+ protected BundleServerService getCurrentBundleServerService() {
+ return currentBundleServerService;
+ }
+
+ protected static File getTmpDirectory() {
+ File ret = new File(System.getProperty("java.io.tmpdir"), "resource-upgrade-test" + System.currentTimeMillis());
+
+ while (ret.exists() || !ret.mkdir()) {
+ ret = new File(System.getProperty("java.io.tmpdir"), "resource-upgrade-test" + System.currentTimeMillis());
+ }
+
+ return ret;
+ }
+
+ private PluginContainerConfiguration createPluginContainerConfiguration(Mockery context) throws Exception {
+ PluginContainerConfiguration conf = new PluginContainerConfiguration();
+
+ conf.setPluginDirectory(new File(tmpDir, PLUGINS_DIR_NAME));
+ conf.setDataDirectory(new File(tmpDir, DATA_DIR_NAME));
+ conf.setTemporaryDirectory(new File(tmpDir, TMP_DIR_NAME));
+ conf.setInsideAgent(true); //pc must think it's inside an agent so that it persists the inventory between restarts
+ conf.setPluginFinder(new FileSystemPluginFinder(conf.getPluginDirectory()));
+ conf.setCreateResourceClassloaders(false);
+
+ //we're not interested in any scans happening out of our control
+ conf.setAvailabilityScanInitialDelay(Long.MAX_VALUE);
+ conf.setConfigurationDiscoveryInitialDelay(Long.MAX_VALUE);
+ conf.setContentDiscoveryInitialDelay(Long.MAX_VALUE);
+ conf.setEventSenderInitialDelay(Long.MAX_VALUE);
+ conf.setMeasurementCollectionInitialDelay(Long.MAX_VALUE);
+ conf.setServerDiscoveryInitialDelay(Long.MAX_VALUE);
+ conf.setServiceDiscoveryInitialDelay(Long.MAX_VALUE);
+
+ setCurrentBundleServerService(context.mock(BundleServerService.class));
+ setCurrentConfigurationServerService(context.mock(ConfigurationServerService.class));
+ setCurrentContentServerService(context.mock(ContentServerService.class));
+ setCurrentCoreServerService(context.mock(CoreServerService.class));
+ setCurrentDiscoveryServerService(context.mock(DiscoveryServerService.class));
+ setCurrentEventServerService(context.mock(EventServerService.class));
+ setCurrentMeasurementServerService(context.mock(MeasurementServerService.class));
+ setCurrentOperationServerService(context.mock(OperationServerService.class));
+ setCurrentResourceFactoryServerService(context.mock(ResourceFactoryServerService.class));
+
+ ServerServices serverServices = new ServerServices();
+ serverServices.setBundleServerService(getCurrentBundleServerService());
+ serverServices.setConfigurationServerService(getCurrentConfigurationServerService());
+ serverServices.setContentServerService(getCurrentContentServerService());
+ serverServices.setCoreServerService(getCurrentCoreServerService());
+ serverServices.setDiscoveryServerService(getCurrentDiscoveryServerService());
+ serverServices.setEventServerService(getCurrentEventServerService());
+ serverServices.setMeasurementServerService(getCurrentMeasurementServerService());
+ serverServices.setOperationServerService(getCurrentOperationServerService());
+ serverServices.setResourceFactoryServerService(getCurrentResourceFactoryServerService());
+
+ conf.setServerServices(serverServices);
+
+ return conf;
+ }
+
+ /**
+ * @param pluginResourcePath
+ */
+ protected void verifyPluginExists(String pluginResourcePath) {
+ URL url = getClass().getResource(pluginResourcePath);
+
+ File pluginFile = FileUtils.toFile(url);
+
+ assertTrue(pluginFile.exists(), pluginFile.getAbsoluteFile() + " plugin jar could not be found.");
+ }
+
+ private void copyPlugin(String pluginResourcePath, File pluginDirectory) throws IOException {
+ URL pluginUrl = getClass().getResource(pluginResourcePath);
+
+ File pluginFile = new File(pluginResourcePath);
+ String pluginFileName = pluginFile.getName();
+
+ FileUtils.copyURLToFile(pluginUrl, new File(pluginDirectory, pluginFileName));
+ }
+
+ protected interface TestPayload {
+ Expectations getExpectations(Mockery context) throws Exception;
+ void test(Set<Resource> resourceUpgradeTestResources);
+ boolean isClearInventoryDat();
+ String getResourceTypeName();
+ String getResourceTypePluginName();
+ }
+
+ protected static abstract class AbstractTestPayload implements TestPayload {
+ private boolean clearInventoryDat;
+ private String resourceTypeName;
+ private String resourceTypePluginName;
+
+ public AbstractTestPayload(boolean clearInventoryDat, String resourceTypeName, String resourceTypePluginName) {
+ this.clearInventoryDat = clearInventoryDat;
+ this.resourceTypeName = resourceTypeName;
+ this.resourceTypePluginName = resourceTypePluginName;
+ }
+
+ public boolean isClearInventoryDat() {
+ return clearInventoryDat;
+ }
+
+ public String getResourceTypeName() {
+ return resourceTypeName;
+ }
+
+ public String getResourceTypePluginName() {
+ return resourceTypePluginName;
+ }
+ }
+
+ /**
+ *
+ */
+ public ResourceUpgradeTestBase() {
+ super();
+ }
+
+ private Set<Resource> getTestingResources(String resourceTypeName, String resourceTypePluginName) {
+ ResourceType resType = PluginContainer.getInstance().getPluginManager().getMetadataManager().getType(resourceTypeName, resourceTypePluginName);
+
+ return getCurrentServerSideInventory().findResourcesByType(resType);
+ }
+
+ protected void executeTestWithPlugins(Set<String> pluginResourcePaths, TestPayload test) throws Exception {
+ FileUtils.cleanDirectory(new File(tmpDir, PLUGINS_DIR_NAME));
+
+ for(String pluginResourcePath : pluginResourcePaths) {
+ copyPlugin(pluginResourcePath, pluginDir);
+ }
+
+ Mockery context = new Mockery();
+
+ PluginContainerConfiguration pcConfig = createPluginContainerConfiguration(context);
+
+ if (test.isClearInventoryDat()) {
+ File inventoryDat = new File(pcConfig.getDataDirectory(), "inventory.dat");
+ inventoryDat.delete();
+ }
+
+ context.checking(test.getExpectations(context));
+
+ PluginContainer.getInstance().setConfiguration(pcConfig);
+ PluginContainer.getInstance().initialize();
+
+ try {
+ //give the pc the time to finish resource upgrade
+ Thread.sleep(1000);
+
+ //execute full discovery
+ InventoryManager im = PluginContainer.getInstance().getInventoryManager();
+ im.executeServerScanImmediately();
+ im.executeServiceScanImmediately();
+
+ Set<Resource> resources = getTestingResources(test.getResourceTypeName(), test.getResourceTypePluginName());
+
+ test.test(resources);
+
+ context.assertIsSatisfied();
+ } finally {
+ PluginContainer.getInstance().shutdown();
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void defineDefaultExpectations(Expectations expectations) {
+ expectations.ignoring(getCurrentBundleServerService());
+ expectations.ignoring(getCurrentConfigurationServerService());
+ expectations.ignoring(getCurrentContentServerService());
+ expectations.ignoring(getCurrentCoreServerService());
+ expectations.ignoring(getCurrentEventServerService());
+ expectations.ignoring(getCurrentMeasurementServerService());
+ expectations.ignoring(getCurrentOperationServerService());
+ expectations.ignoring(getCurrentResourceFactoryServerService());
+
+ //just ignore these invocations if we get a availability scan in the PC...
+ expectations.allowing(getCurrentDiscoveryServerService()).mergeAvailabilityReport(expectations.with(Expectations.any(AvailabilityReport.class)));
+
+ expectations.allowing(getCurrentDiscoveryServerService()).getResources(expectations.with(Expectations.any(Set.class)), expectations.with(Expectations.any(boolean.class)));
+ expectations.will(getCurrentServerSideInventory().getResources());
+ }
+
+ protected void cleanDataDir() throws IOException {
+ FileUtils.cleanDirectory(new File(tmpDir, DATA_DIR_NAME));
+ }
+}
commit 1863f1ab0c4473e6a79c469c16b73b6810733325
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Sep 29 12:58:32 2010 +0200
Preparing the upgrade tests to accept more complicated scenarios.
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 1479345..0a2a660 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -77,6 +77,9 @@ public class ResourceUpgradeTest {
private static final String DATA_DIR_NAME = "data";
private static final String TMP_DIR_NAME = "tmp";
+ private static final String SINGLETON_RESOURCE_TYPE_NAME = "Resource";
+ private static final String SINGLETON_RESOURCE_TYPE_PLUGIN_NAME = "ResourceUpgradeTest";
+
private File tmpDir;
private File pluginDir;
private File dataDir;
@@ -119,8 +122,12 @@ public class ResourceUpgradeTest {
currentServerSideInventory = new FakeServerInventory();
initialSyncAndDiscovery(InventoryStatus.NEW);
- TestPayload testNoChange = new TestPayload() {
- public void test(Resource discoveredResource) {
+ TestPayload testNoChange = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
+ public void test(Set<Resource> discoveredResources) {
+ assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
+
+ Resource discoveredResource = discoveredResources.iterator().next();
+
assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
assertEquals(discoveredResource.getName(), "resource-name-v1");
assertEquals(discoveredResource.getDescription(), "resource-description-v1");
@@ -138,7 +145,7 @@ public class ResourceUpgradeTest {
}
};
- executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, testNoChange);
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), testNoChange);
}
@Test
@@ -160,8 +167,12 @@ public class ResourceUpgradeTest {
currentServerSideInventory.setFailing(true);
- TestPayload test = new TestPayload() {
- public void test(Resource discoveredResource) {
+ TestPayload test = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
+ public void test(Set<Resource> discoveredResources) {
+ assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
+
+ Resource discoveredResource = discoveredResources.iterator().next();
+
assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
assertEquals(discoveredResource.getName(), "resource-name-v1");
assertEquals(discoveredResource.getDescription(), "resource-description-v1");
@@ -182,7 +193,7 @@ public class ResourceUpgradeTest {
}
};
- executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, test);
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), test);
}
@Test
@@ -190,8 +201,12 @@ public class ResourceUpgradeTest {
currentServerSideInventory = new FakeServerInventory();
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
- TestPayload test = new TestPayload() {
- public void test(Resource discoveredResource) {
+ TestPayload test = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
+ public void test(Set<Resource> discoveredResources) {
+ assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
+
+ Resource discoveredResource = discoveredResources.iterator().next();
+
assertEquals(discoveredResource.getResourceKey(), "resource-key-v2");
assertEquals(discoveredResource.getName(), "resource-name-v2");
assertEquals(discoveredResource.getDescription(), "resource-description-v2");
@@ -226,7 +241,7 @@ public class ResourceUpgradeTest {
}
};
- executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, test);
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), test);
}
@Test
@@ -234,12 +249,16 @@ public class ResourceUpgradeTest {
currentServerSideInventory = new FakeServerInventory();
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
- TestPayload test = new TestPayload() {
- public void test(Resource resourceUpgradeTestResource) {
- assertTrue(resourceUpgradeTestResource.getResourceErrors().size() > 0, "There should be upgrade errors persisted on the server side.");
+ TestPayload test = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
+ public void test(Set<Resource> resourceUpgradeTestResources) {
+ assertEquals(resourceUpgradeTestResources.size(), 1, "Expected single test resource but multiple found.");
+
+ Resource discoveredResource = resourceUpgradeTestResources.iterator().next();
+
+ assertTrue(discoveredResource.getResourceErrors().size() > 0, "There should be upgrade errors persisted on the server side.");
//the discovery of the failed resource mustn't have run
- ResourceContainer container = PluginContainer.getInstance().getInventoryManager().getResourceContainer(resourceUpgradeTestResource);
+ ResourceContainer container = PluginContainer.getInstance().getInventoryManager().getResourceContainer(discoveredResource);
File dataDir = container.getResourceContext().getDataDirectory();
File marker = new File(dataDir, "failing-discovery-ran");
@@ -263,13 +282,17 @@ public class ResourceUpgradeTest {
}
};
- executeTestWithPlugins(Collections.singleton(FAILING_PLUGIN_FILE_NAME), false, test);
+ executeTestWithPlugins(Collections.singleton(FAILING_PLUGIN_FILE_NAME), test);
}
private void initialSyncAndDiscovery(final InventoryStatus requiredInventoryStatus) throws Exception {
cleanDataDir();
- executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), true, new TestPayload() {
- public void test(Resource discoveredResource) {
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), new AbstractTestPayload(true, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
+ public void test(Set<Resource> discoveredResources) {
+ assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
+
+ Resource discoveredResource = discoveredResources.iterator().next();
+
assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
assertEquals(discoveredResource.getName(), "resource-name-v1");
assertEquals(discoveredResource.getDescription(), "resource-description-v1");
@@ -292,8 +315,12 @@ public class ResourceUpgradeTest {
private void upgradeTest(boolean clearInventoryDat) throws Exception {
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
- executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), clearInventoryDat, new TestPayload() {
- public void test(Resource discoveredResource) {
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), new AbstractTestPayload(clearInventoryDat, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
+ public void test(Set<Resource> discoveredResources) {
+ assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
+
+ Resource discoveredResource = discoveredResources.iterator().next();
+
assertEquals(discoveredResource.getResourceKey(), "resource-key-v2");
assertEquals(discoveredResource.getName(), "resource-name-v2");
assertEquals(discoveredResource.getDescription(), "resource-description-v2");
@@ -400,16 +427,43 @@ public class ResourceUpgradeTest {
private interface TestPayload {
Expectations getExpectations(Mockery context) throws Exception;
- void test(Resource resourceUpgradeTestResource);
+ void test(Set<Resource> resourceUpgradeTestResources);
+ boolean isClearInventoryDat();
+ String getResourceTypeName();
+ String getResourceTypePluginName();
}
- private Set<Resource> getTestingResources() {
- ResourceType resType = PluginContainer.getInstance().getPluginManager().getMetadataManager().getType("Resource", "ResourceUpgradeTest");
+ private static abstract class AbstractTestPayload implements TestPayload {
+ private boolean clearInventoryDat;
+ private String resourceTypeName;
+ private String resourceTypePluginName;
+
+ public AbstractTestPayload(boolean clearInventoryDat, String resourceTypeName, String resourceTypePluginName) {
+ this.clearInventoryDat = clearInventoryDat;
+ this.resourceTypeName = resourceTypeName;
+ this.resourceTypePluginName = resourceTypePluginName;
+ }
+
+ public boolean isClearInventoryDat() {
+ return clearInventoryDat;
+ }
+
+ public String getResourceTypeName() {
+ return resourceTypeName;
+ }
+
+ public String getResourceTypePluginName() {
+ return resourceTypePluginName;
+ }
+ }
+
+ private Set<Resource> getTestingResources(String resourceTypeName, String resourceTypePluginName) {
+ ResourceType resType = PluginContainer.getInstance().getPluginManager().getMetadataManager().getType(resourceTypeName, resourceTypePluginName);
return currentServerSideInventory.findResourcesByType(resType);
}
- private void executeTestWithPlugins(Set<String> pluginResourcePaths, boolean clearInventoryDat, TestPayload test) throws Exception {
+ private void executeTestWithPlugins(Set<String> pluginResourcePaths, TestPayload test) throws Exception {
FileUtils.cleanDirectory(new File(tmpDir, PLUGINS_DIR_NAME));
for(String pluginResourcePath : pluginResourcePaths) {
@@ -420,7 +474,7 @@ public class ResourceUpgradeTest {
PluginContainerConfiguration pcConfig = createPluginContainerConfiguration(context);
- if (clearInventoryDat) {
+ if (test.isClearInventoryDat()) {
File inventoryDat = new File(pcConfig.getDataDirectory(), "inventory.dat");
inventoryDat.delete();
}
@@ -439,14 +493,9 @@ public class ResourceUpgradeTest {
im.executeServerScanImmediately();
im.executeServiceScanImmediately();
- Set<Resource> resources = getTestingResources();
-
- assertEquals(resources.size(), 1, "There should be only a single testing resource but " + resources
- + " were found.");
-
- Resource discoveredResource = resources.iterator().next();
+ Set<Resource> resources = getTestingResources(test.getResourceTypeName(), test.getResourceTypePluginName());
- test.test(discoveredResource);
+ test.test(resources);
context.assertIsSatisfied();
} finally {
commit 659920513807b095cdd0ac91c3f1c2e091d090a7
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Sep 29 12:57:21 2010 +0200
Setting the height of the errorsGrid to a fixed value so that it stays at the bottom of the page.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
index 95bec5f..b439d44 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
@@ -23,11 +23,7 @@ import org.rhq.core.domain.resource.composite.ResourceComposite;
import org.rhq.enterprise.gui.coregui.client.components.table.Table;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
-import com.smartgwt.client.data.DSCallback;
-import com.smartgwt.client.data.DSRequest;
-import com.smartgwt.client.data.DSResponse;
import com.smartgwt.client.types.Alignment;
-import com.smartgwt.client.types.GroupStartOpen;
import com.smartgwt.client.widgets.HTMLPane;
import com.smartgwt.client.widgets.IButton;
import com.smartgwt.client.widgets.Window;
@@ -44,13 +40,11 @@ import com.smartgwt.client.widgets.grid.events.CellClickHandler;
*/
public class OverviewView extends LocatableVLayout {
- private ResourceComposite resourceComposite;
private OverviewForm form;
private Table errorsGrid;
public OverviewView(String locatorId, ResourceComposite resourceComposite) {
super(locatorId);
- this.resourceComposite = resourceComposite;
form = new OverviewForm(extendLocatorId("form"), resourceComposite);
errorsGrid = new Table(extendLocatorId("errors"), "Detected errors", null, null, new String[] { ResourceErrorsDataSource.DETAIL_ID });
@@ -61,7 +55,7 @@ public class OverviewView extends LocatableVLayout {
errorsGrid.setDataSource(errors);
form.setHeight("*");
- errorsGrid.setHeight("10%");
+ errorsGrid.setHeight(200); //this should be just enough to fit the maximum of 3 rows in this table (there's at most 1 error per type)
addMember(form);
addMember(errorsGrid);
commit c704c79f4acfedf4d959de6d7d27db1b22efa1f3
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Sep 29 12:44:55 2010 +0200
Adding a bunch of test plugins for dependency resolution during resource upgrade failure handling.
diff --git a/modules/core/plugin-container/pom.xml b/modules/core/plugin-container/pom.xml
index 4b09ef8..035bf36 100644
--- a/modules/core/plugin-container/pom.xml
+++ b/modules/core/plugin-container/pom.xml
@@ -195,6 +195,106 @@
<fileset dir="${project.build.testOutputDirectory}/tmp/failing" includes="**/*.class,**/rhq-plugin.xml" />
</jar>
+ <copy toDir="${project.build.testOutputDirectory}/tmp/multi/base/META-INF">
+ <fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/base/rhq-plugin.xml" />
+ </copy>
+ <copy toDir="${project.build.testOutputDirectory}/tmp/multi/base/org/rhq/core/pc/upgrade/plugins/multi/base">
+ <fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/base/*.class" />
+ </copy>
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-base-1.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/tmp/multi/base" includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
+ <copy toDir="${project.build.testOutputDirectory}/tmp/multi/parentdep1/META-INF">
+ <fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/rhq-plugin.xml" />
+ </copy>
+ <!-- <copy toDir="${project.build.testOutputDirectory}/tmp/multi/parentdep1/org/rhq/core/pc/upgrade/plugins/multi/parentdep1">
+ <fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/*.class" />
+ </copy> -->
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-parentdep-1.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/tmp/multi/parentdep1" includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
+ <copy toDir="${project.build.testOutputDirectory}/tmp/multi/parentdep2/META-INF">
+ <fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/rhq-plugin.xml" />
+ </copy>
+ <!-- <copy toDir="${project.build.testOutputDirectory}/tmp/multi/parentdep2/org/rhq/core/pc/upgrade/plugins/multi/parentdep2">
+ <fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/*.class" />
+ </copy> -->
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-parentdep-2.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/tmp/multi/parentdep2" includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
+ <copy toDir="${project.build.testOutputDirectory}/tmp/multi/parentsibling1/META-INF">
+ <fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml" />
+ </copy>
+ <!-- <copy toDir="${project.build.testOutputDirectory}/tmp/multi/parentsibling1/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1">
+ <fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/*.class" />
+ </copy> -->
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-parentsibling-1.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/tmp/multi/parentsibling1" includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
+ <copy toDir="${project.build.testOutputDirectory}/tmp/multi/parentsibling2/META-INF">
+ <fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml" />
+ </copy>
+ <!-- <copy toDir="${project.build.testOutputDirectory}/tmp/multi/parentsibling2/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2">
+ <fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/*.class" />
+ </copy> -->
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-parentsibling-2.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/tmp/multi/parentsibling2" includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
+ <copy toDir="${project.build.testOutputDirectory}/tmp/multi/root/META-INF">
+ <fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/root/rhq-plugin.xml" />
+ </copy>
+ <!-- <copy toDir="${project.build.testOutputDirectory}/tmp/multi/root/org/rhq/core/pc/upgrade/plugins/multi/root">
+ <fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/root/*.class" />
+ </copy> -->
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-root-1.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/tmp/multi/root" includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
+ <copy toDir="${project.build.testOutputDirectory}/tmp/multi/sibling1/META-INF">
+ <fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml" />
+ </copy>
+ <!-- <copy toDir="${project.build.testOutputDirectory}/tmp/multi/sibling1/org/rhq/core/pc/upgrade/plugins/multi/sibling1">
+ <fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/sibling1/*.class" />
+ </copy> -->
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-sibling-1.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/tmp/multi/sibling1" includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
+ <copy toDir="${project.build.testOutputDirectory}/tmp/multi/sibling2/META-INF">
+ <fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml" />
+ </copy>
+ <!-- <copy toDir="${project.build.testOutputDirectory}/tmp/multi/sibling2/org/rhq/core/pc/upgrade/plugins/multi/sibling2">
+ <fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/sibling2/*.class" />
+ </copy> -->
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-sibling-2.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/tmp/multi/sibling2" includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
+ <copy toDir="${project.build.testOutputDirectory}/tmp/multi/v1/META-INF">
+ <fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml" />
+ </copy>
+ <!-- <copy toDir="${project.build.testOutputDirectory}/tmp/multi/v1/org/rhq/core/pc/upgrade/plugins/multi/v1">
+ <fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/v1/*.class" />
+ </copy> -->
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-1.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/tmp/multi/v1" includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
+ <copy toDir="${project.build.testOutputDirectory}/tmp/multi/v2/META-INF">
+ <fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml" />
+ </copy>
+ <!-- <copy toDir="${project.build.testOutputDirectory}/tmp/multi/v2/org/rhq/core/pc/upgrade/plugins/multi/v2">
+ <fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/v2/*.class" />
+ </copy> -->
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-2.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/tmp/multi/v2" includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
<delete dir="${project.build.testOutputDirectory}/tmp"/>
</tasks>
</configuration>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseDiscoveryComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseDiscoveryComponent.java
new file mode 100644
index 0000000..61d4fe0
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseDiscoveryComponent.java
@@ -0,0 +1,70 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.core.pc.upgrade.plugins.multi.base;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+
+/**
+ *
+ * @author Lukas Krejci
+ */
+public class BaseDiscoveryComponent<T extends ResourceComponent> implements ResourceDiscoveryComponent<T> {
+
+ public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext<T> context)
+ throws InvalidPluginConfigurationException, Exception {
+
+ HashSet<DiscoveredResourceDetails> results = new HashSet<DiscoveredResourceDetails>();
+
+ Configuration pluginConfig = context.getDefaultPluginConfiguration();
+
+ String keyTemplate = pluginConfig.getSimpleValue("key", null);
+ int count = pluginConfig.getSimple("count").getIntegerValue();
+
+ int parentN = context.getParentResourceContext().getPluginConfiguration().getSimple("ordinal")
+ .getIntegerValue();
+
+ for (int i = 0; i < count; ++i) {
+
+ String key = getResourceKey(keyTemplate, i, parentN);
+
+ pluginConfig.put(new PropertySimple("ordinal", i));
+
+ DiscoveredResourceDetails detail = new DiscoveredResourceDetails(context.getResourceType(), key, key, null,
+ null, pluginConfig, null);
+
+ results.add(detail);
+ }
+
+ return results;
+ }
+
+ protected static String getResourceKey(String template, int n, int parentN) {
+ return template.replace("%n", Integer.toString(n)).replace("%p", Integer.toString(parentN));
+ }
+}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponent.java
new file mode 100644
index 0000000..c5bbf3a
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponent.java
@@ -0,0 +1,67 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.core.pc.upgrade.plugins.multi.base;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
+
+/**
+ *
+ * @author Lukas Krejci
+ */
+public class BaseResourceComponent<T extends ResourceComponent> implements ResourceComponent<T> {
+
+ private ResourceContext<T> context;
+ private final Log log = LogFactory.getLog(getClass());
+
+ private Set<Integer> childrenToFailUpgrade;
+
+ public AvailabilityType getAvailability() {
+ return AvailabilityType.UP;
+ }
+
+ public void start(ResourceContext<T> context) throws InvalidPluginConfigurationException, Exception {
+ log.info("Starting multi resource child component with resource key '" + context.getResourceKey() + "'.");
+ this.context = context;
+ }
+
+ public void stop() {
+ log.info("Stopping multi resource child component with resource key '" + context.getResourceKey() + "'.");
+ }
+
+ public int getOrdinal() {
+ return context.getPluginConfiguration().getSimple("ordinal").getIntegerValue();
+ }
+
+ public Set<Integer> getChildrenToFailUpgrade() {
+ return childrenToFailUpgrade == null ? Collections.<Integer>emptySet() : childrenToFailUpgrade;
+ }
+
+ public void setChildrenToFailUpgrade(Set<Integer> childrenToFailUpgrade) {
+ this.childrenToFailUpgrade = childrenToFailUpgrade;
+ }
+}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java
new file mode 100644
index 0000000..beb36db
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java
@@ -0,0 +1,61 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.core.pc.upgrade.plugins.multi.base;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
+
+/**
+ *
+ * @author Lukas Krejci
+ */
+public class BaseUpgradingDiscoveryComponent<T extends BaseResourceComponent> extends BaseDiscoveryComponent<T> implements ResourceUpgradeFacet<T> {
+
+ public ResourceUpgradeReport upgrade(ResourceUpgradeContext<T> inventoriedResource) {
+ Configuration pluginConfig = inventoriedResource.getPluginConfiguration();
+
+ BaseResourceComponent<?> parent = inventoriedResource.getParentResourceComponent();
+ int ordinal = pluginConfig.getSimple("ordinal").getIntegerValue();
+ int parentOrdinal = parent == null ? 0 : parent.getOrdinal();
+
+ boolean fail = Boolean.getBoolean(pluginConfig.getSimpleValue("failUpgrade", "false"));
+
+ if (!fail && parent != null) {
+ fail = parent.getChildrenToFailUpgrade().contains(Integer.valueOf(ordinal));
+ }
+
+ if (fail) {
+ throw new RuntimeException("Failing the resource upgrade purposefully.");
+ }
+
+ String newKey = pluginConfig.getSimpleValue("upgradedKey", null);
+
+ if (newKey == null) {
+ return null;
+ }
+
+ ResourceUpgradeReport report = new ResourceUpgradeReport();
+
+ report.setNewResourceKey(getResourceKey(newKey, ordinal, parentOrdinal));
+ return null;
+ }
+}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/rhq-plugin.xml
new file mode 100644
index 0000000..7edfba1
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/rhq-plugin.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plugin name="ResourceUpgradeMultiTestBase"
+ displayName=""
+ description=""
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <!--
+ Only the inheriting plugins create the concrete resources based on the
+ classes defined in this abstract base plugin.
+
+ These are the plugin configuration properties needed by the base plugin:
+
+ key = the template to create the resource key from
+ count = the number of resources to discover
+ upgradedKey = this *must* be specified on the resource type *to be upgraded* and
+ *must* be the same as the key template on the resource type that
+ it is upgraded to (i.e. the plugin.v1.upgradedKey == plugin.v2.key)
+
+ the discovery add a new property called "ordinal" to the plugin config
+ of the created resources, which contains the index of that resource amongst
+ its siblings.
+
+ the key template can contain %n which is replaced by the ordinal and %p which
+ is replaced by the ordinal of its parent.
+
+
+
+ if the discovery component of the concrete resource is (or inherits from)
+ BaseUpgradingDiscoveryComponent, it can specify further plugin config properties
+ influencing the upgrade:
+
+ failUpgrade = true to throw an exception during upgrade
+ -->
+
+</plugin>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/rhq-plugin.xml
new file mode 100644
index 0000000..3612974
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/rhq-plugin.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeMultiTestParentDep"
+ displayName="Resource Upgrade Multi Test"
+ description="Resource Upgrade Multi Test"
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
+ <depends plugin="ResourceUpgradeMultiTestRoot"/>
+
+ <server name="ParentDependency"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+
+ <runs-inside>
+ <parent-resource-type name="Root" plugin="ResourceUpgradeMultiTestRoot"/>
+ </runs-inside>
+
+ <plugin-configuration>
+ <c:simple-property name="count" default="1" />
+ <c:simple-property name="key" default="test-resource-parent-dep-%n,parent-%p" />
+ <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-parent-dep-%n,parent-%p" />
+ </plugin-configuration>
+
+ </server>
+
+</plugin>
+
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/rhq-plugin.xml
new file mode 100644
index 0000000..6b95114
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/rhq-plugin.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeMultiTestParentDep"
+ displayName="Resource Upgrade Multi Test"
+ description="Resource Upgrade Multi Test"
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="2.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
+ <depends plugin="ResourceUpgradeMultiTestRoot"/>
+
+ <server name="ParentDependency"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+
+ <runs-inside>
+ <parent-resource-type name="Root" plugin="ResourceUpgradeMultiTestRoot"/>
+ </runs-inside>
+
+ <plugin-configuration>
+ <c:simple-property name="count" default="1" />
+ <c:simple-property name="key" default="UPGRADED-test-resource-parent-dep-%n,parent-%p" />
+ </plugin-configuration>
+
+ </server>
+
+</plugin>
+
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml
new file mode 100644
index 0000000..fbade54
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeMultiTestParentSibling"
+ displayName="Resource Upgrade Multi Test"
+ description="Resource Upgrade Multi Test"
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
+ <depends plugin="ResourceUpgradeMultiTestRoot"/>
+
+ <server name="ParentDepSibling"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+
+ <runs-inside>
+ <parent-resource-type name="Root" plugin="ResourceUpgradeMultiTestRoot"/>
+ </runs-inside>
+
+ <plugin-configuration>
+ <c:simple-property name="count" default="1" />
+ <c:simple-property name="key" default="test-resource-parent-sibling-%n,parent-%p" />
+ <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-parent-sibling-%n,parent-%p" />
+ </plugin-configuration>
+
+ </server>
+
+</plugin>
+
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml
new file mode 100644
index 0000000..f16d526
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeMultiTestParentSibling"
+ displayName="Resource Upgrade Multi Test"
+ description="Resource Upgrade Multi Test"
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="2.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
+ <depends plugin="ResourceUpgradeMultiTestRoot"/>
+
+ <server name="ParentDepSibling"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+
+ <runs-inside>
+ <parent-resource-type name="Root" plugin="ResourceUpgradeMultiTestRoot"/>
+ </runs-inside>
+
+ <plugin-configuration>
+ <c:simple-property name="count" default="1" />
+ <c:simple-property name="key" default="UPGRADED-test-resource-parent-sibling-%n,parent-%p" />
+ </plugin-configuration>
+
+ </server>
+
+</plugin>
+
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/root/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/root/rhq-plugin.xml
new file mode 100644
index 0000000..b5efbb1
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/root/rhq-plugin.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeMultiTestRoot"
+ displayName=""
+ description=""
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <server name="Root"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+
+ <plugin-configuration>
+ <c:simple-property name="count" default="1" />
+ <c:simple-property name="key" default="test-resource-root-%n" />
+ </plugin-configuration>
+ </server>
+
+</plugin>
+
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
new file mode 100644
index 0000000..f87ef4d
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeMultiTestSibling"
+ displayName="Resource Upgrade Multi Test"
+ description="Resource Upgrade Multi Test"
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
+ <depends plugin="ResourceUpgradeMultiTestParentDep"/>
+
+ <server name="TestResourceParentSibling"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+
+ <plugin-configuration>
+ <c:simple-property name="count" default="2" />
+ <c:simple-property name="key" default="test-resource-parent-sibling-%n,parent-%p" />
+ <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-parent-sibling-%n,parent-%p" />
+ </plugin-configuration>
+
+ <service name="TestResourceSibling"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+ <plugin-configuration>
+ <c:simple-property name="count" default="10" />
+ <c:simple-property name="key" default="test-resource-sibling-%n,parent-%p" />
+ <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-sibling-%n,parent-%p" />
+ </plugin-configuration>
+
+ </service>
+ </server>
+
+</plugin>
+
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
new file mode 100644
index 0000000..e6ab95f
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plugin name="ResourceUpgradeMultiTestSibling"
+ displayName="Resource Upgrade Multi Test"
+ description="Resource Upgrade Multi Test"
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="2.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
+ <depends plugin="ResourceUpgradeMultiTestParentDep"/>
+
+ <server name="TestResourceParentSibling"
+ discovery="BaseUpgradingDiscoveryComponent"
+ class="BaseResourceComponent">
+
+ <runs-inside>
+ <parent-resource-type name="ParentDependency" plugin="ResourceUpgradeMultiTestParentDep"/>
+ </runs-inside>
+
+ <plugin-configuration>
+ <c:simple-property name="count" default="2" />
+ <c:simple-property name="key" default="UPGRADED-test-resource-parent-sibling-%n,parent-%p" />
+ </plugin-configuration>
+
+ <service name="TestResourceSibling"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+ <plugin-configuration>
+ <c:simple-property name="count" default="15" />
+ <c:simple-property name="key" default="UPGRADED-test-resource-sibling-%n,parent-%p" />
+ </plugin-configuration>
+
+ </service>
+
+
+ </server>
+
+</plugin>
+
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml
new file mode 100644
index 0000000..32ad438
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeMultiTest"
+ displayName="Resource Upgrade Multi Test"
+ description="Resource Upgrade Multi Test"
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
+ <depends plugin="ResourceUpgradeMultiTestParentDep"/>
+
+ <server name="TestResourceParent"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+
+ <runs-inside>
+ <parent-resource-type name="ParentDependency" plugin="ResourceUpgradeMultiTestParentDep"/>
+ </runs-inside>
+
+ <plugin-configuration>
+ <c:simple-property name="count" default="2" />
+ <c:simple-property name="key" default="test-resource-parent-%n,parent-%p" />
+ <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-parent-%n,parent-%p" />
+ </plugin-configuration>
+
+ <service name="TestResource"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+ <plugin-configuration>
+ <c:simple-property name="count" default="10" />
+ <c:simple-property name="key" default="test-resource-%n,parent-%p" />
+ <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-%n,parent-%p" />
+ </plugin-configuration>
+
+ </service>
+ </server>
+
+</plugin>
+
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
new file mode 100644
index 0000000..824d3fe
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plugin name="ResourceUpgradeMultiTest"
+ displayName="Resource Upgrade Multi Test"
+ description="Resource Upgrade Multi Test"
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="2.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
+ <depends plugin="ResourceUpgradeMultiTestParentDep"/>
+
+ <server name="TestResourceParent"
+ discovery="BaseUpgradingDiscoveryComponent"
+ class="BaseResourceComponent">
+
+ <runs-inside>
+ <parent-resource-type name="ParentDependency" plugin="ResourceUpgradeMultiTestParentDep"/>
+ </runs-inside>
+
+ <plugin-configuration>
+ <c:simple-property name="count" default="2" />
+ <c:simple-property name="key" default="UPGRADED-test-resource-parent-%n,parent-%p" />
+ </plugin-configuration>
+
+ <service name="TestResource"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+ <plugin-configuration>
+ <c:simple-property name="count" default="15" />
+ <c:simple-property name="key" default="UPGRADED-test-resource-%n,parent-%p" />
+ </plugin-configuration>
+
+ </service>
+
+
+ </server>
+
+</plugin>
+
commit c2f5b5363d1023106bc7e12a78999603c4c5f26e
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Sep 28 10:39:33 2010 +0200
remove the commented-out portions of the resource upgrade code.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 1b0ed8e..de52cd8 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -1232,10 +1232,7 @@ public class InventoryManager extends AgentService implements ContainerService,
for (ResourceUpgradeResponse upgradeResponse : serverUpdates) {
String resourceKey = upgradeResponse.getUpgradedResourceKey();
String name = upgradeResponse.getUpgradedResourceName();
- //String version = upgradeReport.getNewVersion();
String description = upgradeResponse.getUpgradedResourceDescription();
- //Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
- //Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
//only bother if there's something to upgrade at all on this resource.
if (resourceKey != null || name != null || description != null) {
@@ -1256,23 +1253,11 @@ public class InventoryManager extends AgentService implements ContainerService,
logMessage.append("name, ");
}
- //if (version != null) {
- // existingResource.setVersion(version);
- //}
-
if (description != null) {
existingResource.setDescription(description);
logMessage.append("description, ");
}
- //if (pluginConfiguration != null) {
- // existingResource.setPluginConfiguration(pluginConfiguration);
- //}
- //
- //if (resourceConfiguration != null) {
- // existingResource.setResourceConfiguration(resourceConfiguration);
- //}
-
logMessage.replace(logMessage.length() - 1, logMessage.length(), "to become [").append(
existingResource.toString()).append("]");
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index 51287b7..e4cbf03 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -495,10 +495,7 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
String resourceKey = upgradeRequest.getNewResourceKey();
String name = upgradeRequest.getNewName();
-// String version = upgradeReport.getNewVersion();
String description = upgradeRequest.getNewDescription();
-// Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
-// Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
if (resourceKey != null || name != null || description != null) {
StringBuilder logMessage = new StringBuilder("Resource [")
@@ -516,38 +513,12 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
}
ret.setUpgradedResourceName(resource.getName());
-// if (version != null) {
-// changed = updateResourceVersion(resource, version) || changed;
-// }
-
if (allowGenericPropertiesUpgrade && needsUpgrade(resource.getDescription(), description)) {
resource.setDescription(description);
logMessage.append("description, ");
}
ret.setUpgradedResourceDescription(resource.getDescription());
-
-// if (pluginConfiguration != null) {
-// if (!equalOrNull(pluginConfiguration, resource.getPluginConfiguration())) {
-// log.info("Resource [" + resource + "] upgraded its plugin configuration from [" +
-// resource.getPluginConfiguration() + "] to [" + pluginConfiguration + "]");
-// changed = true;
-// resource.setPluginConfiguration(pluginConfiguration);
-// }
-// }
-//
-// if (resourceConfiguration != null) {
-// if (!equalOrNull(resourceConfiguration, resource.getResourceConfiguration())) {
-// //XXX Will this create a new history entry?
-//
-// log.info("Resource [" + resource + "] upgraded its resource configuration from [" +
-// resource.getResourceConfiguration() + "] to [" + resourceConfiguration + "]");
-//
-// changed = true;
-// resource.setResourceConfiguration(resourceConfiguration);
-// }
-// }
-
-
+
//finally let's remove the potential previous upgrade error. we've now successfully
//upgraded the resource.
List<ResourceError> upgradeErrors = resourceManager.findResourceErrors(subjectManager.getOverlord(), resource.getId(), ResourceErrorType.UPGRADE);
commit 0ae5aa90c40d239e294857a961596ee500643dee
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Sep 28 10:36:32 2010 +0200
Clear the upgrade errors if the upgrade for given resource succeeds.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index a480fb7..51287b7 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -481,7 +481,7 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
* @param existingResource
* @param upgradeRequest
* @param allowGenericPropertiesUpgrade name and description are only upgraded if this is true
- * @return true if the resource was changed, false otherwise
+ * @return response to the upgrade request detailing what has been accepted on the server side
*/
private ResourceUpgradeResponse upgradeResource(@NotNull Resource resource, ResourceUpgradeRequest upgradeRequest, boolean allowGenericPropertiesUpgrade) {
if (upgradeRequest.getUpgradeErrorMessage() != null) {
@@ -547,6 +547,14 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
// }
// }
+
+ //finally let's remove the potential previous upgrade error. we've now successfully
+ //upgraded the resource.
+ List<ResourceError> upgradeErrors = resourceManager.findResourceErrors(subjectManager.getOverlord(), resource.getId(), ResourceErrorType.UPGRADE);
+ for(ResourceError error : upgradeErrors) {
+ entityManager.remove(error);
+ }
+
logMessage.replace(logMessage.length() - 1, logMessage.length(),
"to become [").append(resource.toString()).append("]");
commit c1b1f4dfdcf05c39879133c9fb562f8ecada6690
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Sep 24 14:32:23 2010 +0200
Handling the resource upgrade failure by disabling discovery of its siblings of the same type.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 563a786..1b0ed8e 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -192,7 +192,7 @@ public class InventoryManager extends AgentService implements ContainerService,
/**
* Handles the resource upgrade during the initialization of the inventory manager.
*/
- private ResourceUpgradeDelegate resourceUpgradeDelegate;
+ private ResourceUpgradeDelegate resourceUpgradeDelegate = new ResourceUpgradeDelegate(this);
public InventoryManager() {
super(DiscoveryAgentService.class);
@@ -222,7 +222,6 @@ public class InventoryManager extends AgentService implements ContainerService,
//try the resource upgrade before we have any schedulers set up
//so that we don't get any interventions from concurrently running
//discoveries.
- resourceUpgradeDelegate = new ResourceUpgradeDelegate(this);
upgradeResources();
availabilityCollectors = new AvailabilityCollectorThreadPool();
@@ -282,15 +281,24 @@ public class InventoryManager extends AgentService implements ContainerService,
* an empty set if nothing is discovered. This may return <code>null</code> if for some reason
* we could not invoke the discovery component.
*
+ * @param parentResourceContainer the container of the resource under which we are going to execute the discovery
* @param component the discovery component that will actually go out and discover resources
* @param context the context for use by the discovery component
* @return the details of all discovered resources, may be empty or <code>null</code>
*
* @throws Exception if the discovery component threw an exception
*/
- public Set<DiscoveredResourceDetails> invokeDiscoveryComponent(ResourceDiscoveryComponent component,
+ public Set<DiscoveredResourceDetails> invokeDiscoveryComponent(ResourceContainer parentResourceContainer, ResourceDiscoveryComponent component,
ResourceDiscoveryContext context) throws Exception {
+ Resource parentResource = parentResourceContainer == null ? null : parentResourceContainer.getResource();
+
+ if (resourceUpgradeDelegate.hasUpgradeFailedInChildren(parentResource, context.getResourceType())) {
+ log.debug("Discovery of [" + context.getResourceType() + "] has been disallowed under " + (parentResource == null ? " the platform " : parentResource) +
+ " because some of its siblings failed to upgrade.");
+ return null;
+ }
+
long timeout = getDiscoveryComponentTimeout(context.getResourceType());
try {
@@ -687,7 +695,7 @@ public class InventoryManager extends AgentService implements ContainerService,
// Ask the plugin's discovery component to find the new resource, throwing exceptions if it cannot be
// found at all.
- Set<DiscoveredResourceDetails> discoveredResources = invokeDiscoveryComponent(discoveryComponent,
+ Set<DiscoveredResourceDetails> discoveredResources = invokeDiscoveryComponent(parentResourceContainer, discoveryComponent,
discoveryContext);
if ((discoveredResources == null) || discoveredResources.isEmpty()) {
log.info("Plugin Error: During manual add, discovery component method ["
@@ -1207,7 +1215,7 @@ public class InventoryManager extends AgentService implements ContainerService,
return resourceContainer.updateAvailability(availabilityType);
}
- public void mergeResourceFromUpgrade(Set<ResourceUpgradeRequest> upgradeRequests) {
+ public void mergeResourcesFromUpgrade(Set<ResourceUpgradeRequest> upgradeRequests) {
Set<ResourceUpgradeResponse> serverUpdates = null;
try {
ServerServices serverServices = this.configuration.getServerServices();
@@ -1430,6 +1438,13 @@ public class InventoryManager extends AgentService implements ContainerService,
@SuppressWarnings("unchecked")
public void activateResource(Resource resource, @NotNull ResourceContainer container, boolean updatedPluginConfig)
throws InvalidPluginConfigurationException, PluginContainerException {
+ if (resourceUpgradeDelegate.hasUpgradeFailed(resource)) {
+ if (log.isTraceEnabled()) {
+ log.trace("Skipping activation of " + resource + " - it has failed to upgrade.");
+ }
+ return;
+ }
+
ResourceComponent component = container.getResourceComponent();
// if the component already exists and is started, and the resource's plugin config has not changed, there is
@@ -1762,7 +1777,7 @@ public class InventoryManager extends AgentService implements ContainerService,
* Shutdown the ResourceComponents from the bottom up.
* @param resource The resource to deactivate
*/
- private void deactivateResource(Resource resource) {
+ public void deactivateResource(Resource resource) {
this.inventoryLock.writeLock().lock();
try {
ResourceContainer container = getResourceContainer(resource);
@@ -1841,7 +1856,7 @@ public class InventoryManager extends AgentService implements ContainerService,
Set<DiscoveredResourceDetails> discoveredResources = null;
try {
- discoveredResources = invokeDiscoveryComponent(component, context);
+ discoveredResources = invokeDiscoveryComponent(null, component, context);
} catch (Throwable e) {
log.warn("Platform plugin discovery failed - skipping", e);
}
@@ -2043,6 +2058,13 @@ public class InventoryManager extends AgentService implements ContainerService,
}
}
+ /**
+ * @return true if the inventory manager failed to merge the upgrade requests with the server during startup.
+ */
+ public boolean hasUpgradeMergeFailed() {
+ return resourceUpgradeDelegate.hasUpgradeMergeFailed();
+ }
+
/**
* Always use this before accessing the event listeners because this ensures
* thread safety.
@@ -2171,7 +2193,7 @@ public class InventoryManager extends AgentService implements ContainerService,
parentResourceContext, SystemInfoFactory.createSystemInfo(), processScanResults,
Collections.EMPTY_LIST, this.configuration.getContainerName(), this.configuration
.getPluginContainerDeployment());
- Set<DiscoveredResourceDetails> discoveredResources = invokeDiscoveryComponent(discoveryComponent, context);
+ Set<DiscoveredResourceDetails> discoveredResources = invokeDiscoveryComponent(parentContainer, discoveryComponent, context);
newResources = new HashSet<Resource>();
if ((discoveredResources != null) && (!discoveredResources.isEmpty())) {
IdentityHashMap<Configuration, DiscoveredResourceDetails> pluginConfigObjects = new IdentityHashMap<Configuration, DiscoveredResourceDetails>();
@@ -2613,6 +2635,12 @@ public class InventoryManager extends AgentService implements ContainerService,
private void upgradeResources() {
try {
+
+ if (!configuration.isInsideAgent()) {
+ log.debug("Skipping resource upgrade in embedded mode.");
+ return;
+ }
+
log.debug("Executing resource upgrade.");
boolean syncResult = handleReport(new InventoryReport(getAgent()), true);
@@ -2622,7 +2650,7 @@ public class InventoryManager extends AgentService implements ContainerService,
}
upgradeResource(getPlatform());
-
+
log.debug("Sending the upgrade requests to the server.");
resourceUpgradeDelegate.sendRequests();
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
index 025ba3a..98a897e 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
@@ -19,15 +19,17 @@
package org.rhq.core.pc.upgrade;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-
import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.pc.PluginContainer;
import org.rhq.core.pc.inventory.InventoryManager;
@@ -56,7 +58,10 @@ public class ResourceUpgradeDelegate {
private Set<ResourceUpgradeRequest> requests = new HashSet<ResourceUpgradeRequest>();
private InventoryManager inventoryManager;
-
+ private Set<Resource> failedResources = new HashSet<Resource>();
+ private Map<Resource, Set<ResourceType>> failedResourceTypesPerParent = new HashMap<Resource, Set<ResourceType>>();
+ private boolean mergeFailed;
+
public ResourceUpgradeDelegate(InventoryManager inventoryManager) {
this.inventoryManager = inventoryManager;
}
@@ -88,11 +93,56 @@ public class ResourceUpgradeDelegate {
}
}
- public void sendRequests() {
- if (enabled) {
- if (requests.size() > 0) {
- inventoryManager.mergeResourceFromUpgrade(requests);
- requests.clear();
+ /**
+ * @return true if {@link #sendRequests()} threw an exception, false otherwise
+ */
+ public boolean hasUpgradeMergeFailed() {
+ return mergeFailed;
+ }
+
+ /**
+ * Tells whether given resource had a upgrade failure during the {@link #processAndQueue(ResourceContainer)} invocation.
+ *
+ * @param resource the resource to test
+ * @return true if there was an error upgrading this resource, false otherwise
+ */
+ public boolean hasUpgradeFailed(Resource resource) {
+ return mergeFailed || failedResources.contains(resource);
+ }
+
+ /**
+ * Tells whether at least one of the children with given resource type of the given parent resource
+ * had an upgrade failure during {@link #processAndQueue(ResourceContainer)} invocation.
+ *
+ * @return true if at least one of the children of given type failed to upgrade, false otherwise
+ */
+ public boolean hasUpgradeFailedInChildren(Resource parentResource, ResourceType childrenResourceType) {
+ if (mergeFailed) {
+ return true;
+ }
+
+ Set<ResourceType> failedTypes = failedResourceTypesPerParent.get(parentResource);
+
+ return failedTypes != null && failedTypes.contains(childrenResourceType);
+ }
+
+ public void sendRequests() throws Throwable {
+ if (enabled && requests.size() > 0) {
+ try {
+ inventoryManager.mergeResourcesFromUpgrade(requests);
+ } catch (Throwable t) {
+ mergeFailed = true;
+
+ //deactivate all the resources to be upgraded. We might have a problem
+ //because they have not been upgraded because the merge failed.
+ for(ResourceUpgradeRequest request : requests) {
+ ResourceContainer container = inventoryManager.getResourceContainer(request.getResourceId());
+ if (container != null) {
+ inventoryManager.deactivateResource(container.getResource());
+ }
+ }
+
+ throw t;
}
}
}
@@ -157,6 +207,20 @@ public class ResourceUpgradeDelegate {
if (request.hasSomethingToUpgrade()) {
requests.add(request);
}
+
+ if (request.getUpgradeErrorMessage() != null) {
+ failedResources.add(resource);
+
+ Set<ResourceType> failedResourceTypesInParent = failedResourceTypesPerParent.get(parentResource);
+ if (failedResourceTypesInParent == null) {
+ failedResourceTypesInParent = new HashSet<ResourceType>();
+ failedResourceTypesPerParent.put(parentResource, failedResourceTypesInParent);
+ }
+
+ failedResourceTypesInParent.add(resource.getResourceType());
+
+ inventoryManager.deactivateResource(resource);
+ }
}
private String checkUpgradeValid(Resource resource, ResourceUpgradeReport upgradeReport) {
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 244d2f2..1479345 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -237,6 +237,14 @@ public class ResourceUpgradeTest {
TestPayload test = new TestPayload() {
public void test(Resource resourceUpgradeTestResource) {
assertTrue(resourceUpgradeTestResource.getResourceErrors().size() > 0, "There should be upgrade errors persisted on the server side.");
+
+ //the discovery of the failed resource mustn't have run
+ ResourceContainer container = PluginContainer.getInstance().getInventoryManager().getResourceContainer(resourceUpgradeTestResource);
+ File dataDir = container.getResourceContext().getDataDirectory();
+
+ File marker = new File(dataDir, "failing-discovery-ran");
+
+ assertFalse(marker.exists(), "The discovery of the resource type with a failed upgraded resource must not be executed but it was.");
}
@SuppressWarnings("unchecked")
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/DiscComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/DiscComponent.java
index 54153e6..75bfbd7 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/DiscComponent.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/DiscComponent.java
@@ -19,6 +19,8 @@
package org.rhq.core.pc.upgrade.plugins.failing;
+import java.io.File;
+import java.io.IOException;
import java.util.Collections;
import java.util.Set;
@@ -44,6 +46,20 @@ public class DiscComponent implements ResourceDiscoveryComponent<ResourceCompone
public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext<ResourceComponent> context)
throws InvalidPluginConfigurationException, Exception {
+
+ //create a marker file so that the testing code knows this method has run
+ File dataDir = context.getParentResourceContext().getDataDirectory();
+ if (dataDir != null) {
+ if (!(dataDir.exists())) {
+ dataDir.mkdir();
+ }
+ File marker = new File(dataDir, "failing-discovery-ran");
+ try {
+ marker.createNewFile();
+ } catch (IOException e) {
+ }
+ }
+
return Collections.singleton(new DiscoveredResourceDetails(context.getResourceType(), RESOURCE_KEY,
RESOURCE_NAME, null, RESOURCE_DESCRIPTION, context.getDefaultPluginConfiguration(), null));
}
diff --git a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
index d1894cb..43c2ba5 100644
--- a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
+++ b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
@@ -91,6 +91,7 @@ import org.rhq.core.domain.cloud.composite.FailoverListComposite.ServerEntry;
import org.rhq.core.pc.PluginContainer;
import org.rhq.core.pc.PluginContainerConfiguration;
import org.rhq.core.pc.ServerServices;
+import org.rhq.core.pc.inventory.InventoryManager;
import org.rhq.core.pc.plugin.FileSystemPluginFinder;
import org.rhq.core.system.SystemInfoFactory;
import org.rhq.core.util.ObjectNameFactory;
@@ -1591,6 +1592,7 @@ public class AgentMain {
* <ul>
* <li>Registering with the server (if the agent needs to do so at startup)</li>
* <li>Updating the plugins with the latest versions that are found on the server</li>
+ * <li>Setup a conditional restart of the plugin container, see {@link PluginContainerConditionalRestartListener}</li>
* </ul>
*
* @return <code>true</code> if the agent is not registered or the agent was asked to re-register with the server;
@@ -1623,6 +1625,10 @@ public class AgentMain {
updatePlugins();
}
+ //the next thing is to setup the conditional restart of the PC if it fails to merge
+ //the upgrade results with the server due to some network glitch
+ m_clientSender.addStateListener(new PluginContainerConditionalRestartListener(), false);
+
return register;
}
@@ -3390,6 +3396,42 @@ public class AgentMain {
}
/**
+ * This listener restarts the plugin container upon establishing the connection with the server
+ * if the following conditions are met:
+ * <ol>
+ * <li> The plugin container is started
+ * <li> It performed the resource upgrade but failed to merge the changes to the server
+ * </ol>
+ * By restarting the plugin container in such conditions, we essentially re-run the resource upgrade
+ * and let the plugin container try to re-merge with the server that we know has just connected.
+ *
+ * @author Lukas Krejci
+ */
+ private class PluginContainerConditionalRestartListener implements ClientCommandSenderStateListener {
+ public boolean startedSending(ClientCommandSender sender) {
+ try {
+ InventoryManager inventoryManager = PluginContainer.getInstance().getInventoryManager();
+ if (inventoryManager != null && inventoryManager.hasUpgradeMergeFailed()) {
+ m_output.println(MSG.getMsg(AgentI18NResourceKeys.RESTARTING_PLUGIN_CONTAINER_AFTER_UPGRADE_MERGE_FAILURE));
+ LOG.info(AgentI18NResourceKeys.RESTARTING_PLUGIN_CONTAINER_AFTER_UPGRADE_MERGE_FAILURE);
+
+ PluginContainerPromptCommand pcCommand = new PluginContainerPromptCommand();
+ pcCommand.execute(AgentMain.this, new String[] { "stop" });
+ pcCommand.execute(AgentMain.this, new String[] { "start" });
+ }
+ } catch (Exception e) {
+ LOG.error("Failed to restart the plugin container when server connection established.");
+ }
+ return true;
+ }
+
+ public boolean stoppedSending(ClientCommandSender sender) {
+ //do nothing but keep listening
+ return true;
+ }
+ }
+
+ /**
* When the agent starts up, it needs to create the communications servers before starting the plugin container;
* however, the agent must not process any incoming commands until after the plugin container fully starts. This
* command listener will actually block indefinitely all commands from being processed until its told to open the
diff --git a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/i18n/AgentI18NResourceKeys.java b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/i18n/AgentI18NResourceKeys.java
index eb1df86..c28349c 100644
--- a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/i18n/AgentI18NResourceKeys.java
+++ b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/i18n/AgentI18NResourceKeys.java
@@ -2050,4 +2050,7 @@ public interface AgentI18NResourceKeys {
@I18NMessage("Done.")
String AVAILABILITY_REPORT_SENT = "PromptCommand.availability.sent";
+
+ @I18NMessage("Restarting the plugin container due to previous failure to merge the upgrade results with the server.")
+ String RESTARTING_PLUGIN_CONTAINER_AFTER_UPGRADE_MERGE_FAILURE = "AgentMain.pc-conditional-restart";
}
\ No newline at end of file
diff --git a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/promptcmd/DiscoveryPromptCommand.java b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/promptcmd/DiscoveryPromptCommand.java
index 8736f05..1de2dfb 100644
--- a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/promptcmd/DiscoveryPromptCommand.java
+++ b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/promptcmd/DiscoveryPromptCommand.java
@@ -359,7 +359,7 @@ public class DiscoveryPromptCommand implements AgentPromptCommand {
PluginContainerDeployment.AGENT);
Set<DiscoveredResourceDetails> discoveredResources;
- discoveredResources = inventoryManager.invokeDiscoveryComponent(discoveryComponent, context);
+ discoveredResources = inventoryManager.invokeDiscoveryComponent(platformContainer, discoveryComponent, context);
if (discoveredResources != null) {
for (DiscoveredResourceDetails discoveredResource : discoveredResources) {
out.println(MSG.getMsg(AgentI18NResourceKeys.DISCOVERY_COMPONENT_RESULT, discoveredResource
diff --git a/modules/enterprise/agent/src/test/java/org/rhq/enterprise/agent/PluginContainerConditionalRestart.java b/modules/enterprise/agent/src/test/java/org/rhq/enterprise/agent/PluginContainerConditionalRestart.java
new file mode 100644
index 0000000..b88d097
--- /dev/null
+++ b/modules/enterprise/agent/src/test/java/org/rhq/enterprise/agent/PluginContainerConditionalRestart.java
@@ -0,0 +1,31 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.enterprise.agent;
+
+import org.testng.annotations.Test;
+
+/**
+ *
+ * @author Lukas Krejci
+ */
+@Test
+public class PluginContainerConditionalRestart {
+ //TODO implement
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
index 29815cc..95bec5f 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
@@ -23,7 +23,11 @@ import org.rhq.core.domain.resource.composite.ResourceComposite;
import org.rhq.enterprise.gui.coregui.client.components.table.Table;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
+import com.smartgwt.client.data.DSCallback;
+import com.smartgwt.client.data.DSRequest;
+import com.smartgwt.client.data.DSResponse;
import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.types.GroupStartOpen;
import com.smartgwt.client.widgets.HTMLPane;
import com.smartgwt.client.widgets.IButton;
import com.smartgwt.client.widgets.Window;
@@ -41,43 +45,37 @@ import com.smartgwt.client.widgets.grid.events.CellClickHandler;
public class OverviewView extends LocatableVLayout {
private ResourceComposite resourceComposite;
-
+ private OverviewForm form;
+ private Table errorsGrid;
+
public OverviewView(String locatorId, ResourceComposite resourceComposite) {
super(locatorId);
this.resourceComposite = resourceComposite;
- }
-
- @Override
- protected void onDraw() {
- super.onDraw();
-
- setLeft("10%");
- setWidth("80%");
-
- if (this.resourceComposite != null) {
- onResourceSelected(this.resourceComposite);
- }
- }
-
- public void onResourceSelected(ResourceComposite resourceComposite) {
- addMember(new OverviewForm(extendLocatorId("form"), resourceComposite));
- buildErrorListGrid(resourceComposite);
- }
+ form = new OverviewForm(extendLocatorId("form"), resourceComposite);
+ errorsGrid = new Table(extendLocatorId("errors"), "Detected errors", null, null, new String[] { ResourceErrorsDataSource.DETAIL_ID });
- private void buildErrorListGrid(ResourceComposite resourceComposite) {
- final Resource resource = resourceComposite.getResource();
- final Table errorsGrid = new Table(extendLocatorId("errors"));
+ Resource resource = resourceComposite.getResource();
+ ResourceErrorsDataSource errors = new ResourceErrorsDataSource(resource.getId());
errorsGrid.setShowFooter(false);
-// errorsGrid.getListGrid().setGroupByField(ResourceErrorsDataSource.ERROR_TYPE_ID);
-// errorsGrid.getListGrid().setGroupStartOpen(GroupStartOpen.ALL);
-// errorsGrid.getListGrid().setShowGroupSummary(true);
-
- errorsGrid.setDataSource(new ResourceErrorsDataSource(resource.getId()));
+ errorsGrid.setDataSource(errors);
- //hide only works after we set the datasource
- errorsGrid.getListGrid().hideField(ResourceErrorsDataSource.DETAIL_ID);
+ form.setHeight("*");
+ errorsGrid.setHeight("10%");
+ addMember(form);
+ addMember(errorsGrid);
+
+ }
+
+ @Override
+ public void onInit() {
+ super.onInit();
+ initErrorsGrid();
+ }
+
+ private void initErrorsGrid() {
+ errorsGrid.setTooltip("Click on the rows to see the error details.");
errorsGrid.getListGrid().addCellClickHandler(new CellClickHandler() {
public void onCellClick(CellClickEvent event) {
ListGridRecord record = event.getRecord();
@@ -113,7 +111,5 @@ public class OverviewView extends LocatableVLayout {
w.show();
}
});
-
- addMember(errorsGrid);
}
}
commit 34483f9ca83545ab317caf12545531ab5d9b31e9
Merge: b9e1f2c... 24ba997...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Sep 20 16:58:46 2010 +0200
Merge branch 'master' into resource-upgrade
diff --cc modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewForm.java
index 074b3c9,0000000..2479c87
mode 100644,000000..100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewForm.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewForm.java
@@@ -1,298 -1,0 +1,299 @@@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.summary;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.EnumSet;
+import java.util.List;
+
+import org.rhq.core.domain.measurement.DataType;
+import org.rhq.core.domain.measurement.DisplayType;
+import org.rhq.core.domain.measurement.MeasurementDataTrait;
+import org.rhq.core.domain.measurement.MeasurementDefinition;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.resource.composite.ResourceComposite;
+import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.components.form.EnhancedDynamicForm;
+import org.rhq.enterprise.gui.coregui.client.components.form.TogglableTextItem;
+import org.rhq.enterprise.gui.coregui.client.components.form.ValueUpdatedHandler;
+import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGWTServiceAsync;
+import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
+import org.rhq.enterprise.gui.coregui.client.util.message.Message;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.util.SC;
+import com.smartgwt.client.widgets.form.fields.FormItem;
+import com.smartgwt.client.widgets.form.fields.HeaderItem;
+import com.smartgwt.client.widgets.form.fields.SpacerItem;
+import com.smartgwt.client.widgets.form.fields.StaticTextItem;
+
+/**
+ * The Resource Summary>Overview tab, the form with resource data.
+ *
+ * @author Greg Hinkle
+ * @author Ian Springer
+ */
+public class OverviewForm extends EnhancedDynamicForm {
+
+ private ResourceGWTServiceAsync resourceService = GWTServiceLookup.getResourceService();
+ private ResourceComposite resourceComposite;
+
- public OverviewForm(ResourceComposite resourceComposite) {
++ public OverviewForm(String locatorId, ResourceComposite resourceComposite) {
++ super(locatorId);
+ this.resourceComposite = resourceComposite;
+ }
+
+ @Override
+ protected void onDraw() {
+ super.onDraw();
+
+ setLeft("10%");
+ setWidth("80%");
+
+ if (this.resourceComposite != null) {
+ setResource(this.resourceComposite);
+ }
+ }
+
+ public void setResource(ResourceComposite resourceComposite) {
+
+ this.resourceComposite = resourceComposite;
+ Resource resource = resourceComposite.getResource();
+
+ // Load metric defs.
+ ResourceTypeRepository.Cache.getInstance().getResourceTypes(resource.getResourceType().getId(),
+ EnumSet.of(ResourceTypeRepository.MetadataType.measurements),
+ new ResourceTypeRepository.TypeLoadedCallback() {
+ public void onTypesLoaded(ResourceType type) {
+ try {
+ buildForm(type);
+ loadTraitValues();
+ } catch (Exception e) {
+ SC.say("Form load failure");
+ e.printStackTrace();
+ }
+ }
+ });
+ }
+
+ private void loadTraitValues() {
+ final Resource resource = resourceComposite.getResource();
+ GWTServiceLookup.getMeasurementDataService().findCurrentTraitsForResource(
+ resource.getId(),
+ DisplayType.SUMMARY,
+ new AsyncCallback<List<MeasurementDataTrait>>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Failed to load traits for " + resource + ".",
+ caught);
+ }
+
+ public void onSuccess(List<MeasurementDataTrait> result) {
+ // TODO: Implement this method.
+ for (MeasurementDataTrait trait : result) {
+ String formId = trait.getName().replaceAll("\\.", "_").replaceAll(" ", "__");
+ FormItem item = getItem(formId);
+
+ if (item != null) {
+ setValue(formId, trait.getValue());
+ }
+ }
+ markForRedraw();
+ }
+ }
+ );
+
+ }
+
+ private void buildForm(ResourceType type) {
+ List<MeasurementDefinition> traits = new ArrayList<MeasurementDefinition>();
+
+ for (MeasurementDefinition measurement : type.getMetricDefinitions()) {
+ if (measurement.getDataType() == DataType.TRAIT && measurement.getDisplayType() == DisplayType.SUMMARY) {
+ traits.add(measurement);
+ }
+ }
+
+ Collections.sort(traits, new Comparator<MeasurementDefinition>() {
+ public int compare(MeasurementDefinition o1, MeasurementDefinition o2) {
+ return new Integer(o1.getDisplayOrder()).compareTo(o2.getDisplayOrder());
+ }
+ });
+
+ List<FormItem> formItems = new ArrayList<FormItem>();
+
+ HeaderItem headerItem = new HeaderItem("header", "Summary");
+ headerItem.setValue("Summary");
+ formItems.add(headerItem);
+
+ StaticTextItem typeItem = new StaticTextItem("type", "Type");
+ typeItem.setTooltip("Plugin: " + type.getPlugin() + "\n<br>" + "Type: " + type.getName());
+ typeItem.setValue(type.getName() + " (" + type.getPlugin() + ")");
+ formItems.add(typeItem);
+
+ final Resource resource = this.resourceComposite.getResource();
+ boolean modifiable = this.resourceComposite.getResourcePermission().isInventory();
+
+ final FormItem nameItem = (modifiable) ? new TogglableTextItem() : new StaticTextItem();
+ nameItem.setName("name");
+ nameItem.setTitle("Name");
+ nameItem.setValue(resource.getName());
+ if (nameItem instanceof TogglableTextItem) {
+ TogglableTextItem togglableNameItem = (TogglableTextItem) nameItem;
+ togglableNameItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
+ public void onValueUpdated(final String newName) {
+ final String oldName = resource.getName();
+ if (newName.equals(oldName)) {
+ return;
+ }
+ resource.setName(newName);
+ OverviewForm.this.resourceService.updateResource(resource, new AsyncCallback<Void>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Failed to change name of Resource with id "
+ + resource.getId()
+ + " from \"" + oldName + "\" to \"" + newName + "\".", caught);
+ // We failed to update it on the Server, so change back the Resource and the form item to
+ // the original value.
+ resource.setName(oldName);
+ nameItem.setValue(oldName);
+ }
+
+ public void onSuccess(Void result) {
+ CoreGUI.getMessageCenter().notify(new Message("Name of Resource with id "
+ + resource.getId() + " was changed from \""
+ + oldName + "\" to \"" + newName + "\".", Message.Severity.Info));
+ }
+ });
+ }
+ });
+ }
+ formItems.add(nameItem);
+
+ final FormItem descriptionItem = (modifiable) ? new TogglableTextItem() : new StaticTextItem();
+ descriptionItem.setName("description");
+ descriptionItem.setTitle("Description");
+ descriptionItem.setValue(resource.getDescription());
+ if (descriptionItem instanceof TogglableTextItem) {
+ TogglableTextItem togglableDescriptionItem = (TogglableTextItem) descriptionItem;
+ togglableDescriptionItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
+ public void onValueUpdated(final String newDescription) {
+ final String oldDescription = resource.getDescription();
+ if (newDescription.equals(oldDescription)) {
+ return;
+ }
+ resource.setDescription(newDescription);
+ OverviewForm.this.resourceService.updateResource(resource, new AsyncCallback<Void>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Failed to change description of Resource with id "
+ + resource.getId()
+ + " from \"" + oldDescription + "\" to \"" + newDescription + "\".", caught);
+ // We failed to update it on the Server, so change back the Resource and the form item to
+ // the original value.
+ resource.setDescription(oldDescription);
+ descriptionItem.setValue(oldDescription);
+ }
+
+ public void onSuccess(Void result) {
+ CoreGUI.getMessageCenter().notify(new Message("Description of Resource with id "
+ + resource.getId() + " was changed from \""
+ + oldDescription + "\" to \"" + newDescription + "\".", Message.Severity.Info));
+ }
+ });
+ }
+ });
+ }
+ formItems.add(descriptionItem);
+
+ final FormItem locationItem = (modifiable) ? new TogglableTextItem() : new StaticTextItem();
+ locationItem.setName("location");
+ locationItem.setTitle("Location");
+ locationItem.setValue(resource.getLocation());
+ if (locationItem instanceof TogglableTextItem) {
+ TogglableTextItem togglableNameItem = (TogglableTextItem) locationItem;
+ togglableNameItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
+ public void onValueUpdated(final String newLocation) {
+ final String oldLocation = resource.getLocation();
+ if (newLocation.equals(oldLocation)) {
+ return;
+ }
+ resource.setLocation(newLocation);
+ OverviewForm.this.resourceService.updateResource(resource, new AsyncCallback<Void>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Failed to change location of Resource with id "
+ + resource.getId()
+ + " from \"" + oldLocation + "\" to \"" + newLocation + "\".", caught);
+ // We failed to update it on the Server, so change back the Resource and the form item to
+ // the original value.
+ resource.setLocation(oldLocation);
+ locationItem.setValue(oldLocation);
+ }
+
+ public void onSuccess(Void result) {
+ CoreGUI.getMessageCenter().notify(new Message("Location of Resource with id "
+ + resource.getId() + " was changed from \""
+ + oldLocation + "\" to \"" + newLocation + "\".", Message.Severity.Info));
+ }
+ });
+ }
+ });
+ }
+ formItems.add(locationItem);
+
+
+ StaticTextItem versionItem = new StaticTextItem("version", "Version");
+ formItems.add(versionItem);
+
+ StaticTextItem parentItem = new StaticTextItem("parent", "Parent");
+ formItems.add(parentItem);
+
+ for (MeasurementDefinition trait : traits) {
+ String id = trait.getDisplayName().replaceAll("\\.", "_").replaceAll(" ", "__");
+
+ StaticTextItem item = new StaticTextItem(id, trait.getDisplayName());
+ item.setTooltip(trait.getDescription());
+ formItems.add(item);
+// item.setValue("?");
+ }
+
+// SectionItem section = new SectionItem("Summary", "Summary");
+// section.setTitle("Summary");
+// section.setDefaultValue("Summary");
+// section.setCanCollapse(true);
+// section.setCellStyle("HidablePlainSectionHeader");
+// section.setItemIds(itemIds.toArray(new String[itemIds.size()]));
+// formItems.add(0, section);
+
+ formItems.add(new SpacerItem());
+ setItems(formItems.toArray(new FormItem[formItems.size()]));
+
+ setValue("type", type.getName() + " (" + type.getPlugin() + ")");
+ setValue("name", resource.getName());
+ setValue("description", resource.getDescription());
+ setValue("location", resource.getLocation());
+ setValue("version", (resource.getVersion() != null) ? resource.getVersion() : "<i>none</i>");
+ Resource parentResource = resource.getParentResource();
+ setValue("parent", parentResource != null ?
+ ("<a href=\"#Resource/" + parentResource.getId() + "\">" +
+ parentResource.getName() + "</a>") : "<i>none</i>");
+ }
+}
diff --cc modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
index 10bde5b,4cf2119..29815cc
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
@@@ -18,31 -18,49 +18,32 @@@
*/
package org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.summary;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.EnumSet;
-import java.util.List;
-
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.smartgwt.client.util.SC;
-import com.smartgwt.client.widgets.form.fields.FormItem;
-import com.smartgwt.client.widgets.form.fields.HeaderItem;
-import com.smartgwt.client.widgets.form.fields.SpacerItem;
-import com.smartgwt.client.widgets.form.fields.StaticTextItem;
-
-import org.rhq.core.domain.measurement.DataType;
-import org.rhq.core.domain.measurement.DisplayType;
-import org.rhq.core.domain.measurement.MeasurementDataTrait;
-import org.rhq.core.domain.measurement.MeasurementDefinition;
import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.composite.ResourceComposite;
-import org.rhq.enterprise.gui.coregui.client.CoreGUI;
-import org.rhq.enterprise.gui.coregui.client.components.form.EnhancedDynamicForm;
-import org.rhq.enterprise.gui.coregui.client.components.form.TogglableTextItem;
-import org.rhq.enterprise.gui.coregui.client.components.form.ValueUpdatedHandler;
-import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
-import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGWTServiceAsync;
-import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceSelectListener;
-import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
-import org.rhq.enterprise.gui.coregui.client.util.message.Message;
+import org.rhq.enterprise.gui.coregui.client.components.table.Table;
++import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
+
+import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.widgets.HTMLPane;
+import com.smartgwt.client.widgets.IButton;
+import com.smartgwt.client.widgets.Window;
+import com.smartgwt.client.widgets.events.ClickEvent;
+import com.smartgwt.client.widgets.events.ClickHandler;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+import com.smartgwt.client.widgets.grid.events.CellClickEvent;
+import com.smartgwt.client.widgets.grid.events.CellClickHandler;
- import com.smartgwt.client.widgets.layout.VLayout;
/**
* The Resource Summary>Overview tab.
*
- * @author Greg Hinkle
- * @author Ian Springer
+ * @author Lukas Krejci
*/
- public class OverviewView extends VLayout {
-public class OverviewView extends EnhancedDynamicForm implements ResourceSelectListener {
++public class OverviewView extends LocatableVLayout {
- private ResourceGWTServiceAsync resourceService = GWTServiceLookup.getResourceService();
private ResourceComposite resourceComposite;
- public OverviewView(ResourceComposite resourceComposite) {
+ public OverviewView(String locatorId, ResourceComposite resourceComposite) {
+ super(locatorId);
this.resourceComposite = resourceComposite;
}
@@@ -59,60 -77,218 +60,60 @@@
}
public void onResourceSelected(ResourceComposite resourceComposite) {
- addMember(new OverviewForm(resourceComposite));
-
- this.resourceComposite = resourceComposite;
- Resource resource = resourceComposite.getResource();
-
- // Load metric defs.
- ResourceTypeRepository.Cache.getInstance().getResourceTypes(resource.getResourceType().getId(),
- EnumSet.of(ResourceTypeRepository.MetadataType.measurements),
- new ResourceTypeRepository.TypeLoadedCallback() {
- public void onTypesLoaded(ResourceType type) {
- try {
- buildForm(type);
- loadTraitValues();
- } catch (Exception e) {
- SC.say("Form load failure");
- e.printStackTrace();
- }
- }
- });
++ addMember(new OverviewForm(extendLocatorId("form"), resourceComposite));
+ buildErrorListGrid(resourceComposite);
}
- private void loadTraitValues() {
+ private void buildErrorListGrid(ResourceComposite resourceComposite) {
final Resource resource = resourceComposite.getResource();
- Table errorsGrid = new Table("Errors");
- GWTServiceLookup.getMeasurementDataService().findCurrentTraitsForResource(resource.getId(),
- DisplayType.SUMMARY, new AsyncCallback<List<MeasurementDataTrait>>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError("Failed to load traits for " + resource + ".", caught);
- }
-
- public void onSuccess(List<MeasurementDataTrait> result) {
- // TODO: Implement this method.
- for (MeasurementDataTrait trait : result) {
- String formId = trait.getName().replaceAll("\\.", "_").replaceAll(" ", "__");
- FormItem item = getItem(formId);
-
- if (item != null) {
- setValue(formId, trait.getValue());
- }
++ final Table errorsGrid = new Table(extendLocatorId("errors"));
+
+ errorsGrid.setShowFooter(false);
+// errorsGrid.getListGrid().setGroupByField(ResourceErrorsDataSource.ERROR_TYPE_ID);
+// errorsGrid.getListGrid().setGroupStartOpen(GroupStartOpen.ALL);
+// errorsGrid.getListGrid().setShowGroupSummary(true);
+
+ errorsGrid.setDataSource(new ResourceErrorsDataSource(resource.getId()));
+
+ //hide only works after we set the datasource
+ errorsGrid.getListGrid().hideField(ResourceErrorsDataSource.DETAIL_ID);
+
+ errorsGrid.getListGrid().addCellClickHandler(new CellClickHandler() {
+ public void onCellClick(CellClickEvent event) {
+ ListGridRecord record = event.getRecord();
+ final Window w = new Window();
+ w.setTitle("Error Details");
+ w.setIsModal(true);
+ w.setShowMinimizeButton(false);
+ w.setShowModalMask(true);
+ w.setWidth(640);
+ w.setHeight(480);
+ w.centerInPage();
+ w.setCanDragResize(true);
+
- VLayout layout = new VLayout(10);
++ LocatableVLayout layout = new LocatableVLayout(errorsGrid.extendLocatorId("dialogLayout"), 10);
+ layout.setDefaultLayoutAlign(Alignment.CENTER);
+ layout.setLayoutMargin(10);
+
+ w.addItem(layout);
+
+ HTMLPane details = new HTMLPane();
+ details.setContents("<pre>" + record.getAttribute(ResourceErrorsDataSource.DETAIL_ID) + "</pre>");
+ layout.addMember(details);
+
+ IButton ok = new IButton("Ok");
+ ok.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ w.destroy();
}
- markForRedraw();
- }
- });
-
- }
-
- private void buildForm(ResourceType type) {
- List<MeasurementDefinition> traits = new ArrayList<MeasurementDefinition>();
-
- for (MeasurementDefinition measurement : type.getMetricDefinitions()) {
- if (measurement.getDataType() == DataType.TRAIT && measurement.getDisplayType() == DisplayType.SUMMARY) {
- traits.add(measurement);
- }
- }
-
- Collections.sort(traits, new Comparator<MeasurementDefinition>() {
- public int compare(MeasurementDefinition o1, MeasurementDefinition o2) {
- return new Integer(o1.getDisplayOrder()).compareTo(o2.getDisplayOrder());
+ });
+
+ layout.addMember(ok);
+
+ w.show();
}
});
-
- List<FormItem> formItems = new ArrayList<FormItem>();
-
- HeaderItem headerItem = new HeaderItem("header", "Summary");
- headerItem.setValue("Summary");
- formItems.add(headerItem);
-
- StaticTextItem typeItem = new StaticTextItem("type", "Type");
- typeItem.setTooltip("Plugin: " + type.getPlugin() + "\n<br>" + "Type: " + type.getName());
- typeItem.setValue(type.getName() + " (" + type.getPlugin() + ")");
- formItems.add(typeItem);
-
- final Resource resource = this.resourceComposite.getResource();
- boolean modifiable = this.resourceComposite.getResourcePermission().isInventory();
-
- final FormItem nameItem = (modifiable) ? new TogglableTextItem() : new StaticTextItem();
- nameItem.setName("name");
- nameItem.setTitle("Name");
- nameItem.setValue(resource.getName());
- if (nameItem instanceof TogglableTextItem) {
- TogglableTextItem togglableNameItem = (TogglableTextItem) nameItem;
- togglableNameItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
- public void onValueUpdated(final String newName) {
- final String oldName = resource.getName();
- if (newName.equals(oldName)) {
- return;
- }
- resource.setName(newName);
- OverviewView.this.resourceService.updateResource(resource, new AsyncCallback<Void>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError(
- "Failed to change name of Resource with id " + resource.getId() + " from \"" + oldName
- + "\" to \"" + newName + "\".", caught);
- // We failed to update it on the Server, so change back the Resource and the form item to
- // the original value.
- resource.setName(oldName);
- nameItem.setValue(oldName);
- }
-
- public void onSuccess(Void result) {
- CoreGUI.getMessageCenter().notify(
- new Message("Name of Resource with id " + resource.getId() + " was changed from \""
- + oldName + "\" to \"" + newName + "\".", Message.Severity.Info));
- }
- });
- }
- });
- }
- formItems.add(nameItem);
-
- final FormItem descriptionItem = (modifiable) ? new TogglableTextItem() : new StaticTextItem();
- descriptionItem.setName("description");
- descriptionItem.setTitle("Description");
- descriptionItem.setValue(resource.getDescription());
- if (descriptionItem instanceof TogglableTextItem) {
- TogglableTextItem togglableDescriptionItem = (TogglableTextItem) descriptionItem;
- togglableDescriptionItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
- public void onValueUpdated(final String newDescription) {
- final String oldDescription = resource.getDescription();
- if (newDescription.equals(oldDescription)) {
- return;
- }
- resource.setDescription(newDescription);
- OverviewView.this.resourceService.updateResource(resource, new AsyncCallback<Void>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError(
- "Failed to change description of Resource with id " + resource.getId() + " from \""
- + oldDescription + "\" to \"" + newDescription + "\".", caught);
- // We failed to update it on the Server, so change back the Resource and the form item to
- // the original value.
- resource.setDescription(oldDescription);
- descriptionItem.setValue(oldDescription);
- }
-
- public void onSuccess(Void result) {
- CoreGUI.getMessageCenter().notify(
- new Message("Description of Resource with id " + resource.getId()
- + " was changed from \"" + oldDescription + "\" to \"" + newDescription + "\".",
- Message.Severity.Info));
- }
- });
- }
- });
- }
- formItems.add(descriptionItem);
-
- final FormItem locationItem = (modifiable) ? new TogglableTextItem() : new StaticTextItem();
- locationItem.setName("location");
- locationItem.setTitle("Location");
- locationItem.setValue(resource.getLocation());
- if (locationItem instanceof TogglableTextItem) {
- TogglableTextItem togglableNameItem = (TogglableTextItem) locationItem;
- togglableNameItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
- public void onValueUpdated(final String newLocation) {
- final String oldLocation = resource.getLocation();
- if (newLocation.equals(oldLocation)) {
- return;
- }
- resource.setLocation(newLocation);
- OverviewView.this.resourceService.updateResource(resource, new AsyncCallback<Void>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError(
- "Failed to change location of Resource with id " + resource.getId() + " from \""
- + oldLocation + "\" to \"" + newLocation + "\".", caught);
- // We failed to update it on the Server, so change back the Resource and the form item to
- // the original value.
- resource.setLocation(oldLocation);
- locationItem.setValue(oldLocation);
- }
-
- public void onSuccess(Void result) {
- CoreGUI.getMessageCenter().notify(
- new Message("Location of Resource with id " + resource.getId() + " was changed from \""
- + oldLocation + "\" to \"" + newLocation + "\".", Message.Severity.Info));
- }
- });
- }
- });
- }
- formItems.add(locationItem);
-
- StaticTextItem versionItem = new StaticTextItem("version", "Version");
- formItems.add(versionItem);
-
- StaticTextItem parentItem = new StaticTextItem("parent", "Parent");
- formItems.add(parentItem);
-
- for (MeasurementDefinition trait : traits) {
- String id = trait.getDisplayName().replaceAll("\\.", "_").replaceAll(" ", "__");
-
- StaticTextItem item = new StaticTextItem(id, trait.getDisplayName());
- item.setTooltip(trait.getDescription());
- formItems.add(item);
- // item.setValue("?");
- }
-
- // SectionItem section = new SectionItem("Summary", "Summary");
- // section.setTitle("Summary");
- // section.setDefaultValue("Summary");
- // section.setCanCollapse(true);
- // section.setCellStyle("HidablePlainSectionHeader");
- // section.setItemIds(itemIds.toArray(new String[itemIds.size()]));
- // formItems.add(0, section);
-
- formItems.add(new SpacerItem());
- setItems(formItems.toArray(new FormItem[formItems.size()]));
-
- setValue("type", type.getName() + " (" + type.getPlugin() + ")");
- setValue("name", resource.getName());
- setValue("description", resource.getDescription());
- setValue("location", resource.getLocation());
- setValue("version", (resource.getVersion() != null) ? resource.getVersion() : "<i>none</i>");
- Resource parentResource = resource.getParentResource();
- setValue("parent", parentResource != null ? ("<a href=\"#Resource/" + parentResource.getId() + "\">"
- + parentResource.getName() + "</a>") : "<i>none</i>");
+
+ addMember(errorsGrid);
}
}
diff --cc modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
index 267b0f1,dd5e77b..4ac0f61
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
@@@ -225,8 -226,18 +227,22 @@@ public abstract class RPCDataSource<T>
addField(field);
}
}
+
+ public void addFields(DataSourceField... fields) {
+ addFields(Arrays.asList(fields));
+ }
+
+ public ListGridRecord getEditedRecord(DSRequest request) {
+ // Retrieving values before edit
+ JavaScriptObject oldValues = request.getAttributeAsJavaScriptObject("oldValues");
+ // Creating new record for combining old values with changes
+ ListGridRecord newRecord = new ListGridRecord();
+ // Copying properties from old record
+ JSOHelper.apply(oldValues, newRecord.getJsObj());
+ // Retrieving changed values
+ JavaScriptObject data = request.getData();
+ // Apply changes
+ JSOHelper.apply(data, newRecord.getJsObj());
+ return newRecord;
+ }
}
commit b9e1f2c995a66a147793c72dbeb13df7c162128e
Merge: 0cd6acd... e5fac0a...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Sep 14 18:33:01 2010 +0200
Merge branch 'master' into resource-upgrade
diff --cc modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
index c06d0c2,b282e41..5990b60
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
@@@ -28,7 -28,8 +28,9 @@@ import org.rhq.core.domain.configuratio
import org.rhq.core.domain.criteria.ResourceCriteria;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceError;
+ import org.rhq.core.domain.resource.composite.DisambiguationReport;
+ import org.rhq.core.domain.resource.composite.ProblemResourceComposite;
import org.rhq.core.domain.resource.composite.RecentlyAddedResourceComposite;
import org.rhq.core.domain.resource.composite.ResourceComposite;
import org.rhq.core.domain.util.PageControl;
@@@ -65,7 -68,5 +69,7 @@@ public interface ResourceGWTService ext
void ignoreResources(Integer[] resourceIds);
void unignoreResources(Integer[] resourceIds);
+
+ List<ResourceError> findResourceErrors(int resourceId);
--}
++}
diff --cc modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
index e63978a,ac2abc2..10bde5b
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
@@@ -18,33 -18,50 +18,31 @@@
*/
package org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.summary;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.EnumSet;
-import java.util.List;
-
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.smartgwt.client.util.SC;
-import com.smartgwt.client.widgets.form.fields.FormItem;
-import com.smartgwt.client.widgets.form.fields.HeaderItem;
-import com.smartgwt.client.widgets.form.fields.SpacerItem;
-import com.smartgwt.client.widgets.form.fields.StaticTextItem;
-
-import org.rhq.core.domain.measurement.DataType;
-import org.rhq.core.domain.measurement.DisplayType;
-import org.rhq.core.domain.measurement.MeasurementDataTrait;
-import org.rhq.core.domain.measurement.MeasurementDefinition;
import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.composite.ResourceComposite;
-import org.rhq.enterprise.gui.coregui.client.CoreGUI;
-import org.rhq.enterprise.gui.coregui.client.components.form.EnhancedDynamicForm;
-import org.rhq.enterprise.gui.coregui.client.components.form.TogglableTextItem;
-import org.rhq.enterprise.gui.coregui.client.components.form.ValueUpdatedHandler;
-import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
-import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGWTServiceAsync;
-import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceSelectListener;
-import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
-import org.rhq.enterprise.gui.coregui.client.util.message.Message;
+import org.rhq.enterprise.gui.coregui.client.components.table.Table;
- import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceSelectListener;
+
+import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.widgets.HTMLPane;
+import com.smartgwt.client.widgets.IButton;
+import com.smartgwt.client.widgets.Window;
+import com.smartgwt.client.widgets.events.ClickEvent;
+import com.smartgwt.client.widgets.events.ClickHandler;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+import com.smartgwt.client.widgets.grid.events.CellClickEvent;
+import com.smartgwt.client.widgets.grid.events.CellClickHandler;
+import com.smartgwt.client.widgets.layout.VLayout;
/**
* The Resource Summary>Overview tab.
*
- * @author Greg Hinkle
- * @author Ian Springer
+ * @author Lukas Krejci
*/
- public class OverviewView extends VLayout implements ResourceSelectListener {
-public class OverviewView extends EnhancedDynamicForm implements ResourceSelectListener {
++public class OverviewView extends VLayout {
- private ResourceGWTServiceAsync resourceService = GWTServiceLookup.getResourceService();
private ResourceComposite resourceComposite;
-
public OverviewView(ResourceComposite resourceComposite) {
-- super();
this.resourceComposite = resourceComposite;
}
diff --cc modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
index 4f3f3ce,cb2768f..267b0f1
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
@@@ -18,9 -18,10 +18,11 @@@
*/
package org.rhq.enterprise.gui.coregui.client.util;
+import java.util.Arrays;
+ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+ import java.util.Map;
import com.smartgwt.client.data.DSRequest;
import com.smartgwt.client.data.DSResponse;
@@@ -183,11 -221,7 +222,11 @@@ public abstract class RPCDataSource<T>
*/
public void addFields(List<DataSourceField> fields) {
for (DataSourceField field : fields) {
- addField(field);
+ addField(field);
}
}
+
+ public void addFields(DataSourceField... fields) {
+ addFields(Arrays.asList(fields));
+ }
}
diff --cc modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
index b933248,25b19b0..6db01f8
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
@@@ -35,7 -35,8 +35,9 @@@ import org.rhq.core.domain.configuratio
import org.rhq.core.domain.criteria.ResourceCriteria;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceError;
+ import org.rhq.core.domain.resource.composite.DisambiguationReport;
+ import org.rhq.core.domain.resource.composite.ProblemResourceComposite;
import org.rhq.core.domain.resource.composite.RecentlyAddedResourceComposite;
import org.rhq.core.domain.resource.composite.ResourceComposite;
import org.rhq.core.domain.util.PageControl;
@@@ -215,9 -239,5 +240,9 @@@ public class ResourceGWTServiceImpl ext
public void unignoreResources(Integer[] resourceIds) {
discoveryBoss.unignoreResources(getSessionSubject(), resourceIds);
}
-
-}
+
+ public List<ResourceError> findResourceErrors(int resourceId) {
+ return SerialUtility.prepare(resourceManager.findResourceErrors(getSessionSubject(), resourceId),
+ "ResourceService.getResourceErrors");
+ }
- }
++}
commit 0cd6acd2fe93a35a9b2cdbde0828c416ac49f67d
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Aug 24 17:48:01 2010 +0200
Make tests work with the changed test plugin jars location, added tests for upgrade failure reporting.
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
index 19c1d95..adb3989 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
@@ -43,6 +43,8 @@ import org.rhq.core.clientapi.server.discovery.InventoryReport;
import org.rhq.core.domain.discovery.ResourceSyncInfo;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceError;
+import org.rhq.core.domain.resource.ResourceErrorType;
import org.rhq.core.domain.resource.ResourceType;
/**
@@ -137,6 +139,11 @@ public class FakeServerInventory {
resource.setResourceKey(request.getNewResourceKey());
}
+ if (request.getUpgradeErrorMessage() != null) {
+ ResourceError error = new ResourceError(resource, ResourceErrorType.UPGRADE, request.getUpgradeErrorMessage(), request.getUpgradeErrorStackTrace(), request.getTimestamp());
+ resource.getResourceErrors().add(error);
+ }
+
ResourceUpgradeResponse resp = new ResourceUpgradeResponse();
resp.setResourceId(resource.getId());
resp.setUpgradedResourceName(resource.getName());
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 202e0c0..244d2f2 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -69,8 +69,9 @@ import org.rhq.core.pc.plugin.FileSystemPluginFinder;
@Test(sequential = true, invocationCount = 1)
public class ResourceUpgradeTest {
- private static final String PLUGIN_V1_FILENAME = "resource-upgrade-test-plugin-1.0.0.jar";
- private static final String PLUGIN_V2_FILENAME = "resource-upgrade-test-plugin-2.0.0.jar";
+ private static final String PLUGIN_V1_FILENAME = "/resource-upgrade-test-plugin-1.0.0.jar";
+ private static final String PLUGIN_V2_FILENAME = "/resource-upgrade-test-plugin-2.0.0.jar";
+ private static final String FAILING_PLUGIN_FILE_NAME = "/resource-upgrade-test-plugin-3.0.0.jar";
private static final String PLUGINS_DIR_NAME = "plugins";
private static final String DATA_DIR_NAME = "data";
@@ -101,6 +102,7 @@ public class ResourceUpgradeTest {
public void sanityCheck() {
verifyPluginExists(PLUGIN_V1_FILENAME);
verifyPluginExists(PLUGIN_V2_FILENAME);
+ verifyPluginExists(FAILING_PLUGIN_FILE_NAME);
}
@BeforeClass(dependsOnMethods = "sanityCheck")
@@ -227,6 +229,35 @@ public class ResourceUpgradeTest {
executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, test);
}
+ @Test
+ public void testUpgradeFailureHandling() throws Exception {
+ currentServerSideInventory = new FakeServerInventory();
+ initialSyncAndDiscovery(InventoryStatus.COMMITTED);
+
+ TestPayload test = new TestPayload() {
+ public void test(Resource resourceUpgradeTestResource) {
+ assertTrue(resourceUpgradeTestResource.getResourceErrors().size() > 0, "There should be upgrade errors persisted on the server side.");
+ }
+
+ @SuppressWarnings("unchecked")
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+
+ between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+
+ oneOf(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
+ will(currentServerSideInventory.upgradeResources());
+ }
+ };
+ }
+ };
+
+ executeTestWithPlugins(Collections.singleton(FAILING_PLUGIN_FILE_NAME), false, test);
+ }
+
private void initialSyncAndDiscovery(final InventoryStatus requiredInventoryStatus) throws Exception {
cleanDataDir();
executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), true, new TestPayload() {
commit 90b602f22c280ee63deb7e51470db1fcda9b79a1
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Aug 24 17:46:58 2010 +0200
Final touches on the Server side error reporting.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
index cc63040..e63978a 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
@@ -24,7 +24,6 @@ import org.rhq.enterprise.gui.coregui.client.components.table.Table;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceSelectListener;
import com.smartgwt.client.types.Alignment;
-import com.smartgwt.client.types.GroupStartOpen;
import com.smartgwt.client.widgets.HTMLPane;
import com.smartgwt.client.widgets.IButton;
import com.smartgwt.client.widgets.Window;
@@ -33,7 +32,6 @@ import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.grid.events.CellClickEvent;
import com.smartgwt.client.widgets.grid.events.CellClickHandler;
-import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;
/**
@@ -92,9 +90,10 @@ public class OverviewView extends VLayout implements ResourceSelectListener {
w.setWidth(640);
w.setHeight(480);
w.centerInPage();
+ w.setCanDragResize(true);
VLayout layout = new VLayout(10);
- layout.setLayoutAlign(Alignment.CENTER);
+ layout.setDefaultLayoutAlign(Alignment.CENTER);
layout.setLayoutMargin(10);
w.addItem(layout);
@@ -109,7 +108,6 @@ public class OverviewView extends VLayout implements ResourceSelectListener {
w.destroy();
}
});
- ok.setAlign(Alignment.CENTER);
layout.addMember(ok);
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ResourceErrorsDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ResourceErrorsDataSource.java
index 4957fc7..1843f2b 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ResourceErrorsDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ResourceErrorsDataSource.java
@@ -90,7 +90,7 @@ public class ResourceErrorsDataSource extends RPCDataSource<ResourceError> {
ListGridRecord record = new ListGridRecord();
record.setAttribute(DETAIL_ID, from.getDetail());
- record.setAttribute(ERROR_TYPE_ID, from.getErrorType());
+ record.setAttribute(ERROR_TYPE_ID, from.getErrorType().toString());
record.setAttribute(SUMMARY_ID, from.getSummary());
record.setAttribute(TIME_OCCURED_ID, new Date(from.getTimeOccurred()));
commit f0b6cda14af2bce898dd6af66b4bb2627a836d72
Merge: d689f70... 66234db...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Aug 24 13:25:05 2010 +0200
Merge branch 'master' into resource-upgrade
diff --cc modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
index 1ea9630,950d28c..4f3f3ce
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
@@@ -18,8 -18,8 +18,9 @@@
*/
package org.rhq.enterprise.gui.coregui.client.util;
+import java.util.Arrays;
import java.util.Collection;
+ import java.util.List;
import com.smartgwt.client.data.DSRequest;
import com.smartgwt.client.data.DSResponse;
@@@ -172,13 -173,16 +174,20 @@@ public abstract class RPCDataSource<T>
return response;
}
- public void addFields(Collection<DataSourceField> fields) {
+ /**
+ * Add the specified fields to this data source. When the data source is associated with a
+ * {@link com.smartgwt.client.widgets.grid.ListGrid}, the fields will be displayed in the order they are specified
+ * here.
+ *
+ * @param fields the fields to be added
+ */
+ public void addFields(List<DataSourceField> fields) {
for (DataSourceField field : fields) {
- addField(field);
+ addField(field);
}
}
+
+ public void addFields(DataSourceField... fields) {
+ addFields(Arrays.asList(fields));
+ }
}
commit d689f70de060cdb776cea923f759f0e5de226955
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Aug 24 13:17:24 2010 +0200
Upgrade errors (and other resource errors) shown in the summary tab. Not everything seems to work yet.
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
index 9532920..aca9c90 100644
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
@@ -41,7 +41,7 @@ public class ResourceUpgradeRequest extends ResourceUpgradeReport {
private String upgradeErrorMessage;
private String upgradeErrorStackTrace;
private long timestamp;
-
+
public ResourceUpgradeRequest(int resourceId) {
this.resourceId = resourceId;
}
@@ -74,14 +74,37 @@ public class ResourceUpgradeRequest extends ResourceUpgradeReport {
public long getTimestamp() {
return timestamp;
}
-
+
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
-
+
public void setErrorProperties(Throwable t) {
- upgradeErrorMessage = t.getMessage();
+ upgradeErrorMessage = null;
+ upgradeErrorStackTrace = null;
+
+ //first try to extract an error message from the exception
+ //or some of its parents
+ Throwable p = t;
+ while (upgradeErrorMessage == null && p != null) {
+ upgradeErrorMessage = p.getMessage();
+ if (upgradeErrorMessage == null) {
+ upgradeErrorMessage = p.getLocalizedMessage();
+ }
+ p = p.getCause();
+ }
+
+ //ok, we have no error messages. But we have to supply something
+ //as the message, so let's use the class name as a last resort.
+ if (upgradeErrorMessage == null) {
+ if (t.getClass().getCanonicalName() != null) {
+ upgradeErrorMessage = t.getClass().getCanonicalName();
+ } else if (t.getClass().getName() != null) {
+ upgradeErrorMessage = t.getClass().getName();
+ }
+ }
+ //print the stack trace into a string
StringWriter string = new StringWriter();
PrintWriter w = new PrintWriter(string);
t.printStackTrace(w);
diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ResourceErrorTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ResourceErrorTest.java
index 8fdc2f7..6630d4b 100644
--- a/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ResourceErrorTest.java
+++ b/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ResourceErrorTest.java
@@ -92,7 +92,7 @@ public class ResourceErrorTest extends AbstractEJB3Test {
q.setParameter("resourceId", newResource.getId());
assert q.getResultList().size() == 2;
- q = em.createNamedQuery(ResourceError.QUERY_FIND_BY_RESOURCE_ID_AND_ERROR_TYPE);
+ q = em.createNamedQuery(ResourceError.QUERY_FIND_BY_RESOURCE_ID_AND_ERROR_TYPES);
q.setParameter("resourceId", newResource.getId());
q.setParameter("errorType", ResourceErrorType.INVALID_PLUGIN_CONFIGURATION);
assert q.getResultList().size() == 2;
@@ -129,7 +129,7 @@ public class ResourceErrorTest extends AbstractEJB3Test {
assert errors.get(0).getDetail().equals("test detail");
assert errors.get(0).getTimeOccurred() == 12345;
- q = em.createNamedQuery(ResourceError.QUERY_FIND_BY_RESOURCE_ID_AND_ERROR_TYPE);
+ q = em.createNamedQuery(ResourceError.QUERY_FIND_BY_RESOURCE_ID_AND_ERROR_TYPES);
q.setParameter("resourceId", newResource.getId());
q.setParameter("errorType", ResourceErrorType.INVALID_PLUGIN_CONFIGURATION);
errors = q.getResultList();
diff --git a/modules/core/plugin-container/pom.xml b/modules/core/plugin-container/pom.xml
index a4ca249..4b09ef8 100644
--- a/modules/core/plugin-container/pom.xml
+++ b/modules/core/plugin-container/pom.xml
@@ -163,26 +163,39 @@
<id>process-test-classes</id>
<phase>process-test-classes</phase>
<configuration>
- <tasks>
- <echo>Assembling the two resource upgrade test plugins</echo>
- <copy toDir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v1/META-INF">
+ <tasks unless="maven.test.skip">
+ <echo>Assembling the resource upgrade test plugins</echo>
+ <copy toDir="${project.build.testOutputDirectory}/tmp/v1/META-INF">
<fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/v1/rhq-plugin.xml" />
</copy>
- <jar destfile="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-1.0.0.jar">
- <fileset dir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v1" includes="*.class,**/rhq-plugin.xml" />
+ <copy toDir="${project.build.testOutputDirectory}/tmp/v1/org/rhq/core/pc/upgrade/plugins/v1">
+ <fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v1/*.class" />
+ </copy>
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-1.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/tmp/v1" includes="**/*.class,**/rhq-plugin.xml" />
</jar>
- <copy toDir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v2/META-INF">
+
+ <copy toDir="${project.build.testOutputDirectory}/tmp/v2/META-INF">
<fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/v2/rhq-plugin.xml" />
</copy>
- <jar destfile="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar">
- <fileset dir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v2" includes="*.class,**/rhq-plugin.xml" />
+ <copy toDir="${project.build.testOutputDirectory}/tmp/v2/org/rhq/core/pc/upgrade/plugins/v2">
+ <fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v2/*.class" />
+ </copy>
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-2.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/tmp/v2" includes="**/*.class,**/rhq-plugin.xml" />
</jar>
- <copy toDir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/failing/META-INF">
+
+ <copy toDir="${project.build.testOutputDirectory}/tmp/failing/META-INF">
<fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/failing/rhq-plugin.xml" />
</copy>
- <jar destfile="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-3.0.0.jar">
- <fileset dir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/failing" includes="*.class,**/rhq-plugin.xml" />
+ <copy toDir="${project.build.testOutputDirectory}/tmp/failing/org/rhq/core/pc/upgrade/plugins/failing">
+ <fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/failing/*.class" />
+ </copy>
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-3.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/tmp/failing" includes="**/*.class,**/rhq-plugin.xml" />
</jar>
+
+ <delete dir="${project.build.testOutputDirectory}/tmp"/>
</tasks>
</configuration>
<goals>
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
index f92e7d5..c06d0c2 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
@@ -28,6 +28,7 @@ import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.criteria.ResourceCriteria;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.domain.resource.composite.RecentlyAddedResourceComposite;
import org.rhq.core.domain.resource.composite.ResourceComposite;
import org.rhq.core.domain.util.PageControl;
@@ -64,5 +65,7 @@ public interface ResourceGWTService extends RemoteService {
void ignoreResources(Integer[] resourceIds);
void unignoreResources(Integer[] resourceIds);
+
+ List<ResourceError> findResourceErrors(int resourceId);
}
\ No newline at end of file
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
index 2fff538..cc63040 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
@@ -18,20 +18,22 @@
*/
package org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.summary;
-import java.util.ArrayList;
-import java.util.List;
-
import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.domain.resource.composite.ResourceComposite;
+import org.rhq.enterprise.gui.coregui.client.components.table.Table;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceSelectListener;
-import com.smartgwt.client.util.SC;
-import com.smartgwt.client.widgets.grid.ListGrid;
-import com.smartgwt.client.widgets.grid.ListGridField;
+import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.types.GroupStartOpen;
+import com.smartgwt.client.widgets.HTMLPane;
+import com.smartgwt.client.widgets.IButton;
+import com.smartgwt.client.widgets.Window;
+import com.smartgwt.client.widgets.events.ClickEvent;
+import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.grid.ListGridRecord;
-import com.smartgwt.client.widgets.grid.events.RecordClickEvent;
-import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
+import com.smartgwt.client.widgets.grid.events.CellClickEvent;
+import com.smartgwt.client.widgets.grid.events.CellClickHandler;
+import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;
/**
@@ -62,41 +64,59 @@ public class OverviewView extends VLayout implements ResourceSelectListener {
public void onResourceSelected(ResourceComposite resourceComposite) {
addMember(new OverviewForm(resourceComposite));
- ListGrid errorsGrid = buildErrorListGrid(resourceComposite);
- if (errorsGrid != null) {
- addMember(errorsGrid);
- }
+ buildErrorListGrid(resourceComposite);
}
- private static ListGrid buildErrorListGrid(ResourceComposite resourceComposite) {
+ private void buildErrorListGrid(ResourceComposite resourceComposite) {
final Resource resource = resourceComposite.getResource();
- ListGrid errorsGrid = null;
- if (resource.getResourceErrors() != null && resource.getResourceErrors().size() > 0) {
- errorsGrid = new ListGrid();
-
- ListGridField summaryField = new ListGridField("summary", "Errors");
- summaryField.addRecordClickHandler(new RecordClickHandler() {
-
- @Override
- public void onRecordClick(RecordClickEvent event) {
- String detail = event.getRecord().getAttribute("detail");
- SC.say("Error details", detail);
- }
- });
-
- errorsGrid.setFields(summaryField);
-
- List<ListGridRecord> errorList = new ArrayList<ListGridRecord>();
- for (ResourceError error : resource.getResourceErrors()) {
- ListGridRecord record = new ListGridRecord();
- record.setAttribute("summary", error.getSummary());
- record.setAttribute("detail", error.getDetail());
- errorList.add(record);
+ Table errorsGrid = new Table("Errors");
+
+ errorsGrid.setShowFooter(false);
+// errorsGrid.getListGrid().setGroupByField(ResourceErrorsDataSource.ERROR_TYPE_ID);
+// errorsGrid.getListGrid().setGroupStartOpen(GroupStartOpen.ALL);
+// errorsGrid.getListGrid().setShowGroupSummary(true);
+
+ errorsGrid.setDataSource(new ResourceErrorsDataSource(resource.getId()));
+
+ //hide only works after we set the datasource
+ errorsGrid.getListGrid().hideField(ResourceErrorsDataSource.DETAIL_ID);
+
+ errorsGrid.getListGrid().addCellClickHandler(new CellClickHandler() {
+ public void onCellClick(CellClickEvent event) {
+ ListGridRecord record = event.getRecord();
+ final Window w = new Window();
+ w.setTitle("Error Details");
+ w.setIsModal(true);
+ w.setShowMinimizeButton(false);
+ w.setShowModalMask(true);
+ w.setWidth(640);
+ w.setHeight(480);
+ w.centerInPage();
+
+ VLayout layout = new VLayout(10);
+ layout.setLayoutAlign(Alignment.CENTER);
+ layout.setLayoutMargin(10);
+
+ w.addItem(layout);
+
+ HTMLPane details = new HTMLPane();
+ details.setContents("<pre>" + record.getAttribute(ResourceErrorsDataSource.DETAIL_ID) + "</pre>");
+ layout.addMember(details);
+
+ IButton ok = new IButton("Ok");
+ ok.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ w.destroy();
+ }
+ });
+ ok.setAlign(Alignment.CENTER);
+
+ layout.addMember(ok);
+
+ w.show();
}
-
- errorsGrid.setRecords(errorList.toArray(new ListGridRecord[errorList.size()]));
- }
-
- return errorsGrid;
+ });
+
+ addMember(errorsGrid);
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ResourceErrorsDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ResourceErrorsDataSource.java
new file mode 100644
index 0000000..4957fc7
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ResourceErrorsDataSource.java
@@ -0,0 +1,100 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.summary;
+
+import java.util.Date;
+import java.util.List;
+
+import org.rhq.core.domain.resource.ResourceError;
+import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGWTServiceAsync;
+import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.data.DSRequest;
+import com.smartgwt.client.data.DSResponse;
+import com.smartgwt.client.data.fields.DataSourceDateField;
+import com.smartgwt.client.data.fields.DataSourceDateTimeField;
+import com.smartgwt.client.data.fields.DataSourceEnumField;
+import com.smartgwt.client.data.fields.DataSourceTextField;
+import com.smartgwt.client.rpc.RPCResponse;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+
+/**
+ *
+ * @author Lukas Krejci
+ */
+public class ResourceErrorsDataSource extends RPCDataSource<ResourceError> {
+
+ public static final String SUMMARY_ID = "summary";
+ public static final String DETAIL_ID = "detail";
+ public static final String ERROR_TYPE_ID = "errorType";
+ public static final String TIME_OCCURED_ID = "timeOccured";
+
+ ResourceGWTServiceAsync resourceService;
+ int resourceId;
+
+ public ResourceErrorsDataSource(int resourceId) {
+ resourceService = GWTServiceLookup.getResourceService();
+ this.resourceId = resourceId;
+
+ addFields(new DataSourceTextField(SUMMARY_ID, "Summary"),
+ new DataSourceTextField(DETAIL_ID, "Detailed Message"),
+ new DataSourceEnumField(ERROR_TYPE_ID, "Error Type"), new DataSourceDateTimeField(TIME_OCCURED_ID, "Time"));
+ }
+
+ /* (non-Javadoc)
+ * @see org.rhq.enterprise.gui.coregui.client.util.RPCDataSource#executeFetch(com.smartgwt.client.data.DSRequest, com.smartgwt.client.data.DSResponse)
+ */
+ @Override
+ protected void executeFetch(final DSRequest request, final DSResponse response) {
+ resourceService.findResourceErrors(resourceId, new AsyncCallback<List<ResourceError>>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError(
+ "Failed to find resource errors for resource with id: " + resourceId, caught);
+ response.setStatus(RPCResponse.STATUS_FAILURE);
+ processResponse(request.getRequestId(), response);
+ }
+
+ public void onSuccess(List<ResourceError> result) {
+ response.setData(buildRecords(result));
+ processResponse(request.getRequestId(), response);
+ };
+ });
+ }
+
+ public ResourceError copyValues(ListGridRecord from) {
+ //This is read-only datasource, so no need to implement this.
+ return null;
+ }
+
+ public ListGridRecord copyValues(ResourceError from) {
+ ListGridRecord record = new ListGridRecord();
+
+ record.setAttribute(DETAIL_ID, from.getDetail());
+ record.setAttribute(ERROR_TYPE_ID, from.getErrorType());
+ record.setAttribute(SUMMARY_ID, from.getSummary());
+ record.setAttribute(TIME_OCCURED_ID, new Date(from.getTimeOccurred()));
+
+ return record;
+ }
+
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
index 1b6f6cd..1ea9630 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
@@ -18,6 +18,7 @@
*/
package org.rhq.enterprise.gui.coregui.client.util;
+import java.util.Arrays;
import java.util.Collection;
import com.smartgwt.client.data.DSRequest;
@@ -176,4 +177,8 @@ public abstract class RPCDataSource<T> extends DataSource {
addField(field);
}
}
+
+ public void addFields(DataSourceField... fields) {
+ addFields(Arrays.asList(fields));
+ }
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
index c10254e..b933248 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
@@ -35,6 +35,7 @@ import org.rhq.core.domain.configuration.definition.ConfigurationTemplate;
import org.rhq.core.domain.criteria.ResourceCriteria;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.domain.resource.composite.RecentlyAddedResourceComposite;
import org.rhq.core.domain.resource.composite.ResourceComposite;
import org.rhq.core.domain.util.PageControl;
@@ -215,4 +216,8 @@ public class ResourceGWTServiceImpl extends AbstractGWTServiceImpl implements Re
discoveryBoss.unignoreResources(getSessionSubject(), resourceIds);
}
+ public List<ResourceError> findResourceErrors(int resourceId) {
+ return SerialUtility.prepare(resourceManager.findResourceErrors(getSessionSubject(), resourceId),
+ "ResourceService.getResourceErrors");
+ }
}
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index b773384..a480fb7 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -486,7 +486,7 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
private ResourceUpgradeResponse upgradeResource(@NotNull Resource resource, ResourceUpgradeRequest upgradeRequest, boolean allowGenericPropertiesUpgrade) {
if (upgradeRequest.getUpgradeErrorMessage() != null) {
ResourceError error = new ResourceError(resource, ResourceErrorType.UPGRADE, upgradeRequest.getUpgradeErrorMessage(), upgradeRequest.getUpgradeErrorStackTrace(), upgradeRequest.getTimestamp());
- entityManager.persist(error);
+ resourceManager.addResourceError(error);
return null;
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
index 5a4cf92..29672cc 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
@@ -1708,6 +1708,21 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
return query.getResultList();
}
+ @NotNull
+ @SuppressWarnings("unchecked")
+ public List<ResourceError> findResourceErrors(Subject user, int resourceId) {
+ // do authz check
+ if (!authorizationManager.canViewResource(user, resourceId)) {
+ throw new PermissionException("User [" + user + "] does not have permission to view resource ["
+ + resourceId + "]");
+ }
+
+ // we passed authz check, now get the errors
+ Query query = entityManager.createNamedQuery(ResourceError.QUERY_FIND_BY_RESOURCE_ID);
+ query.setParameter("resourceId", resourceId);
+ return query.getResultList();
+ }
+
public void addResourceError(ResourceError resourceError) {
Subject overlord = subjectManager.getOverlord();
Resource resource;
@@ -1718,9 +1733,10 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
}
if (resourceError.getErrorType() == ResourceErrorType.INVALID_PLUGIN_CONFIGURATION
- || resourceError.getErrorType() == ResourceErrorType.AVAILABILITY_CHECK) {
- // there should be at most one invalid plugin configuration error and one availability check error per
- // resource, so delete any currently existing ones before we add this new one
+ || resourceError.getErrorType() == ResourceErrorType.AVAILABILITY_CHECK
+ || resourceError.getErrorType() == ResourceErrorType.UPGRADE) {
+ // there should be at most one invalid plugin configuration error, availability check
+ // or upgrade error per resource, so delete any currently existing ones before we add this new one
List<ResourceError> doomedErrors = resource.getResourceErrors(resourceError.getErrorType());
// there should only ever be at most 1, but loop through the list just in case something got screwed up
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
index a2f26ff..b84a104 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
@@ -319,6 +319,17 @@ public interface ResourceManagerLocal {
List<ResourceError> findResourceErrors(Subject user, int resourceId, ResourceErrorType errorType);
/**
+ * Returns all the errors that have occurred for the given resource.
+ *
+ * @param user the user asking to see the errors
+ * @param resourceId the resource whose errors are to be returned
+ *
+ * @return the list of resource errors
+ */
+ @NotNull
+ List<ResourceError> findResourceErrors(Subject user, int resourceId);
+
+ /**
* Indicates an error occurred on a resource. The given error will be associated with the resource found in the
* error.
*
commit 4e8ae3349ff28b025741a1c3bb0d1a827c0feff8
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Aug 20 15:14:27 2010 +0200
first stab at the errors display GUI.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewForm.java
new file mode 100644
index 0000000..074b3c9
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewForm.java
@@ -0,0 +1,298 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.summary;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.EnumSet;
+import java.util.List;
+
+import org.rhq.core.domain.measurement.DataType;
+import org.rhq.core.domain.measurement.DisplayType;
+import org.rhq.core.domain.measurement.MeasurementDataTrait;
+import org.rhq.core.domain.measurement.MeasurementDefinition;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.resource.composite.ResourceComposite;
+import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.components.form.EnhancedDynamicForm;
+import org.rhq.enterprise.gui.coregui.client.components.form.TogglableTextItem;
+import org.rhq.enterprise.gui.coregui.client.components.form.ValueUpdatedHandler;
+import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGWTServiceAsync;
+import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
+import org.rhq.enterprise.gui.coregui.client.util.message.Message;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.util.SC;
+import com.smartgwt.client.widgets.form.fields.FormItem;
+import com.smartgwt.client.widgets.form.fields.HeaderItem;
+import com.smartgwt.client.widgets.form.fields.SpacerItem;
+import com.smartgwt.client.widgets.form.fields.StaticTextItem;
+
+/**
+ * The Resource Summary>Overview tab, the form with resource data.
+ *
+ * @author Greg Hinkle
+ * @author Ian Springer
+ */
+public class OverviewForm extends EnhancedDynamicForm {
+
+ private ResourceGWTServiceAsync resourceService = GWTServiceLookup.getResourceService();
+ private ResourceComposite resourceComposite;
+
+ public OverviewForm(ResourceComposite resourceComposite) {
+ this.resourceComposite = resourceComposite;
+ }
+
+ @Override
+ protected void onDraw() {
+ super.onDraw();
+
+ setLeft("10%");
+ setWidth("80%");
+
+ if (this.resourceComposite != null) {
+ setResource(this.resourceComposite);
+ }
+ }
+
+ public void setResource(ResourceComposite resourceComposite) {
+
+ this.resourceComposite = resourceComposite;
+ Resource resource = resourceComposite.getResource();
+
+ // Load metric defs.
+ ResourceTypeRepository.Cache.getInstance().getResourceTypes(resource.getResourceType().getId(),
+ EnumSet.of(ResourceTypeRepository.MetadataType.measurements),
+ new ResourceTypeRepository.TypeLoadedCallback() {
+ public void onTypesLoaded(ResourceType type) {
+ try {
+ buildForm(type);
+ loadTraitValues();
+ } catch (Exception e) {
+ SC.say("Form load failure");
+ e.printStackTrace();
+ }
+ }
+ });
+ }
+
+ private void loadTraitValues() {
+ final Resource resource = resourceComposite.getResource();
+ GWTServiceLookup.getMeasurementDataService().findCurrentTraitsForResource(
+ resource.getId(),
+ DisplayType.SUMMARY,
+ new AsyncCallback<List<MeasurementDataTrait>>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Failed to load traits for " + resource + ".",
+ caught);
+ }
+
+ public void onSuccess(List<MeasurementDataTrait> result) {
+ // TODO: Implement this method.
+ for (MeasurementDataTrait trait : result) {
+ String formId = trait.getName().replaceAll("\\.", "_").replaceAll(" ", "__");
+ FormItem item = getItem(formId);
+
+ if (item != null) {
+ setValue(formId, trait.getValue());
+ }
+ }
+ markForRedraw();
+ }
+ }
+ );
+
+ }
+
+ private void buildForm(ResourceType type) {
+ List<MeasurementDefinition> traits = new ArrayList<MeasurementDefinition>();
+
+ for (MeasurementDefinition measurement : type.getMetricDefinitions()) {
+ if (measurement.getDataType() == DataType.TRAIT && measurement.getDisplayType() == DisplayType.SUMMARY) {
+ traits.add(measurement);
+ }
+ }
+
+ Collections.sort(traits, new Comparator<MeasurementDefinition>() {
+ public int compare(MeasurementDefinition o1, MeasurementDefinition o2) {
+ return new Integer(o1.getDisplayOrder()).compareTo(o2.getDisplayOrder());
+ }
+ });
+
+ List<FormItem> formItems = new ArrayList<FormItem>();
+
+ HeaderItem headerItem = new HeaderItem("header", "Summary");
+ headerItem.setValue("Summary");
+ formItems.add(headerItem);
+
+ StaticTextItem typeItem = new StaticTextItem("type", "Type");
+ typeItem.setTooltip("Plugin: " + type.getPlugin() + "\n<br>" + "Type: " + type.getName());
+ typeItem.setValue(type.getName() + " (" + type.getPlugin() + ")");
+ formItems.add(typeItem);
+
+ final Resource resource = this.resourceComposite.getResource();
+ boolean modifiable = this.resourceComposite.getResourcePermission().isInventory();
+
+ final FormItem nameItem = (modifiable) ? new TogglableTextItem() : new StaticTextItem();
+ nameItem.setName("name");
+ nameItem.setTitle("Name");
+ nameItem.setValue(resource.getName());
+ if (nameItem instanceof TogglableTextItem) {
+ TogglableTextItem togglableNameItem = (TogglableTextItem) nameItem;
+ togglableNameItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
+ public void onValueUpdated(final String newName) {
+ final String oldName = resource.getName();
+ if (newName.equals(oldName)) {
+ return;
+ }
+ resource.setName(newName);
+ OverviewForm.this.resourceService.updateResource(resource, new AsyncCallback<Void>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Failed to change name of Resource with id "
+ + resource.getId()
+ + " from \"" + oldName + "\" to \"" + newName + "\".", caught);
+ // We failed to update it on the Server, so change back the Resource and the form item to
+ // the original value.
+ resource.setName(oldName);
+ nameItem.setValue(oldName);
+ }
+
+ public void onSuccess(Void result) {
+ CoreGUI.getMessageCenter().notify(new Message("Name of Resource with id "
+ + resource.getId() + " was changed from \""
+ + oldName + "\" to \"" + newName + "\".", Message.Severity.Info));
+ }
+ });
+ }
+ });
+ }
+ formItems.add(nameItem);
+
+ final FormItem descriptionItem = (modifiable) ? new TogglableTextItem() : new StaticTextItem();
+ descriptionItem.setName("description");
+ descriptionItem.setTitle("Description");
+ descriptionItem.setValue(resource.getDescription());
+ if (descriptionItem instanceof TogglableTextItem) {
+ TogglableTextItem togglableDescriptionItem = (TogglableTextItem) descriptionItem;
+ togglableDescriptionItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
+ public void onValueUpdated(final String newDescription) {
+ final String oldDescription = resource.getDescription();
+ if (newDescription.equals(oldDescription)) {
+ return;
+ }
+ resource.setDescription(newDescription);
+ OverviewForm.this.resourceService.updateResource(resource, new AsyncCallback<Void>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Failed to change description of Resource with id "
+ + resource.getId()
+ + " from \"" + oldDescription + "\" to \"" + newDescription + "\".", caught);
+ // We failed to update it on the Server, so change back the Resource and the form item to
+ // the original value.
+ resource.setDescription(oldDescription);
+ descriptionItem.setValue(oldDescription);
+ }
+
+ public void onSuccess(Void result) {
+ CoreGUI.getMessageCenter().notify(new Message("Description of Resource with id "
+ + resource.getId() + " was changed from \""
+ + oldDescription + "\" to \"" + newDescription + "\".", Message.Severity.Info));
+ }
+ });
+ }
+ });
+ }
+ formItems.add(descriptionItem);
+
+ final FormItem locationItem = (modifiable) ? new TogglableTextItem() : new StaticTextItem();
+ locationItem.setName("location");
+ locationItem.setTitle("Location");
+ locationItem.setValue(resource.getLocation());
+ if (locationItem instanceof TogglableTextItem) {
+ TogglableTextItem togglableNameItem = (TogglableTextItem) locationItem;
+ togglableNameItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
+ public void onValueUpdated(final String newLocation) {
+ final String oldLocation = resource.getLocation();
+ if (newLocation.equals(oldLocation)) {
+ return;
+ }
+ resource.setLocation(newLocation);
+ OverviewForm.this.resourceService.updateResource(resource, new AsyncCallback<Void>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Failed to change location of Resource with id "
+ + resource.getId()
+ + " from \"" + oldLocation + "\" to \"" + newLocation + "\".", caught);
+ // We failed to update it on the Server, so change back the Resource and the form item to
+ // the original value.
+ resource.setLocation(oldLocation);
+ locationItem.setValue(oldLocation);
+ }
+
+ public void onSuccess(Void result) {
+ CoreGUI.getMessageCenter().notify(new Message("Location of Resource with id "
+ + resource.getId() + " was changed from \""
+ + oldLocation + "\" to \"" + newLocation + "\".", Message.Severity.Info));
+ }
+ });
+ }
+ });
+ }
+ formItems.add(locationItem);
+
+
+ StaticTextItem versionItem = new StaticTextItem("version", "Version");
+ formItems.add(versionItem);
+
+ StaticTextItem parentItem = new StaticTextItem("parent", "Parent");
+ formItems.add(parentItem);
+
+ for (MeasurementDefinition trait : traits) {
+ String id = trait.getDisplayName().replaceAll("\\.", "_").replaceAll(" ", "__");
+
+ StaticTextItem item = new StaticTextItem(id, trait.getDisplayName());
+ item.setTooltip(trait.getDescription());
+ formItems.add(item);
+// item.setValue("?");
+ }
+
+// SectionItem section = new SectionItem("Summary", "Summary");
+// section.setTitle("Summary");
+// section.setDefaultValue("Summary");
+// section.setCanCollapse(true);
+// section.setCellStyle("HidablePlainSectionHeader");
+// section.setItemIds(itemIds.toArray(new String[itemIds.size()]));
+// formItems.add(0, section);
+
+ formItems.add(new SpacerItem());
+ setItems(formItems.toArray(new FormItem[formItems.size()]));
+
+ setValue("type", type.getName() + " (" + type.getPlugin() + ")");
+ setValue("name", resource.getName());
+ setValue("description", resource.getDescription());
+ setValue("location", resource.getLocation());
+ setValue("version", (resource.getVersion() != null) ? resource.getVersion() : "<i>none</i>");
+ Resource parentResource = resource.getParentResource();
+ setValue("parent", parentResource != null ?
+ ("<a href=\"#Resource/" + parentResource.getId() + "\">" +
+ parentResource.getName() + "</a>") : "<i>none</i>");
+ }
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
index ac2abc2..2fff538 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
@@ -19,53 +19,35 @@
package org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.summary;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.EnumSet;
import java.util.List;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.smartgwt.client.util.SC;
-import com.smartgwt.client.widgets.form.fields.FormItem;
-import com.smartgwt.client.widgets.form.fields.HeaderItem;
-import com.smartgwt.client.widgets.form.fields.SpacerItem;
-import com.smartgwt.client.widgets.form.fields.StaticTextItem;
-
-import org.rhq.core.domain.measurement.DataType;
-import org.rhq.core.domain.measurement.DisplayType;
-import org.rhq.core.domain.measurement.MeasurementDataTrait;
-import org.rhq.core.domain.measurement.MeasurementDefinition;
import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.domain.resource.composite.ResourceComposite;
-import org.rhq.enterprise.gui.coregui.client.CoreGUI;
-import org.rhq.enterprise.gui.coregui.client.components.form.EnhancedDynamicForm;
-import org.rhq.enterprise.gui.coregui.client.components.form.TogglableTextItem;
-import org.rhq.enterprise.gui.coregui.client.components.form.ValueUpdatedHandler;
-import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
-import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGWTServiceAsync;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceSelectListener;
-import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
-import org.rhq.enterprise.gui.coregui.client.util.message.Message;
+
+import com.smartgwt.client.util.SC;
+import com.smartgwt.client.widgets.grid.ListGrid;
+import com.smartgwt.client.widgets.grid.ListGridField;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+import com.smartgwt.client.widgets.grid.events.RecordClickEvent;
+import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
+import com.smartgwt.client.widgets.layout.VLayout;
/**
* The Resource Summary>Overview tab.
*
- * @author Greg Hinkle
- * @author Ian Springer
+ * @author Lukas Krejci
*/
-public class OverviewView extends EnhancedDynamicForm implements ResourceSelectListener {
+public class OverviewView extends VLayout implements ResourceSelectListener {
- private ResourceGWTServiceAsync resourceService = GWTServiceLookup.getResourceService();
private ResourceComposite resourceComposite;
-
public OverviewView(ResourceComposite resourceComposite) {
super();
this.resourceComposite = resourceComposite;
}
-
@Override
protected void onDraw() {
super.onDraw();
@@ -78,225 +60,43 @@ public class OverviewView extends EnhancedDynamicForm implements ResourceSelectL
}
}
-
public void onResourceSelected(ResourceComposite resourceComposite) {
-
- this.resourceComposite = resourceComposite;
- Resource resource = resourceComposite.getResource();
-
- // Load metric defs.
- ResourceTypeRepository.Cache.getInstance().getResourceTypes(resource.getResourceType().getId(),
- EnumSet.of(ResourceTypeRepository.MetadataType.measurements),
- new ResourceTypeRepository.TypeLoadedCallback() {
- public void onTypesLoaded(ResourceType type) {
- try {
- buildForm(type);
- loadTraitValues();
- } catch (Exception e) {
- SC.say("Form load failure");
- e.printStackTrace();
- }
- }
- });
+ addMember(new OverviewForm(resourceComposite));
+ ListGrid errorsGrid = buildErrorListGrid(resourceComposite);
+ if (errorsGrid != null) {
+ addMember(errorsGrid);
+ }
}
- private void loadTraitValues() {
+ private static ListGrid buildErrorListGrid(ResourceComposite resourceComposite) {
final Resource resource = resourceComposite.getResource();
- GWTServiceLookup.getMeasurementDataService().findCurrentTraitsForResource(
- resource.getId(),
- DisplayType.SUMMARY,
- new AsyncCallback<List<MeasurementDataTrait>>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError("Failed to load traits for " + resource + ".",
- caught);
- }
-
- public void onSuccess(List<MeasurementDataTrait> result) {
- // TODO: Implement this method.
- for (MeasurementDataTrait trait : result) {
- String formId = trait.getName().replaceAll("\\.", "_").replaceAll(" ", "__");
- FormItem item = getItem(formId);
-
- if (item != null) {
- setValue(formId, trait.getValue());
- }
- }
- markForRedraw();
- }
- }
- );
-
- }
-
- private void buildForm(ResourceType type) {
- List<MeasurementDefinition> traits = new ArrayList<MeasurementDefinition>();
-
- for (MeasurementDefinition measurement : type.getMetricDefinitions()) {
- if (measurement.getDataType() == DataType.TRAIT && measurement.getDisplayType() == DisplayType.SUMMARY) {
- traits.add(measurement);
- }
- }
-
- Collections.sort(traits, new Comparator<MeasurementDefinition>() {
- public int compare(MeasurementDefinition o1, MeasurementDefinition o2) {
- return new Integer(o1.getDisplayOrder()).compareTo(o2.getDisplayOrder());
- }
- });
-
- List<FormItem> formItems = new ArrayList<FormItem>();
-
- HeaderItem headerItem = new HeaderItem("header", "Summary");
- headerItem.setValue("Summary");
- formItems.add(headerItem);
+ ListGrid errorsGrid = null;
+ if (resource.getResourceErrors() != null && resource.getResourceErrors().size() > 0) {
+ errorsGrid = new ListGrid();
- StaticTextItem typeItem = new StaticTextItem("type", "Type");
- typeItem.setTooltip("Plugin: " + type.getPlugin() + "\n<br>" + "Type: " + type.getName());
- typeItem.setValue(type.getName() + " (" + type.getPlugin() + ")");
- formItems.add(typeItem);
+ ListGridField summaryField = new ListGridField("summary", "Errors");
+ summaryField.addRecordClickHandler(new RecordClickHandler() {
- final Resource resource = this.resourceComposite.getResource();
- boolean modifiable = this.resourceComposite.getResourcePermission().isInventory();
-
- final FormItem nameItem = (modifiable) ? new TogglableTextItem() : new StaticTextItem();
- nameItem.setName("name");
- nameItem.setTitle("Name");
- nameItem.setValue(resource.getName());
- if (nameItem instanceof TogglableTextItem) {
- TogglableTextItem togglableNameItem = (TogglableTextItem) nameItem;
- togglableNameItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
- public void onValueUpdated(final String newName) {
- final String oldName = resource.getName();
- if (newName.equals(oldName)) {
- return;
- }
- resource.setName(newName);
- OverviewView.this.resourceService.updateResource(resource, new AsyncCallback<Void>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError("Failed to change name of Resource with id "
- + resource.getId()
- + " from \"" + oldName + "\" to \"" + newName + "\".", caught);
- // We failed to update it on the Server, so change back the Resource and the form item to
- // the original value.
- resource.setName(oldName);
- nameItem.setValue(oldName);
- }
-
- public void onSuccess(Void result) {
- CoreGUI.getMessageCenter().notify(new Message("Name of Resource with id "
- + resource.getId() + " was changed from \""
- + oldName + "\" to \"" + newName + "\".", Message.Severity.Info));
- }
- });
+ @Override
+ public void onRecordClick(RecordClickEvent event) {
+ String detail = event.getRecord().getAttribute("detail");
+ SC.say("Error details", detail);
}
});
- }
- formItems.add(nameItem);
-
- final FormItem descriptionItem = (modifiable) ? new TogglableTextItem() : new StaticTextItem();
- descriptionItem.setName("description");
- descriptionItem.setTitle("Description");
- descriptionItem.setValue(resource.getDescription());
- if (descriptionItem instanceof TogglableTextItem) {
- TogglableTextItem togglableDescriptionItem = (TogglableTextItem) descriptionItem;
- togglableDescriptionItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
- public void onValueUpdated(final String newDescription) {
- final String oldDescription = resource.getDescription();
- if (newDescription.equals(oldDescription)) {
- return;
- }
- resource.setDescription(newDescription);
- OverviewView.this.resourceService.updateResource(resource, new AsyncCallback<Void>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError("Failed to change description of Resource with id "
- + resource.getId()
- + " from \"" + oldDescription + "\" to \"" + newDescription + "\".", caught);
- // We failed to update it on the Server, so change back the Resource and the form item to
- // the original value.
- resource.setDescription(oldDescription);
- descriptionItem.setValue(oldDescription);
- }
-
- public void onSuccess(Void result) {
- CoreGUI.getMessageCenter().notify(new Message("Description of Resource with id "
- + resource.getId() + " was changed from \""
- + oldDescription + "\" to \"" + newDescription + "\".", Message.Severity.Info));
- }
- });
- }
- });
- }
- formItems.add(descriptionItem);
- final FormItem locationItem = (modifiable) ? new TogglableTextItem() : new StaticTextItem();
- locationItem.setName("location");
- locationItem.setTitle("Location");
- locationItem.setValue(resource.getLocation());
- if (locationItem instanceof TogglableTextItem) {
- TogglableTextItem togglableNameItem = (TogglableTextItem) locationItem;
- togglableNameItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
- public void onValueUpdated(final String newLocation) {
- final String oldLocation = resource.getLocation();
- if (newLocation.equals(oldLocation)) {
- return;
- }
- resource.setLocation(newLocation);
- OverviewView.this.resourceService.updateResource(resource, new AsyncCallback<Void>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError("Failed to change location of Resource with id "
- + resource.getId()
- + " from \"" + oldLocation + "\" to \"" + newLocation + "\".", caught);
- // We failed to update it on the Server, so change back the Resource and the form item to
- // the original value.
- resource.setLocation(oldLocation);
- locationItem.setValue(oldLocation);
- }
+ errorsGrid.setFields(summaryField);
- public void onSuccess(Void result) {
- CoreGUI.getMessageCenter().notify(new Message("Location of Resource with id "
- + resource.getId() + " was changed from \""
- + oldLocation + "\" to \"" + newLocation + "\".", Message.Severity.Info));
- }
- });
- }
- });
- }
- formItems.add(locationItem);
-
-
- StaticTextItem versionItem = new StaticTextItem("version", "Version");
- formItems.add(versionItem);
-
- StaticTextItem parentItem = new StaticTextItem("parent", "Parent");
- formItems.add(parentItem);
-
- for (MeasurementDefinition trait : traits) {
- String id = trait.getDisplayName().replaceAll("\\.", "_").replaceAll(" ", "__");
+ List<ListGridRecord> errorList = new ArrayList<ListGridRecord>();
+ for (ResourceError error : resource.getResourceErrors()) {
+ ListGridRecord record = new ListGridRecord();
+ record.setAttribute("summary", error.getSummary());
+ record.setAttribute("detail", error.getDetail());
+ errorList.add(record);
+ }
- StaticTextItem item = new StaticTextItem(id, trait.getDisplayName());
- item.setTooltip(trait.getDescription());
- formItems.add(item);
-// item.setValue("?");
+ errorsGrid.setRecords(errorList.toArray(new ListGridRecord[errorList.size()]));
}
-// SectionItem section = new SectionItem("Summary", "Summary");
-// section.setTitle("Summary");
-// section.setDefaultValue("Summary");
-// section.setCanCollapse(true);
-// section.setCellStyle("HidablePlainSectionHeader");
-// section.setItemIds(itemIds.toArray(new String[itemIds.size()]));
-// formItems.add(0, section);
-
- formItems.add(new SpacerItem());
- setItems(formItems.toArray(new FormItem[formItems.size()]));
-
- setValue("type", type.getName() + " (" + type.getPlugin() + ")");
- setValue("name", resource.getName());
- setValue("description", resource.getDescription());
- setValue("location", resource.getLocation());
- setValue("version", (resource.getVersion() != null) ? resource.getVersion() : "<i>none</i>");
- Resource parentResource = resource.getParentResource();
- setValue("parent", parentResource != null ?
- ("<a href=\"#Resource/" + parentResource.getId() + "\">" +
- parentResource.getName() + "</a>") : "<i>none</i>");
+ return errorsGrid;
}
}
commit d266142e299215832de65b40be45e40862f56128
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Aug 20 15:14:04 2010 +0200
adding a test plugin that fails the upgrade so that we can add the tests for handling that scenario
diff --git a/modules/core/plugin-container/pom.xml b/modules/core/plugin-container/pom.xml
index 4b4524a..a4ca249 100644
--- a/modules/core/plugin-container/pom.xml
+++ b/modules/core/plugin-container/pom.xml
@@ -177,6 +177,12 @@
<jar destfile="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar">
<fileset dir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v2" includes="*.class,**/rhq-plugin.xml" />
</jar>
+ <copy toDir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/failing/META-INF">
+ <fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/failing/rhq-plugin.xml" />
+ </copy>
+ <jar destfile="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-3.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/failing" includes="*.class,**/rhq-plugin.xml" />
+ </jar>
</tasks>
</configuration>
<goals>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/DiscComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/DiscComponent.java
new file mode 100644
index 0000000..54153e6
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/DiscComponent.java
@@ -0,0 +1,54 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.core.pc.upgrade.plugins.failing;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
+import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
+
+/**
+ *
+ * @author Lukas Krejci
+ */
+public class DiscComponent implements ResourceDiscoveryComponent<ResourceComponent>,
+ ResourceUpgradeFacet<ResourceComponent> {
+
+ private static final String RESOURCE_KEY = "resource-key-failing";
+ private static final String RESOURCE_NAME = "resource-name-failing";
+ private static final String RESOURCE_DESCRIPTION = "resource-description-failing";
+
+ public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext<ResourceComponent> context)
+ throws InvalidPluginConfigurationException, Exception {
+ return Collections.singleton(new DiscoveredResourceDetails(context.getResourceType(), RESOURCE_KEY,
+ RESOURCE_NAME, null, RESOURCE_DESCRIPTION, context.getDefaultPluginConfiguration(), null));
+ }
+
+ public ResourceUpgradeReport upgrade(ResourceUpgradeContext<ResourceComponent> inventoriedResource) {
+ throw new RuntimeException("Failing the upgrade purposefully.");
+ }
+}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/ResComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/ResComponent.java
new file mode 100644
index 0000000..4c33adc
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/ResComponent.java
@@ -0,0 +1,46 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.core.pc.upgrade.plugins.failing;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
+
+/**
+ *
+ * @author Lukas Krejci
+ */
+public class ResComponent implements ResourceComponent<ResourceComponent> {
+ private static final Log log = LogFactory.getLog(ResComponent.class);
+
+ public AvailabilityType getAvailability() {
+ return AvailabilityType.UP;
+ }
+
+ public void start(ResourceContext<ResourceComponent> context) throws InvalidPluginConfigurationException, Exception {
+ log.info("~~~ starting the resource upgrade test failing component with resource key: " + context.getResourceKey());
+ }
+
+ public void stop() {
+ }
+}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/rhq-plugin.xml
new file mode 100644
index 0000000..9e750d1
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/rhq-plugin.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeTest"
+ displayName="Resource Upgrade Test"
+ description="Resource Upgrade Test"
+ package="org.rhq.core.pc.upgrade.plugins.failing"
+ version="3.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <server name="Resource"
+ discovery="DiscComponent"
+ class="ResComponent"
+ singleton="true" />
+
+</plugin>
+
commit 6dde2f7be37f23a5e8a9b25ccf66e99541fd3bc7
Merge: d58520e... 462e15f...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Aug 20 12:50:39 2010 +0200
Merge branch 'master' into resource-upgrade
commit d58520e4a31ab38e03151e827488776d4dcca93f
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Aug 20 12:46:29 2010 +0200
Added agent and server side support for upgrade error reporting.
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
index f055e8c..9532920 100644
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
@@ -23,6 +23,9 @@
package org.rhq.core.clientapi.agent.upgrade;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
import org.rhq.core.domain.resource.ResourceUpgradeReport;
/**
@@ -34,44 +37,95 @@ public class ResourceUpgradeRequest extends ResourceUpgradeReport {
private static final long serialVersionUID = 1L;
- private int resourceId;
+ private final int resourceId;
+ private String upgradeErrorMessage;
+ private String upgradeErrorStackTrace;
+ private long timestamp;
- public ResourceUpgradeRequest() {
-
+ public ResourceUpgradeRequest(int resourceId) {
+ this.resourceId = resourceId;
}
public ResourceUpgradeRequest(int resourceId, ResourceUpgradeReport report) {
- setResourceId(resourceId);
- setNewDescription(report.getNewDescription());
- setNewName(report.getNewName());
- setNewResourceKey(report.getNewResourceKey());
+ this.resourceId = resourceId;
+ fillInFromReport(report);
}
-
+
public int getResourceId() {
return resourceId;
}
- public void setResourceId(int resourceId) {
- this.resourceId = resourceId;
+ public String getUpgradeErrorMessage() {
+ return upgradeErrorMessage;
+ }
+
+ public void setUpgradeErrorMessage(String upgradeErrorMessage) {
+ this.upgradeErrorMessage = upgradeErrorMessage;
+ }
+
+ public String getUpgradeErrorStackTrace() {
+ return upgradeErrorStackTrace;
+ }
+
+ public void setUpgradeErrorStackTrace(String upgradeErrorStackTrace) {
+ this.upgradeErrorStackTrace = upgradeErrorStackTrace;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
}
+ public void setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ public void setErrorProperties(Throwable t) {
+ upgradeErrorMessage = t.getMessage();
+
+ StringWriter string = new StringWriter();
+ PrintWriter w = new PrintWriter(string);
+ t.printStackTrace(w);
+ w.close();
+
+ upgradeErrorStackTrace = string.toString();
+ }
+
+ public void fillInFromReport(ResourceUpgradeReport report) {
+ setNewDescription(report.getNewDescription());
+ setNewName(report.getNewName());
+ setNewResourceKey(report.getNewResourceKey());
+ }
+
+ @Override
+ public boolean hasSomethingToUpgrade() {
+ return super.hasSomethingToUpgrade() || upgradeErrorMessage != null || upgradeErrorStackTrace != null;
+ }
+
@Override
public int hashCode() {
return 31 * resourceId;
}
-
+
@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}
-
+
if (!(other instanceof ResourceUpgradeRequest)) {
return false;
}
-
+
ResourceUpgradeRequest r = (ResourceUpgradeRequest) other;
-
+
return r.getResourceId() == resourceId;
}
+
+ @Override
+ public String toString() {
+ return "ResourceUpgradeRequest[resourceId = '" + resourceId + "', newResourceKey = '" + getNewResourceKey()
+ + "', newName = '" + getNewName() + "', newDescription = '" + getNewDescription()
+ + "', upgradeErrorMessage = '" + upgradeErrorMessage + "', upgradeErrorStackTrace = '"
+ + upgradeErrorStackTrace + "']";
+ }
}
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceErrorType.java b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceErrorType.java
index 1435cc3..8fcedb7 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceErrorType.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceErrorType.java
@@ -36,5 +36,10 @@ public enum ResourceErrorType {
/**
* An exception was thrown by the Resource component's getAvailablity() method the last time it was called.
*/
- AVAILABILITY_CHECK
+ AVAILABILITY_CHECK,
+
+ /**
+ * There was an attempt to upgrade the resource on the agent but it failed.
+ */
+ UPGRADE
}
\ No newline at end of file
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 728b2e3..3af9b84 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -1202,14 +1202,14 @@ public class InventoryManager extends AgentService implements ContainerService,
return resourceContainer.updateAvailability(availabilityType);
}
- public void mergeResourceFromUpgrade(Set<ResourceUpgradeRequest> upgradeReports) {
+ public void mergeResourceFromUpgrade(Set<ResourceUpgradeRequest> upgradeRequests) {
Set<ResourceUpgradeResponse> serverUpdates = null;
try {
ServerServices serverServices = this.configuration.getServerServices();
if (serverServices != null) {
DiscoveryServerService discoveryServerService = serverServices.getDiscoveryServerService();
- serverUpdates = discoveryServerService.upgradeResources(upgradeReports);
+ serverUpdates = discoveryServerService.upgradeResources(upgradeRequests);
}
} catch (Exception e) {
log.error("Failed to process resource upgrades on the server.", e);
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
index 5b33fe1..025ba3a 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
@@ -82,12 +82,10 @@ public class ResourceUpgradeDelegate {
* @return true if the resource was queued for upgrade, false otherwise
* @throws PluginContainerException on error
*/
- public boolean processAndQueue(ResourceContainer resourceContainer) throws PluginContainerException {
+ public void processAndQueue(ResourceContainer resourceContainer) throws PluginContainerException {
if (enabled) {
- return executeResourceUpgradeFacetAndStoreRequest(resourceContainer);
+ executeResourceUpgradeFacetAndStoreRequest(resourceContainer);
}
-
- return false;
}
public void sendRequests() {
@@ -100,7 +98,7 @@ public class ResourceUpgradeDelegate {
}
@SuppressWarnings("unchecked")
- private <T extends ResourceComponent> boolean executeResourceUpgradeFacetAndStoreRequest(
+ private <T extends ResourceComponent> void executeResourceUpgradeFacetAndStoreRequest(
ResourceContainer resourceContainer) throws PluginContainerException {
ResourceComponent<T> parentResourceComponent = resourceContainer.getResourceContext()
@@ -118,36 +116,47 @@ public class ResourceUpgradeDelegate {
if (!(discoveryComponent instanceof ResourceUpgradeFacet)) {
//well, there's no point in continuing if the resource doesn't support the facet
- return false;
+ return;
}
ResourceUpgradeContext<ResourceComponent<T>> upgradeContext = inventoryManager.createResourceUpgradeContext(
resource, parentResourceComponent, discoveryComponent);
- ResourceUpgradeReport upgradeReport;
+ ResourceUpgradeRequest request = new ResourceUpgradeRequest(resource.getId());
+
+ request.setTimestamp(System.currentTimeMillis());
+
+ ResourceUpgradeReport upgradeReport = null;
try {
upgradeReport = inventoryManager.invokeDiscoveryComponentResourceUpgradeFacet(resource.getResourceType(),
discoveryComponent, upgradeContext);
} catch (Throwable t) {
log.error("ResourceUpgradeFacet threw an exception while upgrading resource [" + resource + "]", t);
- return false;
+ request.setErrorProperties(t);
}
- if (upgradeReport == null || !upgradeReport.hasSomethingToUpgrade()) {
- return false;
- }
+ if (upgradeReport != null && upgradeReport.hasSomethingToUpgrade()) {
+ String upgradeErrors = null;
+ if ((upgradeErrors = checkUpgradeValid(resource, upgradeReport)) != null) {
+ String errorString = "Upgrading the resource [" + resource + "] using these updates [" + upgradeReport
+ + "] would render the inventory invalid because of the following reasons: " + upgradeErrors;
+
+ log.error(errorString);
+
+ IllegalStateException ex = new IllegalStateException(errorString);
+ ex.fillInStackTrace();
+
+ request.setErrorProperties(ex);
+ } else {
+ request.fillInFromReport(upgradeReport);
+ }
- String upgradeErrors = null;
- if ((upgradeErrors = checkUpgradeValid(resource, upgradeReport)) != null) {
- log.error("Upgrading the resource [" + resource + "] using these updates [" + upgradeReport
- + "] would render the inventory invalid because of the following reasons: " + upgradeErrors);
- return false;
}
//everything went ok, let's queue a upgrade request that will be sent to the server
- requests.add(new ResourceUpgradeRequest(resource.getId(), upgradeReport));
-
- return true;
+ if (request.hasSomethingToUpgrade()) {
+ requests.add(request);
+ }
}
private String checkUpgradeValid(Resource resource, ResourceUpgradeReport upgradeReport) {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index 304cbad..b773384 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -58,6 +58,8 @@ import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.ProductVersion;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceCategory;
+import org.rhq.core.domain.resource.ResourceError;
+import org.rhq.core.domain.resource.ResourceErrorType;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.domain.util.PageControl;
@@ -422,7 +424,9 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
Resource existingResource = this.entityManager.find(Resource.class, request.getResourceId());
if (existingResource != null) {
ResourceUpgradeResponse upgradedData = upgradeResource(existingResource, request, allowGenericPropertiesUpgrade);
- result.add(upgradedData);
+ if (upgradedData != null) {
+ result.add(upgradedData);
+ }
}
}
return result;
@@ -475,18 +479,24 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
/**
* @param existingResource
- * @param upgradeReport
+ * @param upgradeRequest
* @param allowGenericPropertiesUpgrade name and description are only upgraded if this is true
* @return true if the resource was changed, false otherwise
*/
- private ResourceUpgradeResponse upgradeResource(@NotNull Resource resource, ResourceUpgradeReport upgradeReport, boolean allowGenericPropertiesUpgrade) {
+ private ResourceUpgradeResponse upgradeResource(@NotNull Resource resource, ResourceUpgradeRequest upgradeRequest, boolean allowGenericPropertiesUpgrade) {
+ if (upgradeRequest.getUpgradeErrorMessage() != null) {
+ ResourceError error = new ResourceError(resource, ResourceErrorType.UPGRADE, upgradeRequest.getUpgradeErrorMessage(), upgradeRequest.getUpgradeErrorStackTrace(), upgradeRequest.getTimestamp());
+ entityManager.persist(error);
+ return null;
+ }
+
ResourceUpgradeResponse ret = new ResourceUpgradeResponse();
ret.setResourceId(resource.getId());
- String resourceKey = upgradeReport.getNewResourceKey();
- String name = upgradeReport.getNewName();
+ String resourceKey = upgradeRequest.getNewResourceKey();
+ String name = upgradeRequest.getNewName();
// String version = upgradeReport.getNewVersion();
- String description = upgradeReport.getNewDescription();
+ String description = upgradeRequest.getNewDescription();
// Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
// Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
commit 5b093893923a739ed2634c73e05392e917b8e7fb
Merge: 63d04ea... a13c17d...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Aug 11 16:43:07 2010 +0200
Merge branch 'master' into resource-upgrade
diff --cc modules/enterprise/gui/portal-war/src/main/webapp/admin/config/GeneralPropertiesConfigForm.jsp
index 136c37c,45526f7..0000000
deleted file mode 100644,100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/GeneralPropertiesConfigForm.jsp
+++ /dev/null
diff --cc modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index add8168,2773b4c..304cbad
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@@ -659,22 -559,10 +659,22 @@@ public class DiscoveryBossBean implemen
*/
ResourceType resourceType = resource.getResourceType();
Resource parent = resource;
+ Subject overlord = subjectManager.getOverlord();
while (parent != null && existingResource == null) {
parent = parent.getParentResource();
- existingResource = resourceManager.getResourceByParentAndKey(subjectManager.getOverlord(), parent,
+ //check if the parent itself is inventoried. This might not be the case
+ //during initial sync-up for resource upgrade.
+ Resource existingParent = null;
+ if (parent != null) {
+ existingParent = entityManager.find(Resource.class, parent.getId());
+ if (existingParent == null) {
+ //well, this parent is not known to the server, so there's no
+ //point in trying to find a child of it...
+ continue;
+ }
+ }
+ existingResource = resourceManager.getResourceByParentAndKey(overlord, existingParent,
- resource.getResourceKey(), resourceType.getPlugin(), resourceType.getName());
+ resource.getResourceKey(), resourceType.getPlugin(), resourceType.getName());
}
if (existingResource != null) {
@@@ -905,8 -808,4 +920,8 @@@
updateInventoryStatus(subject, platforms, servers, target);
}
-}
+
+ private static <T> boolean needsUpgrade(T oldValue, T newValue) {
+ return newValue != null && (oldValue == null || !newValue.equals(oldValue));
+ }
- }
++}
commit 63d04eaf7e697a241efe59832d7a4e127a084f92
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Jul 12 18:39:22 2010 +0200
Adding tests for graceful handling of server-side exceptions and platform "disappearance" on the server-side.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index a5c3d1f..6fe7e96 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -940,8 +940,16 @@ public class InventoryManager extends AgentService implements ContainerService,
//resource upgrade executor to sync up with the server side inventory *JUST AFTER*
//this agent registered with the server for the very first time. In that case
//the server hasn't received any info from us yet.
+ //Another (rare) scenario where this would happen would be when the platform resource type
+ //would change.
+ //In either case, let's sync up with the server - if it's got nothing, neither should the agent.
if (syncInfo != null) {
synchInventory(syncInfo);
+ } else {
+ purgeObsoleteResources(Collections.<String>emptySet());
+
+ //can't live without a platform, but we just deleted it. Let's rediscover it.
+ discoverPlatform();
}
return true;
@@ -1077,8 +1085,10 @@ public class InventoryManager extends AgentService implements ContainerService,
return;
}
boolean scan = removeResourceAndIndicateIfScanIsNeeded(resourceContainer.getResource());
-
- if (scan) {
+
+ //only actually schedule the scanning when we are finished with resource upgrade. The resource upgrade
+ //happens before any scanning infrastructure is established.
+ if (!resourceUpgradeDelegate.enabled() && scan) {
log.info("Deleted resource #[" + resourceId + "] - this will trigger a server scan now");
inventoryThreadPoolExecutor.submit((Callable<InventoryReport>) this.serverScanExecutor);
}
@@ -2612,14 +2622,13 @@ public class InventoryManager extends AgentService implements ContainerService,
ResourceContainer container = getResourceContainer(resource);
if (container != null) {
- try {
- container = getResourceContainer(resource);
- resourceUpgradeDelegate.processAndQueue(container);
- } catch (PluginContainerException e) {
- log.error("Exception thrown while upgrading [" + resource + "].");
- }
-
if (container.getResourceComponentState() == ResourceComponentState.STARTED) {
+ try {
+ resourceUpgradeDelegate.processAndQueue(container);
+ } catch (PluginContainerException e) {
+ log.error("Exception thrown while upgrading [" + resource + "].", e);
+ }
+
for (Resource child : resource.getChildResources()) {
upgradeResource(child);
}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
index c3bdbf4..19c1d95 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
@@ -56,7 +56,8 @@ public class FakeServerInventory {
private Resource platform;
private Map<String, Resource> resourceStore = new HashMap<String, Resource>();
private int counter;
-
+ private boolean failing;
+
private static final Comparator<Resource> ID_COMPARATOR = new Comparator<Resource>() {
public int compare(Resource o1, Resource o2) {
return o1.getId() - o2.getId();
@@ -69,11 +70,21 @@ public class FakeServerInventory {
}
};
+ public FakeServerInventory() {
+ this(false);
+ }
+
+ public FakeServerInventory(boolean failing) {
+ this.failing = failing;
+ }
+
//need to synchronize, because resource upgrade is async and can overlap with
//resource discovery.
public synchronized CustomAction mergeInventoryReport(final InventoryStatus requiredInventoryStatus) {
return new CustomAction("updateServerSideInventory") {
public Object invoke(Invocation invocation) throws Throwable {
+ throwIfFailing();
+
InventoryReport inventoryReport = (InventoryReport) invocation.getParameter(0);
for(Resource res : inventoryReport.getAddedRoots()) {
@@ -87,10 +98,24 @@ public class FakeServerInventory {
};
}
+ public synchronized CustomAction clearPlatform() {
+ return new CustomAction("updateServerSideInventory - report platform deleted on the server") {
+ public Object invoke(Invocation invocation) throws Throwable {
+ throwIfFailing();
+
+ platform = null;
+
+ return getSyncInfo();
+ }
+ };
+ }
+
public synchronized CustomAction upgradeResources() {
return new CustomAction("upgradeServerSideInventory") {
@SuppressWarnings({"serial", "unchecked"})
public Object invoke(Invocation invocation) throws Throwable {
+ throwIfFailing();
+
Set<ResourceUpgradeRequest> requests = (Set<ResourceUpgradeRequest>) invocation.getParameter(0);
Set<ResourceUpgradeResponse> responses = new HashSet<ResourceUpgradeResponse>();
@@ -129,6 +154,8 @@ public class FakeServerInventory {
return new CustomAction("getResources") {
@SuppressWarnings("unchecked")
public Object invoke(Invocation invocation) throws Throwable {
+ throwIfFailing();
+
Set<Integer> resourceIds = (Set<Integer>)invocation.getParameter(0);
boolean includeDescendants = (Boolean) invocation.getParameter(1);
@@ -137,6 +164,14 @@ public class FakeServerInventory {
};
}
+ public boolean isFailing() {
+ return failing;
+ }
+
+ public void setFailing(boolean failing) {
+ this.failing = failing;
+ }
+
@SuppressWarnings("serial")
public synchronized Set<Resource> findResourcesByType(final ResourceType type) {
Set<Resource> result = new HashSet<Resource>();
@@ -218,6 +253,12 @@ public class FakeServerInventory {
return platform != null ? convert(platform) : null;
}
+ private void throwIfFailing() {
+ if (failing) {
+ throw new RuntimeException("Fake server inventory is in the failing mode.");
+ }
+ }
+
private static ResourceSyncInfo convert(Resource root) {
try {
ResourceSyncInfo ret = new ResourceSyncInfo();
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index b5d571f..202e0c0 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -25,6 +25,7 @@ package org.rhq.core.pc.upgrade;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
import java.io.File;
import java.io.IOException;
@@ -151,11 +152,83 @@ public class ResourceUpgradeTest {
}
@Test
- public void testRecoveryWithServerUnavailable() throws Exception {
- //TODO implement
+ public void testSkipUpgradeWhenServerUnavailable() throws Exception {
+ currentServerSideInventory = new FakeServerInventory();
+ initialSyncAndDiscovery(InventoryStatus.COMMITTED);
+
+ currentServerSideInventory.setFailing(true);
+
+ TestPayload test = new TestPayload() {
+ public void test(Resource discoveredResource) {
+ assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
+ assertEquals(discoveredResource.getName(), "resource-name-v1");
+ assertEquals(discoveredResource.getDescription(), "resource-description-v1");
+ }
+
+ @SuppressWarnings("unchecked")
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+
+ between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+
+ never(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
+ }
+ };
+ }
+ };
+
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, test);
+ }
+
+ @Test
+ public void testUpgradeWithPlatformDeletedOnServer() throws Exception {
+ currentServerSideInventory = new FakeServerInventory();
+ initialSyncAndDiscovery(InventoryStatus.COMMITTED);
+
+ TestPayload test = new TestPayload() {
+ public void test(Resource discoveredResource) {
+ assertEquals(discoveredResource.getResourceKey(), "resource-key-v2");
+ assertEquals(discoveredResource.getName(), "resource-name-v2");
+ assertEquals(discoveredResource.getDescription(), "resource-description-v2");
+
+ ResourceContainer container = PluginContainer.getInstance().getInventoryManager().getResourceContainer(discoveredResource);
+ File dataDir = container.getResourceContext().getDataDirectory();
+
+ File marker = new File(dataDir, "upgrade-succeeded");
+
+ assertFalse(marker.exists(), "The upgrade seems to have occured even though there shouldn't have been a resource to upgrade.");
+ }
+
+ @SuppressWarnings("unchecked")
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+
+ //the first merge will be triggered from within the upgrade process and we are
+ //going to report null sync.
+ oneOf(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(currentServerSideInventory.clearPlatform());
+
+ //the rest of the inventory merges are executed by discoveries, so let's import the
+ //discovered stuff into the server-side inventory.
+ between(1, 3).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+
+ never(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
+ }
+ };
+ }
+ };
+
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, test);
}
private void initialSyncAndDiscovery(final InventoryStatus requiredInventoryStatus) throws Exception {
+ cleanDataDir();
executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), true, new TestPayload() {
public void test(Resource discoveredResource) {
assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
@@ -303,40 +376,43 @@ public class ResourceUpgradeTest {
for(String pluginResourcePath : pluginResourcePaths) {
copyPlugin(pluginResourcePath, pluginDir);
}
-
+
Mockery context = new Mockery();
-
+
PluginContainerConfiguration pcConfig = createPluginContainerConfiguration(context);
-
+
if (clearInventoryDat) {
File inventoryDat = new File(pcConfig.getDataDirectory(), "inventory.dat");
inventoryDat.delete();
}
-
+
context.checking(test.getExpectations(context));
-
+
PluginContainer.getInstance().setConfiguration(pcConfig);
PluginContainer.getInstance().initialize();
-
- //give the pc the time to finish resource upgrade
- Thread.sleep(1000);
-
- //execute full discovery
- InventoryManager im = PluginContainer.getInstance().getInventoryManager();
- im.executeServerScanImmediately();
- im.executeServiceScanImmediately();
-
- Set<Resource> resources = getTestingResources();
-
- assertEquals(resources.size(), 1, "There should be only a single testing resource but " + resources + " were found.");
-
- Resource discoveredResource = resources.iterator().next();
-
- test.test(discoveredResource);
-
- PluginContainer.getInstance().shutdown();
-
- context.assertIsSatisfied();
+
+ try {
+ //give the pc the time to finish resource upgrade
+ Thread.sleep(1000);
+
+ //execute full discovery
+ InventoryManager im = PluginContainer.getInstance().getInventoryManager();
+ im.executeServerScanImmediately();
+ im.executeServiceScanImmediately();
+
+ Set<Resource> resources = getTestingResources();
+
+ assertEquals(resources.size(), 1, "There should be only a single testing resource but " + resources
+ + " were found.");
+
+ Resource discoveredResource = resources.iterator().next();
+
+ test.test(discoveredResource);
+
+ context.assertIsSatisfied();
+ } finally {
+ PluginContainer.getInstance().shutdown();
+ }
}
@SuppressWarnings("unchecked")
@@ -356,4 +432,8 @@ public class ResourceUpgradeTest {
expectations.allowing(currentDiscoveryServerService).getResources(expectations.with(Expectations.any(Set.class)), expectations.with(Expectations.any(boolean.class)));
expectations.will(currentServerSideInventory.getResources());
}
+
+ private void cleanDataDir() throws IOException {
+ FileUtils.cleanDirectory(new File(tmpDir, DATA_DIR_NAME));
+ }
}
commit 178d4de9fb18d7f9045e673e64c33a359436be81
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Jul 6 19:12:26 2010 -0400
generate the two resource upgrade test plugins rather than have the .jar files committed directly to git
this way we can see the source and change it if we ever need to.
also allows us to have source to step through in a debugger
diff --git a/modules/core/plugin-container/pom.xml b/modules/core/plugin-container/pom.xml
index 2e58102..93f64cf 100644
--- a/modules/core/plugin-container/pom.xml
+++ b/modules/core/plugin-container/pom.xml
@@ -126,6 +126,7 @@
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
+ <id>process-test-resources</id>
<phase>process-test-resources</phase>
<configuration>
<tasks>
@@ -151,7 +152,31 @@
<include name="**/lib/*" />
</fileset>
</move>
- <delete dir="${project.build.directory}/jboss-sigar/hyperic-sigar-${sigar.version}" />
+ <delete dir="${project.build.directory}/jboss-sigar/hyperic-sigar-${sigar.version}" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>process-test-classes</id>
+ <phase>process-test-classes</phase>
+ <configuration>
+ <tasks>
+ <echo>Assembling the two resource upgrade test plugins</echo>
+ <copy toDir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v1/META-INF">
+ <fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/v1/rhq-plugin.xml" />
+ </copy>
+ <jar destfile="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-1.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v1" includes="*.class,**/rhq-plugin.xml" />
+ </jar>
+ <copy toDir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v2/META-INF">
+ <fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/v2/rhq-plugin.xml" />
+ </copy>
+ <jar destfile="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v2" includes="*.class,**/rhq-plugin.xml" />
+ </jar>
</tasks>
</configuration>
<goals>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/DiscComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/DiscComponent.java
new file mode 100644
index 0000000..5fbca32
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/DiscComponent.java
@@ -0,0 +1,22 @@
+package org.rhq.core.pc.upgrade.plugins.v1;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+
+public class DiscComponent implements ResourceDiscoveryComponent<ResourceComponent> {
+ private static final String RESOURCE_KEY = "resource-key-v1";
+ private static final String RESOURCE_NAME = "resource-name-v1";
+ private static final String RESOURCE_DESCRIPTION = "resource-description-v1";
+
+ public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext<ResourceComponent> context)
+ throws InvalidPluginConfigurationException, Exception {
+ return Collections.singleton(new DiscoveredResourceDetails(context.getResourceType(), RESOURCE_KEY,
+ RESOURCE_NAME, null, RESOURCE_DESCRIPTION, context.getDefaultPluginConfiguration(), null));
+ }
+}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/ResComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/ResComponent.java
new file mode 100644
index 0000000..cc21fc3
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/ResComponent.java
@@ -0,0 +1,21 @@
+package org.rhq.core.pc.upgrade.plugins.v1;
+
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
+
+public class ResComponent implements ResourceComponent<ResourceComponent> {
+ public AvailabilityType getAvailability() {
+ return AvailabilityType.UP;
+ }
+
+ public void start(ResourceContext<ResourceComponent> context) {
+ LogFactory.getLog(this.getClass()).info(
+ "~~~ Starting resource upgrade test plugin v1 component: key=" + context.getResourceKey());
+ }
+
+ public void stop() {
+ }
+}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/rhq-plugin.xml
new file mode 100644
index 0000000..c658e0c
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/rhq-plugin.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeTest"
+ displayName="Resource Upgrade Test"
+ description="Resource Upgrade Test"
+ package="org.rhq.core.pc.upgrade.plugins.v1"
+ version="1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <server name="Resource"
+ discovery="DiscComponent"
+ class="ResComponent"
+ singleton="true" />
+
+</plugin>
+
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/DiscComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/DiscComponent.java
new file mode 100644
index 0000000..d113d1c
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/DiscComponent.java
@@ -0,0 +1,54 @@
+package org.rhq.core.pc.upgrade.plugins.v2;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Set;
+
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
+import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
+
+public class DiscComponent implements ResourceDiscoveryComponent<ResourceComponent>,
+ ResourceUpgradeFacet<ResourceComponent> {
+ private static final String V1_RESOURCE_KEY = "resource-key-v1";
+ private static final String RESOURCE_KEY = "resource-key-v2";
+ private static final String RESOURCE_NAME = "resource-name-v2";
+ private static final String RESOURCE_DESCRIPTION = "resource-description-v2";
+
+ public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext<ResourceComponent> context)
+ throws InvalidPluginConfigurationException, Exception {
+ return Collections.singleton(new DiscoveredResourceDetails(context.getResourceType(), RESOURCE_KEY,
+ RESOURCE_NAME, null, RESOURCE_DESCRIPTION, context.getDefaultPluginConfiguration(), null));
+ }
+
+ public ResourceUpgradeReport upgrade(ResourceUpgradeContext<ResourceComponent> inventoriedResource) {
+ if (V1_RESOURCE_KEY.equals(inventoriedResource.getResourceKey())) {
+ ResourceUpgradeReport report = new ResourceUpgradeReport();
+ report.setNewResourceKey(RESOURCE_KEY);
+ report.setNewName(RESOURCE_NAME);
+ report.setNewDescription(RESOURCE_DESCRIPTION);
+
+ File dataDir = inventoriedResource.getDataDirectory();
+
+ if (dataDir != null) {
+ if (!(dataDir.exists())) {
+ dataDir.mkdir();
+ }
+ File marker = new File(dataDir, "upgrade-succeeded");
+ try {
+ marker.createNewFile();
+ } catch (IOException localIOException) {
+ }
+ }
+ return report;
+ }
+
+ return null;
+ }
+}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/ResComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/ResComponent.java
new file mode 100644
index 0000000..83144b2
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/ResComponent.java
@@ -0,0 +1,21 @@
+package org.rhq.core.pc.upgrade.plugins.v2;
+
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
+
+public class ResComponent implements ResourceComponent<ResourceComponent> {
+ public AvailabilityType getAvailability() {
+ return AvailabilityType.UP;
+ }
+
+ public void start(ResourceContext<ResourceComponent> context) {
+ LogFactory.getLog(this.getClass()).info(
+ "~~~ Starting resource upgrade test plugin v2 component: key=" + context.getResourceKey());
+ }
+
+ public void stop() {
+ }
+}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/rhq-plugin.xml
new file mode 100644
index 0000000..9f63892
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/rhq-plugin.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeTest"
+ displayName="Resource Upgrade Test"
+ description="Resource Upgrade Test"
+ package="org.rhq.core.pc.upgrade.plugins.v2"
+ version="2.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <server name="Resource"
+ discovery="DiscComponent"
+ class="ResComponent"
+ singleton="true" />
+
+</plugin>
+
diff --git a/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-1.0.0.jar b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-1.0.0.jar
deleted file mode 100644
index 33a79c0..0000000
Binary files a/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-1.0.0.jar and /dev/null differ
diff --git a/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar
deleted file mode 100644
index 7ffc5bb..0000000
Binary files a/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar and /dev/null differ
commit 9edde408d4dbabbc057e5e11fdfb6c3c16d2936e
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Jul 6 16:11:44 2010 -0400
trivial - reformat some things. no need to use isDebugEnabled if you are logging a simple string message with no string concatentation
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 5786702..a5c3d1f 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -72,8 +72,8 @@ import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceCreationDataType;
import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.domain.resource.ResourceErrorType;
-import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.pc.ContainerService;
import org.rhq.core.pc.PluginContainer;
import org.rhq.core.pc.PluginContainerConfiguration;
@@ -193,7 +193,7 @@ public class InventoryManager extends AgentService implements ContainerService,
* Handles the resource upgrade during the initialization of the inventory manager.
*/
private ResourceUpgradeDelegate resourceUpgradeDelegate;
-
+
public InventoryManager() {
super(DiscoveryAgentService.class);
}
@@ -224,7 +224,7 @@ public class InventoryManager extends AgentService implements ContainerService,
//discoveries.
resourceUpgradeDelegate = new ResourceUpgradeDelegate(this);
upgradeResources();
-
+
availabilityCollectors = new AvailabilityCollectorThreadPool();
availabilityCollectors.initialize();
@@ -300,7 +300,7 @@ public class InventoryManager extends AgentService implements ContainerService,
return results;
} catch (TimeoutException te) {
log.warn("Discovery for Resources of [" + context.getResourceType() + "] has been running for more than "
- + timeout + " milliseconds. This may be a plugin bug.", te);
+ + timeout + " milliseconds. This may be a plugin bug.", te);
return null;
} catch (BlacklistedException be) {
// Discovery did not run, because the ResourceType was blacklisted during a prior discovery scan.
@@ -333,8 +333,8 @@ public class InventoryManager extends AgentService implements ContainerService,
return result;
} catch (TimeoutException te) {
log.warn("Manual add of Resource of type [" + context.getResourceType() + "] with plugin configuration ["
- + pluginConfig.toString(true) + "] has been running for more than "
- + timeout + " milliseconds. This may be a plugin bug.", te);
+ + pluginConfig.toString(true) + "] has been running for more than " + timeout
+ + " milliseconds. This may be a plugin bug.", te);
return null;
} catch (BlacklistedException be) {
log.debug(ThrowableUtil.getAllMessages(be));
@@ -382,11 +382,12 @@ public class InventoryManager extends AgentService implements ContainerService,
public <T extends ResourceComponent> ResourceUpgradeReport invokeDiscoveryComponentResourceUpgradeFacet(
ResourceType resourceType, ResourceDiscoveryComponent<T> component,
ResourceUpgradeContext<T> inventoriedResource) throws Throwable {
-
+
long timeout = getDiscoveryComponentTimeout(resourceType);
try {
@SuppressWarnings("unchecked")
- ResourceUpgradeFacet<T> proxy = this.discoveryComponentProxyFactory.getDiscoveryComponentProxy(resourceType, component, timeout, ResourceUpgradeFacet.class);
+ ResourceUpgradeFacet<T> proxy = this.discoveryComponentProxyFactory.getDiscoveryComponentProxy(
+ resourceType, component, timeout, ResourceUpgradeFacet.class);
return proxy.upgrade(inventoriedResource);
} catch (BlacklistedException e) {
@@ -394,7 +395,7 @@ public class InventoryManager extends AgentService implements ContainerService,
return null;
}
}
-
+
public DiscoveryComponentProxyFactory getDiscoveryComponentProxyFactory() {
return this.discoveryComponentProxyFactory;
}
@@ -892,7 +893,7 @@ public class InventoryManager extends AgentService implements ContainerService,
public boolean handleReport(InventoryReport report) {
return handleReport(report, false);
}
-
+
/**
* Send an inventory report to the Server.
*
@@ -904,7 +905,7 @@ public class InventoryManager extends AgentService implements ContainerService,
if (!configuration.isInsideAgent()) {
return true;
}
-
+
if (report.getAddedRoots().isEmpty() && !forceServerRoundtrip) {
return true; // nothing to do
}
@@ -981,7 +982,7 @@ public class InventoryManager extends AgentService implements ContainerService,
log.debug(String.format("DONE syncing local inventory [%d] ms.",
(System.currentTimeMillis() - startTime)));
}
-
+
// If we synced any Resources, one or more Resource components were probably started,
// so run an avail check to report on their availabilities immediately. Also kick off
// a service scan to scan those Resources for new child Resources. Kick both tasks off
@@ -991,7 +992,8 @@ public class InventoryManager extends AgentService implements ContainerService,
// inventory with the server side as well as to disallow any other server-agent traffic during
// the upgrade phase. Not to mention the fact that no thread pools are initialized yet by the
// time the upgrade kicks in..
- if (!resourceUpgradeDelegate.enabled() && (!syncedResources.isEmpty() || !unknownResourceIds.isEmpty() || !modifiedResourceIds.isEmpty())) {
+ if (!resourceUpgradeDelegate.enabled()
+ && (!syncedResources.isEmpty() || !unknownResourceIds.isEmpty() || !modifiedResourceIds.isEmpty())) {
performAvailabilityChecks(true);
this.inventoryThreadPoolExecutor.schedule((Callable<? extends Object>) this.serviceScanExecutor, 5,
TimeUnit.SECONDS);
@@ -1003,7 +1005,7 @@ public class InventoryManager extends AgentService implements ContainerService,
throw new RuntimeException(t);
}
}
-
+
private void getAllUuids(ResourceSyncInfo syncInfo, Set<String> allServerSideUuids) {
allServerSideUuids.add(syncInfo.getUuid());
for (ResourceSyncInfo child : syncInfo.getChildSyncInfos()) {
@@ -1181,13 +1183,13 @@ public class InventoryManager extends AgentService implements ContainerService,
ServerServices serverServices = this.configuration.getServerServices();
if (serverServices != null) {
DiscoveryServerService discoveryServerService = serverServices.getDiscoveryServerService();
-
+
serverUpdates = discoveryServerService.upgradeResources(upgradeReports);
}
} catch (Exception e) {
log.error("Failed to process resource upgrades on the server.", e);
}
-
+
if (serverUpdates != null) {
for (ResourceUpgradeResponse upgradeResponse : serverUpdates) {
String resourceKey = upgradeResponse.getUpgradedResourceKey();
@@ -1202,49 +1204,50 @@ public class InventoryManager extends AgentService implements ContainerService,
ResourceContainer existingResourceContainer = getResourceContainer(upgradeResponse.getResourceId());
if (existingResourceContainer != null) {
Resource existingResource = existingResourceContainer.getResource();
-
- StringBuilder logMessage = new StringBuilder("Resource [")
- .append(existingResource.toString()).append("] upgraded its ");
-
+
+ StringBuilder logMessage = new StringBuilder("Resource [").append(existingResource.toString())
+ .append("] upgraded its ");
+
if (resourceKey != null) {
existingResource.setResourceKey(resourceKey);
logMessage.append("resourceKey, ");
}
-
+
if (name != null) {
existingResource.setName(name);
logMessage.append("name, ");
}
-
-// if (version != null) {
-// existingResource.setVersion(version);
-// }
-
+
+ //if (version != null) {
+ // existingResource.setVersion(version);
+ //}
+
if (description != null) {
existingResource.setDescription(description);
logMessage.append("description, ");
}
-
-// if (pluginConfiguration != null) {
-// existingResource.setPluginConfiguration(pluginConfiguration);
-// }
-//
-// if (resourceConfiguration != null) {
-// existingResource.setResourceConfiguration(resourceConfiguration);
-// }
-
- logMessage.replace(logMessage.length() - 1, logMessage.length(),
- "to become [").append(existingResource.toString()).append("]");
-
+
+ //if (pluginConfiguration != null) {
+ // existingResource.setPluginConfiguration(pluginConfiguration);
+ //}
+ //
+ //if (resourceConfiguration != null) {
+ // existingResource.setResourceConfiguration(resourceConfiguration);
+ //}
+
+ logMessage.replace(logMessage.length() - 1, logMessage.length(), "to become [").append(
+ existingResource.toString()).append("]");
+
log.info(logMessage.toString());
} else {
- log.error("Upgraded a resource that is not present on the agent. This should not happen. The id of the missing resource is " + upgradeResponse.getResourceId());
+ log.error("Upgraded a resource that is not present on the agent. This should not happen. "
+ + "The id of the missing resource is: " + upgradeResponse.getResourceId());
}
}
}
}
}
-
+
public Resource mergeResourceFromDiscovery(Resource resource, Resource parent) throws PluginContainerException {
// If the Resource is already in inventory, make sure its version is up-to-date, then simply return the
// existing Resource.
@@ -1466,7 +1469,7 @@ public class InventoryManager extends AgentService implements ContainerService,
}
ResourceContext context = createResourceContext(resource, parentComponent, discoveryComponent);
-
+
container.setResourceContext(context);
// Wrap the component in a proxy that will provide locking and a timeout for the call to start().
@@ -1513,7 +1516,8 @@ public class InventoryManager extends AgentService implements ContainerService,
}
}
- private <T extends ResourceComponent> ResourceContext<T> createResourceContext(Resource resource, T parentComponent, ResourceDiscoveryComponent<T> discoveryComponent) {
+ private <T extends ResourceComponent> ResourceContext<T> createResourceContext(Resource resource,
+ T parentComponent, ResourceDiscoveryComponent<T> discoveryComponent) {
File pluginDataDir = new File(this.configuration.getDataDirectory(), resource.getResourceType().getPlugin());
return new ResourceContext<T>(resource, // the resource itself
@@ -1529,8 +1533,9 @@ public class InventoryManager extends AgentService implements ContainerService,
this.availabilityCollectors, // for components that want to perform async avail checking
this.configuration.getPluginContainerDeployment()); // helps components make determinations of what to do
}
-
- public <T extends ResourceComponent> ResourceUpgradeContext<T> createResourceUpgradeContext(Resource resource, T parentComponent, ResourceDiscoveryComponent<T> discoveryComponent) {
+
+ public <T extends ResourceComponent> ResourceUpgradeContext<T> createResourceUpgradeContext(Resource resource,
+ T parentComponent, ResourceDiscoveryComponent<T> discoveryComponent) {
File pluginDataDir = new File(this.configuration.getDataDirectory(), resource.getResourceType().getPlugin());
return new ResourceUpgradeContext<T>(resource, // the resource itself
@@ -1546,7 +1551,7 @@ public class InventoryManager extends AgentService implements ContainerService,
this.availabilityCollectors, // for components that want to perform async avail checking
this.configuration.getPluginContainerDeployment()); // helps components make determinations of what to do
}
-
+
/**
* This will send a resource error to the server (if applicable) to indicate that the given resource could not be
* connected to due to an invalid plugin configuration.
@@ -1789,13 +1794,13 @@ public class InventoryManager extends AgentService implements ContainerService,
Set<DiscoveredResourceDetails> allDiscoveredPlatforms = new HashSet<DiscoveredResourceDetails>(2);
if ((platformTypes != null) && (platformTypes.size() > 0)) {
-
+
//check for fake testing type. If the test platform type is being used, it is always going to be
//the sole platform type available.
if (platformTypes.size() == 1 && platformTypes.contains(PluginMetadataManager.TEST_PLATFORM_TYPE)) {
return getTestPlatform();
}
-
+
// Go through all the platform types that are supported and see if they can detect our platform.
for (ResourceType platformType : platformTypes) {
try {
@@ -2123,11 +2128,11 @@ public class InventoryManager extends AgentService implements ContainerService,
@NotNull
Set<Resource> executeComponentDiscovery(ResourceType resourceType, ResourceDiscoveryComponent discoveryComponent,
ResourceContainer parentContainer, List<ProcessScanResult> processScanResults) {
-
+
ResourceContext parentResourceContext = parentContainer.getResourceContext();
ResourceComponent parentComponent = parentContainer.getResourceComponent();
Resource parentResource = parentContainer.getResource();
-
+
long startTime = System.currentTimeMillis();
log.debug("Executing discovery for [" + resourceType.getName() + "] Resources...");
Set<Resource> newResources;
@@ -2578,9 +2583,7 @@ public class InventoryManager extends AgentService implements ContainerService,
private void upgradeResources() {
try {
- if (log.isDebugEnabled()) {
- log.debug("Executing resource upgrade.");
- }
+ log.debug("Executing resource upgrade.");
boolean syncResult = handleReport(new InventoryReport(getAgent()), true);
if (!syncResult) {
@@ -2590,27 +2593,23 @@ public class InventoryManager extends AgentService implements ContainerService,
upgradeResource(getPlatform());
- if (log.isDebugEnabled()) {
- log.debug("Sending the upgrade requests to the server.");
- }
+ log.debug("Sending the upgrade requests to the server.");
resourceUpgradeDelegate.sendRequests();
resourceUpgradeDelegate.disable();
- if (log.isDebugEnabled()) {
- log.debug("Resource upgrade finished.");
- }
+ log.debug("Resource upgrade finished.");
} catch (Throwable t) {
log.error("Resource upgrade failed with an exception.", t);
}
}
-
+
private void upgradeResource(Resource resource) {
//only process committed resources
if (resource.getInventoryStatus() != InventoryStatus.COMMITTED) {
return;
}
-
+
ResourceContainer container = getResourceContainer(resource);
if (container != null) {
try {
@@ -2625,14 +2624,15 @@ public class InventoryManager extends AgentService implements ContainerService,
upgradeResource(child);
}
} else {
- log.error("The resource container for resource [" + resource + "] wasn't started during upgrade. This should not happen.");
- }
+ log.error("The resource container for resource [" + resource
+ + "] wasn't started during upgrade. This should not happen.");
+ }
} else {
log.error("Resource container not initialized for resource [" + resource
+ "] during upgrade. This should not happen.");
}
}
-
+
/**
* That class implements a listener that gets called when the resource got activated
* @author hrupp
commit 1e41a098af78a7d97e0a0415dba48bf0b98dba73
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Jul 6 16:03:35 2010 -0400
trivial - add comment, small reformat
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
index cb466bd..5b33fe1 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
@@ -24,6 +24,7 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+
import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
import org.rhq.core.domain.resource.Resource;
@@ -40,6 +41,11 @@ import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
* This is a helper class to {@link InventoryManager} that takes care of resource upgrade.
* Note that this class is not thread-safe in any manner.
*
+ * This class must not call (explicitly or implicitly anywhere in its outgoing call chain)
+ * any other plugin container manager other than the InventoryManager. This is because
+ * this delegate is called within the Inventory Manager's initialize method and hence
+ * many other managers are not yet initialized themselves yet.
+ *
* @author Lukas Krejci
*/
public class ResourceUpgradeDelegate {
@@ -62,7 +68,7 @@ public class ResourceUpgradeDelegate {
public boolean enabled() {
return enabled;
}
-
+
/**
* Disables all future operations of the delegate.
*/
@@ -93,10 +99,10 @@ public class ResourceUpgradeDelegate {
}
}
+ @SuppressWarnings("unchecked")
private <T extends ResourceComponent> boolean executeResourceUpgradeFacetAndStoreRequest(
ResourceContainer resourceContainer) throws PluginContainerException {
- @SuppressWarnings("unchecked")
ResourceComponent<T> parentResourceComponent = resourceContainer.getResourceContext()
.getParentResourceComponent();
@@ -107,7 +113,6 @@ public class ResourceUpgradeDelegate {
Resource resource = resourceContainer.getResource();
- @SuppressWarnings("unchecked")
ResourceDiscoveryComponent<ResourceComponent<T>> discoveryComponent = PluginContainer.getInstance()
.getPluginComponentFactory().getDiscoveryComponent(resource.getResourceType(), parentResourceContainer);
@@ -146,13 +151,13 @@ public class ResourceUpgradeDelegate {
}
private String checkUpgradeValid(Resource resource, ResourceUpgradeReport upgradeReport) {
- StringBuilder bld = new StringBuilder();
+ StringBuilder s = new StringBuilder();
if (!checkResourceKeyUniqueAmongSiblings(resource, upgradeReport)) {
- bld.append("\nAnother inventoried sibling resource of the same type already has the proposed resource key.");
+ s.append("\nAnother inventoried sibling resource of the same type already has the proposed resource key.");
}
- return bld.length() > 0 ? bld.toString() : null;
+ return s.length() > 0 ? s.toString() : null;
}
private boolean checkResourceKeyUniqueAmongSiblings(Resource resource, ResourceUpgradeReport upgradeReport) {
commit fb7c05447b2b4d0f3ebf30481942f12d176f759e
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Jul 6 16:02:39 2010 -0400
trivial - remove tabs
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
index d122da4..915a9e7 100644
--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
@@ -35,12 +35,11 @@ import org.rhq.core.pluginapi.inventory.ResourceComponent;
* @author Lukas Krejci
*/
public interface ResourceUpgradeFacet<T extends ResourceComponent> {
-
- /**
- * Specifies what data should change on the provided resource to upgrade it to the current version.
- *
- * @param inventoriedResource a context representing the resource to be upgraded
- * @return a report specifying what aspects of the resource should be changed or null if there is nothing to upgrade
- */
- ResourceUpgradeReport upgrade(ResourceUpgradeContext<T> inventoriedResource);
+ /**
+ * Specifies what data should change on the provided resource to upgrade it to the current version.
+ *
+ * @param inventoriedResource a context representing the resource to be upgraded
+ * @return a report specifying what aspects of the resource should be changed or null if there is nothing to upgrade
+ */
+ ResourceUpgradeReport upgrade(ResourceUpgradeContext<T> inventoriedResource);
}
commit 18316510cafe27425cd1ac3cc1d08afe398d77ab
Merge: 14db66f... fac71cd...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Jul 2 17:54:08 2010 +0200
Merge branch 'release-3.0.0' into resource-upgrade
commit 14db66fe1f2774bcead24daebee947e6b52851dd
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Jul 2 17:52:12 2010 +0200
Refactoring the resource upgrade to upgrade before the discovery during InventoryManager.initialize(). That enables us to remove all the synchronization on the resources.
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
index 825a616..f055e8c 100644
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
@@ -32,6 +32,8 @@ import org.rhq.core.domain.resource.ResourceUpgradeReport;
*/
public class ResourceUpgradeRequest extends ResourceUpgradeReport {
+ private static final long serialVersionUID = 1L;
+
private int resourceId;
public ResourceUpgradeRequest() {
@@ -52,4 +54,24 @@ public class ResourceUpgradeRequest extends ResourceUpgradeReport {
public void setResourceId(int resourceId) {
this.resourceId = resourceId;
}
+
+ @Override
+ public int hashCode() {
+ return 31 * resourceId;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ if (!(other instanceof ResourceUpgradeRequest)) {
+ return false;
+ }
+
+ ResourceUpgradeRequest r = (ResourceUpgradeRequest) other;
+
+ return r.getResourceId() == resourceId;
+ }
}
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
index 0f9db04..c2bc392 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
@@ -108,4 +108,14 @@ public class ResourceUpgradeReport implements Serializable {
public void setNewDescription(String newDescription) {
this.newDescription = newDescription;
}
+
+ public boolean hasSomethingToUpgrade() {
+ return newResourceKey != null ||
+ newName != null ||
+ newDescription != null;
+ }
+
+ public String toString() {
+ return "ResourceUpgradeReport[newResourceKey = '" + newResourceKey + "', newName = '" + newName + "', newDescription = '" + newDescription + "']";
+ }
}
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
index 914641c..d122da4 100644
--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
@@ -23,9 +23,6 @@
package org.rhq.core.pluginapi.upgrade;
-import java.util.Map;
-import java.util.Set;
-
import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.pluginapi.inventory.ResourceComponent;
@@ -39,19 +36,11 @@ import org.rhq.core.pluginapi.inventory.ResourceComponent;
*/
public interface ResourceUpgradeFacet<T extends ResourceComponent> {
- /**
- * This method is called on the discovery component straight after it has finished the discovery.
- * The exact same discovery results are passed to this method along with the set of resources
- * that already exist in the inventory.
- *
- * @param inventoriedSiblings the existing resources
- * @param parentContext the parent of both the newly discovered and existing resources
- * @param discoveryResults the discovered resources. The resources from this set that have
- * the same resource key as one of the inventoried siblings (after upgrade using the results of this method) won't
- * be reported.
- * @return the mapping of old resources to the newly desired data. The keys are instances from the
- * inventoriedSiblings set, the values are the upgrade reports detailing what the data of the
- * corresponding siblings should be upgraded to.
- */
- Map<ResourceUpgradeContext<T>, ResourceUpgradeReport> upgrade(Set<ResourceUpgradeContext<T>> inventoriedSiblings, ResourceUpgradeContext<? extends ResourceComponent> parentContext, Set<ResourceUpgradeContext<T>> discoveryResults);
+ /**
+ * Specifies what data should change on the provided resource to upgrade it to the current version.
+ *
+ * @param inventoriedResource a context representing the resource to be upgraded
+ * @return a report specifying what aspects of the resource should be changed or null if there is nothing to upgrade
+ */
+ ResourceUpgradeReport upgrade(ResourceUpgradeContext<T> inventoriedResource);
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java
index 4d61e93..7561bf7 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java
@@ -261,10 +261,6 @@ public class PluginContainer implements ContainerService {
} finally {
releaseLock(lock);
}
-
- //fire off the resource upgrade as soon as possible. It will run only once per plugin container
- //lifetime.
- inventoryManager.fireResourceUpgrade();
return;
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index ee42f7d..5786702 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -33,11 +33,9 @@ import java.util.IdentityHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
-import java.util.Queue;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
-import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@@ -93,8 +91,7 @@ import org.rhq.core.pc.plugin.BlacklistedException;
import org.rhq.core.pc.plugin.CanonicalResourceKey;
import org.rhq.core.pc.plugin.PluginComponentFactory;
import org.rhq.core.pc.plugin.PluginManager;
-import org.rhq.core.pc.upgrade.ResourceUpgradeExecutor;
-import org.rhq.core.pc.upgrade.ResourceUpgradePendingRequest;
+import org.rhq.core.pc.upgrade.ResourceUpgradeDelegate;
import org.rhq.core.pc.util.DiscoveryComponentProxyFactory;
import org.rhq.core.pc.util.FacetLockType;
import org.rhq.core.pc.util.LoggingThreadFactory;
@@ -195,7 +192,7 @@ public class InventoryManager extends AgentService implements ContainerService,
/**
* Handles the resource upgrade during the initialization of the inventory manager.
*/
- private ResourceUpgradeExecutor resourceUpgradeExecutor;
+ private ResourceUpgradeDelegate resourceUpgradeDelegate;
public InventoryManager() {
super(DiscoveryAgentService.class);
@@ -219,12 +216,18 @@ public class InventoryManager extends AgentService implements ContainerService,
loadFromDisk();
}
- availabilityCollectors = new AvailabilityCollectorThreadPool();
- availabilityCollectors.initialize();
-
// Discover the platform first thing.
executePlatformScan();
+ //try the resource upgrade before we have any schedulers set up
+ //so that we don't get any interventions from concurrently running
+ //discoveries.
+ resourceUpgradeDelegate = new ResourceUpgradeDelegate(this);
+ upgradeResources();
+
+ availabilityCollectors = new AvailabilityCollectorThreadPool();
+ availabilityCollectors.initialize();
+
// Never run more than one avail check at a time.
availabilityThreadPoolExecutor = new ScheduledThreadPoolExecutor(AVAIL_THREAD_POOL_CORE_POOL_SIZE,
new LoggingThreadFactory(AVAIL_THREAD_POOL_NAME, true));
@@ -251,8 +254,6 @@ public class InventoryManager extends AgentService implements ContainerService,
inventoryThreadPoolExecutor.scheduleWithFixedDelay(serviceScanExecutor, configuration
.getServiceDiscoveryInitialDelay(), configuration.getServiceDiscoveryPeriod(), TimeUnit.SECONDS);
}
-
- resourceUpgradeExecutor = new ResourceUpgradeExecutor(this);
} finally {
inventoryLock.writeLock().unlock();
}
@@ -378,20 +379,19 @@ public class InventoryManager extends AgentService implements ContainerService,
return results;
}
- public <T extends ResourceComponent> Map<ResourceUpgradeContext<T>, ResourceUpgradeReport> invokeDiscoveryComponentResourceUpgradeFacet(
+ public <T extends ResourceComponent> ResourceUpgradeReport invokeDiscoveryComponentResourceUpgradeFacet(
ResourceType resourceType, ResourceDiscoveryComponent<T> component,
- Set<ResourceUpgradeContext<T>> inventoriedSiblings, ResourceUpgradeContext<?> parent,
- Set<ResourceUpgradeContext<T>> discoveredResources) throws Throwable {
+ ResourceUpgradeContext<T> inventoriedResource) throws Throwable {
long timeout = getDiscoveryComponentTimeout(resourceType);
try {
@SuppressWarnings("unchecked")
ResourceUpgradeFacet<T> proxy = this.discoveryComponentProxyFactory.getDiscoveryComponentProxy(resourceType, component, timeout, ResourceUpgradeFacet.class);
- return proxy.upgrade(inventoriedSiblings, parent, discoveredResources);
+ return proxy.upgrade(inventoriedResource);
} catch (BlacklistedException e) {
log.debug(e);
- return Collections.emptyMap();
+ return null;
}
}
@@ -518,15 +518,6 @@ public class InventoryManager extends AgentService implements ContainerService,
}
}
- /**
- * Executes the resource upgrade asynchronously.
- */
- public void fireResourceUpgrade() {
- Thread resourceUpgradeThread = new Thread(resourceUpgradeExecutor, "Resource Upgrade Thread");
- resourceUpgradeThread.setDaemon(true);
- resourceUpgradeThread.start();
- }
-
public InventoryReport executeServerScanImmediately() {
try {
return inventoryThreadPoolExecutor.submit((Callable<InventoryReport>) this.serverScanExecutor).get();
@@ -914,16 +905,6 @@ public class InventoryManager extends AgentService implements ContainerService,
return true;
}
- //finish the resource upgrade.
- //by now all the resource upgrade requests have been processed
- //by the executor, which means that the inventory report
- //we got already only contains the "correct" new resources and
- //that the executor has all the upgrade requests queued up
- //to be sent to the server in a batch.
- if (resourceUpgradeExecutor.isEnabled()) {
- resourceUpgradeExecutor.sendRequests();
- }
-
if (report.getAddedRoots().isEmpty() && !forceServerRoundtrip) {
return true; // nothing to do
}
@@ -1005,7 +986,12 @@ public class InventoryManager extends AgentService implements ContainerService,
// so run an avail check to report on their availabilities immediately. Also kick off
// a service scan to scan those Resources for new child Resources. Kick both tasks off
// asynchronously.
- if (!syncedResources.isEmpty() || !unknownResourceIds.isEmpty() || !modifiedResourceIds.isEmpty()) {
+ // Do this only if we are finished with resource upgrade because no availability checks
+ // or discoveries can happen during upgrade. This is to ensure maximum consistency of the
+ // inventory with the server side as well as to disallow any other server-agent traffic during
+ // the upgrade phase. Not to mention the fact that no thread pools are initialized yet by the
+ // time the upgrade kicks in..
+ if (!resourceUpgradeDelegate.enabled() && (!syncedResources.isEmpty() || !unknownResourceIds.isEmpty() || !modifiedResourceIds.isEmpty())) {
performAvailabilityChecks(true);
this.inventoryThreadPoolExecutor.schedule((Callable<? extends Object>) this.serviceScanExecutor, 5,
TimeUnit.SECONDS);
@@ -2180,10 +2166,6 @@ public class InventoryManager extends AgentService implements ContainerService,
newResources.add(newResource);
}
}
-
- if (resourceUpgradeExecutor.isEnabled()) {
- resourceUpgradeExecutor.processAndQueue(new ResourceUpgradePendingRequest(newResources, context, parentResource.getId()), newResources);
- }
} catch (Throwable e) {
// TODO GH: Add server/parent - up/down semantics so this won't happen just because a server is not up
long elapsedTime = System.currentTimeMillis() - startTime;
@@ -2594,6 +2576,63 @@ public class InventoryManager extends AgentService implements ContainerService,
container.setSynchronizationState(ResourceContainer.SynchronizationState.SYNCHRONIZED);
}
+ private void upgradeResources() {
+ try {
+ if (log.isDebugEnabled()) {
+ log.debug("Executing resource upgrade.");
+ }
+
+ boolean syncResult = handleReport(new InventoryReport(getAgent()), true);
+ if (!syncResult) {
+ log.warn("Resource upgrade failed to sync up the inventory with the server.");
+ return;
+ }
+
+ upgradeResource(getPlatform());
+
+ if (log.isDebugEnabled()) {
+ log.debug("Sending the upgrade requests to the server.");
+ }
+ resourceUpgradeDelegate.sendRequests();
+
+ resourceUpgradeDelegate.disable();
+
+ if (log.isDebugEnabled()) {
+ log.debug("Resource upgrade finished.");
+ }
+ } catch (Throwable t) {
+ log.error("Resource upgrade failed with an exception.", t);
+ }
+ }
+
+ private void upgradeResource(Resource resource) {
+ //only process committed resources
+ if (resource.getInventoryStatus() != InventoryStatus.COMMITTED) {
+ return;
+ }
+
+ ResourceContainer container = getResourceContainer(resource);
+ if (container != null) {
+ try {
+ container = getResourceContainer(resource);
+ resourceUpgradeDelegate.processAndQueue(container);
+ } catch (PluginContainerException e) {
+ log.error("Exception thrown while upgrading [" + resource + "].");
+ }
+
+ if (container.getResourceComponentState() == ResourceComponentState.STARTED) {
+ for (Resource child : resource.getChildResources()) {
+ upgradeResource(child);
+ }
+ } else {
+ log.error("The resource container for resource [" + resource + "] wasn't started during upgrade. This should not happen.");
+ }
+ } else {
+ log.error("Resource container not initialized for resource [" + resource
+ + "] during upgrade. This should not happen.");
+ }
+ }
+
/**
* That class implements a listener that gets called when the resource got activated
* @author hrupp
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
new file mode 100644
index 0000000..cb466bd
--- /dev/null
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
@@ -0,0 +1,180 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.core.pc.upgrade;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.rhq.core.clientapi.agent.PluginContainerException;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
+import org.rhq.core.pc.PluginContainer;
+import org.rhq.core.pc.inventory.InventoryManager;
+import org.rhq.core.pc.inventory.ResourceContainer;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
+
+/**
+ * This is a helper class to {@link InventoryManager} that takes care of resource upgrade.
+ * Note that this class is not thread-safe in any manner.
+ *
+ * @author Lukas Krejci
+ */
+public class ResourceUpgradeDelegate {
+
+ private static final Log log = LogFactory.getLog(ResourceUpgradeDelegate.class);
+
+ private boolean enabled = true;
+
+ private Set<ResourceUpgradeRequest> requests = new HashSet<ResourceUpgradeRequest>();
+ private InventoryManager inventoryManager;
+
+ public ResourceUpgradeDelegate(InventoryManager inventoryManager) {
+ this.inventoryManager = inventoryManager;
+ }
+
+ /**
+ * Is the delegate enabled? In another words has the resource upgrade phase finished in the {@link IventoryManager#initialize()}
+ * method?
+ */
+ public boolean enabled() {
+ return enabled;
+ }
+
+ /**
+ * Disables all future operations of the delegate.
+ */
+ public void disable() {
+ enabled = false;
+ }
+
+ /**
+ * Asks the resource's discovery component to upgrade the resource.
+ * @param resourceContainer
+ * @return true if the resource was queued for upgrade, false otherwise
+ * @throws PluginContainerException on error
+ */
+ public boolean processAndQueue(ResourceContainer resourceContainer) throws PluginContainerException {
+ if (enabled) {
+ return executeResourceUpgradeFacetAndStoreRequest(resourceContainer);
+ }
+
+ return false;
+ }
+
+ public void sendRequests() {
+ if (enabled) {
+ if (requests.size() > 0) {
+ inventoryManager.mergeResourceFromUpgrade(requests);
+ requests.clear();
+ }
+ }
+ }
+
+ private <T extends ResourceComponent> boolean executeResourceUpgradeFacetAndStoreRequest(
+ ResourceContainer resourceContainer) throws PluginContainerException {
+
+ @SuppressWarnings("unchecked")
+ ResourceComponent<T> parentResourceComponent = resourceContainer.getResourceContext()
+ .getParentResourceComponent();
+
+ Resource parentResource = resourceContainer.getResource().getParentResource();
+
+ ResourceContainer parentResourceContainer = (parentResource != null) ? inventoryManager
+ .getResourceContainer(resourceContainer.getResource().getParentResource()) : null;
+
+ Resource resource = resourceContainer.getResource();
+
+ @SuppressWarnings("unchecked")
+ ResourceDiscoveryComponent<ResourceComponent<T>> discoveryComponent = PluginContainer.getInstance()
+ .getPluginComponentFactory().getDiscoveryComponent(resource.getResourceType(), parentResourceContainer);
+
+ if (!(discoveryComponent instanceof ResourceUpgradeFacet)) {
+ //well, there's no point in continuing if the resource doesn't support the facet
+ return false;
+ }
+
+ ResourceUpgradeContext<ResourceComponent<T>> upgradeContext = inventoryManager.createResourceUpgradeContext(
+ resource, parentResourceComponent, discoveryComponent);
+
+ ResourceUpgradeReport upgradeReport;
+ try {
+ upgradeReport = inventoryManager.invokeDiscoveryComponentResourceUpgradeFacet(resource.getResourceType(),
+ discoveryComponent, upgradeContext);
+ } catch (Throwable t) {
+ log.error("ResourceUpgradeFacet threw an exception while upgrading resource [" + resource + "]", t);
+ return false;
+ }
+
+ if (upgradeReport == null || !upgradeReport.hasSomethingToUpgrade()) {
+ return false;
+ }
+
+ String upgradeErrors = null;
+ if ((upgradeErrors = checkUpgradeValid(resource, upgradeReport)) != null) {
+ log.error("Upgrading the resource [" + resource + "] using these updates [" + upgradeReport
+ + "] would render the inventory invalid because of the following reasons: " + upgradeErrors);
+ return false;
+ }
+
+ //everything went ok, let's queue a upgrade request that will be sent to the server
+ requests.add(new ResourceUpgradeRequest(resource.getId(), upgradeReport));
+
+ return true;
+ }
+
+ private String checkUpgradeValid(Resource resource, ResourceUpgradeReport upgradeReport) {
+ StringBuilder bld = new StringBuilder();
+
+ if (!checkResourceKeyUniqueAmongSiblings(resource, upgradeReport)) {
+ bld.append("\nAnother inventoried sibling resource of the same type already has the proposed resource key.");
+ }
+
+ return bld.length() > 0 ? bld.toString() : null;
+ }
+
+ private boolean checkResourceKeyUniqueAmongSiblings(Resource resource, ResourceUpgradeReport upgradeReport) {
+ Resource parent = resource.getParentResource();
+ if (parent == null) {
+ return true;
+ }
+
+ for (Resource sibling : parent.getChildResources()) {
+ //we'd have a resource key conflict if there was a resource
+ //of the same type under the same parent that would have the same
+ //resource key.
+ if (upgradeReport.getNewResourceKey() != null
+ && sibling.getResourceType().equals(resource.getResourceType())
+ && !sibling.getUuid().equals(resource.getUuid())) {
+
+ if (sibling.getResourceKey().equals(upgradeReport.getNewResourceKey())) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
deleted file mode 100644
index f344900..0000000
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2010 Red Hat, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation, and/or the GNU Lesser
- * General Public License, version 2.1, also as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License and the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * and the GNU Lesser General Public License along with this program;
- * if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-package org.rhq.core.pc.upgrade;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.rhq.core.clientapi.agent.PluginContainerException;
-import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
-import org.rhq.core.clientapi.server.discovery.InventoryReport;
-import org.rhq.core.domain.resource.InventoryStatus;
-import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.resource.ResourceType;
-import org.rhq.core.domain.resource.ResourceUpgradeReport;
-import org.rhq.core.pc.PluginContainer;
-import org.rhq.core.pc.inventory.InventoryManager;
-import org.rhq.core.pc.inventory.ResourceContainer;
-import org.rhq.core.pluginapi.inventory.ResourceComponent;
-import org.rhq.core.pluginapi.inventory.ResourceContext;
-import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
-import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
-import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
-import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
-
-/**
- * This class is responsible for performing the resource upgrade on behalf on of {@link InventoryManager}.
- * Despite its name, it is not an {@link java.util.concurrent.Executor} implementation.
- *
- * @author Lukas Krejci
- */
-public class ResourceUpgradeExecutor implements Runnable {
- private static final Log log = LogFactory.getLog(ResourceUpgradeExecutor.class);
-
- /**
- * The upgrade runs only once in its lifetime.
- */
- private AtomicBoolean enabled = new AtomicBoolean(true);
- private AtomicBoolean started = new AtomicBoolean(false);
-
- private InventoryManager inventoryManager;
-
- private ConcurrentLinkedQueue<ResourceUpgradeRequest> requests;
-
- public ResourceUpgradeExecutor(InventoryManager inventoryManager) {
- this.inventoryManager = inventoryManager;
- requests = new ConcurrentLinkedQueue<ResourceUpgradeRequest>();
- }
-
- /**
- * This method is called from within the {@link InventoryManager} during the
- * discovery process as individual upgrade requests are generated.
- * <p>
- * This method calls the appropriate discovery component to perform the upgrade and
- * at the same time stores off the results so that they can be sent to the server
- * at the end of the discovery in one big batch.
- * <p>
- * The provided set of discovery results is updated if this method detects that an existing
- * resource upgrade would result in a resource key collision with some of the newly discovered
- * resources.
- *
- * @param request the upgrade request
- * @param discoveredResources the set of discovered resources that this method can optionally remove some elements from.
- */
- public <T extends ResourceComponent> Map<ResourceUpgradeContext<T>, ResourceUpgradeReport> processAndQueue(
- ResourceUpgradePendingRequest<T> request, Set<Resource> discoveredResources) {
-
- return enabled.get() ? executeResourceUpgradeAndStoreRequest(request, discoveredResources) : null;
- }
-
- /**
- * @return true if the executor is ready to perform the upgrade, false otherwise.
- */
- public boolean isEnabled() {
- return enabled.get();
- }
-
- /**
- * This method is called from within the {@link InventoryManager} once it's collected
- * all the upgrade requests.
- */
- public void sendRequests() {
- if (enabled.get() && requests.size() > 0) {
- HashSet<ResourceUpgradeRequest> currentCopy = new HashSet<ResourceUpgradeRequest>(requests);
- inventoryManager.mergeResourceFromUpgrade(currentCopy);
- requests.removeAll(currentCopy);
- }
- }
-
- /**
- * Performs the resource upgrade. First, a full inventory report is pulled down from the
- * server to ensure we have an up-to-date picture of the inventory.
- * After that a full discovery is performed and both the upgrade report and discovery report
- * are sent to the server.
- */
- public void run() {
- if (!started.getAndSet(true)) {
- if (log.isDebugEnabled()) {
- log.debug("Starting resource upgrade.");
- }
-
- try {
- //pull the inventory down from the server.
- //this will ensure that we have an up-to-date info on the
- //server inventory before we try to upgrade.
- boolean syncResult = inventoryManager.handleReport(new InventoryReport(inventoryManager.getAgent()), true);
- if (!syncResult) {
- log.warn("Resource upgrade failed to sync up the inventory with the server.");
- return;
- }
-
- //fire off the full discovery
- inventoryManager.executeServerScanImmediately();
- inventoryManager.executeServiceScanImmediately();
- } catch (Throwable t) {
- log.warn("Resource upgrade failed.", t);
- } finally {
- //make sure to switch off the upgrade...
- this.enabled.set(false);
-
- //clear up so that we don't hold unnecessary instances.
- requests.clear();
-
- if (log.isDebugEnabled()) {
- log.debug("Resource upgrade finished.");
- }
- }
-
- } else {
- if (log.isDebugEnabled()) {
- log.debug("ResourceUpgradeExecutor already ran before. Skipping the execution.");
- }
- }
- }
-
- /**
- * Executes the resource upgrade request on the agent (if the appropriate discovery component support {@link ResourceUpgradeFacet}).
- *
- * @param request the upgrade request to execute on the agent.
- * @param discoveredResources the set of the discovered resources that this method can remove some elements from
- * @return the resulting upgrade map as reported by the plugin from {@link ResourceUpgradeFacet#upgrade(Set, ResourceUpgradeContext, Set)} method.
- *
- * @throws PluginContainerException
- */
- private <T extends ResourceComponent> Map<ResourceUpgradeContext<T>, ResourceUpgradeReport> executeResourceUpgradeAndStoreRequest(
- ResourceUpgradePendingRequest<T> request, Set<Resource> discoveredResources) {
-
- ResourceDiscoveryContext<T> discoveryContext = request.getDiscoveryContext();
- Set<Resource> newResources = request.getDiscoveredResources();
- Integer parentResourceId = request.getParentResourceId();
-
- try {
- ResourceType resourceType = discoveryContext.getResourceType();
- ResourceContainer parentResourceContainer = null;
- Resource parentResource = null;
- if (parentResourceId != null) {
- parentResourceContainer = inventoryManager.getResourceContainer(parentResourceId);
- if (parentResourceContainer != null) {
- parentResource = parentResourceContainer.getResource();
- }
- }
-
- @SuppressWarnings("unchecked")
- ResourceDiscoveryComponent<T> discoveryComponent = PluginContainer.getInstance()
- .getPluginComponentFactory().getDiscoveryComponent(resourceType, parentResourceContainer);
-
- ResourceContext<?> parentResourceContext = discoveryContext.getParentResourceContext();
-
- T parentComponent = discoveryContext.getParentResourceComponent();
-
- //check if the discovery component supports resource upgrade
- //if it does, perform the resource upgrade straight away here during the discovery process.
- if (discoveryComponent instanceof ResourceUpgradeFacet) {
- //the siblings are the resources of the type that is currently being discovered that are already
- //present in the inventory. These are the candidate resources for the upgrade.
- Set<Resource> siblings = parentResource == null ? Collections.singleton(inventoryManager.getPlatform())
- : inventoryManager.getResourcesWithType(resourceType, parentResource.getChildResources());
-
- //filter out not committed resources
- //XXX what about uninventoried or ignored ones? is it correct to not upgrade those?
- Iterator<Resource> siblingsIterator = siblings.iterator();
- while (siblingsIterator.hasNext()) {
- if (siblingsIterator.next().getInventoryStatus() != InventoryStatus.COMMITTED) {
- siblingsIterator.remove();
- }
- }
-
- //get the upgrade context of the parent resource so that it can be passed to the upgrade method
- //of the discovery component.
- ResourceUpgradeContext<?> parentUpgradeContext = null;
-
- if (parentResource != null) {
- Resource grandParent = parentResource.getParentResource();
- ResourceContainer grandParentContainer = grandParent == null ? null : inventoryManager
- .getResourceContainer(grandParent);
-
- @SuppressWarnings("unchecked")
- ResourceDiscoveryComponent<ResourceComponent> parentDiscoveryComponent = PluginContainer
- .getInstance().getPluginComponentFactory().getDiscoveryComponent(
- parentResource.getResourceType(), grandParentContainer);
-
- ResourceComponent<?> grandParentResourceComponent = grandParentContainer == null ? null
- : grandParentContainer.getResourceComponent();
-
- parentUpgradeContext = inventoryManager.createResourceUpgradeContext(parentResource,
- grandParentResourceComponent, parentDiscoveryComponent);
- }
-
- //convert the sibling resources into upgrade context objects so that the plugin methods don't access the
- //domain objects directly.
- Set<ResourceUpgradeContext<T>> siblingContexts = new HashSet<ResourceUpgradeContext<T>>(siblings.size());
-
- //but we are going to need to update the resources in the end, so map the contexts with the resources.
- Map<ResourceUpgradeContext<T>, Resource> siblingContextToResource = new HashMap<ResourceUpgradeContext<T>, Resource>();
-
- for (Resource sibling : siblings) {
- ResourceUpgradeContext<T> siblingContext = inventoryManager.createResourceUpgradeContext(sibling,
- parentComponent, discoveryComponent);
- siblingContexts.add(siblingContext);
- siblingContextToResource.put(siblingContext, sibling);
- }
-
- //convert the new resources into contexts.
- //map the resources by resource key so that we can later check for uniqueness of the reported results.
- Set<ResourceUpgradeContext<T>> newResourceContexts = new HashSet<ResourceUpgradeContext<T>>();
- Map<String, Resource> newResourceKeyToResource = new HashMap<String, Resource>();
-
- for (Resource newResource : newResources) {
- ResourceUpgradeContext<T> newUpgradeContext = inventoryManager.createResourceUpgradeContext(
- newResource, parentComponent, discoveryComponent);
- newResourceContexts.add(newUpgradeContext);
- newResourceKeyToResource.put(newResource.getResourceKey(), newResource);
- }
-
- //ask the discovery component to upgrade the siblings.
- Map<ResourceUpgradeContext<T>, ResourceUpgradeReport> results;
- try {
- results = inventoryManager.invokeDiscoveryComponentResourceUpgradeFacet(resourceType,
- discoveryComponent, siblingContexts, parentUpgradeContext, newResourceContexts);
-
- //now go through the results and create the upgrade requests.
- for (Map.Entry<ResourceUpgradeContext<T>, ResourceUpgradeReport> upgradeEntry : results.entrySet()) {
- Resource siblingToUpgrade = siblingContextToResource.get(upgradeEntry.getKey());
- ResourceUpgradeRequest newData = new ResourceUpgradeRequest(siblingToUpgrade.getId(), upgradeEntry.getValue());
-
- requests.add(newData);
-
- //if there was a resource key upgrade, remove a resource with the same resource key
- //from the discovery results. Otherwise we'd end up with 2 sibling resources with
- //the same resource key, which is illegal.
- if (newData.getNewResourceKey() != null) {
- Resource newResourceToRemove = newResourceKeyToResource.get(newData.getNewResourceKey());
- if (newResourceToRemove != null) {
- discoveredResources.remove(newResourceToRemove);
- }
- }
- }
-
- return results;
- } catch (Throwable t) {
- log.warn("Exception in discovery component " + discoveryComponent.getClass() + " upgrade method.",
- t);
- }
- }
- } catch (PluginContainerException e) {
- log.warn("Failed resource upgrade of children of resource id " + parentResourceId, e);
- }
- return null;
- }
-}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradePendingRequest.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradePendingRequest.java
deleted file mode 100644
index 1099643..0000000
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradePendingRequest.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.rhq.core.pc.upgrade;
-
-import java.util.Set;
-
-import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.pluginapi.inventory.ResourceComponent;
-import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
-
-/**
- * This class is used to store the requests for resource upgrade that originate in
- * the discovery workflow, but can only be executed after an inventory sync.
- */
-public class ResourceUpgradePendingRequest<T extends ResourceComponent> {
- private Set<Resource> discoveredResources;
- private ResourceDiscoveryContext<T> discoveryContext;
- private Integer parentResourceId;
-
- public ResourceUpgradePendingRequest(Set<Resource> discoveredResources, ResourceDiscoveryContext<T> discoveryContext, Integer parentResourceId) {
- this.discoveredResources = discoveredResources;
- this.discoveryContext = discoveryContext;
- this.parentResourceId = parentResourceId;
- }
-
- public Set<Resource> getDiscoveredResources() {
- return discoveredResources;
- }
-
- public ResourceDiscoveryContext<T> getDiscoveryContext() {
- return discoveryContext;
- }
-
- public Integer getParentResourceId() {
- return parentResourceId;
- }
-}
\ No newline at end of file
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 087b46f..b5d571f 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -151,34 +151,8 @@ public class ResourceUpgradeTest {
}
@Test
- public void testResourceUpgradeRunsOnlyOnce() throws Exception {
- currentServerSideInventory = new FakeServerInventory();
- initialSyncAndDiscovery(InventoryStatus.COMMITTED);
-
- executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, new TestPayload() {
- public void test(Resource discoveredResource) {
- for(int i = 0; i < 100; i++) {
- PluginContainer.getInstance().getInventoryManager().fireResourceUpgrade();
- }
- }
-
- @SuppressWarnings("unchecked")
- public Expectations getExpectations(Mockery context) throws Exception {
- return new Expectations() {
- {
- defineDefaultExpectations(this);
-
- between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
- will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
-
- //even though we fire the resource upgrade 100 times above,
- //only 1 upgrade should actually occur and go up to the server.
- oneOf(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
- will(currentServerSideInventory.upgradeResources());
- }
- };
- }
- });
+ public void testRecoveryWithServerUnavailable() throws Exception {
+ //TODO implement
}
private void initialSyncAndDiscovery(final InventoryStatus requiredInventoryStatus) throws Exception {
diff --git a/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar
index 412ae00..7ffc5bb 100644
Binary files a/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar and b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar differ
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index 329f476..add8168 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -20,7 +20,6 @@ package org.rhq.enterprise.server.discovery;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
index 7fe7a5e..de265eb 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
@@ -1715,8 +1715,16 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
Query query = entityManager.createNamedQuery(Resource.QUERY_FIND_PLATFORM_BY_AGENT);
query.setParameter("category", ResourceCategory.PLATFORM);
query.setParameter("agent", agent);
- Resource platform = (Resource) query.getSingleResult();
- return platform;
+
+ try {
+ Resource platform = (Resource) query.getSingleResult();
+ return platform;
+ } catch (NoResultException e) {
+ //this means that the agent didn't send any info to us yet.
+ //this can happen during the inital resource upgrade sync between
+ //the agent and server.
+ return null;
+ }
}
@SuppressWarnings("unchecked")
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
index 327c439..faf0b11 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
@@ -376,7 +376,7 @@ public interface ResourceManagerLocal {
*
* @param agent an Agent
*
- * @return the platform Resource associated with the specified Agent
+ * @return the platform Resource associated with the specified Agent or null if the platform for the agent is not known yet.
*/
Resource getPlatform(Agent agent);
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
index 362a1df..c31d153 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
@@ -170,45 +170,40 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
return discoveredResources;
}
- public Map<ResourceUpgradeContext<PlatformComponent>, ResourceUpgradeReport> upgrade(Set<ResourceUpgradeContext<PlatformComponent>> inventoriedSiblings,
- ResourceUpgradeContext<?> parentContext, Set<ResourceUpgradeContext<PlatformComponent>> discoveryResults) {
-
- Map<ResourceUpgradeContext<PlatformComponent>, ResourceUpgradeReport> ret = new HashMap<ResourceUpgradeContext<PlatformComponent>, ResourceUpgradeReport>();
-
- for (ResourceUpgradeContext context : inventoriedSiblings) {
- String inventoriedResourceKey = context.getResourceKey();
- File inventoriedResourceKeyAsPath = new File(inventoriedResourceKey);
-
- //the resource key we use now is a full path to the httpdconf.
- //in the old version, it was the server root.
- //so if the inventoried resource key is a path to a file,
- //we know it's a new style resource key.
- if (inventoriedResourceKeyAsPath.isFile()) {
- continue;
- }
-
- Configuration pluginConfiguration = context.getPluginConfiguration();
-
- String serverRoot = pluginConfiguration.getSimpleValue("serverRoot", null);
- String httpdConf = pluginConfiguration.getSimpleValue("configFile", null);
-
- String resourceKey = null;
-
- if (httpdConf != null) {
- File httpdConfFile = new File(httpdConf);
- if (!httpdConfFile.isAbsolute()) {
- httpdConfFile = new File(serverRoot, httpdConf);
- }
-
- resourceKey = httpdConfFile.getPath();
-
- ResourceUpgradeReport rep = new ResourceUpgradeReport();
- rep.setNewResourceKey(resourceKey);
-
- ret.put(context, rep);
+ public ResourceUpgradeReport upgrade(ResourceUpgradeContext<PlatformComponent> context) {
+ String inventoriedResourceKey = context.getResourceKey();
+ File inventoriedResourceKeyAsPath = new File(inventoriedResourceKey);
+
+ //the resource key we use now is a full path to the httpd.conf.
+ //in the old version, it was the server root.
+ //so if the inventoried resource key is a path to a file,
+ //we know it's a new style resource key.
+ if (inventoriedResourceKeyAsPath.isFile()) {
+ return null;
+ }
+
+ Configuration pluginConfiguration = context.getPluginConfiguration();
+
+ String serverRoot = pluginConfiguration.getSimpleValue("serverRoot", null);
+ String httpdConf = pluginConfiguration.getSimpleValue("configFile", null);
+
+ String resourceKey = null;
+
+ if (httpdConf != null) {
+ File httpdConfFile = new File(httpdConf);
+ if (!httpdConfFile.isAbsolute()) {
+ httpdConfFile = new File(serverRoot, httpdConf);
}
+
+ resourceKey = httpdConfFile.getPath();
+
+ ResourceUpgradeReport rep = new ResourceUpgradeReport();
+ rep.setNewResourceKey(resourceKey);
+
+ return rep;
}
- return ret;
+
+ return null;
}
public DiscoveredResourceDetails discoverResource(Configuration pluginConfig,
commit 00b2aae2f27dd64092eee3c2d09df33e48736e10
Merge: 90ca72b... ed06919...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Jul 2 14:25:47 2010 +0200
Merge branch 'release-3.0.0' into resource-upgrade
diff --cc modules/core/dbutils/pom.xml
index 2013b3d,d536ce6..96685db
--- a/modules/core/dbutils/pom.xml
+++ b/modules/core/dbutils/pom.xml
@@@ -22,7 -22,7 +22,7 @@@
<properties>
<scm.module.path>modules/core/dbutils/</scm.module.path>
-- <db.schema.version>2.88</db.schema.version>
++ <db.schema.version>2.89</db.schema.version>
</properties>
<dependencies>
diff --cc modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
index 3ee8217,7f8f9da..20e9d2f
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@@ -2994,15 -3000,17 +3000,27 @@@
</statement>
</schema-directSQL>
</schemaSpec>
-
- <schemaSpec version="2.88">
+
+ <schemaSpec version="2.88">
+ <schema-directSQL>
+ <statement desc="Add end time index on call time data to speed up purges">
+ CREATE INDEX RHQ_CT_DA_VA_END_TIM_IDX ON RHQ_CALLTIME_DATA_VALUE (end_time)
+ </statement>
+ <statement desc="Add index on measurement definition numeric type">
+ CREATE INDEX RHQ_METRIC_DEF_NT_IDX ON RHQ_MEASUREMENT_DEF (numeric_type)
+ </statement>
+ </schema-directSQL>
+ </schemaSpec>
++
++ <schemaSpec version="2.89">
+ <schema-directSQL>
+ <statement desc="Adding 'Allow Agent Plugins To Upgrade Generic Resource Properties' system configuration setting">
+ INSERT INTO rhq_system_config (id, property_key, property_value, default_property_value)
+ VALUES (56, 'RESOURCE_GENERIC_PROPERTIES_UPGRADE', 'false', 'false')
+ </statement>
+ </schema-directSQL>
+ </schemaSpec>
++
</dbupgrade>
</target>
</project>
commit 90ca72b3aa73f41165ab2d616f53f12d642bef7d
Merge: 5449040... b9ca90d...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Jun 23 19:01:34 2010 +0200
Merge branch 'release-3.0.0' into resource-upgrade
commit 54490406d19753524b052beeab418af68bf68c2c
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Jun 23 15:41:36 2010 +0200
Restructuring the tests a bit, adding a test for correct reinitialization of the agent inventory from the server inventory during the resource upgrade.
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 46d069c..087b46f 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -49,6 +49,7 @@ import org.rhq.core.clientapi.server.event.EventServerService;
import org.rhq.core.clientapi.server.inventory.ResourceFactoryServerService;
import org.rhq.core.clientapi.server.measurement.MeasurementServerService;
import org.rhq.core.clientapi.server.operation.OperationServerService;
+import org.rhq.core.domain.discovery.AvailabilityReport;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
@@ -64,6 +65,7 @@ import org.rhq.core.pc.plugin.FileSystemPluginFinder;
*
* @author Lukas Krejci
*/
+@Test(sequential = true, invocationCount = 1)
public class ResourceUpgradeTest {
private static final String PLUGIN_V1_FILENAME = "resource-upgrade-test-plugin-1.0.0.jar";
@@ -100,7 +102,7 @@ public class ResourceUpgradeTest {
verifyPluginExists(PLUGIN_V2_FILENAME);
}
- @BeforeClass
+ @BeforeClass(dependsOnMethods = "sanityCheck")
public void init() {
tmpDir = getTmpDirectory();
pluginDir = new File(tmpDir, PLUGINS_DIR_NAME);
@@ -110,12 +112,10 @@ public class ResourceUpgradeTest {
}
@Test
- public void testInitialSyncAndDiscoveryWithoutCommit() throws Exception {
- testInitialSyncAndDiscovery(InventoryStatus.NEW);
- }
-
- @Test(dependsOnMethods = "testInitialSyncAndDiscoveryWithoutCommit")
public void testIgnoreUncommittedResources() throws Exception {
+ currentServerSideInventory = new FakeServerInventory();
+ initialSyncAndDiscovery(InventoryStatus.NEW);
+
TestPayload testNoChange = new TestPayload() {
public void test(Resource discoveredResource) {
assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
@@ -123,17 +123,13 @@ public class ResourceUpgradeTest {
assertEquals(discoveredResource.getDescription(), "resource-description-v1");
}
- @SuppressWarnings("unchecked")
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
- defineIgnoredExpectations(this);
+ defineDefaultExpectations(this);
between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
-
- allowing(currentDiscoveryServerService).getResources(with(any(Set.class)), with(any(boolean.class)));
- will(currentServerSideInventory.getResources());
}
};
}
@@ -142,52 +138,50 @@ public class ResourceUpgradeTest {
executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, testNoChange);
}
- //make the tests run serially, so that they don't overwrite the currentServerSideInventory
- //variable concurrently
- @Test(dependsOnMethods = "testIgnoreUncommittedResources")
- public void testInitialSyncAndDiscoveryWithCommit() throws Exception {
- testInitialSyncAndDiscovery(InventoryStatus.COMMITTED);
- }
-
- @Test(dependsOnMethods = "testInitialSyncAndDiscoveryWithCommit")
+ @Test
public void testUpgradeData() throws Exception {
- //we are keeping the currentServerSideInventory from the previous test
+ currentServerSideInventory = new FakeServerInventory();
+ upgradeTest(false);
+ }
+
+ @Test
+ public void testInventoryReinitializationFromServerDuringUpgrade() throws Exception {
+ currentServerSideInventory = new FakeServerInventory();
+ upgradeTest(true);
+ }
+
+ @Test
+ public void testResourceUpgradeRunsOnlyOnce() throws Exception {
+ currentServerSideInventory = new FakeServerInventory();
+ initialSyncAndDiscovery(InventoryStatus.COMMITTED);
+
executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, new TestPayload() {
public void test(Resource discoveredResource) {
- assertEquals(discoveredResource.getResourceKey(), "resource-key-v2");
- assertEquals(discoveredResource.getName(), "resource-name-v2");
- assertEquals(discoveredResource.getDescription(), "resource-description-v2");
-
- ResourceContainer container = PluginContainer.getInstance().getInventoryManager().getResourceContainer(discoveredResource);
- File dataDir = container.getResourceContext().getDataDirectory();
-
- File marker = new File(dataDir, "upgrade-succeeded");
-
- assertTrue(marker.exists(), "The upgrade success marker file wasn't found. This means the upgrade didn't actually run.");
+ for(int i = 0; i < 100; i++) {
+ PluginContainer.getInstance().getInventoryManager().fireResourceUpgrade();
+ }
}
@SuppressWarnings("unchecked")
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
- defineIgnoredExpectations(this);
+ defineDefaultExpectations(this);
between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+ //even though we fire the resource upgrade 100 times above,
+ //only 1 upgrade should actually occur and go up to the server.
oneOf(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
will(currentServerSideInventory.upgradeResources());
-
- allowing(currentDiscoveryServerService).getResources(with(any(Set.class)), with(any(boolean.class)));
- will(currentServerSideInventory.getResources());
}
};
}
});
}
- private void testInitialSyncAndDiscovery(final InventoryStatus requiredInventoryStatus) throws Exception {
- currentServerSideInventory = new FakeServerInventory();
+ private void initialSyncAndDiscovery(final InventoryStatus requiredInventoryStatus) throws Exception {
executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), true, new TestPayload() {
public void test(Resource discoveredResource) {
assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
@@ -195,17 +189,13 @@ public class ResourceUpgradeTest {
assertEquals(discoveredResource.getDescription(), "resource-description-v1");
}
- @SuppressWarnings("unchecked")
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
- defineIgnoredExpectations(this);
+ defineDefaultExpectations(this);
between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
will(currentServerSideInventory.mergeInventoryReport(requiredInventoryStatus));
-
- allowing(currentDiscoveryServerService).getResources(with(any(Set.class)), with(any(boolean.class)));
- will(currentServerSideInventory.getResources());
}
};
}
@@ -213,6 +203,40 @@ public class ResourceUpgradeTest {
}
+ private void upgradeTest(boolean clearInventoryDat) throws Exception {
+ initialSyncAndDiscovery(InventoryStatus.COMMITTED);
+
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), clearInventoryDat, new TestPayload() {
+ public void test(Resource discoveredResource) {
+ assertEquals(discoveredResource.getResourceKey(), "resource-key-v2");
+ assertEquals(discoveredResource.getName(), "resource-name-v2");
+ assertEquals(discoveredResource.getDescription(), "resource-description-v2");
+
+ ResourceContainer container = PluginContainer.getInstance().getInventoryManager().getResourceContainer(discoveredResource);
+ File dataDir = container.getResourceContext().getDataDirectory();
+
+ File marker = new File(dataDir, "upgrade-succeeded");
+
+ assertTrue(marker.exists(), "The upgrade success marker file wasn't found. This means the upgrade didn't actually run.");
+ }
+
+ @SuppressWarnings("unchecked")
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+
+ between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+
+ oneOf(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
+ will(currentServerSideInventory.upgradeResources());
+ }
+ };
+ }
+ });
+ }
+
private PluginContainerConfiguration createPluginContainerConfiguration(Mockery context) throws Exception {
PluginContainerConfiguration conf = new PluginContainerConfiguration();
@@ -223,6 +247,15 @@ public class ResourceUpgradeTest {
conf.setPluginFinder(new FileSystemPluginFinder(conf.getPluginDirectory()));
conf.setCreateResourceClassloaders(false);
+ //we're not interested in any scans happening out of our control
+ conf.setAvailabilityScanInitialDelay(Long.MAX_VALUE);
+ conf.setConfigurationDiscoveryInitialDelay(Long.MAX_VALUE);
+ conf.setContentDiscoveryInitialDelay(Long.MAX_VALUE);
+ conf.setEventSenderInitialDelay(Long.MAX_VALUE);
+ conf.setMeasurementCollectionInitialDelay(Long.MAX_VALUE);
+ conf.setServerDiscoveryInitialDelay(Long.MAX_VALUE);
+ conf.setServiceDiscoveryInitialDelay(Long.MAX_VALUE);
+
currentBundleServerService = context.mock(BundleServerService.class);
currentConfigurationServerService = context.mock(ConfigurationServerService.class);
currentContentServerService = context.mock(ContentServerService.class);
@@ -332,7 +365,8 @@ public class ResourceUpgradeTest {
context.assertIsSatisfied();
}
- private void defineIgnoredExpectations(Expectations expectations) {
+ @SuppressWarnings("unchecked")
+ private void defineDefaultExpectations(Expectations expectations) {
expectations.ignoring(currentBundleServerService);
expectations.ignoring(currentConfigurationServerService);
expectations.ignoring(currentContentServerService);
@@ -341,5 +375,11 @@ public class ResourceUpgradeTest {
expectations.ignoring(currentMeasurementServerService);
expectations.ignoring(currentOperationServerService);
expectations.ignoring(currentResourceFactoryServerService);
+
+ //just ignore these invocations if we get a availability scan in the PC...
+ expectations.allowing(currentDiscoveryServerService).mergeAvailabilityReport(expectations.with(Expectations.any(AvailabilityReport.class)));
+
+ expectations.allowing(currentDiscoveryServerService).getResources(expectations.with(Expectations.any(Set.class)), expectations.with(Expectations.any(boolean.class)));
+ expectations.will(currentServerSideInventory.getResources());
}
}
commit 0d5d63e1ed0825ddc0ea256b695a66c980b69e6e
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Jun 23 15:40:16 2010 +0200
Forgot to bump the db version.
diff --git a/modules/core/dbutils/pom.xml b/modules/core/dbutils/pom.xml
index 92ae1d2..2013b3d 100644
--- a/modules/core/dbutils/pom.xml
+++ b/modules/core/dbutils/pom.xml
@@ -22,7 +22,7 @@
<properties>
<scm.module.path>modules/core/dbutils/</scm.module.path>
- <db.schema.version>2.87</db.schema.version>
+ <db.schema.version>2.88</db.schema.version>
</properties>
<dependencies>
commit 7f8310f4d3648ba3386fda883563bdcc8c5d1492
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Jun 23 15:39:54 2010 +0200
Adding the server side system config property for controlling whether to allow resource name and description upgrades.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/config/SystemConfigForm.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/config/SystemConfigForm.java
index 237858d..508a4ac 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/config/SystemConfigForm.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/config/SystemConfigForm.java
@@ -66,7 +66,8 @@ public class SystemConfigForm extends BaseValidatorForm {
private String ldapPassword = "";
private Boolean ldapEnabled = null;
private boolean reindex = false;
-
+ private boolean allowResourceGenericPropertiesUpgrade;
+
@Override
public String toString() {
StringBuffer buf = new StringBuffer(super.toString());
@@ -230,6 +231,8 @@ public class SystemConfigForm extends BaseValidatorForm {
String jaasProvider = prop.getProperty(RHQConstants.JAASProvider);
ldapEnabled = RHQConstants.LDAPJAASProvider.equals(jaasProvider) ? Boolean.TRUE : null;
+ String resourceGenericPropertiesUpgradeAllowed = prop.getProperty(RHQConstants.AllowResourceGenericPropertiesUpgrade);
+ allowResourceGenericPropertiesUpgrade = Boolean.parseBoolean(resourceGenericPropertiesUpgradeAllowed);
}
/**
@@ -332,6 +335,8 @@ public class SystemConfigForm extends BaseValidatorForm {
prop.setProperty(RHQConstants.JAASProvider, RHQConstants.JDBCJAASProvider);
}
+ prop.setProperty(RHQConstants.AllowResourceGenericPropertiesUpgrade, String.valueOf(allowResourceGenericPropertiesUpgrade));
+
return prop;
}
@@ -608,6 +613,14 @@ public class SystemConfigForm extends BaseValidatorForm {
public void setReindex(boolean reindex) {
this.reindex = reindex;
}
+
+ public boolean isAllowResourceGenericPropertiesUpgrade() {
+ return allowResourceGenericPropertiesUpgrade;
+ }
+
+ public void setAllowResourceGenericPropertiesUpgrade(boolean allowResourceGenericPropertiesUpgrade) {
+ this.allowResourceGenericPropertiesUpgrade = allowResourceGenericPropertiesUpgrade;
+ }
/* (non-Javadoc)
* @see org.apache.struts.action.ActionForm#validate(org.apache.struts.action.ActionMapping,
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties b/modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties
index f02efb5..83f42f0 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties
+++ b/modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties
@@ -667,6 +667,8 @@ admin.settings.ServerPluginsConfigPropTab=Server Plugins Configuration Propertie
admin.settings.UseCAMAuth=Use ${product.shortName} Internal Authentication
admin.settings.UseLDAPAuth=Use LDAP Authentication
+admin.settings.AllowResourceGenericPropertiesUpgrade=Allow Agent Plugins To Upgrade Generic Resource Properties
+
admin.settings.error.DeleteUnitsField=Value must be between 1 and 7 days.
admin.settings.error.InvalidSNMPTrapOID=SNMP Trap OID invalid, please enter OID in form of 1.2.3.4.
admin.settings.error.InvalidSNMPEngineID=SNMP Engine ID is invalid, must be a valid number.
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/GeneralPropertiesConfigForm.jsp b/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/GeneralPropertiesConfigForm.jsp
index 30df9ef..136c37c 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/GeneralPropertiesConfigForm.jsp
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/GeneralPropertiesConfigForm.jsp
@@ -86,6 +86,17 @@
</table>
</td>
</tr>
+ <tr>
+ <td class="BlockLabel"><fmt:message key="admin.settings.AllowResourceGenericPropertiesUpgrade"/></td>
+ <td class="BlockContent">
+ <table cellpadding="0" cellspacing="4" border="0">
+ <tr>
+ <td align="left"><html:radio property="allowResourceGenericPropertiesUpgrade" value="true"/><fmt:message key="yesno.true"/></td>
+ <td align="left"><html:radio property="allowResourceGenericPropertiesUpgrade" value="false"/><fmt:message key="yesno.false"/></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
<hq:authorization permission="superuser">
<tr>
commit 6c2472739d2df4b5a99f1e4fae22b945440dd5fd
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Jun 23 15:29:15 2010 +0200
Adding the ability of the server to alter/ignore some upgrade data.
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
new file mode 100644
index 0000000..825a616
--- /dev/null
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
@@ -0,0 +1,55 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.rhq.core.clientapi.agent.upgrade;
+
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
+
+/**
+ * Represents a request to upgrade a resource.
+ *
+ * @author Lukas Krejci
+ */
+public class ResourceUpgradeRequest extends ResourceUpgradeReport {
+
+ private int resourceId;
+
+ public ResourceUpgradeRequest() {
+
+ }
+
+ public ResourceUpgradeRequest(int resourceId, ResourceUpgradeReport report) {
+ setResourceId(resourceId);
+ setNewDescription(report.getNewDescription());
+ setNewName(report.getNewName());
+ setNewResourceKey(report.getNewResourceKey());
+ }
+
+ public int getResourceId() {
+ return resourceId;
+ }
+
+ public void setResourceId(int resourceId) {
+ this.resourceId = resourceId;
+ }
+}
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeResponse.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeResponse.java
new file mode 100644
index 0000000..3faa9ef
--- /dev/null
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeResponse.java
@@ -0,0 +1,80 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.rhq.core.clientapi.agent.upgrade;
+
+import java.io.Serializable;
+
+/**
+ * Represents a response to a resource upgrade request.
+ * The upgraded* properties contain the values of the corresponding resource properties
+ * as they were stored on the server.
+ *
+ * @author Lukas Krejci
+ */
+public class ResourceUpgradeResponse implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private int resourceId;
+
+ private String upgradedResourceName;
+ private String upgradedResourceKey;
+ private String upgradedResourceDescription;
+
+ public ResourceUpgradeResponse() {
+
+ }
+
+ public int getResourceId() {
+ return resourceId;
+ }
+
+ public void setResourceId(int resourceId) {
+ this.resourceId = resourceId;
+ }
+
+ public String getUpgradedResourceName() {
+ return upgradedResourceName;
+ }
+
+ public void setUpgradedResourceName(String upgradedResourceName) {
+ this.upgradedResourceName = upgradedResourceName;
+ }
+
+ public String getUpgradedResourceKey() {
+ return upgradedResourceKey;
+ }
+
+ public void setUpgradedResourceKey(String upgradedResourceKey) {
+ this.upgradedResourceKey = upgradedResourceKey;
+ }
+
+ public String getUpgradedResourceDescription() {
+ return upgradedResourceDescription;
+ }
+
+ public void setUpgradedResourceDescription(String upgradedResourceDescription) {
+ this.upgradedResourceDescription = upgradedResourceDescription;
+ }
+}
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
index 61e5084..0622fc5 100644
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
@@ -29,6 +29,8 @@ import org.rhq.core.communications.command.annotation.Asynchronous;
import org.rhq.core.communications.command.annotation.LimitedConcurrency;
import org.rhq.core.communications.command.annotation.Timeout;
import org.rhq.core.domain.discovery.AvailabilityReport;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeResponse;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
import org.rhq.core.domain.discovery.MergeResourceResponse;
import org.rhq.core.domain.discovery.ResourceSyncInfo;
@@ -37,7 +39,6 @@ import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.domain.resource.ResourceErrorType;
-import org.rhq.core.domain.resource.ResourceUpgradeReport;
/**
* The interface to a JON server's resource discovery subsystem.
@@ -139,11 +140,13 @@ public interface DiscoveryServerService {
/**
* Upgrades the data of the resources according to the provided reports.
+ * The server is free to ignore or modify the requests and will provide the
+ * true changes made to the resources on the server-side in the result of this method.
*
- * @param upgradeReports contains the information about the upgrade of individual resources.
- * @return true if the upgrade succeeded, false otherwise.
+ * @param upgradeRequests contains the information about the upgrade of individual resources.
+ * @return details on what resources have been upgraded with what data.
*/
- boolean upgradeResources(Set<ResourceUpgradeReport> upgradeReports);
+ Set<ResourceUpgradeResponse> upgradeResources(Set<ResourceUpgradeRequest> upgradeRequests);
/**
* Gives the server a chance to apply any necessary post-processing that's needed for newly committed resources
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/sysconfig-data.xml b/modules/core/dbutils/src/main/scripts/dbsetup/sysconfig-data.xml
index 26d648e..121e971 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup/sysconfig-data.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/sysconfig-data.xml
@@ -121,6 +121,9 @@
<!-- How old does availability have to be in order to get purged -->
<data ID="55" PROPERTY_KEY="AVAILABILITY_PURGE" PROPERTY_VALUE="31536000000"
DEFAULT_PROPERTY_VALUE="31536000000" FREAD_ONLY="FALSE"/>
+
+ <data ID="56" PROPERTY_KEY="RESOURCE_GENERIC_PROPERTIES_UPGRADE" PROPERTY_VALUE="false"
+ DEFAULT_PROPERTY_VALUE="false" FREAD_ONLY="FALSE"/>
</table>
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
index 71aa297..ad53803 100644
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@ -2994,6 +2994,14 @@
</schema-directSQL>
</schemaSpec>
+ <schemaSpec version="2.88">
+ <schema-directSQL>
+ <statement desc="Adding 'Allow Agent Plugins To Upgrade Generic Resource Properties' system configuration setting">
+ INSERT INTO rhq_system_config (id, property_key, property_value, default_property_value)
+ VALUES (56, 'RESOURCE_GENERIC_PROPERTIES_UPGRADE', 'false', 'false')
+ </statement>
+ </schema-directSQL>
+ </schemaSpec>
</dbupgrade>
</target>
</project>
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
index 979c456..0f9db04 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
@@ -41,7 +41,6 @@ public class ResourceUpgradeReport implements Serializable {
private static final long serialVersionUID = 1L;
- private int resourceId;
private String newResourceKey;
private String newName;
@@ -62,22 +61,6 @@ public class ResourceUpgradeReport implements Serializable {
}
- /**
- * The server-side id of the resource being upgraded.
- * The discovery components don't need to assign this value.
- */
- public int getResourceId() {
- return resourceId;
- }
-
- /**
- * The server-side id of the resource being upgraded.
- * The discovery components don't need to assign this value.
- */
- public void setResourceId(int resourceId) {
- this.resourceId = resourceId;
- }
-
public String getNewResourceKey() {
return newResourceKey;
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 6c3d26a..b5f5f00 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -55,6 +55,8 @@ import org.rhq.core.clientapi.agent.configuration.ConfigurationUtility;
import org.rhq.core.clientapi.agent.discovery.DiscoveryAgentService;
import org.rhq.core.clientapi.agent.discovery.InvalidPluginConfigurationClientException;
import org.rhq.core.clientapi.agent.metadata.PluginMetadataManager;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeResponse;
import org.rhq.core.clientapi.server.discovery.DiscoveryServerService;
import org.rhq.core.clientapi.server.discovery.InvalidInventoryReportException;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
@@ -92,7 +94,7 @@ import org.rhq.core.pc.plugin.CanonicalResourceKey;
import org.rhq.core.pc.plugin.PluginComponentFactory;
import org.rhq.core.pc.plugin.PluginManager;
import org.rhq.core.pc.upgrade.ResourceUpgradeExecutor;
-import org.rhq.core.pc.upgrade.ResourceUpgradeRequest;
+import org.rhq.core.pc.upgrade.ResourceUpgradePendingRequest;
import org.rhq.core.pc.util.DiscoveryComponentProxyFactory;
import org.rhq.core.pc.util.FacetLockType;
import org.rhq.core.pc.util.LoggingThreadFactory;
@@ -1178,31 +1180,31 @@ public class InventoryManager extends AgentService implements ContainerService,
return resourceContainer.updateAvailability(availabilityType);
}
- public boolean mergeResourceFromUpgrade(Set<ResourceUpgradeReport> upgradeReports) {
- boolean serverUpdated = false;
+ public void mergeResourceFromUpgrade(Set<ResourceUpgradeRequest> upgradeReports) {
+ Set<ResourceUpgradeResponse> serverUpdates = null;
try {
ServerServices serverServices = this.configuration.getServerServices();
if (serverServices != null) {
DiscoveryServerService discoveryServerService = serverServices.getDiscoveryServerService();
- serverUpdated = discoveryServerService.upgradeResources(upgradeReports);
+ serverUpdates = discoveryServerService.upgradeResources(upgradeReports);
}
} catch (Exception e) {
log.error("Failed to process resource upgrades on the server.", e);
}
- if (serverUpdated) {
- for (ResourceUpgradeReport upgradeReport : upgradeReports) {
- String resourceKey = upgradeReport.getNewResourceKey();
- String name = upgradeReport.getNewName();
+ if (serverUpdates != null) {
+ for (ResourceUpgradeResponse upgradeResponse : serverUpdates) {
+ String resourceKey = upgradeResponse.getUpgradedResourceKey();
+ String name = upgradeResponse.getUpgradedResourceName();
//String version = upgradeReport.getNewVersion();
- String description = upgradeReport.getNewDescription();
+ String description = upgradeResponse.getUpgradedResourceDescription();
//Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
//Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
//only bother if there's something to upgrade at all on this resource.
if (resourceKey != null || name != null || description != null) {
- ResourceContainer existingResourceContainer = getResourceContainer(upgradeReport.getResourceId());
+ ResourceContainer existingResourceContainer = getResourceContainer(upgradeResponse.getResourceId());
if (existingResourceContainer != null) {
Resource existingResource = existingResourceContainer.getResource();
@@ -1241,13 +1243,11 @@ public class InventoryManager extends AgentService implements ContainerService,
log.info(logMessage.toString());
} else {
- log.error("Upgraded a resource that is not present on the agent. This should not happen. The id of the missing resource is " + upgradeReport.getResourceId());
+ log.error("Upgraded a resource that is not present on the agent. This should not happen. The id of the missing resource is " + upgradeResponse.getResourceId());
}
}
}
}
-
- return serverUpdated;
}
public Resource mergeResourceFromDiscovery(Resource resource, Resource parent) throws PluginContainerException {
@@ -2173,7 +2173,7 @@ public class InventoryManager extends AgentService implements ContainerService,
}
if (resourceUpgradeExecutor.isEnabled()) {
- resourceUpgradeExecutor.processAndQueue(new ResourceUpgradeRequest(newResources, context, parentResource.getId()), newResources);
+ resourceUpgradeExecutor.processAndQueue(new ResourceUpgradePendingRequest(newResources, context, parentResource.getId()), newResources);
}
} catch (Throwable e) {
// TODO GH: Add server/parent - up/down semantics so this won't happen just because a server is not up
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
index bb20054..f344900 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
@@ -29,7 +29,6 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -37,6 +36,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rhq.core.clientapi.agent.PluginContainerException;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
@@ -69,11 +69,11 @@ public class ResourceUpgradeExecutor implements Runnable {
private InventoryManager inventoryManager;
- private ConcurrentLinkedQueue<ResourceUpgradeReport> reports;
+ private ConcurrentLinkedQueue<ResourceUpgradeRequest> requests;
public ResourceUpgradeExecutor(InventoryManager inventoryManager) {
this.inventoryManager = inventoryManager;
- reports = new ConcurrentLinkedQueue<ResourceUpgradeReport>();
+ requests = new ConcurrentLinkedQueue<ResourceUpgradeRequest>();
}
/**
@@ -92,9 +92,9 @@ public class ResourceUpgradeExecutor implements Runnable {
* @param discoveredResources the set of discovered resources that this method can optionally remove some elements from.
*/
public <T extends ResourceComponent> Map<ResourceUpgradeContext<T>, ResourceUpgradeReport> processAndQueue(
- ResourceUpgradeRequest<T> request, Set<Resource> discoveredResources) {
+ ResourceUpgradePendingRequest<T> request, Set<Resource> discoveredResources) {
- return enabled.get() ? executeResourceUpgradeAndStoreReport(request, discoveredResources) : null;
+ return enabled.get() ? executeResourceUpgradeAndStoreRequest(request, discoveredResources) : null;
}
/**
@@ -109,10 +109,10 @@ public class ResourceUpgradeExecutor implements Runnable {
* all the upgrade requests.
*/
public void sendRequests() {
- if (enabled.get() && reports.size() > 0) {
- HashSet<ResourceUpgradeReport> currentCopy = new HashSet<ResourceUpgradeReport>(reports);
+ if (enabled.get() && requests.size() > 0) {
+ HashSet<ResourceUpgradeRequest> currentCopy = new HashSet<ResourceUpgradeRequest>(requests);
inventoryManager.mergeResourceFromUpgrade(currentCopy);
- reports.removeAll(currentCopy);
+ requests.removeAll(currentCopy);
}
}
@@ -148,7 +148,7 @@ public class ResourceUpgradeExecutor implements Runnable {
this.enabled.set(false);
//clear up so that we don't hold unnecessary instances.
- reports.clear();
+ requests.clear();
if (log.isDebugEnabled()) {
log.debug("Resource upgrade finished.");
@@ -171,8 +171,8 @@ public class ResourceUpgradeExecutor implements Runnable {
*
* @throws PluginContainerException
*/
- private <T extends ResourceComponent> Map<ResourceUpgradeContext<T>, ResourceUpgradeReport> executeResourceUpgradeAndStoreReport(
- ResourceUpgradeRequest<T> request, Set<Resource> discoveredResources) {
+ private <T extends ResourceComponent> Map<ResourceUpgradeContext<T>, ResourceUpgradeReport> executeResourceUpgradeAndStoreRequest(
+ ResourceUpgradePendingRequest<T> request, Set<Resource> discoveredResources) {
ResourceDiscoveryContext<T> discoveryContext = request.getDiscoveryContext();
Set<Resource> newResources = request.getDiscoveredResources();
@@ -267,14 +267,12 @@ public class ResourceUpgradeExecutor implements Runnable {
results = inventoryManager.invokeDiscoveryComponentResourceUpgradeFacet(resourceType,
discoveryComponent, siblingContexts, parentUpgradeContext, newResourceContexts);
- //now go through the results and upgrade the resources as needed.
+ //now go through the results and create the upgrade requests.
for (Map.Entry<ResourceUpgradeContext<T>, ResourceUpgradeReport> upgradeEntry : results.entrySet()) {
Resource siblingToUpgrade = siblingContextToResource.get(upgradeEntry.getKey());
- ResourceUpgradeReport newData = upgradeEntry.getValue();
+ ResourceUpgradeRequest newData = new ResourceUpgradeRequest(siblingToUpgrade.getId(), upgradeEntry.getValue());
- //upgrade the data on the server first
- newData.setResourceId(siblingToUpgrade.getId());
- reports.add(newData);
+ requests.add(newData);
//if there was a resource key upgrade, remove a resource with the same resource key
//from the discovery results. Otherwise we'd end up with 2 sibling resources with
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradePendingRequest.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradePendingRequest.java
new file mode 100644
index 0000000..1099643
--- /dev/null
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradePendingRequest.java
@@ -0,0 +1,35 @@
+package org.rhq.core.pc.upgrade;
+
+import java.util.Set;
+
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+
+/**
+ * This class is used to store the requests for resource upgrade that originate in
+ * the discovery workflow, but can only be executed after an inventory sync.
+ */
+public class ResourceUpgradePendingRequest<T extends ResourceComponent> {
+ private Set<Resource> discoveredResources;
+ private ResourceDiscoveryContext<T> discoveryContext;
+ private Integer parentResourceId;
+
+ public ResourceUpgradePendingRequest(Set<Resource> discoveredResources, ResourceDiscoveryContext<T> discoveryContext, Integer parentResourceId) {
+ this.discoveredResources = discoveredResources;
+ this.discoveryContext = discoveryContext;
+ this.parentResourceId = parentResourceId;
+ }
+
+ public Set<Resource> getDiscoveredResources() {
+ return discoveredResources;
+ }
+
+ public ResourceDiscoveryContext<T> getDiscoveryContext() {
+ return discoveryContext;
+ }
+
+ public Integer getParentResourceId() {
+ return parentResourceId;
+ }
+}
\ No newline at end of file
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeRequest.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeRequest.java
deleted file mode 100644
index 25178ee..0000000
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeRequest.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.rhq.core.pc.upgrade;
-
-import java.util.Set;
-
-import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.pluginapi.inventory.ResourceComponent;
-import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
-
-/**
- * This class is used to store the requests for resource upgrade that originate in
- * the discovery workflow, but can only be executed after an inventory sync.
- */
-public class ResourceUpgradeRequest<T extends ResourceComponent> {
- private Set<Resource> discoveredResources;
- private ResourceDiscoveryContext<T> discoveryContext;
- private Integer parentResourceId;
-
- public ResourceUpgradeRequest(Set<Resource> discoveredResources, ResourceDiscoveryContext<T> discoveryContext, Integer parentResourceId) {
- this.discoveredResources = discoveredResources;
- this.discoveryContext = discoveryContext;
- this.parentResourceId = parentResourceId;
- }
-
- public Set<Resource> getDiscoveredResources() {
- return discoveredResources;
- }
-
- public ResourceDiscoveryContext<T> getDiscoveryContext() {
- return discoveryContext;
- }
-
- public Integer getParentResourceId() {
- return parentResourceId;
- }
-}
\ No newline at end of file
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
index 4341e3a..c3bdbf4 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
@@ -37,15 +37,17 @@ import java.util.Set;
import org.jmock.api.Invocation;
import org.jmock.lib.action.CustomAction;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeResponse;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
import org.rhq.core.domain.discovery.ResourceSyncInfo;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
-import org.rhq.core.domain.resource.ResourceUpgradeReport;
/**
- *
+ * This class represents a server side database store of the inventory for the purposes
+ * of the ResourceUpgradeTest unit test.
*
* @author Lukas Krejci
*/
@@ -89,28 +91,36 @@ public class FakeServerInventory {
return new CustomAction("upgradeServerSideInventory") {
@SuppressWarnings({"serial", "unchecked"})
public Object invoke(Invocation invocation) throws Throwable {
- Set<ResourceUpgradeReport> reports = (Set<ResourceUpgradeReport>) invocation.getParameter(0);
-
- for (final ResourceUpgradeReport report : reports) {
+ Set<ResourceUpgradeRequest> requests = (Set<ResourceUpgradeRequest>) invocation.getParameter(0);
+ Set<ResourceUpgradeResponse> responses = new HashSet<ResourceUpgradeResponse>();
+
+ for (final ResourceUpgradeRequest request : requests) {
Resource resource = findResource(platform, new Resource() {
public int getId() {
- return report.getResourceId();
+ return request.getResourceId();
}
}, ID_COMPARATOR);
if (resource != null) {
- if (report.getNewDescription() != null) {
- resource.setDescription(report.getNewDescription());
+ if (request.getNewDescription() != null) {
+ resource.setDescription(request.getNewDescription());
}
- if (report.getNewName() != null) {
- resource.setName(report.getNewName());
+ if (request.getNewName() != null) {
+ resource.setName(request.getNewName());
}
- if (report.getNewResourceKey() != null) {
- resource.setResourceKey(report.getNewResourceKey());
+ if (request.getNewResourceKey() != null) {
+ resource.setResourceKey(request.getNewResourceKey());
}
+
+ ResourceUpgradeResponse resp = new ResourceUpgradeResponse();
+ resp.setResourceId(resource.getId());
+ resp.setUpgradedResourceName(resource.getName());
+ resp.setUpgradedResourceKey(resource.getResourceKey());
+ resp.setUpgradedResourceDescription(resource.getDescription());
+ responses.add(resp);
}
}
- return true;
+ return responses;
}
};
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/RHQConstants.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/RHQConstants.java
index 7bb1d72..fff7872 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/RHQConstants.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/RHQConstants.java
@@ -110,5 +110,8 @@ public class RHQConstants {
// Syslog Actions enabled
public static final String SyslogActionsEnabled = "CAM_SYSLOG_ACTIONS_ENABLED";
+
+ //allow plugin initiated resource name & description upgrades (resource key is always upgradable)
+ public static final String AllowResourceGenericPropertiesUpgrade = "RESOURCE_GENERIC_PROPERTIES_UPGRADE";
}
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index fd59590..329f476 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -20,8 +20,10 @@ package org.rhq.enterprise.server.discovery;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -43,6 +45,8 @@ import org.jetbrains.annotations.Nullable;
import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.agent.discovery.InvalidPluginConfigurationClientException;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeResponse;
import org.rhq.core.clientapi.server.discovery.InvalidInventoryReportException;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
import org.rhq.core.domain.auth.Subject;
@@ -75,6 +79,7 @@ import org.rhq.enterprise.server.resource.ResourceAvailabilityManagerLocal;
import org.rhq.enterprise.server.resource.ResourceManagerLocal;
import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal;
import org.rhq.enterprise.server.resource.group.ResourceGroupManagerLocal;
+import org.rhq.enterprise.server.system.SystemManagerLocal;
/**
* SLSB that provides the interface point to the discovery subsystem for the UI layer and the discovery server service.
@@ -107,6 +112,8 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
private SubjectManagerLocal subjectManager;
@EJB
private ProductVersionManagerLocal productVersionManager;
+ @EJB
+ private SystemManagerLocal systemManager;
public ResourceSyncInfo mergeInventoryReport(InventoryReport report) throws InvalidInventoryReportException {
validateInventoryReport(report);
@@ -407,20 +414,19 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
}
}
- public boolean upgradeResources(Set<ResourceUpgradeReport> upgradeReports) {
- for (ResourceUpgradeReport report : upgradeReports) {
- Resource existingResource = this.entityManager.find(Resource.class, report.getResourceId());
+ public Set<ResourceUpgradeResponse> upgradeResources(Set<ResourceUpgradeRequest> upgradeRequests) {
+ Set<ResourceUpgradeResponse> result = new HashSet<ResourceUpgradeResponse>();
+
+ boolean allowGenericPropertiesUpgrade = Boolean.parseBoolean(systemManager.getSystemConfiguration().getProperty(RHQConstants.AllowResourceGenericPropertiesUpgrade, "false"));
+
+ for (ResourceUpgradeRequest request : upgradeRequests) {
+ Resource existingResource = this.entityManager.find(Resource.class, request.getResourceId());
if (existingResource != null) {
- boolean changed = upgradeResource(existingResource, report);
- if (changed) {
- this.entityManager.merge(existingResource);
- }
- } else {
- this.entityManager.getTransaction().setRollbackOnly();
- return false;
+ ResourceUpgradeResponse upgradedData = upgradeResource(existingResource, request, allowGenericPropertiesUpgrade);
+ result.add(upgradedData);
}
}
- return true;
+ return result;
}
/**
@@ -471,40 +477,46 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
/**
* @param existingResource
* @param upgradeReport
+ * @param allowGenericPropertiesUpgrade name and description are only upgraded if this is true
* @return true if the resource was changed, false otherwise
*/
- private boolean upgradeResource(Resource resource, ResourceUpgradeReport upgradeReport) {
- if (resource != null) {
- String resourceKey = upgradeReport.getNewResourceKey();
- String name = upgradeReport.getNewName();
+ private ResourceUpgradeResponse upgradeResource(@NotNull Resource resource, ResourceUpgradeReport upgradeReport, boolean allowGenericPropertiesUpgrade) {
+ ResourceUpgradeResponse ret = new ResourceUpgradeResponse();
+ ret.setResourceId(resource.getId());
+
+ String resourceKey = upgradeReport.getNewResourceKey();
+ String name = upgradeReport.getNewName();
// String version = upgradeReport.getNewVersion();
- String description = upgradeReport.getNewDescription();
+ String description = upgradeReport.getNewDescription();
// Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
// Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
+
+ if (resourceKey != null || name != null || description != null) {
+ StringBuilder logMessage = new StringBuilder("Resource [")
+ .append(resource.toString()).append("] upgraded its ");
+
+ if (needsUpgrade(resource.getResourceKey(), resourceKey)) {
+ resource.setResourceKey(resourceKey);
+ logMessage.append("resourceKey, ");
+ }
+ ret.setUpgradedResourceKey(resource.getResourceKey());
+
+ if (allowGenericPropertiesUpgrade && needsUpgrade(resource.getName(), name)) {
+ resource.setName(name);
+ logMessage.append("name, ");
+ }
+ ret.setUpgradedResourceName(resource.getName());
- if (resourceKey != null || name != null || description != null) {
- StringBuilder logMessage = new StringBuilder("Resource [")
- .append(resource.toString()).append("] upgraded its ");
-
- if (needsUpgrade(resource.getResourceKey(), resourceKey)) {
- resource.setResourceKey(resourceKey);
- logMessage.append("resourceKey, ");
- }
-
- if (needsUpgrade(resource.getName(), name)) {
- resource.setName(name);
- logMessage.append("name, ");
- }
-
// if (version != null) {
// changed = updateResourceVersion(resource, version) || changed;
// }
-
- if (needsUpgrade(resource.getDescription(), description)) {
- resource.setDescription(description);
- logMessage.append("description, ");
- }
-
+
+ if (allowGenericPropertiesUpgrade && needsUpgrade(resource.getDescription(), description)) {
+ resource.setDescription(description);
+ logMessage.append("description, ");
+ }
+ ret.setUpgradedResourceDescription(resource.getDescription());
+
// if (pluginConfiguration != null) {
// if (!equalOrNull(pluginConfiguration, resource.getPluginConfiguration())) {
// log.info("Resource [" + resource + "] upgraded its plugin configuration from [" +
@@ -525,16 +537,13 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
// resource.setResourceConfiguration(resourceConfiguration);
// }
// }
-
- logMessage.replace(logMessage.length() - 1, logMessage.length(),
- "to become [").append(resource.toString()).append("]");
- log.info(logMessage.toString());
-
- return true;
- }
+ logMessage.replace(logMessage.length() - 1, logMessage.length(),
+ "to become [").append(resource.toString()).append("]");
+
+ log.info(logMessage.toString());
}
- return false;
+ return ret;
}
private void validateInventoryReport(InventoryReport report) throws InvalidInventoryReportException {
@@ -651,9 +660,21 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
*/
ResourceType resourceType = resource.getResourceType();
Resource parent = resource;
+ Subject overlord = subjectManager.getOverlord();
while (parent != null && existingResource == null) {
parent = parent.getParentResource();
- existingResource = resourceManager.getResourceByParentAndKey(subjectManager.getOverlord(), parent,
+ //check if the parent itself is inventoried. This might not be the case
+ //during initial sync-up for resource upgrade.
+ Resource existingParent = null;
+ if (parent != null) {
+ existingParent = entityManager.find(Resource.class, parent.getId());
+ if (existingParent == null) {
+ //well, this parent is not known to the server, so there's no
+ //point in trying to find a child of it...
+ continue;
+ }
+ }
+ existingResource = resourceManager.getResourceByParentAndKey(overlord, existingParent,
resource.getResourceKey(), resourceType.getPlugin(), resourceType.getName());
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
index af518eb..c9208fc 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
@@ -29,6 +29,8 @@ import org.jetbrains.annotations.NotNull;
import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.agent.discovery.InvalidPluginConfigurationClientException;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeResponse;
import org.rhq.core.clientapi.server.discovery.InvalidInventoryReportException;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
import org.rhq.core.domain.auth.Subject;
@@ -181,9 +183,11 @@ public interface DiscoveryBossLocal extends DiscoveryBossRemote {
/**
* Upgrades the data of the resources according to the provided reports.
+ * The server is free to ignore or modify the requests and will provide the
+ * true changes made to the resources on the server-side in the result of this method.
*
- * @param upgradeReports contains the information about the upgrade of individual resources.
- * @return true if the upgrade succeeded, false otherwise.
+ * @param upgradeRequests contains the information about the upgrade of individual resources.
+ * @return details on what resources have been upgraded with what data.
*/
- boolean upgradeResources(Set<ResourceUpgradeReport> upgradeReports);
+ Set<ResourceUpgradeResponse> upgradeResources(Set<ResourceUpgradeRequest> upgradeRequest);
}
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
index 0f90cdc..5dbe59a 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
@@ -25,6 +25,8 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeResponse;
import org.rhq.core.clientapi.server.discovery.DiscoveryServerService;
import org.rhq.core.clientapi.server.discovery.InvalidInventoryReportException;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
@@ -177,9 +179,9 @@ public class DiscoveryServerServiceImpl implements DiscoveryServerService {
return discoveryBoss.updateResourceVersion(resourceId, version);
}
- public boolean upgradeResources(Set<ResourceUpgradeReport> upgradeReports) {
+ public Set<ResourceUpgradeResponse> upgradeResources(Set<ResourceUpgradeRequest> upgradeRequests) {
DiscoveryBossLocal discoveryBoss = LookupUtil.getDiscoveryBoss();
- return discoveryBoss.upgradeResources(upgradeReports);
+ return discoveryBoss.upgradeResources(upgradeRequests);
}
private static Resource convertToPojoResource(Resource resource, boolean includeDescendants) {
commit a479fd3591a15b7422b378a000f213a21b9bf750
Merge: ab45b75... f595c48...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Jun 18 21:19:23 2010 +0200
Merge branch 'release-3.0.0' into resource-upgrade
commit ab45b7518ec6b740899c694c3229746cd0490fd6
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Jun 18 20:25:56 2010 +0200
Basic unit tests of the resource upgrade workflow along with some minor changes in the PC to handle the hardcoded test platform in a normal connected-like scenarios.
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/PluginMetadataManager.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/PluginMetadataManager.java
index 63072db..0c5e0b6 100644
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/PluginMetadataManager.java
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/PluginMetadataManager.java
@@ -55,7 +55,7 @@ public class PluginMetadataManager {
private Object typesLock = new Object();
private Map<String, PluginMetadataParser> parsersByPlugin = new HashMap<String, PluginMetadataParser>();
-
+
public PluginMetadataManager() {
}
@@ -177,6 +177,9 @@ public class PluginMetadataManager {
@Nullable
public ResourceType getType(ResourceType resourceType) {
+ if (TEST_PLATFORM_TYPE.equals(resourceType)) {
+ return TEST_PLATFORM_TYPE;
+ }
return getType(resourceType.getName(), resourceType.getPlugin());
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index dbee063..1433120 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -1369,12 +1369,6 @@ public class InventoryManager extends AgentService implements ContainerService,
resourceContainer.setSynchronizationState(ResourceContainer.SynchronizationState.SYNCHRONIZED);
}
this.resourceContainers.put(resource.getUuid(), resourceContainer);
- if (resource.getParentResource() == null) {
- // no parent - must be the top level platform - do some things needed for unit tests
- if (this.platform.getResourceType().equals(PluginMetadataManager.TEST_PLATFORM_TYPE)) {
- resourceContainer.setResourceComponent(createTestPlatformComponent());
- }
- }
} else {
// container already exists, but make sure the classloader exists too
if (resourceContainer.getResourceClassLoader() == null) {
@@ -1800,6 +1794,13 @@ public class InventoryManager extends AgentService implements ContainerService,
Set<DiscoveredResourceDetails> allDiscoveredPlatforms = new HashSet<DiscoveredResourceDetails>(2);
if ((platformTypes != null) && (platformTypes.size() > 0)) {
+
+ //check for fake testing type. If the test platform type is being used, it is always going to be
+ //the sole platform type available.
+ if (platformTypes.size() == 1 && platformTypes.contains(PluginMetadataManager.TEST_PLATFORM_TYPE)) {
+ return getTestPlatform();
+ }
+
// Go through all the platform types that are supported and see if they can detect our platform.
for (ResourceType platformType : platformTypes) {
try {
@@ -1828,7 +1829,7 @@ public class InventoryManager extends AgentService implements ContainerService,
.error("Missing platform plugin(s) - falling back to dummy platform impl; this should only occur in tests!");
// TODO: Set sysprop (e.g. rhq.test.mode=true) in integration tests,
// and throw a runtime exception here if that sysprop is not set.
- return createTestPlatform();
+ return getTestPlatform();
}
if (allDiscoveredPlatforms.isEmpty()) {
@@ -1870,9 +1871,13 @@ public class InventoryManager extends AgentService implements ContainerService,
* resource. This is normally only used during tests.
* @return A dummy platform for testing purposes only.
*/
- private Resource createTestPlatform() {
+ private Resource getTestPlatform() {
ResourceType type = PluginContainer.getInstance().getPluginManager().getMetadataManager().addTestPlatformType();
+ if (this.platform != null && this.platform.getResourceType() == type) {
+ return this.platform;
+ }
Resource platform = new Resource("testkey" + configuration.getContainerName(), "testplatform", type);
+ platform.setUuid(UUID.randomUUID().toString());
platform.setAgent(this.agent);
return platform;
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginComponentFactory.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginComponentFactory.java
index 4176353..b9d9cf3 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginComponentFactory.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginComponentFactory.java
@@ -30,6 +30,7 @@ import org.apache.commons.logging.LogFactory;
import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.agent.metadata.PluginMetadataManager;
+import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.pc.ContainerService;
@@ -39,6 +40,7 @@ import org.rhq.core.pc.inventory.InventoryManager;
import org.rhq.core.pc.inventory.ResourceContainer;
import org.rhq.core.pluginapi.inventory.ClassLoaderFacet;
import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
/**
@@ -129,6 +131,19 @@ public class PluginComponentFactory implements ContainerService {
*/
public ResourceComponent buildResourceComponent(Resource resource) throws PluginContainerException {
ResourceType resourceType = resource.getResourceType();
+ if (PluginMetadataManager.TEST_PLATFORM_TYPE.equals(resourceType)) {
+ return new ResourceComponent() {
+ public AvailabilityType getAvailability() {
+ return AvailabilityType.UP;
+ }
+
+ public void start(ResourceContext context) {
+ }
+
+ public void stop() {
+ }
+ };
+ }
String className = getPluginManager().getMetadataManager().getComponentClass(resourceType);
ClassLoader resourceClassloader = getResourceClassloader(resource);
ResourceComponent component = (ResourceComponent) instantiateClass(resourceClassloader, className);
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
new file mode 100644
index 0000000..4341e3a
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
@@ -0,0 +1,272 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.rhq.core.pc.upgrade;
+
+import static org.testng.Assert.fail;
+
+import java.lang.reflect.Field;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.jmock.api.Invocation;
+import org.jmock.lib.action.CustomAction;
+
+import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.domain.discovery.ResourceSyncInfo;
+import org.rhq.core.domain.resource.InventoryStatus;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
+
+/**
+ *
+ *
+ * @author Lukas Krejci
+ */
+public class FakeServerInventory {
+
+ private Resource platform;
+ private Map<String, Resource> resourceStore = new HashMap<String, Resource>();
+ private int counter;
+
+ private static final Comparator<Resource> ID_COMPARATOR = new Comparator<Resource>() {
+ public int compare(Resource o1, Resource o2) {
+ return o1.getId() - o2.getId();
+ }
+ };
+
+ private static final Comparator<Resource> RESOURCE_TYPE_COMPARATOR = new Comparator<Resource>() {
+ public int compare(Resource o1, Resource o2) {
+ return o1.getResourceType().equals(o2.getResourceType()) ? 0 : o1.getId() - o2.getId();
+ }
+ };
+
+ //need to synchronize, because resource upgrade is async and can overlap with
+ //resource discovery.
+ public synchronized CustomAction mergeInventoryReport(final InventoryStatus requiredInventoryStatus) {
+ return new CustomAction("updateServerSideInventory") {
+ public Object invoke(Invocation invocation) throws Throwable {
+ InventoryReport inventoryReport = (InventoryReport) invocation.getParameter(0);
+
+ for(Resource res : inventoryReport.getAddedRoots()) {
+ if (res.getParentResource() == Resource.ROOT) {
+ platform = fakePersist(res, requiredInventoryStatus, new HashSet<String>());
+ break;
+ }
+ }
+ return getSyncInfo();
+ }
+ };
+ }
+
+ public synchronized CustomAction upgradeResources() {
+ return new CustomAction("upgradeServerSideInventory") {
+ @SuppressWarnings({"serial", "unchecked"})
+ public Object invoke(Invocation invocation) throws Throwable {
+ Set<ResourceUpgradeReport> reports = (Set<ResourceUpgradeReport>) invocation.getParameter(0);
+
+ for (final ResourceUpgradeReport report : reports) {
+ Resource resource = findResource(platform, new Resource() {
+ public int getId() {
+ return report.getResourceId();
+ }
+ }, ID_COMPARATOR);
+ if (resource != null) {
+ if (report.getNewDescription() != null) {
+ resource.setDescription(report.getNewDescription());
+ }
+ if (report.getNewName() != null) {
+ resource.setName(report.getNewName());
+ }
+
+ if (report.getNewResourceKey() != null) {
+ resource.setResourceKey(report.getNewResourceKey());
+ }
+ }
+ }
+ return true;
+ }
+ };
+ }
+
+ public synchronized CustomAction getResources() {
+ return new CustomAction("getResources") {
+ @SuppressWarnings("unchecked")
+ public Object invoke(Invocation invocation) throws Throwable {
+ Set<Integer> resourceIds = (Set<Integer>)invocation.getParameter(0);
+ boolean includeDescendants = (Boolean) invocation.getParameter(1);
+
+ return getResources(resourceIds, includeDescendants);
+ }
+ };
+ }
+
+ @SuppressWarnings("serial")
+ public synchronized Set<Resource> findResourcesByType(final ResourceType type) {
+ Set<Resource> result = new HashSet<Resource>();
+ if (platform != null) {
+ findResources(platform, new Resource() {
+ public ResourceType getResourceType() {
+ return type;
+ }
+ }, result, RESOURCE_TYPE_COMPARATOR);
+ }
+ return result;
+ }
+
+ @SuppressWarnings("serial")
+ private Set<Resource> getResources(Set<Integer> resourceIds, boolean includeDescendants) {
+ Set<Resource> result = new HashSet<Resource>();
+
+ for(final Integer id : resourceIds) {
+ Resource r = findResource(platform, new Resource() {
+ public int getId() {
+ return id;
+ }
+ }, ID_COMPARATOR);
+ if (r != null) {
+ result.add(r);
+
+ if (includeDescendants) {
+ for(Resource child : r.getChildResources()) {
+ result.addAll(getResources(Collections.singleton(child.getId()), true));
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private Resource fakePersist(Resource agentSideResource, InventoryStatus requiredInventoryStatus, Set<String> inProgressUUIds) {
+ Resource persisted = resourceStore.get(agentSideResource.getUuid());
+ if (!inProgressUUIds.add(agentSideResource.getUuid())) {
+ return persisted;
+ }
+ if (persisted == null) {
+ persisted = new Resource();
+ persisted.setId(++counter);
+ persisted.setUuid(agentSideResource.getUuid());
+ resourceStore.put(persisted.getUuid(), persisted);
+ }
+ persisted.setAgent(agentSideResource.getAgent());
+ persisted.setCurrentAvailability(agentSideResource.getCurrentAvailability());
+ persisted.setDescription(agentSideResource.getDescription());
+ persisted.setName(agentSideResource.getName());
+ persisted.setPluginConfiguration(agentSideResource.getPluginConfiguration().clone());
+ persisted.setResourceConfiguration(agentSideResource.getResourceConfiguration().clone());
+ persisted.setVersion(agentSideResource.getVersion());
+ persisted.setInventoryStatus(requiredInventoryStatus);
+ persisted.setResourceKey(agentSideResource.getResourceKey());
+ persisted.setResourceType(agentSideResource.getResourceType());
+
+ Resource parent = agentSideResource.getParentResource();
+ if (parent != null && parent != Resource.ROOT) {
+ persisted.setParentResource(fakePersist(agentSideResource.getParentResource(), requiredInventoryStatus, inProgressUUIds));
+ } else {
+ persisted.setParentResource(parent);
+ }
+
+ Set<Resource> childResources = new HashSet<Resource>();
+ persisted.setChildResources(childResources);
+ for(Resource child : agentSideResource.getChildResources()) {
+ childResources.add(fakePersist(child, requiredInventoryStatus, inProgressUUIds));
+ }
+
+ inProgressUUIds.remove(agentSideResource.getUuid());
+
+ return persisted;
+ }
+
+ private ResourceSyncInfo getSyncInfo() {
+ return platform != null ? convert(platform) : null;
+ }
+
+ private static ResourceSyncInfo convert(Resource root) {
+ try {
+ ResourceSyncInfo ret = new ResourceSyncInfo();
+
+ Class<ResourceSyncInfo> clazz = ResourceSyncInfo.class;
+
+ getPrivateField(clazz, "id").set(ret, root.getId());
+ getPrivateField(clazz, "uuid").set(ret, root.getUuid());
+ getPrivateField(clazz, "mtime").set(ret, root.getMtime());
+ getPrivateField(clazz, "inventoryStatus").set(ret, root.getInventoryStatus());
+ getPrivateField(clazz, "parent").set(ret, null);
+
+ Set<ResourceSyncInfo> children = new LinkedHashSet<ResourceSyncInfo>();
+ for(Resource child : root.getChildResources()) {
+ ResourceSyncInfo syncChild = convert(child);
+ getPrivateField(clazz, "parent").set(syncChild, ret);
+
+ children.add(convert(child));
+ }
+ getPrivateField(clazz, "childSyncInfos").set(ret, children);
+
+ return ret;
+ } catch (Exception e) {
+ fail("Failed to convert resource " + root + " to a ResourceSyncInfo. This should not happen.", e);
+ return null;
+ }
+ }
+
+ private static Field getPrivateField(Class<?> clazz, String fieldName) throws NoSuchFieldException {
+ Field field = clazz.getDeclaredField(fieldName);
+ if (!field.isAccessible()) {
+ field.setAccessible(true);
+ }
+
+ return field;
+ }
+
+ private static Resource findResource(Resource root, Resource template, Comparator<Resource> comparator) {
+ if (root == null) return null;
+ if (comparator.compare(root, template) == 0) {
+ return root;
+ } else {
+ for(Resource child : root.getChildResources()) {
+ Resource found = findResource(child, template, comparator);
+ if (found != null) return found;
+ }
+ }
+
+ return null;
+ }
+
+ private static void findResources(Resource root, Resource template, Set<Resource> result, Comparator<Resource> comparator) {
+ if (root == null) return;
+ if (comparator.compare(root, template) == 0) {
+ result.add(root);
+ } else {
+ for(Resource child : root.getChildResources()) {
+ findResources(child, template, result, comparator);
+ }
+ }
+ }
+}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
new file mode 100644
index 0000000..46d069c
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -0,0 +1,345 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.rhq.core.pc.upgrade;
+
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertEquals;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Set;
+
+import org.apache.commons.io.FileUtils;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import org.rhq.core.clientapi.server.bundle.BundleServerService;
+import org.rhq.core.clientapi.server.configuration.ConfigurationServerService;
+import org.rhq.core.clientapi.server.content.ContentServerService;
+import org.rhq.core.clientapi.server.core.CoreServerService;
+import org.rhq.core.clientapi.server.discovery.DiscoveryServerService;
+import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.clientapi.server.event.EventServerService;
+import org.rhq.core.clientapi.server.inventory.ResourceFactoryServerService;
+import org.rhq.core.clientapi.server.measurement.MeasurementServerService;
+import org.rhq.core.clientapi.server.operation.OperationServerService;
+import org.rhq.core.domain.resource.InventoryStatus;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.pc.PluginContainer;
+import org.rhq.core.pc.PluginContainerConfiguration;
+import org.rhq.core.pc.ServerServices;
+import org.rhq.core.pc.inventory.InventoryManager;
+import org.rhq.core.pc.inventory.ResourceContainer;
+import org.rhq.core.pc.plugin.FileSystemPluginFinder;
+
+/**
+ * Test cases for resource upgrade.
+ *
+ * @author Lukas Krejci
+ */
+public class ResourceUpgradeTest {
+
+ private static final String PLUGIN_V1_FILENAME = "resource-upgrade-test-plugin-1.0.0.jar";
+ private static final String PLUGIN_V2_FILENAME = "resource-upgrade-test-plugin-2.0.0.jar";
+
+ private static final String PLUGINS_DIR_NAME = "plugins";
+ private static final String DATA_DIR_NAME = "data";
+ private static final String TMP_DIR_NAME = "tmp";
+
+ private File tmpDir;
+ private File pluginDir;
+ private File dataDir;
+
+ private BundleServerService currentBundleServerService;
+ private ConfigurationServerService currentConfigurationServerService;
+ private ContentServerService currentContentServerService;
+ private CoreServerService currentCoreServerService;
+ private DiscoveryServerService currentDiscoveryServerService;
+ private EventServerService currentEventServerService;
+ private MeasurementServerService currentMeasurementServerService;
+ private OperationServerService currentOperationServerService;
+ private ResourceFactoryServerService currentResourceFactoryServerService;
+
+ private FakeServerInventory currentServerSideInventory;
+
+ @AfterClass
+ public void undeployPlugins() throws IOException {
+ FileUtils.deleteDirectory(tmpDir);
+ }
+
+ @BeforeClass
+ public void sanityCheck() {
+ verifyPluginExists(PLUGIN_V1_FILENAME);
+ verifyPluginExists(PLUGIN_V2_FILENAME);
+ }
+
+ @BeforeClass
+ public void init() {
+ tmpDir = getTmpDirectory();
+ pluginDir = new File(tmpDir, PLUGINS_DIR_NAME);
+ assertTrue(pluginDir.mkdir(), "Could not create plugin deploy directory.");
+ dataDir = new File(tmpDir, DATA_DIR_NAME);
+ assertTrue(dataDir.mkdir(), "Could not create plugin container data directory.");
+ }
+
+ @Test
+ public void testInitialSyncAndDiscoveryWithoutCommit() throws Exception {
+ testInitialSyncAndDiscovery(InventoryStatus.NEW);
+ }
+
+ @Test(dependsOnMethods = "testInitialSyncAndDiscoveryWithoutCommit")
+ public void testIgnoreUncommittedResources() throws Exception {
+ TestPayload testNoChange = new TestPayload() {
+ public void test(Resource discoveredResource) {
+ assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
+ assertEquals(discoveredResource.getName(), "resource-name-v1");
+ assertEquals(discoveredResource.getDescription(), "resource-description-v1");
+ }
+
+ @SuppressWarnings("unchecked")
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineIgnoredExpectations(this);
+
+ between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+
+ allowing(currentDiscoveryServerService).getResources(with(any(Set.class)), with(any(boolean.class)));
+ will(currentServerSideInventory.getResources());
+ }
+ };
+ }
+ };
+
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, testNoChange);
+ }
+
+ //make the tests run serially, so that they don't overwrite the currentServerSideInventory
+ //variable concurrently
+ @Test(dependsOnMethods = "testIgnoreUncommittedResources")
+ public void testInitialSyncAndDiscoveryWithCommit() throws Exception {
+ testInitialSyncAndDiscovery(InventoryStatus.COMMITTED);
+ }
+
+ @Test(dependsOnMethods = "testInitialSyncAndDiscoveryWithCommit")
+ public void testUpgradeData() throws Exception {
+ //we are keeping the currentServerSideInventory from the previous test
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, new TestPayload() {
+ public void test(Resource discoveredResource) {
+ assertEquals(discoveredResource.getResourceKey(), "resource-key-v2");
+ assertEquals(discoveredResource.getName(), "resource-name-v2");
+ assertEquals(discoveredResource.getDescription(), "resource-description-v2");
+
+ ResourceContainer container = PluginContainer.getInstance().getInventoryManager().getResourceContainer(discoveredResource);
+ File dataDir = container.getResourceContext().getDataDirectory();
+
+ File marker = new File(dataDir, "upgrade-succeeded");
+
+ assertTrue(marker.exists(), "The upgrade success marker file wasn't found. This means the upgrade didn't actually run.");
+ }
+
+ @SuppressWarnings("unchecked")
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineIgnoredExpectations(this);
+
+ between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+
+ oneOf(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
+ will(currentServerSideInventory.upgradeResources());
+
+ allowing(currentDiscoveryServerService).getResources(with(any(Set.class)), with(any(boolean.class)));
+ will(currentServerSideInventory.getResources());
+ }
+ };
+ }
+ });
+ }
+
+ private void testInitialSyncAndDiscovery(final InventoryStatus requiredInventoryStatus) throws Exception {
+ currentServerSideInventory = new FakeServerInventory();
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), true, new TestPayload() {
+ public void test(Resource discoveredResource) {
+ assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
+ assertEquals(discoveredResource.getName(), "resource-name-v1");
+ assertEquals(discoveredResource.getDescription(), "resource-description-v1");
+ }
+
+ @SuppressWarnings("unchecked")
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineIgnoredExpectations(this);
+
+ between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(currentServerSideInventory.mergeInventoryReport(requiredInventoryStatus));
+
+ allowing(currentDiscoveryServerService).getResources(with(any(Set.class)), with(any(boolean.class)));
+ will(currentServerSideInventory.getResources());
+ }
+ };
+ }
+ });
+
+ }
+
+ private PluginContainerConfiguration createPluginContainerConfiguration(Mockery context) throws Exception {
+ PluginContainerConfiguration conf = new PluginContainerConfiguration();
+
+ conf.setPluginDirectory(new File(tmpDir, PLUGINS_DIR_NAME));
+ conf.setDataDirectory(new File(tmpDir, DATA_DIR_NAME));
+ conf.setTemporaryDirectory(new File(tmpDir, TMP_DIR_NAME));
+ conf.setInsideAgent(true); //pc must think it's inside an agent so that it persists the inventory between restarts
+ conf.setPluginFinder(new FileSystemPluginFinder(conf.getPluginDirectory()));
+ conf.setCreateResourceClassloaders(false);
+
+ currentBundleServerService = context.mock(BundleServerService.class);
+ currentConfigurationServerService = context.mock(ConfigurationServerService.class);
+ currentContentServerService = context.mock(ContentServerService.class);
+ currentCoreServerService = context.mock(CoreServerService.class);
+ currentDiscoveryServerService = context.mock(DiscoveryServerService.class);
+ currentEventServerService = context.mock(EventServerService.class);
+ currentMeasurementServerService = context.mock(MeasurementServerService.class);
+ currentOperationServerService = context.mock(OperationServerService.class);
+ currentResourceFactoryServerService = context.mock(ResourceFactoryServerService.class);
+
+ ServerServices serverServices = new ServerServices();
+ serverServices.setBundleServerService(currentBundleServerService);
+ serverServices.setConfigurationServerService(currentConfigurationServerService);
+ serverServices.setContentServerService(currentContentServerService);
+ serverServices.setCoreServerService(currentCoreServerService);
+ serverServices.setDiscoveryServerService(currentDiscoveryServerService);
+ serverServices.setEventServerService(currentEventServerService);
+ serverServices.setMeasurementServerService(currentMeasurementServerService);
+ serverServices.setOperationServerService(currentOperationServerService);
+ serverServices.setResourceFactoryServerService(currentResourceFactoryServerService);
+
+ conf.setServerServices(serverServices);
+
+ return conf;
+ }
+
+ /**
+ * @param pluginResourcePath
+ */
+ private void verifyPluginExists(String pluginResourcePath) {
+ URL url = getClass().getResource(pluginResourcePath);
+
+ File pluginFile = FileUtils.toFile(url);
+
+ assertTrue(pluginFile.exists(), pluginFile.getAbsoluteFile() + " plugin jar could not be found.");
+ }
+
+ private void copyPlugin(String pluginResourcePath, File pluginDirectory) throws IOException {
+ URL pluginUrl = getClass().getResource(pluginResourcePath);
+
+ File pluginFile = new File(pluginResourcePath);
+ String pluginFileName = pluginFile.getName();
+
+ FileUtils.copyURLToFile(pluginUrl, new File(pluginDirectory, pluginFileName));
+ }
+
+ private static File getTmpDirectory() {
+ File ret = new File(System.getProperty("java.io.tmpdir"), "resource-upgrade-test" + System.currentTimeMillis());
+
+ while (ret.exists() || !ret.mkdir()) {
+ ret = new File(System.getProperty("java.io.tmpdir"), "resource-upgrade-test" + System.currentTimeMillis());
+ }
+
+ return ret;
+ }
+
+ private interface TestPayload {
+ Expectations getExpectations(Mockery context) throws Exception;
+ void test(Resource resourceUpgradeTestResource);
+ }
+
+ private Set<Resource> getTestingResources() {
+ ResourceType resType = PluginContainer.getInstance().getPluginManager().getMetadataManager().getType("Resource", "ResourceUpgradeTest");
+
+ return currentServerSideInventory.findResourcesByType(resType);
+ }
+
+ private void executeTestWithPlugins(Set<String> pluginResourcePaths, boolean clearInventoryDat, TestPayload test) throws Exception {
+ FileUtils.cleanDirectory(new File(tmpDir, PLUGINS_DIR_NAME));
+
+ for(String pluginResourcePath : pluginResourcePaths) {
+ copyPlugin(pluginResourcePath, pluginDir);
+ }
+
+ Mockery context = new Mockery();
+
+ PluginContainerConfiguration pcConfig = createPluginContainerConfiguration(context);
+
+ if (clearInventoryDat) {
+ File inventoryDat = new File(pcConfig.getDataDirectory(), "inventory.dat");
+ inventoryDat.delete();
+ }
+
+ context.checking(test.getExpectations(context));
+
+ PluginContainer.getInstance().setConfiguration(pcConfig);
+ PluginContainer.getInstance().initialize();
+
+ //give the pc the time to finish resource upgrade
+ Thread.sleep(1000);
+
+ //execute full discovery
+ InventoryManager im = PluginContainer.getInstance().getInventoryManager();
+ im.executeServerScanImmediately();
+ im.executeServiceScanImmediately();
+
+ Set<Resource> resources = getTestingResources();
+
+ assertEquals(resources.size(), 1, "There should be only a single testing resource but " + resources + " were found.");
+
+ Resource discoveredResource = resources.iterator().next();
+
+ test.test(discoveredResource);
+
+ PluginContainer.getInstance().shutdown();
+
+ context.assertIsSatisfied();
+ }
+
+ private void defineIgnoredExpectations(Expectations expectations) {
+ expectations.ignoring(currentBundleServerService);
+ expectations.ignoring(currentConfigurationServerService);
+ expectations.ignoring(currentContentServerService);
+ expectations.ignoring(currentCoreServerService);
+ expectations.ignoring(currentEventServerService);
+ expectations.ignoring(currentMeasurementServerService);
+ expectations.ignoring(currentOperationServerService);
+ expectations.ignoring(currentResourceFactoryServerService);
+ }
+}
diff --git a/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-1.0.0.jar b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-1.0.0.jar
new file mode 100644
index 0000000..33a79c0
Binary files /dev/null and b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-1.0.0.jar differ
diff --git a/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar
new file mode 100644
index 0000000..412ae00
Binary files /dev/null and b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar differ
commit 8dae62e89bc703cf2b8e16272b8d9ebc912606dd
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Jun 18 20:22:33 2010 +0200
Correctly handle the upgrade sync up when the agent is connected to the server for the very first time.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 54c6bcc..dbee063 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -900,7 +900,6 @@ public class InventoryManager extends AgentService implements ContainerService,
*/
public boolean handleReport(InventoryReport report, boolean forceServerRoundtrip) {
if (!configuration.isInsideAgent()) {
- //TODO how does resource upgrade behave in the embedded scenario?
return true;
}
@@ -943,7 +942,14 @@ public class InventoryManager extends AgentService implements ContainerService,
return false;
}
- synchInventory(syncInfo);
+ //sync info can be null if the server hasn't received a full inventory report
+ //from us yet. This can happen if this method is being invoked from inside the
+ //resource upgrade executor to sync up with the server side inventory *JUST AFTER*
+ //this agent registered with the server for the very first time. In that case
+ //the server hasn't received any info from us yet.
+ if (syncInfo != null) {
+ synchInventory(syncInfo);
+ }
return true;
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index 76d6265..fd59590 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -156,7 +156,13 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
// Prepare the ResourceSyncInfo tree which contains all the info the PC needs to sync itself up with us.
Resource platform = this.resourceManager.getPlatform(knownAgent);
- ResourceSyncInfo syncInfo = this.entityManager.find(ResourceSyncInfo.class, platform.getId());
+
+ //the platform can be null in only one scenario.. a brand new agent has connected to the server
+ //and that agent is currently trying to upgrade its resources. For that it asks us to send down
+ //the current inventory on the server side. But at this point there isn't any since that very
+ //agent just registered and is starting up for the very first time and therefore hasn't had
+ //a chance yet to send us its full inventory report.
+ ResourceSyncInfo syncInfo = platform != null ? this.entityManager.find(ResourceSyncInfo.class, platform.getId()) : null;
if (log.isDebugEnabled()) {
log.debug("Inventory merge completed in (" + (System.currentTimeMillis() - start) + ")ms");
commit a9622206993586ce28df9e586206cbf981cc7c3b
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri May 28 18:09:24 2010 +0200
Filter out not-commited resources from the upgrade process.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
index 3397e76..bb20054 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
@@ -26,6 +26,7 @@ package org.rhq.core.pc.upgrade;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -37,6 +38,7 @@ import org.apache.commons.logging.LogFactory;
import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.ResourceUpgradeReport;
@@ -203,6 +205,15 @@ public class ResourceUpgradeExecutor implements Runnable {
Set<Resource> siblings = parentResource == null ? Collections.singleton(inventoryManager.getPlatform())
: inventoryManager.getResourcesWithType(resourceType, parentResource.getChildResources());
+ //filter out not committed resources
+ //XXX what about uninventoried or ignored ones? is it correct to not upgrade those?
+ Iterator<Resource> siblingsIterator = siblings.iterator();
+ while (siblingsIterator.hasNext()) {
+ if (siblingsIterator.next().getInventoryStatus() != InventoryStatus.COMMITTED) {
+ siblingsIterator.remove();
+ }
+ }
+
//get the upgrade context of the parent resource so that it can be passed to the upgrade method
//of the discovery component.
ResourceUpgradeContext<?> parentUpgradeContext = null;
commit df4ffc41f2554332ba870eaeb69e20017ea25240
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri May 28 18:08:53 2010 +0200
Improve resource upgrade logging on both agent and server side.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index ba5f316..54c6bcc 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -1194,36 +1194,50 @@ public class InventoryManager extends AgentService implements ContainerService,
//Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
//Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
- ResourceContainer existingResourceContainer = getResourceContainer(upgradeReport.getResourceId());
- if (existingResourceContainer != null) {
- Resource existingResource = existingResourceContainer.getResource();
- if (resourceKey != null) {
- existingResource.setResourceKey(resourceKey);
- }
-
- if (name != null) {
- existingResource.setName(name);
- }
-
-// if (version != null) {
-// existingResource.setVersion(version);
-// }
-
- if (description != null) {
- existingResource.setDescription(description);
+ //only bother if there's something to upgrade at all on this resource.
+ if (resourceKey != null || name != null || description != null) {
+ ResourceContainer existingResourceContainer = getResourceContainer(upgradeReport.getResourceId());
+ if (existingResourceContainer != null) {
+ Resource existingResource = existingResourceContainer.getResource();
+
+ StringBuilder logMessage = new StringBuilder("Resource [")
+ .append(existingResource.toString()).append("] upgraded its ");
+
+ if (resourceKey != null) {
+ existingResource.setResourceKey(resourceKey);
+ logMessage.append("resourceKey, ");
+ }
+
+ if (name != null) {
+ existingResource.setName(name);
+ logMessage.append("name, ");
+ }
+
+// if (version != null) {
+// existingResource.setVersion(version);
+// }
+
+ if (description != null) {
+ existingResource.setDescription(description);
+ logMessage.append("description, ");
+ }
+
+// if (pluginConfiguration != null) {
+// existingResource.setPluginConfiguration(pluginConfiguration);
+// }
+//
+// if (resourceConfiguration != null) {
+// existingResource.setResourceConfiguration(resourceConfiguration);
+// }
+
+ logMessage.replace(logMessage.length() - 1, logMessage.length(),
+ "to become [").append(existingResource.toString()).append("]");
+
+ log.info(logMessage.toString());
+ } else {
+ log.error("Upgraded a resource that is not present on the agent. This should not happen. The id of the missing resource is " + upgradeReport.getResourceId());
}
-
-// if (pluginConfiguration != null) {
-// existingResource.setPluginConfiguration(pluginConfiguration);
-// }
-//
-// if (resourceConfiguration != null) {
-// existingResource.setResourceConfiguration(resourceConfiguration);
-// }
- } else {
- log.error("Upgraded a resource that is not present on the agent. This should not happen. The id of the missing resource is " + upgradeReport.getResourceId());
}
-
}
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index 1101199..76d6265 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -465,65 +465,70 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
/**
* @param existingResource
* @param upgradeReport
- * @return
+ * @return true if the resource was changed, false otherwise
*/
private boolean upgradeResource(Resource resource, ResourceUpgradeReport upgradeReport) {
- boolean changed = false;
if (resource != null) {
String resourceKey = upgradeReport.getNewResourceKey();
String name = upgradeReport.getNewName();
- //String version = upgradeReport.getNewVersion();
+// String version = upgradeReport.getNewVersion();
String description = upgradeReport.getNewDescription();
// Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
// Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
- if (needsUpgrade(resource.getResourceKey(), resourceKey)) {
- log.info("Resource [" + resource + "] upgraded its resource key from [" +
- resource.getResourceKey() + "] to [" + resourceKey + "]");
- changed = true;
- resource.setResourceKey(resourceKey);
- }
-
- if (needsUpgrade(resource.getName(), name)) {
- log.info("Resource [" + resource + "] upgraded its name from [" +
- resource.getName() + "] to [" + name + "]");
- changed = true;
- resource.setName(name);
- }
-
-// if (version != null) {
-// changed = updateResourceVersion(resource, version) || changed;
-// }
-
- if (needsUpgrade(resource.getDescription(), description)) {
- log.info("Resource [" + resource + "] upgraded its description from [" +
- resource.getDescription() + "] to [" + description + "]");
- changed = true;
- resource.setDescription(description);
- }
-
-// if (pluginConfiguration != null) {
-// if (!equalOrNull(pluginConfiguration, resource.getPluginConfiguration())) {
-// log.info("Resource [" + resource + "] upgraded its plugin configuration from [" +
-// resource.getPluginConfiguration() + "] to [" + pluginConfiguration + "]");
-// changed = true;
-// resource.setPluginConfiguration(pluginConfiguration);
+ if (resourceKey != null || name != null || description != null) {
+ StringBuilder logMessage = new StringBuilder("Resource [")
+ .append(resource.toString()).append("] upgraded its ");
+
+ if (needsUpgrade(resource.getResourceKey(), resourceKey)) {
+ resource.setResourceKey(resourceKey);
+ logMessage.append("resourceKey, ");
+ }
+
+ if (needsUpgrade(resource.getName(), name)) {
+ resource.setName(name);
+ logMessage.append("name, ");
+ }
+
+// if (version != null) {
+// changed = updateResourceVersion(resource, version) || changed;
// }
-// }
-//
-// if (resourceConfiguration != null) {
-// if (!equalOrNull(resourceConfiguration, resource.getResourceConfiguration())) {
-// //XXX Will this create a new history entry?
-//
-// log.info("Resource [" + resource + "] upgraded its resource configuration from [" +
-// resource.getResourceConfiguration() + "] to [" + resourceConfiguration + "]");
-//
-// changed = true;
-// resource.setResourceConfiguration(resourceConfiguration);
+
+ if (needsUpgrade(resource.getDescription(), description)) {
+ resource.setDescription(description);
+ logMessage.append("description, ");
+ }
+
+// if (pluginConfiguration != null) {
+// if (!equalOrNull(pluginConfiguration, resource.getPluginConfiguration())) {
+// log.info("Resource [" + resource + "] upgraded its plugin configuration from [" +
+// resource.getPluginConfiguration() + "] to [" + pluginConfiguration + "]");
+// changed = true;
+// resource.setPluginConfiguration(pluginConfiguration);
+// }
// }
-// }
+//
+// if (resourceConfiguration != null) {
+// if (!equalOrNull(resourceConfiguration, resource.getResourceConfiguration())) {
+// //XXX Will this create a new history entry?
+//
+// log.info("Resource [" + resource + "] upgraded its resource configuration from [" +
+// resource.getResourceConfiguration() + "] to [" + resourceConfiguration + "]");
+//
+// changed = true;
+// resource.setResourceConfiguration(resourceConfiguration);
+// }
+// }
+
+ logMessage.replace(logMessage.length() - 1, logMessage.length(),
+ "to become [").append(resource.toString()).append("]");
+
+ log.info(logMessage.toString());
+
+ return true;
+ }
}
- return changed;
+ return false;
}
private void validateInventoryReport(InventoryReport report) throws InvalidInventoryReportException {
@@ -875,18 +880,6 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
updateInventoryStatus(subject, platforms, servers, target);
}
- private static <T> boolean equalOrNull(T a, T b) {
- if (a == null) {
- return b == null;
- } else {
- if (b == null) {
- return false;
- } else {
- return a.equals(b);
- }
- }
- }
-
private static <T> boolean needsUpgrade(T oldValue, T newValue) {
return newValue != null && (oldValue == null || !newValue.equals(oldValue));
}
commit d896c3792ebf8b45938972eb2ff2f45bd990be83
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri May 28 18:08:16 2010 +0200
Run a method in a new thread only if it originates in the interface that is being proxied.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/DiscoveryComponentProxyFactory.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/DiscoveryComponentProxyFactory.java
index f8d1267..4c68970 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/DiscoveryComponentProxyFactory.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/DiscoveryComponentProxyFactory.java
@@ -81,7 +81,7 @@ public class DiscoveryComponentProxyFactory {
// This is the handler that will actually invoke the method calls.
ResourceDiscoveryComponentInvocationHandler handler = new ResourceDiscoveryComponentInvocationHandler(type,
- component, timeout, pluginClassLoader);
+ component, timeout, pluginClassLoader, componentInterface);
// This is the proxy that will look like the discovery component object that the caller will use.
T proxy = (T) Proxy.newProxyInstance(pluginClassLoader, new Class<?>[] { componentInterface }, handler);
@@ -167,9 +167,10 @@ public class DiscoveryComponentProxyFactory {
private final long timeout;
private final ResourceType resourceType;
private final ClassLoader pluginClassLoader;
-
+ private Class<?> componentInterface;
+
public ResourceDiscoveryComponentInvocationHandler(ResourceType type, ResourceDiscoveryComponent component,
- long timeout, ClassLoader pluginClassLoader) {
+ long timeout, ClassLoader pluginClassLoader, Class<?> componentInterface) {
if (timeout <= 0) {
throw new IllegalArgumentException("timeout value is not positive.");
}
@@ -181,6 +182,7 @@ public class DiscoveryComponentProxyFactory {
this.component = component;
this.timeout = timeout;
this.pluginClassLoader = pluginClassLoader;
+ this.componentInterface = componentInterface;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
@@ -189,7 +191,7 @@ public class DiscoveryComponentProxyFactory {
+ "] has been blacklisted and can no longer be invoked.");
}
- if (method.getDeclaringClass().getPackage().getName().startsWith("org.rhq")) {
+ if (componentInterface.isAssignableFrom(method.getDeclaringClass())) {
return invokeInNewThread(method, args);
} else {
// toString(), etc.
commit 708dee442c2519ecc9d27c723e79239b14b25455
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu May 27 19:04:32 2010 +0200
Fixing a stupid bug that would cause no initial sync to happen during upgrade.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 83743d9..ba5f316 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -883,13 +883,22 @@ public class InventoryManager extends AgentService implements ContainerService,
}
/**
+ * @see #handleReport(InventoryReport, boolean)
+ * @param report
+ * @return
+ */
+ public boolean handleReport(InventoryReport report) {
+ return handleReport(report, false);
+ }
+
+ /**
* Send an inventory report to the Server.
*
* @param report the inventory report to be sent
- *
+ * @param forceServerRoundtrip whether to report to the server even if there are no resources to report.
* @return true if sending the report to the Server succeeded, or false otherwise
*/
- public boolean handleReport(InventoryReport report) {
+ public boolean handleReport(InventoryReport report, boolean forceServerRoundtrip) {
if (!configuration.isInsideAgent()) {
//TODO how does resource upgrade behave in the embedded scenario?
return true;
@@ -905,7 +914,7 @@ public class InventoryManager extends AgentService implements ContainerService,
resourceUpgradeExecutor.sendRequests();
}
- if (report.getAddedRoots().isEmpty()) {
+ if (report.getAddedRoots().isEmpty() && !forceServerRoundtrip) {
return true; // nothing to do
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
index f0721cb..3397e76 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
@@ -130,7 +130,7 @@ public class ResourceUpgradeExecutor implements Runnable {
//pull the inventory down from the server.
//this will ensure that we have an up-to-date info on the
//server inventory before we try to upgrade.
- boolean syncResult = inventoryManager.handleReport(new InventoryReport(inventoryManager.getAgent()));
+ boolean syncResult = inventoryManager.handleReport(new InventoryReport(inventoryManager.getAgent()), true);
if (!syncResult) {
log.warn("Resource upgrade failed to sync up the inventory with the server.");
return;
commit c9b82d93170e03e564ef2db2c50a007f4d1176dc
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu May 27 18:39:32 2010 +0200
Make the ResourceUpgradeExecutor thread safe (even though it probably shouldn't have to be) and make sure it can only be run once.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java
index 21da6bc..4d61e93 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java
@@ -264,7 +264,7 @@ public class PluginContainer implements ContainerService {
//fire off the resource upgrade as soon as possible. It will run only once per plugin container
//lifetime.
- inventoryManager.executeResourceUpgradeImmediately();
+ inventoryManager.fireResourceUpgrade();
return;
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 7fcfd6e..83743d9 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -507,8 +507,13 @@ public class InventoryManager extends AgentService implements ContainerService,
}
}
- public void executeResourceUpgradeImmediately() {
- resourceUpgradeExecutor.execute();
+ /**
+ * Executes the resource upgrade asynchronously.
+ */
+ public void fireResourceUpgrade() {
+ Thread resourceUpgradeThread = new Thread(resourceUpgradeExecutor, "Resource Upgrade Thread");
+ resourceUpgradeThread.setDaemon(true);
+ resourceUpgradeThread.start();
}
public InventoryReport executeServerScanImmediately() {
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
index d15a1c2..f0721cb 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
@@ -27,9 +27,10 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
-import java.util.Queue;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -55,21 +56,22 @@ import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
*
* @author Lukas Krejci
*/
-public class ResourceUpgradeExecutor {
+public class ResourceUpgradeExecutor implements Runnable {
private static final Log log = LogFactory.getLog(ResourceUpgradeExecutor.class);
/**
* The upgrade runs only once in its lifetime.
*/
- private boolean enabled = true;
-
+ private AtomicBoolean enabled = new AtomicBoolean(true);
+ private AtomicBoolean started = new AtomicBoolean(false);
+
private InventoryManager inventoryManager;
- private Set<ResourceUpgradeReport> reports;
+ private ConcurrentLinkedQueue<ResourceUpgradeReport> reports;
public ResourceUpgradeExecutor(InventoryManager inventoryManager) {
this.inventoryManager = inventoryManager;
- reports = new HashSet<ResourceUpgradeReport>();
+ reports = new ConcurrentLinkedQueue<ResourceUpgradeReport>();
}
/**
@@ -90,14 +92,14 @@ public class ResourceUpgradeExecutor {
public <T extends ResourceComponent> Map<ResourceUpgradeContext<T>, ResourceUpgradeReport> processAndQueue(
ResourceUpgradeRequest<T> request, Set<Resource> discoveredResources) {
- return enabled ? executeResourceUpgradeAndStoreReport(request, discoveredResources) : null;
+ return enabled.get() ? executeResourceUpgradeAndStoreReport(request, discoveredResources) : null;
}
/**
* @return true if the executor is ready to perform the upgrade, false otherwise.
*/
public boolean isEnabled() {
- return enabled;
+ return enabled.get();
}
/**
@@ -105,9 +107,10 @@ public class ResourceUpgradeExecutor {
* all the upgrade requests.
*/
public void sendRequests() {
- if (enabled && reports.size() > 0) {
- inventoryManager.mergeResourceFromUpgrade(reports);
- reports.clear();
+ if (enabled.get() && reports.size() > 0) {
+ HashSet<ResourceUpgradeReport> currentCopy = new HashSet<ResourceUpgradeReport>(reports);
+ inventoryManager.mergeResourceFromUpgrade(currentCopy);
+ reports.removeAll(currentCopy);
}
}
@@ -117,8 +120,8 @@ public class ResourceUpgradeExecutor {
* After that a full discovery is performed and both the upgrade report and discovery report
* are sent to the server.
*/
- public void execute() {
- if (enabled) {
+ public void run() {
+ if (!started.getAndSet(true)) {
if (log.isDebugEnabled()) {
log.debug("Starting resource upgrade.");
}
@@ -140,7 +143,7 @@ public class ResourceUpgradeExecutor {
log.warn("Resource upgrade failed.", t);
} finally {
//make sure to switch off the upgrade...
- this.enabled = false;
+ this.enabled.set(false);
//clear up so that we don't hold unnecessary instances.
reports.clear();
commit 760871c264eca5adf2cf322a48614b3cd68a3640
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu May 27 18:11:49 2010 +0200
Avoid deadlock by invoking the resource upgrade only after all services are initialized, removing the ability to perform plugin/resource configuration upgrades, generally made stuff work.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
index bfeba0d..979c456 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
@@ -44,9 +44,18 @@ public class ResourceUpgradeReport implements Serializable {
private int resourceId;
private String newResourceKey;
private String newName;
- private String newVersion;
- private Configuration newPluginConfiguration;
- private Configuration newResourceConfiguration;
+
+// version changes are handled differently.
+// private String newVersion;
+
+// upgrading configurations would have large consequences.
+// it would be difficult to synchronize the upgrade process
+// with the agent or server initiated configuration updates.
+// It could also be difficult for the UI to reflect more complicated
+// structural changes as currently, it is assumed that
+// the configurations are kept backwards compatible.
+// private Configuration newPluginConfiguration;
+// private Configuration newResourceConfiguration;
private String newDescription;
public ResourceUpgradeReport() {
@@ -85,29 +94,29 @@ public class ResourceUpgradeReport implements Serializable {
this.newName = newName;
}
- public String getNewVersion() {
- return newVersion;
- }
-
- public void setNewVersion(String newVersion) {
- this.newVersion = newVersion;
- }
-
- public Configuration getNewPluginConfiguration() {
- return newPluginConfiguration;
- }
-
- public void setNewPluginConfiguration(Configuration newPluginConfiguration) {
- this.newPluginConfiguration = newPluginConfiguration;
- }
-
- public Configuration getNewResourceConfiguration() {
- return newResourceConfiguration;
- }
-
- public void setNewResourceConfiguration(Configuration newResourceConfiguration) {
- this.newResourceConfiguration = newResourceConfiguration;
- }
+// public String getNewVersion() {
+// return newVersion;
+// }
+//
+// public void setNewVersion(String newVersion) {
+// this.newVersion = newVersion;
+// }
+//
+// public Configuration getNewPluginConfiguration() {
+// return newPluginConfiguration;
+// }
+//
+// public void setNewPluginConfiguration(Configuration newPluginConfiguration) {
+// this.newPluginConfiguration = newPluginConfiguration;
+// }
+//
+// public Configuration getNewResourceConfiguration() {
+// return newResourceConfiguration;
+// }
+//
+// public void setNewResourceConfiguration(Configuration newResourceConfiguration) {
+// this.newResourceConfiguration = newResourceConfiguration;
+// }
public String getNewDescription() {
return newDescription;
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java
index 8970404..21da6bc 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java
@@ -262,6 +262,10 @@ public class PluginContainer implements ContainerService {
releaseLock(lock);
}
+ //fire off the resource upgrade as soon as possible. It will run only once per plugin container
+ //lifetime.
+ inventoryManager.executeResourceUpgradeImmediately();
+
return;
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 044aa25..7fcfd6e 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -250,16 +250,7 @@ public class InventoryManager extends AgentService implements ContainerService,
.getServiceDiscoveryInitialDelay(), configuration.getServiceDiscoveryPeriod(), TimeUnit.SECONDS);
}
- //try to perform the full resource upgrade now.
- //The initialization time is ideal for this because inventory manager
- //is the first plugin container service to start and hence we can
- //be sure that no under concurrent updates to the resources are happening.
- //Because PC doesn't support online updates of plugins and needs to be restarted
- //in order to pick up the changed plugins, we can be sure that running the
- //upgrade only once at the PC start up is enough for the lifetime of
- //plugin container (and hence this instance of InventoryManager).
resourceUpgradeExecutor = new ResourceUpgradeExecutor(this);
- resourceUpgradeExecutor.execute();
} finally {
inventoryLock.writeLock().unlock();
}
@@ -516,6 +507,10 @@ public class InventoryManager extends AgentService implements ContainerService,
}
}
+ public void executeResourceUpgradeImmediately() {
+ resourceUpgradeExecutor.execute();
+ }
+
public InventoryReport executeServerScanImmediately() {
try {
return inventoryThreadPoolExecutor.submit((Callable<InventoryReport>) this.serverScanExecutor).get();
@@ -1180,10 +1175,10 @@ public class InventoryManager extends AgentService implements ContainerService,
for (ResourceUpgradeReport upgradeReport : upgradeReports) {
String resourceKey = upgradeReport.getNewResourceKey();
String name = upgradeReport.getNewName();
- String version = upgradeReport.getNewVersion();
+ //String version = upgradeReport.getNewVersion();
String description = upgradeReport.getNewDescription();
- Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
- Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
+ //Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
+ //Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
ResourceContainer existingResourceContainer = getResourceContainer(upgradeReport.getResourceId());
if (existingResourceContainer != null) {
@@ -1196,21 +1191,21 @@ public class InventoryManager extends AgentService implements ContainerService,
existingResource.setName(name);
}
- if (version != null) {
- existingResource.setVersion(version);
- }
+// if (version != null) {
+// existingResource.setVersion(version);
+// }
if (description != null) {
existingResource.setDescription(description);
}
- if (pluginConfiguration != null) {
- existingResource.setPluginConfiguration(pluginConfiguration);
- }
-
- if (resourceConfiguration != null) {
- existingResource.setResourceConfiguration(resourceConfiguration);
- }
+// if (pluginConfiguration != null) {
+// existingResource.setPluginConfiguration(pluginConfiguration);
+// }
+//
+// if (resourceConfiguration != null) {
+// existingResource.setResourceConfiguration(resourceConfiguration);
+// }
} else {
log.error("Upgraded a resource that is not present on the agent. This should not happen. The id of the missing resource is " + upgradeReport.getResourceId());
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
index b00dfd4..d15a1c2 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
@@ -69,6 +69,7 @@ public class ResourceUpgradeExecutor {
public ResourceUpgradeExecutor(InventoryManager inventoryManager) {
this.inventoryManager = inventoryManager;
+ reports = new HashSet<ResourceUpgradeReport>();
}
/**
@@ -104,8 +105,9 @@ public class ResourceUpgradeExecutor {
* all the upgrade requests.
*/
public void sendRequests() {
- if (enabled) {
+ if (enabled && reports.size() > 0) {
inventoryManager.mergeResourceFromUpgrade(reports);
+ reports.clear();
}
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index 44f79a2..1101199 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -472,67 +472,56 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
if (resource != null) {
String resourceKey = upgradeReport.getNewResourceKey();
String name = upgradeReport.getNewName();
- String version = upgradeReport.getNewVersion();
+ //String version = upgradeReport.getNewVersion();
String description = upgradeReport.getNewDescription();
- Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
- Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
+// Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
+// Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
- if (resourceKey != null) {
- if (!equalOrNull(resourceKey, resource.getResourceKey())) {
- log.info("Resource [" + resource + "] upgraded its resource key from [" +
- resource.getResourceKey() + "] to [" + resourceKey + "]");
- changed = true;
- resource.setResourceKey(resourceKey);
- }
- }
-
- if (name != null) {
- if (!equalOrNull(name, resource.getName())) {
- log.info("Resource [" + resource + "] upgraded its name from [" +
- resource.getName() + "] to [" + name + "]");
- changed = true;
- resource.setName(name);
- }
- }
-
- if (version != null) {
- changed = updateResourceVersion(resource, version) || changed;
+ if (needsUpgrade(resource.getResourceKey(), resourceKey)) {
+ log.info("Resource [" + resource + "] upgraded its resource key from [" +
+ resource.getResourceKey() + "] to [" + resourceKey + "]");
+ changed = true;
+ resource.setResourceKey(resourceKey);
}
- if (description != null) {
- if (!equalOrNull(description, resource.getDescription())) {
- log.info("Resource [" + resource + "] upgraded its description from [" +
- resource.getDescription() + "] to [" + description + "]");
- changed = true;
- resource.setDescription(description);
- }
+ if (needsUpgrade(resource.getName(), name)) {
+ log.info("Resource [" + resource + "] upgraded its name from [" +
+ resource.getName() + "] to [" + name + "]");
+ changed = true;
+ resource.setName(name);
}
- if (pluginConfiguration != null) {
- if (!equalOrNull(pluginConfiguration, resource.getPluginConfiguration())) {
- log.info("Resource [" + resource + "] upgraded its plugin configuration from [" +
- resource.getPluginConfiguration() + "] to [" + pluginConfiguration + "]");
- changed = true;
- resource.setPluginConfiguration(pluginConfiguration);
- }
- }
+// if (version != null) {
+// changed = updateResourceVersion(resource, version) || changed;
+// }
- if (resourceConfiguration != null) {
- if (!equalOrNull(resourceConfiguration, resource.getResourceConfiguration())) {
- //XXX Will this create a new history entry?
-
- log.info("Resource [" + resource + "] upgraded its resource configuration from [" +
- resource.getResourceConfiguration() + "] to [" + resourceConfiguration + "]");
-
- changed = true;
- resource.setResourceConfiguration(resourceConfiguration);
- }
+ if (needsUpgrade(resource.getDescription(), description)) {
+ log.info("Resource [" + resource + "] upgraded its description from [" +
+ resource.getDescription() + "] to [" + description + "]");
+ changed = true;
+ resource.setDescription(description);
}
- // If the resource was marked as deleted, reactivate it again.
- if (resource.getInventoryStatus() == InventoryStatus.DELETED) {
- resource.setInventoryStatus(InventoryStatus.COMMITTED);
- }
+// if (pluginConfiguration != null) {
+// if (!equalOrNull(pluginConfiguration, resource.getPluginConfiguration())) {
+// log.info("Resource [" + resource + "] upgraded its plugin configuration from [" +
+// resource.getPluginConfiguration() + "] to [" + pluginConfiguration + "]");
+// changed = true;
+// resource.setPluginConfiguration(pluginConfiguration);
+// }
+// }
+//
+// if (resourceConfiguration != null) {
+// if (!equalOrNull(resourceConfiguration, resource.getResourceConfiguration())) {
+// //XXX Will this create a new history entry?
+//
+// log.info("Resource [" + resource + "] upgraded its resource configuration from [" +
+// resource.getResourceConfiguration() + "] to [" + resourceConfiguration + "]");
+//
+// changed = true;
+// resource.setResourceConfiguration(resourceConfiguration);
+// }
+// }
}
return changed;
}
@@ -897,4 +886,8 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
}
}
}
+
+ private static <T> boolean needsUpgrade(T oldValue, T newValue) {
+ return newValue != null && (oldValue == null || !newValue.equals(oldValue));
+ }
}
\ No newline at end of file
commit 1fe97fb0bb997c5e6c023adca8bb94da0fca7c79
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu May 27 16:18:21 2010 +0200
Actually call out back to inv manager to perform the upgrade.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
index f0f2b43..b00dfd4 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
@@ -105,7 +105,7 @@ public class ResourceUpgradeExecutor {
*/
public void sendRequests() {
if (enabled) {
- //TODO implement
+ inventoryManager.mergeResourceFromUpgrade(reports);
}
}
commit d0d2e582e00344b1720ee9d01a730fa1d1c3cb46
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu May 27 15:58:35 2010 +0200
reimplemented the upgrade process on the agent to happen only at init time. the server receives a full batch of upgrades, not one upgrade after another.
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
index cfa2459..61e5084 100644
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
@@ -138,13 +138,12 @@ public interface DiscoveryServerService {
boolean updateResourceVersion(int resourceId, String version);
/**
- * Upgrades the data of the resource according to the provided report.
+ * Upgrades the data of the resources according to the provided reports.
*
- * @param resourceId the id of the resource to be upgraded
- * @param upgradeReport contains the information about the upgrade
+ * @param upgradeReports contains the information about the upgrade of individual resources.
* @return true if the upgrade succeeded, false otherwise.
*/
- boolean upgradeResource(int resourceId, ResourceUpgradeReport upgradeReport);
+ boolean upgradeResources(Set<ResourceUpgradeReport> upgradeReports);
/**
* Gives the server a chance to apply any necessary post-processing that's needed for newly committed resources
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
index 52acf09..bfeba0d 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
@@ -41,6 +41,7 @@ public class ResourceUpgradeReport implements Serializable {
private static final long serialVersionUID = 1L;
+ private int resourceId;
private String newResourceKey;
private String newName;
private String newVersion;
@@ -52,6 +53,22 @@ public class ResourceUpgradeReport implements Serializable {
}
+ /**
+ * The server-side id of the resource being upgraded.
+ * The discovery components don't need to assign this value.
+ */
+ public int getResourceId() {
+ return resourceId;
+ }
+
+ /**
+ * The server-side id of the resource being upgraded.
+ * The discovery components don't need to assign this value.
+ */
+ public void setResourceId(int resourceId) {
+ this.resourceId = resourceId;
+ }
+
public String getNewResourceKey() {
return newResourceKey;
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 032256b..044aa25 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -33,9 +33,11 @@ import java.util.IdentityHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
+import java.util.Queue;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@@ -89,6 +91,8 @@ import org.rhq.core.pc.plugin.BlacklistedException;
import org.rhq.core.pc.plugin.CanonicalResourceKey;
import org.rhq.core.pc.plugin.PluginComponentFactory;
import org.rhq.core.pc.plugin.PluginManager;
+import org.rhq.core.pc.upgrade.ResourceUpgradeExecutor;
+import org.rhq.core.pc.upgrade.ResourceUpgradeRequest;
import org.rhq.core.pc.util.DiscoveryComponentProxyFactory;
import org.rhq.core.pc.util.FacetLockType;
import org.rhq.core.pc.util.LoggingThreadFactory;
@@ -186,6 +190,11 @@ public class InventoryManager extends AgentService implements ContainerService,
*/
private AvailabilityCollectorThreadPool availabilityCollectors;
+ /**
+ * Handles the resource upgrade during the initialization of the inventory manager.
+ */
+ private ResourceUpgradeExecutor resourceUpgradeExecutor;
+
public InventoryManager() {
super(DiscoveryAgentService.class);
}
@@ -240,6 +249,17 @@ public class InventoryManager extends AgentService implements ContainerService,
inventoryThreadPoolExecutor.scheduleWithFixedDelay(serviceScanExecutor, configuration
.getServiceDiscoveryInitialDelay(), configuration.getServiceDiscoveryPeriod(), TimeUnit.SECONDS);
}
+
+ //try to perform the full resource upgrade now.
+ //The initialization time is ideal for this because inventory manager
+ //is the first plugin container service to start and hence we can
+ //be sure that no under concurrent updates to the resources are happening.
+ //Because PC doesn't support online updates of plugins and needs to be restarted
+ //in order to pick up the changed plugins, we can be sure that running the
+ //upgrade only once at the PC start up is enough for the lifetime of
+ //plugin container (and hence this instance of InventoryManager).
+ resourceUpgradeExecutor = new ResourceUpgradeExecutor(this);
+ resourceUpgradeExecutor.execute();
} finally {
inventoryLock.writeLock().unlock();
}
@@ -356,6 +376,23 @@ public class InventoryManager extends AgentService implements ContainerService,
return results;
}
+ public <T extends ResourceComponent> Map<ResourceUpgradeContext<T>, ResourceUpgradeReport> invokeDiscoveryComponentResourceUpgradeFacet(
+ ResourceType resourceType, ResourceDiscoveryComponent<T> component,
+ Set<ResourceUpgradeContext<T>> inventoriedSiblings, ResourceUpgradeContext<?> parent,
+ Set<ResourceUpgradeContext<T>> discoveredResources) throws Throwable {
+
+ long timeout = getDiscoveryComponentTimeout(resourceType);
+ try {
+ @SuppressWarnings("unchecked")
+ ResourceUpgradeFacet<T> proxy = this.discoveryComponentProxyFactory.getDiscoveryComponentProxy(resourceType, component, timeout, ResourceUpgradeFacet.class);
+
+ return proxy.upgrade(inventoriedSiblings, parent, discoveredResources);
+ } catch (BlacklistedException e) {
+ log.debug(e);
+ return Collections.emptyMap();
+ }
+ }
+
public DiscoveryComponentProxyFactory getDiscoveryComponentProxyFactory() {
return this.discoveryComponentProxyFactory;
}
@@ -854,8 +891,20 @@ public class InventoryManager extends AgentService implements ContainerService,
*/
public boolean handleReport(InventoryReport report) {
if (!configuration.isInsideAgent()) {
+ //TODO how does resource upgrade behave in the embedded scenario?
return true;
}
+
+ //finish the resource upgrade.
+ //by now all the resource upgrade requests have been processed
+ //by the executor, which means that the inventory report
+ //we got already only contains the "correct" new resources and
+ //that the executor has all the upgrade requests queued up
+ //to be sent to the server in a batch.
+ if (resourceUpgradeExecutor.isEnabled()) {
+ resourceUpgradeExecutor.sendRequests();
+ }
+
if (report.getAddedRoots().isEmpty()) {
return true; // nothing to do
}
@@ -925,6 +974,7 @@ public class InventoryManager extends AgentService implements ContainerService,
log.debug(String.format("DONE syncing local inventory [%d] ms.",
(System.currentTimeMillis() - startTime)));
}
+
// If we synced any Resources, one or more Resource components were probably started,
// so run an avail check to report on their availabilities immediately. Also kick off
// a service scan to scan those Resources for new child Resources. Kick both tasks off
@@ -941,7 +991,7 @@ public class InventoryManager extends AgentService implements ContainerService,
throw new RuntimeException(t);
}
}
-
+
private void getAllUuids(ResourceSyncInfo syncInfo, Set<String> allServerSideUuids) {
allServerSideUuids.add(syncInfo.getUuid());
for (ResourceSyncInfo child : syncInfo.getChildSyncInfos()) {
@@ -1113,49 +1163,58 @@ public class InventoryManager extends AgentService implements ContainerService,
return resourceContainer.updateAvailability(availabilityType);
}
- private boolean mergeResourceFromUpgrade(Resource existingResource, ResourceUpgradeReport upgradeReport) {
- String resourceKey = upgradeReport.getNewResourceKey();
- String name = upgradeReport.getNewName();
- String version = upgradeReport.getNewVersion();
- String description = upgradeReport.getNewDescription();
- Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
- Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
-
+ public boolean mergeResourceFromUpgrade(Set<ResourceUpgradeReport> upgradeReports) {
boolean serverUpdated = false;
try {
ServerServices serverServices = this.configuration.getServerServices();
if (serverServices != null) {
DiscoveryServerService discoveryServerService = serverServices.getDiscoveryServerService();
- serverUpdated = discoveryServerService.upgradeResource(existingResource.getId(), upgradeReport);
+ serverUpdated = discoveryServerService.upgradeResources(upgradeReports);
}
} catch (Exception e) {
- log.error("Failed to upgrade the resource [" + existingResource + "] on the server.", e);
+ log.error("Failed to process resource upgrades on the server.", e);
}
if (serverUpdated) {
- if (resourceKey != null) {
- existingResource.setResourceKey(resourceKey);
- }
-
- if (name != null) {
- existingResource.setName(name);
- }
-
- if (version != null) {
- existingResource.setVersion(version);
- }
-
- if (description != null) {
- existingResource.setDescription(description);
- }
-
- if (pluginConfiguration != null) {
- existingResource.setPluginConfiguration(pluginConfiguration);
- }
-
- if (resourceConfiguration != null) {
- existingResource.setResourceConfiguration(resourceConfiguration);
+ for (ResourceUpgradeReport upgradeReport : upgradeReports) {
+ String resourceKey = upgradeReport.getNewResourceKey();
+ String name = upgradeReport.getNewName();
+ String version = upgradeReport.getNewVersion();
+ String description = upgradeReport.getNewDescription();
+ Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
+ Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
+
+ ResourceContainer existingResourceContainer = getResourceContainer(upgradeReport.getResourceId());
+ if (existingResourceContainer != null) {
+ Resource existingResource = existingResourceContainer.getResource();
+ if (resourceKey != null) {
+ existingResource.setResourceKey(resourceKey);
+ }
+
+ if (name != null) {
+ existingResource.setName(name);
+ }
+
+ if (version != null) {
+ existingResource.setVersion(version);
+ }
+
+ if (description != null) {
+ existingResource.setDescription(description);
+ }
+
+ if (pluginConfiguration != null) {
+ existingResource.setPluginConfiguration(pluginConfiguration);
+ }
+
+ if (resourceConfiguration != null) {
+ existingResource.setResourceConfiguration(resourceConfiguration);
+ }
+ } else {
+ log.error("Upgraded a resource that is not present on the agent. This should not happen. The id of the missing resource is " + upgradeReport.getResourceId());
+ }
+
}
}
@@ -1453,6 +1512,23 @@ public class InventoryManager extends AgentService implements ContainerService,
this.configuration.getPluginContainerDeployment()); // helps components make determinations of what to do
}
+ public <T extends ResourceComponent> ResourceUpgradeContext<T> createResourceUpgradeContext(Resource resource, T parentComponent, ResourceDiscoveryComponent<T> discoveryComponent) {
+ File pluginDataDir = new File(this.configuration.getDataDirectory(), resource.getResourceType().getPlugin());
+
+ return new ResourceUpgradeContext<T>(resource, // the resource itself
+ parentComponent, // its parent component
+ discoveryComponent, // the discovery component (this is actually the proxy to it)
+ SystemInfoFactory.createSystemInfo(), // for native access
+ this.configuration.getTemporaryDirectory(), // location for plugin to write temp files
+ pluginDataDir, // location for plugin to write data files
+ this.configuration.getContainerName(), // the name of the agent/PC
+ getEventContext(resource), // for event access
+ getOperationContext(resource), // for operation manager access
+ getContentContext(resource), // for content manager access
+ this.availabilityCollectors, // for components that want to perform async avail checking
+ this.configuration.getPluginContainerDeployment()); // helps components make determinations of what to do
+ }
+
/**
* This will send a resource error to the server (if applicable) to indicate that the given resource could not be
* connected to due to an invalid plugin configuration.
@@ -1536,7 +1612,7 @@ public class InventoryManager extends AgentService implements ContainerService,
return getResourcesWithType(serverType, this.platform.getChildResources());
}
- private Set<Resource> getResourcesWithType(ResourceType serverType, Set<Resource> resources) {
+ public Set<Resource> getResourcesWithType(ResourceType serverType, Set<Resource> resources) {
Set<Resource> servers = new HashSet<Resource>();
if (resources == null) {
@@ -2061,76 +2137,10 @@ public class InventoryManager extends AgentService implements ContainerService,
newResources.add(newResource);
}
}
-
- //check if the discovery component supports resource upgrade
- //if it does, perform the resource upgrade straight away here during the discovery process.
- if (discoveryComponent instanceof ResourceUpgradeFacet) {
- ResourceUpgradeFacet resourceUpgrade = (ResourceUpgradeFacet) discoveryComponent;
-
- //the siblings are the resources of the type that is currently being discovered that are already
- //present in the inventory. These are the candidate resources for the upgrade.
- Set<Resource> siblings = getResourcesWithType(resourceType, parentResource.getChildResources());
-
- ResourceUpgradeContext<?> parentUpgradeContext = null;
-
- //get the upgrade context of the parent resource so that it can be passed to the upgrade method
- //of the discovery component.
- if (parentResource != null) {
- Resource grandParent = parentResource.getParentResource();
- ResourceContainer grandParentContainer = grandParent == null ? null : getResourceContainer(grandParent);
- ResourceDiscoveryComponent parentDiscoveryComponent = PluginContainer.getInstance().getPluginComponentFactory()
- .getDiscoveryComponent(parentResource.getResourceType(), grandParentContainer);
-
- parentUpgradeContext = new ResourceUpgradeContext(parentResource, parentDiscoveryComponent, parentResourceContext, availabilityCollectors);
- }
-
- //convert the sibling resources into upgrade context objects so that the plugin methods don't access the
- //domain objects directly.
- Set<ResourceUpgradeContext> siblingContexts = new HashSet<ResourceUpgradeContext>(siblings.size());
-
- //but we are going to need to update the resources in the end, so map the contexts with the resources.
- Map<ResourceUpgradeContext, Resource> siblingContextToResource = new HashMap<ResourceUpgradeContext, Resource>();
-
- for (Resource sibling : siblings) {
- ResourceUpgradeContext siblingContext = new ResourceUpgradeContext(sibling, discoveryComponent, getResourceContainer(sibling).getResourceContext(), availabilityCollectors);
- siblingContexts.add(siblingContext);
- siblingContextToResource.put(siblingContext, sibling);
- }
-
- //covert the new resources into contexts.
- //map the resources by resource key so that we can later check for uniqueness of the reported results.
- Set<ResourceUpgradeContext> newResourceContexts = new HashSet<ResourceUpgradeContext>();
- Map<String, Resource> newResourceKeyToResource = new HashMap<String, Resource>();
-
- for (Resource newResource : newResources) {
- ResourceUpgradeContext newUpgradeContext = new ResourceUpgradeContext(newResource, discoveryComponent, createResourceContext(newResource, parentComponent, discoveryComponent), availabilityCollectors);
- newResourceContexts.add(newUpgradeContext);
- newResourceKeyToResource.put(newResource.getResourceKey(), newResource);
- }
-
- //ask the discovery component to upgrade the siblings.
- Map<ResourceUpgradeContext, ResourceUpgradeReport> results = resourceUpgrade.upgrade(siblingContexts, parentUpgradeContext, newResourceContexts);
-
- //now go through the results and upgrade the resources as needed.
- for(Map.Entry<ResourceUpgradeContext, ResourceUpgradeReport> upgradeEntry : results.entrySet()) {
- Resource siblingToUpgrade = siblingContextToResource.get(upgradeEntry.getKey());
- ResourceUpgradeReport newData = upgradeEntry.getValue();
-
- //upgrade the data on the server first
- mergeResourceFromUpgrade(siblingToUpgrade, newData);
-
- //if there was a resource key upgrade, remove a resource with the same resource key
- //from the discovery results. Otherwise we'd end up with 2 sibling resources with
- //the same resource key, which is illegal.
- if (newData.getNewResourceKey() != null) {
- Resource newResourceToRemove = newResourceKeyToResource.get(newData.getNewResourceKey());
- if (newResourceToRemove != null) {
- newResources.remove(newResourceToRemove);
- }
- }
- }
- }
+ if (resourceUpgradeExecutor.isEnabled()) {
+ resourceUpgradeExecutor.processAndQueue(new ResourceUpgradeRequest(newResources, context, parentResource.getId()), newResources);
+ }
} catch (Throwable e) {
// TODO GH: Add server/parent - up/down semantics so this won't happen just because a server is not up
long elapsedTime = System.currentTimeMillis() - startTime;
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
new file mode 100644
index 0000000..f0f2b43
--- /dev/null
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
@@ -0,0 +1,285 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.rhq.core.pc.upgrade;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.clientapi.agent.PluginContainerException;
+import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
+import org.rhq.core.pc.PluginContainer;
+import org.rhq.core.pc.inventory.InventoryManager;
+import org.rhq.core.pc.inventory.ResourceContainer;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
+
+/**
+ * This class is responsible for performing the resource upgrade on behalf on of {@link InventoryManager}.
+ * Despite its name, it is not an {@link java.util.concurrent.Executor} implementation.
+ *
+ * @author Lukas Krejci
+ */
+public class ResourceUpgradeExecutor {
+ private static final Log log = LogFactory.getLog(ResourceUpgradeExecutor.class);
+
+ /**
+ * The upgrade runs only once in its lifetime.
+ */
+ private boolean enabled = true;
+
+ private InventoryManager inventoryManager;
+
+ private Set<ResourceUpgradeReport> reports;
+
+ public ResourceUpgradeExecutor(InventoryManager inventoryManager) {
+ this.inventoryManager = inventoryManager;
+ }
+
+ /**
+ * This method is called from within the {@link InventoryManager} during the
+ * discovery process as individual upgrade requests are generated.
+ * <p>
+ * This method calls the appropriate discovery component to perform the upgrade and
+ * at the same time stores off the results so that they can be sent to the server
+ * at the end of the discovery in one big batch.
+ * <p>
+ * The provided set of discovery results is updated if this method detects that an existing
+ * resource upgrade would result in a resource key collision with some of the newly discovered
+ * resources.
+ *
+ * @param request the upgrade request
+ * @param discoveredResources the set of discovered resources that this method can optionally remove some elements from.
+ */
+ public <T extends ResourceComponent> Map<ResourceUpgradeContext<T>, ResourceUpgradeReport> processAndQueue(
+ ResourceUpgradeRequest<T> request, Set<Resource> discoveredResources) {
+
+ return enabled ? executeResourceUpgradeAndStoreReport(request, discoveredResources) : null;
+ }
+
+ /**
+ * @return true if the executor is ready to perform the upgrade, false otherwise.
+ */
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ /**
+ * This method is called from within the {@link InventoryManager} once it's collected
+ * all the upgrade requests.
+ */
+ public void sendRequests() {
+ if (enabled) {
+ //TODO implement
+ }
+ }
+
+ /**
+ * Performs the resource upgrade. First, a full inventory report is pulled down from the
+ * server to ensure we have an up-to-date picture of the inventory.
+ * After that a full discovery is performed and both the upgrade report and discovery report
+ * are sent to the server.
+ */
+ public void execute() {
+ if (enabled) {
+ if (log.isDebugEnabled()) {
+ log.debug("Starting resource upgrade.");
+ }
+
+ try {
+ //pull the inventory down from the server.
+ //this will ensure that we have an up-to-date info on the
+ //server inventory before we try to upgrade.
+ boolean syncResult = inventoryManager.handleReport(new InventoryReport(inventoryManager.getAgent()));
+ if (!syncResult) {
+ log.warn("Resource upgrade failed to sync up the inventory with the server.");
+ return;
+ }
+
+ //fire off the full discovery
+ inventoryManager.executeServerScanImmediately();
+ inventoryManager.executeServiceScanImmediately();
+ } catch (Throwable t) {
+ log.warn("Resource upgrade failed.", t);
+ } finally {
+ //make sure to switch off the upgrade...
+ this.enabled = false;
+
+ //clear up so that we don't hold unnecessary instances.
+ reports.clear();
+
+ if (log.isDebugEnabled()) {
+ log.debug("Resource upgrade finished.");
+ }
+ }
+
+ } else {
+ if (log.isDebugEnabled()) {
+ log.debug("ResourceUpgradeExecutor already ran before. Skipping the execution.");
+ }
+ }
+ }
+
+ /**
+ * Executes the resource upgrade request on the agent (if the appropriate discovery component support {@link ResourceUpgradeFacet}).
+ *
+ * @param request the upgrade request to execute on the agent.
+ * @param discoveredResources the set of the discovered resources that this method can remove some elements from
+ * @return the resulting upgrade map as reported by the plugin from {@link ResourceUpgradeFacet#upgrade(Set, ResourceUpgradeContext, Set)} method.
+ *
+ * @throws PluginContainerException
+ */
+ private <T extends ResourceComponent> Map<ResourceUpgradeContext<T>, ResourceUpgradeReport> executeResourceUpgradeAndStoreReport(
+ ResourceUpgradeRequest<T> request, Set<Resource> discoveredResources) {
+
+ ResourceDiscoveryContext<T> discoveryContext = request.getDiscoveryContext();
+ Set<Resource> newResources = request.getDiscoveredResources();
+ Integer parentResourceId = request.getParentResourceId();
+
+ try {
+ ResourceType resourceType = discoveryContext.getResourceType();
+ ResourceContainer parentResourceContainer = null;
+ Resource parentResource = null;
+ if (parentResourceId != null) {
+ parentResourceContainer = inventoryManager.getResourceContainer(parentResourceId);
+ if (parentResourceContainer != null) {
+ parentResource = parentResourceContainer.getResource();
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ ResourceDiscoveryComponent<T> discoveryComponent = PluginContainer.getInstance()
+ .getPluginComponentFactory().getDiscoveryComponent(resourceType, parentResourceContainer);
+
+ ResourceContext<?> parentResourceContext = discoveryContext.getParentResourceContext();
+
+ T parentComponent = discoveryContext.getParentResourceComponent();
+
+ //check if the discovery component supports resource upgrade
+ //if it does, perform the resource upgrade straight away here during the discovery process.
+ if (discoveryComponent instanceof ResourceUpgradeFacet) {
+ //the siblings are the resources of the type that is currently being discovered that are already
+ //present in the inventory. These are the candidate resources for the upgrade.
+ Set<Resource> siblings = parentResource == null ? Collections.singleton(inventoryManager.getPlatform())
+ : inventoryManager.getResourcesWithType(resourceType, parentResource.getChildResources());
+
+ //get the upgrade context of the parent resource so that it can be passed to the upgrade method
+ //of the discovery component.
+ ResourceUpgradeContext<?> parentUpgradeContext = null;
+
+ if (parentResource != null) {
+ Resource grandParent = parentResource.getParentResource();
+ ResourceContainer grandParentContainer = grandParent == null ? null : inventoryManager
+ .getResourceContainer(grandParent);
+
+ @SuppressWarnings("unchecked")
+ ResourceDiscoveryComponent<ResourceComponent> parentDiscoveryComponent = PluginContainer
+ .getInstance().getPluginComponentFactory().getDiscoveryComponent(
+ parentResource.getResourceType(), grandParentContainer);
+
+ ResourceComponent<?> grandParentResourceComponent = grandParentContainer == null ? null
+ : grandParentContainer.getResourceComponent();
+
+ parentUpgradeContext = inventoryManager.createResourceUpgradeContext(parentResource,
+ grandParentResourceComponent, parentDiscoveryComponent);
+ }
+
+ //convert the sibling resources into upgrade context objects so that the plugin methods don't access the
+ //domain objects directly.
+ Set<ResourceUpgradeContext<T>> siblingContexts = new HashSet<ResourceUpgradeContext<T>>(siblings.size());
+
+ //but we are going to need to update the resources in the end, so map the contexts with the resources.
+ Map<ResourceUpgradeContext<T>, Resource> siblingContextToResource = new HashMap<ResourceUpgradeContext<T>, Resource>();
+
+ for (Resource sibling : siblings) {
+ ResourceUpgradeContext<T> siblingContext = inventoryManager.createResourceUpgradeContext(sibling,
+ parentComponent, discoveryComponent);
+ siblingContexts.add(siblingContext);
+ siblingContextToResource.put(siblingContext, sibling);
+ }
+
+ //convert the new resources into contexts.
+ //map the resources by resource key so that we can later check for uniqueness of the reported results.
+ Set<ResourceUpgradeContext<T>> newResourceContexts = new HashSet<ResourceUpgradeContext<T>>();
+ Map<String, Resource> newResourceKeyToResource = new HashMap<String, Resource>();
+
+ for (Resource newResource : newResources) {
+ ResourceUpgradeContext<T> newUpgradeContext = inventoryManager.createResourceUpgradeContext(
+ newResource, parentComponent, discoveryComponent);
+ newResourceContexts.add(newUpgradeContext);
+ newResourceKeyToResource.put(newResource.getResourceKey(), newResource);
+ }
+
+ //ask the discovery component to upgrade the siblings.
+ Map<ResourceUpgradeContext<T>, ResourceUpgradeReport> results;
+ try {
+ results = inventoryManager.invokeDiscoveryComponentResourceUpgradeFacet(resourceType,
+ discoveryComponent, siblingContexts, parentUpgradeContext, newResourceContexts);
+
+ //now go through the results and upgrade the resources as needed.
+ for (Map.Entry<ResourceUpgradeContext<T>, ResourceUpgradeReport> upgradeEntry : results.entrySet()) {
+ Resource siblingToUpgrade = siblingContextToResource.get(upgradeEntry.getKey());
+ ResourceUpgradeReport newData = upgradeEntry.getValue();
+
+ //upgrade the data on the server first
+ newData.setResourceId(siblingToUpgrade.getId());
+ reports.add(newData);
+
+ //if there was a resource key upgrade, remove a resource with the same resource key
+ //from the discovery results. Otherwise we'd end up with 2 sibling resources with
+ //the same resource key, which is illegal.
+ if (newData.getNewResourceKey() != null) {
+ Resource newResourceToRemove = newResourceKeyToResource.get(newData.getNewResourceKey());
+ if (newResourceToRemove != null) {
+ discoveredResources.remove(newResourceToRemove);
+ }
+ }
+ }
+
+ return results;
+ } catch (Throwable t) {
+ log.warn("Exception in discovery component " + discoveryComponent.getClass() + " upgrade method.",
+ t);
+ }
+ }
+ } catch (PluginContainerException e) {
+ log.warn("Failed resource upgrade of children of resource id " + parentResourceId, e);
+ }
+ return null;
+ }
+}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeRequest.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeRequest.java
new file mode 100644
index 0000000..25178ee
--- /dev/null
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeRequest.java
@@ -0,0 +1,35 @@
+package org.rhq.core.pc.upgrade;
+
+import java.util.Set;
+
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+
+/**
+ * This class is used to store the requests for resource upgrade that originate in
+ * the discovery workflow, but can only be executed after an inventory sync.
+ */
+public class ResourceUpgradeRequest<T extends ResourceComponent> {
+ private Set<Resource> discoveredResources;
+ private ResourceDiscoveryContext<T> discoveryContext;
+ private Integer parentResourceId;
+
+ public ResourceUpgradeRequest(Set<Resource> discoveredResources, ResourceDiscoveryContext<T> discoveryContext, Integer parentResourceId) {
+ this.discoveredResources = discoveredResources;
+ this.discoveryContext = discoveryContext;
+ this.parentResourceId = parentResourceId;
+ }
+
+ public Set<Resource> getDiscoveredResources() {
+ return discoveredResources;
+ }
+
+ public ResourceDiscoveryContext<T> getDiscoveryContext() {
+ return discoveryContext;
+ }
+
+ public Integer getParentResourceId() {
+ return parentResourceId;
+ }
+}
\ No newline at end of file
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/DiscoveryComponentProxyFactory.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/DiscoveryComponentProxyFactory.java
index 57b9874..f8d1267 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/DiscoveryComponentProxyFactory.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/DiscoveryComponentProxyFactory.java
@@ -189,7 +189,7 @@ public class DiscoveryComponentProxyFactory {
+ "] has been blacklisted and can no longer be invoked.");
}
- if (method.getDeclaringClass().equals(ResourceDiscoveryComponent.class)) {
+ if (method.getDeclaringClass().getPackage().getName().startsWith("org.rhq")) {
return invokeInNewThread(method, args);
} else {
// toString(), etc.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index 2d3e9e6..44f79a2 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -401,17 +401,20 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
}
}
- public boolean upgradeResource(int resourceId, ResourceUpgradeReport upgradeReport) {
- Resource existingResource = this.entityManager.find(Resource.class, resourceId);
- if (existingResource != null) {
- boolean changed = upgradeResource(existingResource, upgradeReport);
- if (changed) {
- this.entityManager.merge(existingResource);
+ public boolean upgradeResources(Set<ResourceUpgradeReport> upgradeReports) {
+ for (ResourceUpgradeReport report : upgradeReports) {
+ Resource existingResource = this.entityManager.find(Resource.class, report.getResourceId());
+ if (existingResource != null) {
+ boolean changed = upgradeResource(existingResource, report);
+ if (changed) {
+ this.entityManager.merge(existingResource);
+ }
+ } else {
+ this.entityManager.getTransaction().setRollbackOnly();
+ return false;
}
- return true;
- } else {
- return false;
}
+ return true;
}
/**
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
index 4e60ffb..af518eb 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
@@ -21,6 +21,7 @@ package org.rhq.enterprise.server.discovery;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import javax.ejb.Local;
@@ -179,11 +180,10 @@ public interface DiscoveryBossLocal extends DiscoveryBossRemote {
boolean updateResourceVersion(int resourceId, String version);
/**
- * Upgrades the data of the resource according to the provided report.
+ * Upgrades the data of the resources according to the provided reports.
*
- * @param resourceId the id of the resource to be upgraded
- * @param upgradeReport contains the information about the upgrade
+ * @param upgradeReports contains the information about the upgrade of individual resources.
* @return true if the upgrade succeeded, false otherwise.
*/
- boolean upgradeResource(int resourceId, ResourceUpgradeReport upgradeReport);
+ boolean upgradeResources(Set<ResourceUpgradeReport> upgradeReports);
}
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
index 720465e..0f90cdc 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
@@ -177,9 +177,9 @@ public class DiscoveryServerServiceImpl implements DiscoveryServerService {
return discoveryBoss.updateResourceVersion(resourceId, version);
}
- public boolean upgradeResource(int resourceId, ResourceUpgradeReport upgradeReport) {
+ public boolean upgradeResources(Set<ResourceUpgradeReport> upgradeReports) {
DiscoveryBossLocal discoveryBoss = LookupUtil.getDiscoveryBoss();
- return discoveryBoss.upgradeResource(resourceId, upgradeReport);
+ return discoveryBoss.upgradeResources(upgradeReports);
}
private static Resource convertToPojoResource(Resource resource, boolean includeDescendants) {
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
index fc001f9..2f3431b 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
@@ -170,10 +170,10 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
return discoveredResources;
}
- public Map<ResourceUpgradeContext, ResourceUpgradeReport> upgrade(Set<ResourceUpgradeContext> inventoriedSiblings,
- ResourceUpgradeContext<PlatformComponent> parentContext, Set<ResourceUpgradeContext> discoveryResults) {
+ public Map<ResourceUpgradeContext<PlatformComponent>, ResourceUpgradeReport> upgrade(Set<ResourceUpgradeContext<PlatformComponent>> inventoriedSiblings,
+ ResourceUpgradeContext<?> parentContext, Set<ResourceUpgradeContext<PlatformComponent>> discoveryResults) {
- Map<ResourceUpgradeContext, ResourceUpgradeReport> ret = new HashMap<ResourceUpgradeContext, ResourceUpgradeReport>();
+ Map<ResourceUpgradeContext<PlatformComponent>, ResourceUpgradeReport> ret = new HashMap<ResourceUpgradeContext<PlatformComponent>, ResourceUpgradeReport>();
for (ResourceUpgradeContext context : inventoriedSiblings) {
String inventoriedResourceKey = context.getResourceKey();
commit 15ee2d7c543480cb636eb0b2c68a773d0728fe78
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu May 27 12:11:54 2010 +0200
Small interface correction.
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
index cea777a..914641c 100644
--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
@@ -37,7 +37,6 @@ import org.rhq.core.pluginapi.inventory.ResourceComponent;
*
* @author Lukas Krejci
*/
-@SuppressWarnings("unchecked")
public interface ResourceUpgradeFacet<T extends ResourceComponent> {
/**
@@ -54,5 +53,5 @@ public interface ResourceUpgradeFacet<T extends ResourceComponent> {
* inventoriedSiblings set, the values are the upgrade reports detailing what the data of the
* corresponding siblings should be upgraded to.
*/
- Map<ResourceUpgradeContext, ResourceUpgradeReport> upgrade(Set<ResourceUpgradeContext> inventoriedSiblings, ResourceUpgradeContext<T> parentContext, Set<ResourceUpgradeContext> discoveryResults);
+ Map<ResourceUpgradeContext<T>, ResourceUpgradeReport> upgrade(Set<ResourceUpgradeContext<T>> inventoriedSiblings, ResourceUpgradeContext<? extends ResourceComponent> parentContext, Set<ResourceUpgradeContext<T>> discoveryResults);
}
commit df9228b55e6fdd293be1b1b030a00fb109fd649c
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed May 26 15:06:37 2010 +0200
added some comments, fixed typos and one possible NPE.
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
index b68b5df..cea777a 100644
--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
@@ -45,7 +45,7 @@ public interface ResourceUpgradeFacet<T extends ResourceComponent> {
* The exact same discovery results are passed to this method along with the set of resources
* that already exist in the inventory.
*
- * @param inventoriedSimblings the existing resources
+ * @param inventoriedSiblings the existing resources
* @param parentContext the parent of both the newly discovered and existing resources
* @param discoveryResults the discovered resources. The resources from this set that have
* the same resource key as one of the inventoried siblings (after upgrade using the results of this method) won't
@@ -54,5 +54,5 @@ public interface ResourceUpgradeFacet<T extends ResourceComponent> {
* inventoriedSiblings set, the values are the upgrade reports detailing what the data of the
* corresponding siblings should be upgraded to.
*/
- Map<ResourceUpgradeContext, ResourceUpgradeReport> upgrade(Set<ResourceUpgradeContext> inventoriedSimblings, ResourceUpgradeContext<T> parentContext, Set<ResourceUpgradeContext> discoveryResults);
+ Map<ResourceUpgradeContext, ResourceUpgradeReport> upgrade(Set<ResourceUpgradeContext> inventoriedSiblings, ResourceUpgradeContext<T> parentContext, Set<ResourceUpgradeContext> discoveryResults);
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 866fd79..032256b 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -2062,21 +2062,33 @@ public class InventoryManager extends AgentService implements ContainerService,
}
}
- //check for upgrade support
+ //check if the discovery component supports resource upgrade
+ //if it does, perform the resource upgrade straight away here during the discovery process.
if (discoveryComponent instanceof ResourceUpgradeFacet) {
ResourceUpgradeFacet resourceUpgrade = (ResourceUpgradeFacet) discoveryComponent;
+ //the siblings are the resources of the type that is currently being discovered that are already
+ //present in the inventory. These are the candidate resources for the upgrade.
Set<Resource> siblings = getResourcesWithType(resourceType, parentResource.getChildResources());
- Resource grandParent = parentResource.getParentResource();
- ResourceContainer grandParentContainer = grandParent == null ? null : getResourceContainer(grandParent);
- ResourceDiscoveryComponent parentDiscoveryComponent = PluginContainer.getInstance().getPluginComponentFactory()
- .getDiscoveryComponent(parentResource.getResourceType(), grandParentContainer);
-
- ResourceUpgradeContext<?> parentUpgradeContext = new ResourceUpgradeContext(parentResource, parentDiscoveryComponent, parentResourceContext, availabilityCollectors);
+ ResourceUpgradeContext<?> parentUpgradeContext = null;
+
+ //get the upgrade context of the parent resource so that it can be passed to the upgrade method
+ //of the discovery component.
+ if (parentResource != null) {
+ Resource grandParent = parentResource.getParentResource();
+ ResourceContainer grandParentContainer = grandParent == null ? null : getResourceContainer(grandParent);
+ ResourceDiscoveryComponent parentDiscoveryComponent = PluginContainer.getInstance().getPluginComponentFactory()
+ .getDiscoveryComponent(parentResource.getResourceType(), grandParentContainer);
+
+ parentUpgradeContext = new ResourceUpgradeContext(parentResource, parentDiscoveryComponent, parentResourceContext, availabilityCollectors);
+ }
+ //convert the sibling resources into upgrade context objects so that the plugin methods don't access the
+ //domain objects directly.
Set<ResourceUpgradeContext> siblingContexts = new HashSet<ResourceUpgradeContext>(siblings.size());
+ //but we are going to need to update the resources in the end, so map the contexts with the resources.
Map<ResourceUpgradeContext, Resource> siblingContextToResource = new HashMap<ResourceUpgradeContext, Resource>();
for (Resource sibling : siblings) {
@@ -2085,6 +2097,8 @@ public class InventoryManager extends AgentService implements ContainerService,
siblingContextToResource.put(siblingContext, sibling);
}
+ //covert the new resources into contexts.
+ //map the resources by resource key so that we can later check for uniqueness of the reported results.
Set<ResourceUpgradeContext> newResourceContexts = new HashSet<ResourceUpgradeContext>();
Map<String, Resource> newResourceKeyToResource = new HashMap<String, Resource>();
@@ -2094,12 +2108,15 @@ public class InventoryManager extends AgentService implements ContainerService,
newResourceKeyToResource.put(newResource.getResourceKey(), newResource);
}
+ //ask the discovery component to upgrade the siblings.
Map<ResourceUpgradeContext, ResourceUpgradeReport> results = resourceUpgrade.upgrade(siblingContexts, parentUpgradeContext, newResourceContexts);
+ //now go through the results and upgrade the resources as needed.
for(Map.Entry<ResourceUpgradeContext, ResourceUpgradeReport> upgradeEntry : results.entrySet()) {
Resource siblingToUpgrade = siblingContextToResource.get(upgradeEntry.getKey());
ResourceUpgradeReport newData = upgradeEntry.getValue();
+ //upgrade the data on the server first
mergeResourceFromUpgrade(siblingToUpgrade, newData);
//if there was a resource key upgrade, remove a resource with the same resource key
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
index 45887f6..fc001f9 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
@@ -170,12 +170,12 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
return discoveredResources;
}
- public Map<ResourceUpgradeContext, ResourceUpgradeReport> upgrade(Set<ResourceUpgradeContext> inventoriedSimblings,
+ public Map<ResourceUpgradeContext, ResourceUpgradeReport> upgrade(Set<ResourceUpgradeContext> inventoriedSiblings,
ResourceUpgradeContext<PlatformComponent> parentContext, Set<ResourceUpgradeContext> discoveryResults) {
Map<ResourceUpgradeContext, ResourceUpgradeReport> ret = new HashMap<ResourceUpgradeContext, ResourceUpgradeReport>();
- for (ResourceUpgradeContext context : inventoriedSimblings) {
+ for (ResourceUpgradeContext context : inventoriedSiblings) {
String inventoriedResourceKey = context.getResourceKey();
File inventoriedResourceKeyAsPath = new File(inventoriedResourceKey);
commit 3c7d8241ea85fdceb317049664886b204f4d9cba
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed May 26 14:49:03 2010 +0200
renamed the org.rhq.core.pluginapi.migration package to org.rhq.core.pluginapi.upgrade to make it use the "upgrade" notion used by the classes in it.
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeContext.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeContext.java
deleted file mode 100644
index e8c5f03..0000000
--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeContext.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2010 Red Hat, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation, and/or the GNU Lesser
- * General Public License, version 2.1, also as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License and the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * and the GNU Lesser General Public License along with this program;
- * if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-package org.rhq.core.pluginapi.migration;
-
-import java.io.File;
-import java.util.concurrent.Executor;
-
-import org.rhq.core.domain.configuration.Configuration;
-import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.pluginapi.content.ContentContext;
-import org.rhq.core.pluginapi.event.EventContext;
-import org.rhq.core.pluginapi.inventory.PluginContainerDeployment;
-import org.rhq.core.pluginapi.inventory.ResourceComponent;
-import org.rhq.core.pluginapi.inventory.ResourceContext;
-import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
-import org.rhq.core.pluginapi.operation.OperationContext;
-import org.rhq.core.system.SystemInfo;
-
-/**
- * Represents a resource during the resource upgrade phase of discovery.
- *
- * @see ResourceUpgradeFacet
- *
- * @author Lukas Krejci
- */
-@SuppressWarnings("unchecked")
-public class ResourceUpgradeContext<T extends ResourceComponent> extends ResourceContext<T> {
-
- private final Configuration resourceConfiguration;
- private final String name;
- private final String description;
-
- /**
- * @see ResourceContext#ResourceContext(Resource, ResourceComponent, ResourceDiscoveryComponent, SystemInfo, File, File, String, EventContext, OperationContext, ContentContext, Executor, PluginContainerDeployment)
- */
- public ResourceUpgradeContext(Resource resource, T parentResourceComponent,
- ResourceDiscoveryComponent resourceDiscoveryComponent, SystemInfo systemInfo, File temporaryDirectory,
- File dataDirectory, String pluginContainerName, EventContext eventContext, OperationContext operationContext,
- ContentContext contentContext, Executor availCollectorThreadPool,
- PluginContainerDeployment pluginContainerDeployment) {
-
- super(resource, parentResourceComponent, resourceDiscoveryComponent, systemInfo, temporaryDirectory, dataDirectory,
- pluginContainerName, eventContext, operationContext, contentContext, availCollectorThreadPool,
- pluginContainerDeployment);
-
- this.resourceConfiguration = resource.getResourceConfiguration();
- this.name = resource.getName();
- this.description = resource.getDescription();
- }
-
- public ResourceUpgradeContext(Resource resource, ResourceDiscoveryComponent discoveryComponent, ResourceContext<T> context, Executor availCollectorThreadPool) {
- this(resource, context.getParentResourceComponent(), discoveryComponent, context.getSystemInformation(), context.getTemporaryDirectory(),
- context.getDataDirectory(), context.getPluginContainerName(), context.getEventContext(), context.getOperationContext(),
- context.getContentContext(), availCollectorThreadPool, context.getPluginContainerDeployment());
- }
-
- public Configuration getResourceConfiguration() {
- return resourceConfiguration;
- }
-
- public String getName() {
- return name;
- }
-
- public String getDescription() {
- return description;
- }
-}
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeFacet.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeFacet.java
deleted file mode 100644
index df372bf..0000000
--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeFacet.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2010 Red Hat, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation, and/or the GNU Lesser
- * General Public License, version 2.1, also as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License and the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * and the GNU Lesser General Public License along with this program;
- * if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-package org.rhq.core.pluginapi.migration;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.rhq.core.domain.resource.ResourceUpgradeReport;
-import org.rhq.core.pluginapi.inventory.ResourceComponent;
-
-/**
- * This interface is to be implemented by discovery classes if they want to support
- * upgrading the existing resources to a new format needed by an updated resource component.
- * This is useful for example in the case when a new version of plugin redefined a resource
- * key generation algorithm and wants to upgrade the legacy resources to use the new format.
- *
- * @author Lukas Krejci
- */
-@SuppressWarnings("unchecked")
-public interface ResourceUpgradeFacet<T extends ResourceComponent> {
-
- /**
- * This method is called on the discovery component straight after it has finished the discovery.
- * The exact same discovery results are passed to this method along with the set of resources
- * that already exist in the inventory.
- *
- * @param inventoriedSimblings the existing resources
- * @param parentContext the parent of both the newly discovered and existing resources
- * @param discoveryResults the discovered resources. The resources from this set that have
- * the same resource key as one of the inventoried siblings (after upgrade using the results of this method) won't
- * be reported.
- * @return the mapping of old resources to the newly desired data. The keys are instances from the
- * inventoriedSiblings set, the values are the upgrade reports detailing what the data of the
- * corresponding siblings should be upgraded to.
- */
- Map<ResourceUpgradeContext, ResourceUpgradeReport> upgrade(Set<ResourceUpgradeContext> inventoriedSimblings, ResourceUpgradeContext<T> parentContext, Set<ResourceUpgradeContext> discoveryResults);
-}
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeContext.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeContext.java
new file mode 100644
index 0000000..35f5029
--- /dev/null
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeContext.java
@@ -0,0 +1,89 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.rhq.core.pluginapi.upgrade;
+
+import java.io.File;
+import java.util.concurrent.Executor;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.pluginapi.content.ContentContext;
+import org.rhq.core.pluginapi.event.EventContext;
+import org.rhq.core.pluginapi.inventory.PluginContainerDeployment;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.operation.OperationContext;
+import org.rhq.core.system.SystemInfo;
+
+/**
+ * Represents a resource during the resource upgrade phase of discovery.
+ *
+ * @see ResourceUpgradeFacet
+ *
+ * @author Lukas Krejci
+ */
+@SuppressWarnings("unchecked")
+public class ResourceUpgradeContext<T extends ResourceComponent> extends ResourceContext<T> {
+
+ private final Configuration resourceConfiguration;
+ private final String name;
+ private final String description;
+
+ /**
+ * @see ResourceContext#ResourceContext(Resource, ResourceComponent, ResourceDiscoveryComponent, SystemInfo, File, File, String, EventContext, OperationContext, ContentContext, Executor, PluginContainerDeployment)
+ */
+ public ResourceUpgradeContext(Resource resource, T parentResourceComponent,
+ ResourceDiscoveryComponent resourceDiscoveryComponent, SystemInfo systemInfo, File temporaryDirectory,
+ File dataDirectory, String pluginContainerName, EventContext eventContext, OperationContext operationContext,
+ ContentContext contentContext, Executor availCollectorThreadPool,
+ PluginContainerDeployment pluginContainerDeployment) {
+
+ super(resource, parentResourceComponent, resourceDiscoveryComponent, systemInfo, temporaryDirectory, dataDirectory,
+ pluginContainerName, eventContext, operationContext, contentContext, availCollectorThreadPool,
+ pluginContainerDeployment);
+
+ this.resourceConfiguration = resource.getResourceConfiguration();
+ this.name = resource.getName();
+ this.description = resource.getDescription();
+ }
+
+ public ResourceUpgradeContext(Resource resource, ResourceDiscoveryComponent discoveryComponent, ResourceContext<T> context, Executor availCollectorThreadPool) {
+ this(resource, context.getParentResourceComponent(), discoveryComponent, context.getSystemInformation(), context.getTemporaryDirectory(),
+ context.getDataDirectory(), context.getPluginContainerName(), context.getEventContext(), context.getOperationContext(),
+ context.getContentContext(), availCollectorThreadPool, context.getPluginContainerDeployment());
+ }
+
+ public Configuration getResourceConfiguration() {
+ return resourceConfiguration;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+}
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
new file mode 100644
index 0000000..b68b5df
--- /dev/null
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
@@ -0,0 +1,58 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.rhq.core.pluginapi.upgrade;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+
+/**
+ * This interface is to be implemented by discovery classes if they want to support
+ * upgrading the existing resources to a new format needed by an updated resource component.
+ * This is useful for example in the case when a new version of plugin redefined a resource
+ * key generation algorithm and wants to upgrade the legacy resources to use the new format.
+ *
+ * @author Lukas Krejci
+ */
+@SuppressWarnings("unchecked")
+public interface ResourceUpgradeFacet<T extends ResourceComponent> {
+
+ /**
+ * This method is called on the discovery component straight after it has finished the discovery.
+ * The exact same discovery results are passed to this method along with the set of resources
+ * that already exist in the inventory.
+ *
+ * @param inventoriedSimblings the existing resources
+ * @param parentContext the parent of both the newly discovered and existing resources
+ * @param discoveryResults the discovered resources. The resources from this set that have
+ * the same resource key as one of the inventoried siblings (after upgrade using the results of this method) won't
+ * be reported.
+ * @return the mapping of old resources to the newly desired data. The keys are instances from the
+ * inventoriedSiblings set, the values are the upgrade reports detailing what the data of the
+ * corresponding siblings should be upgraded to.
+ */
+ Map<ResourceUpgradeContext, ResourceUpgradeReport> upgrade(Set<ResourceUpgradeContext> inventoriedSimblings, ResourceUpgradeContext<T> parentContext, Set<ResourceUpgradeContext> discoveryResults);
+}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index feb2d81..866fd79 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -105,10 +105,10 @@ import org.rhq.core.pluginapi.inventory.ResourceComponent;
import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
-import org.rhq.core.pluginapi.migration.ResourceUpgradeContext;
-import org.rhq.core.pluginapi.migration.ResourceUpgradeFacet;
import org.rhq.core.pluginapi.operation.OperationContext;
import org.rhq.core.pluginapi.operation.OperationServices;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
import org.rhq.core.system.SystemInfo;
import org.rhq.core.system.SystemInfoFactory;
import org.rhq.core.util.exception.ThrowableUtil;
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/RuntimeDiscoveryExecutor.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/RuntimeDiscoveryExecutor.java
index c60d4a8..e31ffda 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/RuntimeDiscoveryExecutor.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/RuntimeDiscoveryExecutor.java
@@ -46,8 +46,8 @@ import org.rhq.core.pc.plugin.PluginComponentFactory;
import org.rhq.core.pluginapi.inventory.ProcessScanResult;
import org.rhq.core.pluginapi.inventory.ResourceComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
-import org.rhq.core.pluginapi.migration.ResourceUpgradeContext;
-import org.rhq.core.pluginapi.migration.ResourceUpgradeFacet;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
import org.rhq.core.util.exception.ExceptionPackage;
import org.rhq.core.util.exception.Severity;
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
index 4d80ac1..45887f6 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
@@ -46,8 +46,8 @@ import org.rhq.core.pluginapi.inventory.ProcessScanResult;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
import org.rhq.core.pluginapi.inventory.ManualAddFacet;
-import org.rhq.core.pluginapi.migration.ResourceUpgradeContext;
-import org.rhq.core.pluginapi.migration.ResourceUpgradeFacet;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
import org.rhq.core.pluginapi.util.FileUtils;
import org.rhq.core.system.ProcessInfo;
import org.rhq.plugins.apache.parser.ApacheConfigReader;
commit 15bea470c93d5a59c69cd8bea3dc0f0c2a728a37
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue May 25 18:17:02 2010 +0200
Update the resource with upgrade data only if the upgrade data is not null.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 8cc5280..feb2d81 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -1134,12 +1134,29 @@ public class InventoryManager extends AgentService implements ContainerService,
}
if (serverUpdated) {
- existingResource.setResourceKey(resourceKey);
- existingResource.setName(name);
- existingResource.setVersion(version);
- existingResource.setDescription(description);
- existingResource.setPluginConfiguration(pluginConfiguration);
- existingResource.setResourceConfiguration(resourceConfiguration);
+ if (resourceKey != null) {
+ existingResource.setResourceKey(resourceKey);
+ }
+
+ if (name != null) {
+ existingResource.setName(name);
+ }
+
+ if (version != null) {
+ existingResource.setVersion(version);
+ }
+
+ if (description != null) {
+ existingResource.setDescription(description);
+ }
+
+ if (pluginConfiguration != null) {
+ existingResource.setPluginConfiguration(pluginConfiguration);
+ }
+
+ if (resourceConfiguration != null) {
+ existingResource.setResourceConfiguration(resourceConfiguration);
+ }
}
return serverUpdated;
commit 5c77f642a72f50fcb0c89613def447c39fcd1308
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue May 25 14:10:02 2010 +0200
First version of plugin-driven resource upgrade.
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
index f542f57..cfa2459 100644
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
@@ -37,6 +37,7 @@ import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.domain.resource.ResourceErrorType;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
/**
* The interface to a JON server's resource discovery subsystem.
@@ -137,6 +138,15 @@ public interface DiscoveryServerService {
boolean updateResourceVersion(int resourceId, String version);
/**
+ * Upgrades the data of the resource according to the provided report.
+ *
+ * @param resourceId the id of the resource to be upgraded
+ * @param upgradeReport contains the information about the upgrade
+ * @return true if the upgrade succeeded, false otherwise.
+ */
+ boolean upgradeResource(int resourceId, ResourceUpgradeReport upgradeReport);
+
+ /**
* Gives the server a chance to apply any necessary post-processing that's needed for newly committed resources
* that have been successfully synchronized on the agent.
*
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
new file mode 100644
index 0000000..52acf09
--- /dev/null
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
@@ -0,0 +1,102 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.rhq.core.domain.resource;
+
+import java.io.Serializable;
+
+import org.rhq.core.domain.configuration.Configuration;
+
+/**
+ * Represents the changes that should be applied to the existing resource
+ * in order to upgrade it to conform to the new requirements set by the
+ * changed resource component.
+ * <p>
+ * Null values of the properties mean no change, non-null values represent
+ * the desired new values.
+ *
+ * @author Lukas Krejci
+ */
+public class ResourceUpgradeReport implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private String newResourceKey;
+ private String newName;
+ private String newVersion;
+ private Configuration newPluginConfiguration;
+ private Configuration newResourceConfiguration;
+ private String newDescription;
+
+ public ResourceUpgradeReport() {
+
+ }
+
+ public String getNewResourceKey() {
+ return newResourceKey;
+ }
+
+ public void setNewResourceKey(String newResourceKey) {
+ this.newResourceKey = newResourceKey;
+ }
+
+ public String getNewName() {
+ return newName;
+ }
+
+ public void setNewName(String newName) {
+ this.newName = newName;
+ }
+
+ public String getNewVersion() {
+ return newVersion;
+ }
+
+ public void setNewVersion(String newVersion) {
+ this.newVersion = newVersion;
+ }
+
+ public Configuration getNewPluginConfiguration() {
+ return newPluginConfiguration;
+ }
+
+ public void setNewPluginConfiguration(Configuration newPluginConfiguration) {
+ this.newPluginConfiguration = newPluginConfiguration;
+ }
+
+ public Configuration getNewResourceConfiguration() {
+ return newResourceConfiguration;
+ }
+
+ public void setNewResourceConfiguration(Configuration newResourceConfiguration) {
+ this.newResourceConfiguration = newResourceConfiguration;
+ }
+
+ public String getNewDescription() {
+ return newDescription;
+ }
+
+ public void setNewDescription(String newDescription) {
+ this.newDescription = newDescription;
+ }
+}
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeContext.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeContext.java
new file mode 100644
index 0000000..e8c5f03
--- /dev/null
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeContext.java
@@ -0,0 +1,89 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.rhq.core.pluginapi.migration;
+
+import java.io.File;
+import java.util.concurrent.Executor;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.pluginapi.content.ContentContext;
+import org.rhq.core.pluginapi.event.EventContext;
+import org.rhq.core.pluginapi.inventory.PluginContainerDeployment;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.operation.OperationContext;
+import org.rhq.core.system.SystemInfo;
+
+/**
+ * Represents a resource during the resource upgrade phase of discovery.
+ *
+ * @see ResourceUpgradeFacet
+ *
+ * @author Lukas Krejci
+ */
+@SuppressWarnings("unchecked")
+public class ResourceUpgradeContext<T extends ResourceComponent> extends ResourceContext<T> {
+
+ private final Configuration resourceConfiguration;
+ private final String name;
+ private final String description;
+
+ /**
+ * @see ResourceContext#ResourceContext(Resource, ResourceComponent, ResourceDiscoveryComponent, SystemInfo, File, File, String, EventContext, OperationContext, ContentContext, Executor, PluginContainerDeployment)
+ */
+ public ResourceUpgradeContext(Resource resource, T parentResourceComponent,
+ ResourceDiscoveryComponent resourceDiscoveryComponent, SystemInfo systemInfo, File temporaryDirectory,
+ File dataDirectory, String pluginContainerName, EventContext eventContext, OperationContext operationContext,
+ ContentContext contentContext, Executor availCollectorThreadPool,
+ PluginContainerDeployment pluginContainerDeployment) {
+
+ super(resource, parentResourceComponent, resourceDiscoveryComponent, systemInfo, temporaryDirectory, dataDirectory,
+ pluginContainerName, eventContext, operationContext, contentContext, availCollectorThreadPool,
+ pluginContainerDeployment);
+
+ this.resourceConfiguration = resource.getResourceConfiguration();
+ this.name = resource.getName();
+ this.description = resource.getDescription();
+ }
+
+ public ResourceUpgradeContext(Resource resource, ResourceDiscoveryComponent discoveryComponent, ResourceContext<T> context, Executor availCollectorThreadPool) {
+ this(resource, context.getParentResourceComponent(), discoveryComponent, context.getSystemInformation(), context.getTemporaryDirectory(),
+ context.getDataDirectory(), context.getPluginContainerName(), context.getEventContext(), context.getOperationContext(),
+ context.getContentContext(), availCollectorThreadPool, context.getPluginContainerDeployment());
+ }
+
+ public Configuration getResourceConfiguration() {
+ return resourceConfiguration;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+}
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeFacet.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeFacet.java
new file mode 100644
index 0000000..df372bf
--- /dev/null
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeFacet.java
@@ -0,0 +1,58 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.rhq.core.pluginapi.migration;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+
+/**
+ * This interface is to be implemented by discovery classes if they want to support
+ * upgrading the existing resources to a new format needed by an updated resource component.
+ * This is useful for example in the case when a new version of plugin redefined a resource
+ * key generation algorithm and wants to upgrade the legacy resources to use the new format.
+ *
+ * @author Lukas Krejci
+ */
+@SuppressWarnings("unchecked")
+public interface ResourceUpgradeFacet<T extends ResourceComponent> {
+
+ /**
+ * This method is called on the discovery component straight after it has finished the discovery.
+ * The exact same discovery results are passed to this method along with the set of resources
+ * that already exist in the inventory.
+ *
+ * @param inventoriedSimblings the existing resources
+ * @param parentContext the parent of both the newly discovered and existing resources
+ * @param discoveryResults the discovered resources. The resources from this set that have
+ * the same resource key as one of the inventoried siblings (after upgrade using the results of this method) won't
+ * be reported.
+ * @return the mapping of old resources to the newly desired data. The keys are instances from the
+ * inventoriedSiblings set, the values are the upgrade reports detailing what the data of the
+ * corresponding siblings should be upgraded to.
+ */
+ Map<ResourceUpgradeContext, ResourceUpgradeReport> upgrade(Set<ResourceUpgradeContext> inventoriedSimblings, ResourceUpgradeContext<T> parentContext, Set<ResourceUpgradeContext> discoveryResults);
+}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AutoDiscoveryExecutor.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AutoDiscoveryExecutor.java
index b84cdbc..e8abbbf 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AutoDiscoveryExecutor.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AutoDiscoveryExecutor.java
@@ -183,7 +183,7 @@ public class AutoDiscoveryExecutor implements Runnable, Callable<InventoryReport
List<ProcessScanResult> scanResults = performProcessScans(processInfos, serverType);
Set<Resource> discoveredServers = this.inventoryManager.executeComponentDiscovery(serverType,
- component, platformComponent, platformContainer.getResourceContext(), scanResults);
+ component, platformContainer, scanResults);
for (Resource discoveredServer : discoveredServers) {
log.debug("Detected server " + discoveredServer);
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 8944b99..8cc5280 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -70,6 +70,7 @@ import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceCreationDataType;
import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.domain.resource.ResourceErrorType;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.pc.ContainerService;
import org.rhq.core.pc.PluginContainer;
@@ -104,6 +105,8 @@ import org.rhq.core.pluginapi.inventory.ResourceComponent;
import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+import org.rhq.core.pluginapi.migration.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.migration.ResourceUpgradeFacet;
import org.rhq.core.pluginapi.operation.OperationContext;
import org.rhq.core.pluginapi.operation.OperationServices;
import org.rhq.core.system.SystemInfo;
@@ -1110,6 +1113,38 @@ public class InventoryManager extends AgentService implements ContainerService,
return resourceContainer.updateAvailability(availabilityType);
}
+ private boolean mergeResourceFromUpgrade(Resource existingResource, ResourceUpgradeReport upgradeReport) {
+ String resourceKey = upgradeReport.getNewResourceKey();
+ String name = upgradeReport.getNewName();
+ String version = upgradeReport.getNewVersion();
+ String description = upgradeReport.getNewDescription();
+ Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
+ Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
+
+ boolean serverUpdated = false;
+ try {
+ ServerServices serverServices = this.configuration.getServerServices();
+ if (serverServices != null) {
+ DiscoveryServerService discoveryServerService = serverServices.getDiscoveryServerService();
+
+ serverUpdated = discoveryServerService.upgradeResource(existingResource.getId(), upgradeReport);
+ }
+ } catch (Exception e) {
+ log.error("Failed to upgrade the resource [" + existingResource + "] on the server.", e);
+ }
+
+ if (serverUpdated) {
+ existingResource.setResourceKey(resourceKey);
+ existingResource.setName(name);
+ existingResource.setVersion(version);
+ existingResource.setDescription(description);
+ existingResource.setPluginConfiguration(pluginConfiguration);
+ existingResource.setResourceConfiguration(resourceConfiguration);
+ }
+
+ return serverUpdated;
+ }
+
public Resource mergeResourceFromDiscovery(Resource resource, Resource parent) throws PluginContainerException {
// If the Resource is already in inventory, make sure its version is up-to-date, then simply return the
// existing Resource.
@@ -1336,20 +1371,8 @@ public class InventoryManager extends AgentService implements ContainerService,
parentComponent = getResourceComponent(resource.getParentResource());
}
- File pluginDataDir = new File(this.configuration.getDataDirectory(), resource.getResourceType().getPlugin());
-
- ResourceContext context = new ResourceContext(resource, // the resource itself
- parentComponent, // its parent component
- discoveryComponent, // the discovery component (this is actually the proxy to it)
- SystemInfoFactory.createSystemInfo(), // for native access
- this.configuration.getTemporaryDirectory(), // location for plugin to write temp files
- pluginDataDir, // location for plugin to write data files
- this.configuration.getContainerName(), // the name of the agent/PC
- getEventContext(resource), // for event access
- getOperationContext(resource), // for operation manager access
- getContentContext(resource), // for content manager access
- this.availabilityCollectors, // for components that want to perform async avail checking
- this.configuration.getPluginContainerDeployment()); // helps components make determinations of what to do
+ ResourceContext context = createResourceContext(resource, parentComponent, discoveryComponent);
+
container.setResourceContext(context);
// Wrap the component in a proxy that will provide locking and a timeout for the call to start().
@@ -1396,6 +1419,23 @@ public class InventoryManager extends AgentService implements ContainerService,
}
}
+ private <T extends ResourceComponent> ResourceContext<T> createResourceContext(Resource resource, T parentComponent, ResourceDiscoveryComponent<T> discoveryComponent) {
+ File pluginDataDir = new File(this.configuration.getDataDirectory(), resource.getResourceType().getPlugin());
+
+ return new ResourceContext<T>(resource, // the resource itself
+ parentComponent, // its parent component
+ discoveryComponent, // the discovery component (this is actually the proxy to it)
+ SystemInfoFactory.createSystemInfo(), // for native access
+ this.configuration.getTemporaryDirectory(), // location for plugin to write temp files
+ pluginDataDir, // location for plugin to write data files
+ this.configuration.getContainerName(), // the name of the agent/PC
+ getEventContext(resource), // for event access
+ getOperationContext(resource), // for operation manager access
+ getContentContext(resource), // for content manager access
+ this.availabilityCollectors, // for components that want to perform async avail checking
+ this.configuration.getPluginContainerDeployment()); // helps components make determinations of what to do
+ }
+
/**
* This will send a resource error to the server (if applicable) to indicate that the given resource could not be
* connected to due to an invalid plugin configuration.
@@ -1960,8 +2000,12 @@ public class InventoryManager extends AgentService implements ContainerService,
@NotNull
Set<Resource> executeComponentDiscovery(ResourceType resourceType, ResourceDiscoveryComponent discoveryComponent,
- ResourceComponent parentComponent, ResourceContext parentResourceContext,
- List<ProcessScanResult> processScanResults) {
+ ResourceContainer parentContainer, List<ProcessScanResult> processScanResults) {
+
+ ResourceContext parentResourceContext = parentContainer.getResourceContext();
+ ResourceComponent parentComponent = parentContainer.getResourceComponent();
+ Resource parentResource = parentContainer.getResource();
+
long startTime = System.currentTimeMillis();
log.debug("Executing discovery for [" + resourceType.getName() + "] Resources...");
Set<Resource> newResources;
@@ -2000,6 +2044,59 @@ public class InventoryManager extends AgentService implements ContainerService,
newResources.add(newResource);
}
}
+
+ //check for upgrade support
+ if (discoveryComponent instanceof ResourceUpgradeFacet) {
+ ResourceUpgradeFacet resourceUpgrade = (ResourceUpgradeFacet) discoveryComponent;
+
+ Set<Resource> siblings = getResourcesWithType(resourceType, parentResource.getChildResources());
+
+ Resource grandParent = parentResource.getParentResource();
+ ResourceContainer grandParentContainer = grandParent == null ? null : getResourceContainer(grandParent);
+ ResourceDiscoveryComponent parentDiscoveryComponent = PluginContainer.getInstance().getPluginComponentFactory()
+ .getDiscoveryComponent(parentResource.getResourceType(), grandParentContainer);
+
+ ResourceUpgradeContext<?> parentUpgradeContext = new ResourceUpgradeContext(parentResource, parentDiscoveryComponent, parentResourceContext, availabilityCollectors);
+
+ Set<ResourceUpgradeContext> siblingContexts = new HashSet<ResourceUpgradeContext>(siblings.size());
+
+ Map<ResourceUpgradeContext, Resource> siblingContextToResource = new HashMap<ResourceUpgradeContext, Resource>();
+
+ for (Resource sibling : siblings) {
+ ResourceUpgradeContext siblingContext = new ResourceUpgradeContext(sibling, discoveryComponent, getResourceContainer(sibling).getResourceContext(), availabilityCollectors);
+ siblingContexts.add(siblingContext);
+ siblingContextToResource.put(siblingContext, sibling);
+ }
+
+ Set<ResourceUpgradeContext> newResourceContexts = new HashSet<ResourceUpgradeContext>();
+ Map<String, Resource> newResourceKeyToResource = new HashMap<String, Resource>();
+
+ for (Resource newResource : newResources) {
+ ResourceUpgradeContext newUpgradeContext = new ResourceUpgradeContext(newResource, discoveryComponent, createResourceContext(newResource, parentComponent, discoveryComponent), availabilityCollectors);
+ newResourceContexts.add(newUpgradeContext);
+ newResourceKeyToResource.put(newResource.getResourceKey(), newResource);
+ }
+
+ Map<ResourceUpgradeContext, ResourceUpgradeReport> results = resourceUpgrade.upgrade(siblingContexts, parentUpgradeContext, newResourceContexts);
+
+ for(Map.Entry<ResourceUpgradeContext, ResourceUpgradeReport> upgradeEntry : results.entrySet()) {
+ Resource siblingToUpgrade = siblingContextToResource.get(upgradeEntry.getKey());
+ ResourceUpgradeReport newData = upgradeEntry.getValue();
+
+ mergeResourceFromUpgrade(siblingToUpgrade, newData);
+
+ //if there was a resource key upgrade, remove a resource with the same resource key
+ //from the discovery results. Otherwise we'd end up with 2 sibling resources with
+ //the same resource key, which is illegal.
+ if (newData.getNewResourceKey() != null) {
+ Resource newResourceToRemove = newResourceKeyToResource.get(newData.getNewResourceKey());
+ if (newResourceToRemove != null) {
+ newResources.remove(newResourceToRemove);
+ }
+ }
+ }
+ }
+
} catch (Throwable e) {
// TODO GH: Add server/parent - up/down semantics so this won't happen just because a server is not up
long elapsedTime = System.currentTimeMillis() - startTime;
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/RuntimeDiscoveryExecutor.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/RuntimeDiscoveryExecutor.java
index c16ba56..c60d4a8 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/RuntimeDiscoveryExecutor.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/RuntimeDiscoveryExecutor.java
@@ -43,8 +43,11 @@ import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.pc.PluginContainer;
import org.rhq.core.pc.PluginContainerConfiguration;
import org.rhq.core.pc.plugin.PluginComponentFactory;
+import org.rhq.core.pluginapi.inventory.ProcessScanResult;
import org.rhq.core.pluginapi.inventory.ResourceComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.migration.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.migration.ResourceUpgradeFacet;
import org.rhq.core.util.exception.ExceptionPackage;
import org.rhq.core.util.exception.Severity;
@@ -237,8 +240,8 @@ public class RuntimeDiscoveryExecutor implements Runnable, Callable<InventoryRep
+ childResourceType + "]");
}
Set<Resource> childResources = this.inventoryManager.executeComponentDiscovery(childResourceType,
- discoveryComponent, parentComponent, parentContainer.getResourceContext(), Collections.EMPTY_LIST);
-
+ discoveryComponent, parentContainer, Collections.<ProcessScanResult>emptyList());
+
// For each discovered resource, update it in the inventory manager and recursively discover its child resources
Map<String, Resource> mergedResources = new HashMap<String, Resource>();
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index cded63b..2d3e9e6 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -56,6 +56,7 @@ import org.rhq.core.domain.resource.ProductVersion;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.domain.util.PageOrdering;
@@ -400,6 +401,19 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
}
}
+ public boolean upgradeResource(int resourceId, ResourceUpgradeReport upgradeReport) {
+ Resource existingResource = this.entityManager.find(Resource.class, resourceId);
+ if (existingResource != null) {
+ boolean changed = upgradeResource(existingResource, upgradeReport);
+ if (changed) {
+ this.entityManager.merge(existingResource);
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
/**
* Convienence method that looks at <code>resource</code> and if its version is not
* the same as <code>newVersion</code>, its version string will be set to it. If
@@ -445,6 +459,81 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
return versionChanged;
}
+ /**
+ * @param existingResource
+ * @param upgradeReport
+ * @return
+ */
+ private boolean upgradeResource(Resource resource, ResourceUpgradeReport upgradeReport) {
+ boolean changed = false;
+ if (resource != null) {
+ String resourceKey = upgradeReport.getNewResourceKey();
+ String name = upgradeReport.getNewName();
+ String version = upgradeReport.getNewVersion();
+ String description = upgradeReport.getNewDescription();
+ Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
+ Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
+
+ if (resourceKey != null) {
+ if (!equalOrNull(resourceKey, resource.getResourceKey())) {
+ log.info("Resource [" + resource + "] upgraded its resource key from [" +
+ resource.getResourceKey() + "] to [" + resourceKey + "]");
+ changed = true;
+ resource.setResourceKey(resourceKey);
+ }
+ }
+
+ if (name != null) {
+ if (!equalOrNull(name, resource.getName())) {
+ log.info("Resource [" + resource + "] upgraded its name from [" +
+ resource.getName() + "] to [" + name + "]");
+ changed = true;
+ resource.setName(name);
+ }
+ }
+
+ if (version != null) {
+ changed = updateResourceVersion(resource, version) || changed;
+ }
+
+ if (description != null) {
+ if (!equalOrNull(description, resource.getDescription())) {
+ log.info("Resource [" + resource + "] upgraded its description from [" +
+ resource.getDescription() + "] to [" + description + "]");
+ changed = true;
+ resource.setDescription(description);
+ }
+ }
+
+ if (pluginConfiguration != null) {
+ if (!equalOrNull(pluginConfiguration, resource.getPluginConfiguration())) {
+ log.info("Resource [" + resource + "] upgraded its plugin configuration from [" +
+ resource.getPluginConfiguration() + "] to [" + pluginConfiguration + "]");
+ changed = true;
+ resource.setPluginConfiguration(pluginConfiguration);
+ }
+ }
+
+ if (resourceConfiguration != null) {
+ if (!equalOrNull(resourceConfiguration, resource.getResourceConfiguration())) {
+ //XXX Will this create a new history entry?
+
+ log.info("Resource [" + resource + "] upgraded its resource configuration from [" +
+ resource.getResourceConfiguration() + "] to [" + resourceConfiguration + "]");
+
+ changed = true;
+ resource.setResourceConfiguration(resourceConfiguration);
+ }
+ }
+
+ // If the resource was marked as deleted, reactivate it again.
+ if (resource.getInventoryStatus() == InventoryStatus.DELETED) {
+ resource.setInventoryStatus(InventoryStatus.COMMITTED);
+ }
+ }
+ return changed;
+ }
+
private void validateInventoryReport(InventoryReport report) throws InvalidInventoryReportException {
for (Resource root : report.getAddedRoots()) {
validateResource(root);
@@ -793,4 +882,16 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
updateInventoryStatus(subject, platforms, servers, target);
}
+
+ private static <T> boolean equalOrNull(T a, T b) {
+ if (a == null) {
+ return b == null;
+ } else {
+ if (b == null) {
+ return false;
+ } else {
+ return a.equals(b);
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
index 01394b9..4e60ffb 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
@@ -38,6 +38,7 @@ import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
@@ -176,4 +177,13 @@ public interface DiscoveryBossLocal extends DiscoveryBossRemote {
* <code>false</code> if the Resource was not in inventory
*/
boolean updateResourceVersion(int resourceId, String version);
+
+ /**
+ * Upgrades the data of the resource according to the provided report.
+ *
+ * @param resourceId the id of the resource to be upgraded
+ * @param upgradeReport contains the information about the upgrade
+ * @return true if the upgrade succeeded, false otherwise.
+ */
+ boolean upgradeResource(int resourceId, ResourceUpgradeReport upgradeReport);
}
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
index d692ad8..720465e 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
@@ -37,6 +37,7 @@ import org.rhq.core.domain.resource.Agent;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceError;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.util.collection.ArrayUtils;
import org.rhq.core.util.exception.ThrowableUtil;
import org.rhq.enterprise.server.alert.AlertDefinitionCreationException;
@@ -176,6 +177,11 @@ public class DiscoveryServerServiceImpl implements DiscoveryServerService {
return discoveryBoss.updateResourceVersion(resourceId, version);
}
+ public boolean upgradeResource(int resourceId, ResourceUpgradeReport upgradeReport) {
+ DiscoveryBossLocal discoveryBoss = LookupUtil.getDiscoveryBoss();
+ return discoveryBoss.upgradeResource(resourceId, upgradeReport);
+ }
+
private static Resource convertToPojoResource(Resource resource, boolean includeDescendants) {
Resource pojoResource = new Resource(resource.getId());
pojoResource.setUuid(resource.getUuid());
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
index 8f6deb7..4d80ac1 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
@@ -21,8 +21,10 @@ package org.rhq.plugins.apache;
import java.io.File;
import java.io.IOException;
import java.net.URI;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
@@ -36,12 +38,16 @@ import org.rhq.augeas.util.GlobFilter;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.Property;
import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
import org.rhq.core.pluginapi.inventory.ManualAddFacet;
import org.rhq.core.pluginapi.inventory.ProcessScanResult;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+import org.rhq.core.pluginapi.inventory.ManualAddFacet;
+import org.rhq.core.pluginapi.migration.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.migration.ResourceUpgradeFacet;
import org.rhq.core.pluginapi.util.FileUtils;
import org.rhq.core.system.ProcessInfo;
import org.rhq.plugins.apache.parser.ApacheConfigReader;
@@ -63,7 +69,8 @@ import org.rhq.rhqtransform.impl.PluginDescriptorBasedAugeasConfiguration;
* @author Ian Springer
* @author Lukas Krejci
*/
-public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponent<PlatformComponent>, ManualAddFacet<PlatformComponent> {
+public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponent<PlatformComponent>, ManualAddFacet<PlatformComponent>,
+ ResourceUpgradeFacet<PlatformComponent> {
private static final String PRODUCT_DESCRIPTION = "Apache Web Server";
private static final Log log = LogFactory.getLog(ApacheServerDiscoveryComponent.class);
@@ -163,7 +170,46 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
return discoveredResources;
}
-
+ public Map<ResourceUpgradeContext, ResourceUpgradeReport> upgrade(Set<ResourceUpgradeContext> inventoriedSimblings,
+ ResourceUpgradeContext<PlatformComponent> parentContext, Set<ResourceUpgradeContext> discoveryResults) {
+
+ Map<ResourceUpgradeContext, ResourceUpgradeReport> ret = new HashMap<ResourceUpgradeContext, ResourceUpgradeReport>();
+
+ for (ResourceUpgradeContext context : inventoriedSimblings) {
+ String inventoriedResourceKey = context.getResourceKey();
+ File inventoriedResourceKeyAsPath = new File(inventoriedResourceKey);
+
+ //the resource key we use now is a full path to the httpdconf.
+ //in the old version, it was the server root.
+ //so if the inventoried resource key is a path to a file,
+ //we know it's a new style resource key.
+ if (inventoriedResourceKeyAsPath.isFile()) {
+ continue;
+ }
+
+ Configuration pluginConfiguration = context.getPluginConfiguration();
+
+ String serverRoot = pluginConfiguration.getSimpleValue("serverRoot", null);
+ String httpdConf = pluginConfiguration.getSimpleValue("configFile", null);
+
+ String resourceKey = null;
+
+ if (httpdConf != null) {
+ File httpdConfFile = new File(httpdConf);
+ if (!httpdConfFile.isAbsolute()) {
+ httpdConfFile = new File(serverRoot, httpdConf);
+ }
+
+ resourceKey = httpdConfFile.getPath();
+
+ ResourceUpgradeReport rep = new ResourceUpgradeReport();
+ rep.setNewResourceKey(resourceKey);
+
+ ret.put(context, rep);
+ }
+ }
+ return ret;
+ }
public DiscoveredResourceDetails discoverResource(Configuration pluginConfig,
ResourceDiscoveryContext<PlatformComponent> discoveryContext)
13 years, 7 months
[rhq] 63 commits - modules/core modules/enterprise modules/plugins
by lkrejci
modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/PluginMetadataManager.java | 5
modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java | 154 +++
modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeResponse.java | 80 +
modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java | 12
modules/core/dbutils/src/main/scripts/dbsetup/sysconfig-data.xml | 3
modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceErrorType.java | 7
modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java | 121 ++
modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ResourceErrorTest.java | 4
modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeContext.java | 89 +
modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java | 45
modules/core/plugin-container/pom.xml | 146 ++
modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java | 2
modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AutoDiscoveryExecutor.java | 2
modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java | 470 +++++++--
modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/RuntimeDiscoveryExecutor.java | 7
modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginComponentFactory.java | 15
modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/DiscoverySuspendedException.java | 50 +
modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java | 267 +++++
modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/DiscoveryComponentProxyFactory.java | 10
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java | 352 +++++++
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ForwardingProxy.java | 72 +
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java | 493 ++++++++++
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java | 331 ++++++
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java | 413 ++++++++
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/DiscComponent.java | 70 +
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/ResComponent.java | 46
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/rhq-plugin.xml | 18
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseDiscoveryComponent.java | 80 +
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponent.java | 118 ++
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponentInterface.java | 36
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java | 68 +
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/NothingDiscoveringDiscoveryComponent.java | 42
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/rhq-plugin.xml | 39
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/rhq-plugin.xml | 32
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/rhq-plugin.xml | 31
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml | 32
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml | 31
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/root/rhq-plugin.xml | 25
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml | 28
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml | 25
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml | 45
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml | 43
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/DiscComponent.java | 22
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/ResComponent.java | 21
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/rhq-plugin.xml | 18
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/DiscComponent.java | 54 +
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/ResComponent.java | 21
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/rhq-plugin.xml | 18
modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java | 42
modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/i18n/AgentI18NResourceKeys.java | 3
modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/promptcmd/DiscoveryPromptCommand.java | 2
modules/enterprise/agent/src/test/java/org/rhq/enterprise/agent/PluginContainerConditionalRestart.java | 31
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java | 5
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewForm.java | 299 ++++++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java | 327 +-----
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ResourceErrorsDataSource.java | 100 ++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java | 5
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java | 9
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/config/SystemConfigForm.java | 15
modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties | 2
modules/enterprise/gui/portal-war/src/main/webapp/admin/config/GeneralPropertiesConfigForm.jsp | 104 --
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/RHQConstants.java | 3
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java | 111 ++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java | 14
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java | 8
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java | 34
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java | 13
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java | 152 +--
68 files changed, 4835 insertions(+), 557 deletions(-)
New commits:
commit 4969aa53cf7f5ff45fbb1510d2f110560f3f6a8f
Merge: 065319e... 1b86f3a...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Oct 5 14:18:01 2010 +0200
Merge branch '_resource-upgrade' into resource-upgrade
commit 1b86f3abaf44ebb4e0d62cb75a559b130500cd9f
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Oct 5 14:17:46 2010 +0200
BZ 593270 - the new style resource key for apache is <server-root>||<httpd-conf>. Implemented the ResourceUpgradeFacet to upgrade existing resources to that new format.
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
index 660f727..ca8f972 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
@@ -170,38 +170,24 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
public ResourceUpgradeReport upgrade(ResourceUpgradeContext<PlatformComponent> context) {
String inventoriedResourceKey = context.getResourceKey();
- File inventoriedResourceKeyAsPath = new File(inventoriedResourceKey);
- //the resource key we use now is a full path to the httpd.conf.
- //in the old version, it was the server root.
- //so if the inventoried resource key is a path to a file,
- //we know it's a new style resource key.
- if (inventoriedResourceKeyAsPath.isFile()) {
+ //check if the inventoried resource has the old format of the resource key.
+ //the old format was "server-root", while the new format
+ //is "server-root||httpd-conf". Checking for "||" in the resource key is therefore
+ //enough.
+ if (inventoriedResourceKey.contains("||")) {
return null;
}
+
+ //all the information we need for the new style resource key is
+ //actually present in the plugin configuration of the existing resource
+ //already, so let's just generate the new style resource key from it.
+ String resourceKey = formatResourceKey(context.getPluginConfiguration());
- Configuration pluginConfiguration = context.getPluginConfiguration();
+ ResourceUpgradeReport rep = new ResourceUpgradeReport();
+ rep.setNewResourceKey(resourceKey);
- String serverRoot = pluginConfiguration.getSimpleValue("serverRoot", null);
- String httpdConf = pluginConfiguration.getSimpleValue("configFile", null);
-
- String resourceKey = null;
-
- if (httpdConf != null) {
- File httpdConfFile = new File(httpdConf);
- if (!httpdConfFile.isAbsolute()) {
- httpdConfFile = new File(serverRoot, httpdConf);
- }
-
- resourceKey = httpdConfFile.getPath();
-
- ResourceUpgradeReport rep = new ResourceUpgradeReport();
- rep.setNewResourceKey(resourceKey);
-
- return rep;
- }
-
- return null;
+ return rep;
}
public DiscoveredResourceDetails discoverResource(Configuration pluginConfig,
@@ -256,15 +242,7 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
name = uri.getHost() + ":" + uri.getPort();
}
- String serverRoot = pluginConfig.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_SERVER_ROOT)
- .getStringValue();
-
- String key = FileUtils.getCanonicalPath(serverRoot);
-
- //BZ 612189 - reverting to the serverRoot as the resource key temporarily until we have the resource
- //upgrade functionality ready (BZ 592038). Uncommenting the line below will make the resource key totally unique
- //(see BZ 593270).
- //key += "|" + httpdConf;
+ String key = formatResourceKey(pluginConfig);
DiscoveredResourceDetails resourceDetails = new DiscoveredResourceDetails(discoveryContext.getResourceType(),
key, name, version, PRODUCT_DESCRIPTION, pluginConfig, processInfo);
@@ -455,4 +433,14 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
}
return null;
}
+
+ private static String formatResourceKey(Configuration pluginConfiguration) {
+ String serverRoot = pluginConfiguration.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_SERVER_ROOT).getStringValue();
+ String httpdConf = pluginConfiguration.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_HTTPD_CONF).getStringValue();
+
+ serverRoot = FileUtils.getCanonicalPath(serverRoot);
+ httpdConf = FileUtils.getCanonicalPath(httpdConf);
+
+ return serverRoot + "||" + httpdConf;
+ }
}
commit a0edcceda8b63f23cc6570fb1da34251f245f3c0
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Oct 5 13:35:57 2010 +0200
code formatting
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
index c305ec4..660f727 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
@@ -21,18 +21,14 @@ package org.rhq.plugins.apache;
import java.io.File;
import java.io.IOException;
import java.net.URI;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.rhq.augeas.node.AugeasNode;
-import org.rhq.augeas.tree.AugeasTree;
import org.rhq.augeas.util.Glob;
import org.rhq.augeas.util.GlobFilter;
import org.rhq.core.domain.configuration.Configuration;
@@ -45,7 +41,6 @@ import org.rhq.core.pluginapi.inventory.ManualAddFacet;
import org.rhq.core.pluginapi.inventory.ProcessScanResult;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
-import org.rhq.core.pluginapi.inventory.ManualAddFacet;
import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
import org.rhq.core.pluginapi.util.FileUtils;
@@ -58,8 +53,8 @@ import org.rhq.plugins.apache.parser.ApacheParserImpl;
import org.rhq.plugins.apache.util.ApacheBinaryInfo;
import org.rhq.plugins.apache.util.AugeasNodeValueUtil;
import org.rhq.plugins.apache.util.HttpdAddressUtility;
-import org.rhq.plugins.apache.util.OsProcessUtility;
import org.rhq.plugins.apache.util.HttpdAddressUtility.Address;
+import org.rhq.plugins.apache.util.OsProcessUtility;
import org.rhq.plugins.platform.PlatformComponent;
import org.rhq.rhqtransform.impl.PluginDescriptorBasedAugeasConfiguration;
@@ -69,13 +64,14 @@ import org.rhq.rhqtransform.impl.PluginDescriptorBasedAugeasConfiguration;
* @author Ian Springer
* @author Lukas Krejci
*/
-public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponent<PlatformComponent>, ManualAddFacet<PlatformComponent>,
- ResourceUpgradeFacet<PlatformComponent> {
+public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponent<PlatformComponent>,
+ ManualAddFacet<PlatformComponent>, ResourceUpgradeFacet<PlatformComponent> {
private static final String PRODUCT_DESCRIPTION = "Apache Web Server";
private static final Log log = LogFactory.getLog(ApacheServerDiscoveryComponent.class);
- public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext<PlatformComponent> discoveryContext) throws Exception {
+ public Set<DiscoveredResourceDetails>
+ discoverResources(ResourceDiscoveryContext<PlatformComponent> discoveryContext) throws Exception {
Set<DiscoveredResourceDetails> discoveredResources = new HashSet<DiscoveredResourceDetails>();
// Process any PC-discovered OS processes...
@@ -89,16 +85,16 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
continue;
}
if (!executablePath.isAbsolute()) {
- log.error("Executable path (" + executablePath + ") is not absolute for Apache [" +
- process.getProcessInfo() + "]." +
- "Please restart Apache specifying an absolute path for the executable.");
+ log.error("Executable path (" + executablePath + ") is not absolute for Apache ["
+ + process.getProcessInfo() + "]."
+ + "Please restart Apache specifying an absolute path for the executable.");
continue;
}
log.debug("Apache executable path: " + executablePath);
ApacheBinaryInfo binaryInfo;
try {
- binaryInfo = ApacheBinaryInfo.getInfo(executablePath.getPath(),
- discoveryContext.getSystemInformation());
+ binaryInfo = ApacheBinaryInfo
+ .getInfo(executablePath.getPath(), discoveryContext.getSystemInformation());
} catch (Exception e) {
log.error("'" + executablePath + "' is not a valid Apache executable (" + e + ").");
continue;
@@ -130,38 +126,40 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
PropertySimple configFile = new PropertySimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_HTTPD_CONF,
serverConfigFile);
pluginConfig.put(configFile);
-
- PropertySimple inclusionGlobs = new PropertySimple(PluginDescriptorBasedAugeasConfiguration.INCLUDE_GLOBS_PROP, serverConfigFile);
+
+ PropertySimple inclusionGlobs = new PropertySimple(
+ PluginDescriptorBasedAugeasConfiguration.INCLUDE_GLOBS_PROP, serverConfigFile);
pluginConfig.put(inclusionGlobs);
-
- ApacheDirectiveTree serverConfig = loadParser(serverConfigFile.getAbsolutePath(),serverRoot);
-
+
+ ApacheDirectiveTree serverConfig = loadParser(serverConfigFile.getAbsolutePath(), serverRoot);
+
String serverUrl = null;
String vhostsGlobInclude = null;
-
+
//now check if the httpd.conf doesn't redefine the ServerRoot
List<ApacheDirective> serverRoots = serverConfig.search("/ServerRoot");
if (!serverRoots.isEmpty()) {
serverRoot = AugeasNodeValueUtil.unescape(serverRoots.get(0).getValuesAsString());
serverRootProp.setValue(serverRoot);
- }
+ }
+
+ serverUrl = getUrl(serverConfig, binaryInfo.getVersion());
+ vhostsGlobInclude = scanForGlobInclude(serverConfig);
- serverUrl = getUrl(serverConfig, binaryInfo.getVersion());
- vhostsGlobInclude = scanForGlobInclude(serverConfig);
-
if (serverUrl != null) {
Property urlProp = new PropertySimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_URL, serverUrl);
- pluginConfig.put(urlProp);
+ pluginConfig.put(urlProp);
}
-
+
if (vhostsGlobInclude != null) {
- pluginConfig.put(new PropertySimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_VHOST_FILES_MASK, vhostsGlobInclude));
- }else
- {
+ pluginConfig.put(new PropertySimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_VHOST_FILES_MASK,
+ vhostsGlobInclude));
+ } else {
if (serverConfigFile.exists())
- pluginConfig.put(new PropertySimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_VHOST_FILES_MASK, serverConfigFile.getParent()+File.separator+"*"));
+ pluginConfig.put(new PropertySimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_VHOST_FILES_MASK,
+ serverConfigFile.getParent() + File.separator + "*"));
}
-
+
discoveredResources.add(createResourceDetails(discoveryContext, pluginConfig, process.getProcessInfo(),
binaryInfo));
}
@@ -202,18 +200,16 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
return rep;
}
-
+
return null;
}
public DiscoveredResourceDetails discoverResource(Configuration pluginConfig,
- ResourceDiscoveryContext<PlatformComponent> discoveryContext)
- throws InvalidPluginConfigurationException {
+ ResourceDiscoveryContext<PlatformComponent> discoveryContext) throws InvalidPluginConfigurationException {
validateServerRootAndServerConfigFile(pluginConfig);
- String executablePath = pluginConfig
- .getSimpleValue(ApacheServerComponent.PLUGIN_CONFIG_PROP_EXECUTABLE_PATH,
- ApacheServerComponent.DEFAULT_EXECUTABLE_PATH);
+ String executablePath = pluginConfig.getSimpleValue(ApacheServerComponent.PLUGIN_CONFIG_PROP_EXECUTABLE_PATH,
+ ApacheServerComponent.DEFAULT_EXECUTABLE_PATH);
String absoluteExecutablePath = ApacheServerComponent.resolvePathRelativeToServerRoot(pluginConfig,
executablePath).getPath();
ApacheBinaryInfo binaryInfo;
@@ -222,13 +218,12 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
} catch (Exception e) {
throw new InvalidPluginConfigurationException("'" + absoluteExecutablePath
+ "' is not a valid Apache executable (" + e + "). Please make sure the '"
- + ApacheServerComponent.PLUGIN_CONFIG_PROP_EXECUTABLE_PATH
- + "' connection property is set correctly.");
+ + ApacheServerComponent.PLUGIN_CONFIG_PROP_EXECUTABLE_PATH + "' connection property is set correctly.");
}
if (!isSupportedVersion(binaryInfo.getVersion())) {
- throw new InvalidPluginConfigurationException("Version of Apache executable ("
- + binaryInfo.getVersion() + ") is not a supported version; supported versions are 1.3.x and 2.x.");
+ throw new InvalidPluginConfigurationException("Version of Apache executable (" + binaryInfo.getVersion()
+ + ") is not a supported version; supported versions are 1.3.x and 2.x.");
}
ProcessInfo processInfo = null;
@@ -236,8 +231,7 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
DiscoveredResourceDetails resourceDetails = createResourceDetails(discoveryContext, pluginConfig,
processInfo, binaryInfo);
return resourceDetails;
- }
- catch (Exception e) {
+ } catch (Exception e) {
throw new RuntimeException("Failed to create resource details during manual add.");
}
}
@@ -247,8 +241,9 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
return (version != null) && (version.startsWith("1.3") || version.startsWith("2."));
}
- private DiscoveredResourceDetails createResourceDetails(ResourceDiscoveryContext<PlatformComponent> discoveryContext,
- Configuration pluginConfig, ProcessInfo processInfo, ApacheBinaryInfo binaryInfo) throws Exception {
+ private DiscoveredResourceDetails createResourceDetails(
+ ResourceDiscoveryContext<PlatformComponent> discoveryContext, Configuration pluginConfig,
+ ProcessInfo processInfo, ApacheBinaryInfo binaryInfo) throws Exception {
String httpdConf = pluginConfig.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_HTTPD_CONF).getStringValue();
String version = binaryInfo.getVersion();
String serverUrl = pluginConfig.getSimpleValue(ApacheServerComponent.PLUGIN_CONFIG_PROP_URL, null);
@@ -258,19 +253,19 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
name = httpdConf;
} else {
URI uri = new URI(serverUrl);
- name = uri.getHost() + ":" + uri.getPort();
+ name = uri.getHost() + ":" + uri.getPort();
}
String serverRoot = pluginConfig.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_SERVER_ROOT)
.getStringValue();
-
+
String key = FileUtils.getCanonicalPath(serverRoot);
//BZ 612189 - reverting to the serverRoot as the resource key temporarily until we have the resource
//upgrade functionality ready (BZ 592038). Uncommenting the line below will make the resource key totally unique
//(see BZ 593270).
//key += "|" + httpdConf;
-
+
DiscoveredResourceDetails resourceDetails = new DiscoveredResourceDetails(discoveryContext.getResourceType(),
key, name, version, PRODUCT_DESCRIPTION, pluginConfig, processInfo);
log.debug("Apache Server resource details created: " + resourceDetails);
@@ -290,7 +285,6 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
return addr == null ? null : "http://" + addr.host + ":" + addr.port + "/";
}
-
@Nullable
private String getServerRoot(@NotNull ApacheBinaryInfo binaryInfo, @NotNull ProcessInfo processInfo) {
// First see if -d was specified on the httpd command line.
@@ -315,12 +309,12 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
currentWorkingDir = processInfo.getCurrentWorkingDirectory();
} catch (Exception e) {
log.error("Unable to determine current working directory of Apache process [" + processInfo
- + "], which is needed to determine the server root of the Apache instance.", e);
+ + "], which is needed to determine the server root of the Apache instance.", e);
return null;
}
if (currentWorkingDir == null) {
log.error("Unable to determine current working directory of Apache process [" + processInfo
- + "], which is needed to determine the server root of the Apache instance.");
+ + "], which is needed to determine the server root of the Apache instance.");
return null;
} else {
rootFile = new File(currentWorkingDir, root);
@@ -396,12 +390,12 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
}
private static void validateServerRootAndServerConfigFile(Configuration pluginConfig) {
- String serverRoot = pluginConfig.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_SERVER_ROOT).getStringValue();
+ String serverRoot = pluginConfig.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_SERVER_ROOT)
+ .getStringValue();
File serverRootFile;
try {
serverRootFile = new File(serverRoot).getCanonicalFile(); // this will resolve symlinks
- }
- catch (IOException e) {
+ } catch (IOException e) {
serverRootFile = null;
}
if (serverRootFile == null || !serverRootFile.isDirectory()) {
@@ -413,8 +407,7 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
File httpdConfFile;
try {
httpdConfFile = new File(httpdConf).getCanonicalFile(); // this will resolve symlinks
- }
- catch (IOException e) {
+ } catch (IOException e) {
httpdConfFile = null;
}
if (httpdConfFile == null || !httpdConfFile.isFile()) {
@@ -423,15 +416,15 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
+ ApacheServerComponent.PLUGIN_CONFIG_PROP_HTTPD_CONF + "' connection property is set correctly.");
}
}
-
- private static ApacheDirectiveTree loadParser(String path,String serverRoot) throws Exception{
+
+ private static ApacheDirectiveTree loadParser(String path, String serverRoot) throws Exception {
ApacheDirectiveTree tree = new ApacheDirectiveTree();
- ApacheParser parser = new ApacheParserImpl(tree,serverRoot);
+ ApacheParser parser = new ApacheParserImpl(tree, serverRoot);
ApacheConfigReader.buildTree(path, parser);
return tree;
}
-
+
public static String scanForGlobInclude(ApacheDirectiveTree tree) {
try {
List<ApacheDirective> includes = tree.search("/Include");
@@ -440,9 +433,9 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
if (Glob.isWildcard(include)) {
//we only take the '*.something' into account here
//so that we have a useful mask to base the file names on.
-
+
//the only special glob character allowed is *.
- for(char specialChar : GlobFilter.WILDCARD_CHARS) {
+ for (char specialChar : GlobFilter.WILDCARD_CHARS) {
if (specialChar == '*') {
if (include.indexOf(specialChar) != include.lastIndexOf(specialChar)) {
//more than 1 star... that's too much
@@ -462,4 +455,4 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
}
return null;
}
-}
\ No newline at end of file
+}
commit 065319e2048376d93509e31dd526789b26947b4f
Merge: 98a4d17... 297cc73...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Oct 5 12:49:38 2010 +0200
Merge branch 'master' into resource-upgrade
commit 98a4d17665d0fed83e0fd2c28770545178b00150
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Oct 5 12:48:12 2010 +0200
making the getResourcesWithType(ResourceType, Set<Resource>) private again.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index c5004dd..351f751 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -1668,7 +1668,7 @@ public class InventoryManager extends AgentService implements ContainerService,
return getResourcesWithType(serverType, this.platform.getChildResources());
}
- public Set<Resource> getResourcesWithType(ResourceType serverType, Set<Resource> resources) {
+ private Set<Resource> getResourcesWithType(ResourceType serverType, Set<Resource> resources) {
Set<Resource> servers = new HashSet<Resource>();
if (resources == null) {
commit 98ab21b9a9348520b30fae149d67d39af7553373
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Oct 4 18:58:14 2010 +0200
Getting the InventoryManager.handleReport(InventoryReport) inline with the version in master, updating the upgrade tests to accommodate for the changed behavior.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index ec40b0c..c5004dd 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -932,30 +932,16 @@ public class InventoryManager extends AgentService implements ContainerService,
}
/**
- * @see #handleReport(InventoryReport, boolean)
- * @param report
- * @return
- */
- public boolean handleReport(InventoryReport report) {
- return handleReport(report, false);
- }
-
- /**
* Send an inventory report to the Server.
*
* @param report the inventory report to be sent
- * @param forceServerRoundtrip whether to report to the server even if there are no resources to report.
* @return true if sending the report to the Server succeeded, or false otherwise
*/
- public boolean handleReport(InventoryReport report, boolean forceServerRoundtrip) {
+ public boolean handleReport(InventoryReport report) {
if (!configuration.isInsideAgent()) {
return true;
}
- if (report.getAddedRoots().isEmpty() && !forceServerRoundtrip) {
- return true; // nothing to do
- }
-
ResourceSyncInfo syncInfo;
try {
String reportType = (report.isRuntimeReport()) ? "runtime" : "server";
@@ -2659,7 +2645,7 @@ public class InventoryManager extends AgentService implements ContainerService,
log.debug("Executing resource upgrade.");
- boolean syncResult = handleReport(new InventoryReport(getAgent()), true);
+ boolean syncResult = handleReport(new InventoryReport(getAgent()));
if (!syncResult) {
log.warn("Resource upgrade failed to sync up the inventory with the server.");
return;
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
index ebb73be..ab1cd2b 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
@@ -342,10 +342,6 @@ public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase
expectations.allowing(getCurrentDiscoveryServerService()).upgradeResources(
expectations.with(Expectations.any(Set.class)));
expectations.will(getCurrentServerSideInventory().upgradeResources());
-
- expectations.allowing(getCurrentDiscoveryServerService()).postProcessNewlyCommittedResources(
- expectations.with(Expectations.any(Set.class)));
-
} catch (InvalidInventoryReportException e) {
//this is not going to happen because we're mocking the invocation
}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 8b966c3..e2a8a84 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -93,7 +93,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
{
defineDefaultExpectations(this);
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ allowing(getCurrentDiscoveryServerService()).mergeInventoryReport(
with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
@@ -144,7 +144,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
{
defineDefaultExpectations(this);
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ allowing(getCurrentDiscoveryServerService()).mergeInventoryReport(
with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
@@ -197,7 +197,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
//the rest of the inventory merges are executed by discoveries, so let's import the
//discovered stuff into the server-side inventory.
- between(1, 3).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ allowing(getCurrentDiscoveryServerService()).mergeInventoryReport(
with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
@@ -242,7 +242,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
{
defineDefaultExpectations(this);
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ allowing(getCurrentDiscoveryServerService()).mergeInventoryReport(
with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
@@ -276,7 +276,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
{
defineDefaultExpectations(this);
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ allowing(getCurrentDiscoveryServerService()).mergeInventoryReport(
with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(requiredInventoryStatus));
}
@@ -317,7 +317,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
{
defineDefaultExpectations(this);
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ allowing(getCurrentDiscoveryServerService()).mergeInventoryReport(
with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
index 0aefafd..c299cce 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
@@ -402,6 +402,9 @@ public abstract class ResourceUpgradeTestBase {
expectations.allowing(getCurrentDiscoveryServerService()).getResources(
expectations.with(Expectations.any(Set.class)), expectations.with(Expectations.any(boolean.class)));
expectations.will(getCurrentServerSideInventory().getResources());
+
+ expectations.allowing(getCurrentDiscoveryServerService()).postProcessNewlyCommittedResources(
+ expectations.with(Expectations.any(Set.class)));
}
protected void cleanDataDir() throws IOException {
commit 65c3b23735a092f9675cb2e878b79039b5ab9c93
Merge: e7fb6ed... ebd4ec6...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Oct 4 18:37:55 2010 +0200
Merge branch 'master' into resource-upgrade
diff --cc modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
index 150a692,4e14b75..a004680
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
@@@ -238,11 -274,11 +275,15 @@@ public class ResourceGWTServiceImpl ext
}
public void unignoreResources(Integer[] resourceIds) {
- discoveryBoss.unignoreResources(getSessionSubject(), resourceIds);
+ try {
+ discoveryBoss.unignoreResources(getSessionSubject(), resourceIds);
+ } catch (Exception e) {
+ throw new RuntimeException(ThrowableUtil.getAllMessages(e));
+ }
}
-
-}
+
+ public List<ResourceError> findResourceErrors(int resourceId) {
+ return SerialUtility.prepare(resourceManager.findResourceErrors(getSessionSubject(), resourceId),
+ "ResourceService.getResourceErrors");
+ }
+}
commit e7fb6edacd4c172a236cfc39b19096f03cef85ee
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Oct 4 18:34:25 2010 +0200
Discovery now recurses to child resource types of the existing resources even if the discovery of the existing resources' type is disallowed due to upgrade failure.
This means that no new siblings will be discovered but the existing resources "contents" will be up-to-date with the plugin version.
Added tests for this behaviour and updated the existing to reflect the changes.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 99a0513..ec40b0c 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -91,6 +91,7 @@ import org.rhq.core.pc.plugin.BlacklistedException;
import org.rhq.core.pc.plugin.CanonicalResourceKey;
import org.rhq.core.pc.plugin.PluginComponentFactory;
import org.rhq.core.pc.plugin.PluginManager;
+import org.rhq.core.pc.upgrade.DiscoverySuspendedException;
import org.rhq.core.pc.upgrade.ResourceUpgradeDelegate;
import org.rhq.core.pc.util.DiscoveryComponentProxyFactory;
import org.rhq.core.pc.util.FacetLockType;
@@ -289,18 +290,22 @@ public class InventoryManager extends AgentService implements ContainerService,
* @param context the context for use by the discovery component
* @return the details of all discovered resources, may be empty or <code>null</code>
*
+ * @throws DiscoverySuspendedException if the discovery is suspended due to a resource upgrade failure
* @throws Exception if the discovery component threw an exception
*/
public Set<DiscoveredResourceDetails> invokeDiscoveryComponent(ResourceContainer parentResourceContainer,
- ResourceDiscoveryComponent component, ResourceDiscoveryContext context) throws Exception {
+ ResourceDiscoveryComponent component, ResourceDiscoveryContext context) throws DiscoverySuspendedException, Exception {
Resource parentResource = parentResourceContainer == null ? null : parentResourceContainer.getResource();
if (resourceUpgradeDelegate.hasUpgradeFailedInChildren(parentResource, context.getResourceType())) {
- log.debug("Discovery of [" + context.getResourceType() + "] has been disallowed under "
- + (parentResource == null ? " the platform " : parentResource)
- + " because some of its siblings failed to upgrade.");
- return null;
+ String message = "Discovery of [" + context.getResourceType() + "] has been suspended under "
+ + (parentResource == null ? " the platform " : parentResource)
+ + " because some of its siblings failed to upgrade.";
+
+ log.debug(message);
+
+ throw new DiscoverySuspendedException(message);
}
long timeout = getDiscoveryComponentTimeout(context.getResourceType());
@@ -699,19 +704,29 @@ public class InventoryManager extends AgentService implements ContainerService,
// Ask the plugin's discovery component to find the new resource, throwing exceptions if it cannot be
// found at all.
- Set<DiscoveredResourceDetails> discoveredResources = invokeDiscoveryComponent(parentResourceContainer,
- discoveryComponent, discoveryContext);
- if ((discoveredResources == null) || discoveredResources.isEmpty()) {
- log.info("Plugin Error: During manual add, discovery component method ["
- + discoveryComponent.getClass().getName() + ".discoverResources()] returned "
- + discoveredResources + " when passed a single plugin configuration "
- + "(either the resource type was blacklisted or the plugin developer "
- + "did not implement support for manually discovered resources correctly).");
- throw new PluginContainerException("The [" + resourceType.getPlugin()
- + "] plugin does not properly support manual addition of [" + resourceType.getName()
- + "] resources.");
+ try {
+ Set<DiscoveredResourceDetails> discoveredResources = invokeDiscoveryComponent(parentResourceContainer,
+ discoveryComponent, discoveryContext);
+ if ((discoveredResources == null) || discoveredResources.isEmpty()) {
+ log.info("Plugin Error: During manual add, discovery component method ["
+ + discoveryComponent.getClass().getName() + ".discoverResources()] returned "
+ + discoveredResources + " when passed a single plugin configuration "
+ + "(either the resource type was blacklisted or the plugin developer "
+ + "did not implement support for manually discovered resources correctly).");
+ throw new PluginContainerException("The [" + resourceType.getPlugin()
+ + "] plugin does not properly support manual addition of [" + resourceType.getName()
+ + "] resources.");
+ }
+ discoveredResourceDetails = discoveredResources.iterator().next();
+ } catch (DiscoverySuspendedException e) {
+ String message = "The discovery class [" + discoveryComponent.getClass().getName() + "]" +
+ " uses a legacy implementation of \"manual add\" functionality. Some of the child resources" +
+ " with the resource type [" + resourceType + "] under the parent resource [" + parentResourceContainer.getResource() + "]" +
+ " failed to upgrade, which makes it impossible to support the legacy manual-add implementation. Either upgrade the plugin [" +
+ resourceType.getPlugin() + "] to successfully upgrade all resources or consider implementing the ManuallAdd facet.";
+ log.info(message);
+ throw new PluginContainerException(message, e);
}
- discoveredResourceDetails = discoveredResources.iterator().next();
}
// Create the new Resource and add it to inventory if it isn't already there.
@@ -1844,6 +1859,8 @@ public class InventoryManager extends AgentService implements ContainerService,
try {
discoveredResources = invokeDiscoveryComponent(null, component, context);
+ } catch (DiscoverySuspendedException e) {
+ log.error("Discovery seems to be suspended for platforms due to upgrade error.", e);
} catch (Throwable e) {
log.warn("Platform plugin discovery failed - skipping", e);
}
@@ -2179,35 +2196,47 @@ public class InventoryManager extends AgentService implements ContainerService,
parentResourceContext, SystemInfoFactory.createSystemInfo(), processScanResults,
Collections.EMPTY_LIST, this.configuration.getContainerName(),
this.configuration.getPluginContainerDeployment());
- Set<DiscoveredResourceDetails> discoveredResources = invokeDiscoveryComponent(parentContainer,
- discoveryComponent, context);
newResources = new HashSet<Resource>();
- if ((discoveredResources != null) && (!discoveredResources.isEmpty())) {
- IdentityHashMap<Configuration, DiscoveredResourceDetails> pluginConfigObjects = new IdentityHashMap<Configuration, DiscoveredResourceDetails>();
- for (DiscoveredResourceDetails discoveredResource : discoveredResources) {
- if (discoveredResource == null) {
- throw new IllegalStateException("Plugin error: Discovery class "
- + discoveryComponent.getClass().getName()
- + " returned a Set containing one or more null items.");
- }
- if (!discoveredResource.getResourceType().equals(resourceType)) {
- throw new IllegalStateException("Plugin error: Discovery class "
- + discoveryComponent.getClass().getName()
- + " returned a DiscoveredResourceDetails with an incorrect ResourceType (was "
- + discoveredResource.getResourceType().getName() + " but should have been "
- + resourceType.getName());
+ try {
+ Set<DiscoveredResourceDetails> discoveredResources = invokeDiscoveryComponent(parentContainer,
+ discoveryComponent, context);
+ if ((discoveredResources != null) && (!discoveredResources.isEmpty())) {
+ IdentityHashMap<Configuration, DiscoveredResourceDetails> pluginConfigObjects = new IdentityHashMap<Configuration, DiscoveredResourceDetails>();
+ for (DiscoveredResourceDetails discoveredResource : discoveredResources) {
+ if (discoveredResource == null) {
+ throw new IllegalStateException("Plugin error: Discovery class "
+ + discoveryComponent.getClass().getName()
+ + " returned a Set containing one or more null items.");
+ }
+ if (!discoveredResource.getResourceType().equals(resourceType)) {
+ throw new IllegalStateException("Plugin error: Discovery class "
+ + discoveryComponent.getClass().getName()
+ + " returned a DiscoveredResourceDetails with an incorrect ResourceType (was "
+ + discoveredResource.getResourceType().getName() + " but should have been "
+ + resourceType.getName());
+ }
+ if (null != pluginConfigObjects
+ .put(discoveredResource.getPluginConfiguration(), discoveredResource)) {
+ throw new IllegalStateException("The plugin component "
+ + discoveryComponent.getClass().getName()
+ + " returned multiple resources that point to the same plugin configuration object on the "
+ + "resource type [" + resourceType + "]. This is not allowed, please use "
+ + "ResoureDiscoveryContext.getDefaultPluginConfiguration() "
+ + "for each discovered resource.");
+ }
+ Resource newResource = InventoryManager.createNewResource(discoveredResource);
+ newResources.add(newResource);
}
- if (null != pluginConfigObjects
- .put(discoveredResource.getPluginConfiguration(), discoveredResource)) {
- throw new IllegalStateException("The plugin component "
- + discoveryComponent.getClass().getName()
- + " returned multiple resources that point to the same plugin configuration object on the "
- + "resource type [" + resourceType + "]. This is not allowed, please use "
- + "ResoureDiscoveryContext.getDefaultPluginConfiguration() "
- + "for each discovered resource.");
+ }
+ } catch (DiscoverySuspendedException e) {
+ //ok, the discovery is suspended for this resource type under this parent.
+ //but we can continue the discovery in the child resource types of the existing resources.
+ //we can therefore pretend that the discovery returned the existing resources so that
+ //we can recurse into their children up in the call-chain.
+ for(Resource existingResource : parentResource.getChildResources()) {
+ if (resourceType.equals(existingResource.getResourceType())) {
+ newResources.add(existingResource);
}
- Resource newResource = InventoryManager.createNewResource(discoveredResource);
- newResources.add(newResource);
}
}
} catch (Throwable e) {
@@ -2654,14 +2683,14 @@ public class InventoryManager extends AgentService implements ContainerService,
if (container != null) {
if (container.getResourceComponentState() == ResourceComponentState.STARTED) {
try {
- resourceUpgradeDelegate.processAndQueue(container);
+ if (resourceUpgradeDelegate.processAndQueue(container)) {
+ for (Resource child : resource.getChildResources()) {
+ upgradeResource(child);
+ }
+ }
} catch (PluginContainerException e) {
log.error("Exception thrown while upgrading [" + resource + "].", e);
}
-
- for (Resource child : resource.getChildResources()) {
- upgradeResource(child);
- }
} else {
String message = "The resource container for resource [" + resource
+ "] wasn't started while upgrading.";
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/DiscoverySuspendedException.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/DiscoverySuspendedException.java
new file mode 100644
index 0000000..5cb695d
--- /dev/null
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/DiscoverySuspendedException.java
@@ -0,0 +1,50 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.core.pc.upgrade;
+
+import org.rhq.core.pc.inventory.InventoryManager;
+
+/**
+ * This exception is thrown from the {@link InventoryManager#invokeDiscoveryComponent(org.rhq.core.pc.inventory.ResourceContainer, org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent, org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext)} if the
+ * discovery is suspended for given resource type due to a resource upgrade failure.
+ *
+ * @author Lukas Krejci
+ */
+public class DiscoverySuspendedException extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+ public DiscoverySuspendedException() {
+ super();
+ }
+
+ public DiscoverySuspendedException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public DiscoverySuspendedException(String message) {
+ super(message);
+ }
+
+ public DiscoverySuspendedException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
index 98a897e..06d2cd0 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
@@ -26,6 +26,7 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+
import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
import org.rhq.core.domain.resource.Resource;
@@ -61,7 +62,7 @@ public class ResourceUpgradeDelegate {
private Set<Resource> failedResources = new HashSet<Resource>();
private Map<Resource, Set<ResourceType>> failedResourceTypesPerParent = new HashMap<Resource, Set<ResourceType>>();
private boolean mergeFailed;
-
+
public ResourceUpgradeDelegate(InventoryManager inventoryManager) {
this.inventoryManager = inventoryManager;
}
@@ -84,13 +85,17 @@ public class ResourceUpgradeDelegate {
/**
* Asks the resource's discovery component to upgrade the resource.
* @param resourceContainer
- * @return true if the resource was queued for upgrade, false otherwise
+ * @return true if the resource was queued for upgrade with no problems,
+ * false if there was some problem upgrading and the resource container was deactivated as
+ * a results of that.
* @throws PluginContainerException on error
*/
- public void processAndQueue(ResourceContainer resourceContainer) throws PluginContainerException {
+ public boolean processAndQueue(ResourceContainer resourceContainer) throws PluginContainerException {
if (enabled) {
- executeResourceUpgradeFacetAndStoreRequest(resourceContainer);
+ return executeResourceUpgradeFacetAndStoreRequest(resourceContainer);
}
+
+ return true;
}
/**
@@ -99,7 +104,7 @@ public class ResourceUpgradeDelegate {
public boolean hasUpgradeMergeFailed() {
return mergeFailed;
}
-
+
/**
* Tells whether given resource had a upgrade failure during the {@link #processAndQueue(ResourceContainer)} invocation.
*
@@ -109,7 +114,7 @@ public class ResourceUpgradeDelegate {
public boolean hasUpgradeFailed(Resource resource) {
return mergeFailed || failedResources.contains(resource);
}
-
+
/**
* Tells whether at least one of the children with given resource type of the given parent resource
* had an upgrade failure during {@link #processAndQueue(ResourceContainer)} invocation.
@@ -120,35 +125,35 @@ public class ResourceUpgradeDelegate {
if (mergeFailed) {
return true;
}
-
+
Set<ResourceType> failedTypes = failedResourceTypesPerParent.get(parentResource);
-
+
return failedTypes != null && failedTypes.contains(childrenResourceType);
}
-
+
public void sendRequests() throws Throwable {
if (enabled && requests.size() > 0) {
try {
inventoryManager.mergeResourcesFromUpgrade(requests);
} catch (Throwable t) {
mergeFailed = true;
-
+
//deactivate all the resources to be upgraded. We might have a problem
//because they have not been upgraded because the merge failed.
- for(ResourceUpgradeRequest request : requests) {
+ for (ResourceUpgradeRequest request : requests) {
ResourceContainer container = inventoryManager.getResourceContainer(request.getResourceId());
if (container != null) {
inventoryManager.deactivateResource(container.getResource());
}
}
-
+
throw t;
}
}
}
@SuppressWarnings("unchecked")
- private <T extends ResourceComponent> void executeResourceUpgradeFacetAndStoreRequest(
+ private <T extends ResourceComponent> boolean executeResourceUpgradeFacetAndStoreRequest(
ResourceContainer resourceContainer) throws PluginContainerException {
ResourceComponent<T> parentResourceComponent = resourceContainer.getResourceContext()
@@ -166,16 +171,16 @@ public class ResourceUpgradeDelegate {
if (!(discoveryComponent instanceof ResourceUpgradeFacet)) {
//well, there's no point in continuing if the resource doesn't support the facet
- return;
+ return true;
}
ResourceUpgradeContext<ResourceComponent<T>> upgradeContext = inventoryManager.createResourceUpgradeContext(
resource, parentResourceComponent, discoveryComponent);
ResourceUpgradeRequest request = new ResourceUpgradeRequest(resource.getId());
-
+
request.setTimestamp(System.currentTimeMillis());
-
+
ResourceUpgradeReport upgradeReport = null;
try {
upgradeReport = inventoryManager.invokeDiscoveryComponentResourceUpgradeFacet(resource.getResourceType(),
@@ -189,13 +194,13 @@ public class ResourceUpgradeDelegate {
String upgradeErrors = null;
if ((upgradeErrors = checkUpgradeValid(resource, upgradeReport)) != null) {
String errorString = "Upgrading the resource [" + resource + "] using these updates [" + upgradeReport
- + "] would render the inventory invalid because of the following reasons: " + upgradeErrors;
-
+ + "] would render the inventory invalid because of the following reasons: " + upgradeErrors;
+
log.error(errorString);
-
+
IllegalStateException ex = new IllegalStateException(errorString);
ex.fillInStackTrace();
-
+
request.setErrorProperties(ex);
} else {
request.fillInFromReport(upgradeReport);
@@ -207,20 +212,24 @@ public class ResourceUpgradeDelegate {
if (request.hasSomethingToUpgrade()) {
requests.add(request);
}
-
+
if (request.getUpgradeErrorMessage() != null) {
failedResources.add(resource);
-
+
Set<ResourceType> failedResourceTypesInParent = failedResourceTypesPerParent.get(parentResource);
if (failedResourceTypesInParent == null) {
failedResourceTypesInParent = new HashSet<ResourceType>();
failedResourceTypesPerParent.put(parentResource, failedResourceTypesInParent);
}
-
+
failedResourceTypesInParent.add(resource.getResourceType());
-
+
inventoryManager.deactivateResource(resource);
+
+ return false;
}
+
+ return true;
}
private String checkUpgradeValid(Resource resource, ResourceUpgradeReport upgradeReport) {
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
index 7eafafc..ebb73be 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
@@ -156,9 +156,9 @@ public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase
//check that the resources are upgraded
checkResourcesUpgraded(resources.get(PARENT_DEP_SIBLING_TYPE), 1);
- checkResourcesUpgraded(resources.get(PARENT_TYPE), 2);
- checkResourcesUpgraded(resources.get(SIBLING_TYPE), 30);
- checkResourcesUpgraded(resources.get(TEST_TYPE), 30);
+ checkResourcesUpgraded(resources.get(PARENT_TYPE), 3);
+ checkResourcesUpgraded(resources.get(SIBLING_TYPE), 45);
+ checkResourcesUpgraded(resources.get(TEST_TYPE), 45);
}
public Expectations getExpectations(Mockery context) throws Exception {
@@ -206,19 +206,24 @@ public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase
checkNumberOfResources(resources, ROOT_TYPE, 1);
checkNumberOfResources(resources, PARENT_DEP_TYPE, 1);
- checkNumberOfResources(resources, PARENT_TYPE, 2);
- checkResourcesUpgraded(resources.get(PARENT_TYPE), 2);
+ checkResourcesUpgraded(resources.get(PARENT_TYPE), 3);
checkResourcesUpgraded(resources.get(PARENT_DEP_SIBLING_TYPE), 1);
Resource parent0 = findResourceWithOrdinal(PARENT_TYPE, 0);
Resource parent1 = findResourceWithOrdinal(PARENT_TYPE, 1);
-
- Set<Resource> siblingsUnderParent0 = filterResources(parent0.getChildResources(), SIBLING_TYPE);
+ Resource parent2 = findResourceWithOrdinal(PARENT_TYPE, 2);
+
Set<Resource> testsUnderParent0 = filterResources(parent0.getChildResources(), TEST_TYPE);
- Set<Resource> siblingsUnderParent1 = filterResources(parent1.getChildResources(), SIBLING_TYPE);
+ Set<Resource> siblingsUnderParent0 = filterResources(parent0.getChildResources(), SIBLING_TYPE);
Set<Resource> testsUnderParent1 = filterResources(parent1.getChildResources(), TEST_TYPE);
-
+ Set<Resource> siblingsUnderParent1 = filterResources(parent1.getChildResources(), SIBLING_TYPE);
+ Set<Resource> testsUnderParent2 = filterResources(parent2.getChildResources(), TEST_TYPE);
+ Set<Resource> siblingsUnderParent2 = filterResources(parent2.getChildResources(), SIBLING_TYPE);
+
+ //first check for the successful upgrades
+ checkResourcesUpgraded(testsUnderParent2, 15);
+ checkResourcesUpgraded(siblingsUnderParent2, 15);
checkResourcesUpgraded(siblingsUnderParent0, 15);
checkResourcesUpgraded(testsUnderParent1, 15);
@@ -257,10 +262,72 @@ public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase
}
@Test
- public void testFailureOnDependencies() {
- //TODO implement
- //check that stuff works if there is an upgrade failure on some of the resources
- //in the plugin some "in the middle" of the plugin dep graph
+ public void testFailureOnDependencies() throws Exception {
+ setCurrentServerSideInventory(new FakeServerInventory());
+
+ executeTestWithPlugins(getAllDepsFor(TEST_V1_PLUGIN_NAME, PARENT_SIBLING_V1_PLUGIN_NAME),
+ new AbstractTestPayload(true, Collections.<ResType> emptyList()) {
+ public void test(Map<ResType, Set<Resource>> resourceUpgradeTestResources) {
+ //in here we set up the failures that are going to happen when
+ //the v2 plugins are run
+
+ Resource parent = findResourceWithOrdinal(PARENT_DEP_TYPE, 0);
+ assertNotNull(parent, "Failed to find the parent to setup the failures for.");
+
+ addChildrenToFail(parent, PARENT_TYPE, 0);
+ }
+
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+ }
+ };
+ }
+ });
+
+ executeTestWithPlugins(getAllDepsFor(TEST_V2_PLUGIN_NAME, PARENT_SIBLING_V2_PLUGIN_NAME),
+ new AbstractTestPayload(false, ALL_TYPES) {
+ public void test(Map<ResType, Set<Resource>> resources) {
+ checkPresenceOfResourceTypes(resources, getExpectedResourceTypes());
+
+ checkNumberOfResources(resources, ROOT_TYPE, 1);
+ checkNumberOfResources(resources, PARENT_DEP_TYPE, 1);
+ checkResourcesUpgraded(resources.get(PARENT_DEP_SIBLING_TYPE), 1);
+
+ //check that the failed resources have the error attached to them
+ //we find the resource instance from the map provided to this method
+ //because that map contains the resources as found on the server-side
+ //(i.e. they include error objects).
+ Resource parent0 = getEqualFrom(resources.get(PARENT_TYPE), findResourceWithOrdinal(PARENT_TYPE, 0));
+ Resource parent1 = getEqualFrom(resources.get(PARENT_TYPE), findResourceWithOrdinal(PARENT_TYPE, 1));
+
+ //v2 plugin discovers 3 resources but because parent0 failed to upgrade,
+ //the discovery shouldn't have occurred leaving us with the 2 already existing resources.
+ checkNumberOfResources(resources, PARENT_TYPE, 2);
+ checkResourceFailedUpgrade(parent0);
+ checkOthersUpgraded(resources.get(PARENT_TYPE), parent0);
+
+ //parent1 upgraded ok, so discovering its children should have executed.
+ //this is v2, so we should find 15 of each.
+ checkResourcesUpgraded(filterResources(parent1.getChildResources(), TEST_TYPE), 15);
+ checkResourcesUpgraded(filterResources(parent1.getChildResources(), SIBLING_TYPE), 15);
+
+ //these shouldn't have been upgraded. in v1 we had 10 resources of TEST_TYPE
+ //and 10 resources of SIBLING_TYPE and that's what we should be seeing
+ //now.
+ checkResourcesNotUpgraded(filterResources(parent0.getChildResources(), TEST_TYPE), 10);
+ checkResourcesNotUpgraded(filterResources(parent0.getChildResources(), SIBLING_TYPE), 10);
+ }
+
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+ }
+ };
+ }
+ });
}
@SuppressWarnings("unchecked")
@@ -317,6 +384,22 @@ public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase
}
}
+ private static void checkResourcesNotUpgraded(Set<Resource> resources, int expectedSize) {
+ assertEquals(resources.size(), expectedSize, "The set of resources has unexpected size.");
+ for(Resource res : resources) {
+ assertFalse(res.getResourceKey().startsWith(UPGRADED_RESOURCE_KEY_PREFIX), "Resource " + res
+ + " seems to be upgraded even though it shouldn't.");
+
+ ResourceContainer rc = PluginContainer.getInstance().getInventoryManager().getResourceContainer(res);
+
+ assertEquals(rc.getResourceComponentState(), ResourceComponentState.STOPPED,
+ "A resource that has not been upgraded due to upgrade error in parent should be stopped.");
+
+ //recurse, since the whole subtree under the failed resource should be not upgraded and stopped.
+ checkResourcesNotUpgraded(res.getChildResources(), res.getChildResources().size());
+ }
+ }
+
private static void checkResourceFailedUpgrade(Resource resource) {
assertFalse(resource.getResourceKey().startsWith(UPGRADED_RESOURCE_KEY_PREFIX), "Resource " + resource
+ " seems to be upgraded even though it shouldn't.");
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
index 3d709b0..0f6671b 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
@@ -21,7 +21,7 @@
</runs-inside>
<plugin-configuration>
- <c:simple-property name="count" default="2" />
+ <c:simple-property name="count" default="3" />
<c:simple-property name="key" default="UPGRADED-test-resource-parent-%n,parent-%p" />
</plugin-configuration>
commit 9533fc2898f18af7262f513049d7261516787f4f
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Oct 4 14:50:49 2010 +0200
Upgrade even the non-commited resources to prevent duplication of resources in the auto-discovery queue
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index c6f1169..99a0513 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -2650,11 +2650,6 @@ public class InventoryManager extends AgentService implements ContainerService,
}
private void upgradeResource(Resource resource) {
- //only process committed resources
- if (resource.getInventoryStatus() != InventoryStatus.COMMITTED) {
- return;
- }
-
ResourceContainer container = getResourceContainer(resource);
if (container != null) {
if (container.getResourceComponentState() == ResourceComponentState.STARTED) {
@@ -2668,8 +2663,17 @@ public class InventoryManager extends AgentService implements ContainerService,
upgradeResource(child);
}
} else {
- log.error("The resource container for resource [" + resource
- + "] wasn't started during upgrade. This should not happen.");
+ String message = "The resource container for resource [" + resource
+ + "] wasn't started while upgrading.";
+
+ if (resource.getChildResources().isEmpty()) {
+ log.info(message
+ + " If this is the first time the plugin container starts up and has completely empty inventory, you can ignore this message.");
+ } else {
+ log.error(message
+ + " This can potentially cause the discovery to find resources logically equivalent to already "
+ + "existing resources if the corresponding plugins support upgrade for that particular resource type.");
+ }
}
} else {
log.error("Resource container not initialized for resource [" + resource
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
index 39597ee..0dd3459 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
@@ -80,8 +80,6 @@ public class FakeServerInventory {
this.failing = failing;
}
- //need to synchronize, because resource upgrade is async and can overlap with
- //resource discovery.
public synchronized CustomAction mergeInventoryReport(final InventoryStatus requiredInventoryStatus) {
return new CustomAction("updateServerSideInventory") {
public Object invoke(Invocation invocation) throws Throwable {
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 04858c6..8b966c3 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -71,7 +71,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
}
@Test
- public void testIgnoreUncommittedResources() throws Exception {
+ public void testIncludeUncommittedResources() throws Exception {
setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.NEW);
@@ -82,11 +82,12 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
Resource discoveredResource = discoveredResources.get(SINGLETON_TYPE).iterator().next();
- assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
- assertEquals(discoveredResource.getName(), "resource-name-v1");
- assertEquals(discoveredResource.getDescription(), "resource-description-v1");
+ assertEquals(discoveredResource.getResourceKey(), "resource-key-v2");
+ assertEquals(discoveredResource.getName(), "resource-name-v2");
+ assertEquals(discoveredResource.getDescription(), "resource-description-v2");
}
+ @SuppressWarnings("unchecked")
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
@@ -95,6 +96,9 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
+
+ oneOf(getCurrentDiscoveryServerService()).upgradeResources(with(any(Set.class)));
+ will(getCurrentServerSideInventory().upgradeResources());
}
};
}
commit 8ecbe7dec08b0e2e1f86ad8e1e56efd9f651cc7e
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Oct 4 14:32:55 2010 +0200
code formatting
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index de52cd8..c6f1169 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -242,16 +242,19 @@ public class InventoryManager extends AgentService implements ContainerService,
// inside EmbJopr).
if (configuration.isInsideAgent()) {
// After an initial delay (5s by default), periodically run an availability check (every 1m by default).
- availabilityThreadPoolExecutor.scheduleWithFixedDelay(availabilityExecutor, configuration
- .getAvailabilityScanInitialDelay(), configuration.getAvailabilityScanPeriod(), TimeUnit.SECONDS);
+ availabilityThreadPoolExecutor.scheduleWithFixedDelay(availabilityExecutor,
+ configuration.getAvailabilityScanInitialDelay(), configuration.getAvailabilityScanPeriod(),
+ TimeUnit.SECONDS);
// After an initial delay (10s by default), periodically run a server discovery scan (every 15m by default).
- inventoryThreadPoolExecutor.scheduleWithFixedDelay(serverScanExecutor, configuration
- .getServerDiscoveryInitialDelay(), configuration.getServerDiscoveryPeriod(), TimeUnit.SECONDS);
+ inventoryThreadPoolExecutor.scheduleWithFixedDelay(serverScanExecutor,
+ configuration.getServerDiscoveryInitialDelay(), configuration.getServerDiscoveryPeriod(),
+ TimeUnit.SECONDS);
// After an initial delay (20s by default), periodically run a service discovery scan (every 1d by default).
- inventoryThreadPoolExecutor.scheduleWithFixedDelay(serviceScanExecutor, configuration
- .getServiceDiscoveryInitialDelay(), configuration.getServiceDiscoveryPeriod(), TimeUnit.SECONDS);
+ inventoryThreadPoolExecutor.scheduleWithFixedDelay(serviceScanExecutor,
+ configuration.getServiceDiscoveryInitialDelay(), configuration.getServiceDiscoveryPeriod(),
+ TimeUnit.SECONDS);
}
} finally {
inventoryLock.writeLock().unlock();
@@ -288,22 +291,23 @@ public class InventoryManager extends AgentService implements ContainerService,
*
* @throws Exception if the discovery component threw an exception
*/
- public Set<DiscoveredResourceDetails> invokeDiscoveryComponent(ResourceContainer parentResourceContainer, ResourceDiscoveryComponent component,
- ResourceDiscoveryContext context) throws Exception {
+ public Set<DiscoveredResourceDetails> invokeDiscoveryComponent(ResourceContainer parentResourceContainer,
+ ResourceDiscoveryComponent component, ResourceDiscoveryContext context) throws Exception {
Resource parentResource = parentResourceContainer == null ? null : parentResourceContainer.getResource();
-
+
if (resourceUpgradeDelegate.hasUpgradeFailedInChildren(parentResource, context.getResourceType())) {
- log.debug("Discovery of [" + context.getResourceType() + "] has been disallowed under " + (parentResource == null ? " the platform " : parentResource) +
- " because some of its siblings failed to upgrade.");
+ log.debug("Discovery of [" + context.getResourceType() + "] has been disallowed under "
+ + (parentResource == null ? " the platform " : parentResource)
+ + " because some of its siblings failed to upgrade.");
return null;
}
-
+
long timeout = getDiscoveryComponentTimeout(context.getResourceType());
try {
- ResourceDiscoveryComponent proxy = this.discoveryComponentProxyFactory.getDiscoveryComponentProxy(context
- .getResourceType(), component, timeout);
+ ResourceDiscoveryComponent proxy = this.discoveryComponentProxyFactory.getDiscoveryComponentProxy(
+ context.getResourceType(), component, timeout);
Set<DiscoveredResourceDetails> results = proxy.discoverResources(context);
return results;
} catch (TimeoutException te) {
@@ -335,8 +339,8 @@ public class InventoryManager extends AgentService implements ContainerService,
long timeout = getDiscoveryComponentTimeout(context.getResourceType());
try {
- ManualAddFacet proxy = this.discoveryComponentProxyFactory.getDiscoveryComponentProxy(context
- .getResourceType(), component, timeout, ManualAddFacet.class);
+ ManualAddFacet proxy = this.discoveryComponentProxyFactory.getDiscoveryComponentProxy(
+ context.getResourceType(), component, timeout, ManualAddFacet.class);
DiscoveredResourceDetails result = proxy.discoverResource(pluginConfig, context);
return result;
} catch (TimeoutException te) {
@@ -375,8 +379,8 @@ public class InventoryManager extends AgentService implements ContainerService,
component, timeout, ClassLoaderFacet.class);
ResourceDiscoveryContext discoveryContext = new ResourceDiscoveryContext(resourceType, parentComponent,
- parentResourceContext, SystemInfoFactory.createSystemInfo(), null, null, this.configuration
- .getContainerName(), this.configuration.getPluginContainerDeployment());
+ parentResourceContext, SystemInfoFactory.createSystemInfo(), null, null,
+ this.configuration.getContainerName(), this.configuration.getPluginContainerDeployment());
// Configurations are not immutable, so clone the plugin config, so the plugin will not be able to change the
// actual PC-managed plugin config.
@@ -384,8 +388,7 @@ public class InventoryManager extends AgentService implements ContainerService,
// TODO (ips): Clone the ResourceType too for the same reason.
DiscoveredResourceDetails details = new DiscoveredResourceDetails(resourceType, resource.getResourceKey(),
- resource.getName(), resource.getVersion(), resource.getDescription(), pluginConfigClone,
- null); // TODO: I have a feeling we'll need process info, how to get it??
+ resource.getName(), resource.getVersion(), resource.getDescription(), pluginConfigClone, null); // TODO: I have a feeling we'll need process info, how to get it??
List<URL> results = proxy.getAdditionalClasspathUrls(discoveryContext, details);
@@ -592,7 +595,8 @@ public class InventoryManager extends AgentService implements ContainerService,
@NotNull
// TODO (ips): Perhaps refactor this so that it shares code with AvailablityExecutor.checkInventory().
- public Availability getCurrentAvailability(Resource resource) {
+ public
+ Availability getCurrentAvailability(Resource resource) {
AvailabilityType availType = null; // i.e. UNKNOWN;
ResourceContainer resourceContainer = getResourceContainer(resource);
if (resourceContainer != null) {
@@ -665,8 +669,8 @@ public class InventoryManager extends AgentService implements ContainerService,
ResourceDiscoveryContext<ResourceComponent> discoveryContext = new ResourceDiscoveryContext<ResourceComponent>(
resourceType, parentResourceComponent, parentResourceContainer.getResourceContext(),
SystemInfoFactory.createSystemInfo(), new ArrayList<ProcessScanResult>(0),
- new ArrayList<Configuration>(0), this.configuration.getContainerName(), this.configuration
- .getPluginContainerDeployment());
+ new ArrayList<Configuration>(0), this.configuration.getContainerName(),
+ this.configuration.getPluginContainerDeployment());
// Ask the plugin's discovery component to find the new resource, throwing exceptions if it cannot be
// found at all.
@@ -695,8 +699,8 @@ public class InventoryManager extends AgentService implements ContainerService,
// Ask the plugin's discovery component to find the new resource, throwing exceptions if it cannot be
// found at all.
- Set<DiscoveredResourceDetails> discoveredResources = invokeDiscoveryComponent(parentResourceContainer, discoveryComponent,
- discoveryContext);
+ Set<DiscoveredResourceDetails> discoveredResources = invokeDiscoveryComponent(parentResourceContainer,
+ discoveryComponent, discoveryContext);
if ((discoveredResources == null) || discoveredResources.isEmpty()) {
log.info("Plugin Error: During manual add, discovery component method ["
+ discoveryComponent.getClass().getName() + ".discoverResources()] returned "
@@ -850,8 +854,7 @@ public class InventoryManager extends AgentService implements ContainerService,
if ((this.platform != null) && (this.platform.getInventoryStatus() == InventoryStatus.NEW)
&& newPlatformWasDeletedRecently) {
// let's make sure we are registered; its probable that our platform was deleted and we need to re-register
- log
- .info("No committed resources to send in our availability report - the platform/agent was deleted, let's re-register again");
+ log.info("No committed resources to send in our availability report - the platform/agent was deleted, let's re-register again");
registerWithServer();
newPlatformWasDeletedRecently = false; // we've tried to recover from our platform being deleted, let's not do it again
}
@@ -891,8 +894,8 @@ public class InventoryManager extends AgentService implements ContainerService,
log.debug("Availability report content: " + report.toString(log.isTraceEnabled()));
}
- boolean ok = configuration.getServerServices().getDiscoveryServerService().mergeAvailabilityReport(
- report);
+ boolean ok = configuration.getServerServices().getDiscoveryServerService()
+ .mergeAvailabilityReport(report);
if (!ok) {
// I guess I could immediately call executeAvailabilityScanImmediately and pass its results to
// mergeAvailabilityReport again right now, but what happens if we've queued up a bunch of
@@ -955,8 +958,7 @@ public class InventoryManager extends AgentService implements ContainerService,
if ((this.platform != null) && (this.platform.getInventoryStatus() == InventoryStatus.NEW)
&& newPlatformWasDeletedRecently) {
// let's make sure we are registered; its probable that our platform was deleted and we need to re-register
- log
- .info("The inventory report was invalid probably because the platform/Agent was deleted; let's re-register...");
+ log.info("The inventory report was invalid probably because the platform/Agent was deleted; let's re-register...");
registerWithServer();
newPlatformWasDeletedRecently = false; // we've tried to recover from our platform being deleted, let's not do it again
}
@@ -974,8 +976,8 @@ public class InventoryManager extends AgentService implements ContainerService,
if (syncInfo != null) {
synchInventory(syncInfo);
} else {
- purgeObsoleteResources(Collections.<String>emptySet());
-
+ purgeObsoleteResources(Collections.<String> emptySet());
+
//can't live without a platform, but we just deleted it. Let's rediscover it.
discoverPlatform();
}
@@ -1113,7 +1115,7 @@ public class InventoryManager extends AgentService implements ContainerService,
return;
}
boolean scan = removeResourceAndIndicateIfScanIsNeeded(resourceContainer.getResource());
-
+
//only actually schedule the scanning when we are finished with resource upgrade. The resource upgrade
//happens before any scanning infrastructure is established.
if (!resourceUpgradeDelegate.enabled() && scan) {
@@ -1152,8 +1154,8 @@ public class InventoryManager extends AgentService implements ContainerService,
parent.removeChildResource(resource);
}
- PluginContainer.getInstance().getMeasurementManager().unscheduleCollection(
- Collections.singleton(resource.getId()));
+ PluginContainer.getInstance().getMeasurementManager()
+ .unscheduleCollection(Collections.singleton(resource.getId()));
if (this.resourceContainers.remove(resource.getUuid()) == null) {
if (log.isDebugEnabled()) {
@@ -1258,8 +1260,8 @@ public class InventoryManager extends AgentService implements ContainerService,
logMessage.append("description, ");
}
- logMessage.replace(logMessage.length() - 1, logMessage.length(), "to become [").append(
- existingResource.toString()).append("]");
+ logMessage.replace(logMessage.length() - 1, logMessage.length(), "to become [")
+ .append(existingResource.toString()).append("]");
log.info(logMessage.toString());
} else {
@@ -1429,7 +1431,7 @@ public class InventoryManager extends AgentService implements ContainerService,
}
return;
}
-
+
ResourceComponent component = container.getResourceComponent();
// if the component already exists and is started, and the resource's plugin config has not changed, there is
@@ -1490,8 +1492,8 @@ public class InventoryManager extends AgentService implements ContainerService,
log.warn("Cannot give activated resource its discovery component. Cause: " + e);
}
- ConfigurationUtility.normalizeConfiguration(resource.getPluginConfiguration(), type
- .getPluginConfigurationDefinition());
+ ConfigurationUtility.normalizeConfiguration(resource.getPluginConfiguration(),
+ type.getPluginConfigurationDefinition());
ResourceComponent parentComponent = null;
if (resource.getParentResource() != null) {
@@ -1855,8 +1857,7 @@ public class InventoryManager extends AgentService implements ContainerService,
}
} else {
// This is very strange - there are no platform types - we should never be missing the built-in platform plugin.
- log
- .error("Missing platform plugin(s) - falling back to dummy platform impl; this should only occur in tests!");
+ log.error("Missing platform plugin(s) - falling back to dummy platform impl; this should only occur in tests!");
// TODO: Set sysprop (e.g. rhq.test.mode=true) in integration tests,
// and throw a runtime exception here if that sysprop is not set.
return getTestPlatform();
@@ -2049,7 +2050,7 @@ public class InventoryManager extends AgentService implements ContainerService,
public boolean hasUpgradeMergeFailed() {
return resourceUpgradeDelegate.hasUpgradeMergeFailed();
}
-
+
/**
* Always use this before accessing the event listeners because this ensures
* thread safety.
@@ -2176,9 +2177,10 @@ public class InventoryManager extends AgentService implements ContainerService,
try {
ResourceDiscoveryContext context = new ResourceDiscoveryContext(resourceType, parentComponent,
parentResourceContext, SystemInfoFactory.createSystemInfo(), processScanResults,
- Collections.EMPTY_LIST, this.configuration.getContainerName(), this.configuration
- .getPluginContainerDeployment());
- Set<DiscoveredResourceDetails> discoveredResources = invokeDiscoveryComponent(parentContainer, discoveryComponent, context);
+ Collections.EMPTY_LIST, this.configuration.getContainerName(),
+ this.configuration.getPluginContainerDeployment());
+ Set<DiscoveredResourceDetails> discoveredResources = invokeDiscoveryComponent(parentContainer,
+ discoveryComponent, context);
newResources = new HashSet<Resource>();
if ((discoveredResources != null) && (!discoveredResources.isEmpty())) {
IdentityHashMap<Configuration, DiscoveredResourceDetails> pluginConfigObjects = new IdentityHashMap<Configuration, DiscoveredResourceDetails>();
@@ -2403,8 +2405,8 @@ public class InventoryManager extends AgentService implements ContainerService,
if (log.isDebugEnabled()) {
log.debug("Merging [" + modifiedResourceIds.size() + "] modified Resources into local inventory...");
}
- Set<Resource> modifiedResources = configuration.getServerServices().getDiscoveryServerService().getResources(
- modifiedResourceIds, false);
+ Set<Resource> modifiedResources = configuration.getServerServices().getDiscoveryServerService()
+ .getResources(modifiedResourceIds, false);
syncSchedules(modifiedResources); // RHQ-792, mtime is the indicator that schedules should be sync'ed too
for (Resource modifiedResource : modifiedResources) {
mergeResource(modifiedResource);
@@ -2620,12 +2622,12 @@ public class InventoryManager extends AgentService implements ContainerService,
private void upgradeResources() {
try {
-
+
if (!configuration.isInsideAgent()) {
log.debug("Skipping resource upgrade in embedded mode.");
return;
}
-
+
log.debug("Executing resource upgrade.");
boolean syncResult = handleReport(new InventoryReport(getAgent()), true);
@@ -2635,7 +2637,7 @@ public class InventoryManager extends AgentService implements ContainerService,
}
upgradeResource(getPlatform());
-
+
log.debug("Sending the upgrade requests to the server.");
resourceUpgradeDelegate.sendRequests();
commit 9050f4bfab5114ff31e19cb9c04b2d087dba2bff
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Oct 4 14:04:52 2010 +0200
Adding the test for handling the failure to upgrade some of the resources on the leaf of the plugin dependency graph.
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ForwardingProxy.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ForwardingProxy.java
new file mode 100644
index 0000000..7c7d277
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ForwardingProxy.java
@@ -0,0 +1,72 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.core.pc.upgrade;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+/**
+ * This class provides a simple proxy that just forwards the calls to the
+ * actual object.
+ * <p>
+ * This seemingly pointless behavior is useful when dealing with the classes
+ * loaded in different classloaders.
+ * <p>
+ * The arguments passed to the method invocations of the proxy must unfortunately be "understandable"
+ * both in the "current" classloader and in the context of the classloader that loaded the target object.
+ * I don't know about a generic solution to this problem.
+ * A partial solution would be to serialize the arguments and deserialize them in the context
+ * of the target classloader but that doesn't cut it for non-serializable classes obviously.
+ *
+ * @author Lukas Krejci
+ */
+public class ForwardingProxy {
+
+ private static class ForwardingHandler implements InvocationHandler {
+ private Object target;
+
+ public ForwardingHandler(Object target) {
+ this.target = target;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ Method targetMethod = findMethodOnTarget(method);
+
+ return targetMethod.invoke(target, args);
+ }
+
+ private Method findMethodOnTarget(Method method) throws SecurityException, NoSuchMethodException {
+ Class<?>[] origParamTypes = method.getParameterTypes();
+
+ return target.getClass().getMethod(method.getName(), origParamTypes);
+ }
+ }
+
+ public static <T> T forward(Object target, Class<T> targetInterface, Class<?>... additionalInterfaces) {
+ Class<?>[] interfaces = new Class<?>[additionalInterfaces.length + 1];
+ interfaces[0] = targetInterface;
+ System.arraycopy(additionalInterfaces, 0, interfaces, 1, additionalInterfaces.length);
+
+ Object proxy = Proxy.newProxyInstance(targetInterface.getClassLoader(), interfaces, new ForwardingHandler(target));
+ return targetInterface.cast(proxy);
+ }
+}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
index 5949b76..7eafafc 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
@@ -20,14 +20,17 @@
package org.rhq.core.pc.upgrade;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -36,10 +39,20 @@ import org.jmock.Expectations;
import org.jmock.Mockery;
import org.testng.annotations.Test;
+import org.rhq.core.clientapi.agent.PluginContainerException;
+import org.rhq.core.clientapi.agent.discovery.InvalidPluginConfigurationClientException;
import org.rhq.core.clientapi.server.discovery.InvalidInventoryReportException;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceErrorType;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.pc.PluginContainer;
+import org.rhq.core.pc.inventory.InventoryManager;
+import org.rhq.core.pc.inventory.ResourceContainer;
+import org.rhq.core.pc.inventory.ResourceContainer.ResourceComponentState;
+import org.rhq.core.pc.upgrade.plugins.multi.base.BaseResourceComponentInterface;
import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
/**
@@ -76,7 +89,7 @@ public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase
private static final String TEST_V2_PLUGIN_NAME = "/resource-upgrade-test-plugin-multi-test-2.0.0.jar";
private static final String UPGRADED_RESOURCE_KEY_PREFIX = "UPGRADED";
-
+
private static final HashMap<String, List<String>> DEPS;
static {
@@ -100,9 +113,12 @@ public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase
private static final ResType SIBLING_TYPE = new ResType("TestResourceSibling", "test");
private static final ResType PARENT_TYPE = new ResType("TestResourceParent", "test");
private static final ResType PARENT_DEP_TYPE = new ResType("ParentDependency", "parentdep");
- private static final ResType PARENT_SIBLING_TYPE = new ResType("ParentDepSibling", "parentsibling");
+ private static final ResType PARENT_DEP_SIBLING_TYPE = new ResType("ParentDepSibling", "parentsibling");
private static final ResType ROOT_TYPE = new ResType("Root", "root");
+ private static List<ResType> ALL_TYPES = Arrays.asList(TEST_TYPE, SIBLING_TYPE, PARENT_TYPE, PARENT_DEP_TYPE,
+ PARENT_DEP_SIBLING_TYPE, ROOT_TYPE);
+
protected Collection<String> getRequiredPlugins() {
return Arrays.asList(BASE_PLUGIN_NAME, PARENT_DEP_V1_PLUGIN_NAME, PARENT_DEP_V2_PLUGIN_NAME,
PARENT_SIBLING_V1_PLUGIN_NAME, PARENT_SIBLING_V2_PLUGIN_NAME, ROOT_PLUGIN_NAME, SIBLING_V1_PLUGIN_NAME,
@@ -129,26 +145,20 @@ public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase
});
//now let's run with v2 plugins and check the layout of the inventory
- executeTestWithPlugins(
- getAllDepsFor(TEST_V2_PLUGIN_NAME, PARENT_SIBLING_V2_PLUGIN_NAME),
- new AbstractTestPayload(false, Arrays.asList(TEST_TYPE, SIBLING_TYPE, PARENT_TYPE, PARENT_DEP_TYPE,
- PARENT_SIBLING_TYPE, ROOT_TYPE)) {
+ executeTestWithPlugins(getAllDepsFor(TEST_V2_PLUGIN_NAME, PARENT_SIBLING_V2_PLUGIN_NAME),
+ new AbstractTestPayload(false, ALL_TYPES) {
public void test(Map<ResType, Set<Resource>> resources) {
checkPresenceOfResourceTypes(resources, getExpectedResourceTypes());
checkNumberOfResources(resources, ROOT_TYPE, 1);
checkNumberOfResources(resources, PARENT_DEP_TYPE, 1);
- checkNumberOfResources(resources, PARENT_SIBLING_TYPE, 1);
- checkNumberOfResources(resources, PARENT_TYPE, 2);
- checkNumberOfResources(resources, SIBLING_TYPE, 30);
- checkNumberOfResources(resources, TEST_TYPE, 30);
-
+
//check that the resources are upgraded
- checkResourcesUpgraded(resources.get(PARENT_SIBLING_TYPE));
- checkResourcesUpgraded(resources.get(PARENT_TYPE));
- checkResourcesUpgraded(resources.get(SIBLING_TYPE));
- checkResourcesUpgraded(resources.get(TEST_TYPE));
+ checkResourcesUpgraded(resources.get(PARENT_DEP_SIBLING_TYPE), 1);
+ checkResourcesUpgraded(resources.get(PARENT_TYPE), 2);
+ checkResourcesUpgraded(resources.get(SIBLING_TYPE), 30);
+ checkResourcesUpgraded(resources.get(TEST_TYPE), 30);
}
public Expectations getExpectations(Mockery context) throws Exception {
@@ -162,10 +172,88 @@ public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase
}
@Test
- public void testFailureOnLeaf() {
- //TODO implement
- //check that the system behaves correctly if there is an upgrade failure
- //at the leaf node of the plugin dep graph
+ public void testFailureOnLeaf() throws Exception {
+ setCurrentServerSideInventory(new FakeServerInventory());
+
+ executeTestWithPlugins(getAllDepsFor(TEST_V1_PLUGIN_NAME, PARENT_SIBLING_V1_PLUGIN_NAME),
+ new AbstractTestPayload(true, Collections.<ResType> emptyList()) {
+ public void test(Map<ResType, Set<Resource>> resourceUpgradeTestResources) {
+ //in here we set up the failures that are going to happen when
+ //the v2 plugins are run
+
+ Resource parent0 = findResourceWithOrdinal(PARENT_TYPE, 0);
+ assertNotNull(parent0, "Failed to find the parent to setup the failures for.");
+ Resource parent1 = findResourceWithOrdinal(PARENT_TYPE, 1);
+ assertNotNull(parent1, "Failed to find the parent to setup the failures for.");
+
+ addChildrenToFail(parent0, TEST_TYPE, 1, 2);
+ addChildrenToFail(parent1, SIBLING_TYPE, 1);
+ }
+
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+ }
+ };
+ }
+ });
+
+ executeTestWithPlugins(getAllDepsFor(TEST_V2_PLUGIN_NAME, PARENT_SIBLING_V2_PLUGIN_NAME),
+ new AbstractTestPayload(false, ALL_TYPES) {
+ public void test(Map<ResType, Set<Resource>> resources) {
+ checkPresenceOfResourceTypes(resources, getExpectedResourceTypes());
+
+ checkNumberOfResources(resources, ROOT_TYPE, 1);
+ checkNumberOfResources(resources, PARENT_DEP_TYPE, 1);
+ checkNumberOfResources(resources, PARENT_TYPE, 2);
+
+ checkResourcesUpgraded(resources.get(PARENT_TYPE), 2);
+ checkResourcesUpgraded(resources.get(PARENT_DEP_SIBLING_TYPE), 1);
+
+ Resource parent0 = findResourceWithOrdinal(PARENT_TYPE, 0);
+ Resource parent1 = findResourceWithOrdinal(PARENT_TYPE, 1);
+
+ Set<Resource> siblingsUnderParent0 = filterResources(parent0.getChildResources(), SIBLING_TYPE);
+ Set<Resource> testsUnderParent0 = filterResources(parent0.getChildResources(), TEST_TYPE);
+ Set<Resource> siblingsUnderParent1 = filterResources(parent1.getChildResources(), SIBLING_TYPE);
+ Set<Resource> testsUnderParent1 = filterResources(parent1.getChildResources(), TEST_TYPE);
+
+ checkResourcesUpgraded(siblingsUnderParent0, 15);
+ checkResourcesUpgraded(testsUnderParent1, 15);
+
+ //there should be no newly discovered sibling resources of the failed ones
+ assertEquals(testsUnderParent0.size(), 10);
+ assertEquals(siblingsUnderParent1.size(), 10);
+
+ //check that the failed resources have the error attached to them
+ //we find the resource instance from the map provided to this method
+ //because that map contains the resources as found on the server-side
+ //(i.e. they include error objects).
+ Resource failedTest1 = getEqualFrom(resources.get(TEST_TYPE),
+ findResourceWithOrdinal(testsUnderParent0, 1));
+ Resource failedTest2 = getEqualFrom(resources.get(TEST_TYPE),
+ findResourceWithOrdinal(testsUnderParent0, 2));
+
+ checkResourceFailedUpgrade(failedTest1);
+ checkResourceFailedUpgrade(failedTest2);
+ checkOthersUpgraded(testsUnderParent0, failedTest1, failedTest2);
+
+ Resource failedSibling = getEqualFrom(resources.get(SIBLING_TYPE),
+ findResourceWithOrdinal(siblingsUnderParent1, 1));
+
+ checkResourceFailedUpgrade(failedSibling);
+ checkOthersUpgraded(siblingsUnderParent1, failedSibling);
+ }
+
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+ }
+ };
+ }
+ });
}
@Test
@@ -180,13 +268,14 @@ public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase
protected void defineDefaultExpectations(Expectations expectations) {
super.defineDefaultExpectations(expectations);
try {
- expectations.allowing(getCurrentDiscoveryServerService())
- .mergeInventoryReport(expectations.with(Expectations.any(InventoryReport.class)));
+ expectations.allowing(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ expectations.with(Expectations.any(InventoryReport.class)));
expectations.will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
- expectations.allowing(getCurrentDiscoveryServerService()).upgradeResources(expectations.with(Expectations.any(Set.class)));
+ expectations.allowing(getCurrentDiscoveryServerService()).upgradeResources(
+ expectations.with(Expectations.any(Set.class)));
expectations.will(getCurrentServerSideInventory().upgradeResources());
-
+
expectations.allowing(getCurrentDiscoveryServerService()).postProcessNewlyCommittedResources(
expectations.with(Expectations.any(Set.class)));
@@ -214,10 +303,112 @@ public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase
private static void checkNumberOfResources(Map<ResType, Set<Resource>> resources, ResType type, int count) {
assertEquals(resources.get(type).size(), count, "Unexpected number of " + type + " discovered.");
}
-
- private static void checkResourcesUpgraded(Set<Resource> resources) {
- for(Resource res : resources) {
- assertTrue(res.getResourceKey().startsWith(UPGRADED_RESOURCE_KEY_PREFIX), "Resource " + res + " doesn't seem to be upgraded even though it should.");
+
+ private static void checkResourcesUpgraded(Set<Resource> resources, int expectedSize) {
+ assertEquals(resources.size(), expectedSize, "The set of resources has unexpected size.");
+ for (Resource res : resources) {
+ assertTrue(res.getResourceKey().startsWith(UPGRADED_RESOURCE_KEY_PREFIX), "Resource " + res
+ + " doesn't seem to be upgraded even though it should.");
+
+ ResourceContainer rc = PluginContainer.getInstance().getInventoryManager().getResourceContainer(res);
+
+ assertEquals(rc.getResourceComponentState(), ResourceComponentState.STARTED,
+ "A resource that successfully upgraded should be started.");
+ }
+ }
+
+ private static void checkResourceFailedUpgrade(Resource resource) {
+ assertFalse(resource.getResourceKey().startsWith(UPGRADED_RESOURCE_KEY_PREFIX), "Resource " + resource
+ + " seems to be upgraded even though it shouldn't.");
+ assertTrue(resource.getResourceErrors(ResourceErrorType.UPGRADE).size() == 1,
+ "The failed resource should have an error associated with it.");
+
+ ResourceContainer rc = PluginContainer.getInstance().getInventoryManager().getResourceContainer(resource);
+
+ assertEquals(rc.getResourceComponentState(), ResourceComponentState.STOPPED,
+ "A resource that failed to upgrade should be stopped.");
+ }
+
+ private static void checkOthersUpgraded(Set<Resource> resources, Resource... failedResource) {
+ Set<Resource> others = new HashSet<Resource>(resources);
+ others.removeAll(Arrays.asList(failedResource));
+ checkResourcesUpgraded(others, others.size());
+ }
+
+ private void addChildrenToFail(Resource parent, ResType childResType, int... childrenOrdinals) {
+ InventoryManager inventoryManager = PluginContainer.getInstance().getInventoryManager();
+ ResourceContainer parentContainer = inventoryManager.getResourceContainer(parent);
+ BaseResourceComponentInterface parentComponent = (BaseResourceComponentInterface) parentContainer
+ .getResourceComponent();
+
+ Map<String, Set<Integer>> childrenToFail = new HashMap<String, Set<Integer>>();
+ Set<Integer> ordinals = new HashSet<Integer>();
+ for (int i = 0; i < childrenOrdinals.length; ++i) {
+ ordinals.add(childrenOrdinals[i]);
+ }
+
+ childrenToFail.put(childResType.getResourceTypeName(), ordinals);
+
+ Configuration newPluginConfig = parentComponent.createPluginConfigurationWithMarkedFailures(childrenToFail);
+
+ try {
+ int resourceId = parent.getId();
+ inventoryManager.updatePluginConfiguration(resourceId, newPluginConfig);
+ } catch (InvalidPluginConfigurationClientException e) {
+ fail("Updating plugin configuration failed.", e);
+ } catch (PluginContainerException e) {
+ fail("Updating plugin configuration failed.", e);
+ }
+ }
+
+ private Resource findResourceWithOrdinal(ResType resType, int ordinal) {
+ ResourceType resourceType = PluginContainer.getInstance().getPluginManager().getMetadataManager()
+ .getType(resType.getResourceTypeName(), resType.getResourceTypePluginName());
+
+ InventoryManager inventoryManager = PluginContainer.getInstance().getInventoryManager();
+ Set<Resource> resources = inventoryManager.getResourcesWithType(resourceType);
+
+ return findResourceWithOrdinal(resources, ordinal);
+ }
+
+ private Resource findResourceWithOrdinal(Set<Resource> resources, int ordinal) {
+ for (Resource r : resources) {
+ Configuration pluginConfig = r.getPluginConfiguration();
+ String ordinalString = pluginConfig.getSimpleValue("ordinal", null);
+
+ if (ordinalString != null && Integer.parseInt(ordinalString) == ordinal) {
+ return r;
+ }
+ }
+
+ return null;
+ }
+
+ private Set<Resource> filterResources(Set<Resource> resources, ResType resType) {
+ Set<Resource> ret = new HashSet<Resource>(resources);
+
+ Iterator<Resource> it = ret.iterator();
+
+ while (it.hasNext()) {
+ ResourceType resourceType = it.next().getResourceType();
+
+ if (!resourceType.getName().equals(resType.getResourceTypeName())
+ || !resourceType.getPlugin().equals(resType.getResourceTypePluginName())) {
+
+ it.remove();
+ }
}
+
+ return ret;
+ }
+
+ private static <T> T getEqualFrom(Collection<? extends T> collection, T object) {
+ for (T other : collection) {
+ if (object.equals(other)) {
+ return other;
+ }
+ }
+
+ return null;
}
}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index d47d00c..04858c6 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -37,12 +37,13 @@ import java.util.Set;
import org.jmock.Expectations;
import org.jmock.Mockery;
+import org.testng.annotations.Test;
+
import org.rhq.core.clientapi.server.discovery.InventoryReport;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.pc.PluginContainer;
import org.rhq.core.pc.inventory.ResourceContainer;
-import org.testng.annotations.Test;
/**
* Test cases for resource upgrade.
@@ -55,234 +56,255 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
private static final String PLUGIN_V1_FILENAME = "/resource-upgrade-test-plugin-1.0.0.jar";
private static final String PLUGIN_V2_FILENAME = "/resource-upgrade-test-plugin-2.0.0.jar";
private static final String FAILING_PLUGIN_FILE_NAME = "/resource-upgrade-test-plugin-3.0.0.jar";
-
+
private static final String SINGLETON_RESOURCE_TYPE_NAME = "Resource";
private static final String SINGLETON_RESOURCE_TYPE_PLUGIN_NAME = "ResourceUpgradeTest";
- private static final ResType SINGLETON_TYPE = new ResType(SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME);
-
+ private static final ResType SINGLETON_TYPE = new ResType(SINGLETON_RESOURCE_TYPE_NAME,
+ SINGLETON_RESOURCE_TYPE_PLUGIN_NAME);
+
private static List<ResType> getMyExpectedTypes() {
return Arrays.asList(SINGLETON_TYPE);
}
-
+
protected Collection<String> getRequiredPlugins() {
return Arrays.asList(PLUGIN_V1_FILENAME, PLUGIN_V2_FILENAME, FAILING_PLUGIN_FILE_NAME);
}
-
+
@Test
public void testIgnoreUncommittedResources() throws Exception {
setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.NEW);
-
- TestPayload testNoChange = new AbstractTestPayload(false, getMyExpectedTypes()) {
+
+ TestPayload testNoChange = new AbstractTestPayload(false, getMyExpectedTypes()) {
public void test(Map<ResType, Set<Resource>> discoveredResources) {
- assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
-
+ assertEquals(discoveredResources.get(SINGLETON_TYPE).size(), 1,
+ "Expected single test resource but multiple found.");
+
Resource discoveredResource = discoveredResources.get(SINGLETON_TYPE).iterator().next();
assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
assertEquals(discoveredResource.getName(), "resource-name-v1");
assertEquals(discoveredResource.getDescription(), "resource-description-v1");
}
-
+
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
defineDefaultExpectations(this);
-
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+
+ between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
}
};
}
};
-
+
executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), testNoChange);
}
-
+
@Test
public void testUpgradeData() throws Exception {
setCurrentServerSideInventory(new FakeServerInventory());
upgradeTest(false);
}
-
+
@Test
public void testInventoryReinitializationFromServerDuringUpgrade() throws Exception {
setCurrentServerSideInventory(new FakeServerInventory());
upgradeTest(true);
}
-
+
@Test
public void testSkipUpgradeWhenServerUnavailable() throws Exception {
setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
-
+
getCurrentServerSideInventory().setFailing(true);
- TestPayload test = new AbstractTestPayload(false, getMyExpectedTypes()) {
+ TestPayload test = new AbstractTestPayload(false, getMyExpectedTypes()) {
public void test(Map<ResType, Set<Resource>> discoveredResources) {
- assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
-
+ assertEquals(discoveredResources.get(SINGLETON_TYPE).size(), 1,
+ "Expected single test resource but multiple found.");
+
Resource discoveredResource = discoveredResources.get(SINGLETON_TYPE).iterator().next();
-
+
assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
assertEquals(discoveredResource.getName(), "resource-name-v1");
assertEquals(discoveredResource.getDescription(), "resource-description-v1");
}
-
+
@SuppressWarnings("unchecked")
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
defineDefaultExpectations(this);
-
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+
+ between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
-
+
never(getCurrentDiscoveryServerService()).upgradeResources(with(any(Set.class)));
}
};
}
};
-
+
executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), test);
}
-
+
@Test
public void testUpgradeWithPlatformDeletedOnServer() throws Exception {
setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
-
- TestPayload test = new AbstractTestPayload(false, getMyExpectedTypes()) {
+
+ TestPayload test = new AbstractTestPayload(false, getMyExpectedTypes()) {
public void test(Map<ResType, Set<Resource>> discoveredResources) {
- assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
-
+ assertEquals(discoveredResources.get(SINGLETON_TYPE).size(), 1,
+ "Expected single test resource but multiple found.");
+
Resource discoveredResource = discoveredResources.get(SINGLETON_TYPE).iterator().next();
-
+
assertEquals(discoveredResource.getResourceKey(), "resource-key-v2");
assertEquals(discoveredResource.getName(), "resource-name-v2");
assertEquals(discoveredResource.getDescription(), "resource-description-v2");
- ResourceContainer container = PluginContainer.getInstance().getInventoryManager().getResourceContainer(discoveredResource);
+ ResourceContainer container = PluginContainer.getInstance().getInventoryManager()
+ .getResourceContainer(discoveredResource);
File dataDir = container.getResourceContext().getDataDirectory();
-
+
File marker = new File(dataDir, "upgrade-succeeded");
-
- assertFalse(marker.exists(), "The upgrade seems to have occured even though there shouldn't have been a resource to upgrade.");
+
+ assertFalse(marker.exists(),
+ "The upgrade seems to have occured even though there shouldn't have been a resource to upgrade.");
}
-
+
@SuppressWarnings("unchecked")
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
defineDefaultExpectations(this);
-
+
//the first merge will be triggered from within the upgrade process and we are
//going to report null sync.
- oneOf(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+ oneOf(getCurrentDiscoveryServerService())
+ .mergeInventoryReport(with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().clearPlatform());
-
+
//the rest of the inventory merges are executed by discoveries, so let's import the
//discovered stuff into the server-side inventory.
- between(1, 3).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+ between(1, 3).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
-
+
never(getCurrentDiscoveryServerService()).upgradeResources(with(any(Set.class)));
}
};
}
};
-
+
executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), test);
}
-
+
@Test
public void testUpgradeFailureHandling() throws Exception {
setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
-
- TestPayload test = new AbstractTestPayload(false, getMyExpectedTypes()) {
+
+ TestPayload test = new AbstractTestPayload(false, getMyExpectedTypes()) {
public void test(Map<ResType, Set<Resource>> resourceUpgradeTestResources) {
- assertEquals(resourceUpgradeTestResources.size(), 1, "Expected single test resource but multiple found.");
-
+ assertEquals(resourceUpgradeTestResources.get(SINGLETON_TYPE).size(), 1,
+ "Expected single test resource but multiple found.");
+
Resource discoveredResource = resourceUpgradeTestResources.get(SINGLETON_TYPE).iterator().next();
-
- assertTrue(discoveredResource.getResourceErrors().size() > 0, "There should be upgrade errors persisted on the server side.");
-
+
+ assertTrue(discoveredResource.getResourceErrors().size() > 0,
+ "There should be upgrade errors persisted on the server side.");
+
//the discovery of the failed resource mustn't have run
- ResourceContainer container = PluginContainer.getInstance().getInventoryManager().getResourceContainer(discoveredResource);
+ ResourceContainer container = PluginContainer.getInstance().getInventoryManager()
+ .getResourceContainer(discoveredResource);
File dataDir = container.getResourceContext().getDataDirectory();
-
+
File marker = new File(dataDir, "failing-discovery-ran");
-
- assertFalse(marker.exists(), "The discovery of the resource type with a failed upgraded resource must not be executed but it was.");
+
+ assertFalse(marker.exists(),
+ "The discovery of the resource type with a failed upgraded resource must not be executed but it was.");
}
-
+
@SuppressWarnings("unchecked")
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
defineDefaultExpectations(this);
-
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+
+ between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
-
+
oneOf(getCurrentDiscoveryServerService()).upgradeResources(with(any(Set.class)));
will(getCurrentServerSideInventory().upgradeResources());
}
};
}
};
-
+
executeTestWithPlugins(Collections.singleton(FAILING_PLUGIN_FILE_NAME), test);
}
-
+
private void initialSyncAndDiscovery(final InventoryStatus requiredInventoryStatus) throws Exception {
cleanDataDir();
- executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), new AbstractTestPayload(true, getMyExpectedTypes()) {
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), new AbstractTestPayload(true,
+ getMyExpectedTypes()) {
public void test(Map<ResType, Set<Resource>> discoveredResources) {
- assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
-
+ assertEquals(discoveredResources.get(SINGLETON_TYPE).size(), 1,
+ "Expected single test resource but multiple found.");
+
Resource discoveredResource = discoveredResources.get(SINGLETON_TYPE).iterator().next();
-
+
assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
assertEquals(discoveredResource.getName(), "resource-name-v1");
assertEquals(discoveredResource.getDescription(), "resource-description-v1");
}
-
+
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
defineDefaultExpectations(this);
-
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+
+ between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(requiredInventoryStatus));
}
};
}
- });
-
+ });
+
}
-
private void upgradeTest(boolean clearInventoryDat) throws Exception {
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
-
- executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), new AbstractTestPayload(clearInventoryDat, getMyExpectedTypes()) {
+
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), new AbstractTestPayload(clearInventoryDat,
+ getMyExpectedTypes()) {
public void test(Map<ResType, Set<Resource>> discoveredResources) {
- assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
-
+ assertEquals(discoveredResources.get(SINGLETON_TYPE).size(), 1,
+ "Expected single test resource but multiple found.");
+
Resource discoveredResource = discoveredResources.get(SINGLETON_TYPE).iterator().next();
-
+
assertEquals(discoveredResource.getResourceKey(), "resource-key-v2");
assertEquals(discoveredResource.getName(), "resource-name-v2");
assertEquals(discoveredResource.getDescription(), "resource-description-v2");
-
- ResourceContainer container = PluginContainer.getInstance().getInventoryManager().getResourceContainer(discoveredResource);
+
+ ResourceContainer container = PluginContainer.getInstance().getInventoryManager()
+ .getResourceContainer(discoveredResource);
File dataDir = container.getResourceContext().getDataDirectory();
-
+
File marker = new File(dataDir, "upgrade-succeeded");
-
- assertTrue(marker.exists(), "The upgrade success marker file wasn't found. This means the upgrade didn't actually run.");
+
+ assertTrue(marker.exists(),
+ "The upgrade success marker file wasn't found. This means the upgrade didn't actually run.");
}
@SuppressWarnings("unchecked")
@@ -290,10 +312,11 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
return new Expectations() {
{
defineDefaultExpectations(this);
-
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+
+ between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
-
+
oneOf(getCurrentDiscoveryServerService()).upgradeResources(with(any(Set.class)));
will(getCurrentServerSideInventory().upgradeResources());
}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponent.java
index c5bbf3a..04d3767 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponent.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponent.java
@@ -19,11 +19,18 @@
package org.rhq.core.pc.upgrade.plugins.multi.base;
-import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.Property;
+import org.rhq.core.domain.configuration.PropertyList;
+import org.rhq.core.domain.configuration.PropertyMap;
+import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
import org.rhq.core.pluginapi.inventory.ResourceComponent;
@@ -33,13 +40,11 @@ import org.rhq.core.pluginapi.inventory.ResourceContext;
*
* @author Lukas Krejci
*/
-public class BaseResourceComponent<T extends ResourceComponent> implements ResourceComponent<T> {
+public class BaseResourceComponent<T extends ResourceComponent> implements ResourceComponent<T>, BaseResourceComponentInterface {
private ResourceContext<T> context;
private final Log log = LogFactory.getLog(getClass());
- private Set<Integer> childrenToFailUpgrade;
-
public AvailabilityType getAvailability() {
return AvailabilityType.UP;
}
@@ -57,11 +62,57 @@ public class BaseResourceComponent<T extends ResourceComponent> implements Resou
return context.getPluginConfiguration().getSimple("ordinal").getIntegerValue();
}
- public Set<Integer> getChildrenToFailUpgrade() {
- return childrenToFailUpgrade == null ? Collections.<Integer>emptySet() : childrenToFailUpgrade;
+ public Map<String, Set<Integer>> getChildrenToFailUpgrade() {
+
+ Map<String, Set<Integer>> ret = new HashMap<String, Set<Integer>>();
+
+ Configuration pluginConfig = context.getPluginConfiguration();
+ PropertyList childrenToFail = pluginConfig.getList("childrenToFail");
+
+ if (childrenToFail != null) {
+ for(Property p : childrenToFail.getList()) {
+ PropertyMap entry = (PropertyMap) p;
+
+ String type = entry.getSimpleValue("type", null);
+
+ PropertyList typeList = entry.getList("children");
+
+ if (type != null && typeList != null) {
+ Set<Integer> ordinals = new HashSet<Integer>();
+
+ for(Property pp : typeList.getList()) {
+ ordinals.add(((PropertySimple)pp).getIntegerValue());
+ }
+
+ ret.put(type, ordinals);
+ }
+ }
+ }
+
+ return ret;
}
- public void setChildrenToFailUpgrade(Set<Integer> childrenToFailUpgrade) {
- this.childrenToFailUpgrade = childrenToFailUpgrade;
+ public Configuration createPluginConfigurationWithMarkedFailures(Map<String, Set<Integer>> childrenToFailUpgrade) {
+ Configuration ret = context.getPluginConfiguration().clone();
+ PropertyList list = new PropertyList("childrenToFail");
+
+ for(Map.Entry<String, Set<Integer>> entry : childrenToFailUpgrade.entrySet()) {
+ PropertyMap configEntry = new PropertyMap("childrenInType");
+ configEntry.put(new PropertySimple("type", entry.getKey()));
+
+ PropertyList typeList = new PropertyList("children");
+
+ for(Integer childOrdinal : entry.getValue()) {
+ typeList.add(new PropertySimple("ordinal", childOrdinal));
+ }
+
+ configEntry.put(typeList);
+
+ list.add(configEntry);
+ }
+
+ ret.put(list);
+
+ return ret;
}
}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponentInterface.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponentInterface.java
new file mode 100644
index 0000000..1c9bef0
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponentInterface.java
@@ -0,0 +1,36 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.core.pc.upgrade.plugins.multi.base;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.rhq.core.domain.configuration.Configuration;
+
+/**
+ * This is to support proxying to required methods from the tests.
+ *
+ * @author Lukas Krejci
+ */
+public interface BaseResourceComponentInterface {
+
+ Configuration createPluginConfigurationWithMarkedFailures(Map<String, Set<Integer>> childrenToFailUpgrade);
+
+}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java
index ec1cb20..5b8af94 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java
@@ -19,6 +19,8 @@
package org.rhq.core.pc.upgrade.plugins.multi.base;
+import java.util.Set;
+
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
@@ -41,7 +43,10 @@ public class BaseUpgradingDiscoveryComponent<T extends BaseResourceComponent> ex
boolean fail = Boolean.getBoolean(pluginConfig.getSimpleValue("failUpgrade", "false"));
if (!fail && parent != null) {
- fail = parent.getChildrenToFailUpgrade().contains(Integer.valueOf(ordinal));
+ String typeName = inventoriedResource.getResourceType().getName();
+ Set<Integer> failingOrdinals = parent.getChildrenToFailUpgrade().get(typeName);
+
+ fail = failingOrdinals != null && failingOrdinals.contains(Integer.valueOf(ordinal));
}
if (fail) {
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/NothingDiscoveringDiscoveryComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/NothingDiscoveringDiscoveryComponent.java
new file mode 100644
index 0000000..b6189e5
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/NothingDiscoveringDiscoveryComponent.java
@@ -0,0 +1,42 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.core.pc.upgrade.plugins.multi.base;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+
+/**
+ *
+ * @author Lukas Krejci
+ */
+public class NothingDiscoveringDiscoveryComponent<T extends ResourceComponent> implements ResourceDiscoveryComponent<T> {
+
+ public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext<T> context)
+ throws InvalidPluginConfigurationException, Exception {
+
+ return Collections.emptySet();
+ }
+}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
index d3ea7b7..e3b4f9b 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
@@ -11,7 +11,7 @@
<depends plugin="base" useClasses="true"/>
- <server name="Bogus" class="BaseDiscoveryComponent">
+ <server name="Bogus" class="BaseDiscoveryComponent" discovery="NothingDiscoveringDiscoveryComponent">
<!-- This service is put in the type hierarchy in the v1/v2 test plugins -->
<service name="TestResourceSibling"
discovery="BaseDiscoveryComponent"
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
index f7f7a2c..e7792b9 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
@@ -10,7 +10,7 @@
<depends plugin="base" useClasses="true"/>
- <server name="Bogus" class="BaseDiscoveryComponent">
+ <server name="Bogus" class="BaseDiscoveryComponent" discovery="NothingDiscoveringDiscoveryComponent">
<!-- This service is put in the type hierarchy in the v1/v2 test plugins -->
<service name="TestResourceSibling"
discovery="BaseUpgradingDiscoveryComponent"
commit e6dd8c2618a009053b06c3f63fff808fc5e64dbf
Merge: 14fd25e... 3c5a00e...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Oct 1 12:58:36 2010 +0200
Merge branch 'master' into resource-upgrade
commit 14fd25e86c1a4013c1047c343f3860720a3f9c68
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Oct 1 12:55:37 2010 +0200
Adapted the resource upgrade test infrastructure to work with the new requirements of the failure handling tests and added the first round of the failure handling tests.
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
index adb3989..39597ee 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
@@ -59,68 +59,69 @@ public class FakeServerInventory {
private Map<String, Resource> resourceStore = new HashMap<String, Resource>();
private int counter;
private boolean failing;
-
+
private static final Comparator<Resource> ID_COMPARATOR = new Comparator<Resource>() {
public int compare(Resource o1, Resource o2) {
return o1.getId() - o2.getId();
}
};
-
+
private static final Comparator<Resource> RESOURCE_TYPE_COMPARATOR = new Comparator<Resource>() {
public int compare(Resource o1, Resource o2) {
return o1.getResourceType().equals(o2.getResourceType()) ? 0 : o1.getId() - o2.getId();
}
};
-
+
public FakeServerInventory() {
this(false);
}
-
+
public FakeServerInventory(boolean failing) {
this.failing = failing;
}
-
+
//need to synchronize, because resource upgrade is async and can overlap with
//resource discovery.
public synchronized CustomAction mergeInventoryReport(final InventoryStatus requiredInventoryStatus) {
return new CustomAction("updateServerSideInventory") {
public Object invoke(Invocation invocation) throws Throwable {
throwIfFailing();
-
+
InventoryReport inventoryReport = (InventoryReport) invocation.getParameter(0);
-
- for(Resource res : inventoryReport.getAddedRoots()) {
+
+ for (Resource res : inventoryReport.getAddedRoots()) {
+ Resource persisted = fakePersist(res, requiredInventoryStatus, new HashSet<String>());
+
if (res.getParentResource() == Resource.ROOT) {
- platform = fakePersist(res, requiredInventoryStatus, new HashSet<String>());
- break;
+ platform = persisted;
}
}
return getSyncInfo();
- }
+ }
};
}
-
+
public synchronized CustomAction clearPlatform() {
return new CustomAction("updateServerSideInventory - report platform deleted on the server") {
public Object invoke(Invocation invocation) throws Throwable {
throwIfFailing();
-
+
platform = null;
-
+
return getSyncInfo();
}
};
}
-
+
public synchronized CustomAction upgradeResources() {
return new CustomAction("upgradeServerSideInventory") {
- @SuppressWarnings({"serial", "unchecked"})
+ @SuppressWarnings({ "serial", "unchecked" })
public Object invoke(Invocation invocation) throws Throwable {
throwIfFailing();
-
+
Set<ResourceUpgradeRequest> requests = (Set<ResourceUpgradeRequest>) invocation.getParameter(0);
Set<ResourceUpgradeResponse> responses = new HashSet<ResourceUpgradeResponse>();
-
+
for (final ResourceUpgradeRequest request : requests) {
Resource resource = findResource(platform, new Resource() {
public int getId() {
@@ -134,16 +135,18 @@ public class FakeServerInventory {
if (request.getNewName() != null) {
resource.setName(request.getNewName());
}
-
+
if (request.getNewResourceKey() != null) {
resource.setResourceKey(request.getNewResourceKey());
}
-
+
if (request.getUpgradeErrorMessage() != null) {
- ResourceError error = new ResourceError(resource, ResourceErrorType.UPGRADE, request.getUpgradeErrorMessage(), request.getUpgradeErrorStackTrace(), request.getTimestamp());
+ ResourceError error = new ResourceError(resource, ResourceErrorType.UPGRADE,
+ request.getUpgradeErrorMessage(), request.getUpgradeErrorStackTrace(),
+ request.getTimestamp());
resource.getResourceErrors().add(error);
}
-
+
ResourceUpgradeResponse resp = new ResourceUpgradeResponse();
resp.setResourceId(resource.getId());
resp.setUpgradedResourceName(resource.getName());
@@ -156,21 +159,21 @@ public class FakeServerInventory {
}
};
}
-
+
public synchronized CustomAction getResources() {
return new CustomAction("getResources") {
@SuppressWarnings("unchecked")
public Object invoke(Invocation invocation) throws Throwable {
throwIfFailing();
-
- Set<Integer> resourceIds = (Set<Integer>)invocation.getParameter(0);
+
+ Set<Integer> resourceIds = (Set<Integer>) invocation.getParameter(0);
boolean includeDescendants = (Boolean) invocation.getParameter(1);
-
+
return getResources(resourceIds, includeDescendants);
}
- };
+ };
}
-
+
public boolean isFailing() {
return failing;
}
@@ -191,12 +194,12 @@ public class FakeServerInventory {
}
return result;
}
-
+
@SuppressWarnings("serial")
- private Set<Resource> getResources(Set<Integer> resourceIds, boolean includeDescendants) {
+ private Set<Resource> getResources(Set<Integer> resourceIds, boolean includeDescendants) {
Set<Resource> result = new HashSet<Resource>();
-
- for(final Integer id : resourceIds) {
+
+ for (final Integer id : resourceIds) {
Resource r = findResource(platform, new Resource() {
public int getId() {
return id;
@@ -204,19 +207,20 @@ public class FakeServerInventory {
}, ID_COMPARATOR);
if (r != null) {
result.add(r);
-
+
if (includeDescendants) {
- for(Resource child : r.getChildResources()) {
+ for (Resource child : r.getChildResources()) {
result.addAll(getResources(Collections.singleton(child.getId()), true));
}
}
}
}
-
+
return result;
}
-
- private Resource fakePersist(Resource agentSideResource, InventoryStatus requiredInventoryStatus, Set<String> inProgressUUIds) {
+
+ private Resource fakePersist(Resource agentSideResource, InventoryStatus requiredInventoryStatus,
+ Set<String> inProgressUUIds) {
Resource persisted = resourceStore.get(agentSideResource.getUuid());
if (!inProgressUUIds.add(agentSideResource.getUuid())) {
return persisted;
@@ -237,94 +241,114 @@ public class FakeServerInventory {
persisted.setInventoryStatus(requiredInventoryStatus);
persisted.setResourceKey(agentSideResource.getResourceKey());
persisted.setResourceType(agentSideResource.getResourceType());
-
+
Resource parent = agentSideResource.getParentResource();
if (parent != null && parent != Resource.ROOT) {
- persisted.setParentResource(fakePersist(agentSideResource.getParentResource(), requiredInventoryStatus, inProgressUUIds));
+ persisted.setParentResource(fakePersist(agentSideResource.getParentResource(), requiredInventoryStatus,
+ inProgressUUIds));
} else {
persisted.setParentResource(parent);
}
Set<Resource> childResources = new HashSet<Resource>();
persisted.setChildResources(childResources);
- for(Resource child : agentSideResource.getChildResources()) {
+ for (Resource child : agentSideResource.getChildResources()) {
childResources.add(fakePersist(child, requiredInventoryStatus, inProgressUUIds));
}
-
+
inProgressUUIds.remove(agentSideResource.getUuid());
-
+
return persisted;
}
-
+
private ResourceSyncInfo getSyncInfo() {
return platform != null ? convert(platform) : null;
}
-
+
private void throwIfFailing() {
if (failing) {
throw new RuntimeException("Fake server inventory is in the failing mode.");
}
}
-
+
private static ResourceSyncInfo convert(Resource root) {
+ return convertInternal(root, new HashMap<String, ResourceSyncInfo>());
+ }
+
+ private static ResourceSyncInfo convertInternal(Resource root, Map<String, ResourceSyncInfo> intermediateResults) {
+ ResourceSyncInfo ret = intermediateResults.get(root.getUuid());
+
+ if (ret != null) {
+ return ret;
+ }
+
try {
- ResourceSyncInfo ret = new ResourceSyncInfo();
-
+ ret = new ResourceSyncInfo();
+
+ intermediateResults.put(root.getUuid(), ret);
+
Class<ResourceSyncInfo> clazz = ResourceSyncInfo.class;
getPrivateField(clazz, "id").set(ret, root.getId());
getPrivateField(clazz, "uuid").set(ret, root.getUuid());
getPrivateField(clazz, "mtime").set(ret, root.getMtime());
getPrivateField(clazz, "inventoryStatus").set(ret, root.getInventoryStatus());
- getPrivateField(clazz, "parent").set(ret, null);
-
+
+ ResourceSyncInfo parent = root.getParentResource() == null ? null : convertInternal(
+ root.getParentResource(), intermediateResults);
+
+ getPrivateField(clazz, "parent").set(ret, parent);
+
Set<ResourceSyncInfo> children = new LinkedHashSet<ResourceSyncInfo>();
- for(Resource child : root.getChildResources()) {
- ResourceSyncInfo syncChild = convert(child);
- getPrivateField(clazz, "parent").set(syncChild, ret);
-
- children.add(convert(child));
- }
+ for (Resource child : root.getChildResources()) {
+ ResourceSyncInfo syncChild = convertInternal(child, intermediateResults);
+
+ children.add(syncChild);
+ }
getPrivateField(clazz, "childSyncInfos").set(ret, children);
-
+
return ret;
} catch (Exception e) {
fail("Failed to convert resource " + root + " to a ResourceSyncInfo. This should not happen.", e);
return null;
}
- }
-
+ }
+
private static Field getPrivateField(Class<?> clazz, String fieldName) throws NoSuchFieldException {
Field field = clazz.getDeclaredField(fieldName);
if (!field.isAccessible()) {
field.setAccessible(true);
}
-
+
return field;
}
-
+
private static Resource findResource(Resource root, Resource template, Comparator<Resource> comparator) {
- if (root == null) return null;
+ if (root == null)
+ return null;
if (comparator.compare(root, template) == 0) {
return root;
} else {
- for(Resource child : root.getChildResources()) {
+ for (Resource child : root.getChildResources()) {
Resource found = findResource(child, template, comparator);
- if (found != null) return found;
+ if (found != null)
+ return found;
}
}
-
+
return null;
- }
-
- private static void findResources(Resource root, Resource template, Set<Resource> result, Comparator<Resource> comparator) {
- if (root == null) return;
+ }
+
+ private static void findResources(Resource root, Resource template, Set<Resource> result,
+ Comparator<Resource> comparator) {
+ if (root == null)
+ return;
if (comparator.compare(root, template) == 0) {
result.add(root);
} else {
- for(Resource child : root.getChildResources()) {
+ for (Resource child : root.getChildResources()) {
findResources(child, template, result, comparator);
}
- }
+ }
}
}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
index 25eca30..5949b76 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
@@ -19,11 +19,29 @@
package org.rhq.core.pc.upgrade;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
import org.testng.annotations.Test;
+import org.rhq.core.clientapi.server.discovery.InvalidInventoryReportException;
+import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.domain.resource.InventoryStatus;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
+
/**
* The plugins and their resource types form the following dependency structure:
* <pre>
@@ -35,6 +53,10 @@ import org.testng.annotations.Test;
* </pre>
* The dependencies in the above "chart" are formed using either the <code><runs-inside></code>
* or <code>sourcePlugin/sourceType</code> approaches just to test that both are handled correctly.
+ * <p>
+ * The <code>parentdep</code>, <code>parentsibling</code>, <code>test</code> and <code>sibling</code> plugins are present
+ * in two versions and support the {@link ResourceUpgradeFacet}, while the rest of the plugins is
+ * present only in single version.
*
* @author Lukas Krejci
*/
@@ -53,29 +75,149 @@ public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase
private static final String TEST_V1_PLUGIN_NAME = "/resource-upgrade-test-plugin-multi-test-1.0.0.jar";
private static final String TEST_V2_PLUGIN_NAME = "/resource-upgrade-test-plugin-multi-test-2.0.0.jar";
+ private static final String UPGRADED_RESOURCE_KEY_PREFIX = "UPGRADED";
+
+ private static final HashMap<String, List<String>> DEPS;
+
+ static {
+ DEPS = new HashMap<String, List<String>>();
+
+ DEPS.put(BASE_PLUGIN_NAME, Collections.<String> emptyList());
+ DEPS.put(PARENT_DEP_V1_PLUGIN_NAME, Arrays.asList(BASE_PLUGIN_NAME, ROOT_PLUGIN_NAME));
+ DEPS.put(PARENT_DEP_V2_PLUGIN_NAME, DEPS.get(PARENT_DEP_V1_PLUGIN_NAME));
+ DEPS.put(PARENT_SIBLING_V1_PLUGIN_NAME, Arrays.asList(BASE_PLUGIN_NAME, ROOT_PLUGIN_NAME));
+ DEPS.put(PARENT_SIBLING_V2_PLUGIN_NAME, DEPS.get(PARENT_SIBLING_V1_PLUGIN_NAME));
+ DEPS.put(ROOT_PLUGIN_NAME, Arrays.asList(BASE_PLUGIN_NAME));
+ DEPS.put(SIBLING_V1_PLUGIN_NAME, Arrays.asList(BASE_PLUGIN_NAME, ROOT_PLUGIN_NAME, PARENT_DEP_V1_PLUGIN_NAME));
+ DEPS.put(SIBLING_V2_PLUGIN_NAME, Arrays.asList(BASE_PLUGIN_NAME, ROOT_PLUGIN_NAME, PARENT_DEP_V2_PLUGIN_NAME));
+ DEPS.put(TEST_V1_PLUGIN_NAME,
+ Arrays.asList(BASE_PLUGIN_NAME, ROOT_PLUGIN_NAME, PARENT_DEP_V1_PLUGIN_NAME, SIBLING_V1_PLUGIN_NAME));
+ DEPS.put(TEST_V2_PLUGIN_NAME,
+ Arrays.asList(BASE_PLUGIN_NAME, ROOT_PLUGIN_NAME, PARENT_DEP_V1_PLUGIN_NAME, SIBLING_V2_PLUGIN_NAME));
+ }
+
+ private static final ResType TEST_TYPE = new ResType("TestResource", "test");
+ private static final ResType SIBLING_TYPE = new ResType("TestResourceSibling", "test");
+ private static final ResType PARENT_TYPE = new ResType("TestResourceParent", "test");
+ private static final ResType PARENT_DEP_TYPE = new ResType("ParentDependency", "parentdep");
+ private static final ResType PARENT_SIBLING_TYPE = new ResType("ParentDepSibling", "parentsibling");
+ private static final ResType ROOT_TYPE = new ResType("Root", "root");
+
protected Collection<String> getRequiredPlugins() {
return Arrays.asList(BASE_PLUGIN_NAME, PARENT_DEP_V1_PLUGIN_NAME, PARENT_DEP_V2_PLUGIN_NAME,
PARENT_SIBLING_V1_PLUGIN_NAME, PARENT_SIBLING_V2_PLUGIN_NAME, ROOT_PLUGIN_NAME, SIBLING_V1_PLUGIN_NAME,
SIBLING_V2_PLUGIN_NAME, TEST_V1_PLUGIN_NAME, TEST_V2_PLUGIN_NAME);
}
-
+
@Test
- public void testSuccess() {
- //TODO implement
- //check that all the stuff is properly upgraded on success
+ public void testSuccess() throws Exception {
+ setCurrentServerSideInventory(new FakeServerInventory());
+
+ //let it all run in v1
+ executeTestWithPlugins(getAllDepsFor(TEST_V1_PLUGIN_NAME, PARENT_SIBLING_V1_PLUGIN_NAME),
+ new AbstractTestPayload(true, Collections.<ResType> emptyList()) {
+ public void test(Map<ResType, Set<Resource>> resourceUpgradeTestResources) {
+ }
+
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+ }
+ };
+ }
+ });
+
+ //now let's run with v2 plugins and check the layout of the inventory
+ executeTestWithPlugins(
+ getAllDepsFor(TEST_V2_PLUGIN_NAME, PARENT_SIBLING_V2_PLUGIN_NAME),
+ new AbstractTestPayload(false, Arrays.asList(TEST_TYPE, SIBLING_TYPE, PARENT_TYPE, PARENT_DEP_TYPE,
+ PARENT_SIBLING_TYPE, ROOT_TYPE)) {
+
+ public void test(Map<ResType, Set<Resource>> resources) {
+ checkPresenceOfResourceTypes(resources, getExpectedResourceTypes());
+
+ checkNumberOfResources(resources, ROOT_TYPE, 1);
+ checkNumberOfResources(resources, PARENT_DEP_TYPE, 1);
+ checkNumberOfResources(resources, PARENT_SIBLING_TYPE, 1);
+ checkNumberOfResources(resources, PARENT_TYPE, 2);
+ checkNumberOfResources(resources, SIBLING_TYPE, 30);
+ checkNumberOfResources(resources, TEST_TYPE, 30);
+
+ //check that the resources are upgraded
+ checkResourcesUpgraded(resources.get(PARENT_SIBLING_TYPE));
+ checkResourcesUpgraded(resources.get(PARENT_TYPE));
+ checkResourcesUpgraded(resources.get(SIBLING_TYPE));
+ checkResourcesUpgraded(resources.get(TEST_TYPE));
+ }
+
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+ }
+ };
+ }
+ });
}
-
+
@Test
public void testFailureOnLeaf() {
//TODO implement
//check that the system behaves correctly if there is an upgrade failure
//at the leaf node of the plugin dep graph
}
-
+
@Test
public void testFailureOnDependencies() {
//TODO implement
//check that stuff works if there is an upgrade failure on some of the resources
//in the plugin some "in the middle" of the plugin dep graph
}
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void defineDefaultExpectations(Expectations expectations) {
+ super.defineDefaultExpectations(expectations);
+ try {
+ expectations.allowing(getCurrentDiscoveryServerService())
+ .mergeInventoryReport(expectations.with(Expectations.any(InventoryReport.class)));
+ expectations.will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
+
+ expectations.allowing(getCurrentDiscoveryServerService()).upgradeResources(expectations.with(Expectations.any(Set.class)));
+ expectations.will(getCurrentServerSideInventory().upgradeResources());
+
+ expectations.allowing(getCurrentDiscoveryServerService()).postProcessNewlyCommittedResources(
+ expectations.with(Expectations.any(Set.class)));
+
+ } catch (InvalidInventoryReportException e) {
+ //this is not going to happen because we're mocking the invocation
+ }
+ }
+
+ private Set<String> getAllDepsFor(String... plugins) {
+ HashSet<String> deps = new HashSet<String>();
+ for (String plugin : plugins) {
+ deps.add(plugin);
+ deps.addAll(DEPS.get(plugin));
+ }
+
+ return deps;
+ }
+
+ private static void checkPresenceOfResourceTypes(Map<ResType, Set<Resource>> resources, Set<ResType> expectedTypes) {
+ for (ResType resType : expectedTypes) {
+ assertNotNull(resources.get(resType), "Expecting some resources of type " + resType);
+ }
+ }
+
+ private static void checkNumberOfResources(Map<ResType, Set<Resource>> resources, ResType type, int count) {
+ assertEquals(resources.get(type).size(), count, "Unexpected number of " + type + " discovered.");
+ }
+
+ private static void checkResourcesUpgraded(Set<Resource> resources) {
+ for(Resource res : resources) {
+ assertTrue(res.getResourceKey().startsWith(UPGRADED_RESOURCE_KEY_PREFIX), "Resource " + res + " doesn't seem to be upgraded even though it should.");
+ }
+ }
}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 8cfec36..d47d00c 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -31,6 +31,8 @@ import java.io.File;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.jmock.Expectations;
@@ -54,8 +56,13 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
private static final String PLUGIN_V2_FILENAME = "/resource-upgrade-test-plugin-2.0.0.jar";
private static final String FAILING_PLUGIN_FILE_NAME = "/resource-upgrade-test-plugin-3.0.0.jar";
- static final String SINGLETON_RESOURCE_TYPE_NAME = "Resource";
- static final String SINGLETON_RESOURCE_TYPE_PLUGIN_NAME = "ResourceUpgradeTest";
+ private static final String SINGLETON_RESOURCE_TYPE_NAME = "Resource";
+ private static final String SINGLETON_RESOURCE_TYPE_PLUGIN_NAME = "ResourceUpgradeTest";
+ private static final ResType SINGLETON_TYPE = new ResType(SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME);
+
+ private static List<ResType> getMyExpectedTypes() {
+ return Arrays.asList(SINGLETON_TYPE);
+ }
protected Collection<String> getRequiredPlugins() {
return Arrays.asList(PLUGIN_V1_FILENAME, PLUGIN_V2_FILENAME, FAILING_PLUGIN_FILE_NAME);
@@ -66,11 +73,11 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.NEW);
- TestPayload testNoChange = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
- public void test(Set<Resource> discoveredResources) {
+ TestPayload testNoChange = new AbstractTestPayload(false, getMyExpectedTypes()) {
+ public void test(Map<ResType, Set<Resource>> discoveredResources) {
assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
- Resource discoveredResource = discoveredResources.iterator().next();
+ Resource discoveredResource = discoveredResources.get(SINGLETON_TYPE).iterator().next();
assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
assertEquals(discoveredResource.getName(), "resource-name-v1");
@@ -111,11 +118,11 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
getCurrentServerSideInventory().setFailing(true);
- TestPayload test = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
- public void test(Set<Resource> discoveredResources) {
+ TestPayload test = new AbstractTestPayload(false, getMyExpectedTypes()) {
+ public void test(Map<ResType, Set<Resource>> discoveredResources) {
assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
- Resource discoveredResource = discoveredResources.iterator().next();
+ Resource discoveredResource = discoveredResources.get(SINGLETON_TYPE).iterator().next();
assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
assertEquals(discoveredResource.getName(), "resource-name-v1");
@@ -145,11 +152,11 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
- TestPayload test = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
- public void test(Set<Resource> discoveredResources) {
+ TestPayload test = new AbstractTestPayload(false, getMyExpectedTypes()) {
+ public void test(Map<ResType, Set<Resource>> discoveredResources) {
assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
- Resource discoveredResource = discoveredResources.iterator().next();
+ Resource discoveredResource = discoveredResources.get(SINGLETON_TYPE).iterator().next();
assertEquals(discoveredResource.getResourceKey(), "resource-key-v2");
assertEquals(discoveredResource.getName(), "resource-name-v2");
@@ -193,11 +200,11 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
- TestPayload test = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
- public void test(Set<Resource> resourceUpgradeTestResources) {
+ TestPayload test = new AbstractTestPayload(false, getMyExpectedTypes()) {
+ public void test(Map<ResType, Set<Resource>> resourceUpgradeTestResources) {
assertEquals(resourceUpgradeTestResources.size(), 1, "Expected single test resource but multiple found.");
- Resource discoveredResource = resourceUpgradeTestResources.iterator().next();
+ Resource discoveredResource = resourceUpgradeTestResources.get(SINGLETON_TYPE).iterator().next();
assertTrue(discoveredResource.getResourceErrors().size() > 0, "There should be upgrade errors persisted on the server side.");
@@ -231,11 +238,11 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
private void initialSyncAndDiscovery(final InventoryStatus requiredInventoryStatus) throws Exception {
cleanDataDir();
- executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), new AbstractTestPayload(true, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
- public void test(Set<Resource> discoveredResources) {
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), new AbstractTestPayload(true, getMyExpectedTypes()) {
+ public void test(Map<ResType, Set<Resource>> discoveredResources) {
assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
- Resource discoveredResource = discoveredResources.iterator().next();
+ Resource discoveredResource = discoveredResources.get(SINGLETON_TYPE).iterator().next();
assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
assertEquals(discoveredResource.getName(), "resource-name-v1");
@@ -260,11 +267,11 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
private void upgradeTest(boolean clearInventoryDat) throws Exception {
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
- executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), new AbstractTestPayload(clearInventoryDat, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
- public void test(Set<Resource> discoveredResources) {
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), new AbstractTestPayload(clearInventoryDat, getMyExpectedTypes()) {
+ public void test(Map<ResType, Set<Resource>> discoveredResources) {
assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
- Resource discoveredResource = discoveredResources.iterator().next();
+ Resource discoveredResource = discoveredResources.get(SINGLETON_TYPE).iterator().next();
assertEquals(discoveredResource.getResourceKey(), "resource-key-v2");
assertEquals(discoveredResource.getName(), "resource-name-v2");
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
index 3aa772b..0aefafd 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
@@ -25,6 +25,9 @@ import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import org.apache.commons.io.FileUtils;
@@ -73,6 +76,78 @@ public abstract class ResourceUpgradeTestBase {
private ResourceFactoryServerService currentResourceFactoryServerService;
private FakeServerInventory currentServerSideInventory;
+ protected static class ResType {
+ private String resourceTypeName;
+ private String resourceTypePluginName;
+
+ public ResType(String resourceTypeName, String resourceTypePluginName) {
+ super();
+ this.resourceTypeName = resourceTypeName;
+ this.resourceTypePluginName = resourceTypePluginName;
+ }
+
+ public String getResourceTypeName() {
+ return resourceTypeName;
+ }
+
+ public String getResourceTypePluginName() {
+ return resourceTypePluginName;
+ }
+
+ @Override
+ public int hashCode() {
+ return resourceTypeName.hashCode() * resourceTypePluginName.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ if (!(other instanceof ResType)) {
+ return false;
+ }
+
+ ResType o = (ResType)other;
+
+ return resourceTypeName.equals(o.getResourceTypeName()) && resourceTypePluginName.equals(o.getResourceTypePluginName());
+ }
+
+ @Override
+ public String toString() {
+ return "ResType[name='" + resourceTypeName + "', plugin='" + resourceTypePluginName + "']";
+ }
+ }
+
+ protected interface TestPayload {
+ Expectations getExpectations(Mockery context) throws Exception;
+
+ void test(Map<ResType,Set<Resource>> resourceUpgradeTestResources);
+
+ boolean isClearInventoryDat();
+
+ Set<ResType> getExpectedResourceTypes();
+ }
+
+ protected static abstract class AbstractTestPayload implements TestPayload {
+ private boolean clearInventoryDat;
+ private Set<ResType> resourceTypes;
+
+ public AbstractTestPayload(boolean clearInventoryDat, Collection<ResType> resourceTypes) {
+ this.clearInventoryDat = clearInventoryDat;
+ this.resourceTypes = new HashSet<ResType>(resourceTypes);
+ }
+
+ public boolean isClearInventoryDat() {
+ return clearInventoryDat;
+ }
+
+ public Set<ResType> getExpectedResourceTypes() {
+ return resourceTypes;
+ }
+ }
+
@BeforeClass
public void init() {
tmpDir = getTmpDirectory();
@@ -81,21 +156,21 @@ public abstract class ResourceUpgradeTestBase {
dataDir = new File(tmpDir, DATA_DIR_NAME);
assertTrue(dataDir.mkdir(), "Could not create plugin container data directory.");
}
-
+
@BeforeClass
public void verifyPluginsExist() {
for (String plugin : getRequiredPlugins()) {
verifyPluginExists(plugin);
}
}
-
+
@AfterClass
public void undeployPlugins() throws IOException {
FileUtils.deleteDirectory(tmpDir);
}
-
+
protected abstract Collection<String> getRequiredPlugins();
-
+
protected void setCurrentServerSideInventory(FakeServerInventory currentServerSideInventory) {
this.currentServerSideInventory = currentServerSideInventory;
}
@@ -103,8 +178,9 @@ public abstract class ResourceUpgradeTestBase {
protected FakeServerInventory getCurrentServerSideInventory() {
return currentServerSideInventory;
}
-
- protected void setCurrentResourceFactoryServerService(ResourceFactoryServerService currentResourceFactoryServerService) {
+
+ protected void setCurrentResourceFactoryServerService(
+ ResourceFactoryServerService currentResourceFactoryServerService) {
this.currentResourceFactoryServerService = currentResourceFactoryServerService;
}
@@ -178,24 +254,24 @@ public abstract class ResourceUpgradeTestBase {
protected static File getTmpDirectory() {
File ret = new File(System.getProperty("java.io.tmpdir"), "resource-upgrade-test" + System.currentTimeMillis());
-
+
while (ret.exists() || !ret.mkdir()) {
ret = new File(System.getProperty("java.io.tmpdir"), "resource-upgrade-test" + System.currentTimeMillis());
}
-
+
return ret;
}
private PluginContainerConfiguration createPluginContainerConfiguration(Mockery context) throws Exception {
PluginContainerConfiguration conf = new PluginContainerConfiguration();
-
+
conf.setPluginDirectory(new File(tmpDir, PLUGINS_DIR_NAME));
conf.setDataDirectory(new File(tmpDir, DATA_DIR_NAME));
conf.setTemporaryDirectory(new File(tmpDir, TMP_DIR_NAME));
conf.setInsideAgent(true); //pc must think it's inside an agent so that it persists the inventory between restarts
conf.setPluginFinder(new FileSystemPluginFinder(conf.getPluginDirectory()));
- conf.setCreateResourceClassloaders(false);
-
+ conf.setCreateResourceClassloaders(false);
+
//we're not interested in any scans happening out of our control
conf.setAvailabilityScanInitialDelay(Long.MAX_VALUE);
conf.setConfigurationDiscoveryInitialDelay(Long.MAX_VALUE);
@@ -204,7 +280,7 @@ public abstract class ResourceUpgradeTestBase {
conf.setMeasurementCollectionInitialDelay(Long.MAX_VALUE);
conf.setServerDiscoveryInitialDelay(Long.MAX_VALUE);
conf.setServiceDiscoveryInitialDelay(Long.MAX_VALUE);
-
+
setCurrentBundleServerService(context.mock(BundleServerService.class));
setCurrentConfigurationServerService(context.mock(ConfigurationServerService.class));
setCurrentContentServerService(context.mock(ContentServerService.class));
@@ -214,7 +290,7 @@ public abstract class ResourceUpgradeTestBase {
setCurrentMeasurementServerService(context.mock(MeasurementServerService.class));
setCurrentOperationServerService(context.mock(OperationServerService.class));
setCurrentResourceFactoryServerService(context.mock(ResourceFactoryServerService.class));
-
+
ServerServices serverServices = new ServerServices();
serverServices.setBundleServerService(getCurrentBundleServerService());
serverServices.setConfigurationServerService(getCurrentConfigurationServerService());
@@ -225,9 +301,9 @@ public abstract class ResourceUpgradeTestBase {
serverServices.setMeasurementServerService(getCurrentMeasurementServerService());
serverServices.setOperationServerService(getCurrentOperationServerService());
serverServices.setResourceFactoryServerService(getCurrentResourceFactoryServerService());
-
+
conf.setServerServices(serverServices);
-
+
return conf;
}
@@ -236,104 +312,76 @@ public abstract class ResourceUpgradeTestBase {
*/
protected void verifyPluginExists(String pluginResourcePath) {
URL url = getClass().getResource(pluginResourcePath);
-
+
File pluginFile = FileUtils.toFile(url);
-
+
assertTrue(pluginFile.exists(), pluginFile.getAbsoluteFile() + " plugin jar could not be found.");
}
private void copyPlugin(String pluginResourcePath, File pluginDirectory) throws IOException {
URL pluginUrl = getClass().getResource(pluginResourcePath);
-
+
File pluginFile = new File(pluginResourcePath);
String pluginFileName = pluginFile.getName();
-
- FileUtils.copyURLToFile(pluginUrl, new File(pluginDirectory, pluginFileName));
- }
-
- protected interface TestPayload {
- Expectations getExpectations(Mockery context) throws Exception;
- void test(Set<Resource> resourceUpgradeTestResources);
- boolean isClearInventoryDat();
- String getResourceTypeName();
- String getResourceTypePluginName();
- }
-
- protected static abstract class AbstractTestPayload implements TestPayload {
- private boolean clearInventoryDat;
- private String resourceTypeName;
- private String resourceTypePluginName;
-
- public AbstractTestPayload(boolean clearInventoryDat, String resourceTypeName, String resourceTypePluginName) {
- this.clearInventoryDat = clearInventoryDat;
- this.resourceTypeName = resourceTypeName;
- this.resourceTypePluginName = resourceTypePluginName;
- }
-
- public boolean isClearInventoryDat() {
- return clearInventoryDat;
- }
-
- public String getResourceTypeName() {
- return resourceTypeName;
- }
-
- public String getResourceTypePluginName() {
- return resourceTypePluginName;
- }
- }
- /**
- *
- */
- public ResourceUpgradeTestBase() {
- super();
+ FileUtils.copyURLToFile(pluginUrl, new File(pluginDirectory, pluginFileName));
}
private Set<Resource> getTestingResources(String resourceTypeName, String resourceTypePluginName) {
- ResourceType resType = PluginContainer.getInstance().getPluginManager().getMetadataManager().getType(resourceTypeName, resourceTypePluginName);
-
+ ResourceType resType = PluginContainer.getInstance().getPluginManager().getMetadataManager()
+ .getType(resourceTypeName, resourceTypePluginName);
+
return getCurrentServerSideInventory().findResourcesByType(resType);
}
protected void executeTestWithPlugins(Set<String> pluginResourcePaths, TestPayload test) throws Exception {
FileUtils.cleanDirectory(new File(tmpDir, PLUGINS_DIR_NAME));
-
- for(String pluginResourcePath : pluginResourcePaths) {
+
+ for (String pluginResourcePath : pluginResourcePaths) {
copyPlugin(pluginResourcePath, pluginDir);
}
-
+
Mockery context = new Mockery();
-
+
PluginContainerConfiguration pcConfig = createPluginContainerConfiguration(context);
-
+
if (test.isClearInventoryDat()) {
File inventoryDat = new File(pcConfig.getDataDirectory(), "inventory.dat");
inventoryDat.delete();
}
-
+
context.checking(test.getExpectations(context));
-
+
PluginContainer.getInstance().setConfiguration(pcConfig);
PluginContainer.getInstance().initialize();
-
+
try {
//give the pc the time to finish resource upgrade
Thread.sleep(1000);
-
+
//execute full discovery
InventoryManager im = PluginContainer.getInstance().getInventoryManager();
im.executeServerScanImmediately();
- im.executeServiceScanImmediately();
-
- Set<Resource> resources = getTestingResources(test.getResourceTypeName(), test.getResourceTypePluginName());
-
+
+ //do the service scan a couple of times so that we can commit
+ //the resources deep in the type hierarchy
+ for(int i = 0; i < 10; ++i) {
+ im.executeServiceScanImmediately();
+ }
+
+ Map<ResType, Set<Resource>> resources = new HashMap<ResType, Set<Resource>>();
+
+ for(ResType type : test.getExpectedResourceTypes()) {
+ Set<Resource> rs = getTestingResources(type.getResourceTypeName(), type.getResourceTypePluginName());
+ resources.put(type, rs);
+ }
+
test.test(resources);
-
+
context.assertIsSatisfied();
} finally {
- PluginContainer.getInstance().shutdown();
- }
+ PluginContainer.getInstance().shutdown();
+ }
}
@SuppressWarnings("unchecked")
@@ -346,11 +394,13 @@ public abstract class ResourceUpgradeTestBase {
expectations.ignoring(getCurrentMeasurementServerService());
expectations.ignoring(getCurrentOperationServerService());
expectations.ignoring(getCurrentResourceFactoryServerService());
-
+
//just ignore these invocations if we get a availability scan in the PC...
- expectations.allowing(getCurrentDiscoveryServerService()).mergeAvailabilityReport(expectations.with(Expectations.any(AvailabilityReport.class)));
-
- expectations.allowing(getCurrentDiscoveryServerService()).getResources(expectations.with(Expectations.any(Set.class)), expectations.with(Expectations.any(boolean.class)));
+ expectations.allowing(getCurrentDiscoveryServerService()).mergeAvailabilityReport(
+ expectations.with(Expectations.any(AvailabilityReport.class)));
+
+ expectations.allowing(getCurrentDiscoveryServerService()).getResources(
+ expectations.with(Expectations.any(Set.class)), expectations.with(Expectations.any(boolean.class)));
expectations.will(getCurrentServerSideInventory().getResources());
}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseDiscoveryComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseDiscoveryComponent.java
index 61d4fe0..a03dff5 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseDiscoveryComponent.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseDiscoveryComponent.java
@@ -46,15 +46,25 @@ public class BaseDiscoveryComponent<T extends ResourceComponent> implements Reso
String keyTemplate = pluginConfig.getSimpleValue("key", null);
int count = pluginConfig.getSimple("count").getIntegerValue();
- int parentN = context.getParentResourceContext().getPluginConfiguration().getSimple("ordinal")
- .getIntegerValue();
+ int parentN = 0;
+
+ if (context.getParentResourceContext() != null) {
+ PropertySimple parentOrdinalProperty = context.getParentResourceContext().getPluginConfiguration()
+ .getSimple("ordinal");
+
+ if (parentOrdinalProperty != null) {
+ parentN = parentOrdinalProperty.getIntegerValue();
+ }
+ }
for (int i = 0; i < count; ++i) {
String key = getResourceKey(keyTemplate, i, parentN);
+ pluginConfig = context.getDefaultPluginConfiguration();
+
pluginConfig.put(new PropertySimple("ordinal", i));
-
+
DiscoveredResourceDetails detail = new DiscoveredResourceDetails(context.getResourceType(), key, key, null,
null, pluginConfig, null);
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java
index beb36db..ec1cb20 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java
@@ -28,34 +28,36 @@ import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
*
* @author Lukas Krejci
*/
-public class BaseUpgradingDiscoveryComponent<T extends BaseResourceComponent> extends BaseDiscoveryComponent<T> implements ResourceUpgradeFacet<T> {
+public class BaseUpgradingDiscoveryComponent<T extends BaseResourceComponent> extends BaseDiscoveryComponent<T>
+ implements ResourceUpgradeFacet<T> {
public ResourceUpgradeReport upgrade(ResourceUpgradeContext<T> inventoriedResource) {
Configuration pluginConfig = inventoriedResource.getPluginConfiguration();
-
+
BaseResourceComponent<?> parent = inventoriedResource.getParentResourceComponent();
int ordinal = pluginConfig.getSimple("ordinal").getIntegerValue();
int parentOrdinal = parent == null ? 0 : parent.getOrdinal();
-
+
boolean fail = Boolean.getBoolean(pluginConfig.getSimpleValue("failUpgrade", "false"));
-
+
if (!fail && parent != null) {
fail = parent.getChildrenToFailUpgrade().contains(Integer.valueOf(ordinal));
}
-
+
if (fail) {
throw new RuntimeException("Failing the resource upgrade purposefully.");
}
-
+
String newKey = pluginConfig.getSimpleValue("upgradedKey", null);
-
+
if (newKey == null) {
return null;
}
-
+
ResourceUpgradeReport report = new ResourceUpgradeReport();
-
+
report.setNewResourceKey(getResourceKey(newKey, ordinal, parentOrdinal));
- return null;
+
+ return report;
}
}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml
index f5e6920..608793c 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml
@@ -22,8 +22,8 @@
<plugin-configuration>
<c:simple-property name="count" default="1" />
- <c:simple-property name="key" default="test-resource-parent-sibling-%n,parent-%p" />
- <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-parent-sibling-%n,parent-%p" />
+ <c:simple-property name="key" default="test-resource-parent-dep-sibling-%n,parent-%p" />
+ <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-parent-dep-sibling-%n,parent-%p" />
</plugin-configuration>
</server>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml
index d138066..ddda11a 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml
@@ -22,7 +22,7 @@
<plugin-configuration>
<c:simple-property name="count" default="1" />
- <c:simple-property name="key" default="UPGRADED-test-resource-parent-sibling-%n,parent-%p" />
+ <c:simple-property name="key" default="UPGRADED-test-resource-parent-dep-sibling-%n,parent-%p" />
</plugin-configuration>
</server>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
index 44a1033..d3ea7b7 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
@@ -11,10 +11,18 @@
<depends plugin="base" useClasses="true"/>
- <!-- This service is put in the type hierarchy in the v1/v2 test plugins -->
- <service name="TestResourceSibling"
- discovery="BaseDiscoveryComponent"
- class="BaseResourceComponent" />
+ <server name="Bogus" class="BaseDiscoveryComponent">
+ <!-- This service is put in the type hierarchy in the v1/v2 test plugins -->
+ <service name="TestResourceSibling"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+ <plugin-configuration>
+ <c:simple-property name="count" default="10" />
+ <c:simple-property name="key" default="test-resource-sibling-%n,parent-%p" />
+ <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-sibling-%n,parent-%p" />
+ </plugin-configuration>
+ </service>
+ </server>
</plugin>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
index aeab68f..f7f7a2c 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
@@ -10,10 +10,16 @@
<depends plugin="base" useClasses="true"/>
+ <server name="Bogus" class="BaseDiscoveryComponent">
<!-- This service is put in the type hierarchy in the v1/v2 test plugins -->
<service name="TestResourceSibling"
discovery="BaseUpgradingDiscoveryComponent"
- class="BaseResourceComponent" />
-
+ class="BaseResourceComponent">
+ <plugin-configuration>
+ <c:simple-property name="count" default="15" /> <!-- This intentionally differs from v1 -->
+ <c:simple-property name="key" default="UPGRADED-test-resource-sibling-%n,parent-%p" />
+ </plugin-configuration>
+ </service>
+ </server>
</plugin>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml
index e934494..ebe9793 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml
@@ -37,13 +37,8 @@
</plugin-configuration>
</service>
- <service name="TestResourceSibling" sourcePlugin="sibling" sourceType="TestResourceSibling">
- <plugin-configuration>
- <c:simple-property name="count" default="10" />
- <c:simple-property name="key" default="test-resource-sibling-%n,parent-%p" />
- <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-sibling-%n,parent-%p" />
- </plugin-configuration>
- </service>
+ <service name="TestResourceSibling" sourcePlugin="sibling" sourceType="TestResourceSibling"
+ class="BaseResourceComponent" discovery="BaseDiscoveryComponent" />
</server>
</plugin>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
index 96658e3..3d709b0 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
@@ -26,7 +26,7 @@
</plugin-configuration>
<service name="TestResource"
- discovery="BaseDiscoveryComponent"
+ discovery="BaseUpgradingDiscoveryComponent"
class="BaseResourceComponent">
<plugin-configuration>
<c:simple-property name="count" default="15" /> <!-- This intentionally differs from v1 -->
@@ -35,13 +35,8 @@
</service>
- <service name="TestResourceSibling" sourcePlugin="sibling" sourceType="TestResourceSibling">
- <plugin-configuration>
- <c:simple-property name="count" default="15" /> <!-- This intentionally differs from v1 -->
- <c:simple-property name="key" default="UPGRADED-test-resource-sibling-%n,parent-%p" />
- </plugin-configuration>
- </service>
-
+ <service name="TestResourceSibling" sourcePlugin="sibling" sourceType="TestResourceSibling"
+ class="BaseResourceComponent" discovery="BaseUpgradingDiscoveryComponent" />
</server>
</plugin>
commit c99d68dd036f243a2f28e000e10385d27bbdb785
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Sep 29 13:53:45 2010 +0200
Adding a skeleton of what will need to be tested for upgrade failure handling.
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
new file mode 100644
index 0000000..25eca30
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
@@ -0,0 +1,81 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.core.pc.upgrade;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.testng.annotations.Test;
+
+/**
+ * The plugins and their resource types form the following dependency structure:
+ * <pre>
+ * Root(root)
+ * / \
+ * ParentDependency(parentdep) ParentDepSibling(parentsibling)
+ * / \
+ * TestResource(test) TestResourceSibling(sibling)
+ * </pre>
+ * The dependencies in the above "chart" are formed using either the <code><runs-inside></code>
+ * or <code>sourcePlugin/sourceType</code> approaches just to test that both are handled correctly.
+ *
+ * @author Lukas Krejci
+ */
+@Test(sequential = true, invocationCount = 1)
+public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase {
+
+ //plugin names
+ private static final String BASE_PLUGIN_NAME = "/resource-upgrade-test-plugin-multi-base-1.0.0.jar";
+ private static final String PARENT_DEP_V1_PLUGIN_NAME = "/resource-upgrade-test-plugin-multi-parentdep-1.0.0.jar";
+ private static final String PARENT_DEP_V2_PLUGIN_NAME = "/resource-upgrade-test-plugin-multi-parentdep-2.0.0.jar";
+ private static final String PARENT_SIBLING_V1_PLUGIN_NAME = "/resource-upgrade-test-plugin-multi-parentsibling-1.0.0.jar";
+ private static final String PARENT_SIBLING_V2_PLUGIN_NAME = "/resource-upgrade-test-plugin-multi-parentsibling-2.0.0.jar";
+ private static final String ROOT_PLUGIN_NAME = "/resource-upgrade-test-plugin-multi-root-1.0.0.jar";
+ private static final String SIBLING_V1_PLUGIN_NAME = "/resource-upgrade-test-plugin-multi-sibling-1.0.0.jar";
+ private static final String SIBLING_V2_PLUGIN_NAME = "/resource-upgrade-test-plugin-multi-sibling-2.0.0.jar";
+ private static final String TEST_V1_PLUGIN_NAME = "/resource-upgrade-test-plugin-multi-test-1.0.0.jar";
+ private static final String TEST_V2_PLUGIN_NAME = "/resource-upgrade-test-plugin-multi-test-2.0.0.jar";
+
+ protected Collection<String> getRequiredPlugins() {
+ return Arrays.asList(BASE_PLUGIN_NAME, PARENT_DEP_V1_PLUGIN_NAME, PARENT_DEP_V2_PLUGIN_NAME,
+ PARENT_SIBLING_V1_PLUGIN_NAME, PARENT_SIBLING_V2_PLUGIN_NAME, ROOT_PLUGIN_NAME, SIBLING_V1_PLUGIN_NAME,
+ SIBLING_V2_PLUGIN_NAME, TEST_V1_PLUGIN_NAME, TEST_V2_PLUGIN_NAME);
+ }
+
+ @Test
+ public void testSuccess() {
+ //TODO implement
+ //check that all the stuff is properly upgraded on success
+ }
+
+ @Test
+ public void testFailureOnLeaf() {
+ //TODO implement
+ //check that the system behaves correctly if there is an upgrade failure
+ //at the leaf node of the plugin dep graph
+ }
+
+ @Test
+ public void testFailureOnDependencies() {
+ //TODO implement
+ //check that stuff works if there is an upgrade failure on some of the resources
+ //in the plugin some "in the middle" of the plugin dep graph
+ }
+}
commit 4f504f582fc9040bcf5ed7f7dd24cfd3bc2adbad
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Sep 29 13:49:24 2010 +0200
some more minor changes to class structure and plugin names.
diff --git a/modules/core/plugin-container/pom.xml b/modules/core/plugin-container/pom.xml
index 035bf36..4d6e753 100644
--- a/modules/core/plugin-container/pom.xml
+++ b/modules/core/plugin-container/pom.xml
@@ -281,7 +281,7 @@
<!-- <copy toDir="${project.build.testOutputDirectory}/tmp/multi/v1/org/rhq/core/pc/upgrade/plugins/multi/v1">
<fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/v1/*.class" />
</copy> -->
- <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-1.0.0.jar">
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-test-1.0.0.jar">
<fileset dir="${project.build.testOutputDirectory}/tmp/multi/v1" includes="**/*.class,**/rhq-plugin.xml" />
</jar>
@@ -291,7 +291,7 @@
<!-- <copy toDir="${project.build.testOutputDirectory}/tmp/multi/v2/org/rhq/core/pc/upgrade/plugins/multi/v2">
<fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/v2/*.class" />
</copy> -->
- <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-2.0.0.jar">
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-test-2.0.0.jar">
<fileset dir="${project.build.testOutputDirectory}/tmp/multi/v2" includes="**/*.class,**/rhq-plugin.xml" />
</jar>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index e13ea3d..8cfec36 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -28,6 +28,8 @@ import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import java.io.File;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.Set;
@@ -38,7 +40,6 @@ import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.pc.PluginContainer;
import org.rhq.core.pc.inventory.ResourceContainer;
-import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
@@ -56,11 +57,8 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
static final String SINGLETON_RESOURCE_TYPE_NAME = "Resource";
static final String SINGLETON_RESOURCE_TYPE_PLUGIN_NAME = "ResourceUpgradeTest";
- @BeforeClass
- public void sanityCheck() {
- verifyPluginExists(PLUGIN_V1_FILENAME);
- verifyPluginExists(PLUGIN_V2_FILENAME);
- verifyPluginExists(FAILING_PLUGIN_FILE_NAME);
+ protected Collection<String> getRequiredPlugins() {
+ return Arrays.asList(PLUGIN_V1_FILENAME, PLUGIN_V2_FILENAME, FAILING_PLUGIN_FILE_NAME);
}
@Test
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
index f03f2a4..3aa772b 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
@@ -24,6 +24,7 @@ import static org.testng.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import java.net.URL;
+import java.util.Collection;
import java.util.Set;
import org.apache.commons.io.FileUtils;
@@ -53,7 +54,7 @@ import org.testng.annotations.BeforeClass;
*
* @author Lukas Krejci
*/
-public class ResourceUpgradeTestBase {
+public abstract class ResourceUpgradeTestBase {
private static final String PLUGINS_DIR_NAME = "plugins";
private static final String DATA_DIR_NAME = "data";
@@ -81,11 +82,20 @@ public class ResourceUpgradeTestBase {
assertTrue(dataDir.mkdir(), "Could not create plugin container data directory.");
}
+ @BeforeClass
+ public void verifyPluginsExist() {
+ for (String plugin : getRequiredPlugins()) {
+ verifyPluginExists(plugin);
+ }
+ }
+
@AfterClass
public void undeployPlugins() throws IOException {
FileUtils.deleteDirectory(tmpDir);
}
+ protected abstract Collection<String> getRequiredPlugins();
+
protected void setCurrentServerSideInventory(FakeServerInventory currentServerSideInventory) {
this.currentServerSideInventory = currentServerSideInventory;
}
commit b97e79bcbd5c557fba29030f7aa0f8b4c629c56f
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Sep 29 13:48:28 2010 +0200
Simplify plugin names, declare correct discovery components for upgrade failure test plugins.
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/rhq-plugin.xml
index 7edfba1..d262c75 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/rhq-plugin.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTestBase"
+<plugin name="base"
displayName=""
description=""
package="org.rhq.core.pc.upgrade.plugins.multi.base"
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/rhq-plugin.xml
index 3612974..8cadc84 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/rhq-plugin.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTestParentDep"
+<plugin name="parentdep"
displayName="Resource Upgrade Multi Test"
description="Resource Upgrade Multi Test"
package="org.rhq.core.pc.upgrade.plugins.multi.base"
@@ -9,15 +9,15 @@
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
- <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
- <depends plugin="ResourceUpgradeMultiTestRoot"/>
+ <depends plugin="base" useClasses="true"/>
+ <depends plugin="root"/>
<server name="ParentDependency"
discovery="BaseDiscoveryComponent"
class="BaseResourceComponent">
<runs-inside>
- <parent-resource-type name="Root" plugin="ResourceUpgradeMultiTestRoot"/>
+ <parent-resource-type name="Root" plugin="root"/>
</runs-inside>
<plugin-configuration>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/rhq-plugin.xml
index 6b95114..8169122 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/rhq-plugin.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTestParentDep"
+<plugin name="parentdep"
displayName="Resource Upgrade Multi Test"
description="Resource Upgrade Multi Test"
package="org.rhq.core.pc.upgrade.plugins.multi.base"
@@ -9,15 +9,15 @@
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
- <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
- <depends plugin="ResourceUpgradeMultiTestRoot"/>
+ <depends plugin="base" useClasses="true"/>
+ <depends plugin="root"/>
<server name="ParentDependency"
- discovery="BaseDiscoveryComponent"
+ discovery="BaseUpgradingDiscoveryComponent"
class="BaseResourceComponent">
<runs-inside>
- <parent-resource-type name="Root" plugin="ResourceUpgradeMultiTestRoot"/>
+ <parent-resource-type name="Root" plugin="root"/>
</runs-inside>
<plugin-configuration>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml
index fbade54..f5e6920 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTestParentSibling"
+<plugin name="parentsibling"
displayName="Resource Upgrade Multi Test"
description="Resource Upgrade Multi Test"
package="org.rhq.core.pc.upgrade.plugins.multi.base"
@@ -9,15 +9,15 @@
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
- <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
- <depends plugin="ResourceUpgradeMultiTestRoot"/>
+ <depends plugin="base" useClasses="true"/>
+ <depends plugin="root"/>
<server name="ParentDepSibling"
discovery="BaseDiscoveryComponent"
class="BaseResourceComponent">
<runs-inside>
- <parent-resource-type name="Root" plugin="ResourceUpgradeMultiTestRoot"/>
+ <parent-resource-type name="Root" plugin="root"/>
</runs-inside>
<plugin-configuration>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml
index f16d526..d138066 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTestParentSibling"
+<plugin name="parentsibling"
displayName="Resource Upgrade Multi Test"
description="Resource Upgrade Multi Test"
package="org.rhq.core.pc.upgrade.plugins.multi.base"
@@ -9,15 +9,15 @@
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
- <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
- <depends plugin="ResourceUpgradeMultiTestRoot"/>
+ <depends plugin="base" useClasses="true"/>
+ <depends plugin="root"/>
<server name="ParentDepSibling"
- discovery="BaseDiscoveryComponent"
+ discovery="BaseUpgradingDiscoveryComponent"
class="BaseResourceComponent">
<runs-inside>
- <parent-resource-type name="Root" plugin="ResourceUpgradeMultiTestRoot"/>
+ <parent-resource-type name="Root" plugin="root"/>
</runs-inside>
<plugin-configuration>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/root/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/root/rhq-plugin.xml
index b5efbb1..e95c9bd 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/root/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/root/rhq-plugin.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTestRoot"
+<plugin name="root"
displayName=""
description=""
package="org.rhq.core.pc.upgrade.plugins.multi.base"
@@ -9,6 +9,8 @@
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
+ <depends plugin="base" useClasses="true"/>
+
<server name="Root"
discovery="BaseDiscoveryComponent"
class="BaseResourceComponent">
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
index f87ef4d..44a1033 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTestSibling"
+<plugin name="sibling"
displayName="Resource Upgrade Multi Test"
description="Resource Upgrade Multi Test"
package="org.rhq.core.pc.upgrade.plugins.multi.base"
@@ -9,30 +9,12 @@
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
- <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
- <depends plugin="ResourceUpgradeMultiTestParentDep"/>
+ <depends plugin="base" useClasses="true"/>
- <server name="TestResourceParentSibling"
- discovery="BaseDiscoveryComponent"
- class="BaseResourceComponent">
-
- <plugin-configuration>
- <c:simple-property name="count" default="2" />
- <c:simple-property name="key" default="test-resource-parent-sibling-%n,parent-%p" />
- <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-parent-sibling-%n,parent-%p" />
- </plugin-configuration>
-
- <service name="TestResourceSibling"
+ <!-- This service is put in the type hierarchy in the v1/v2 test plugins -->
+ <service name="TestResourceSibling"
discovery="BaseDiscoveryComponent"
- class="BaseResourceComponent">
- <plugin-configuration>
- <c:simple-property name="count" default="10" />
- <c:simple-property name="key" default="test-resource-sibling-%n,parent-%p" />
- <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-sibling-%n,parent-%p" />
- </plugin-configuration>
-
- </service>
- </server>
+ class="BaseResourceComponent" />
</plugin>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
index e6ab95f..aeab68f 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTestSibling"
+<plugin name="sibling"
displayName="Resource Upgrade Multi Test"
description="Resource Upgrade Multi Test"
package="org.rhq.core.pc.upgrade.plugins.multi.base"
@@ -8,34 +8,12 @@
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
- <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
- <depends plugin="ResourceUpgradeMultiTestParentDep"/>
+ <depends plugin="base" useClasses="true"/>
- <server name="TestResourceParentSibling"
- discovery="BaseUpgradingDiscoveryComponent"
- class="BaseResourceComponent">
-
- <runs-inside>
- <parent-resource-type name="ParentDependency" plugin="ResourceUpgradeMultiTestParentDep"/>
- </runs-inside>
-
- <plugin-configuration>
- <c:simple-property name="count" default="2" />
- <c:simple-property name="key" default="UPGRADED-test-resource-parent-sibling-%n,parent-%p" />
- </plugin-configuration>
-
- <service name="TestResourceSibling"
- discovery="BaseDiscoveryComponent"
- class="BaseResourceComponent">
- <plugin-configuration>
- <c:simple-property name="count" default="15" />
- <c:simple-property name="key" default="UPGRADED-test-resource-sibling-%n,parent-%p" />
- </plugin-configuration>
-
- </service>
-
-
- </server>
+ <!-- This service is put in the type hierarchy in the v1/v2 test plugins -->
+ <service name="TestResourceSibling"
+ discovery="BaseUpgradingDiscoveryComponent"
+ class="BaseResourceComponent" />
</plugin>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml
index 32ad438..e934494 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTest"
+<plugin name="test"
displayName="Resource Upgrade Multi Test"
description="Resource Upgrade Multi Test"
package="org.rhq.core.pc.upgrade.plugins.multi.base"
@@ -9,15 +9,16 @@
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
- <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
- <depends plugin="ResourceUpgradeMultiTestParentDep"/>
+ <depends plugin="base" useClasses="true"/>
+ <depends plugin="parentdep"/>
+ <depends plugin="sibling" />
<server name="TestResourceParent"
discovery="BaseDiscoveryComponent"
class="BaseResourceComponent">
<runs-inside>
- <parent-resource-type name="ParentDependency" plugin="ResourceUpgradeMultiTestParentDep"/>
+ <parent-resource-type name="ParentDependency" plugin="parentdep"/>
</runs-inside>
<plugin-configuration>
@@ -29,13 +30,20 @@
<service name="TestResource"
discovery="BaseDiscoveryComponent"
class="BaseResourceComponent">
- <plugin-configuration>
- <c:simple-property name="count" default="10" />
- <c:simple-property name="key" default="test-resource-%n,parent-%p" />
- <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-%n,parent-%p" />
- </plugin-configuration>
-
- </service>
+ <plugin-configuration>
+ <c:simple-property name="count" default="10" />
+ <c:simple-property name="key" default="test-resource-%n,parent-%p" />
+ <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-%n,parent-%p" />
+ </plugin-configuration>
+ </service>
+
+ <service name="TestResourceSibling" sourcePlugin="sibling" sourceType="TestResourceSibling">
+ <plugin-configuration>
+ <c:simple-property name="count" default="10" />
+ <c:simple-property name="key" default="test-resource-sibling-%n,parent-%p" />
+ <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-sibling-%n,parent-%p" />
+ </plugin-configuration>
+ </service>
</server>
</plugin>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
index 824d3fe..96658e3 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin name="ResourceUpgradeMultiTest"
+<plugin name="test"
displayName="Resource Upgrade Multi Test"
description="Resource Upgrade Multi Test"
package="org.rhq.core.pc.upgrade.plugins.multi.base"
@@ -8,15 +8,16 @@
xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
- <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
- <depends plugin="ResourceUpgradeMultiTestParentDep"/>
+ <depends plugin="base" useClasses="true"/>
+ <depends plugin="parentdep"/>
+ <depends plugin="sibling"/>
<server name="TestResourceParent"
discovery="BaseUpgradingDiscoveryComponent"
class="BaseResourceComponent">
<runs-inside>
- <parent-resource-type name="ParentDependency" plugin="ResourceUpgradeMultiTestParentDep"/>
+ <parent-resource-type name="ParentDependency" plugin="parentdep"/>
</runs-inside>
<plugin-configuration>
@@ -27,13 +28,19 @@
<service name="TestResource"
discovery="BaseDiscoveryComponent"
class="BaseResourceComponent">
- <plugin-configuration>
- <c:simple-property name="count" default="15" />
- <c:simple-property name="key" default="UPGRADED-test-resource-%n,parent-%p" />
- </plugin-configuration>
+ <plugin-configuration>
+ <c:simple-property name="count" default="15" /> <!-- This intentionally differs from v1 -->
+ <c:simple-property name="key" default="UPGRADED-test-resource-%n,parent-%p" />
+ </plugin-configuration>
</service>
+ <service name="TestResourceSibling" sourcePlugin="sibling" sourceType="TestResourceSibling">
+ <plugin-configuration>
+ <c:simple-property name="count" default="15" /> <!-- This intentionally differs from v1 -->
+ <c:simple-property name="key" default="UPGRADED-test-resource-sibling-%n,parent-%p" />
+ </plugin-configuration>
+ </service>
</server>
commit 097f744dec27c5584cf6203bbaff6fc041753b26
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Sep 29 13:12:09 2010 +0200
Extracted a base class from the upgrade test in preparation for adding another round of tests.
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 0a2a660..e13ea3d 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -23,43 +23,23 @@
package org.rhq.core.pc.upgrade;
-import static org.testng.Assert.assertTrue;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
import java.io.File;
-import java.io.IOException;
-import java.net.URL;
import java.util.Collections;
import java.util.Set;
-import org.apache.commons.io.FileUtils;
import org.jmock.Expectations;
import org.jmock.Mockery;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
-import org.rhq.core.clientapi.server.bundle.BundleServerService;
-import org.rhq.core.clientapi.server.configuration.ConfigurationServerService;
-import org.rhq.core.clientapi.server.content.ContentServerService;
-import org.rhq.core.clientapi.server.core.CoreServerService;
-import org.rhq.core.clientapi.server.discovery.DiscoveryServerService;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
-import org.rhq.core.clientapi.server.event.EventServerService;
-import org.rhq.core.clientapi.server.inventory.ResourceFactoryServerService;
-import org.rhq.core.clientapi.server.measurement.MeasurementServerService;
-import org.rhq.core.clientapi.server.operation.OperationServerService;
-import org.rhq.core.domain.discovery.AvailabilityReport;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.pc.PluginContainer;
-import org.rhq.core.pc.PluginContainerConfiguration;
-import org.rhq.core.pc.ServerServices;
-import org.rhq.core.pc.inventory.InventoryManager;
import org.rhq.core.pc.inventory.ResourceContainer;
-import org.rhq.core.pc.plugin.FileSystemPluginFinder;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
/**
* Test cases for resource upgrade.
@@ -67,39 +47,14 @@ import org.rhq.core.pc.plugin.FileSystemPluginFinder;
* @author Lukas Krejci
*/
@Test(sequential = true, invocationCount = 1)
-public class ResourceUpgradeTest {
+public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
private static final String PLUGIN_V1_FILENAME = "/resource-upgrade-test-plugin-1.0.0.jar";
private static final String PLUGIN_V2_FILENAME = "/resource-upgrade-test-plugin-2.0.0.jar";
private static final String FAILING_PLUGIN_FILE_NAME = "/resource-upgrade-test-plugin-3.0.0.jar";
- private static final String PLUGINS_DIR_NAME = "plugins";
- private static final String DATA_DIR_NAME = "data";
- private static final String TMP_DIR_NAME = "tmp";
-
- private static final String SINGLETON_RESOURCE_TYPE_NAME = "Resource";
- private static final String SINGLETON_RESOURCE_TYPE_PLUGIN_NAME = "ResourceUpgradeTest";
-
- private File tmpDir;
- private File pluginDir;
- private File dataDir;
-
- private BundleServerService currentBundleServerService;
- private ConfigurationServerService currentConfigurationServerService;
- private ContentServerService currentContentServerService;
- private CoreServerService currentCoreServerService;
- private DiscoveryServerService currentDiscoveryServerService;
- private EventServerService currentEventServerService;
- private MeasurementServerService currentMeasurementServerService;
- private OperationServerService currentOperationServerService;
- private ResourceFactoryServerService currentResourceFactoryServerService;
-
- private FakeServerInventory currentServerSideInventory;
-
- @AfterClass
- public void undeployPlugins() throws IOException {
- FileUtils.deleteDirectory(tmpDir);
- }
+ static final String SINGLETON_RESOURCE_TYPE_NAME = "Resource";
+ static final String SINGLETON_RESOURCE_TYPE_PLUGIN_NAME = "ResourceUpgradeTest";
@BeforeClass
public void sanityCheck() {
@@ -108,18 +63,9 @@ public class ResourceUpgradeTest {
verifyPluginExists(FAILING_PLUGIN_FILE_NAME);
}
- @BeforeClass(dependsOnMethods = "sanityCheck")
- public void init() {
- tmpDir = getTmpDirectory();
- pluginDir = new File(tmpDir, PLUGINS_DIR_NAME);
- assertTrue(pluginDir.mkdir(), "Could not create plugin deploy directory.");
- dataDir = new File(tmpDir, DATA_DIR_NAME);
- assertTrue(dataDir.mkdir(), "Could not create plugin container data directory.");
- }
-
@Test
public void testIgnoreUncommittedResources() throws Exception {
- currentServerSideInventory = new FakeServerInventory();
+ setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.NEW);
TestPayload testNoChange = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
@@ -138,8 +84,8 @@ public class ResourceUpgradeTest {
{
defineDefaultExpectations(this);
- between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
- will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+ between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
}
};
}
@@ -150,22 +96,22 @@ public class ResourceUpgradeTest {
@Test
public void testUpgradeData() throws Exception {
- currentServerSideInventory = new FakeServerInventory();
+ setCurrentServerSideInventory(new FakeServerInventory());
upgradeTest(false);
}
@Test
public void testInventoryReinitializationFromServerDuringUpgrade() throws Exception {
- currentServerSideInventory = new FakeServerInventory();
+ setCurrentServerSideInventory(new FakeServerInventory());
upgradeTest(true);
}
@Test
public void testSkipUpgradeWhenServerUnavailable() throws Exception {
- currentServerSideInventory = new FakeServerInventory();
+ setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
- currentServerSideInventory.setFailing(true);
+ getCurrentServerSideInventory().setFailing(true);
TestPayload test = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
public void test(Set<Resource> discoveredResources) {
@@ -184,10 +130,10 @@ public class ResourceUpgradeTest {
{
defineDefaultExpectations(this);
- between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
- will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+ between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
- never(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
+ never(getCurrentDiscoveryServerService()).upgradeResources(with(any(Set.class)));
}
};
}
@@ -198,7 +144,7 @@ public class ResourceUpgradeTest {
@Test
public void testUpgradeWithPlatformDeletedOnServer() throws Exception {
- currentServerSideInventory = new FakeServerInventory();
+ setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
TestPayload test = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
@@ -227,15 +173,15 @@ public class ResourceUpgradeTest {
//the first merge will be triggered from within the upgrade process and we are
//going to report null sync.
- oneOf(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
- will(currentServerSideInventory.clearPlatform());
+ oneOf(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(getCurrentServerSideInventory().clearPlatform());
//the rest of the inventory merges are executed by discoveries, so let's import the
//discovered stuff into the server-side inventory.
- between(1, 3).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
- will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+ between(1, 3).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
- never(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
+ never(getCurrentDiscoveryServerService()).upgradeResources(with(any(Set.class)));
}
};
}
@@ -246,7 +192,7 @@ public class ResourceUpgradeTest {
@Test
public void testUpgradeFailureHandling() throws Exception {
- currentServerSideInventory = new FakeServerInventory();
+ setCurrentServerSideInventory(new FakeServerInventory());
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
TestPayload test = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
@@ -272,11 +218,11 @@ public class ResourceUpgradeTest {
{
defineDefaultExpectations(this);
- between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
- will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+ between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
- oneOf(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
- will(currentServerSideInventory.upgradeResources());
+ oneOf(getCurrentDiscoveryServerService()).upgradeResources(with(any(Set.class)));
+ will(getCurrentServerSideInventory().upgradeResources());
}
};
}
@@ -297,20 +243,21 @@ public class ResourceUpgradeTest {
assertEquals(discoveredResource.getName(), "resource-name-v1");
assertEquals(discoveredResource.getDescription(), "resource-description-v1");
}
-
+
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
defineDefaultExpectations(this);
- between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
- will(currentServerSideInventory.mergeInventoryReport(requiredInventoryStatus));
+ between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(getCurrentServerSideInventory().mergeInventoryReport(requiredInventoryStatus));
}
};
}
});
}
+
private void upgradeTest(boolean clearInventoryDat) throws Exception {
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
@@ -339,189 +286,14 @@ public class ResourceUpgradeTest {
{
defineDefaultExpectations(this);
- between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
- will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+ between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
- oneOf(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
- will(currentServerSideInventory.upgradeResources());
+ oneOf(getCurrentDiscoveryServerService()).upgradeResources(with(any(Set.class)));
+ will(getCurrentServerSideInventory().upgradeResources());
}
};
}
});
}
-
- private PluginContainerConfiguration createPluginContainerConfiguration(Mockery context) throws Exception {
- PluginContainerConfiguration conf = new PluginContainerConfiguration();
-
- conf.setPluginDirectory(new File(tmpDir, PLUGINS_DIR_NAME));
- conf.setDataDirectory(new File(tmpDir, DATA_DIR_NAME));
- conf.setTemporaryDirectory(new File(tmpDir, TMP_DIR_NAME));
- conf.setInsideAgent(true); //pc must think it's inside an agent so that it persists the inventory between restarts
- conf.setPluginFinder(new FileSystemPluginFinder(conf.getPluginDirectory()));
- conf.setCreateResourceClassloaders(false);
-
- //we're not interested in any scans happening out of our control
- conf.setAvailabilityScanInitialDelay(Long.MAX_VALUE);
- conf.setConfigurationDiscoveryInitialDelay(Long.MAX_VALUE);
- conf.setContentDiscoveryInitialDelay(Long.MAX_VALUE);
- conf.setEventSenderInitialDelay(Long.MAX_VALUE);
- conf.setMeasurementCollectionInitialDelay(Long.MAX_VALUE);
- conf.setServerDiscoveryInitialDelay(Long.MAX_VALUE);
- conf.setServiceDiscoveryInitialDelay(Long.MAX_VALUE);
-
- currentBundleServerService = context.mock(BundleServerService.class);
- currentConfigurationServerService = context.mock(ConfigurationServerService.class);
- currentContentServerService = context.mock(ContentServerService.class);
- currentCoreServerService = context.mock(CoreServerService.class);
- currentDiscoveryServerService = context.mock(DiscoveryServerService.class);
- currentEventServerService = context.mock(EventServerService.class);
- currentMeasurementServerService = context.mock(MeasurementServerService.class);
- currentOperationServerService = context.mock(OperationServerService.class);
- currentResourceFactoryServerService = context.mock(ResourceFactoryServerService.class);
-
- ServerServices serverServices = new ServerServices();
- serverServices.setBundleServerService(currentBundleServerService);
- serverServices.setConfigurationServerService(currentConfigurationServerService);
- serverServices.setContentServerService(currentContentServerService);
- serverServices.setCoreServerService(currentCoreServerService);
- serverServices.setDiscoveryServerService(currentDiscoveryServerService);
- serverServices.setEventServerService(currentEventServerService);
- serverServices.setMeasurementServerService(currentMeasurementServerService);
- serverServices.setOperationServerService(currentOperationServerService);
- serverServices.setResourceFactoryServerService(currentResourceFactoryServerService);
-
- conf.setServerServices(serverServices);
-
- return conf;
- }
-
- /**
- * @param pluginResourcePath
- */
- private void verifyPluginExists(String pluginResourcePath) {
- URL url = getClass().getResource(pluginResourcePath);
-
- File pluginFile = FileUtils.toFile(url);
-
- assertTrue(pluginFile.exists(), pluginFile.getAbsoluteFile() + " plugin jar could not be found.");
- }
-
- private void copyPlugin(String pluginResourcePath, File pluginDirectory) throws IOException {
- URL pluginUrl = getClass().getResource(pluginResourcePath);
-
- File pluginFile = new File(pluginResourcePath);
- String pluginFileName = pluginFile.getName();
-
- FileUtils.copyURLToFile(pluginUrl, new File(pluginDirectory, pluginFileName));
- }
-
- private static File getTmpDirectory() {
- File ret = new File(System.getProperty("java.io.tmpdir"), "resource-upgrade-test" + System.currentTimeMillis());
-
- while (ret.exists() || !ret.mkdir()) {
- ret = new File(System.getProperty("java.io.tmpdir"), "resource-upgrade-test" + System.currentTimeMillis());
- }
-
- return ret;
- }
-
- private interface TestPayload {
- Expectations getExpectations(Mockery context) throws Exception;
- void test(Set<Resource> resourceUpgradeTestResources);
- boolean isClearInventoryDat();
- String getResourceTypeName();
- String getResourceTypePluginName();
- }
-
- private static abstract class AbstractTestPayload implements TestPayload {
- private boolean clearInventoryDat;
- private String resourceTypeName;
- private String resourceTypePluginName;
-
- public AbstractTestPayload(boolean clearInventoryDat, String resourceTypeName, String resourceTypePluginName) {
- this.clearInventoryDat = clearInventoryDat;
- this.resourceTypeName = resourceTypeName;
- this.resourceTypePluginName = resourceTypePluginName;
- }
-
- public boolean isClearInventoryDat() {
- return clearInventoryDat;
- }
-
- public String getResourceTypeName() {
- return resourceTypeName;
- }
-
- public String getResourceTypePluginName() {
- return resourceTypePluginName;
- }
- }
-
- private Set<Resource> getTestingResources(String resourceTypeName, String resourceTypePluginName) {
- ResourceType resType = PluginContainer.getInstance().getPluginManager().getMetadataManager().getType(resourceTypeName, resourceTypePluginName);
-
- return currentServerSideInventory.findResourcesByType(resType);
- }
-
- private void executeTestWithPlugins(Set<String> pluginResourcePaths, TestPayload test) throws Exception {
- FileUtils.cleanDirectory(new File(tmpDir, PLUGINS_DIR_NAME));
-
- for(String pluginResourcePath : pluginResourcePaths) {
- copyPlugin(pluginResourcePath, pluginDir);
- }
-
- Mockery context = new Mockery();
-
- PluginContainerConfiguration pcConfig = createPluginContainerConfiguration(context);
-
- if (test.isClearInventoryDat()) {
- File inventoryDat = new File(pcConfig.getDataDirectory(), "inventory.dat");
- inventoryDat.delete();
- }
-
- context.checking(test.getExpectations(context));
-
- PluginContainer.getInstance().setConfiguration(pcConfig);
- PluginContainer.getInstance().initialize();
-
- try {
- //give the pc the time to finish resource upgrade
- Thread.sleep(1000);
-
- //execute full discovery
- InventoryManager im = PluginContainer.getInstance().getInventoryManager();
- im.executeServerScanImmediately();
- im.executeServiceScanImmediately();
-
- Set<Resource> resources = getTestingResources(test.getResourceTypeName(), test.getResourceTypePluginName());
-
- test.test(resources);
-
- context.assertIsSatisfied();
- } finally {
- PluginContainer.getInstance().shutdown();
- }
- }
-
- @SuppressWarnings("unchecked")
- private void defineDefaultExpectations(Expectations expectations) {
- expectations.ignoring(currentBundleServerService);
- expectations.ignoring(currentConfigurationServerService);
- expectations.ignoring(currentContentServerService);
- expectations.ignoring(currentCoreServerService);
- expectations.ignoring(currentEventServerService);
- expectations.ignoring(currentMeasurementServerService);
- expectations.ignoring(currentOperationServerService);
- expectations.ignoring(currentResourceFactoryServerService);
-
- //just ignore these invocations if we get a availability scan in the PC...
- expectations.allowing(currentDiscoveryServerService).mergeAvailabilityReport(expectations.with(Expectations.any(AvailabilityReport.class)));
-
- expectations.allowing(currentDiscoveryServerService).getResources(expectations.with(Expectations.any(Set.class)), expectations.with(Expectations.any(boolean.class)));
- expectations.will(currentServerSideInventory.getResources());
- }
-
- private void cleanDataDir() throws IOException {
- FileUtils.cleanDirectory(new File(tmpDir, DATA_DIR_NAME));
- }
}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
new file mode 100644
index 0000000..f03f2a4
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
@@ -0,0 +1,350 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.core.pc.upgrade;
+
+import static org.testng.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Set;
+
+import org.apache.commons.io.FileUtils;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.rhq.core.clientapi.server.bundle.BundleServerService;
+import org.rhq.core.clientapi.server.configuration.ConfigurationServerService;
+import org.rhq.core.clientapi.server.content.ContentServerService;
+import org.rhq.core.clientapi.server.core.CoreServerService;
+import org.rhq.core.clientapi.server.discovery.DiscoveryServerService;
+import org.rhq.core.clientapi.server.event.EventServerService;
+import org.rhq.core.clientapi.server.inventory.ResourceFactoryServerService;
+import org.rhq.core.clientapi.server.measurement.MeasurementServerService;
+import org.rhq.core.clientapi.server.operation.OperationServerService;
+import org.rhq.core.domain.discovery.AvailabilityReport;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.pc.PluginContainer;
+import org.rhq.core.pc.PluginContainerConfiguration;
+import org.rhq.core.pc.ServerServices;
+import org.rhq.core.pc.inventory.InventoryManager;
+import org.rhq.core.pc.plugin.FileSystemPluginFinder;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+
+/**
+ *
+ * @author Lukas Krejci
+ */
+public class ResourceUpgradeTestBase {
+
+ private static final String PLUGINS_DIR_NAME = "plugins";
+ private static final String DATA_DIR_NAME = "data";
+ private static final String TMP_DIR_NAME = "tmp";
+ private File tmpDir;
+ private File pluginDir;
+ private File dataDir;
+ private BundleServerService currentBundleServerService;
+ private ConfigurationServerService currentConfigurationServerService;
+ private ContentServerService currentContentServerService;
+ private CoreServerService currentCoreServerService;
+ private DiscoveryServerService currentDiscoveryServerService;
+ private EventServerService currentEventServerService;
+ private MeasurementServerService currentMeasurementServerService;
+ private OperationServerService currentOperationServerService;
+ private ResourceFactoryServerService currentResourceFactoryServerService;
+ private FakeServerInventory currentServerSideInventory;
+
+ @BeforeClass
+ public void init() {
+ tmpDir = getTmpDirectory();
+ pluginDir = new File(tmpDir, PLUGINS_DIR_NAME);
+ assertTrue(pluginDir.mkdir(), "Could not create plugin deploy directory.");
+ dataDir = new File(tmpDir, DATA_DIR_NAME);
+ assertTrue(dataDir.mkdir(), "Could not create plugin container data directory.");
+ }
+
+ @AfterClass
+ public void undeployPlugins() throws IOException {
+ FileUtils.deleteDirectory(tmpDir);
+ }
+
+ protected void setCurrentServerSideInventory(FakeServerInventory currentServerSideInventory) {
+ this.currentServerSideInventory = currentServerSideInventory;
+ }
+
+ protected FakeServerInventory getCurrentServerSideInventory() {
+ return currentServerSideInventory;
+ }
+
+ protected void setCurrentResourceFactoryServerService(ResourceFactoryServerService currentResourceFactoryServerService) {
+ this.currentResourceFactoryServerService = currentResourceFactoryServerService;
+ }
+
+ protected ResourceFactoryServerService getCurrentResourceFactoryServerService() {
+ return currentResourceFactoryServerService;
+ }
+
+ protected void setCurrentOperationServerService(OperationServerService currentOperationServerService) {
+ this.currentOperationServerService = currentOperationServerService;
+ }
+
+ protected OperationServerService getCurrentOperationServerService() {
+ return currentOperationServerService;
+ }
+
+ protected void setCurrentMeasurementServerService(MeasurementServerService currentMeasurementServerService) {
+ this.currentMeasurementServerService = currentMeasurementServerService;
+ }
+
+ protected MeasurementServerService getCurrentMeasurementServerService() {
+ return currentMeasurementServerService;
+ }
+
+ protected void setCurrentEventServerService(EventServerService currentEventServerService) {
+ this.currentEventServerService = currentEventServerService;
+ }
+
+ protected EventServerService getCurrentEventServerService() {
+ return currentEventServerService;
+ }
+
+ protected void setCurrentDiscoveryServerService(DiscoveryServerService currentDiscoveryServerService) {
+ this.currentDiscoveryServerService = currentDiscoveryServerService;
+ }
+
+ protected DiscoveryServerService getCurrentDiscoveryServerService() {
+ return currentDiscoveryServerService;
+ }
+
+ protected void setCurrentCoreServerService(CoreServerService currentCoreServerService) {
+ this.currentCoreServerService = currentCoreServerService;
+ }
+
+ protected CoreServerService getCurrentCoreServerService() {
+ return currentCoreServerService;
+ }
+
+ protected void setCurrentContentServerService(ContentServerService currentContentServerService) {
+ this.currentContentServerService = currentContentServerService;
+ }
+
+ protected ContentServerService getCurrentContentServerService() {
+ return currentContentServerService;
+ }
+
+ protected void setCurrentConfigurationServerService(ConfigurationServerService currentConfigurationServerService) {
+ this.currentConfigurationServerService = currentConfigurationServerService;
+ }
+
+ protected ConfigurationServerService getCurrentConfigurationServerService() {
+ return currentConfigurationServerService;
+ }
+
+ protected void setCurrentBundleServerService(BundleServerService currentBundleServerService) {
+ this.currentBundleServerService = currentBundleServerService;
+ }
+
+ protected BundleServerService getCurrentBundleServerService() {
+ return currentBundleServerService;
+ }
+
+ protected static File getTmpDirectory() {
+ File ret = new File(System.getProperty("java.io.tmpdir"), "resource-upgrade-test" + System.currentTimeMillis());
+
+ while (ret.exists() || !ret.mkdir()) {
+ ret = new File(System.getProperty("java.io.tmpdir"), "resource-upgrade-test" + System.currentTimeMillis());
+ }
+
+ return ret;
+ }
+
+ private PluginContainerConfiguration createPluginContainerConfiguration(Mockery context) throws Exception {
+ PluginContainerConfiguration conf = new PluginContainerConfiguration();
+
+ conf.setPluginDirectory(new File(tmpDir, PLUGINS_DIR_NAME));
+ conf.setDataDirectory(new File(tmpDir, DATA_DIR_NAME));
+ conf.setTemporaryDirectory(new File(tmpDir, TMP_DIR_NAME));
+ conf.setInsideAgent(true); //pc must think it's inside an agent so that it persists the inventory between restarts
+ conf.setPluginFinder(new FileSystemPluginFinder(conf.getPluginDirectory()));
+ conf.setCreateResourceClassloaders(false);
+
+ //we're not interested in any scans happening out of our control
+ conf.setAvailabilityScanInitialDelay(Long.MAX_VALUE);
+ conf.setConfigurationDiscoveryInitialDelay(Long.MAX_VALUE);
+ conf.setContentDiscoveryInitialDelay(Long.MAX_VALUE);
+ conf.setEventSenderInitialDelay(Long.MAX_VALUE);
+ conf.setMeasurementCollectionInitialDelay(Long.MAX_VALUE);
+ conf.setServerDiscoveryInitialDelay(Long.MAX_VALUE);
+ conf.setServiceDiscoveryInitialDelay(Long.MAX_VALUE);
+
+ setCurrentBundleServerService(context.mock(BundleServerService.class));
+ setCurrentConfigurationServerService(context.mock(ConfigurationServerService.class));
+ setCurrentContentServerService(context.mock(ContentServerService.class));
+ setCurrentCoreServerService(context.mock(CoreServerService.class));
+ setCurrentDiscoveryServerService(context.mock(DiscoveryServerService.class));
+ setCurrentEventServerService(context.mock(EventServerService.class));
+ setCurrentMeasurementServerService(context.mock(MeasurementServerService.class));
+ setCurrentOperationServerService(context.mock(OperationServerService.class));
+ setCurrentResourceFactoryServerService(context.mock(ResourceFactoryServerService.class));
+
+ ServerServices serverServices = new ServerServices();
+ serverServices.setBundleServerService(getCurrentBundleServerService());
+ serverServices.setConfigurationServerService(getCurrentConfigurationServerService());
+ serverServices.setContentServerService(getCurrentContentServerService());
+ serverServices.setCoreServerService(getCurrentCoreServerService());
+ serverServices.setDiscoveryServerService(getCurrentDiscoveryServerService());
+ serverServices.setEventServerService(getCurrentEventServerService());
+ serverServices.setMeasurementServerService(getCurrentMeasurementServerService());
+ serverServices.setOperationServerService(getCurrentOperationServerService());
+ serverServices.setResourceFactoryServerService(getCurrentResourceFactoryServerService());
+
+ conf.setServerServices(serverServices);
+
+ return conf;
+ }
+
+ /**
+ * @param pluginResourcePath
+ */
+ protected void verifyPluginExists(String pluginResourcePath) {
+ URL url = getClass().getResource(pluginResourcePath);
+
+ File pluginFile = FileUtils.toFile(url);
+
+ assertTrue(pluginFile.exists(), pluginFile.getAbsoluteFile() + " plugin jar could not be found.");
+ }
+
+ private void copyPlugin(String pluginResourcePath, File pluginDirectory) throws IOException {
+ URL pluginUrl = getClass().getResource(pluginResourcePath);
+
+ File pluginFile = new File(pluginResourcePath);
+ String pluginFileName = pluginFile.getName();
+
+ FileUtils.copyURLToFile(pluginUrl, new File(pluginDirectory, pluginFileName));
+ }
+
+ protected interface TestPayload {
+ Expectations getExpectations(Mockery context) throws Exception;
+ void test(Set<Resource> resourceUpgradeTestResources);
+ boolean isClearInventoryDat();
+ String getResourceTypeName();
+ String getResourceTypePluginName();
+ }
+
+ protected static abstract class AbstractTestPayload implements TestPayload {
+ private boolean clearInventoryDat;
+ private String resourceTypeName;
+ private String resourceTypePluginName;
+
+ public AbstractTestPayload(boolean clearInventoryDat, String resourceTypeName, String resourceTypePluginName) {
+ this.clearInventoryDat = clearInventoryDat;
+ this.resourceTypeName = resourceTypeName;
+ this.resourceTypePluginName = resourceTypePluginName;
+ }
+
+ public boolean isClearInventoryDat() {
+ return clearInventoryDat;
+ }
+
+ public String getResourceTypeName() {
+ return resourceTypeName;
+ }
+
+ public String getResourceTypePluginName() {
+ return resourceTypePluginName;
+ }
+ }
+
+ /**
+ *
+ */
+ public ResourceUpgradeTestBase() {
+ super();
+ }
+
+ private Set<Resource> getTestingResources(String resourceTypeName, String resourceTypePluginName) {
+ ResourceType resType = PluginContainer.getInstance().getPluginManager().getMetadataManager().getType(resourceTypeName, resourceTypePluginName);
+
+ return getCurrentServerSideInventory().findResourcesByType(resType);
+ }
+
+ protected void executeTestWithPlugins(Set<String> pluginResourcePaths, TestPayload test) throws Exception {
+ FileUtils.cleanDirectory(new File(tmpDir, PLUGINS_DIR_NAME));
+
+ for(String pluginResourcePath : pluginResourcePaths) {
+ copyPlugin(pluginResourcePath, pluginDir);
+ }
+
+ Mockery context = new Mockery();
+
+ PluginContainerConfiguration pcConfig = createPluginContainerConfiguration(context);
+
+ if (test.isClearInventoryDat()) {
+ File inventoryDat = new File(pcConfig.getDataDirectory(), "inventory.dat");
+ inventoryDat.delete();
+ }
+
+ context.checking(test.getExpectations(context));
+
+ PluginContainer.getInstance().setConfiguration(pcConfig);
+ PluginContainer.getInstance().initialize();
+
+ try {
+ //give the pc the time to finish resource upgrade
+ Thread.sleep(1000);
+
+ //execute full discovery
+ InventoryManager im = PluginContainer.getInstance().getInventoryManager();
+ im.executeServerScanImmediately();
+ im.executeServiceScanImmediately();
+
+ Set<Resource> resources = getTestingResources(test.getResourceTypeName(), test.getResourceTypePluginName());
+
+ test.test(resources);
+
+ context.assertIsSatisfied();
+ } finally {
+ PluginContainer.getInstance().shutdown();
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void defineDefaultExpectations(Expectations expectations) {
+ expectations.ignoring(getCurrentBundleServerService());
+ expectations.ignoring(getCurrentConfigurationServerService());
+ expectations.ignoring(getCurrentContentServerService());
+ expectations.ignoring(getCurrentCoreServerService());
+ expectations.ignoring(getCurrentEventServerService());
+ expectations.ignoring(getCurrentMeasurementServerService());
+ expectations.ignoring(getCurrentOperationServerService());
+ expectations.ignoring(getCurrentResourceFactoryServerService());
+
+ //just ignore these invocations if we get a availability scan in the PC...
+ expectations.allowing(getCurrentDiscoveryServerService()).mergeAvailabilityReport(expectations.with(Expectations.any(AvailabilityReport.class)));
+
+ expectations.allowing(getCurrentDiscoveryServerService()).getResources(expectations.with(Expectations.any(Set.class)), expectations.with(Expectations.any(boolean.class)));
+ expectations.will(getCurrentServerSideInventory().getResources());
+ }
+
+ protected void cleanDataDir() throws IOException {
+ FileUtils.cleanDirectory(new File(tmpDir, DATA_DIR_NAME));
+ }
+}
commit 1863f1ab0c4473e6a79c469c16b73b6810733325
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Sep 29 12:58:32 2010 +0200
Preparing the upgrade tests to accept more complicated scenarios.
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 1479345..0a2a660 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -77,6 +77,9 @@ public class ResourceUpgradeTest {
private static final String DATA_DIR_NAME = "data";
private static final String TMP_DIR_NAME = "tmp";
+ private static final String SINGLETON_RESOURCE_TYPE_NAME = "Resource";
+ private static final String SINGLETON_RESOURCE_TYPE_PLUGIN_NAME = "ResourceUpgradeTest";
+
private File tmpDir;
private File pluginDir;
private File dataDir;
@@ -119,8 +122,12 @@ public class ResourceUpgradeTest {
currentServerSideInventory = new FakeServerInventory();
initialSyncAndDiscovery(InventoryStatus.NEW);
- TestPayload testNoChange = new TestPayload() {
- public void test(Resource discoveredResource) {
+ TestPayload testNoChange = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
+ public void test(Set<Resource> discoveredResources) {
+ assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
+
+ Resource discoveredResource = discoveredResources.iterator().next();
+
assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
assertEquals(discoveredResource.getName(), "resource-name-v1");
assertEquals(discoveredResource.getDescription(), "resource-description-v1");
@@ -138,7 +145,7 @@ public class ResourceUpgradeTest {
}
};
- executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, testNoChange);
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), testNoChange);
}
@Test
@@ -160,8 +167,12 @@ public class ResourceUpgradeTest {
currentServerSideInventory.setFailing(true);
- TestPayload test = new TestPayload() {
- public void test(Resource discoveredResource) {
+ TestPayload test = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
+ public void test(Set<Resource> discoveredResources) {
+ assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
+
+ Resource discoveredResource = discoveredResources.iterator().next();
+
assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
assertEquals(discoveredResource.getName(), "resource-name-v1");
assertEquals(discoveredResource.getDescription(), "resource-description-v1");
@@ -182,7 +193,7 @@ public class ResourceUpgradeTest {
}
};
- executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, test);
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), test);
}
@Test
@@ -190,8 +201,12 @@ public class ResourceUpgradeTest {
currentServerSideInventory = new FakeServerInventory();
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
- TestPayload test = new TestPayload() {
- public void test(Resource discoveredResource) {
+ TestPayload test = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
+ public void test(Set<Resource> discoveredResources) {
+ assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
+
+ Resource discoveredResource = discoveredResources.iterator().next();
+
assertEquals(discoveredResource.getResourceKey(), "resource-key-v2");
assertEquals(discoveredResource.getName(), "resource-name-v2");
assertEquals(discoveredResource.getDescription(), "resource-description-v2");
@@ -226,7 +241,7 @@ public class ResourceUpgradeTest {
}
};
- executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, test);
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), test);
}
@Test
@@ -234,12 +249,16 @@ public class ResourceUpgradeTest {
currentServerSideInventory = new FakeServerInventory();
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
- TestPayload test = new TestPayload() {
- public void test(Resource resourceUpgradeTestResource) {
- assertTrue(resourceUpgradeTestResource.getResourceErrors().size() > 0, "There should be upgrade errors persisted on the server side.");
+ TestPayload test = new AbstractTestPayload(false, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
+ public void test(Set<Resource> resourceUpgradeTestResources) {
+ assertEquals(resourceUpgradeTestResources.size(), 1, "Expected single test resource but multiple found.");
+
+ Resource discoveredResource = resourceUpgradeTestResources.iterator().next();
+
+ assertTrue(discoveredResource.getResourceErrors().size() > 0, "There should be upgrade errors persisted on the server side.");
//the discovery of the failed resource mustn't have run
- ResourceContainer container = PluginContainer.getInstance().getInventoryManager().getResourceContainer(resourceUpgradeTestResource);
+ ResourceContainer container = PluginContainer.getInstance().getInventoryManager().getResourceContainer(discoveredResource);
File dataDir = container.getResourceContext().getDataDirectory();
File marker = new File(dataDir, "failing-discovery-ran");
@@ -263,13 +282,17 @@ public class ResourceUpgradeTest {
}
};
- executeTestWithPlugins(Collections.singleton(FAILING_PLUGIN_FILE_NAME), false, test);
+ executeTestWithPlugins(Collections.singleton(FAILING_PLUGIN_FILE_NAME), test);
}
private void initialSyncAndDiscovery(final InventoryStatus requiredInventoryStatus) throws Exception {
cleanDataDir();
- executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), true, new TestPayload() {
- public void test(Resource discoveredResource) {
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), new AbstractTestPayload(true, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
+ public void test(Set<Resource> discoveredResources) {
+ assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
+
+ Resource discoveredResource = discoveredResources.iterator().next();
+
assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
assertEquals(discoveredResource.getName(), "resource-name-v1");
assertEquals(discoveredResource.getDescription(), "resource-description-v1");
@@ -292,8 +315,12 @@ public class ResourceUpgradeTest {
private void upgradeTest(boolean clearInventoryDat) throws Exception {
initialSyncAndDiscovery(InventoryStatus.COMMITTED);
- executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), clearInventoryDat, new TestPayload() {
- public void test(Resource discoveredResource) {
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), new AbstractTestPayload(clearInventoryDat, SINGLETON_RESOURCE_TYPE_NAME, SINGLETON_RESOURCE_TYPE_PLUGIN_NAME) {
+ public void test(Set<Resource> discoveredResources) {
+ assertEquals(discoveredResources.size(), 1, "Expected single test resource but multiple found.");
+
+ Resource discoveredResource = discoveredResources.iterator().next();
+
assertEquals(discoveredResource.getResourceKey(), "resource-key-v2");
assertEquals(discoveredResource.getName(), "resource-name-v2");
assertEquals(discoveredResource.getDescription(), "resource-description-v2");
@@ -400,16 +427,43 @@ public class ResourceUpgradeTest {
private interface TestPayload {
Expectations getExpectations(Mockery context) throws Exception;
- void test(Resource resourceUpgradeTestResource);
+ void test(Set<Resource> resourceUpgradeTestResources);
+ boolean isClearInventoryDat();
+ String getResourceTypeName();
+ String getResourceTypePluginName();
}
- private Set<Resource> getTestingResources() {
- ResourceType resType = PluginContainer.getInstance().getPluginManager().getMetadataManager().getType("Resource", "ResourceUpgradeTest");
+ private static abstract class AbstractTestPayload implements TestPayload {
+ private boolean clearInventoryDat;
+ private String resourceTypeName;
+ private String resourceTypePluginName;
+
+ public AbstractTestPayload(boolean clearInventoryDat, String resourceTypeName, String resourceTypePluginName) {
+ this.clearInventoryDat = clearInventoryDat;
+ this.resourceTypeName = resourceTypeName;
+ this.resourceTypePluginName = resourceTypePluginName;
+ }
+
+ public boolean isClearInventoryDat() {
+ return clearInventoryDat;
+ }
+
+ public String getResourceTypeName() {
+ return resourceTypeName;
+ }
+
+ public String getResourceTypePluginName() {
+ return resourceTypePluginName;
+ }
+ }
+
+ private Set<Resource> getTestingResources(String resourceTypeName, String resourceTypePluginName) {
+ ResourceType resType = PluginContainer.getInstance().getPluginManager().getMetadataManager().getType(resourceTypeName, resourceTypePluginName);
return currentServerSideInventory.findResourcesByType(resType);
}
- private void executeTestWithPlugins(Set<String> pluginResourcePaths, boolean clearInventoryDat, TestPayload test) throws Exception {
+ private void executeTestWithPlugins(Set<String> pluginResourcePaths, TestPayload test) throws Exception {
FileUtils.cleanDirectory(new File(tmpDir, PLUGINS_DIR_NAME));
for(String pluginResourcePath : pluginResourcePaths) {
@@ -420,7 +474,7 @@ public class ResourceUpgradeTest {
PluginContainerConfiguration pcConfig = createPluginContainerConfiguration(context);
- if (clearInventoryDat) {
+ if (test.isClearInventoryDat()) {
File inventoryDat = new File(pcConfig.getDataDirectory(), "inventory.dat");
inventoryDat.delete();
}
@@ -439,14 +493,9 @@ public class ResourceUpgradeTest {
im.executeServerScanImmediately();
im.executeServiceScanImmediately();
- Set<Resource> resources = getTestingResources();
-
- assertEquals(resources.size(), 1, "There should be only a single testing resource but " + resources
- + " were found.");
-
- Resource discoveredResource = resources.iterator().next();
+ Set<Resource> resources = getTestingResources(test.getResourceTypeName(), test.getResourceTypePluginName());
- test.test(discoveredResource);
+ test.test(resources);
context.assertIsSatisfied();
} finally {
commit 659920513807b095cdd0ac91c3f1c2e091d090a7
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Sep 29 12:57:21 2010 +0200
Setting the height of the errorsGrid to a fixed value so that it stays at the bottom of the page.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
index 95bec5f..b439d44 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
@@ -23,11 +23,7 @@ import org.rhq.core.domain.resource.composite.ResourceComposite;
import org.rhq.enterprise.gui.coregui.client.components.table.Table;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
-import com.smartgwt.client.data.DSCallback;
-import com.smartgwt.client.data.DSRequest;
-import com.smartgwt.client.data.DSResponse;
import com.smartgwt.client.types.Alignment;
-import com.smartgwt.client.types.GroupStartOpen;
import com.smartgwt.client.widgets.HTMLPane;
import com.smartgwt.client.widgets.IButton;
import com.smartgwt.client.widgets.Window;
@@ -44,13 +40,11 @@ import com.smartgwt.client.widgets.grid.events.CellClickHandler;
*/
public class OverviewView extends LocatableVLayout {
- private ResourceComposite resourceComposite;
private OverviewForm form;
private Table errorsGrid;
public OverviewView(String locatorId, ResourceComposite resourceComposite) {
super(locatorId);
- this.resourceComposite = resourceComposite;
form = new OverviewForm(extendLocatorId("form"), resourceComposite);
errorsGrid = new Table(extendLocatorId("errors"), "Detected errors", null, null, new String[] { ResourceErrorsDataSource.DETAIL_ID });
@@ -61,7 +55,7 @@ public class OverviewView extends LocatableVLayout {
errorsGrid.setDataSource(errors);
form.setHeight("*");
- errorsGrid.setHeight("10%");
+ errorsGrid.setHeight(200); //this should be just enough to fit the maximum of 3 rows in this table (there's at most 1 error per type)
addMember(form);
addMember(errorsGrid);
commit c704c79f4acfedf4d959de6d7d27db1b22efa1f3
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Sep 29 12:44:55 2010 +0200
Adding a bunch of test plugins for dependency resolution during resource upgrade failure handling.
diff --git a/modules/core/plugin-container/pom.xml b/modules/core/plugin-container/pom.xml
index 4b09ef8..035bf36 100644
--- a/modules/core/plugin-container/pom.xml
+++ b/modules/core/plugin-container/pom.xml
@@ -195,6 +195,106 @@
<fileset dir="${project.build.testOutputDirectory}/tmp/failing" includes="**/*.class,**/rhq-plugin.xml" />
</jar>
+ <copy toDir="${project.build.testOutputDirectory}/tmp/multi/base/META-INF">
+ <fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/base/rhq-plugin.xml" />
+ </copy>
+ <copy toDir="${project.build.testOutputDirectory}/tmp/multi/base/org/rhq/core/pc/upgrade/plugins/multi/base">
+ <fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/base/*.class" />
+ </copy>
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-base-1.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/tmp/multi/base" includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
+ <copy toDir="${project.build.testOutputDirectory}/tmp/multi/parentdep1/META-INF">
+ <fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/rhq-plugin.xml" />
+ </copy>
+ <!-- <copy toDir="${project.build.testOutputDirectory}/tmp/multi/parentdep1/org/rhq/core/pc/upgrade/plugins/multi/parentdep1">
+ <fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/*.class" />
+ </copy> -->
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-parentdep-1.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/tmp/multi/parentdep1" includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
+ <copy toDir="${project.build.testOutputDirectory}/tmp/multi/parentdep2/META-INF">
+ <fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/rhq-plugin.xml" />
+ </copy>
+ <!-- <copy toDir="${project.build.testOutputDirectory}/tmp/multi/parentdep2/org/rhq/core/pc/upgrade/plugins/multi/parentdep2">
+ <fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/*.class" />
+ </copy> -->
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-parentdep-2.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/tmp/multi/parentdep2" includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
+ <copy toDir="${project.build.testOutputDirectory}/tmp/multi/parentsibling1/META-INF">
+ <fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml" />
+ </copy>
+ <!-- <copy toDir="${project.build.testOutputDirectory}/tmp/multi/parentsibling1/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1">
+ <fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/*.class" />
+ </copy> -->
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-parentsibling-1.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/tmp/multi/parentsibling1" includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
+ <copy toDir="${project.build.testOutputDirectory}/tmp/multi/parentsibling2/META-INF">
+ <fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml" />
+ </copy>
+ <!-- <copy toDir="${project.build.testOutputDirectory}/tmp/multi/parentsibling2/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2">
+ <fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/*.class" />
+ </copy> -->
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-parentsibling-2.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/tmp/multi/parentsibling2" includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
+ <copy toDir="${project.build.testOutputDirectory}/tmp/multi/root/META-INF">
+ <fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/root/rhq-plugin.xml" />
+ </copy>
+ <!-- <copy toDir="${project.build.testOutputDirectory}/tmp/multi/root/org/rhq/core/pc/upgrade/plugins/multi/root">
+ <fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/root/*.class" />
+ </copy> -->
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-root-1.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/tmp/multi/root" includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
+ <copy toDir="${project.build.testOutputDirectory}/tmp/multi/sibling1/META-INF">
+ <fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml" />
+ </copy>
+ <!-- <copy toDir="${project.build.testOutputDirectory}/tmp/multi/sibling1/org/rhq/core/pc/upgrade/plugins/multi/sibling1">
+ <fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/sibling1/*.class" />
+ </copy> -->
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-sibling-1.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/tmp/multi/sibling1" includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
+ <copy toDir="${project.build.testOutputDirectory}/tmp/multi/sibling2/META-INF">
+ <fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml" />
+ </copy>
+ <!-- <copy toDir="${project.build.testOutputDirectory}/tmp/multi/sibling2/org/rhq/core/pc/upgrade/plugins/multi/sibling2">
+ <fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/sibling2/*.class" />
+ </copy> -->
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-sibling-2.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/tmp/multi/sibling2" includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
+ <copy toDir="${project.build.testOutputDirectory}/tmp/multi/v1/META-INF">
+ <fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml" />
+ </copy>
+ <!-- <copy toDir="${project.build.testOutputDirectory}/tmp/multi/v1/org/rhq/core/pc/upgrade/plugins/multi/v1">
+ <fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/v1/*.class" />
+ </copy> -->
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-1.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/tmp/multi/v1" includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
+ <copy toDir="${project.build.testOutputDirectory}/tmp/multi/v2/META-INF">
+ <fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml" />
+ </copy>
+ <!-- <copy toDir="${project.build.testOutputDirectory}/tmp/multi/v2/org/rhq/core/pc/upgrade/plugins/multi/v2">
+ <fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/multi/v2/*.class" />
+ </copy> -->
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-multi-2.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/tmp/multi/v2" includes="**/*.class,**/rhq-plugin.xml" />
+ </jar>
+
<delete dir="${project.build.testOutputDirectory}/tmp"/>
</tasks>
</configuration>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseDiscoveryComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseDiscoveryComponent.java
new file mode 100644
index 0000000..61d4fe0
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseDiscoveryComponent.java
@@ -0,0 +1,70 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.core.pc.upgrade.plugins.multi.base;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+
+/**
+ *
+ * @author Lukas Krejci
+ */
+public class BaseDiscoveryComponent<T extends ResourceComponent> implements ResourceDiscoveryComponent<T> {
+
+ public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext<T> context)
+ throws InvalidPluginConfigurationException, Exception {
+
+ HashSet<DiscoveredResourceDetails> results = new HashSet<DiscoveredResourceDetails>();
+
+ Configuration pluginConfig = context.getDefaultPluginConfiguration();
+
+ String keyTemplate = pluginConfig.getSimpleValue("key", null);
+ int count = pluginConfig.getSimple("count").getIntegerValue();
+
+ int parentN = context.getParentResourceContext().getPluginConfiguration().getSimple("ordinal")
+ .getIntegerValue();
+
+ for (int i = 0; i < count; ++i) {
+
+ String key = getResourceKey(keyTemplate, i, parentN);
+
+ pluginConfig.put(new PropertySimple("ordinal", i));
+
+ DiscoveredResourceDetails detail = new DiscoveredResourceDetails(context.getResourceType(), key, key, null,
+ null, pluginConfig, null);
+
+ results.add(detail);
+ }
+
+ return results;
+ }
+
+ protected static String getResourceKey(String template, int n, int parentN) {
+ return template.replace("%n", Integer.toString(n)).replace("%p", Integer.toString(parentN));
+ }
+}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponent.java
new file mode 100644
index 0000000..c5bbf3a
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseResourceComponent.java
@@ -0,0 +1,67 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.core.pc.upgrade.plugins.multi.base;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
+
+/**
+ *
+ * @author Lukas Krejci
+ */
+public class BaseResourceComponent<T extends ResourceComponent> implements ResourceComponent<T> {
+
+ private ResourceContext<T> context;
+ private final Log log = LogFactory.getLog(getClass());
+
+ private Set<Integer> childrenToFailUpgrade;
+
+ public AvailabilityType getAvailability() {
+ return AvailabilityType.UP;
+ }
+
+ public void start(ResourceContext<T> context) throws InvalidPluginConfigurationException, Exception {
+ log.info("Starting multi resource child component with resource key '" + context.getResourceKey() + "'.");
+ this.context = context;
+ }
+
+ public void stop() {
+ log.info("Stopping multi resource child component with resource key '" + context.getResourceKey() + "'.");
+ }
+
+ public int getOrdinal() {
+ return context.getPluginConfiguration().getSimple("ordinal").getIntegerValue();
+ }
+
+ public Set<Integer> getChildrenToFailUpgrade() {
+ return childrenToFailUpgrade == null ? Collections.<Integer>emptySet() : childrenToFailUpgrade;
+ }
+
+ public void setChildrenToFailUpgrade(Set<Integer> childrenToFailUpgrade) {
+ this.childrenToFailUpgrade = childrenToFailUpgrade;
+ }
+}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java
new file mode 100644
index 0000000..beb36db
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/BaseUpgradingDiscoveryComponent.java
@@ -0,0 +1,61 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.core.pc.upgrade.plugins.multi.base;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
+
+/**
+ *
+ * @author Lukas Krejci
+ */
+public class BaseUpgradingDiscoveryComponent<T extends BaseResourceComponent> extends BaseDiscoveryComponent<T> implements ResourceUpgradeFacet<T> {
+
+ public ResourceUpgradeReport upgrade(ResourceUpgradeContext<T> inventoriedResource) {
+ Configuration pluginConfig = inventoriedResource.getPluginConfiguration();
+
+ BaseResourceComponent<?> parent = inventoriedResource.getParentResourceComponent();
+ int ordinal = pluginConfig.getSimple("ordinal").getIntegerValue();
+ int parentOrdinal = parent == null ? 0 : parent.getOrdinal();
+
+ boolean fail = Boolean.getBoolean(pluginConfig.getSimpleValue("failUpgrade", "false"));
+
+ if (!fail && parent != null) {
+ fail = parent.getChildrenToFailUpgrade().contains(Integer.valueOf(ordinal));
+ }
+
+ if (fail) {
+ throw new RuntimeException("Failing the resource upgrade purposefully.");
+ }
+
+ String newKey = pluginConfig.getSimpleValue("upgradedKey", null);
+
+ if (newKey == null) {
+ return null;
+ }
+
+ ResourceUpgradeReport report = new ResourceUpgradeReport();
+
+ report.setNewResourceKey(getResourceKey(newKey, ordinal, parentOrdinal));
+ return null;
+ }
+}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/rhq-plugin.xml
new file mode 100644
index 0000000..7edfba1
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/base/rhq-plugin.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plugin name="ResourceUpgradeMultiTestBase"
+ displayName=""
+ description=""
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <!--
+ Only the inheriting plugins create the concrete resources based on the
+ classes defined in this abstract base plugin.
+
+ These are the plugin configuration properties needed by the base plugin:
+
+ key = the template to create the resource key from
+ count = the number of resources to discover
+ upgradedKey = this *must* be specified on the resource type *to be upgraded* and
+ *must* be the same as the key template on the resource type that
+ it is upgraded to (i.e. the plugin.v1.upgradedKey == plugin.v2.key)
+
+ the discovery add a new property called "ordinal" to the plugin config
+ of the created resources, which contains the index of that resource amongst
+ its siblings.
+
+ the key template can contain %n which is replaced by the ordinal and %p which
+ is replaced by the ordinal of its parent.
+
+
+
+ if the discovery component of the concrete resource is (or inherits from)
+ BaseUpgradingDiscoveryComponent, it can specify further plugin config properties
+ influencing the upgrade:
+
+ failUpgrade = true to throw an exception during upgrade
+ -->
+
+</plugin>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/rhq-plugin.xml
new file mode 100644
index 0000000..3612974
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep1/rhq-plugin.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeMultiTestParentDep"
+ displayName="Resource Upgrade Multi Test"
+ description="Resource Upgrade Multi Test"
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
+ <depends plugin="ResourceUpgradeMultiTestRoot"/>
+
+ <server name="ParentDependency"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+
+ <runs-inside>
+ <parent-resource-type name="Root" plugin="ResourceUpgradeMultiTestRoot"/>
+ </runs-inside>
+
+ <plugin-configuration>
+ <c:simple-property name="count" default="1" />
+ <c:simple-property name="key" default="test-resource-parent-dep-%n,parent-%p" />
+ <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-parent-dep-%n,parent-%p" />
+ </plugin-configuration>
+
+ </server>
+
+</plugin>
+
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/rhq-plugin.xml
new file mode 100644
index 0000000..6b95114
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentdep2/rhq-plugin.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeMultiTestParentDep"
+ displayName="Resource Upgrade Multi Test"
+ description="Resource Upgrade Multi Test"
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="2.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
+ <depends plugin="ResourceUpgradeMultiTestRoot"/>
+
+ <server name="ParentDependency"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+
+ <runs-inside>
+ <parent-resource-type name="Root" plugin="ResourceUpgradeMultiTestRoot"/>
+ </runs-inside>
+
+ <plugin-configuration>
+ <c:simple-property name="count" default="1" />
+ <c:simple-property name="key" default="UPGRADED-test-resource-parent-dep-%n,parent-%p" />
+ </plugin-configuration>
+
+ </server>
+
+</plugin>
+
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml
new file mode 100644
index 0000000..fbade54
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling1/rhq-plugin.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeMultiTestParentSibling"
+ displayName="Resource Upgrade Multi Test"
+ description="Resource Upgrade Multi Test"
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
+ <depends plugin="ResourceUpgradeMultiTestRoot"/>
+
+ <server name="ParentDepSibling"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+
+ <runs-inside>
+ <parent-resource-type name="Root" plugin="ResourceUpgradeMultiTestRoot"/>
+ </runs-inside>
+
+ <plugin-configuration>
+ <c:simple-property name="count" default="1" />
+ <c:simple-property name="key" default="test-resource-parent-sibling-%n,parent-%p" />
+ <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-parent-sibling-%n,parent-%p" />
+ </plugin-configuration>
+
+ </server>
+
+</plugin>
+
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml
new file mode 100644
index 0000000..f16d526
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/parentsibling2/rhq-plugin.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeMultiTestParentSibling"
+ displayName="Resource Upgrade Multi Test"
+ description="Resource Upgrade Multi Test"
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="2.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
+ <depends plugin="ResourceUpgradeMultiTestRoot"/>
+
+ <server name="ParentDepSibling"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+
+ <runs-inside>
+ <parent-resource-type name="Root" plugin="ResourceUpgradeMultiTestRoot"/>
+ </runs-inside>
+
+ <plugin-configuration>
+ <c:simple-property name="count" default="1" />
+ <c:simple-property name="key" default="UPGRADED-test-resource-parent-sibling-%n,parent-%p" />
+ </plugin-configuration>
+
+ </server>
+
+</plugin>
+
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/root/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/root/rhq-plugin.xml
new file mode 100644
index 0000000..b5efbb1
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/root/rhq-plugin.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeMultiTestRoot"
+ displayName=""
+ description=""
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <server name="Root"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+
+ <plugin-configuration>
+ <c:simple-property name="count" default="1" />
+ <c:simple-property name="key" default="test-resource-root-%n" />
+ </plugin-configuration>
+ </server>
+
+</plugin>
+
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
new file mode 100644
index 0000000..f87ef4d
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling1/rhq-plugin.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeMultiTestSibling"
+ displayName="Resource Upgrade Multi Test"
+ description="Resource Upgrade Multi Test"
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
+ <depends plugin="ResourceUpgradeMultiTestParentDep"/>
+
+ <server name="TestResourceParentSibling"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+
+ <plugin-configuration>
+ <c:simple-property name="count" default="2" />
+ <c:simple-property name="key" default="test-resource-parent-sibling-%n,parent-%p" />
+ <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-parent-sibling-%n,parent-%p" />
+ </plugin-configuration>
+
+ <service name="TestResourceSibling"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+ <plugin-configuration>
+ <c:simple-property name="count" default="10" />
+ <c:simple-property name="key" default="test-resource-sibling-%n,parent-%p" />
+ <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-sibling-%n,parent-%p" />
+ </plugin-configuration>
+
+ </service>
+ </server>
+
+</plugin>
+
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
new file mode 100644
index 0000000..e6ab95f
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/sibling2/rhq-plugin.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plugin name="ResourceUpgradeMultiTestSibling"
+ displayName="Resource Upgrade Multi Test"
+ description="Resource Upgrade Multi Test"
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="2.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
+ <depends plugin="ResourceUpgradeMultiTestParentDep"/>
+
+ <server name="TestResourceParentSibling"
+ discovery="BaseUpgradingDiscoveryComponent"
+ class="BaseResourceComponent">
+
+ <runs-inside>
+ <parent-resource-type name="ParentDependency" plugin="ResourceUpgradeMultiTestParentDep"/>
+ </runs-inside>
+
+ <plugin-configuration>
+ <c:simple-property name="count" default="2" />
+ <c:simple-property name="key" default="UPGRADED-test-resource-parent-sibling-%n,parent-%p" />
+ </plugin-configuration>
+
+ <service name="TestResourceSibling"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+ <plugin-configuration>
+ <c:simple-property name="count" default="15" />
+ <c:simple-property name="key" default="UPGRADED-test-resource-sibling-%n,parent-%p" />
+ </plugin-configuration>
+
+ </service>
+
+
+ </server>
+
+</plugin>
+
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml
new file mode 100644
index 0000000..32ad438
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v1/rhq-plugin.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeMultiTest"
+ displayName="Resource Upgrade Multi Test"
+ description="Resource Upgrade Multi Test"
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
+ <depends plugin="ResourceUpgradeMultiTestParentDep"/>
+
+ <server name="TestResourceParent"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+
+ <runs-inside>
+ <parent-resource-type name="ParentDependency" plugin="ResourceUpgradeMultiTestParentDep"/>
+ </runs-inside>
+
+ <plugin-configuration>
+ <c:simple-property name="count" default="2" />
+ <c:simple-property name="key" default="test-resource-parent-%n,parent-%p" />
+ <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-parent-%n,parent-%p" />
+ </plugin-configuration>
+
+ <service name="TestResource"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+ <plugin-configuration>
+ <c:simple-property name="count" default="10" />
+ <c:simple-property name="key" default="test-resource-%n,parent-%p" />
+ <c:simple-property name="upgradedKey" default="UPGRADED-test-resource-%n,parent-%p" />
+ </plugin-configuration>
+
+ </service>
+ </server>
+
+</plugin>
+
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
new file mode 100644
index 0000000..824d3fe
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/multi/v2/rhq-plugin.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plugin name="ResourceUpgradeMultiTest"
+ displayName="Resource Upgrade Multi Test"
+ description="Resource Upgrade Multi Test"
+ package="org.rhq.core.pc.upgrade.plugins.multi.base"
+ version="2.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <depends plugin="ResourceUpgradeMultiTestBase" useClasses="true"/>
+ <depends plugin="ResourceUpgradeMultiTestParentDep"/>
+
+ <server name="TestResourceParent"
+ discovery="BaseUpgradingDiscoveryComponent"
+ class="BaseResourceComponent">
+
+ <runs-inside>
+ <parent-resource-type name="ParentDependency" plugin="ResourceUpgradeMultiTestParentDep"/>
+ </runs-inside>
+
+ <plugin-configuration>
+ <c:simple-property name="count" default="2" />
+ <c:simple-property name="key" default="UPGRADED-test-resource-parent-%n,parent-%p" />
+ </plugin-configuration>
+
+ <service name="TestResource"
+ discovery="BaseDiscoveryComponent"
+ class="BaseResourceComponent">
+ <plugin-configuration>
+ <c:simple-property name="count" default="15" />
+ <c:simple-property name="key" default="UPGRADED-test-resource-%n,parent-%p" />
+ </plugin-configuration>
+
+ </service>
+
+
+ </server>
+
+</plugin>
+
commit c2f5b5363d1023106bc7e12a78999603c4c5f26e
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Sep 28 10:39:33 2010 +0200
remove the commented-out portions of the resource upgrade code.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 1b0ed8e..de52cd8 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -1232,10 +1232,7 @@ public class InventoryManager extends AgentService implements ContainerService,
for (ResourceUpgradeResponse upgradeResponse : serverUpdates) {
String resourceKey = upgradeResponse.getUpgradedResourceKey();
String name = upgradeResponse.getUpgradedResourceName();
- //String version = upgradeReport.getNewVersion();
String description = upgradeResponse.getUpgradedResourceDescription();
- //Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
- //Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
//only bother if there's something to upgrade at all on this resource.
if (resourceKey != null || name != null || description != null) {
@@ -1256,23 +1253,11 @@ public class InventoryManager extends AgentService implements ContainerService,
logMessage.append("name, ");
}
- //if (version != null) {
- // existingResource.setVersion(version);
- //}
-
if (description != null) {
existingResource.setDescription(description);
logMessage.append("description, ");
}
- //if (pluginConfiguration != null) {
- // existingResource.setPluginConfiguration(pluginConfiguration);
- //}
- //
- //if (resourceConfiguration != null) {
- // existingResource.setResourceConfiguration(resourceConfiguration);
- //}
-
logMessage.replace(logMessage.length() - 1, logMessage.length(), "to become [").append(
existingResource.toString()).append("]");
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index 51287b7..e4cbf03 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -495,10 +495,7 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
String resourceKey = upgradeRequest.getNewResourceKey();
String name = upgradeRequest.getNewName();
-// String version = upgradeReport.getNewVersion();
String description = upgradeRequest.getNewDescription();
-// Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
-// Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
if (resourceKey != null || name != null || description != null) {
StringBuilder logMessage = new StringBuilder("Resource [")
@@ -516,38 +513,12 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
}
ret.setUpgradedResourceName(resource.getName());
-// if (version != null) {
-// changed = updateResourceVersion(resource, version) || changed;
-// }
-
if (allowGenericPropertiesUpgrade && needsUpgrade(resource.getDescription(), description)) {
resource.setDescription(description);
logMessage.append("description, ");
}
ret.setUpgradedResourceDescription(resource.getDescription());
-
-// if (pluginConfiguration != null) {
-// if (!equalOrNull(pluginConfiguration, resource.getPluginConfiguration())) {
-// log.info("Resource [" + resource + "] upgraded its plugin configuration from [" +
-// resource.getPluginConfiguration() + "] to [" + pluginConfiguration + "]");
-// changed = true;
-// resource.setPluginConfiguration(pluginConfiguration);
-// }
-// }
-//
-// if (resourceConfiguration != null) {
-// if (!equalOrNull(resourceConfiguration, resource.getResourceConfiguration())) {
-// //XXX Will this create a new history entry?
-//
-// log.info("Resource [" + resource + "] upgraded its resource configuration from [" +
-// resource.getResourceConfiguration() + "] to [" + resourceConfiguration + "]");
-//
-// changed = true;
-// resource.setResourceConfiguration(resourceConfiguration);
-// }
-// }
-
-
+
//finally let's remove the potential previous upgrade error. we've now successfully
//upgraded the resource.
List<ResourceError> upgradeErrors = resourceManager.findResourceErrors(subjectManager.getOverlord(), resource.getId(), ResourceErrorType.UPGRADE);
commit 0ae5aa90c40d239e294857a961596ee500643dee
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Sep 28 10:36:32 2010 +0200
Clear the upgrade errors if the upgrade for given resource succeeds.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index a480fb7..51287b7 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -481,7 +481,7 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
* @param existingResource
* @param upgradeRequest
* @param allowGenericPropertiesUpgrade name and description are only upgraded if this is true
- * @return true if the resource was changed, false otherwise
+ * @return response to the upgrade request detailing what has been accepted on the server side
*/
private ResourceUpgradeResponse upgradeResource(@NotNull Resource resource, ResourceUpgradeRequest upgradeRequest, boolean allowGenericPropertiesUpgrade) {
if (upgradeRequest.getUpgradeErrorMessage() != null) {
@@ -547,6 +547,14 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
// }
// }
+
+ //finally let's remove the potential previous upgrade error. we've now successfully
+ //upgraded the resource.
+ List<ResourceError> upgradeErrors = resourceManager.findResourceErrors(subjectManager.getOverlord(), resource.getId(), ResourceErrorType.UPGRADE);
+ for(ResourceError error : upgradeErrors) {
+ entityManager.remove(error);
+ }
+
logMessage.replace(logMessage.length() - 1, logMessage.length(),
"to become [").append(resource.toString()).append("]");
commit c1b1f4dfdcf05c39879133c9fb562f8ecada6690
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Sep 24 14:32:23 2010 +0200
Handling the resource upgrade failure by disabling discovery of its siblings of the same type.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 563a786..1b0ed8e 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -192,7 +192,7 @@ public class InventoryManager extends AgentService implements ContainerService,
/**
* Handles the resource upgrade during the initialization of the inventory manager.
*/
- private ResourceUpgradeDelegate resourceUpgradeDelegate;
+ private ResourceUpgradeDelegate resourceUpgradeDelegate = new ResourceUpgradeDelegate(this);
public InventoryManager() {
super(DiscoveryAgentService.class);
@@ -222,7 +222,6 @@ public class InventoryManager extends AgentService implements ContainerService,
//try the resource upgrade before we have any schedulers set up
//so that we don't get any interventions from concurrently running
//discoveries.
- resourceUpgradeDelegate = new ResourceUpgradeDelegate(this);
upgradeResources();
availabilityCollectors = new AvailabilityCollectorThreadPool();
@@ -282,15 +281,24 @@ public class InventoryManager extends AgentService implements ContainerService,
* an empty set if nothing is discovered. This may return <code>null</code> if for some reason
* we could not invoke the discovery component.
*
+ * @param parentResourceContainer the container of the resource under which we are going to execute the discovery
* @param component the discovery component that will actually go out and discover resources
* @param context the context for use by the discovery component
* @return the details of all discovered resources, may be empty or <code>null</code>
*
* @throws Exception if the discovery component threw an exception
*/
- public Set<DiscoveredResourceDetails> invokeDiscoveryComponent(ResourceDiscoveryComponent component,
+ public Set<DiscoveredResourceDetails> invokeDiscoveryComponent(ResourceContainer parentResourceContainer, ResourceDiscoveryComponent component,
ResourceDiscoveryContext context) throws Exception {
+ Resource parentResource = parentResourceContainer == null ? null : parentResourceContainer.getResource();
+
+ if (resourceUpgradeDelegate.hasUpgradeFailedInChildren(parentResource, context.getResourceType())) {
+ log.debug("Discovery of [" + context.getResourceType() + "] has been disallowed under " + (parentResource == null ? " the platform " : parentResource) +
+ " because some of its siblings failed to upgrade.");
+ return null;
+ }
+
long timeout = getDiscoveryComponentTimeout(context.getResourceType());
try {
@@ -687,7 +695,7 @@ public class InventoryManager extends AgentService implements ContainerService,
// Ask the plugin's discovery component to find the new resource, throwing exceptions if it cannot be
// found at all.
- Set<DiscoveredResourceDetails> discoveredResources = invokeDiscoveryComponent(discoveryComponent,
+ Set<DiscoveredResourceDetails> discoveredResources = invokeDiscoveryComponent(parentResourceContainer, discoveryComponent,
discoveryContext);
if ((discoveredResources == null) || discoveredResources.isEmpty()) {
log.info("Plugin Error: During manual add, discovery component method ["
@@ -1207,7 +1215,7 @@ public class InventoryManager extends AgentService implements ContainerService,
return resourceContainer.updateAvailability(availabilityType);
}
- public void mergeResourceFromUpgrade(Set<ResourceUpgradeRequest> upgradeRequests) {
+ public void mergeResourcesFromUpgrade(Set<ResourceUpgradeRequest> upgradeRequests) {
Set<ResourceUpgradeResponse> serverUpdates = null;
try {
ServerServices serverServices = this.configuration.getServerServices();
@@ -1430,6 +1438,13 @@ public class InventoryManager extends AgentService implements ContainerService,
@SuppressWarnings("unchecked")
public void activateResource(Resource resource, @NotNull ResourceContainer container, boolean updatedPluginConfig)
throws InvalidPluginConfigurationException, PluginContainerException {
+ if (resourceUpgradeDelegate.hasUpgradeFailed(resource)) {
+ if (log.isTraceEnabled()) {
+ log.trace("Skipping activation of " + resource + " - it has failed to upgrade.");
+ }
+ return;
+ }
+
ResourceComponent component = container.getResourceComponent();
// if the component already exists and is started, and the resource's plugin config has not changed, there is
@@ -1762,7 +1777,7 @@ public class InventoryManager extends AgentService implements ContainerService,
* Shutdown the ResourceComponents from the bottom up.
* @param resource The resource to deactivate
*/
- private void deactivateResource(Resource resource) {
+ public void deactivateResource(Resource resource) {
this.inventoryLock.writeLock().lock();
try {
ResourceContainer container = getResourceContainer(resource);
@@ -1841,7 +1856,7 @@ public class InventoryManager extends AgentService implements ContainerService,
Set<DiscoveredResourceDetails> discoveredResources = null;
try {
- discoveredResources = invokeDiscoveryComponent(component, context);
+ discoveredResources = invokeDiscoveryComponent(null, component, context);
} catch (Throwable e) {
log.warn("Platform plugin discovery failed - skipping", e);
}
@@ -2043,6 +2058,13 @@ public class InventoryManager extends AgentService implements ContainerService,
}
}
+ /**
+ * @return true if the inventory manager failed to merge the upgrade requests with the server during startup.
+ */
+ public boolean hasUpgradeMergeFailed() {
+ return resourceUpgradeDelegate.hasUpgradeMergeFailed();
+ }
+
/**
* Always use this before accessing the event listeners because this ensures
* thread safety.
@@ -2171,7 +2193,7 @@ public class InventoryManager extends AgentService implements ContainerService,
parentResourceContext, SystemInfoFactory.createSystemInfo(), processScanResults,
Collections.EMPTY_LIST, this.configuration.getContainerName(), this.configuration
.getPluginContainerDeployment());
- Set<DiscoveredResourceDetails> discoveredResources = invokeDiscoveryComponent(discoveryComponent, context);
+ Set<DiscoveredResourceDetails> discoveredResources = invokeDiscoveryComponent(parentContainer, discoveryComponent, context);
newResources = new HashSet<Resource>();
if ((discoveredResources != null) && (!discoveredResources.isEmpty())) {
IdentityHashMap<Configuration, DiscoveredResourceDetails> pluginConfigObjects = new IdentityHashMap<Configuration, DiscoveredResourceDetails>();
@@ -2613,6 +2635,12 @@ public class InventoryManager extends AgentService implements ContainerService,
private void upgradeResources() {
try {
+
+ if (!configuration.isInsideAgent()) {
+ log.debug("Skipping resource upgrade in embedded mode.");
+ return;
+ }
+
log.debug("Executing resource upgrade.");
boolean syncResult = handleReport(new InventoryReport(getAgent()), true);
@@ -2622,7 +2650,7 @@ public class InventoryManager extends AgentService implements ContainerService,
}
upgradeResource(getPlatform());
-
+
log.debug("Sending the upgrade requests to the server.");
resourceUpgradeDelegate.sendRequests();
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
index 025ba3a..98a897e 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
@@ -19,15 +19,17 @@
package org.rhq.core.pc.upgrade;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-
import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.pc.PluginContainer;
import org.rhq.core.pc.inventory.InventoryManager;
@@ -56,7 +58,10 @@ public class ResourceUpgradeDelegate {
private Set<ResourceUpgradeRequest> requests = new HashSet<ResourceUpgradeRequest>();
private InventoryManager inventoryManager;
-
+ private Set<Resource> failedResources = new HashSet<Resource>();
+ private Map<Resource, Set<ResourceType>> failedResourceTypesPerParent = new HashMap<Resource, Set<ResourceType>>();
+ private boolean mergeFailed;
+
public ResourceUpgradeDelegate(InventoryManager inventoryManager) {
this.inventoryManager = inventoryManager;
}
@@ -88,11 +93,56 @@ public class ResourceUpgradeDelegate {
}
}
- public void sendRequests() {
- if (enabled) {
- if (requests.size() > 0) {
- inventoryManager.mergeResourceFromUpgrade(requests);
- requests.clear();
+ /**
+ * @return true if {@link #sendRequests()} threw an exception, false otherwise
+ */
+ public boolean hasUpgradeMergeFailed() {
+ return mergeFailed;
+ }
+
+ /**
+ * Tells whether given resource had a upgrade failure during the {@link #processAndQueue(ResourceContainer)} invocation.
+ *
+ * @param resource the resource to test
+ * @return true if there was an error upgrading this resource, false otherwise
+ */
+ public boolean hasUpgradeFailed(Resource resource) {
+ return mergeFailed || failedResources.contains(resource);
+ }
+
+ /**
+ * Tells whether at least one of the children with given resource type of the given parent resource
+ * had an upgrade failure during {@link #processAndQueue(ResourceContainer)} invocation.
+ *
+ * @return true if at least one of the children of given type failed to upgrade, false otherwise
+ */
+ public boolean hasUpgradeFailedInChildren(Resource parentResource, ResourceType childrenResourceType) {
+ if (mergeFailed) {
+ return true;
+ }
+
+ Set<ResourceType> failedTypes = failedResourceTypesPerParent.get(parentResource);
+
+ return failedTypes != null && failedTypes.contains(childrenResourceType);
+ }
+
+ public void sendRequests() throws Throwable {
+ if (enabled && requests.size() > 0) {
+ try {
+ inventoryManager.mergeResourcesFromUpgrade(requests);
+ } catch (Throwable t) {
+ mergeFailed = true;
+
+ //deactivate all the resources to be upgraded. We might have a problem
+ //because they have not been upgraded because the merge failed.
+ for(ResourceUpgradeRequest request : requests) {
+ ResourceContainer container = inventoryManager.getResourceContainer(request.getResourceId());
+ if (container != null) {
+ inventoryManager.deactivateResource(container.getResource());
+ }
+ }
+
+ throw t;
}
}
}
@@ -157,6 +207,20 @@ public class ResourceUpgradeDelegate {
if (request.hasSomethingToUpgrade()) {
requests.add(request);
}
+
+ if (request.getUpgradeErrorMessage() != null) {
+ failedResources.add(resource);
+
+ Set<ResourceType> failedResourceTypesInParent = failedResourceTypesPerParent.get(parentResource);
+ if (failedResourceTypesInParent == null) {
+ failedResourceTypesInParent = new HashSet<ResourceType>();
+ failedResourceTypesPerParent.put(parentResource, failedResourceTypesInParent);
+ }
+
+ failedResourceTypesInParent.add(resource.getResourceType());
+
+ inventoryManager.deactivateResource(resource);
+ }
}
private String checkUpgradeValid(Resource resource, ResourceUpgradeReport upgradeReport) {
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 244d2f2..1479345 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -237,6 +237,14 @@ public class ResourceUpgradeTest {
TestPayload test = new TestPayload() {
public void test(Resource resourceUpgradeTestResource) {
assertTrue(resourceUpgradeTestResource.getResourceErrors().size() > 0, "There should be upgrade errors persisted on the server side.");
+
+ //the discovery of the failed resource mustn't have run
+ ResourceContainer container = PluginContainer.getInstance().getInventoryManager().getResourceContainer(resourceUpgradeTestResource);
+ File dataDir = container.getResourceContext().getDataDirectory();
+
+ File marker = new File(dataDir, "failing-discovery-ran");
+
+ assertFalse(marker.exists(), "The discovery of the resource type with a failed upgraded resource must not be executed but it was.");
}
@SuppressWarnings("unchecked")
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/DiscComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/DiscComponent.java
index 54153e6..75bfbd7 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/DiscComponent.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/DiscComponent.java
@@ -19,6 +19,8 @@
package org.rhq.core.pc.upgrade.plugins.failing;
+import java.io.File;
+import java.io.IOException;
import java.util.Collections;
import java.util.Set;
@@ -44,6 +46,20 @@ public class DiscComponent implements ResourceDiscoveryComponent<ResourceCompone
public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext<ResourceComponent> context)
throws InvalidPluginConfigurationException, Exception {
+
+ //create a marker file so that the testing code knows this method has run
+ File dataDir = context.getParentResourceContext().getDataDirectory();
+ if (dataDir != null) {
+ if (!(dataDir.exists())) {
+ dataDir.mkdir();
+ }
+ File marker = new File(dataDir, "failing-discovery-ran");
+ try {
+ marker.createNewFile();
+ } catch (IOException e) {
+ }
+ }
+
return Collections.singleton(new DiscoveredResourceDetails(context.getResourceType(), RESOURCE_KEY,
RESOURCE_NAME, null, RESOURCE_DESCRIPTION, context.getDefaultPluginConfiguration(), null));
}
diff --git a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
index d1894cb..43c2ba5 100644
--- a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
+++ b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
@@ -91,6 +91,7 @@ import org.rhq.core.domain.cloud.composite.FailoverListComposite.ServerEntry;
import org.rhq.core.pc.PluginContainer;
import org.rhq.core.pc.PluginContainerConfiguration;
import org.rhq.core.pc.ServerServices;
+import org.rhq.core.pc.inventory.InventoryManager;
import org.rhq.core.pc.plugin.FileSystemPluginFinder;
import org.rhq.core.system.SystemInfoFactory;
import org.rhq.core.util.ObjectNameFactory;
@@ -1591,6 +1592,7 @@ public class AgentMain {
* <ul>
* <li>Registering with the server (if the agent needs to do so at startup)</li>
* <li>Updating the plugins with the latest versions that are found on the server</li>
+ * <li>Setup a conditional restart of the plugin container, see {@link PluginContainerConditionalRestartListener}</li>
* </ul>
*
* @return <code>true</code> if the agent is not registered or the agent was asked to re-register with the server;
@@ -1623,6 +1625,10 @@ public class AgentMain {
updatePlugins();
}
+ //the next thing is to setup the conditional restart of the PC if it fails to merge
+ //the upgrade results with the server due to some network glitch
+ m_clientSender.addStateListener(new PluginContainerConditionalRestartListener(), false);
+
return register;
}
@@ -3390,6 +3396,42 @@ public class AgentMain {
}
/**
+ * This listener restarts the plugin container upon establishing the connection with the server
+ * if the following conditions are met:
+ * <ol>
+ * <li> The plugin container is started
+ * <li> It performed the resource upgrade but failed to merge the changes to the server
+ * </ol>
+ * By restarting the plugin container in such conditions, we essentially re-run the resource upgrade
+ * and let the plugin container try to re-merge with the server that we know has just connected.
+ *
+ * @author Lukas Krejci
+ */
+ private class PluginContainerConditionalRestartListener implements ClientCommandSenderStateListener {
+ public boolean startedSending(ClientCommandSender sender) {
+ try {
+ InventoryManager inventoryManager = PluginContainer.getInstance().getInventoryManager();
+ if (inventoryManager != null && inventoryManager.hasUpgradeMergeFailed()) {
+ m_output.println(MSG.getMsg(AgentI18NResourceKeys.RESTARTING_PLUGIN_CONTAINER_AFTER_UPGRADE_MERGE_FAILURE));
+ LOG.info(AgentI18NResourceKeys.RESTARTING_PLUGIN_CONTAINER_AFTER_UPGRADE_MERGE_FAILURE);
+
+ PluginContainerPromptCommand pcCommand = new PluginContainerPromptCommand();
+ pcCommand.execute(AgentMain.this, new String[] { "stop" });
+ pcCommand.execute(AgentMain.this, new String[] { "start" });
+ }
+ } catch (Exception e) {
+ LOG.error("Failed to restart the plugin container when server connection established.");
+ }
+ return true;
+ }
+
+ public boolean stoppedSending(ClientCommandSender sender) {
+ //do nothing but keep listening
+ return true;
+ }
+ }
+
+ /**
* When the agent starts up, it needs to create the communications servers before starting the plugin container;
* however, the agent must not process any incoming commands until after the plugin container fully starts. This
* command listener will actually block indefinitely all commands from being processed until its told to open the
diff --git a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/i18n/AgentI18NResourceKeys.java b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/i18n/AgentI18NResourceKeys.java
index eb1df86..c28349c 100644
--- a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/i18n/AgentI18NResourceKeys.java
+++ b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/i18n/AgentI18NResourceKeys.java
@@ -2050,4 +2050,7 @@ public interface AgentI18NResourceKeys {
@I18NMessage("Done.")
String AVAILABILITY_REPORT_SENT = "PromptCommand.availability.sent";
+
+ @I18NMessage("Restarting the plugin container due to previous failure to merge the upgrade results with the server.")
+ String RESTARTING_PLUGIN_CONTAINER_AFTER_UPGRADE_MERGE_FAILURE = "AgentMain.pc-conditional-restart";
}
\ No newline at end of file
diff --git a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/promptcmd/DiscoveryPromptCommand.java b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/promptcmd/DiscoveryPromptCommand.java
index 8736f05..1de2dfb 100644
--- a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/promptcmd/DiscoveryPromptCommand.java
+++ b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/promptcmd/DiscoveryPromptCommand.java
@@ -359,7 +359,7 @@ public class DiscoveryPromptCommand implements AgentPromptCommand {
PluginContainerDeployment.AGENT);
Set<DiscoveredResourceDetails> discoveredResources;
- discoveredResources = inventoryManager.invokeDiscoveryComponent(discoveryComponent, context);
+ discoveredResources = inventoryManager.invokeDiscoveryComponent(platformContainer, discoveryComponent, context);
if (discoveredResources != null) {
for (DiscoveredResourceDetails discoveredResource : discoveredResources) {
out.println(MSG.getMsg(AgentI18NResourceKeys.DISCOVERY_COMPONENT_RESULT, discoveredResource
diff --git a/modules/enterprise/agent/src/test/java/org/rhq/enterprise/agent/PluginContainerConditionalRestart.java b/modules/enterprise/agent/src/test/java/org/rhq/enterprise/agent/PluginContainerConditionalRestart.java
new file mode 100644
index 0000000..b88d097
--- /dev/null
+++ b/modules/enterprise/agent/src/test/java/org/rhq/enterprise/agent/PluginContainerConditionalRestart.java
@@ -0,0 +1,31 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.enterprise.agent;
+
+import org.testng.annotations.Test;
+
+/**
+ *
+ * @author Lukas Krejci
+ */
+@Test
+public class PluginContainerConditionalRestart {
+ //TODO implement
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
index 29815cc..95bec5f 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
@@ -23,7 +23,11 @@ import org.rhq.core.domain.resource.composite.ResourceComposite;
import org.rhq.enterprise.gui.coregui.client.components.table.Table;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
+import com.smartgwt.client.data.DSCallback;
+import com.smartgwt.client.data.DSRequest;
+import com.smartgwt.client.data.DSResponse;
import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.types.GroupStartOpen;
import com.smartgwt.client.widgets.HTMLPane;
import com.smartgwt.client.widgets.IButton;
import com.smartgwt.client.widgets.Window;
@@ -41,43 +45,37 @@ import com.smartgwt.client.widgets.grid.events.CellClickHandler;
public class OverviewView extends LocatableVLayout {
private ResourceComposite resourceComposite;
-
+ private OverviewForm form;
+ private Table errorsGrid;
+
public OverviewView(String locatorId, ResourceComposite resourceComposite) {
super(locatorId);
this.resourceComposite = resourceComposite;
- }
-
- @Override
- protected void onDraw() {
- super.onDraw();
-
- setLeft("10%");
- setWidth("80%");
-
- if (this.resourceComposite != null) {
- onResourceSelected(this.resourceComposite);
- }
- }
-
- public void onResourceSelected(ResourceComposite resourceComposite) {
- addMember(new OverviewForm(extendLocatorId("form"), resourceComposite));
- buildErrorListGrid(resourceComposite);
- }
+ form = new OverviewForm(extendLocatorId("form"), resourceComposite);
+ errorsGrid = new Table(extendLocatorId("errors"), "Detected errors", null, null, new String[] { ResourceErrorsDataSource.DETAIL_ID });
- private void buildErrorListGrid(ResourceComposite resourceComposite) {
- final Resource resource = resourceComposite.getResource();
- final Table errorsGrid = new Table(extendLocatorId("errors"));
+ Resource resource = resourceComposite.getResource();
+ ResourceErrorsDataSource errors = new ResourceErrorsDataSource(resource.getId());
errorsGrid.setShowFooter(false);
-// errorsGrid.getListGrid().setGroupByField(ResourceErrorsDataSource.ERROR_TYPE_ID);
-// errorsGrid.getListGrid().setGroupStartOpen(GroupStartOpen.ALL);
-// errorsGrid.getListGrid().setShowGroupSummary(true);
-
- errorsGrid.setDataSource(new ResourceErrorsDataSource(resource.getId()));
+ errorsGrid.setDataSource(errors);
- //hide only works after we set the datasource
- errorsGrid.getListGrid().hideField(ResourceErrorsDataSource.DETAIL_ID);
+ form.setHeight("*");
+ errorsGrid.setHeight("10%");
+ addMember(form);
+ addMember(errorsGrid);
+
+ }
+
+ @Override
+ public void onInit() {
+ super.onInit();
+ initErrorsGrid();
+ }
+
+ private void initErrorsGrid() {
+ errorsGrid.setTooltip("Click on the rows to see the error details.");
errorsGrid.getListGrid().addCellClickHandler(new CellClickHandler() {
public void onCellClick(CellClickEvent event) {
ListGridRecord record = event.getRecord();
@@ -113,7 +111,5 @@ public class OverviewView extends LocatableVLayout {
w.show();
}
});
-
- addMember(errorsGrid);
}
}
commit 34483f9ca83545ab317caf12545531ab5d9b31e9
Merge: b9e1f2c... 24ba997...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Sep 20 16:58:46 2010 +0200
Merge branch 'master' into resource-upgrade
diff --cc modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewForm.java
index 074b3c9,0000000..2479c87
mode 100644,000000..100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewForm.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewForm.java
@@@ -1,298 -1,0 +1,299 @@@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.summary;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.EnumSet;
+import java.util.List;
+
+import org.rhq.core.domain.measurement.DataType;
+import org.rhq.core.domain.measurement.DisplayType;
+import org.rhq.core.domain.measurement.MeasurementDataTrait;
+import org.rhq.core.domain.measurement.MeasurementDefinition;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.resource.composite.ResourceComposite;
+import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.components.form.EnhancedDynamicForm;
+import org.rhq.enterprise.gui.coregui.client.components.form.TogglableTextItem;
+import org.rhq.enterprise.gui.coregui.client.components.form.ValueUpdatedHandler;
+import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGWTServiceAsync;
+import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
+import org.rhq.enterprise.gui.coregui.client.util.message.Message;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.util.SC;
+import com.smartgwt.client.widgets.form.fields.FormItem;
+import com.smartgwt.client.widgets.form.fields.HeaderItem;
+import com.smartgwt.client.widgets.form.fields.SpacerItem;
+import com.smartgwt.client.widgets.form.fields.StaticTextItem;
+
+/**
+ * The Resource Summary>Overview tab, the form with resource data.
+ *
+ * @author Greg Hinkle
+ * @author Ian Springer
+ */
+public class OverviewForm extends EnhancedDynamicForm {
+
+ private ResourceGWTServiceAsync resourceService = GWTServiceLookup.getResourceService();
+ private ResourceComposite resourceComposite;
+
- public OverviewForm(ResourceComposite resourceComposite) {
++ public OverviewForm(String locatorId, ResourceComposite resourceComposite) {
++ super(locatorId);
+ this.resourceComposite = resourceComposite;
+ }
+
+ @Override
+ protected void onDraw() {
+ super.onDraw();
+
+ setLeft("10%");
+ setWidth("80%");
+
+ if (this.resourceComposite != null) {
+ setResource(this.resourceComposite);
+ }
+ }
+
+ public void setResource(ResourceComposite resourceComposite) {
+
+ this.resourceComposite = resourceComposite;
+ Resource resource = resourceComposite.getResource();
+
+ // Load metric defs.
+ ResourceTypeRepository.Cache.getInstance().getResourceTypes(resource.getResourceType().getId(),
+ EnumSet.of(ResourceTypeRepository.MetadataType.measurements),
+ new ResourceTypeRepository.TypeLoadedCallback() {
+ public void onTypesLoaded(ResourceType type) {
+ try {
+ buildForm(type);
+ loadTraitValues();
+ } catch (Exception e) {
+ SC.say("Form load failure");
+ e.printStackTrace();
+ }
+ }
+ });
+ }
+
+ private void loadTraitValues() {
+ final Resource resource = resourceComposite.getResource();
+ GWTServiceLookup.getMeasurementDataService().findCurrentTraitsForResource(
+ resource.getId(),
+ DisplayType.SUMMARY,
+ new AsyncCallback<List<MeasurementDataTrait>>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Failed to load traits for " + resource + ".",
+ caught);
+ }
+
+ public void onSuccess(List<MeasurementDataTrait> result) {
+ // TODO: Implement this method.
+ for (MeasurementDataTrait trait : result) {
+ String formId = trait.getName().replaceAll("\\.", "_").replaceAll(" ", "__");
+ FormItem item = getItem(formId);
+
+ if (item != null) {
+ setValue(formId, trait.getValue());
+ }
+ }
+ markForRedraw();
+ }
+ }
+ );
+
+ }
+
+ private void buildForm(ResourceType type) {
+ List<MeasurementDefinition> traits = new ArrayList<MeasurementDefinition>();
+
+ for (MeasurementDefinition measurement : type.getMetricDefinitions()) {
+ if (measurement.getDataType() == DataType.TRAIT && measurement.getDisplayType() == DisplayType.SUMMARY) {
+ traits.add(measurement);
+ }
+ }
+
+ Collections.sort(traits, new Comparator<MeasurementDefinition>() {
+ public int compare(MeasurementDefinition o1, MeasurementDefinition o2) {
+ return new Integer(o1.getDisplayOrder()).compareTo(o2.getDisplayOrder());
+ }
+ });
+
+ List<FormItem> formItems = new ArrayList<FormItem>();
+
+ HeaderItem headerItem = new HeaderItem("header", "Summary");
+ headerItem.setValue("Summary");
+ formItems.add(headerItem);
+
+ StaticTextItem typeItem = new StaticTextItem("type", "Type");
+ typeItem.setTooltip("Plugin: " + type.getPlugin() + "\n<br>" + "Type: " + type.getName());
+ typeItem.setValue(type.getName() + " (" + type.getPlugin() + ")");
+ formItems.add(typeItem);
+
+ final Resource resource = this.resourceComposite.getResource();
+ boolean modifiable = this.resourceComposite.getResourcePermission().isInventory();
+
+ final FormItem nameItem = (modifiable) ? new TogglableTextItem() : new StaticTextItem();
+ nameItem.setName("name");
+ nameItem.setTitle("Name");
+ nameItem.setValue(resource.getName());
+ if (nameItem instanceof TogglableTextItem) {
+ TogglableTextItem togglableNameItem = (TogglableTextItem) nameItem;
+ togglableNameItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
+ public void onValueUpdated(final String newName) {
+ final String oldName = resource.getName();
+ if (newName.equals(oldName)) {
+ return;
+ }
+ resource.setName(newName);
+ OverviewForm.this.resourceService.updateResource(resource, new AsyncCallback<Void>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Failed to change name of Resource with id "
+ + resource.getId()
+ + " from \"" + oldName + "\" to \"" + newName + "\".", caught);
+ // We failed to update it on the Server, so change back the Resource and the form item to
+ // the original value.
+ resource.setName(oldName);
+ nameItem.setValue(oldName);
+ }
+
+ public void onSuccess(Void result) {
+ CoreGUI.getMessageCenter().notify(new Message("Name of Resource with id "
+ + resource.getId() + " was changed from \""
+ + oldName + "\" to \"" + newName + "\".", Message.Severity.Info));
+ }
+ });
+ }
+ });
+ }
+ formItems.add(nameItem);
+
+ final FormItem descriptionItem = (modifiable) ? new TogglableTextItem() : new StaticTextItem();
+ descriptionItem.setName("description");
+ descriptionItem.setTitle("Description");
+ descriptionItem.setValue(resource.getDescription());
+ if (descriptionItem instanceof TogglableTextItem) {
+ TogglableTextItem togglableDescriptionItem = (TogglableTextItem) descriptionItem;
+ togglableDescriptionItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
+ public void onValueUpdated(final String newDescription) {
+ final String oldDescription = resource.getDescription();
+ if (newDescription.equals(oldDescription)) {
+ return;
+ }
+ resource.setDescription(newDescription);
+ OverviewForm.this.resourceService.updateResource(resource, new AsyncCallback<Void>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Failed to change description of Resource with id "
+ + resource.getId()
+ + " from \"" + oldDescription + "\" to \"" + newDescription + "\".", caught);
+ // We failed to update it on the Server, so change back the Resource and the form item to
+ // the original value.
+ resource.setDescription(oldDescription);
+ descriptionItem.setValue(oldDescription);
+ }
+
+ public void onSuccess(Void result) {
+ CoreGUI.getMessageCenter().notify(new Message("Description of Resource with id "
+ + resource.getId() + " was changed from \""
+ + oldDescription + "\" to \"" + newDescription + "\".", Message.Severity.Info));
+ }
+ });
+ }
+ });
+ }
+ formItems.add(descriptionItem);
+
+ final FormItem locationItem = (modifiable) ? new TogglableTextItem() : new StaticTextItem();
+ locationItem.setName("location");
+ locationItem.setTitle("Location");
+ locationItem.setValue(resource.getLocation());
+ if (locationItem instanceof TogglableTextItem) {
+ TogglableTextItem togglableNameItem = (TogglableTextItem) locationItem;
+ togglableNameItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
+ public void onValueUpdated(final String newLocation) {
+ final String oldLocation = resource.getLocation();
+ if (newLocation.equals(oldLocation)) {
+ return;
+ }
+ resource.setLocation(newLocation);
+ OverviewForm.this.resourceService.updateResource(resource, new AsyncCallback<Void>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Failed to change location of Resource with id "
+ + resource.getId()
+ + " from \"" + oldLocation + "\" to \"" + newLocation + "\".", caught);
+ // We failed to update it on the Server, so change back the Resource and the form item to
+ // the original value.
+ resource.setLocation(oldLocation);
+ locationItem.setValue(oldLocation);
+ }
+
+ public void onSuccess(Void result) {
+ CoreGUI.getMessageCenter().notify(new Message("Location of Resource with id "
+ + resource.getId() + " was changed from \""
+ + oldLocation + "\" to \"" + newLocation + "\".", Message.Severity.Info));
+ }
+ });
+ }
+ });
+ }
+ formItems.add(locationItem);
+
+
+ StaticTextItem versionItem = new StaticTextItem("version", "Version");
+ formItems.add(versionItem);
+
+ StaticTextItem parentItem = new StaticTextItem("parent", "Parent");
+ formItems.add(parentItem);
+
+ for (MeasurementDefinition trait : traits) {
+ String id = trait.getDisplayName().replaceAll("\\.", "_").replaceAll(" ", "__");
+
+ StaticTextItem item = new StaticTextItem(id, trait.getDisplayName());
+ item.setTooltip(trait.getDescription());
+ formItems.add(item);
+// item.setValue("?");
+ }
+
+// SectionItem section = new SectionItem("Summary", "Summary");
+// section.setTitle("Summary");
+// section.setDefaultValue("Summary");
+// section.setCanCollapse(true);
+// section.setCellStyle("HidablePlainSectionHeader");
+// section.setItemIds(itemIds.toArray(new String[itemIds.size()]));
+// formItems.add(0, section);
+
+ formItems.add(new SpacerItem());
+ setItems(formItems.toArray(new FormItem[formItems.size()]));
+
+ setValue("type", type.getName() + " (" + type.getPlugin() + ")");
+ setValue("name", resource.getName());
+ setValue("description", resource.getDescription());
+ setValue("location", resource.getLocation());
+ setValue("version", (resource.getVersion() != null) ? resource.getVersion() : "<i>none</i>");
+ Resource parentResource = resource.getParentResource();
+ setValue("parent", parentResource != null ?
+ ("<a href=\"#Resource/" + parentResource.getId() + "\">" +
+ parentResource.getName() + "</a>") : "<i>none</i>");
+ }
+}
diff --cc modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
index 10bde5b,4cf2119..29815cc
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
@@@ -18,31 -18,49 +18,32 @@@
*/
package org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.summary;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.EnumSet;
-import java.util.List;
-
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.smartgwt.client.util.SC;
-import com.smartgwt.client.widgets.form.fields.FormItem;
-import com.smartgwt.client.widgets.form.fields.HeaderItem;
-import com.smartgwt.client.widgets.form.fields.SpacerItem;
-import com.smartgwt.client.widgets.form.fields.StaticTextItem;
-
-import org.rhq.core.domain.measurement.DataType;
-import org.rhq.core.domain.measurement.DisplayType;
-import org.rhq.core.domain.measurement.MeasurementDataTrait;
-import org.rhq.core.domain.measurement.MeasurementDefinition;
import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.composite.ResourceComposite;
-import org.rhq.enterprise.gui.coregui.client.CoreGUI;
-import org.rhq.enterprise.gui.coregui.client.components.form.EnhancedDynamicForm;
-import org.rhq.enterprise.gui.coregui.client.components.form.TogglableTextItem;
-import org.rhq.enterprise.gui.coregui.client.components.form.ValueUpdatedHandler;
-import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
-import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGWTServiceAsync;
-import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceSelectListener;
-import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
-import org.rhq.enterprise.gui.coregui.client.util.message.Message;
+import org.rhq.enterprise.gui.coregui.client.components.table.Table;
++import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
+
+import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.widgets.HTMLPane;
+import com.smartgwt.client.widgets.IButton;
+import com.smartgwt.client.widgets.Window;
+import com.smartgwt.client.widgets.events.ClickEvent;
+import com.smartgwt.client.widgets.events.ClickHandler;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+import com.smartgwt.client.widgets.grid.events.CellClickEvent;
+import com.smartgwt.client.widgets.grid.events.CellClickHandler;
- import com.smartgwt.client.widgets.layout.VLayout;
/**
* The Resource Summary>Overview tab.
*
- * @author Greg Hinkle
- * @author Ian Springer
+ * @author Lukas Krejci
*/
- public class OverviewView extends VLayout {
-public class OverviewView extends EnhancedDynamicForm implements ResourceSelectListener {
++public class OverviewView extends LocatableVLayout {
- private ResourceGWTServiceAsync resourceService = GWTServiceLookup.getResourceService();
private ResourceComposite resourceComposite;
- public OverviewView(ResourceComposite resourceComposite) {
+ public OverviewView(String locatorId, ResourceComposite resourceComposite) {
+ super(locatorId);
this.resourceComposite = resourceComposite;
}
@@@ -59,60 -77,218 +60,60 @@@
}
public void onResourceSelected(ResourceComposite resourceComposite) {
- addMember(new OverviewForm(resourceComposite));
-
- this.resourceComposite = resourceComposite;
- Resource resource = resourceComposite.getResource();
-
- // Load metric defs.
- ResourceTypeRepository.Cache.getInstance().getResourceTypes(resource.getResourceType().getId(),
- EnumSet.of(ResourceTypeRepository.MetadataType.measurements),
- new ResourceTypeRepository.TypeLoadedCallback() {
- public void onTypesLoaded(ResourceType type) {
- try {
- buildForm(type);
- loadTraitValues();
- } catch (Exception e) {
- SC.say("Form load failure");
- e.printStackTrace();
- }
- }
- });
++ addMember(new OverviewForm(extendLocatorId("form"), resourceComposite));
+ buildErrorListGrid(resourceComposite);
}
- private void loadTraitValues() {
+ private void buildErrorListGrid(ResourceComposite resourceComposite) {
final Resource resource = resourceComposite.getResource();
- Table errorsGrid = new Table("Errors");
- GWTServiceLookup.getMeasurementDataService().findCurrentTraitsForResource(resource.getId(),
- DisplayType.SUMMARY, new AsyncCallback<List<MeasurementDataTrait>>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError("Failed to load traits for " + resource + ".", caught);
- }
-
- public void onSuccess(List<MeasurementDataTrait> result) {
- // TODO: Implement this method.
- for (MeasurementDataTrait trait : result) {
- String formId = trait.getName().replaceAll("\\.", "_").replaceAll(" ", "__");
- FormItem item = getItem(formId);
-
- if (item != null) {
- setValue(formId, trait.getValue());
- }
++ final Table errorsGrid = new Table(extendLocatorId("errors"));
+
+ errorsGrid.setShowFooter(false);
+// errorsGrid.getListGrid().setGroupByField(ResourceErrorsDataSource.ERROR_TYPE_ID);
+// errorsGrid.getListGrid().setGroupStartOpen(GroupStartOpen.ALL);
+// errorsGrid.getListGrid().setShowGroupSummary(true);
+
+ errorsGrid.setDataSource(new ResourceErrorsDataSource(resource.getId()));
+
+ //hide only works after we set the datasource
+ errorsGrid.getListGrid().hideField(ResourceErrorsDataSource.DETAIL_ID);
+
+ errorsGrid.getListGrid().addCellClickHandler(new CellClickHandler() {
+ public void onCellClick(CellClickEvent event) {
+ ListGridRecord record = event.getRecord();
+ final Window w = new Window();
+ w.setTitle("Error Details");
+ w.setIsModal(true);
+ w.setShowMinimizeButton(false);
+ w.setShowModalMask(true);
+ w.setWidth(640);
+ w.setHeight(480);
+ w.centerInPage();
+ w.setCanDragResize(true);
+
- VLayout layout = new VLayout(10);
++ LocatableVLayout layout = new LocatableVLayout(errorsGrid.extendLocatorId("dialogLayout"), 10);
+ layout.setDefaultLayoutAlign(Alignment.CENTER);
+ layout.setLayoutMargin(10);
+
+ w.addItem(layout);
+
+ HTMLPane details = new HTMLPane();
+ details.setContents("<pre>" + record.getAttribute(ResourceErrorsDataSource.DETAIL_ID) + "</pre>");
+ layout.addMember(details);
+
+ IButton ok = new IButton("Ok");
+ ok.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ w.destroy();
}
- markForRedraw();
- }
- });
-
- }
-
- private void buildForm(ResourceType type) {
- List<MeasurementDefinition> traits = new ArrayList<MeasurementDefinition>();
-
- for (MeasurementDefinition measurement : type.getMetricDefinitions()) {
- if (measurement.getDataType() == DataType.TRAIT && measurement.getDisplayType() == DisplayType.SUMMARY) {
- traits.add(measurement);
- }
- }
-
- Collections.sort(traits, new Comparator<MeasurementDefinition>() {
- public int compare(MeasurementDefinition o1, MeasurementDefinition o2) {
- return new Integer(o1.getDisplayOrder()).compareTo(o2.getDisplayOrder());
+ });
+
+ layout.addMember(ok);
+
+ w.show();
}
});
-
- List<FormItem> formItems = new ArrayList<FormItem>();
-
- HeaderItem headerItem = new HeaderItem("header", "Summary");
- headerItem.setValue("Summary");
- formItems.add(headerItem);
-
- StaticTextItem typeItem = new StaticTextItem("type", "Type");
- typeItem.setTooltip("Plugin: " + type.getPlugin() + "\n<br>" + "Type: " + type.getName());
- typeItem.setValue(type.getName() + " (" + type.getPlugin() + ")");
- formItems.add(typeItem);
-
- final Resource resource = this.resourceComposite.getResource();
- boolean modifiable = this.resourceComposite.getResourcePermission().isInventory();
-
- final FormItem nameItem = (modifiable) ? new TogglableTextItem() : new StaticTextItem();
- nameItem.setName("name");
- nameItem.setTitle("Name");
- nameItem.setValue(resource.getName());
- if (nameItem instanceof TogglableTextItem) {
- TogglableTextItem togglableNameItem = (TogglableTextItem) nameItem;
- togglableNameItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
- public void onValueUpdated(final String newName) {
- final String oldName = resource.getName();
- if (newName.equals(oldName)) {
- return;
- }
- resource.setName(newName);
- OverviewView.this.resourceService.updateResource(resource, new AsyncCallback<Void>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError(
- "Failed to change name of Resource with id " + resource.getId() + " from \"" + oldName
- + "\" to \"" + newName + "\".", caught);
- // We failed to update it on the Server, so change back the Resource and the form item to
- // the original value.
- resource.setName(oldName);
- nameItem.setValue(oldName);
- }
-
- public void onSuccess(Void result) {
- CoreGUI.getMessageCenter().notify(
- new Message("Name of Resource with id " + resource.getId() + " was changed from \""
- + oldName + "\" to \"" + newName + "\".", Message.Severity.Info));
- }
- });
- }
- });
- }
- formItems.add(nameItem);
-
- final FormItem descriptionItem = (modifiable) ? new TogglableTextItem() : new StaticTextItem();
- descriptionItem.setName("description");
- descriptionItem.setTitle("Description");
- descriptionItem.setValue(resource.getDescription());
- if (descriptionItem instanceof TogglableTextItem) {
- TogglableTextItem togglableDescriptionItem = (TogglableTextItem) descriptionItem;
- togglableDescriptionItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
- public void onValueUpdated(final String newDescription) {
- final String oldDescription = resource.getDescription();
- if (newDescription.equals(oldDescription)) {
- return;
- }
- resource.setDescription(newDescription);
- OverviewView.this.resourceService.updateResource(resource, new AsyncCallback<Void>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError(
- "Failed to change description of Resource with id " + resource.getId() + " from \""
- + oldDescription + "\" to \"" + newDescription + "\".", caught);
- // We failed to update it on the Server, so change back the Resource and the form item to
- // the original value.
- resource.setDescription(oldDescription);
- descriptionItem.setValue(oldDescription);
- }
-
- public void onSuccess(Void result) {
- CoreGUI.getMessageCenter().notify(
- new Message("Description of Resource with id " + resource.getId()
- + " was changed from \"" + oldDescription + "\" to \"" + newDescription + "\".",
- Message.Severity.Info));
- }
- });
- }
- });
- }
- formItems.add(descriptionItem);
-
- final FormItem locationItem = (modifiable) ? new TogglableTextItem() : new StaticTextItem();
- locationItem.setName("location");
- locationItem.setTitle("Location");
- locationItem.setValue(resource.getLocation());
- if (locationItem instanceof TogglableTextItem) {
- TogglableTextItem togglableNameItem = (TogglableTextItem) locationItem;
- togglableNameItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
- public void onValueUpdated(final String newLocation) {
- final String oldLocation = resource.getLocation();
- if (newLocation.equals(oldLocation)) {
- return;
- }
- resource.setLocation(newLocation);
- OverviewView.this.resourceService.updateResource(resource, new AsyncCallback<Void>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError(
- "Failed to change location of Resource with id " + resource.getId() + " from \""
- + oldLocation + "\" to \"" + newLocation + "\".", caught);
- // We failed to update it on the Server, so change back the Resource and the form item to
- // the original value.
- resource.setLocation(oldLocation);
- locationItem.setValue(oldLocation);
- }
-
- public void onSuccess(Void result) {
- CoreGUI.getMessageCenter().notify(
- new Message("Location of Resource with id " + resource.getId() + " was changed from \""
- + oldLocation + "\" to \"" + newLocation + "\".", Message.Severity.Info));
- }
- });
- }
- });
- }
- formItems.add(locationItem);
-
- StaticTextItem versionItem = new StaticTextItem("version", "Version");
- formItems.add(versionItem);
-
- StaticTextItem parentItem = new StaticTextItem("parent", "Parent");
- formItems.add(parentItem);
-
- for (MeasurementDefinition trait : traits) {
- String id = trait.getDisplayName().replaceAll("\\.", "_").replaceAll(" ", "__");
-
- StaticTextItem item = new StaticTextItem(id, trait.getDisplayName());
- item.setTooltip(trait.getDescription());
- formItems.add(item);
- // item.setValue("?");
- }
-
- // SectionItem section = new SectionItem("Summary", "Summary");
- // section.setTitle("Summary");
- // section.setDefaultValue("Summary");
- // section.setCanCollapse(true);
- // section.setCellStyle("HidablePlainSectionHeader");
- // section.setItemIds(itemIds.toArray(new String[itemIds.size()]));
- // formItems.add(0, section);
-
- formItems.add(new SpacerItem());
- setItems(formItems.toArray(new FormItem[formItems.size()]));
-
- setValue("type", type.getName() + " (" + type.getPlugin() + ")");
- setValue("name", resource.getName());
- setValue("description", resource.getDescription());
- setValue("location", resource.getLocation());
- setValue("version", (resource.getVersion() != null) ? resource.getVersion() : "<i>none</i>");
- Resource parentResource = resource.getParentResource();
- setValue("parent", parentResource != null ? ("<a href=\"#Resource/" + parentResource.getId() + "\">"
- + parentResource.getName() + "</a>") : "<i>none</i>");
+
+ addMember(errorsGrid);
}
}
diff --cc modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
index 267b0f1,dd5e77b..4ac0f61
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
@@@ -225,8 -226,18 +227,22 @@@ public abstract class RPCDataSource<T>
addField(field);
}
}
+
+ public void addFields(DataSourceField... fields) {
+ addFields(Arrays.asList(fields));
+ }
+
+ public ListGridRecord getEditedRecord(DSRequest request) {
+ // Retrieving values before edit
+ JavaScriptObject oldValues = request.getAttributeAsJavaScriptObject("oldValues");
+ // Creating new record for combining old values with changes
+ ListGridRecord newRecord = new ListGridRecord();
+ // Copying properties from old record
+ JSOHelper.apply(oldValues, newRecord.getJsObj());
+ // Retrieving changed values
+ JavaScriptObject data = request.getData();
+ // Apply changes
+ JSOHelper.apply(data, newRecord.getJsObj());
+ return newRecord;
+ }
}
commit b9e1f2c995a66a147793c72dbeb13df7c162128e
Merge: 0cd6acd... e5fac0a...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Sep 14 18:33:01 2010 +0200
Merge branch 'master' into resource-upgrade
diff --cc modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
index c06d0c2,b282e41..5990b60
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
@@@ -28,7 -28,8 +28,9 @@@ import org.rhq.core.domain.configuratio
import org.rhq.core.domain.criteria.ResourceCriteria;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceError;
+ import org.rhq.core.domain.resource.composite.DisambiguationReport;
+ import org.rhq.core.domain.resource.composite.ProblemResourceComposite;
import org.rhq.core.domain.resource.composite.RecentlyAddedResourceComposite;
import org.rhq.core.domain.resource.composite.ResourceComposite;
import org.rhq.core.domain.util.PageControl;
@@@ -65,7 -68,5 +69,7 @@@ public interface ResourceGWTService ext
void ignoreResources(Integer[] resourceIds);
void unignoreResources(Integer[] resourceIds);
+
+ List<ResourceError> findResourceErrors(int resourceId);
--}
++}
diff --cc modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
index e63978a,ac2abc2..10bde5b
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
@@@ -18,33 -18,50 +18,31 @@@
*/
package org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.summary;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.EnumSet;
-import java.util.List;
-
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.smartgwt.client.util.SC;
-import com.smartgwt.client.widgets.form.fields.FormItem;
-import com.smartgwt.client.widgets.form.fields.HeaderItem;
-import com.smartgwt.client.widgets.form.fields.SpacerItem;
-import com.smartgwt.client.widgets.form.fields.StaticTextItem;
-
-import org.rhq.core.domain.measurement.DataType;
-import org.rhq.core.domain.measurement.DisplayType;
-import org.rhq.core.domain.measurement.MeasurementDataTrait;
-import org.rhq.core.domain.measurement.MeasurementDefinition;
import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.composite.ResourceComposite;
-import org.rhq.enterprise.gui.coregui.client.CoreGUI;
-import org.rhq.enterprise.gui.coregui.client.components.form.EnhancedDynamicForm;
-import org.rhq.enterprise.gui.coregui.client.components.form.TogglableTextItem;
-import org.rhq.enterprise.gui.coregui.client.components.form.ValueUpdatedHandler;
-import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
-import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGWTServiceAsync;
-import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceSelectListener;
-import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
-import org.rhq.enterprise.gui.coregui.client.util.message.Message;
+import org.rhq.enterprise.gui.coregui.client.components.table.Table;
- import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceSelectListener;
+
+import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.widgets.HTMLPane;
+import com.smartgwt.client.widgets.IButton;
+import com.smartgwt.client.widgets.Window;
+import com.smartgwt.client.widgets.events.ClickEvent;
+import com.smartgwt.client.widgets.events.ClickHandler;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+import com.smartgwt.client.widgets.grid.events.CellClickEvent;
+import com.smartgwt.client.widgets.grid.events.CellClickHandler;
+import com.smartgwt.client.widgets.layout.VLayout;
/**
* The Resource Summary>Overview tab.
*
- * @author Greg Hinkle
- * @author Ian Springer
+ * @author Lukas Krejci
*/
- public class OverviewView extends VLayout implements ResourceSelectListener {
-public class OverviewView extends EnhancedDynamicForm implements ResourceSelectListener {
++public class OverviewView extends VLayout {
- private ResourceGWTServiceAsync resourceService = GWTServiceLookup.getResourceService();
private ResourceComposite resourceComposite;
-
public OverviewView(ResourceComposite resourceComposite) {
-- super();
this.resourceComposite = resourceComposite;
}
diff --cc modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
index 4f3f3ce,cb2768f..267b0f1
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
@@@ -18,9 -18,10 +18,11 @@@
*/
package org.rhq.enterprise.gui.coregui.client.util;
+import java.util.Arrays;
+ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+ import java.util.Map;
import com.smartgwt.client.data.DSRequest;
import com.smartgwt.client.data.DSResponse;
@@@ -183,11 -221,7 +222,11 @@@ public abstract class RPCDataSource<T>
*/
public void addFields(List<DataSourceField> fields) {
for (DataSourceField field : fields) {
- addField(field);
+ addField(field);
}
}
+
+ public void addFields(DataSourceField... fields) {
+ addFields(Arrays.asList(fields));
+ }
}
diff --cc modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
index b933248,25b19b0..6db01f8
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
@@@ -35,7 -35,8 +35,9 @@@ import org.rhq.core.domain.configuratio
import org.rhq.core.domain.criteria.ResourceCriteria;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceError;
+ import org.rhq.core.domain.resource.composite.DisambiguationReport;
+ import org.rhq.core.domain.resource.composite.ProblemResourceComposite;
import org.rhq.core.domain.resource.composite.RecentlyAddedResourceComposite;
import org.rhq.core.domain.resource.composite.ResourceComposite;
import org.rhq.core.domain.util.PageControl;
@@@ -215,9 -239,5 +240,9 @@@ public class ResourceGWTServiceImpl ext
public void unignoreResources(Integer[] resourceIds) {
discoveryBoss.unignoreResources(getSessionSubject(), resourceIds);
}
-
-}
+
+ public List<ResourceError> findResourceErrors(int resourceId) {
+ return SerialUtility.prepare(resourceManager.findResourceErrors(getSessionSubject(), resourceId),
+ "ResourceService.getResourceErrors");
+ }
- }
++}
commit 0cd6acd2fe93a35a9b2cdbde0828c416ac49f67d
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Aug 24 17:48:01 2010 +0200
Make tests work with the changed test plugin jars location, added tests for upgrade failure reporting.
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
index 19c1d95..adb3989 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
@@ -43,6 +43,8 @@ import org.rhq.core.clientapi.server.discovery.InventoryReport;
import org.rhq.core.domain.discovery.ResourceSyncInfo;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceError;
+import org.rhq.core.domain.resource.ResourceErrorType;
import org.rhq.core.domain.resource.ResourceType;
/**
@@ -137,6 +139,11 @@ public class FakeServerInventory {
resource.setResourceKey(request.getNewResourceKey());
}
+ if (request.getUpgradeErrorMessage() != null) {
+ ResourceError error = new ResourceError(resource, ResourceErrorType.UPGRADE, request.getUpgradeErrorMessage(), request.getUpgradeErrorStackTrace(), request.getTimestamp());
+ resource.getResourceErrors().add(error);
+ }
+
ResourceUpgradeResponse resp = new ResourceUpgradeResponse();
resp.setResourceId(resource.getId());
resp.setUpgradedResourceName(resource.getName());
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 202e0c0..244d2f2 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -69,8 +69,9 @@ import org.rhq.core.pc.plugin.FileSystemPluginFinder;
@Test(sequential = true, invocationCount = 1)
public class ResourceUpgradeTest {
- private static final String PLUGIN_V1_FILENAME = "resource-upgrade-test-plugin-1.0.0.jar";
- private static final String PLUGIN_V2_FILENAME = "resource-upgrade-test-plugin-2.0.0.jar";
+ private static final String PLUGIN_V1_FILENAME = "/resource-upgrade-test-plugin-1.0.0.jar";
+ private static final String PLUGIN_V2_FILENAME = "/resource-upgrade-test-plugin-2.0.0.jar";
+ private static final String FAILING_PLUGIN_FILE_NAME = "/resource-upgrade-test-plugin-3.0.0.jar";
private static final String PLUGINS_DIR_NAME = "plugins";
private static final String DATA_DIR_NAME = "data";
@@ -101,6 +102,7 @@ public class ResourceUpgradeTest {
public void sanityCheck() {
verifyPluginExists(PLUGIN_V1_FILENAME);
verifyPluginExists(PLUGIN_V2_FILENAME);
+ verifyPluginExists(FAILING_PLUGIN_FILE_NAME);
}
@BeforeClass(dependsOnMethods = "sanityCheck")
@@ -227,6 +229,35 @@ public class ResourceUpgradeTest {
executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, test);
}
+ @Test
+ public void testUpgradeFailureHandling() throws Exception {
+ currentServerSideInventory = new FakeServerInventory();
+ initialSyncAndDiscovery(InventoryStatus.COMMITTED);
+
+ TestPayload test = new TestPayload() {
+ public void test(Resource resourceUpgradeTestResource) {
+ assertTrue(resourceUpgradeTestResource.getResourceErrors().size() > 0, "There should be upgrade errors persisted on the server side.");
+ }
+
+ @SuppressWarnings("unchecked")
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+
+ between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+
+ oneOf(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
+ will(currentServerSideInventory.upgradeResources());
+ }
+ };
+ }
+ };
+
+ executeTestWithPlugins(Collections.singleton(FAILING_PLUGIN_FILE_NAME), false, test);
+ }
+
private void initialSyncAndDiscovery(final InventoryStatus requiredInventoryStatus) throws Exception {
cleanDataDir();
executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), true, new TestPayload() {
commit 90b602f22c280ee63deb7e51470db1fcda9b79a1
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Aug 24 17:46:58 2010 +0200
Final touches on the Server side error reporting.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
index cc63040..e63978a 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
@@ -24,7 +24,6 @@ import org.rhq.enterprise.gui.coregui.client.components.table.Table;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceSelectListener;
import com.smartgwt.client.types.Alignment;
-import com.smartgwt.client.types.GroupStartOpen;
import com.smartgwt.client.widgets.HTMLPane;
import com.smartgwt.client.widgets.IButton;
import com.smartgwt.client.widgets.Window;
@@ -33,7 +32,6 @@ import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.grid.events.CellClickEvent;
import com.smartgwt.client.widgets.grid.events.CellClickHandler;
-import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;
/**
@@ -92,9 +90,10 @@ public class OverviewView extends VLayout implements ResourceSelectListener {
w.setWidth(640);
w.setHeight(480);
w.centerInPage();
+ w.setCanDragResize(true);
VLayout layout = new VLayout(10);
- layout.setLayoutAlign(Alignment.CENTER);
+ layout.setDefaultLayoutAlign(Alignment.CENTER);
layout.setLayoutMargin(10);
w.addItem(layout);
@@ -109,7 +108,6 @@ public class OverviewView extends VLayout implements ResourceSelectListener {
w.destroy();
}
});
- ok.setAlign(Alignment.CENTER);
layout.addMember(ok);
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ResourceErrorsDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ResourceErrorsDataSource.java
index 4957fc7..1843f2b 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ResourceErrorsDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ResourceErrorsDataSource.java
@@ -90,7 +90,7 @@ public class ResourceErrorsDataSource extends RPCDataSource<ResourceError> {
ListGridRecord record = new ListGridRecord();
record.setAttribute(DETAIL_ID, from.getDetail());
- record.setAttribute(ERROR_TYPE_ID, from.getErrorType());
+ record.setAttribute(ERROR_TYPE_ID, from.getErrorType().toString());
record.setAttribute(SUMMARY_ID, from.getSummary());
record.setAttribute(TIME_OCCURED_ID, new Date(from.getTimeOccurred()));
commit f0b6cda14af2bce898dd6af66b4bb2627a836d72
Merge: d689f70... 66234db...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Aug 24 13:25:05 2010 +0200
Merge branch 'master' into resource-upgrade
diff --cc modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
index 1ea9630,950d28c..4f3f3ce
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
@@@ -18,8 -18,8 +18,9 @@@
*/
package org.rhq.enterprise.gui.coregui.client.util;
+import java.util.Arrays;
import java.util.Collection;
+ import java.util.List;
import com.smartgwt.client.data.DSRequest;
import com.smartgwt.client.data.DSResponse;
@@@ -172,13 -173,16 +174,20 @@@ public abstract class RPCDataSource<T>
return response;
}
- public void addFields(Collection<DataSourceField> fields) {
+ /**
+ * Add the specified fields to this data source. When the data source is associated with a
+ * {@link com.smartgwt.client.widgets.grid.ListGrid}, the fields will be displayed in the order they are specified
+ * here.
+ *
+ * @param fields the fields to be added
+ */
+ public void addFields(List<DataSourceField> fields) {
for (DataSourceField field : fields) {
- addField(field);
+ addField(field);
}
}
+
+ public void addFields(DataSourceField... fields) {
+ addFields(Arrays.asList(fields));
+ }
}
commit d689f70de060cdb776cea923f759f0e5de226955
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Aug 24 13:17:24 2010 +0200
Upgrade errors (and other resource errors) shown in the summary tab. Not everything seems to work yet.
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
index 9532920..aca9c90 100644
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
@@ -41,7 +41,7 @@ public class ResourceUpgradeRequest extends ResourceUpgradeReport {
private String upgradeErrorMessage;
private String upgradeErrorStackTrace;
private long timestamp;
-
+
public ResourceUpgradeRequest(int resourceId) {
this.resourceId = resourceId;
}
@@ -74,14 +74,37 @@ public class ResourceUpgradeRequest extends ResourceUpgradeReport {
public long getTimestamp() {
return timestamp;
}
-
+
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
-
+
public void setErrorProperties(Throwable t) {
- upgradeErrorMessage = t.getMessage();
+ upgradeErrorMessage = null;
+ upgradeErrorStackTrace = null;
+
+ //first try to extract an error message from the exception
+ //or some of its parents
+ Throwable p = t;
+ while (upgradeErrorMessage == null && p != null) {
+ upgradeErrorMessage = p.getMessage();
+ if (upgradeErrorMessage == null) {
+ upgradeErrorMessage = p.getLocalizedMessage();
+ }
+ p = p.getCause();
+ }
+
+ //ok, we have no error messages. But we have to supply something
+ //as the message, so let's use the class name as a last resort.
+ if (upgradeErrorMessage == null) {
+ if (t.getClass().getCanonicalName() != null) {
+ upgradeErrorMessage = t.getClass().getCanonicalName();
+ } else if (t.getClass().getName() != null) {
+ upgradeErrorMessage = t.getClass().getName();
+ }
+ }
+ //print the stack trace into a string
StringWriter string = new StringWriter();
PrintWriter w = new PrintWriter(string);
t.printStackTrace(w);
diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ResourceErrorTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ResourceErrorTest.java
index 8fdc2f7..6630d4b 100644
--- a/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ResourceErrorTest.java
+++ b/modules/core/domain/src/test/java/org/rhq/core/domain/resource/test/ResourceErrorTest.java
@@ -92,7 +92,7 @@ public class ResourceErrorTest extends AbstractEJB3Test {
q.setParameter("resourceId", newResource.getId());
assert q.getResultList().size() == 2;
- q = em.createNamedQuery(ResourceError.QUERY_FIND_BY_RESOURCE_ID_AND_ERROR_TYPE);
+ q = em.createNamedQuery(ResourceError.QUERY_FIND_BY_RESOURCE_ID_AND_ERROR_TYPES);
q.setParameter("resourceId", newResource.getId());
q.setParameter("errorType", ResourceErrorType.INVALID_PLUGIN_CONFIGURATION);
assert q.getResultList().size() == 2;
@@ -129,7 +129,7 @@ public class ResourceErrorTest extends AbstractEJB3Test {
assert errors.get(0).getDetail().equals("test detail");
assert errors.get(0).getTimeOccurred() == 12345;
- q = em.createNamedQuery(ResourceError.QUERY_FIND_BY_RESOURCE_ID_AND_ERROR_TYPE);
+ q = em.createNamedQuery(ResourceError.QUERY_FIND_BY_RESOURCE_ID_AND_ERROR_TYPES);
q.setParameter("resourceId", newResource.getId());
q.setParameter("errorType", ResourceErrorType.INVALID_PLUGIN_CONFIGURATION);
errors = q.getResultList();
diff --git a/modules/core/plugin-container/pom.xml b/modules/core/plugin-container/pom.xml
index a4ca249..4b09ef8 100644
--- a/modules/core/plugin-container/pom.xml
+++ b/modules/core/plugin-container/pom.xml
@@ -163,26 +163,39 @@
<id>process-test-classes</id>
<phase>process-test-classes</phase>
<configuration>
- <tasks>
- <echo>Assembling the two resource upgrade test plugins</echo>
- <copy toDir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v1/META-INF">
+ <tasks unless="maven.test.skip">
+ <echo>Assembling the resource upgrade test plugins</echo>
+ <copy toDir="${project.build.testOutputDirectory}/tmp/v1/META-INF">
<fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/v1/rhq-plugin.xml" />
</copy>
- <jar destfile="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-1.0.0.jar">
- <fileset dir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v1" includes="*.class,**/rhq-plugin.xml" />
+ <copy toDir="${project.build.testOutputDirectory}/tmp/v1/org/rhq/core/pc/upgrade/plugins/v1">
+ <fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v1/*.class" />
+ </copy>
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-1.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/tmp/v1" includes="**/*.class,**/rhq-plugin.xml" />
</jar>
- <copy toDir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v2/META-INF">
+
+ <copy toDir="${project.build.testOutputDirectory}/tmp/v2/META-INF">
<fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/v2/rhq-plugin.xml" />
</copy>
- <jar destfile="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar">
- <fileset dir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v2" includes="*.class,**/rhq-plugin.xml" />
+ <copy toDir="${project.build.testOutputDirectory}/tmp/v2/org/rhq/core/pc/upgrade/plugins/v2">
+ <fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v2/*.class" />
+ </copy>
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-2.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/tmp/v2" includes="**/*.class,**/rhq-plugin.xml" />
</jar>
- <copy toDir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/failing/META-INF">
+
+ <copy toDir="${project.build.testOutputDirectory}/tmp/failing/META-INF">
<fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/failing/rhq-plugin.xml" />
</copy>
- <jar destfile="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-3.0.0.jar">
- <fileset dir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/failing" includes="*.class,**/rhq-plugin.xml" />
+ <copy toDir="${project.build.testOutputDirectory}/tmp/failing/org/rhq/core/pc/upgrade/plugins/failing">
+ <fileset file="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/failing/*.class" />
+ </copy>
+ <jar destfile="${project.build.testOutputDirectory}/resource-upgrade-test-plugin-3.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/tmp/failing" includes="**/*.class,**/rhq-plugin.xml" />
</jar>
+
+ <delete dir="${project.build.testOutputDirectory}/tmp"/>
</tasks>
</configuration>
<goals>
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
index f92e7d5..c06d0c2 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
@@ -28,6 +28,7 @@ import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.criteria.ResourceCriteria;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.domain.resource.composite.RecentlyAddedResourceComposite;
import org.rhq.core.domain.resource.composite.ResourceComposite;
import org.rhq.core.domain.util.PageControl;
@@ -64,5 +65,7 @@ public interface ResourceGWTService extends RemoteService {
void ignoreResources(Integer[] resourceIds);
void unignoreResources(Integer[] resourceIds);
+
+ List<ResourceError> findResourceErrors(int resourceId);
}
\ No newline at end of file
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
index 2fff538..cc63040 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
@@ -18,20 +18,22 @@
*/
package org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.summary;
-import java.util.ArrayList;
-import java.util.List;
-
import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.domain.resource.composite.ResourceComposite;
+import org.rhq.enterprise.gui.coregui.client.components.table.Table;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceSelectListener;
-import com.smartgwt.client.util.SC;
-import com.smartgwt.client.widgets.grid.ListGrid;
-import com.smartgwt.client.widgets.grid.ListGridField;
+import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.types.GroupStartOpen;
+import com.smartgwt.client.widgets.HTMLPane;
+import com.smartgwt.client.widgets.IButton;
+import com.smartgwt.client.widgets.Window;
+import com.smartgwt.client.widgets.events.ClickEvent;
+import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.grid.ListGridRecord;
-import com.smartgwt.client.widgets.grid.events.RecordClickEvent;
-import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
+import com.smartgwt.client.widgets.grid.events.CellClickEvent;
+import com.smartgwt.client.widgets.grid.events.CellClickHandler;
+import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;
/**
@@ -62,41 +64,59 @@ public class OverviewView extends VLayout implements ResourceSelectListener {
public void onResourceSelected(ResourceComposite resourceComposite) {
addMember(new OverviewForm(resourceComposite));
- ListGrid errorsGrid = buildErrorListGrid(resourceComposite);
- if (errorsGrid != null) {
- addMember(errorsGrid);
- }
+ buildErrorListGrid(resourceComposite);
}
- private static ListGrid buildErrorListGrid(ResourceComposite resourceComposite) {
+ private void buildErrorListGrid(ResourceComposite resourceComposite) {
final Resource resource = resourceComposite.getResource();
- ListGrid errorsGrid = null;
- if (resource.getResourceErrors() != null && resource.getResourceErrors().size() > 0) {
- errorsGrid = new ListGrid();
-
- ListGridField summaryField = new ListGridField("summary", "Errors");
- summaryField.addRecordClickHandler(new RecordClickHandler() {
-
- @Override
- public void onRecordClick(RecordClickEvent event) {
- String detail = event.getRecord().getAttribute("detail");
- SC.say("Error details", detail);
- }
- });
-
- errorsGrid.setFields(summaryField);
-
- List<ListGridRecord> errorList = new ArrayList<ListGridRecord>();
- for (ResourceError error : resource.getResourceErrors()) {
- ListGridRecord record = new ListGridRecord();
- record.setAttribute("summary", error.getSummary());
- record.setAttribute("detail", error.getDetail());
- errorList.add(record);
+ Table errorsGrid = new Table("Errors");
+
+ errorsGrid.setShowFooter(false);
+// errorsGrid.getListGrid().setGroupByField(ResourceErrorsDataSource.ERROR_TYPE_ID);
+// errorsGrid.getListGrid().setGroupStartOpen(GroupStartOpen.ALL);
+// errorsGrid.getListGrid().setShowGroupSummary(true);
+
+ errorsGrid.setDataSource(new ResourceErrorsDataSource(resource.getId()));
+
+ //hide only works after we set the datasource
+ errorsGrid.getListGrid().hideField(ResourceErrorsDataSource.DETAIL_ID);
+
+ errorsGrid.getListGrid().addCellClickHandler(new CellClickHandler() {
+ public void onCellClick(CellClickEvent event) {
+ ListGridRecord record = event.getRecord();
+ final Window w = new Window();
+ w.setTitle("Error Details");
+ w.setIsModal(true);
+ w.setShowMinimizeButton(false);
+ w.setShowModalMask(true);
+ w.setWidth(640);
+ w.setHeight(480);
+ w.centerInPage();
+
+ VLayout layout = new VLayout(10);
+ layout.setLayoutAlign(Alignment.CENTER);
+ layout.setLayoutMargin(10);
+
+ w.addItem(layout);
+
+ HTMLPane details = new HTMLPane();
+ details.setContents("<pre>" + record.getAttribute(ResourceErrorsDataSource.DETAIL_ID) + "</pre>");
+ layout.addMember(details);
+
+ IButton ok = new IButton("Ok");
+ ok.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ w.destroy();
+ }
+ });
+ ok.setAlign(Alignment.CENTER);
+
+ layout.addMember(ok);
+
+ w.show();
}
-
- errorsGrid.setRecords(errorList.toArray(new ListGridRecord[errorList.size()]));
- }
-
- return errorsGrid;
+ });
+
+ addMember(errorsGrid);
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ResourceErrorsDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ResourceErrorsDataSource.java
new file mode 100644
index 0000000..4957fc7
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/ResourceErrorsDataSource.java
@@ -0,0 +1,100 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.summary;
+
+import java.util.Date;
+import java.util.List;
+
+import org.rhq.core.domain.resource.ResourceError;
+import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGWTServiceAsync;
+import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.data.DSRequest;
+import com.smartgwt.client.data.DSResponse;
+import com.smartgwt.client.data.fields.DataSourceDateField;
+import com.smartgwt.client.data.fields.DataSourceDateTimeField;
+import com.smartgwt.client.data.fields.DataSourceEnumField;
+import com.smartgwt.client.data.fields.DataSourceTextField;
+import com.smartgwt.client.rpc.RPCResponse;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+
+/**
+ *
+ * @author Lukas Krejci
+ */
+public class ResourceErrorsDataSource extends RPCDataSource<ResourceError> {
+
+ public static final String SUMMARY_ID = "summary";
+ public static final String DETAIL_ID = "detail";
+ public static final String ERROR_TYPE_ID = "errorType";
+ public static final String TIME_OCCURED_ID = "timeOccured";
+
+ ResourceGWTServiceAsync resourceService;
+ int resourceId;
+
+ public ResourceErrorsDataSource(int resourceId) {
+ resourceService = GWTServiceLookup.getResourceService();
+ this.resourceId = resourceId;
+
+ addFields(new DataSourceTextField(SUMMARY_ID, "Summary"),
+ new DataSourceTextField(DETAIL_ID, "Detailed Message"),
+ new DataSourceEnumField(ERROR_TYPE_ID, "Error Type"), new DataSourceDateTimeField(TIME_OCCURED_ID, "Time"));
+ }
+
+ /* (non-Javadoc)
+ * @see org.rhq.enterprise.gui.coregui.client.util.RPCDataSource#executeFetch(com.smartgwt.client.data.DSRequest, com.smartgwt.client.data.DSResponse)
+ */
+ @Override
+ protected void executeFetch(final DSRequest request, final DSResponse response) {
+ resourceService.findResourceErrors(resourceId, new AsyncCallback<List<ResourceError>>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError(
+ "Failed to find resource errors for resource with id: " + resourceId, caught);
+ response.setStatus(RPCResponse.STATUS_FAILURE);
+ processResponse(request.getRequestId(), response);
+ }
+
+ public void onSuccess(List<ResourceError> result) {
+ response.setData(buildRecords(result));
+ processResponse(request.getRequestId(), response);
+ };
+ });
+ }
+
+ public ResourceError copyValues(ListGridRecord from) {
+ //This is read-only datasource, so no need to implement this.
+ return null;
+ }
+
+ public ListGridRecord copyValues(ResourceError from) {
+ ListGridRecord record = new ListGridRecord();
+
+ record.setAttribute(DETAIL_ID, from.getDetail());
+ record.setAttribute(ERROR_TYPE_ID, from.getErrorType());
+ record.setAttribute(SUMMARY_ID, from.getSummary());
+ record.setAttribute(TIME_OCCURED_ID, new Date(from.getTimeOccurred()));
+
+ return record;
+ }
+
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
index 1b6f6cd..1ea9630 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
@@ -18,6 +18,7 @@
*/
package org.rhq.enterprise.gui.coregui.client.util;
+import java.util.Arrays;
import java.util.Collection;
import com.smartgwt.client.data.DSRequest;
@@ -176,4 +177,8 @@ public abstract class RPCDataSource<T> extends DataSource {
addField(field);
}
}
+
+ public void addFields(DataSourceField... fields) {
+ addFields(Arrays.asList(fields));
+ }
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
index c10254e..b933248 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
@@ -35,6 +35,7 @@ import org.rhq.core.domain.configuration.definition.ConfigurationTemplate;
import org.rhq.core.domain.criteria.ResourceCriteria;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.domain.resource.composite.RecentlyAddedResourceComposite;
import org.rhq.core.domain.resource.composite.ResourceComposite;
import org.rhq.core.domain.util.PageControl;
@@ -215,4 +216,8 @@ public class ResourceGWTServiceImpl extends AbstractGWTServiceImpl implements Re
discoveryBoss.unignoreResources(getSessionSubject(), resourceIds);
}
+ public List<ResourceError> findResourceErrors(int resourceId) {
+ return SerialUtility.prepare(resourceManager.findResourceErrors(getSessionSubject(), resourceId),
+ "ResourceService.getResourceErrors");
+ }
}
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index b773384..a480fb7 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -486,7 +486,7 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
private ResourceUpgradeResponse upgradeResource(@NotNull Resource resource, ResourceUpgradeRequest upgradeRequest, boolean allowGenericPropertiesUpgrade) {
if (upgradeRequest.getUpgradeErrorMessage() != null) {
ResourceError error = new ResourceError(resource, ResourceErrorType.UPGRADE, upgradeRequest.getUpgradeErrorMessage(), upgradeRequest.getUpgradeErrorStackTrace(), upgradeRequest.getTimestamp());
- entityManager.persist(error);
+ resourceManager.addResourceError(error);
return null;
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
index 5a4cf92..29672cc 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
@@ -1708,6 +1708,21 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
return query.getResultList();
}
+ @NotNull
+ @SuppressWarnings("unchecked")
+ public List<ResourceError> findResourceErrors(Subject user, int resourceId) {
+ // do authz check
+ if (!authorizationManager.canViewResource(user, resourceId)) {
+ throw new PermissionException("User [" + user + "] does not have permission to view resource ["
+ + resourceId + "]");
+ }
+
+ // we passed authz check, now get the errors
+ Query query = entityManager.createNamedQuery(ResourceError.QUERY_FIND_BY_RESOURCE_ID);
+ query.setParameter("resourceId", resourceId);
+ return query.getResultList();
+ }
+
public void addResourceError(ResourceError resourceError) {
Subject overlord = subjectManager.getOverlord();
Resource resource;
@@ -1718,9 +1733,10 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
}
if (resourceError.getErrorType() == ResourceErrorType.INVALID_PLUGIN_CONFIGURATION
- || resourceError.getErrorType() == ResourceErrorType.AVAILABILITY_CHECK) {
- // there should be at most one invalid plugin configuration error and one availability check error per
- // resource, so delete any currently existing ones before we add this new one
+ || resourceError.getErrorType() == ResourceErrorType.AVAILABILITY_CHECK
+ || resourceError.getErrorType() == ResourceErrorType.UPGRADE) {
+ // there should be at most one invalid plugin configuration error, availability check
+ // or upgrade error per resource, so delete any currently existing ones before we add this new one
List<ResourceError> doomedErrors = resource.getResourceErrors(resourceError.getErrorType());
// there should only ever be at most 1, but loop through the list just in case something got screwed up
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
index a2f26ff..b84a104 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
@@ -319,6 +319,17 @@ public interface ResourceManagerLocal {
List<ResourceError> findResourceErrors(Subject user, int resourceId, ResourceErrorType errorType);
/**
+ * Returns all the errors that have occurred for the given resource.
+ *
+ * @param user the user asking to see the errors
+ * @param resourceId the resource whose errors are to be returned
+ *
+ * @return the list of resource errors
+ */
+ @NotNull
+ List<ResourceError> findResourceErrors(Subject user, int resourceId);
+
+ /**
* Indicates an error occurred on a resource. The given error will be associated with the resource found in the
* error.
*
commit 4e8ae3349ff28b025741a1c3bb0d1a827c0feff8
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Aug 20 15:14:27 2010 +0200
first stab at the errors display GUI.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewForm.java
new file mode 100644
index 0000000..074b3c9
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewForm.java
@@ -0,0 +1,298 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.summary;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.EnumSet;
+import java.util.List;
+
+import org.rhq.core.domain.measurement.DataType;
+import org.rhq.core.domain.measurement.DisplayType;
+import org.rhq.core.domain.measurement.MeasurementDataTrait;
+import org.rhq.core.domain.measurement.MeasurementDefinition;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.resource.composite.ResourceComposite;
+import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.components.form.EnhancedDynamicForm;
+import org.rhq.enterprise.gui.coregui.client.components.form.TogglableTextItem;
+import org.rhq.enterprise.gui.coregui.client.components.form.ValueUpdatedHandler;
+import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGWTServiceAsync;
+import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
+import org.rhq.enterprise.gui.coregui.client.util.message.Message;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.util.SC;
+import com.smartgwt.client.widgets.form.fields.FormItem;
+import com.smartgwt.client.widgets.form.fields.HeaderItem;
+import com.smartgwt.client.widgets.form.fields.SpacerItem;
+import com.smartgwt.client.widgets.form.fields.StaticTextItem;
+
+/**
+ * The Resource Summary>Overview tab, the form with resource data.
+ *
+ * @author Greg Hinkle
+ * @author Ian Springer
+ */
+public class OverviewForm extends EnhancedDynamicForm {
+
+ private ResourceGWTServiceAsync resourceService = GWTServiceLookup.getResourceService();
+ private ResourceComposite resourceComposite;
+
+ public OverviewForm(ResourceComposite resourceComposite) {
+ this.resourceComposite = resourceComposite;
+ }
+
+ @Override
+ protected void onDraw() {
+ super.onDraw();
+
+ setLeft("10%");
+ setWidth("80%");
+
+ if (this.resourceComposite != null) {
+ setResource(this.resourceComposite);
+ }
+ }
+
+ public void setResource(ResourceComposite resourceComposite) {
+
+ this.resourceComposite = resourceComposite;
+ Resource resource = resourceComposite.getResource();
+
+ // Load metric defs.
+ ResourceTypeRepository.Cache.getInstance().getResourceTypes(resource.getResourceType().getId(),
+ EnumSet.of(ResourceTypeRepository.MetadataType.measurements),
+ new ResourceTypeRepository.TypeLoadedCallback() {
+ public void onTypesLoaded(ResourceType type) {
+ try {
+ buildForm(type);
+ loadTraitValues();
+ } catch (Exception e) {
+ SC.say("Form load failure");
+ e.printStackTrace();
+ }
+ }
+ });
+ }
+
+ private void loadTraitValues() {
+ final Resource resource = resourceComposite.getResource();
+ GWTServiceLookup.getMeasurementDataService().findCurrentTraitsForResource(
+ resource.getId(),
+ DisplayType.SUMMARY,
+ new AsyncCallback<List<MeasurementDataTrait>>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Failed to load traits for " + resource + ".",
+ caught);
+ }
+
+ public void onSuccess(List<MeasurementDataTrait> result) {
+ // TODO: Implement this method.
+ for (MeasurementDataTrait trait : result) {
+ String formId = trait.getName().replaceAll("\\.", "_").replaceAll(" ", "__");
+ FormItem item = getItem(formId);
+
+ if (item != null) {
+ setValue(formId, trait.getValue());
+ }
+ }
+ markForRedraw();
+ }
+ }
+ );
+
+ }
+
+ private void buildForm(ResourceType type) {
+ List<MeasurementDefinition> traits = new ArrayList<MeasurementDefinition>();
+
+ for (MeasurementDefinition measurement : type.getMetricDefinitions()) {
+ if (measurement.getDataType() == DataType.TRAIT && measurement.getDisplayType() == DisplayType.SUMMARY) {
+ traits.add(measurement);
+ }
+ }
+
+ Collections.sort(traits, new Comparator<MeasurementDefinition>() {
+ public int compare(MeasurementDefinition o1, MeasurementDefinition o2) {
+ return new Integer(o1.getDisplayOrder()).compareTo(o2.getDisplayOrder());
+ }
+ });
+
+ List<FormItem> formItems = new ArrayList<FormItem>();
+
+ HeaderItem headerItem = new HeaderItem("header", "Summary");
+ headerItem.setValue("Summary");
+ formItems.add(headerItem);
+
+ StaticTextItem typeItem = new StaticTextItem("type", "Type");
+ typeItem.setTooltip("Plugin: " + type.getPlugin() + "\n<br>" + "Type: " + type.getName());
+ typeItem.setValue(type.getName() + " (" + type.getPlugin() + ")");
+ formItems.add(typeItem);
+
+ final Resource resource = this.resourceComposite.getResource();
+ boolean modifiable = this.resourceComposite.getResourcePermission().isInventory();
+
+ final FormItem nameItem = (modifiable) ? new TogglableTextItem() : new StaticTextItem();
+ nameItem.setName("name");
+ nameItem.setTitle("Name");
+ nameItem.setValue(resource.getName());
+ if (nameItem instanceof TogglableTextItem) {
+ TogglableTextItem togglableNameItem = (TogglableTextItem) nameItem;
+ togglableNameItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
+ public void onValueUpdated(final String newName) {
+ final String oldName = resource.getName();
+ if (newName.equals(oldName)) {
+ return;
+ }
+ resource.setName(newName);
+ OverviewForm.this.resourceService.updateResource(resource, new AsyncCallback<Void>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Failed to change name of Resource with id "
+ + resource.getId()
+ + " from \"" + oldName + "\" to \"" + newName + "\".", caught);
+ // We failed to update it on the Server, so change back the Resource and the form item to
+ // the original value.
+ resource.setName(oldName);
+ nameItem.setValue(oldName);
+ }
+
+ public void onSuccess(Void result) {
+ CoreGUI.getMessageCenter().notify(new Message("Name of Resource with id "
+ + resource.getId() + " was changed from \""
+ + oldName + "\" to \"" + newName + "\".", Message.Severity.Info));
+ }
+ });
+ }
+ });
+ }
+ formItems.add(nameItem);
+
+ final FormItem descriptionItem = (modifiable) ? new TogglableTextItem() : new StaticTextItem();
+ descriptionItem.setName("description");
+ descriptionItem.setTitle("Description");
+ descriptionItem.setValue(resource.getDescription());
+ if (descriptionItem instanceof TogglableTextItem) {
+ TogglableTextItem togglableDescriptionItem = (TogglableTextItem) descriptionItem;
+ togglableDescriptionItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
+ public void onValueUpdated(final String newDescription) {
+ final String oldDescription = resource.getDescription();
+ if (newDescription.equals(oldDescription)) {
+ return;
+ }
+ resource.setDescription(newDescription);
+ OverviewForm.this.resourceService.updateResource(resource, new AsyncCallback<Void>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Failed to change description of Resource with id "
+ + resource.getId()
+ + " from \"" + oldDescription + "\" to \"" + newDescription + "\".", caught);
+ // We failed to update it on the Server, so change back the Resource and the form item to
+ // the original value.
+ resource.setDescription(oldDescription);
+ descriptionItem.setValue(oldDescription);
+ }
+
+ public void onSuccess(Void result) {
+ CoreGUI.getMessageCenter().notify(new Message("Description of Resource with id "
+ + resource.getId() + " was changed from \""
+ + oldDescription + "\" to \"" + newDescription + "\".", Message.Severity.Info));
+ }
+ });
+ }
+ });
+ }
+ formItems.add(descriptionItem);
+
+ final FormItem locationItem = (modifiable) ? new TogglableTextItem() : new StaticTextItem();
+ locationItem.setName("location");
+ locationItem.setTitle("Location");
+ locationItem.setValue(resource.getLocation());
+ if (locationItem instanceof TogglableTextItem) {
+ TogglableTextItem togglableNameItem = (TogglableTextItem) locationItem;
+ togglableNameItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
+ public void onValueUpdated(final String newLocation) {
+ final String oldLocation = resource.getLocation();
+ if (newLocation.equals(oldLocation)) {
+ return;
+ }
+ resource.setLocation(newLocation);
+ OverviewForm.this.resourceService.updateResource(resource, new AsyncCallback<Void>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Failed to change location of Resource with id "
+ + resource.getId()
+ + " from \"" + oldLocation + "\" to \"" + newLocation + "\".", caught);
+ // We failed to update it on the Server, so change back the Resource and the form item to
+ // the original value.
+ resource.setLocation(oldLocation);
+ locationItem.setValue(oldLocation);
+ }
+
+ public void onSuccess(Void result) {
+ CoreGUI.getMessageCenter().notify(new Message("Location of Resource with id "
+ + resource.getId() + " was changed from \""
+ + oldLocation + "\" to \"" + newLocation + "\".", Message.Severity.Info));
+ }
+ });
+ }
+ });
+ }
+ formItems.add(locationItem);
+
+
+ StaticTextItem versionItem = new StaticTextItem("version", "Version");
+ formItems.add(versionItem);
+
+ StaticTextItem parentItem = new StaticTextItem("parent", "Parent");
+ formItems.add(parentItem);
+
+ for (MeasurementDefinition trait : traits) {
+ String id = trait.getDisplayName().replaceAll("\\.", "_").replaceAll(" ", "__");
+
+ StaticTextItem item = new StaticTextItem(id, trait.getDisplayName());
+ item.setTooltip(trait.getDescription());
+ formItems.add(item);
+// item.setValue("?");
+ }
+
+// SectionItem section = new SectionItem("Summary", "Summary");
+// section.setTitle("Summary");
+// section.setDefaultValue("Summary");
+// section.setCanCollapse(true);
+// section.setCellStyle("HidablePlainSectionHeader");
+// section.setItemIds(itemIds.toArray(new String[itemIds.size()]));
+// formItems.add(0, section);
+
+ formItems.add(new SpacerItem());
+ setItems(formItems.toArray(new FormItem[formItems.size()]));
+
+ setValue("type", type.getName() + " (" + type.getPlugin() + ")");
+ setValue("name", resource.getName());
+ setValue("description", resource.getDescription());
+ setValue("location", resource.getLocation());
+ setValue("version", (resource.getVersion() != null) ? resource.getVersion() : "<i>none</i>");
+ Resource parentResource = resource.getParentResource();
+ setValue("parent", parentResource != null ?
+ ("<a href=\"#Resource/" + parentResource.getId() + "\">" +
+ parentResource.getName() + "</a>") : "<i>none</i>");
+ }
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
index ac2abc2..2fff538 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/summary/OverviewView.java
@@ -19,53 +19,35 @@
package org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.summary;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.EnumSet;
import java.util.List;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.smartgwt.client.util.SC;
-import com.smartgwt.client.widgets.form.fields.FormItem;
-import com.smartgwt.client.widgets.form.fields.HeaderItem;
-import com.smartgwt.client.widgets.form.fields.SpacerItem;
-import com.smartgwt.client.widgets.form.fields.StaticTextItem;
-
-import org.rhq.core.domain.measurement.DataType;
-import org.rhq.core.domain.measurement.DisplayType;
-import org.rhq.core.domain.measurement.MeasurementDataTrait;
-import org.rhq.core.domain.measurement.MeasurementDefinition;
import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.domain.resource.composite.ResourceComposite;
-import org.rhq.enterprise.gui.coregui.client.CoreGUI;
-import org.rhq.enterprise.gui.coregui.client.components.form.EnhancedDynamicForm;
-import org.rhq.enterprise.gui.coregui.client.components.form.TogglableTextItem;
-import org.rhq.enterprise.gui.coregui.client.components.form.ValueUpdatedHandler;
-import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
-import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGWTServiceAsync;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceSelectListener;
-import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
-import org.rhq.enterprise.gui.coregui.client.util.message.Message;
+
+import com.smartgwt.client.util.SC;
+import com.smartgwt.client.widgets.grid.ListGrid;
+import com.smartgwt.client.widgets.grid.ListGridField;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+import com.smartgwt.client.widgets.grid.events.RecordClickEvent;
+import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
+import com.smartgwt.client.widgets.layout.VLayout;
/**
* The Resource Summary>Overview tab.
*
- * @author Greg Hinkle
- * @author Ian Springer
+ * @author Lukas Krejci
*/
-public class OverviewView extends EnhancedDynamicForm implements ResourceSelectListener {
+public class OverviewView extends VLayout implements ResourceSelectListener {
- private ResourceGWTServiceAsync resourceService = GWTServiceLookup.getResourceService();
private ResourceComposite resourceComposite;
-
public OverviewView(ResourceComposite resourceComposite) {
super();
this.resourceComposite = resourceComposite;
}
-
@Override
protected void onDraw() {
super.onDraw();
@@ -78,225 +60,43 @@ public class OverviewView extends EnhancedDynamicForm implements ResourceSelectL
}
}
-
public void onResourceSelected(ResourceComposite resourceComposite) {
-
- this.resourceComposite = resourceComposite;
- Resource resource = resourceComposite.getResource();
-
- // Load metric defs.
- ResourceTypeRepository.Cache.getInstance().getResourceTypes(resource.getResourceType().getId(),
- EnumSet.of(ResourceTypeRepository.MetadataType.measurements),
- new ResourceTypeRepository.TypeLoadedCallback() {
- public void onTypesLoaded(ResourceType type) {
- try {
- buildForm(type);
- loadTraitValues();
- } catch (Exception e) {
- SC.say("Form load failure");
- e.printStackTrace();
- }
- }
- });
+ addMember(new OverviewForm(resourceComposite));
+ ListGrid errorsGrid = buildErrorListGrid(resourceComposite);
+ if (errorsGrid != null) {
+ addMember(errorsGrid);
+ }
}
- private void loadTraitValues() {
+ private static ListGrid buildErrorListGrid(ResourceComposite resourceComposite) {
final Resource resource = resourceComposite.getResource();
- GWTServiceLookup.getMeasurementDataService().findCurrentTraitsForResource(
- resource.getId(),
- DisplayType.SUMMARY,
- new AsyncCallback<List<MeasurementDataTrait>>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError("Failed to load traits for " + resource + ".",
- caught);
- }
-
- public void onSuccess(List<MeasurementDataTrait> result) {
- // TODO: Implement this method.
- for (MeasurementDataTrait trait : result) {
- String formId = trait.getName().replaceAll("\\.", "_").replaceAll(" ", "__");
- FormItem item = getItem(formId);
-
- if (item != null) {
- setValue(formId, trait.getValue());
- }
- }
- markForRedraw();
- }
- }
- );
-
- }
-
- private void buildForm(ResourceType type) {
- List<MeasurementDefinition> traits = new ArrayList<MeasurementDefinition>();
-
- for (MeasurementDefinition measurement : type.getMetricDefinitions()) {
- if (measurement.getDataType() == DataType.TRAIT && measurement.getDisplayType() == DisplayType.SUMMARY) {
- traits.add(measurement);
- }
- }
-
- Collections.sort(traits, new Comparator<MeasurementDefinition>() {
- public int compare(MeasurementDefinition o1, MeasurementDefinition o2) {
- return new Integer(o1.getDisplayOrder()).compareTo(o2.getDisplayOrder());
- }
- });
-
- List<FormItem> formItems = new ArrayList<FormItem>();
-
- HeaderItem headerItem = new HeaderItem("header", "Summary");
- headerItem.setValue("Summary");
- formItems.add(headerItem);
+ ListGrid errorsGrid = null;
+ if (resource.getResourceErrors() != null && resource.getResourceErrors().size() > 0) {
+ errorsGrid = new ListGrid();
- StaticTextItem typeItem = new StaticTextItem("type", "Type");
- typeItem.setTooltip("Plugin: " + type.getPlugin() + "\n<br>" + "Type: " + type.getName());
- typeItem.setValue(type.getName() + " (" + type.getPlugin() + ")");
- formItems.add(typeItem);
+ ListGridField summaryField = new ListGridField("summary", "Errors");
+ summaryField.addRecordClickHandler(new RecordClickHandler() {
- final Resource resource = this.resourceComposite.getResource();
- boolean modifiable = this.resourceComposite.getResourcePermission().isInventory();
-
- final FormItem nameItem = (modifiable) ? new TogglableTextItem() : new StaticTextItem();
- nameItem.setName("name");
- nameItem.setTitle("Name");
- nameItem.setValue(resource.getName());
- if (nameItem instanceof TogglableTextItem) {
- TogglableTextItem togglableNameItem = (TogglableTextItem) nameItem;
- togglableNameItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
- public void onValueUpdated(final String newName) {
- final String oldName = resource.getName();
- if (newName.equals(oldName)) {
- return;
- }
- resource.setName(newName);
- OverviewView.this.resourceService.updateResource(resource, new AsyncCallback<Void>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError("Failed to change name of Resource with id "
- + resource.getId()
- + " from \"" + oldName + "\" to \"" + newName + "\".", caught);
- // We failed to update it on the Server, so change back the Resource and the form item to
- // the original value.
- resource.setName(oldName);
- nameItem.setValue(oldName);
- }
-
- public void onSuccess(Void result) {
- CoreGUI.getMessageCenter().notify(new Message("Name of Resource with id "
- + resource.getId() + " was changed from \""
- + oldName + "\" to \"" + newName + "\".", Message.Severity.Info));
- }
- });
+ @Override
+ public void onRecordClick(RecordClickEvent event) {
+ String detail = event.getRecord().getAttribute("detail");
+ SC.say("Error details", detail);
}
});
- }
- formItems.add(nameItem);
-
- final FormItem descriptionItem = (modifiable) ? new TogglableTextItem() : new StaticTextItem();
- descriptionItem.setName("description");
- descriptionItem.setTitle("Description");
- descriptionItem.setValue(resource.getDescription());
- if (descriptionItem instanceof TogglableTextItem) {
- TogglableTextItem togglableDescriptionItem = (TogglableTextItem) descriptionItem;
- togglableDescriptionItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
- public void onValueUpdated(final String newDescription) {
- final String oldDescription = resource.getDescription();
- if (newDescription.equals(oldDescription)) {
- return;
- }
- resource.setDescription(newDescription);
- OverviewView.this.resourceService.updateResource(resource, new AsyncCallback<Void>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError("Failed to change description of Resource with id "
- + resource.getId()
- + " from \"" + oldDescription + "\" to \"" + newDescription + "\".", caught);
- // We failed to update it on the Server, so change back the Resource and the form item to
- // the original value.
- resource.setDescription(oldDescription);
- descriptionItem.setValue(oldDescription);
- }
-
- public void onSuccess(Void result) {
- CoreGUI.getMessageCenter().notify(new Message("Description of Resource with id "
- + resource.getId() + " was changed from \""
- + oldDescription + "\" to \"" + newDescription + "\".", Message.Severity.Info));
- }
- });
- }
- });
- }
- formItems.add(descriptionItem);
- final FormItem locationItem = (modifiable) ? new TogglableTextItem() : new StaticTextItem();
- locationItem.setName("location");
- locationItem.setTitle("Location");
- locationItem.setValue(resource.getLocation());
- if (locationItem instanceof TogglableTextItem) {
- TogglableTextItem togglableNameItem = (TogglableTextItem) locationItem;
- togglableNameItem.addValueUpdatedHandler(new ValueUpdatedHandler() {
- public void onValueUpdated(final String newLocation) {
- final String oldLocation = resource.getLocation();
- if (newLocation.equals(oldLocation)) {
- return;
- }
- resource.setLocation(newLocation);
- OverviewView.this.resourceService.updateResource(resource, new AsyncCallback<Void>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError("Failed to change location of Resource with id "
- + resource.getId()
- + " from \"" + oldLocation + "\" to \"" + newLocation + "\".", caught);
- // We failed to update it on the Server, so change back the Resource and the form item to
- // the original value.
- resource.setLocation(oldLocation);
- locationItem.setValue(oldLocation);
- }
+ errorsGrid.setFields(summaryField);
- public void onSuccess(Void result) {
- CoreGUI.getMessageCenter().notify(new Message("Location of Resource with id "
- + resource.getId() + " was changed from \""
- + oldLocation + "\" to \"" + newLocation + "\".", Message.Severity.Info));
- }
- });
- }
- });
- }
- formItems.add(locationItem);
-
-
- StaticTextItem versionItem = new StaticTextItem("version", "Version");
- formItems.add(versionItem);
-
- StaticTextItem parentItem = new StaticTextItem("parent", "Parent");
- formItems.add(parentItem);
-
- for (MeasurementDefinition trait : traits) {
- String id = trait.getDisplayName().replaceAll("\\.", "_").replaceAll(" ", "__");
+ List<ListGridRecord> errorList = new ArrayList<ListGridRecord>();
+ for (ResourceError error : resource.getResourceErrors()) {
+ ListGridRecord record = new ListGridRecord();
+ record.setAttribute("summary", error.getSummary());
+ record.setAttribute("detail", error.getDetail());
+ errorList.add(record);
+ }
- StaticTextItem item = new StaticTextItem(id, trait.getDisplayName());
- item.setTooltip(trait.getDescription());
- formItems.add(item);
-// item.setValue("?");
+ errorsGrid.setRecords(errorList.toArray(new ListGridRecord[errorList.size()]));
}
-// SectionItem section = new SectionItem("Summary", "Summary");
-// section.setTitle("Summary");
-// section.setDefaultValue("Summary");
-// section.setCanCollapse(true);
-// section.setCellStyle("HidablePlainSectionHeader");
-// section.setItemIds(itemIds.toArray(new String[itemIds.size()]));
-// formItems.add(0, section);
-
- formItems.add(new SpacerItem());
- setItems(formItems.toArray(new FormItem[formItems.size()]));
-
- setValue("type", type.getName() + " (" + type.getPlugin() + ")");
- setValue("name", resource.getName());
- setValue("description", resource.getDescription());
- setValue("location", resource.getLocation());
- setValue("version", (resource.getVersion() != null) ? resource.getVersion() : "<i>none</i>");
- Resource parentResource = resource.getParentResource();
- setValue("parent", parentResource != null ?
- ("<a href=\"#Resource/" + parentResource.getId() + "\">" +
- parentResource.getName() + "</a>") : "<i>none</i>");
+ return errorsGrid;
}
}
commit d266142e299215832de65b40be45e40862f56128
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Aug 20 15:14:04 2010 +0200
adding a test plugin that fails the upgrade so that we can add the tests for handling that scenario
diff --git a/modules/core/plugin-container/pom.xml b/modules/core/plugin-container/pom.xml
index 4b4524a..a4ca249 100644
--- a/modules/core/plugin-container/pom.xml
+++ b/modules/core/plugin-container/pom.xml
@@ -177,6 +177,12 @@
<jar destfile="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar">
<fileset dir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v2" includes="*.class,**/rhq-plugin.xml" />
</jar>
+ <copy toDir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/failing/META-INF">
+ <fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/failing/rhq-plugin.xml" />
+ </copy>
+ <jar destfile="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-3.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/failing" includes="*.class,**/rhq-plugin.xml" />
+ </jar>
</tasks>
</configuration>
<goals>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/DiscComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/DiscComponent.java
new file mode 100644
index 0000000..54153e6
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/DiscComponent.java
@@ -0,0 +1,54 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.core.pc.upgrade.plugins.failing;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
+import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
+
+/**
+ *
+ * @author Lukas Krejci
+ */
+public class DiscComponent implements ResourceDiscoveryComponent<ResourceComponent>,
+ ResourceUpgradeFacet<ResourceComponent> {
+
+ private static final String RESOURCE_KEY = "resource-key-failing";
+ private static final String RESOURCE_NAME = "resource-name-failing";
+ private static final String RESOURCE_DESCRIPTION = "resource-description-failing";
+
+ public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext<ResourceComponent> context)
+ throws InvalidPluginConfigurationException, Exception {
+ return Collections.singleton(new DiscoveredResourceDetails(context.getResourceType(), RESOURCE_KEY,
+ RESOURCE_NAME, null, RESOURCE_DESCRIPTION, context.getDefaultPluginConfiguration(), null));
+ }
+
+ public ResourceUpgradeReport upgrade(ResourceUpgradeContext<ResourceComponent> inventoriedResource) {
+ throw new RuntimeException("Failing the upgrade purposefully.");
+ }
+}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/ResComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/ResComponent.java
new file mode 100644
index 0000000..4c33adc
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/ResComponent.java
@@ -0,0 +1,46 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.core.pc.upgrade.plugins.failing;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
+
+/**
+ *
+ * @author Lukas Krejci
+ */
+public class ResComponent implements ResourceComponent<ResourceComponent> {
+ private static final Log log = LogFactory.getLog(ResComponent.class);
+
+ public AvailabilityType getAvailability() {
+ return AvailabilityType.UP;
+ }
+
+ public void start(ResourceContext<ResourceComponent> context) throws InvalidPluginConfigurationException, Exception {
+ log.info("~~~ starting the resource upgrade test failing component with resource key: " + context.getResourceKey());
+ }
+
+ public void stop() {
+ }
+}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/rhq-plugin.xml
new file mode 100644
index 0000000..9e750d1
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/failing/rhq-plugin.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeTest"
+ displayName="Resource Upgrade Test"
+ description="Resource Upgrade Test"
+ package="org.rhq.core.pc.upgrade.plugins.failing"
+ version="3.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <server name="Resource"
+ discovery="DiscComponent"
+ class="ResComponent"
+ singleton="true" />
+
+</plugin>
+
commit 6dde2f7be37f23a5e8a9b25ccf66e99541fd3bc7
Merge: d58520e... 462e15f...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Aug 20 12:50:39 2010 +0200
Merge branch 'master' into resource-upgrade
commit d58520e4a31ab38e03151e827488776d4dcca93f
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Aug 20 12:46:29 2010 +0200
Added agent and server side support for upgrade error reporting.
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
index f055e8c..9532920 100644
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
@@ -23,6 +23,9 @@
package org.rhq.core.clientapi.agent.upgrade;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
import org.rhq.core.domain.resource.ResourceUpgradeReport;
/**
@@ -34,44 +37,95 @@ public class ResourceUpgradeRequest extends ResourceUpgradeReport {
private static final long serialVersionUID = 1L;
- private int resourceId;
+ private final int resourceId;
+ private String upgradeErrorMessage;
+ private String upgradeErrorStackTrace;
+ private long timestamp;
- public ResourceUpgradeRequest() {
-
+ public ResourceUpgradeRequest(int resourceId) {
+ this.resourceId = resourceId;
}
public ResourceUpgradeRequest(int resourceId, ResourceUpgradeReport report) {
- setResourceId(resourceId);
- setNewDescription(report.getNewDescription());
- setNewName(report.getNewName());
- setNewResourceKey(report.getNewResourceKey());
+ this.resourceId = resourceId;
+ fillInFromReport(report);
}
-
+
public int getResourceId() {
return resourceId;
}
- public void setResourceId(int resourceId) {
- this.resourceId = resourceId;
+ public String getUpgradeErrorMessage() {
+ return upgradeErrorMessage;
+ }
+
+ public void setUpgradeErrorMessage(String upgradeErrorMessage) {
+ this.upgradeErrorMessage = upgradeErrorMessage;
+ }
+
+ public String getUpgradeErrorStackTrace() {
+ return upgradeErrorStackTrace;
+ }
+
+ public void setUpgradeErrorStackTrace(String upgradeErrorStackTrace) {
+ this.upgradeErrorStackTrace = upgradeErrorStackTrace;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
}
+ public void setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ public void setErrorProperties(Throwable t) {
+ upgradeErrorMessage = t.getMessage();
+
+ StringWriter string = new StringWriter();
+ PrintWriter w = new PrintWriter(string);
+ t.printStackTrace(w);
+ w.close();
+
+ upgradeErrorStackTrace = string.toString();
+ }
+
+ public void fillInFromReport(ResourceUpgradeReport report) {
+ setNewDescription(report.getNewDescription());
+ setNewName(report.getNewName());
+ setNewResourceKey(report.getNewResourceKey());
+ }
+
+ @Override
+ public boolean hasSomethingToUpgrade() {
+ return super.hasSomethingToUpgrade() || upgradeErrorMessage != null || upgradeErrorStackTrace != null;
+ }
+
@Override
public int hashCode() {
return 31 * resourceId;
}
-
+
@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}
-
+
if (!(other instanceof ResourceUpgradeRequest)) {
return false;
}
-
+
ResourceUpgradeRequest r = (ResourceUpgradeRequest) other;
-
+
return r.getResourceId() == resourceId;
}
+
+ @Override
+ public String toString() {
+ return "ResourceUpgradeRequest[resourceId = '" + resourceId + "', newResourceKey = '" + getNewResourceKey()
+ + "', newName = '" + getNewName() + "', newDescription = '" + getNewDescription()
+ + "', upgradeErrorMessage = '" + upgradeErrorMessage + "', upgradeErrorStackTrace = '"
+ + upgradeErrorStackTrace + "']";
+ }
}
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceErrorType.java b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceErrorType.java
index 1435cc3..8fcedb7 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceErrorType.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceErrorType.java
@@ -36,5 +36,10 @@ public enum ResourceErrorType {
/**
* An exception was thrown by the Resource component's getAvailablity() method the last time it was called.
*/
- AVAILABILITY_CHECK
+ AVAILABILITY_CHECK,
+
+ /**
+ * There was an attempt to upgrade the resource on the agent but it failed.
+ */
+ UPGRADE
}
\ No newline at end of file
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 728b2e3..3af9b84 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -1202,14 +1202,14 @@ public class InventoryManager extends AgentService implements ContainerService,
return resourceContainer.updateAvailability(availabilityType);
}
- public void mergeResourceFromUpgrade(Set<ResourceUpgradeRequest> upgradeReports) {
+ public void mergeResourceFromUpgrade(Set<ResourceUpgradeRequest> upgradeRequests) {
Set<ResourceUpgradeResponse> serverUpdates = null;
try {
ServerServices serverServices = this.configuration.getServerServices();
if (serverServices != null) {
DiscoveryServerService discoveryServerService = serverServices.getDiscoveryServerService();
- serverUpdates = discoveryServerService.upgradeResources(upgradeReports);
+ serverUpdates = discoveryServerService.upgradeResources(upgradeRequests);
}
} catch (Exception e) {
log.error("Failed to process resource upgrades on the server.", e);
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
index 5b33fe1..025ba3a 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
@@ -82,12 +82,10 @@ public class ResourceUpgradeDelegate {
* @return true if the resource was queued for upgrade, false otherwise
* @throws PluginContainerException on error
*/
- public boolean processAndQueue(ResourceContainer resourceContainer) throws PluginContainerException {
+ public void processAndQueue(ResourceContainer resourceContainer) throws PluginContainerException {
if (enabled) {
- return executeResourceUpgradeFacetAndStoreRequest(resourceContainer);
+ executeResourceUpgradeFacetAndStoreRequest(resourceContainer);
}
-
- return false;
}
public void sendRequests() {
@@ -100,7 +98,7 @@ public class ResourceUpgradeDelegate {
}
@SuppressWarnings("unchecked")
- private <T extends ResourceComponent> boolean executeResourceUpgradeFacetAndStoreRequest(
+ private <T extends ResourceComponent> void executeResourceUpgradeFacetAndStoreRequest(
ResourceContainer resourceContainer) throws PluginContainerException {
ResourceComponent<T> parentResourceComponent = resourceContainer.getResourceContext()
@@ -118,36 +116,47 @@ public class ResourceUpgradeDelegate {
if (!(discoveryComponent instanceof ResourceUpgradeFacet)) {
//well, there's no point in continuing if the resource doesn't support the facet
- return false;
+ return;
}
ResourceUpgradeContext<ResourceComponent<T>> upgradeContext = inventoryManager.createResourceUpgradeContext(
resource, parentResourceComponent, discoveryComponent);
- ResourceUpgradeReport upgradeReport;
+ ResourceUpgradeRequest request = new ResourceUpgradeRequest(resource.getId());
+
+ request.setTimestamp(System.currentTimeMillis());
+
+ ResourceUpgradeReport upgradeReport = null;
try {
upgradeReport = inventoryManager.invokeDiscoveryComponentResourceUpgradeFacet(resource.getResourceType(),
discoveryComponent, upgradeContext);
} catch (Throwable t) {
log.error("ResourceUpgradeFacet threw an exception while upgrading resource [" + resource + "]", t);
- return false;
+ request.setErrorProperties(t);
}
- if (upgradeReport == null || !upgradeReport.hasSomethingToUpgrade()) {
- return false;
- }
+ if (upgradeReport != null && upgradeReport.hasSomethingToUpgrade()) {
+ String upgradeErrors = null;
+ if ((upgradeErrors = checkUpgradeValid(resource, upgradeReport)) != null) {
+ String errorString = "Upgrading the resource [" + resource + "] using these updates [" + upgradeReport
+ + "] would render the inventory invalid because of the following reasons: " + upgradeErrors;
+
+ log.error(errorString);
+
+ IllegalStateException ex = new IllegalStateException(errorString);
+ ex.fillInStackTrace();
+
+ request.setErrorProperties(ex);
+ } else {
+ request.fillInFromReport(upgradeReport);
+ }
- String upgradeErrors = null;
- if ((upgradeErrors = checkUpgradeValid(resource, upgradeReport)) != null) {
- log.error("Upgrading the resource [" + resource + "] using these updates [" + upgradeReport
- + "] would render the inventory invalid because of the following reasons: " + upgradeErrors);
- return false;
}
//everything went ok, let's queue a upgrade request that will be sent to the server
- requests.add(new ResourceUpgradeRequest(resource.getId(), upgradeReport));
-
- return true;
+ if (request.hasSomethingToUpgrade()) {
+ requests.add(request);
+ }
}
private String checkUpgradeValid(Resource resource, ResourceUpgradeReport upgradeReport) {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index 304cbad..b773384 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -58,6 +58,8 @@ import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.ProductVersion;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceCategory;
+import org.rhq.core.domain.resource.ResourceError;
+import org.rhq.core.domain.resource.ResourceErrorType;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.domain.util.PageControl;
@@ -422,7 +424,9 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
Resource existingResource = this.entityManager.find(Resource.class, request.getResourceId());
if (existingResource != null) {
ResourceUpgradeResponse upgradedData = upgradeResource(existingResource, request, allowGenericPropertiesUpgrade);
- result.add(upgradedData);
+ if (upgradedData != null) {
+ result.add(upgradedData);
+ }
}
}
return result;
@@ -475,18 +479,24 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
/**
* @param existingResource
- * @param upgradeReport
+ * @param upgradeRequest
* @param allowGenericPropertiesUpgrade name and description are only upgraded if this is true
* @return true if the resource was changed, false otherwise
*/
- private ResourceUpgradeResponse upgradeResource(@NotNull Resource resource, ResourceUpgradeReport upgradeReport, boolean allowGenericPropertiesUpgrade) {
+ private ResourceUpgradeResponse upgradeResource(@NotNull Resource resource, ResourceUpgradeRequest upgradeRequest, boolean allowGenericPropertiesUpgrade) {
+ if (upgradeRequest.getUpgradeErrorMessage() != null) {
+ ResourceError error = new ResourceError(resource, ResourceErrorType.UPGRADE, upgradeRequest.getUpgradeErrorMessage(), upgradeRequest.getUpgradeErrorStackTrace(), upgradeRequest.getTimestamp());
+ entityManager.persist(error);
+ return null;
+ }
+
ResourceUpgradeResponse ret = new ResourceUpgradeResponse();
ret.setResourceId(resource.getId());
- String resourceKey = upgradeReport.getNewResourceKey();
- String name = upgradeReport.getNewName();
+ String resourceKey = upgradeRequest.getNewResourceKey();
+ String name = upgradeRequest.getNewName();
// String version = upgradeReport.getNewVersion();
- String description = upgradeReport.getNewDescription();
+ String description = upgradeRequest.getNewDescription();
// Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
// Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
commit 5b093893923a739ed2634c73e05392e917b8e7fb
Merge: 63d04ea... a13c17d...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Aug 11 16:43:07 2010 +0200
Merge branch 'master' into resource-upgrade
diff --cc modules/enterprise/gui/portal-war/src/main/webapp/admin/config/GeneralPropertiesConfigForm.jsp
index 136c37c,45526f7..0000000
deleted file mode 100644,100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/GeneralPropertiesConfigForm.jsp
+++ /dev/null
diff --cc modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index add8168,2773b4c..304cbad
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@@ -659,22 -559,10 +659,22 @@@ public class DiscoveryBossBean implemen
*/
ResourceType resourceType = resource.getResourceType();
Resource parent = resource;
+ Subject overlord = subjectManager.getOverlord();
while (parent != null && existingResource == null) {
parent = parent.getParentResource();
- existingResource = resourceManager.getResourceByParentAndKey(subjectManager.getOverlord(), parent,
+ //check if the parent itself is inventoried. This might not be the case
+ //during initial sync-up for resource upgrade.
+ Resource existingParent = null;
+ if (parent != null) {
+ existingParent = entityManager.find(Resource.class, parent.getId());
+ if (existingParent == null) {
+ //well, this parent is not known to the server, so there's no
+ //point in trying to find a child of it...
+ continue;
+ }
+ }
+ existingResource = resourceManager.getResourceByParentAndKey(overlord, existingParent,
- resource.getResourceKey(), resourceType.getPlugin(), resourceType.getName());
+ resource.getResourceKey(), resourceType.getPlugin(), resourceType.getName());
}
if (existingResource != null) {
@@@ -905,8 -808,4 +920,8 @@@
updateInventoryStatus(subject, platforms, servers, target);
}
-}
+
+ private static <T> boolean needsUpgrade(T oldValue, T newValue) {
+ return newValue != null && (oldValue == null || !newValue.equals(oldValue));
+ }
- }
++}
commit 63d04eaf7e697a241efe59832d7a4e127a084f92
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Jul 12 18:39:22 2010 +0200
Adding tests for graceful handling of server-side exceptions and platform "disappearance" on the server-side.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index a5c3d1f..6fe7e96 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -940,8 +940,16 @@ public class InventoryManager extends AgentService implements ContainerService,
//resource upgrade executor to sync up with the server side inventory *JUST AFTER*
//this agent registered with the server for the very first time. In that case
//the server hasn't received any info from us yet.
+ //Another (rare) scenario where this would happen would be when the platform resource type
+ //would change.
+ //In either case, let's sync up with the server - if it's got nothing, neither should the agent.
if (syncInfo != null) {
synchInventory(syncInfo);
+ } else {
+ purgeObsoleteResources(Collections.<String>emptySet());
+
+ //can't live without a platform, but we just deleted it. Let's rediscover it.
+ discoverPlatform();
}
return true;
@@ -1077,8 +1085,10 @@ public class InventoryManager extends AgentService implements ContainerService,
return;
}
boolean scan = removeResourceAndIndicateIfScanIsNeeded(resourceContainer.getResource());
-
- if (scan) {
+
+ //only actually schedule the scanning when we are finished with resource upgrade. The resource upgrade
+ //happens before any scanning infrastructure is established.
+ if (!resourceUpgradeDelegate.enabled() && scan) {
log.info("Deleted resource #[" + resourceId + "] - this will trigger a server scan now");
inventoryThreadPoolExecutor.submit((Callable<InventoryReport>) this.serverScanExecutor);
}
@@ -2612,14 +2622,13 @@ public class InventoryManager extends AgentService implements ContainerService,
ResourceContainer container = getResourceContainer(resource);
if (container != null) {
- try {
- container = getResourceContainer(resource);
- resourceUpgradeDelegate.processAndQueue(container);
- } catch (PluginContainerException e) {
- log.error("Exception thrown while upgrading [" + resource + "].");
- }
-
if (container.getResourceComponentState() == ResourceComponentState.STARTED) {
+ try {
+ resourceUpgradeDelegate.processAndQueue(container);
+ } catch (PluginContainerException e) {
+ log.error("Exception thrown while upgrading [" + resource + "].", e);
+ }
+
for (Resource child : resource.getChildResources()) {
upgradeResource(child);
}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
index c3bdbf4..19c1d95 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
@@ -56,7 +56,8 @@ public class FakeServerInventory {
private Resource platform;
private Map<String, Resource> resourceStore = new HashMap<String, Resource>();
private int counter;
-
+ private boolean failing;
+
private static final Comparator<Resource> ID_COMPARATOR = new Comparator<Resource>() {
public int compare(Resource o1, Resource o2) {
return o1.getId() - o2.getId();
@@ -69,11 +70,21 @@ public class FakeServerInventory {
}
};
+ public FakeServerInventory() {
+ this(false);
+ }
+
+ public FakeServerInventory(boolean failing) {
+ this.failing = failing;
+ }
+
//need to synchronize, because resource upgrade is async and can overlap with
//resource discovery.
public synchronized CustomAction mergeInventoryReport(final InventoryStatus requiredInventoryStatus) {
return new CustomAction("updateServerSideInventory") {
public Object invoke(Invocation invocation) throws Throwable {
+ throwIfFailing();
+
InventoryReport inventoryReport = (InventoryReport) invocation.getParameter(0);
for(Resource res : inventoryReport.getAddedRoots()) {
@@ -87,10 +98,24 @@ public class FakeServerInventory {
};
}
+ public synchronized CustomAction clearPlatform() {
+ return new CustomAction("updateServerSideInventory - report platform deleted on the server") {
+ public Object invoke(Invocation invocation) throws Throwable {
+ throwIfFailing();
+
+ platform = null;
+
+ return getSyncInfo();
+ }
+ };
+ }
+
public synchronized CustomAction upgradeResources() {
return new CustomAction("upgradeServerSideInventory") {
@SuppressWarnings({"serial", "unchecked"})
public Object invoke(Invocation invocation) throws Throwable {
+ throwIfFailing();
+
Set<ResourceUpgradeRequest> requests = (Set<ResourceUpgradeRequest>) invocation.getParameter(0);
Set<ResourceUpgradeResponse> responses = new HashSet<ResourceUpgradeResponse>();
@@ -129,6 +154,8 @@ public class FakeServerInventory {
return new CustomAction("getResources") {
@SuppressWarnings("unchecked")
public Object invoke(Invocation invocation) throws Throwable {
+ throwIfFailing();
+
Set<Integer> resourceIds = (Set<Integer>)invocation.getParameter(0);
boolean includeDescendants = (Boolean) invocation.getParameter(1);
@@ -137,6 +164,14 @@ public class FakeServerInventory {
};
}
+ public boolean isFailing() {
+ return failing;
+ }
+
+ public void setFailing(boolean failing) {
+ this.failing = failing;
+ }
+
@SuppressWarnings("serial")
public synchronized Set<Resource> findResourcesByType(final ResourceType type) {
Set<Resource> result = new HashSet<Resource>();
@@ -218,6 +253,12 @@ public class FakeServerInventory {
return platform != null ? convert(platform) : null;
}
+ private void throwIfFailing() {
+ if (failing) {
+ throw new RuntimeException("Fake server inventory is in the failing mode.");
+ }
+ }
+
private static ResourceSyncInfo convert(Resource root) {
try {
ResourceSyncInfo ret = new ResourceSyncInfo();
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index b5d571f..202e0c0 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -25,6 +25,7 @@ package org.rhq.core.pc.upgrade;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
import java.io.File;
import java.io.IOException;
@@ -151,11 +152,83 @@ public class ResourceUpgradeTest {
}
@Test
- public void testRecoveryWithServerUnavailable() throws Exception {
- //TODO implement
+ public void testSkipUpgradeWhenServerUnavailable() throws Exception {
+ currentServerSideInventory = new FakeServerInventory();
+ initialSyncAndDiscovery(InventoryStatus.COMMITTED);
+
+ currentServerSideInventory.setFailing(true);
+
+ TestPayload test = new TestPayload() {
+ public void test(Resource discoveredResource) {
+ assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
+ assertEquals(discoveredResource.getName(), "resource-name-v1");
+ assertEquals(discoveredResource.getDescription(), "resource-description-v1");
+ }
+
+ @SuppressWarnings("unchecked")
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+
+ between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+
+ never(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
+ }
+ };
+ }
+ };
+
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, test);
+ }
+
+ @Test
+ public void testUpgradeWithPlatformDeletedOnServer() throws Exception {
+ currentServerSideInventory = new FakeServerInventory();
+ initialSyncAndDiscovery(InventoryStatus.COMMITTED);
+
+ TestPayload test = new TestPayload() {
+ public void test(Resource discoveredResource) {
+ assertEquals(discoveredResource.getResourceKey(), "resource-key-v2");
+ assertEquals(discoveredResource.getName(), "resource-name-v2");
+ assertEquals(discoveredResource.getDescription(), "resource-description-v2");
+
+ ResourceContainer container = PluginContainer.getInstance().getInventoryManager().getResourceContainer(discoveredResource);
+ File dataDir = container.getResourceContext().getDataDirectory();
+
+ File marker = new File(dataDir, "upgrade-succeeded");
+
+ assertFalse(marker.exists(), "The upgrade seems to have occured even though there shouldn't have been a resource to upgrade.");
+ }
+
+ @SuppressWarnings("unchecked")
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+
+ //the first merge will be triggered from within the upgrade process and we are
+ //going to report null sync.
+ oneOf(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(currentServerSideInventory.clearPlatform());
+
+ //the rest of the inventory merges are executed by discoveries, so let's import the
+ //discovered stuff into the server-side inventory.
+ between(1, 3).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+
+ never(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
+ }
+ };
+ }
+ };
+
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, test);
}
private void initialSyncAndDiscovery(final InventoryStatus requiredInventoryStatus) throws Exception {
+ cleanDataDir();
executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), true, new TestPayload() {
public void test(Resource discoveredResource) {
assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
@@ -303,40 +376,43 @@ public class ResourceUpgradeTest {
for(String pluginResourcePath : pluginResourcePaths) {
copyPlugin(pluginResourcePath, pluginDir);
}
-
+
Mockery context = new Mockery();
-
+
PluginContainerConfiguration pcConfig = createPluginContainerConfiguration(context);
-
+
if (clearInventoryDat) {
File inventoryDat = new File(pcConfig.getDataDirectory(), "inventory.dat");
inventoryDat.delete();
}
-
+
context.checking(test.getExpectations(context));
-
+
PluginContainer.getInstance().setConfiguration(pcConfig);
PluginContainer.getInstance().initialize();
-
- //give the pc the time to finish resource upgrade
- Thread.sleep(1000);
-
- //execute full discovery
- InventoryManager im = PluginContainer.getInstance().getInventoryManager();
- im.executeServerScanImmediately();
- im.executeServiceScanImmediately();
-
- Set<Resource> resources = getTestingResources();
-
- assertEquals(resources.size(), 1, "There should be only a single testing resource but " + resources + " were found.");
-
- Resource discoveredResource = resources.iterator().next();
-
- test.test(discoveredResource);
-
- PluginContainer.getInstance().shutdown();
-
- context.assertIsSatisfied();
+
+ try {
+ //give the pc the time to finish resource upgrade
+ Thread.sleep(1000);
+
+ //execute full discovery
+ InventoryManager im = PluginContainer.getInstance().getInventoryManager();
+ im.executeServerScanImmediately();
+ im.executeServiceScanImmediately();
+
+ Set<Resource> resources = getTestingResources();
+
+ assertEquals(resources.size(), 1, "There should be only a single testing resource but " + resources
+ + " were found.");
+
+ Resource discoveredResource = resources.iterator().next();
+
+ test.test(discoveredResource);
+
+ context.assertIsSatisfied();
+ } finally {
+ PluginContainer.getInstance().shutdown();
+ }
}
@SuppressWarnings("unchecked")
@@ -356,4 +432,8 @@ public class ResourceUpgradeTest {
expectations.allowing(currentDiscoveryServerService).getResources(expectations.with(Expectations.any(Set.class)), expectations.with(Expectations.any(boolean.class)));
expectations.will(currentServerSideInventory.getResources());
}
+
+ private void cleanDataDir() throws IOException {
+ FileUtils.cleanDirectory(new File(tmpDir, DATA_DIR_NAME));
+ }
}
commit 178d4de9fb18d7f9045e673e64c33a359436be81
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Jul 6 19:12:26 2010 -0400
generate the two resource upgrade test plugins rather than have the .jar files committed directly to git
this way we can see the source and change it if we ever need to.
also allows us to have source to step through in a debugger
diff --git a/modules/core/plugin-container/pom.xml b/modules/core/plugin-container/pom.xml
index 2e58102..93f64cf 100644
--- a/modules/core/plugin-container/pom.xml
+++ b/modules/core/plugin-container/pom.xml
@@ -126,6 +126,7 @@
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
+ <id>process-test-resources</id>
<phase>process-test-resources</phase>
<configuration>
<tasks>
@@ -151,7 +152,31 @@
<include name="**/lib/*" />
</fileset>
</move>
- <delete dir="${project.build.directory}/jboss-sigar/hyperic-sigar-${sigar.version}" />
+ <delete dir="${project.build.directory}/jboss-sigar/hyperic-sigar-${sigar.version}" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>process-test-classes</id>
+ <phase>process-test-classes</phase>
+ <configuration>
+ <tasks>
+ <echo>Assembling the two resource upgrade test plugins</echo>
+ <copy toDir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v1/META-INF">
+ <fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/v1/rhq-plugin.xml" />
+ </copy>
+ <jar destfile="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-1.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v1" includes="*.class,**/rhq-plugin.xml" />
+ </jar>
+ <copy toDir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v2/META-INF">
+ <fileset file="${project.build.testSourceDirectory}/org/rhq/core/pc/upgrade/plugins/v2/rhq-plugin.xml" />
+ </copy>
+ <jar destfile="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar">
+ <fileset dir="${project.build.testOutputDirectory}/org/rhq/core/pc/upgrade/plugins/v2" includes="*.class,**/rhq-plugin.xml" />
+ </jar>
</tasks>
</configuration>
<goals>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/DiscComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/DiscComponent.java
new file mode 100644
index 0000000..5fbca32
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/DiscComponent.java
@@ -0,0 +1,22 @@
+package org.rhq.core.pc.upgrade.plugins.v1;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+
+public class DiscComponent implements ResourceDiscoveryComponent<ResourceComponent> {
+ private static final String RESOURCE_KEY = "resource-key-v1";
+ private static final String RESOURCE_NAME = "resource-name-v1";
+ private static final String RESOURCE_DESCRIPTION = "resource-description-v1";
+
+ public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext<ResourceComponent> context)
+ throws InvalidPluginConfigurationException, Exception {
+ return Collections.singleton(new DiscoveredResourceDetails(context.getResourceType(), RESOURCE_KEY,
+ RESOURCE_NAME, null, RESOURCE_DESCRIPTION, context.getDefaultPluginConfiguration(), null));
+ }
+}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/ResComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/ResComponent.java
new file mode 100644
index 0000000..cc21fc3
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/ResComponent.java
@@ -0,0 +1,21 @@
+package org.rhq.core.pc.upgrade.plugins.v1;
+
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
+
+public class ResComponent implements ResourceComponent<ResourceComponent> {
+ public AvailabilityType getAvailability() {
+ return AvailabilityType.UP;
+ }
+
+ public void start(ResourceContext<ResourceComponent> context) {
+ LogFactory.getLog(this.getClass()).info(
+ "~~~ Starting resource upgrade test plugin v1 component: key=" + context.getResourceKey());
+ }
+
+ public void stop() {
+ }
+}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/rhq-plugin.xml
new file mode 100644
index 0000000..c658e0c
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v1/rhq-plugin.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeTest"
+ displayName="Resource Upgrade Test"
+ description="Resource Upgrade Test"
+ package="org.rhq.core.pc.upgrade.plugins.v1"
+ version="1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <server name="Resource"
+ discovery="DiscComponent"
+ class="ResComponent"
+ singleton="true" />
+
+</plugin>
+
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/DiscComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/DiscComponent.java
new file mode 100644
index 0000000..d113d1c
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/DiscComponent.java
@@ -0,0 +1,54 @@
+package org.rhq.core.pc.upgrade.plugins.v2;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Set;
+
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
+import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
+
+public class DiscComponent implements ResourceDiscoveryComponent<ResourceComponent>,
+ ResourceUpgradeFacet<ResourceComponent> {
+ private static final String V1_RESOURCE_KEY = "resource-key-v1";
+ private static final String RESOURCE_KEY = "resource-key-v2";
+ private static final String RESOURCE_NAME = "resource-name-v2";
+ private static final String RESOURCE_DESCRIPTION = "resource-description-v2";
+
+ public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext<ResourceComponent> context)
+ throws InvalidPluginConfigurationException, Exception {
+ return Collections.singleton(new DiscoveredResourceDetails(context.getResourceType(), RESOURCE_KEY,
+ RESOURCE_NAME, null, RESOURCE_DESCRIPTION, context.getDefaultPluginConfiguration(), null));
+ }
+
+ public ResourceUpgradeReport upgrade(ResourceUpgradeContext<ResourceComponent> inventoriedResource) {
+ if (V1_RESOURCE_KEY.equals(inventoriedResource.getResourceKey())) {
+ ResourceUpgradeReport report = new ResourceUpgradeReport();
+ report.setNewResourceKey(RESOURCE_KEY);
+ report.setNewName(RESOURCE_NAME);
+ report.setNewDescription(RESOURCE_DESCRIPTION);
+
+ File dataDir = inventoriedResource.getDataDirectory();
+
+ if (dataDir != null) {
+ if (!(dataDir.exists())) {
+ dataDir.mkdir();
+ }
+ File marker = new File(dataDir, "upgrade-succeeded");
+ try {
+ marker.createNewFile();
+ } catch (IOException localIOException) {
+ }
+ }
+ return report;
+ }
+
+ return null;
+ }
+}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/ResComponent.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/ResComponent.java
new file mode 100644
index 0000000..83144b2
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/ResComponent.java
@@ -0,0 +1,21 @@
+package org.rhq.core.pc.upgrade.plugins.v2;
+
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
+
+public class ResComponent implements ResourceComponent<ResourceComponent> {
+ public AvailabilityType getAvailability() {
+ return AvailabilityType.UP;
+ }
+
+ public void start(ResourceContext<ResourceComponent> context) {
+ LogFactory.getLog(this.getClass()).info(
+ "~~~ Starting resource upgrade test plugin v2 component: key=" + context.getResourceKey());
+ }
+
+ public void stop() {
+ }
+}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/rhq-plugin.xml b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/rhq-plugin.xml
new file mode 100644
index 0000000..9f63892
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/plugins/v2/rhq-plugin.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin name="ResourceUpgradeTest"
+ displayName="Resource Upgrade Test"
+ description="Resource Upgrade Test"
+ package="org.rhq.core.pc.upgrade.plugins.v2"
+ version="2.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <server name="Resource"
+ discovery="DiscComponent"
+ class="ResComponent"
+ singleton="true" />
+
+</plugin>
+
diff --git a/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-1.0.0.jar b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-1.0.0.jar
deleted file mode 100644
index 33a79c0..0000000
Binary files a/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-1.0.0.jar and /dev/null differ
diff --git a/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar
deleted file mode 100644
index 7ffc5bb..0000000
Binary files a/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar and /dev/null differ
commit 9edde408d4dbabbc057e5e11fdfb6c3c16d2936e
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Jul 6 16:11:44 2010 -0400
trivial - reformat some things. no need to use isDebugEnabled if you are logging a simple string message with no string concatentation
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 5786702..a5c3d1f 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -72,8 +72,8 @@ import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceCreationDataType;
import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.domain.resource.ResourceErrorType;
-import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.pc.ContainerService;
import org.rhq.core.pc.PluginContainer;
import org.rhq.core.pc.PluginContainerConfiguration;
@@ -193,7 +193,7 @@ public class InventoryManager extends AgentService implements ContainerService,
* Handles the resource upgrade during the initialization of the inventory manager.
*/
private ResourceUpgradeDelegate resourceUpgradeDelegate;
-
+
public InventoryManager() {
super(DiscoveryAgentService.class);
}
@@ -224,7 +224,7 @@ public class InventoryManager extends AgentService implements ContainerService,
//discoveries.
resourceUpgradeDelegate = new ResourceUpgradeDelegate(this);
upgradeResources();
-
+
availabilityCollectors = new AvailabilityCollectorThreadPool();
availabilityCollectors.initialize();
@@ -300,7 +300,7 @@ public class InventoryManager extends AgentService implements ContainerService,
return results;
} catch (TimeoutException te) {
log.warn("Discovery for Resources of [" + context.getResourceType() + "] has been running for more than "
- + timeout + " milliseconds. This may be a plugin bug.", te);
+ + timeout + " milliseconds. This may be a plugin bug.", te);
return null;
} catch (BlacklistedException be) {
// Discovery did not run, because the ResourceType was blacklisted during a prior discovery scan.
@@ -333,8 +333,8 @@ public class InventoryManager extends AgentService implements ContainerService,
return result;
} catch (TimeoutException te) {
log.warn("Manual add of Resource of type [" + context.getResourceType() + "] with plugin configuration ["
- + pluginConfig.toString(true) + "] has been running for more than "
- + timeout + " milliseconds. This may be a plugin bug.", te);
+ + pluginConfig.toString(true) + "] has been running for more than " + timeout
+ + " milliseconds. This may be a plugin bug.", te);
return null;
} catch (BlacklistedException be) {
log.debug(ThrowableUtil.getAllMessages(be));
@@ -382,11 +382,12 @@ public class InventoryManager extends AgentService implements ContainerService,
public <T extends ResourceComponent> ResourceUpgradeReport invokeDiscoveryComponentResourceUpgradeFacet(
ResourceType resourceType, ResourceDiscoveryComponent<T> component,
ResourceUpgradeContext<T> inventoriedResource) throws Throwable {
-
+
long timeout = getDiscoveryComponentTimeout(resourceType);
try {
@SuppressWarnings("unchecked")
- ResourceUpgradeFacet<T> proxy = this.discoveryComponentProxyFactory.getDiscoveryComponentProxy(resourceType, component, timeout, ResourceUpgradeFacet.class);
+ ResourceUpgradeFacet<T> proxy = this.discoveryComponentProxyFactory.getDiscoveryComponentProxy(
+ resourceType, component, timeout, ResourceUpgradeFacet.class);
return proxy.upgrade(inventoriedResource);
} catch (BlacklistedException e) {
@@ -394,7 +395,7 @@ public class InventoryManager extends AgentService implements ContainerService,
return null;
}
}
-
+
public DiscoveryComponentProxyFactory getDiscoveryComponentProxyFactory() {
return this.discoveryComponentProxyFactory;
}
@@ -892,7 +893,7 @@ public class InventoryManager extends AgentService implements ContainerService,
public boolean handleReport(InventoryReport report) {
return handleReport(report, false);
}
-
+
/**
* Send an inventory report to the Server.
*
@@ -904,7 +905,7 @@ public class InventoryManager extends AgentService implements ContainerService,
if (!configuration.isInsideAgent()) {
return true;
}
-
+
if (report.getAddedRoots().isEmpty() && !forceServerRoundtrip) {
return true; // nothing to do
}
@@ -981,7 +982,7 @@ public class InventoryManager extends AgentService implements ContainerService,
log.debug(String.format("DONE syncing local inventory [%d] ms.",
(System.currentTimeMillis() - startTime)));
}
-
+
// If we synced any Resources, one or more Resource components were probably started,
// so run an avail check to report on their availabilities immediately. Also kick off
// a service scan to scan those Resources for new child Resources. Kick both tasks off
@@ -991,7 +992,8 @@ public class InventoryManager extends AgentService implements ContainerService,
// inventory with the server side as well as to disallow any other server-agent traffic during
// the upgrade phase. Not to mention the fact that no thread pools are initialized yet by the
// time the upgrade kicks in..
- if (!resourceUpgradeDelegate.enabled() && (!syncedResources.isEmpty() || !unknownResourceIds.isEmpty() || !modifiedResourceIds.isEmpty())) {
+ if (!resourceUpgradeDelegate.enabled()
+ && (!syncedResources.isEmpty() || !unknownResourceIds.isEmpty() || !modifiedResourceIds.isEmpty())) {
performAvailabilityChecks(true);
this.inventoryThreadPoolExecutor.schedule((Callable<? extends Object>) this.serviceScanExecutor, 5,
TimeUnit.SECONDS);
@@ -1003,7 +1005,7 @@ public class InventoryManager extends AgentService implements ContainerService,
throw new RuntimeException(t);
}
}
-
+
private void getAllUuids(ResourceSyncInfo syncInfo, Set<String> allServerSideUuids) {
allServerSideUuids.add(syncInfo.getUuid());
for (ResourceSyncInfo child : syncInfo.getChildSyncInfos()) {
@@ -1181,13 +1183,13 @@ public class InventoryManager extends AgentService implements ContainerService,
ServerServices serverServices = this.configuration.getServerServices();
if (serverServices != null) {
DiscoveryServerService discoveryServerService = serverServices.getDiscoveryServerService();
-
+
serverUpdates = discoveryServerService.upgradeResources(upgradeReports);
}
} catch (Exception e) {
log.error("Failed to process resource upgrades on the server.", e);
}
-
+
if (serverUpdates != null) {
for (ResourceUpgradeResponse upgradeResponse : serverUpdates) {
String resourceKey = upgradeResponse.getUpgradedResourceKey();
@@ -1202,49 +1204,50 @@ public class InventoryManager extends AgentService implements ContainerService,
ResourceContainer existingResourceContainer = getResourceContainer(upgradeResponse.getResourceId());
if (existingResourceContainer != null) {
Resource existingResource = existingResourceContainer.getResource();
-
- StringBuilder logMessage = new StringBuilder("Resource [")
- .append(existingResource.toString()).append("] upgraded its ");
-
+
+ StringBuilder logMessage = new StringBuilder("Resource [").append(existingResource.toString())
+ .append("] upgraded its ");
+
if (resourceKey != null) {
existingResource.setResourceKey(resourceKey);
logMessage.append("resourceKey, ");
}
-
+
if (name != null) {
existingResource.setName(name);
logMessage.append("name, ");
}
-
-// if (version != null) {
-// existingResource.setVersion(version);
-// }
-
+
+ //if (version != null) {
+ // existingResource.setVersion(version);
+ //}
+
if (description != null) {
existingResource.setDescription(description);
logMessage.append("description, ");
}
-
-// if (pluginConfiguration != null) {
-// existingResource.setPluginConfiguration(pluginConfiguration);
-// }
-//
-// if (resourceConfiguration != null) {
-// existingResource.setResourceConfiguration(resourceConfiguration);
-// }
-
- logMessage.replace(logMessage.length() - 1, logMessage.length(),
- "to become [").append(existingResource.toString()).append("]");
-
+
+ //if (pluginConfiguration != null) {
+ // existingResource.setPluginConfiguration(pluginConfiguration);
+ //}
+ //
+ //if (resourceConfiguration != null) {
+ // existingResource.setResourceConfiguration(resourceConfiguration);
+ //}
+
+ logMessage.replace(logMessage.length() - 1, logMessage.length(), "to become [").append(
+ existingResource.toString()).append("]");
+
log.info(logMessage.toString());
} else {
- log.error("Upgraded a resource that is not present on the agent. This should not happen. The id of the missing resource is " + upgradeResponse.getResourceId());
+ log.error("Upgraded a resource that is not present on the agent. This should not happen. "
+ + "The id of the missing resource is: " + upgradeResponse.getResourceId());
}
}
}
}
}
-
+
public Resource mergeResourceFromDiscovery(Resource resource, Resource parent) throws PluginContainerException {
// If the Resource is already in inventory, make sure its version is up-to-date, then simply return the
// existing Resource.
@@ -1466,7 +1469,7 @@ public class InventoryManager extends AgentService implements ContainerService,
}
ResourceContext context = createResourceContext(resource, parentComponent, discoveryComponent);
-
+
container.setResourceContext(context);
// Wrap the component in a proxy that will provide locking and a timeout for the call to start().
@@ -1513,7 +1516,8 @@ public class InventoryManager extends AgentService implements ContainerService,
}
}
- private <T extends ResourceComponent> ResourceContext<T> createResourceContext(Resource resource, T parentComponent, ResourceDiscoveryComponent<T> discoveryComponent) {
+ private <T extends ResourceComponent> ResourceContext<T> createResourceContext(Resource resource,
+ T parentComponent, ResourceDiscoveryComponent<T> discoveryComponent) {
File pluginDataDir = new File(this.configuration.getDataDirectory(), resource.getResourceType().getPlugin());
return new ResourceContext<T>(resource, // the resource itself
@@ -1529,8 +1533,9 @@ public class InventoryManager extends AgentService implements ContainerService,
this.availabilityCollectors, // for components that want to perform async avail checking
this.configuration.getPluginContainerDeployment()); // helps components make determinations of what to do
}
-
- public <T extends ResourceComponent> ResourceUpgradeContext<T> createResourceUpgradeContext(Resource resource, T parentComponent, ResourceDiscoveryComponent<T> discoveryComponent) {
+
+ public <T extends ResourceComponent> ResourceUpgradeContext<T> createResourceUpgradeContext(Resource resource,
+ T parentComponent, ResourceDiscoveryComponent<T> discoveryComponent) {
File pluginDataDir = new File(this.configuration.getDataDirectory(), resource.getResourceType().getPlugin());
return new ResourceUpgradeContext<T>(resource, // the resource itself
@@ -1546,7 +1551,7 @@ public class InventoryManager extends AgentService implements ContainerService,
this.availabilityCollectors, // for components that want to perform async avail checking
this.configuration.getPluginContainerDeployment()); // helps components make determinations of what to do
}
-
+
/**
* This will send a resource error to the server (if applicable) to indicate that the given resource could not be
* connected to due to an invalid plugin configuration.
@@ -1789,13 +1794,13 @@ public class InventoryManager extends AgentService implements ContainerService,
Set<DiscoveredResourceDetails> allDiscoveredPlatforms = new HashSet<DiscoveredResourceDetails>(2);
if ((platformTypes != null) && (platformTypes.size() > 0)) {
-
+
//check for fake testing type. If the test platform type is being used, it is always going to be
//the sole platform type available.
if (platformTypes.size() == 1 && platformTypes.contains(PluginMetadataManager.TEST_PLATFORM_TYPE)) {
return getTestPlatform();
}
-
+
// Go through all the platform types that are supported and see if they can detect our platform.
for (ResourceType platformType : platformTypes) {
try {
@@ -2123,11 +2128,11 @@ public class InventoryManager extends AgentService implements ContainerService,
@NotNull
Set<Resource> executeComponentDiscovery(ResourceType resourceType, ResourceDiscoveryComponent discoveryComponent,
ResourceContainer parentContainer, List<ProcessScanResult> processScanResults) {
-
+
ResourceContext parentResourceContext = parentContainer.getResourceContext();
ResourceComponent parentComponent = parentContainer.getResourceComponent();
Resource parentResource = parentContainer.getResource();
-
+
long startTime = System.currentTimeMillis();
log.debug("Executing discovery for [" + resourceType.getName() + "] Resources...");
Set<Resource> newResources;
@@ -2578,9 +2583,7 @@ public class InventoryManager extends AgentService implements ContainerService,
private void upgradeResources() {
try {
- if (log.isDebugEnabled()) {
- log.debug("Executing resource upgrade.");
- }
+ log.debug("Executing resource upgrade.");
boolean syncResult = handleReport(new InventoryReport(getAgent()), true);
if (!syncResult) {
@@ -2590,27 +2593,23 @@ public class InventoryManager extends AgentService implements ContainerService,
upgradeResource(getPlatform());
- if (log.isDebugEnabled()) {
- log.debug("Sending the upgrade requests to the server.");
- }
+ log.debug("Sending the upgrade requests to the server.");
resourceUpgradeDelegate.sendRequests();
resourceUpgradeDelegate.disable();
- if (log.isDebugEnabled()) {
- log.debug("Resource upgrade finished.");
- }
+ log.debug("Resource upgrade finished.");
} catch (Throwable t) {
log.error("Resource upgrade failed with an exception.", t);
}
}
-
+
private void upgradeResource(Resource resource) {
//only process committed resources
if (resource.getInventoryStatus() != InventoryStatus.COMMITTED) {
return;
}
-
+
ResourceContainer container = getResourceContainer(resource);
if (container != null) {
try {
@@ -2625,14 +2624,15 @@ public class InventoryManager extends AgentService implements ContainerService,
upgradeResource(child);
}
} else {
- log.error("The resource container for resource [" + resource + "] wasn't started during upgrade. This should not happen.");
- }
+ log.error("The resource container for resource [" + resource
+ + "] wasn't started during upgrade. This should not happen.");
+ }
} else {
log.error("Resource container not initialized for resource [" + resource
+ "] during upgrade. This should not happen.");
}
}
-
+
/**
* That class implements a listener that gets called when the resource got activated
* @author hrupp
commit 1e41a098af78a7d97e0a0415dba48bf0b98dba73
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Jul 6 16:03:35 2010 -0400
trivial - add comment, small reformat
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
index cb466bd..5b33fe1 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
@@ -24,6 +24,7 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+
import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
import org.rhq.core.domain.resource.Resource;
@@ -40,6 +41,11 @@ import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
* This is a helper class to {@link InventoryManager} that takes care of resource upgrade.
* Note that this class is not thread-safe in any manner.
*
+ * This class must not call (explicitly or implicitly anywhere in its outgoing call chain)
+ * any other plugin container manager other than the InventoryManager. This is because
+ * this delegate is called within the Inventory Manager's initialize method and hence
+ * many other managers are not yet initialized themselves yet.
+ *
* @author Lukas Krejci
*/
public class ResourceUpgradeDelegate {
@@ -62,7 +68,7 @@ public class ResourceUpgradeDelegate {
public boolean enabled() {
return enabled;
}
-
+
/**
* Disables all future operations of the delegate.
*/
@@ -93,10 +99,10 @@ public class ResourceUpgradeDelegate {
}
}
+ @SuppressWarnings("unchecked")
private <T extends ResourceComponent> boolean executeResourceUpgradeFacetAndStoreRequest(
ResourceContainer resourceContainer) throws PluginContainerException {
- @SuppressWarnings("unchecked")
ResourceComponent<T> parentResourceComponent = resourceContainer.getResourceContext()
.getParentResourceComponent();
@@ -107,7 +113,6 @@ public class ResourceUpgradeDelegate {
Resource resource = resourceContainer.getResource();
- @SuppressWarnings("unchecked")
ResourceDiscoveryComponent<ResourceComponent<T>> discoveryComponent = PluginContainer.getInstance()
.getPluginComponentFactory().getDiscoveryComponent(resource.getResourceType(), parentResourceContainer);
@@ -146,13 +151,13 @@ public class ResourceUpgradeDelegate {
}
private String checkUpgradeValid(Resource resource, ResourceUpgradeReport upgradeReport) {
- StringBuilder bld = new StringBuilder();
+ StringBuilder s = new StringBuilder();
if (!checkResourceKeyUniqueAmongSiblings(resource, upgradeReport)) {
- bld.append("\nAnother inventoried sibling resource of the same type already has the proposed resource key.");
+ s.append("\nAnother inventoried sibling resource of the same type already has the proposed resource key.");
}
- return bld.length() > 0 ? bld.toString() : null;
+ return s.length() > 0 ? s.toString() : null;
}
private boolean checkResourceKeyUniqueAmongSiblings(Resource resource, ResourceUpgradeReport upgradeReport) {
commit fb7c05447b2b4d0f3ebf30481942f12d176f759e
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Jul 6 16:02:39 2010 -0400
trivial - remove tabs
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
index d122da4..915a9e7 100644
--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
@@ -35,12 +35,11 @@ import org.rhq.core.pluginapi.inventory.ResourceComponent;
* @author Lukas Krejci
*/
public interface ResourceUpgradeFacet<T extends ResourceComponent> {
-
- /**
- * Specifies what data should change on the provided resource to upgrade it to the current version.
- *
- * @param inventoriedResource a context representing the resource to be upgraded
- * @return a report specifying what aspects of the resource should be changed or null if there is nothing to upgrade
- */
- ResourceUpgradeReport upgrade(ResourceUpgradeContext<T> inventoriedResource);
+ /**
+ * Specifies what data should change on the provided resource to upgrade it to the current version.
+ *
+ * @param inventoriedResource a context representing the resource to be upgraded
+ * @return a report specifying what aspects of the resource should be changed or null if there is nothing to upgrade
+ */
+ ResourceUpgradeReport upgrade(ResourceUpgradeContext<T> inventoriedResource);
}
commit 18316510cafe27425cd1ac3cc1d08afe398d77ab
Merge: 14db66f... fac71cd...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Jul 2 17:54:08 2010 +0200
Merge branch 'release-3.0.0' into resource-upgrade
commit 14db66fe1f2774bcead24daebee947e6b52851dd
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Jul 2 17:52:12 2010 +0200
Refactoring the resource upgrade to upgrade before the discovery during InventoryManager.initialize(). That enables us to remove all the synchronization on the resources.
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
index 825a616..f055e8c 100644
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
@@ -32,6 +32,8 @@ import org.rhq.core.domain.resource.ResourceUpgradeReport;
*/
public class ResourceUpgradeRequest extends ResourceUpgradeReport {
+ private static final long serialVersionUID = 1L;
+
private int resourceId;
public ResourceUpgradeRequest() {
@@ -52,4 +54,24 @@ public class ResourceUpgradeRequest extends ResourceUpgradeReport {
public void setResourceId(int resourceId) {
this.resourceId = resourceId;
}
+
+ @Override
+ public int hashCode() {
+ return 31 * resourceId;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ if (!(other instanceof ResourceUpgradeRequest)) {
+ return false;
+ }
+
+ ResourceUpgradeRequest r = (ResourceUpgradeRequest) other;
+
+ return r.getResourceId() == resourceId;
+ }
}
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
index 0f9db04..c2bc392 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
@@ -108,4 +108,14 @@ public class ResourceUpgradeReport implements Serializable {
public void setNewDescription(String newDescription) {
this.newDescription = newDescription;
}
+
+ public boolean hasSomethingToUpgrade() {
+ return newResourceKey != null ||
+ newName != null ||
+ newDescription != null;
+ }
+
+ public String toString() {
+ return "ResourceUpgradeReport[newResourceKey = '" + newResourceKey + "', newName = '" + newName + "', newDescription = '" + newDescription + "']";
+ }
}
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
index 914641c..d122da4 100644
--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
@@ -23,9 +23,6 @@
package org.rhq.core.pluginapi.upgrade;
-import java.util.Map;
-import java.util.Set;
-
import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.pluginapi.inventory.ResourceComponent;
@@ -39,19 +36,11 @@ import org.rhq.core.pluginapi.inventory.ResourceComponent;
*/
public interface ResourceUpgradeFacet<T extends ResourceComponent> {
- /**
- * This method is called on the discovery component straight after it has finished the discovery.
- * The exact same discovery results are passed to this method along with the set of resources
- * that already exist in the inventory.
- *
- * @param inventoriedSiblings the existing resources
- * @param parentContext the parent of both the newly discovered and existing resources
- * @param discoveryResults the discovered resources. The resources from this set that have
- * the same resource key as one of the inventoried siblings (after upgrade using the results of this method) won't
- * be reported.
- * @return the mapping of old resources to the newly desired data. The keys are instances from the
- * inventoriedSiblings set, the values are the upgrade reports detailing what the data of the
- * corresponding siblings should be upgraded to.
- */
- Map<ResourceUpgradeContext<T>, ResourceUpgradeReport> upgrade(Set<ResourceUpgradeContext<T>> inventoriedSiblings, ResourceUpgradeContext<? extends ResourceComponent> parentContext, Set<ResourceUpgradeContext<T>> discoveryResults);
+ /**
+ * Specifies what data should change on the provided resource to upgrade it to the current version.
+ *
+ * @param inventoriedResource a context representing the resource to be upgraded
+ * @return a report specifying what aspects of the resource should be changed or null if there is nothing to upgrade
+ */
+ ResourceUpgradeReport upgrade(ResourceUpgradeContext<T> inventoriedResource);
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java
index 4d61e93..7561bf7 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java
@@ -261,10 +261,6 @@ public class PluginContainer implements ContainerService {
} finally {
releaseLock(lock);
}
-
- //fire off the resource upgrade as soon as possible. It will run only once per plugin container
- //lifetime.
- inventoryManager.fireResourceUpgrade();
return;
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index ee42f7d..5786702 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -33,11 +33,9 @@ import java.util.IdentityHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
-import java.util.Queue;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
-import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@@ -93,8 +91,7 @@ import org.rhq.core.pc.plugin.BlacklistedException;
import org.rhq.core.pc.plugin.CanonicalResourceKey;
import org.rhq.core.pc.plugin.PluginComponentFactory;
import org.rhq.core.pc.plugin.PluginManager;
-import org.rhq.core.pc.upgrade.ResourceUpgradeExecutor;
-import org.rhq.core.pc.upgrade.ResourceUpgradePendingRequest;
+import org.rhq.core.pc.upgrade.ResourceUpgradeDelegate;
import org.rhq.core.pc.util.DiscoveryComponentProxyFactory;
import org.rhq.core.pc.util.FacetLockType;
import org.rhq.core.pc.util.LoggingThreadFactory;
@@ -195,7 +192,7 @@ public class InventoryManager extends AgentService implements ContainerService,
/**
* Handles the resource upgrade during the initialization of the inventory manager.
*/
- private ResourceUpgradeExecutor resourceUpgradeExecutor;
+ private ResourceUpgradeDelegate resourceUpgradeDelegate;
public InventoryManager() {
super(DiscoveryAgentService.class);
@@ -219,12 +216,18 @@ public class InventoryManager extends AgentService implements ContainerService,
loadFromDisk();
}
- availabilityCollectors = new AvailabilityCollectorThreadPool();
- availabilityCollectors.initialize();
-
// Discover the platform first thing.
executePlatformScan();
+ //try the resource upgrade before we have any schedulers set up
+ //so that we don't get any interventions from concurrently running
+ //discoveries.
+ resourceUpgradeDelegate = new ResourceUpgradeDelegate(this);
+ upgradeResources();
+
+ availabilityCollectors = new AvailabilityCollectorThreadPool();
+ availabilityCollectors.initialize();
+
// Never run more than one avail check at a time.
availabilityThreadPoolExecutor = new ScheduledThreadPoolExecutor(AVAIL_THREAD_POOL_CORE_POOL_SIZE,
new LoggingThreadFactory(AVAIL_THREAD_POOL_NAME, true));
@@ -251,8 +254,6 @@ public class InventoryManager extends AgentService implements ContainerService,
inventoryThreadPoolExecutor.scheduleWithFixedDelay(serviceScanExecutor, configuration
.getServiceDiscoveryInitialDelay(), configuration.getServiceDiscoveryPeriod(), TimeUnit.SECONDS);
}
-
- resourceUpgradeExecutor = new ResourceUpgradeExecutor(this);
} finally {
inventoryLock.writeLock().unlock();
}
@@ -378,20 +379,19 @@ public class InventoryManager extends AgentService implements ContainerService,
return results;
}
- public <T extends ResourceComponent> Map<ResourceUpgradeContext<T>, ResourceUpgradeReport> invokeDiscoveryComponentResourceUpgradeFacet(
+ public <T extends ResourceComponent> ResourceUpgradeReport invokeDiscoveryComponentResourceUpgradeFacet(
ResourceType resourceType, ResourceDiscoveryComponent<T> component,
- Set<ResourceUpgradeContext<T>> inventoriedSiblings, ResourceUpgradeContext<?> parent,
- Set<ResourceUpgradeContext<T>> discoveredResources) throws Throwable {
+ ResourceUpgradeContext<T> inventoriedResource) throws Throwable {
long timeout = getDiscoveryComponentTimeout(resourceType);
try {
@SuppressWarnings("unchecked")
ResourceUpgradeFacet<T> proxy = this.discoveryComponentProxyFactory.getDiscoveryComponentProxy(resourceType, component, timeout, ResourceUpgradeFacet.class);
- return proxy.upgrade(inventoriedSiblings, parent, discoveredResources);
+ return proxy.upgrade(inventoriedResource);
} catch (BlacklistedException e) {
log.debug(e);
- return Collections.emptyMap();
+ return null;
}
}
@@ -518,15 +518,6 @@ public class InventoryManager extends AgentService implements ContainerService,
}
}
- /**
- * Executes the resource upgrade asynchronously.
- */
- public void fireResourceUpgrade() {
- Thread resourceUpgradeThread = new Thread(resourceUpgradeExecutor, "Resource Upgrade Thread");
- resourceUpgradeThread.setDaemon(true);
- resourceUpgradeThread.start();
- }
-
public InventoryReport executeServerScanImmediately() {
try {
return inventoryThreadPoolExecutor.submit((Callable<InventoryReport>) this.serverScanExecutor).get();
@@ -914,16 +905,6 @@ public class InventoryManager extends AgentService implements ContainerService,
return true;
}
- //finish the resource upgrade.
- //by now all the resource upgrade requests have been processed
- //by the executor, which means that the inventory report
- //we got already only contains the "correct" new resources and
- //that the executor has all the upgrade requests queued up
- //to be sent to the server in a batch.
- if (resourceUpgradeExecutor.isEnabled()) {
- resourceUpgradeExecutor.sendRequests();
- }
-
if (report.getAddedRoots().isEmpty() && !forceServerRoundtrip) {
return true; // nothing to do
}
@@ -1005,7 +986,12 @@ public class InventoryManager extends AgentService implements ContainerService,
// so run an avail check to report on their availabilities immediately. Also kick off
// a service scan to scan those Resources for new child Resources. Kick both tasks off
// asynchronously.
- if (!syncedResources.isEmpty() || !unknownResourceIds.isEmpty() || !modifiedResourceIds.isEmpty()) {
+ // Do this only if we are finished with resource upgrade because no availability checks
+ // or discoveries can happen during upgrade. This is to ensure maximum consistency of the
+ // inventory with the server side as well as to disallow any other server-agent traffic during
+ // the upgrade phase. Not to mention the fact that no thread pools are initialized yet by the
+ // time the upgrade kicks in..
+ if (!resourceUpgradeDelegate.enabled() && (!syncedResources.isEmpty() || !unknownResourceIds.isEmpty() || !modifiedResourceIds.isEmpty())) {
performAvailabilityChecks(true);
this.inventoryThreadPoolExecutor.schedule((Callable<? extends Object>) this.serviceScanExecutor, 5,
TimeUnit.SECONDS);
@@ -2180,10 +2166,6 @@ public class InventoryManager extends AgentService implements ContainerService,
newResources.add(newResource);
}
}
-
- if (resourceUpgradeExecutor.isEnabled()) {
- resourceUpgradeExecutor.processAndQueue(new ResourceUpgradePendingRequest(newResources, context, parentResource.getId()), newResources);
- }
} catch (Throwable e) {
// TODO GH: Add server/parent - up/down semantics so this won't happen just because a server is not up
long elapsedTime = System.currentTimeMillis() - startTime;
@@ -2594,6 +2576,63 @@ public class InventoryManager extends AgentService implements ContainerService,
container.setSynchronizationState(ResourceContainer.SynchronizationState.SYNCHRONIZED);
}
+ private void upgradeResources() {
+ try {
+ if (log.isDebugEnabled()) {
+ log.debug("Executing resource upgrade.");
+ }
+
+ boolean syncResult = handleReport(new InventoryReport(getAgent()), true);
+ if (!syncResult) {
+ log.warn("Resource upgrade failed to sync up the inventory with the server.");
+ return;
+ }
+
+ upgradeResource(getPlatform());
+
+ if (log.isDebugEnabled()) {
+ log.debug("Sending the upgrade requests to the server.");
+ }
+ resourceUpgradeDelegate.sendRequests();
+
+ resourceUpgradeDelegate.disable();
+
+ if (log.isDebugEnabled()) {
+ log.debug("Resource upgrade finished.");
+ }
+ } catch (Throwable t) {
+ log.error("Resource upgrade failed with an exception.", t);
+ }
+ }
+
+ private void upgradeResource(Resource resource) {
+ //only process committed resources
+ if (resource.getInventoryStatus() != InventoryStatus.COMMITTED) {
+ return;
+ }
+
+ ResourceContainer container = getResourceContainer(resource);
+ if (container != null) {
+ try {
+ container = getResourceContainer(resource);
+ resourceUpgradeDelegate.processAndQueue(container);
+ } catch (PluginContainerException e) {
+ log.error("Exception thrown while upgrading [" + resource + "].");
+ }
+
+ if (container.getResourceComponentState() == ResourceComponentState.STARTED) {
+ for (Resource child : resource.getChildResources()) {
+ upgradeResource(child);
+ }
+ } else {
+ log.error("The resource container for resource [" + resource + "] wasn't started during upgrade. This should not happen.");
+ }
+ } else {
+ log.error("Resource container not initialized for resource [" + resource
+ + "] during upgrade. This should not happen.");
+ }
+ }
+
/**
* That class implements a listener that gets called when the resource got activated
* @author hrupp
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
new file mode 100644
index 0000000..cb466bd
--- /dev/null
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeDelegate.java
@@ -0,0 +1,180 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.core.pc.upgrade;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.rhq.core.clientapi.agent.PluginContainerException;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
+import org.rhq.core.pc.PluginContainer;
+import org.rhq.core.pc.inventory.InventoryManager;
+import org.rhq.core.pc.inventory.ResourceContainer;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
+
+/**
+ * This is a helper class to {@link InventoryManager} that takes care of resource upgrade.
+ * Note that this class is not thread-safe in any manner.
+ *
+ * @author Lukas Krejci
+ */
+public class ResourceUpgradeDelegate {
+
+ private static final Log log = LogFactory.getLog(ResourceUpgradeDelegate.class);
+
+ private boolean enabled = true;
+
+ private Set<ResourceUpgradeRequest> requests = new HashSet<ResourceUpgradeRequest>();
+ private InventoryManager inventoryManager;
+
+ public ResourceUpgradeDelegate(InventoryManager inventoryManager) {
+ this.inventoryManager = inventoryManager;
+ }
+
+ /**
+ * Is the delegate enabled? In another words has the resource upgrade phase finished in the {@link IventoryManager#initialize()}
+ * method?
+ */
+ public boolean enabled() {
+ return enabled;
+ }
+
+ /**
+ * Disables all future operations of the delegate.
+ */
+ public void disable() {
+ enabled = false;
+ }
+
+ /**
+ * Asks the resource's discovery component to upgrade the resource.
+ * @param resourceContainer
+ * @return true if the resource was queued for upgrade, false otherwise
+ * @throws PluginContainerException on error
+ */
+ public boolean processAndQueue(ResourceContainer resourceContainer) throws PluginContainerException {
+ if (enabled) {
+ return executeResourceUpgradeFacetAndStoreRequest(resourceContainer);
+ }
+
+ return false;
+ }
+
+ public void sendRequests() {
+ if (enabled) {
+ if (requests.size() > 0) {
+ inventoryManager.mergeResourceFromUpgrade(requests);
+ requests.clear();
+ }
+ }
+ }
+
+ private <T extends ResourceComponent> boolean executeResourceUpgradeFacetAndStoreRequest(
+ ResourceContainer resourceContainer) throws PluginContainerException {
+
+ @SuppressWarnings("unchecked")
+ ResourceComponent<T> parentResourceComponent = resourceContainer.getResourceContext()
+ .getParentResourceComponent();
+
+ Resource parentResource = resourceContainer.getResource().getParentResource();
+
+ ResourceContainer parentResourceContainer = (parentResource != null) ? inventoryManager
+ .getResourceContainer(resourceContainer.getResource().getParentResource()) : null;
+
+ Resource resource = resourceContainer.getResource();
+
+ @SuppressWarnings("unchecked")
+ ResourceDiscoveryComponent<ResourceComponent<T>> discoveryComponent = PluginContainer.getInstance()
+ .getPluginComponentFactory().getDiscoveryComponent(resource.getResourceType(), parentResourceContainer);
+
+ if (!(discoveryComponent instanceof ResourceUpgradeFacet)) {
+ //well, there's no point in continuing if the resource doesn't support the facet
+ return false;
+ }
+
+ ResourceUpgradeContext<ResourceComponent<T>> upgradeContext = inventoryManager.createResourceUpgradeContext(
+ resource, parentResourceComponent, discoveryComponent);
+
+ ResourceUpgradeReport upgradeReport;
+ try {
+ upgradeReport = inventoryManager.invokeDiscoveryComponentResourceUpgradeFacet(resource.getResourceType(),
+ discoveryComponent, upgradeContext);
+ } catch (Throwable t) {
+ log.error("ResourceUpgradeFacet threw an exception while upgrading resource [" + resource + "]", t);
+ return false;
+ }
+
+ if (upgradeReport == null || !upgradeReport.hasSomethingToUpgrade()) {
+ return false;
+ }
+
+ String upgradeErrors = null;
+ if ((upgradeErrors = checkUpgradeValid(resource, upgradeReport)) != null) {
+ log.error("Upgrading the resource [" + resource + "] using these updates [" + upgradeReport
+ + "] would render the inventory invalid because of the following reasons: " + upgradeErrors);
+ return false;
+ }
+
+ //everything went ok, let's queue a upgrade request that will be sent to the server
+ requests.add(new ResourceUpgradeRequest(resource.getId(), upgradeReport));
+
+ return true;
+ }
+
+ private String checkUpgradeValid(Resource resource, ResourceUpgradeReport upgradeReport) {
+ StringBuilder bld = new StringBuilder();
+
+ if (!checkResourceKeyUniqueAmongSiblings(resource, upgradeReport)) {
+ bld.append("\nAnother inventoried sibling resource of the same type already has the proposed resource key.");
+ }
+
+ return bld.length() > 0 ? bld.toString() : null;
+ }
+
+ private boolean checkResourceKeyUniqueAmongSiblings(Resource resource, ResourceUpgradeReport upgradeReport) {
+ Resource parent = resource.getParentResource();
+ if (parent == null) {
+ return true;
+ }
+
+ for (Resource sibling : parent.getChildResources()) {
+ //we'd have a resource key conflict if there was a resource
+ //of the same type under the same parent that would have the same
+ //resource key.
+ if (upgradeReport.getNewResourceKey() != null
+ && sibling.getResourceType().equals(resource.getResourceType())
+ && !sibling.getUuid().equals(resource.getUuid())) {
+
+ if (sibling.getResourceKey().equals(upgradeReport.getNewResourceKey())) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
deleted file mode 100644
index f344900..0000000
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2010 Red Hat, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation, and/or the GNU Lesser
- * General Public License, version 2.1, also as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License and the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * and the GNU Lesser General Public License along with this program;
- * if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-package org.rhq.core.pc.upgrade;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.rhq.core.clientapi.agent.PluginContainerException;
-import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
-import org.rhq.core.clientapi.server.discovery.InventoryReport;
-import org.rhq.core.domain.resource.InventoryStatus;
-import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.resource.ResourceType;
-import org.rhq.core.domain.resource.ResourceUpgradeReport;
-import org.rhq.core.pc.PluginContainer;
-import org.rhq.core.pc.inventory.InventoryManager;
-import org.rhq.core.pc.inventory.ResourceContainer;
-import org.rhq.core.pluginapi.inventory.ResourceComponent;
-import org.rhq.core.pluginapi.inventory.ResourceContext;
-import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
-import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
-import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
-import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
-
-/**
- * This class is responsible for performing the resource upgrade on behalf on of {@link InventoryManager}.
- * Despite its name, it is not an {@link java.util.concurrent.Executor} implementation.
- *
- * @author Lukas Krejci
- */
-public class ResourceUpgradeExecutor implements Runnable {
- private static final Log log = LogFactory.getLog(ResourceUpgradeExecutor.class);
-
- /**
- * The upgrade runs only once in its lifetime.
- */
- private AtomicBoolean enabled = new AtomicBoolean(true);
- private AtomicBoolean started = new AtomicBoolean(false);
-
- private InventoryManager inventoryManager;
-
- private ConcurrentLinkedQueue<ResourceUpgradeRequest> requests;
-
- public ResourceUpgradeExecutor(InventoryManager inventoryManager) {
- this.inventoryManager = inventoryManager;
- requests = new ConcurrentLinkedQueue<ResourceUpgradeRequest>();
- }
-
- /**
- * This method is called from within the {@link InventoryManager} during the
- * discovery process as individual upgrade requests are generated.
- * <p>
- * This method calls the appropriate discovery component to perform the upgrade and
- * at the same time stores off the results so that they can be sent to the server
- * at the end of the discovery in one big batch.
- * <p>
- * The provided set of discovery results is updated if this method detects that an existing
- * resource upgrade would result in a resource key collision with some of the newly discovered
- * resources.
- *
- * @param request the upgrade request
- * @param discoveredResources the set of discovered resources that this method can optionally remove some elements from.
- */
- public <T extends ResourceComponent> Map<ResourceUpgradeContext<T>, ResourceUpgradeReport> processAndQueue(
- ResourceUpgradePendingRequest<T> request, Set<Resource> discoveredResources) {
-
- return enabled.get() ? executeResourceUpgradeAndStoreRequest(request, discoveredResources) : null;
- }
-
- /**
- * @return true if the executor is ready to perform the upgrade, false otherwise.
- */
- public boolean isEnabled() {
- return enabled.get();
- }
-
- /**
- * This method is called from within the {@link InventoryManager} once it's collected
- * all the upgrade requests.
- */
- public void sendRequests() {
- if (enabled.get() && requests.size() > 0) {
- HashSet<ResourceUpgradeRequest> currentCopy = new HashSet<ResourceUpgradeRequest>(requests);
- inventoryManager.mergeResourceFromUpgrade(currentCopy);
- requests.removeAll(currentCopy);
- }
- }
-
- /**
- * Performs the resource upgrade. First, a full inventory report is pulled down from the
- * server to ensure we have an up-to-date picture of the inventory.
- * After that a full discovery is performed and both the upgrade report and discovery report
- * are sent to the server.
- */
- public void run() {
- if (!started.getAndSet(true)) {
- if (log.isDebugEnabled()) {
- log.debug("Starting resource upgrade.");
- }
-
- try {
- //pull the inventory down from the server.
- //this will ensure that we have an up-to-date info on the
- //server inventory before we try to upgrade.
- boolean syncResult = inventoryManager.handleReport(new InventoryReport(inventoryManager.getAgent()), true);
- if (!syncResult) {
- log.warn("Resource upgrade failed to sync up the inventory with the server.");
- return;
- }
-
- //fire off the full discovery
- inventoryManager.executeServerScanImmediately();
- inventoryManager.executeServiceScanImmediately();
- } catch (Throwable t) {
- log.warn("Resource upgrade failed.", t);
- } finally {
- //make sure to switch off the upgrade...
- this.enabled.set(false);
-
- //clear up so that we don't hold unnecessary instances.
- requests.clear();
-
- if (log.isDebugEnabled()) {
- log.debug("Resource upgrade finished.");
- }
- }
-
- } else {
- if (log.isDebugEnabled()) {
- log.debug("ResourceUpgradeExecutor already ran before. Skipping the execution.");
- }
- }
- }
-
- /**
- * Executes the resource upgrade request on the agent (if the appropriate discovery component support {@link ResourceUpgradeFacet}).
- *
- * @param request the upgrade request to execute on the agent.
- * @param discoveredResources the set of the discovered resources that this method can remove some elements from
- * @return the resulting upgrade map as reported by the plugin from {@link ResourceUpgradeFacet#upgrade(Set, ResourceUpgradeContext, Set)} method.
- *
- * @throws PluginContainerException
- */
- private <T extends ResourceComponent> Map<ResourceUpgradeContext<T>, ResourceUpgradeReport> executeResourceUpgradeAndStoreRequest(
- ResourceUpgradePendingRequest<T> request, Set<Resource> discoveredResources) {
-
- ResourceDiscoveryContext<T> discoveryContext = request.getDiscoveryContext();
- Set<Resource> newResources = request.getDiscoveredResources();
- Integer parentResourceId = request.getParentResourceId();
-
- try {
- ResourceType resourceType = discoveryContext.getResourceType();
- ResourceContainer parentResourceContainer = null;
- Resource parentResource = null;
- if (parentResourceId != null) {
- parentResourceContainer = inventoryManager.getResourceContainer(parentResourceId);
- if (parentResourceContainer != null) {
- parentResource = parentResourceContainer.getResource();
- }
- }
-
- @SuppressWarnings("unchecked")
- ResourceDiscoveryComponent<T> discoveryComponent = PluginContainer.getInstance()
- .getPluginComponentFactory().getDiscoveryComponent(resourceType, parentResourceContainer);
-
- ResourceContext<?> parentResourceContext = discoveryContext.getParentResourceContext();
-
- T parentComponent = discoveryContext.getParentResourceComponent();
-
- //check if the discovery component supports resource upgrade
- //if it does, perform the resource upgrade straight away here during the discovery process.
- if (discoveryComponent instanceof ResourceUpgradeFacet) {
- //the siblings are the resources of the type that is currently being discovered that are already
- //present in the inventory. These are the candidate resources for the upgrade.
- Set<Resource> siblings = parentResource == null ? Collections.singleton(inventoryManager.getPlatform())
- : inventoryManager.getResourcesWithType(resourceType, parentResource.getChildResources());
-
- //filter out not committed resources
- //XXX what about uninventoried or ignored ones? is it correct to not upgrade those?
- Iterator<Resource> siblingsIterator = siblings.iterator();
- while (siblingsIterator.hasNext()) {
- if (siblingsIterator.next().getInventoryStatus() != InventoryStatus.COMMITTED) {
- siblingsIterator.remove();
- }
- }
-
- //get the upgrade context of the parent resource so that it can be passed to the upgrade method
- //of the discovery component.
- ResourceUpgradeContext<?> parentUpgradeContext = null;
-
- if (parentResource != null) {
- Resource grandParent = parentResource.getParentResource();
- ResourceContainer grandParentContainer = grandParent == null ? null : inventoryManager
- .getResourceContainer(grandParent);
-
- @SuppressWarnings("unchecked")
- ResourceDiscoveryComponent<ResourceComponent> parentDiscoveryComponent = PluginContainer
- .getInstance().getPluginComponentFactory().getDiscoveryComponent(
- parentResource.getResourceType(), grandParentContainer);
-
- ResourceComponent<?> grandParentResourceComponent = grandParentContainer == null ? null
- : grandParentContainer.getResourceComponent();
-
- parentUpgradeContext = inventoryManager.createResourceUpgradeContext(parentResource,
- grandParentResourceComponent, parentDiscoveryComponent);
- }
-
- //convert the sibling resources into upgrade context objects so that the plugin methods don't access the
- //domain objects directly.
- Set<ResourceUpgradeContext<T>> siblingContexts = new HashSet<ResourceUpgradeContext<T>>(siblings.size());
-
- //but we are going to need to update the resources in the end, so map the contexts with the resources.
- Map<ResourceUpgradeContext<T>, Resource> siblingContextToResource = new HashMap<ResourceUpgradeContext<T>, Resource>();
-
- for (Resource sibling : siblings) {
- ResourceUpgradeContext<T> siblingContext = inventoryManager.createResourceUpgradeContext(sibling,
- parentComponent, discoveryComponent);
- siblingContexts.add(siblingContext);
- siblingContextToResource.put(siblingContext, sibling);
- }
-
- //convert the new resources into contexts.
- //map the resources by resource key so that we can later check for uniqueness of the reported results.
- Set<ResourceUpgradeContext<T>> newResourceContexts = new HashSet<ResourceUpgradeContext<T>>();
- Map<String, Resource> newResourceKeyToResource = new HashMap<String, Resource>();
-
- for (Resource newResource : newResources) {
- ResourceUpgradeContext<T> newUpgradeContext = inventoryManager.createResourceUpgradeContext(
- newResource, parentComponent, discoveryComponent);
- newResourceContexts.add(newUpgradeContext);
- newResourceKeyToResource.put(newResource.getResourceKey(), newResource);
- }
-
- //ask the discovery component to upgrade the siblings.
- Map<ResourceUpgradeContext<T>, ResourceUpgradeReport> results;
- try {
- results = inventoryManager.invokeDiscoveryComponentResourceUpgradeFacet(resourceType,
- discoveryComponent, siblingContexts, parentUpgradeContext, newResourceContexts);
-
- //now go through the results and create the upgrade requests.
- for (Map.Entry<ResourceUpgradeContext<T>, ResourceUpgradeReport> upgradeEntry : results.entrySet()) {
- Resource siblingToUpgrade = siblingContextToResource.get(upgradeEntry.getKey());
- ResourceUpgradeRequest newData = new ResourceUpgradeRequest(siblingToUpgrade.getId(), upgradeEntry.getValue());
-
- requests.add(newData);
-
- //if there was a resource key upgrade, remove a resource with the same resource key
- //from the discovery results. Otherwise we'd end up with 2 sibling resources with
- //the same resource key, which is illegal.
- if (newData.getNewResourceKey() != null) {
- Resource newResourceToRemove = newResourceKeyToResource.get(newData.getNewResourceKey());
- if (newResourceToRemove != null) {
- discoveredResources.remove(newResourceToRemove);
- }
- }
- }
-
- return results;
- } catch (Throwable t) {
- log.warn("Exception in discovery component " + discoveryComponent.getClass() + " upgrade method.",
- t);
- }
- }
- } catch (PluginContainerException e) {
- log.warn("Failed resource upgrade of children of resource id " + parentResourceId, e);
- }
- return null;
- }
-}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradePendingRequest.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradePendingRequest.java
deleted file mode 100644
index 1099643..0000000
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradePendingRequest.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.rhq.core.pc.upgrade;
-
-import java.util.Set;
-
-import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.pluginapi.inventory.ResourceComponent;
-import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
-
-/**
- * This class is used to store the requests for resource upgrade that originate in
- * the discovery workflow, but can only be executed after an inventory sync.
- */
-public class ResourceUpgradePendingRequest<T extends ResourceComponent> {
- private Set<Resource> discoveredResources;
- private ResourceDiscoveryContext<T> discoveryContext;
- private Integer parentResourceId;
-
- public ResourceUpgradePendingRequest(Set<Resource> discoveredResources, ResourceDiscoveryContext<T> discoveryContext, Integer parentResourceId) {
- this.discoveredResources = discoveredResources;
- this.discoveryContext = discoveryContext;
- this.parentResourceId = parentResourceId;
- }
-
- public Set<Resource> getDiscoveredResources() {
- return discoveredResources;
- }
-
- public ResourceDiscoveryContext<T> getDiscoveryContext() {
- return discoveryContext;
- }
-
- public Integer getParentResourceId() {
- return parentResourceId;
- }
-}
\ No newline at end of file
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 087b46f..b5d571f 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -151,34 +151,8 @@ public class ResourceUpgradeTest {
}
@Test
- public void testResourceUpgradeRunsOnlyOnce() throws Exception {
- currentServerSideInventory = new FakeServerInventory();
- initialSyncAndDiscovery(InventoryStatus.COMMITTED);
-
- executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, new TestPayload() {
- public void test(Resource discoveredResource) {
- for(int i = 0; i < 100; i++) {
- PluginContainer.getInstance().getInventoryManager().fireResourceUpgrade();
- }
- }
-
- @SuppressWarnings("unchecked")
- public Expectations getExpectations(Mockery context) throws Exception {
- return new Expectations() {
- {
- defineDefaultExpectations(this);
-
- between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
- will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
-
- //even though we fire the resource upgrade 100 times above,
- //only 1 upgrade should actually occur and go up to the server.
- oneOf(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
- will(currentServerSideInventory.upgradeResources());
- }
- };
- }
- });
+ public void testRecoveryWithServerUnavailable() throws Exception {
+ //TODO implement
}
private void initialSyncAndDiscovery(final InventoryStatus requiredInventoryStatus) throws Exception {
diff --git a/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar
index 412ae00..7ffc5bb 100644
Binary files a/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar and b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar differ
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index 329f476..add8168 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -20,7 +20,6 @@ package org.rhq.enterprise.server.discovery;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
index 7fe7a5e..de265eb 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
@@ -1715,8 +1715,16 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
Query query = entityManager.createNamedQuery(Resource.QUERY_FIND_PLATFORM_BY_AGENT);
query.setParameter("category", ResourceCategory.PLATFORM);
query.setParameter("agent", agent);
- Resource platform = (Resource) query.getSingleResult();
- return platform;
+
+ try {
+ Resource platform = (Resource) query.getSingleResult();
+ return platform;
+ } catch (NoResultException e) {
+ //this means that the agent didn't send any info to us yet.
+ //this can happen during the inital resource upgrade sync between
+ //the agent and server.
+ return null;
+ }
}
@SuppressWarnings("unchecked")
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
index 327c439..faf0b11 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
@@ -376,7 +376,7 @@ public interface ResourceManagerLocal {
*
* @param agent an Agent
*
- * @return the platform Resource associated with the specified Agent
+ * @return the platform Resource associated with the specified Agent or null if the platform for the agent is not known yet.
*/
Resource getPlatform(Agent agent);
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
index 362a1df..c31d153 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
@@ -170,45 +170,40 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
return discoveredResources;
}
- public Map<ResourceUpgradeContext<PlatformComponent>, ResourceUpgradeReport> upgrade(Set<ResourceUpgradeContext<PlatformComponent>> inventoriedSiblings,
- ResourceUpgradeContext<?> parentContext, Set<ResourceUpgradeContext<PlatformComponent>> discoveryResults) {
-
- Map<ResourceUpgradeContext<PlatformComponent>, ResourceUpgradeReport> ret = new HashMap<ResourceUpgradeContext<PlatformComponent>, ResourceUpgradeReport>();
-
- for (ResourceUpgradeContext context : inventoriedSiblings) {
- String inventoriedResourceKey = context.getResourceKey();
- File inventoriedResourceKeyAsPath = new File(inventoriedResourceKey);
-
- //the resource key we use now is a full path to the httpdconf.
- //in the old version, it was the server root.
- //so if the inventoried resource key is a path to a file,
- //we know it's a new style resource key.
- if (inventoriedResourceKeyAsPath.isFile()) {
- continue;
- }
-
- Configuration pluginConfiguration = context.getPluginConfiguration();
-
- String serverRoot = pluginConfiguration.getSimpleValue("serverRoot", null);
- String httpdConf = pluginConfiguration.getSimpleValue("configFile", null);
-
- String resourceKey = null;
-
- if (httpdConf != null) {
- File httpdConfFile = new File(httpdConf);
- if (!httpdConfFile.isAbsolute()) {
- httpdConfFile = new File(serverRoot, httpdConf);
- }
-
- resourceKey = httpdConfFile.getPath();
-
- ResourceUpgradeReport rep = new ResourceUpgradeReport();
- rep.setNewResourceKey(resourceKey);
-
- ret.put(context, rep);
+ public ResourceUpgradeReport upgrade(ResourceUpgradeContext<PlatformComponent> context) {
+ String inventoriedResourceKey = context.getResourceKey();
+ File inventoriedResourceKeyAsPath = new File(inventoriedResourceKey);
+
+ //the resource key we use now is a full path to the httpd.conf.
+ //in the old version, it was the server root.
+ //so if the inventoried resource key is a path to a file,
+ //we know it's a new style resource key.
+ if (inventoriedResourceKeyAsPath.isFile()) {
+ return null;
+ }
+
+ Configuration pluginConfiguration = context.getPluginConfiguration();
+
+ String serverRoot = pluginConfiguration.getSimpleValue("serverRoot", null);
+ String httpdConf = pluginConfiguration.getSimpleValue("configFile", null);
+
+ String resourceKey = null;
+
+ if (httpdConf != null) {
+ File httpdConfFile = new File(httpdConf);
+ if (!httpdConfFile.isAbsolute()) {
+ httpdConfFile = new File(serverRoot, httpdConf);
}
+
+ resourceKey = httpdConfFile.getPath();
+
+ ResourceUpgradeReport rep = new ResourceUpgradeReport();
+ rep.setNewResourceKey(resourceKey);
+
+ return rep;
}
- return ret;
+
+ return null;
}
public DiscoveredResourceDetails discoverResource(Configuration pluginConfig,
commit 00b2aae2f27dd64092eee3c2d09df33e48736e10
Merge: 90ca72b... ed06919...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Jul 2 14:25:47 2010 +0200
Merge branch 'release-3.0.0' into resource-upgrade
diff --cc modules/core/dbutils/pom.xml
index 2013b3d,d536ce6..96685db
--- a/modules/core/dbutils/pom.xml
+++ b/modules/core/dbutils/pom.xml
@@@ -22,7 -22,7 +22,7 @@@
<properties>
<scm.module.path>modules/core/dbutils/</scm.module.path>
-- <db.schema.version>2.88</db.schema.version>
++ <db.schema.version>2.89</db.schema.version>
</properties>
<dependencies>
diff --cc modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
index 3ee8217,7f8f9da..20e9d2f
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@@ -2994,15 -3000,17 +3000,27 @@@
</statement>
</schema-directSQL>
</schemaSpec>
-
- <schemaSpec version="2.88">
+
+ <schemaSpec version="2.88">
+ <schema-directSQL>
+ <statement desc="Add end time index on call time data to speed up purges">
+ CREATE INDEX RHQ_CT_DA_VA_END_TIM_IDX ON RHQ_CALLTIME_DATA_VALUE (end_time)
+ </statement>
+ <statement desc="Add index on measurement definition numeric type">
+ CREATE INDEX RHQ_METRIC_DEF_NT_IDX ON RHQ_MEASUREMENT_DEF (numeric_type)
+ </statement>
+ </schema-directSQL>
+ </schemaSpec>
++
++ <schemaSpec version="2.89">
+ <schema-directSQL>
+ <statement desc="Adding 'Allow Agent Plugins To Upgrade Generic Resource Properties' system configuration setting">
+ INSERT INTO rhq_system_config (id, property_key, property_value, default_property_value)
+ VALUES (56, 'RESOURCE_GENERIC_PROPERTIES_UPGRADE', 'false', 'false')
+ </statement>
+ </schema-directSQL>
+ </schemaSpec>
++
</dbupgrade>
</target>
</project>
commit 90ca72b3aa73f41165ab2d616f53f12d642bef7d
Merge: 5449040... b9ca90d...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Jun 23 19:01:34 2010 +0200
Merge branch 'release-3.0.0' into resource-upgrade
commit 54490406d19753524b052beeab418af68bf68c2c
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Jun 23 15:41:36 2010 +0200
Restructuring the tests a bit, adding a test for correct reinitialization of the agent inventory from the server inventory during the resource upgrade.
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 46d069c..087b46f 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -49,6 +49,7 @@ import org.rhq.core.clientapi.server.event.EventServerService;
import org.rhq.core.clientapi.server.inventory.ResourceFactoryServerService;
import org.rhq.core.clientapi.server.measurement.MeasurementServerService;
import org.rhq.core.clientapi.server.operation.OperationServerService;
+import org.rhq.core.domain.discovery.AvailabilityReport;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
@@ -64,6 +65,7 @@ import org.rhq.core.pc.plugin.FileSystemPluginFinder;
*
* @author Lukas Krejci
*/
+@Test(sequential = true, invocationCount = 1)
public class ResourceUpgradeTest {
private static final String PLUGIN_V1_FILENAME = "resource-upgrade-test-plugin-1.0.0.jar";
@@ -100,7 +102,7 @@ public class ResourceUpgradeTest {
verifyPluginExists(PLUGIN_V2_FILENAME);
}
- @BeforeClass
+ @BeforeClass(dependsOnMethods = "sanityCheck")
public void init() {
tmpDir = getTmpDirectory();
pluginDir = new File(tmpDir, PLUGINS_DIR_NAME);
@@ -110,12 +112,10 @@ public class ResourceUpgradeTest {
}
@Test
- public void testInitialSyncAndDiscoveryWithoutCommit() throws Exception {
- testInitialSyncAndDiscovery(InventoryStatus.NEW);
- }
-
- @Test(dependsOnMethods = "testInitialSyncAndDiscoveryWithoutCommit")
public void testIgnoreUncommittedResources() throws Exception {
+ currentServerSideInventory = new FakeServerInventory();
+ initialSyncAndDiscovery(InventoryStatus.NEW);
+
TestPayload testNoChange = new TestPayload() {
public void test(Resource discoveredResource) {
assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
@@ -123,17 +123,13 @@ public class ResourceUpgradeTest {
assertEquals(discoveredResource.getDescription(), "resource-description-v1");
}
- @SuppressWarnings("unchecked")
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
- defineIgnoredExpectations(this);
+ defineDefaultExpectations(this);
between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
-
- allowing(currentDiscoveryServerService).getResources(with(any(Set.class)), with(any(boolean.class)));
- will(currentServerSideInventory.getResources());
}
};
}
@@ -142,52 +138,50 @@ public class ResourceUpgradeTest {
executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, testNoChange);
}
- //make the tests run serially, so that they don't overwrite the currentServerSideInventory
- //variable concurrently
- @Test(dependsOnMethods = "testIgnoreUncommittedResources")
- public void testInitialSyncAndDiscoveryWithCommit() throws Exception {
- testInitialSyncAndDiscovery(InventoryStatus.COMMITTED);
- }
-
- @Test(dependsOnMethods = "testInitialSyncAndDiscoveryWithCommit")
+ @Test
public void testUpgradeData() throws Exception {
- //we are keeping the currentServerSideInventory from the previous test
+ currentServerSideInventory = new FakeServerInventory();
+ upgradeTest(false);
+ }
+
+ @Test
+ public void testInventoryReinitializationFromServerDuringUpgrade() throws Exception {
+ currentServerSideInventory = new FakeServerInventory();
+ upgradeTest(true);
+ }
+
+ @Test
+ public void testResourceUpgradeRunsOnlyOnce() throws Exception {
+ currentServerSideInventory = new FakeServerInventory();
+ initialSyncAndDiscovery(InventoryStatus.COMMITTED);
+
executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, new TestPayload() {
public void test(Resource discoveredResource) {
- assertEquals(discoveredResource.getResourceKey(), "resource-key-v2");
- assertEquals(discoveredResource.getName(), "resource-name-v2");
- assertEquals(discoveredResource.getDescription(), "resource-description-v2");
-
- ResourceContainer container = PluginContainer.getInstance().getInventoryManager().getResourceContainer(discoveredResource);
- File dataDir = container.getResourceContext().getDataDirectory();
-
- File marker = new File(dataDir, "upgrade-succeeded");
-
- assertTrue(marker.exists(), "The upgrade success marker file wasn't found. This means the upgrade didn't actually run.");
+ for(int i = 0; i < 100; i++) {
+ PluginContainer.getInstance().getInventoryManager().fireResourceUpgrade();
+ }
}
@SuppressWarnings("unchecked")
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
- defineIgnoredExpectations(this);
+ defineDefaultExpectations(this);
between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+ //even though we fire the resource upgrade 100 times above,
+ //only 1 upgrade should actually occur and go up to the server.
oneOf(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
will(currentServerSideInventory.upgradeResources());
-
- allowing(currentDiscoveryServerService).getResources(with(any(Set.class)), with(any(boolean.class)));
- will(currentServerSideInventory.getResources());
}
};
}
});
}
- private void testInitialSyncAndDiscovery(final InventoryStatus requiredInventoryStatus) throws Exception {
- currentServerSideInventory = new FakeServerInventory();
+ private void initialSyncAndDiscovery(final InventoryStatus requiredInventoryStatus) throws Exception {
executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), true, new TestPayload() {
public void test(Resource discoveredResource) {
assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
@@ -195,17 +189,13 @@ public class ResourceUpgradeTest {
assertEquals(discoveredResource.getDescription(), "resource-description-v1");
}
- @SuppressWarnings("unchecked")
public Expectations getExpectations(Mockery context) throws Exception {
return new Expectations() {
{
- defineIgnoredExpectations(this);
+ defineDefaultExpectations(this);
between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
will(currentServerSideInventory.mergeInventoryReport(requiredInventoryStatus));
-
- allowing(currentDiscoveryServerService).getResources(with(any(Set.class)), with(any(boolean.class)));
- will(currentServerSideInventory.getResources());
}
};
}
@@ -213,6 +203,40 @@ public class ResourceUpgradeTest {
}
+ private void upgradeTest(boolean clearInventoryDat) throws Exception {
+ initialSyncAndDiscovery(InventoryStatus.COMMITTED);
+
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), clearInventoryDat, new TestPayload() {
+ public void test(Resource discoveredResource) {
+ assertEquals(discoveredResource.getResourceKey(), "resource-key-v2");
+ assertEquals(discoveredResource.getName(), "resource-name-v2");
+ assertEquals(discoveredResource.getDescription(), "resource-description-v2");
+
+ ResourceContainer container = PluginContainer.getInstance().getInventoryManager().getResourceContainer(discoveredResource);
+ File dataDir = container.getResourceContext().getDataDirectory();
+
+ File marker = new File(dataDir, "upgrade-succeeded");
+
+ assertTrue(marker.exists(), "The upgrade success marker file wasn't found. This means the upgrade didn't actually run.");
+ }
+
+ @SuppressWarnings("unchecked")
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineDefaultExpectations(this);
+
+ between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+
+ oneOf(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
+ will(currentServerSideInventory.upgradeResources());
+ }
+ };
+ }
+ });
+ }
+
private PluginContainerConfiguration createPluginContainerConfiguration(Mockery context) throws Exception {
PluginContainerConfiguration conf = new PluginContainerConfiguration();
@@ -223,6 +247,15 @@ public class ResourceUpgradeTest {
conf.setPluginFinder(new FileSystemPluginFinder(conf.getPluginDirectory()));
conf.setCreateResourceClassloaders(false);
+ //we're not interested in any scans happening out of our control
+ conf.setAvailabilityScanInitialDelay(Long.MAX_VALUE);
+ conf.setConfigurationDiscoveryInitialDelay(Long.MAX_VALUE);
+ conf.setContentDiscoveryInitialDelay(Long.MAX_VALUE);
+ conf.setEventSenderInitialDelay(Long.MAX_VALUE);
+ conf.setMeasurementCollectionInitialDelay(Long.MAX_VALUE);
+ conf.setServerDiscoveryInitialDelay(Long.MAX_VALUE);
+ conf.setServiceDiscoveryInitialDelay(Long.MAX_VALUE);
+
currentBundleServerService = context.mock(BundleServerService.class);
currentConfigurationServerService = context.mock(ConfigurationServerService.class);
currentContentServerService = context.mock(ContentServerService.class);
@@ -332,7 +365,8 @@ public class ResourceUpgradeTest {
context.assertIsSatisfied();
}
- private void defineIgnoredExpectations(Expectations expectations) {
+ @SuppressWarnings("unchecked")
+ private void defineDefaultExpectations(Expectations expectations) {
expectations.ignoring(currentBundleServerService);
expectations.ignoring(currentConfigurationServerService);
expectations.ignoring(currentContentServerService);
@@ -341,5 +375,11 @@ public class ResourceUpgradeTest {
expectations.ignoring(currentMeasurementServerService);
expectations.ignoring(currentOperationServerService);
expectations.ignoring(currentResourceFactoryServerService);
+
+ //just ignore these invocations if we get a availability scan in the PC...
+ expectations.allowing(currentDiscoveryServerService).mergeAvailabilityReport(expectations.with(Expectations.any(AvailabilityReport.class)));
+
+ expectations.allowing(currentDiscoveryServerService).getResources(expectations.with(Expectations.any(Set.class)), expectations.with(Expectations.any(boolean.class)));
+ expectations.will(currentServerSideInventory.getResources());
}
}
commit 0d5d63e1ed0825ddc0ea256b695a66c980b69e6e
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Jun 23 15:40:16 2010 +0200
Forgot to bump the db version.
diff --git a/modules/core/dbutils/pom.xml b/modules/core/dbutils/pom.xml
index 92ae1d2..2013b3d 100644
--- a/modules/core/dbutils/pom.xml
+++ b/modules/core/dbutils/pom.xml
@@ -22,7 +22,7 @@
<properties>
<scm.module.path>modules/core/dbutils/</scm.module.path>
- <db.schema.version>2.87</db.schema.version>
+ <db.schema.version>2.88</db.schema.version>
</properties>
<dependencies>
commit 7f8310f4d3648ba3386fda883563bdcc8c5d1492
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Jun 23 15:39:54 2010 +0200
Adding the server side system config property for controlling whether to allow resource name and description upgrades.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/config/SystemConfigForm.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/config/SystemConfigForm.java
index 237858d..508a4ac 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/config/SystemConfigForm.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/config/SystemConfigForm.java
@@ -66,7 +66,8 @@ public class SystemConfigForm extends BaseValidatorForm {
private String ldapPassword = "";
private Boolean ldapEnabled = null;
private boolean reindex = false;
-
+ private boolean allowResourceGenericPropertiesUpgrade;
+
@Override
public String toString() {
StringBuffer buf = new StringBuffer(super.toString());
@@ -230,6 +231,8 @@ public class SystemConfigForm extends BaseValidatorForm {
String jaasProvider = prop.getProperty(RHQConstants.JAASProvider);
ldapEnabled = RHQConstants.LDAPJAASProvider.equals(jaasProvider) ? Boolean.TRUE : null;
+ String resourceGenericPropertiesUpgradeAllowed = prop.getProperty(RHQConstants.AllowResourceGenericPropertiesUpgrade);
+ allowResourceGenericPropertiesUpgrade = Boolean.parseBoolean(resourceGenericPropertiesUpgradeAllowed);
}
/**
@@ -332,6 +335,8 @@ public class SystemConfigForm extends BaseValidatorForm {
prop.setProperty(RHQConstants.JAASProvider, RHQConstants.JDBCJAASProvider);
}
+ prop.setProperty(RHQConstants.AllowResourceGenericPropertiesUpgrade, String.valueOf(allowResourceGenericPropertiesUpgrade));
+
return prop;
}
@@ -608,6 +613,14 @@ public class SystemConfigForm extends BaseValidatorForm {
public void setReindex(boolean reindex) {
this.reindex = reindex;
}
+
+ public boolean isAllowResourceGenericPropertiesUpgrade() {
+ return allowResourceGenericPropertiesUpgrade;
+ }
+
+ public void setAllowResourceGenericPropertiesUpgrade(boolean allowResourceGenericPropertiesUpgrade) {
+ this.allowResourceGenericPropertiesUpgrade = allowResourceGenericPropertiesUpgrade;
+ }
/* (non-Javadoc)
* @see org.apache.struts.action.ActionForm#validate(org.apache.struts.action.ActionMapping,
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties b/modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties
index f02efb5..83f42f0 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties
+++ b/modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties
@@ -667,6 +667,8 @@ admin.settings.ServerPluginsConfigPropTab=Server Plugins Configuration Propertie
admin.settings.UseCAMAuth=Use ${product.shortName} Internal Authentication
admin.settings.UseLDAPAuth=Use LDAP Authentication
+admin.settings.AllowResourceGenericPropertiesUpgrade=Allow Agent Plugins To Upgrade Generic Resource Properties
+
admin.settings.error.DeleteUnitsField=Value must be between 1 and 7 days.
admin.settings.error.InvalidSNMPTrapOID=SNMP Trap OID invalid, please enter OID in form of 1.2.3.4.
admin.settings.error.InvalidSNMPEngineID=SNMP Engine ID is invalid, must be a valid number.
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/GeneralPropertiesConfigForm.jsp b/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/GeneralPropertiesConfigForm.jsp
index 30df9ef..136c37c 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/GeneralPropertiesConfigForm.jsp
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/admin/config/GeneralPropertiesConfigForm.jsp
@@ -86,6 +86,17 @@
</table>
</td>
</tr>
+ <tr>
+ <td class="BlockLabel"><fmt:message key="admin.settings.AllowResourceGenericPropertiesUpgrade"/></td>
+ <td class="BlockContent">
+ <table cellpadding="0" cellspacing="4" border="0">
+ <tr>
+ <td align="left"><html:radio property="allowResourceGenericPropertiesUpgrade" value="true"/><fmt:message key="yesno.true"/></td>
+ <td align="left"><html:radio property="allowResourceGenericPropertiesUpgrade" value="false"/><fmt:message key="yesno.false"/></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
<hq:authorization permission="superuser">
<tr>
commit 6c2472739d2df4b5a99f1e4fae22b945440dd5fd
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Jun 23 15:29:15 2010 +0200
Adding the ability of the server to alter/ignore some upgrade data.
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
new file mode 100644
index 0000000..825a616
--- /dev/null
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeRequest.java
@@ -0,0 +1,55 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.rhq.core.clientapi.agent.upgrade;
+
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
+
+/**
+ * Represents a request to upgrade a resource.
+ *
+ * @author Lukas Krejci
+ */
+public class ResourceUpgradeRequest extends ResourceUpgradeReport {
+
+ private int resourceId;
+
+ public ResourceUpgradeRequest() {
+
+ }
+
+ public ResourceUpgradeRequest(int resourceId, ResourceUpgradeReport report) {
+ setResourceId(resourceId);
+ setNewDescription(report.getNewDescription());
+ setNewName(report.getNewName());
+ setNewResourceKey(report.getNewResourceKey());
+ }
+
+ public int getResourceId() {
+ return resourceId;
+ }
+
+ public void setResourceId(int resourceId) {
+ this.resourceId = resourceId;
+ }
+}
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeResponse.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeResponse.java
new file mode 100644
index 0000000..3faa9ef
--- /dev/null
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/upgrade/ResourceUpgradeResponse.java
@@ -0,0 +1,80 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.rhq.core.clientapi.agent.upgrade;
+
+import java.io.Serializable;
+
+/**
+ * Represents a response to a resource upgrade request.
+ * The upgraded* properties contain the values of the corresponding resource properties
+ * as they were stored on the server.
+ *
+ * @author Lukas Krejci
+ */
+public class ResourceUpgradeResponse implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private int resourceId;
+
+ private String upgradedResourceName;
+ private String upgradedResourceKey;
+ private String upgradedResourceDescription;
+
+ public ResourceUpgradeResponse() {
+
+ }
+
+ public int getResourceId() {
+ return resourceId;
+ }
+
+ public void setResourceId(int resourceId) {
+ this.resourceId = resourceId;
+ }
+
+ public String getUpgradedResourceName() {
+ return upgradedResourceName;
+ }
+
+ public void setUpgradedResourceName(String upgradedResourceName) {
+ this.upgradedResourceName = upgradedResourceName;
+ }
+
+ public String getUpgradedResourceKey() {
+ return upgradedResourceKey;
+ }
+
+ public void setUpgradedResourceKey(String upgradedResourceKey) {
+ this.upgradedResourceKey = upgradedResourceKey;
+ }
+
+ public String getUpgradedResourceDescription() {
+ return upgradedResourceDescription;
+ }
+
+ public void setUpgradedResourceDescription(String upgradedResourceDescription) {
+ this.upgradedResourceDescription = upgradedResourceDescription;
+ }
+}
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
index 61e5084..0622fc5 100644
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
@@ -29,6 +29,8 @@ import org.rhq.core.communications.command.annotation.Asynchronous;
import org.rhq.core.communications.command.annotation.LimitedConcurrency;
import org.rhq.core.communications.command.annotation.Timeout;
import org.rhq.core.domain.discovery.AvailabilityReport;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeResponse;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
import org.rhq.core.domain.discovery.MergeResourceResponse;
import org.rhq.core.domain.discovery.ResourceSyncInfo;
@@ -37,7 +39,6 @@ import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.domain.resource.ResourceErrorType;
-import org.rhq.core.domain.resource.ResourceUpgradeReport;
/**
* The interface to a JON server's resource discovery subsystem.
@@ -139,11 +140,13 @@ public interface DiscoveryServerService {
/**
* Upgrades the data of the resources according to the provided reports.
+ * The server is free to ignore or modify the requests and will provide the
+ * true changes made to the resources on the server-side in the result of this method.
*
- * @param upgradeReports contains the information about the upgrade of individual resources.
- * @return true if the upgrade succeeded, false otherwise.
+ * @param upgradeRequests contains the information about the upgrade of individual resources.
+ * @return details on what resources have been upgraded with what data.
*/
- boolean upgradeResources(Set<ResourceUpgradeReport> upgradeReports);
+ Set<ResourceUpgradeResponse> upgradeResources(Set<ResourceUpgradeRequest> upgradeRequests);
/**
* Gives the server a chance to apply any necessary post-processing that's needed for newly committed resources
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/sysconfig-data.xml b/modules/core/dbutils/src/main/scripts/dbsetup/sysconfig-data.xml
index 26d648e..121e971 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup/sysconfig-data.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/sysconfig-data.xml
@@ -121,6 +121,9 @@
<!-- How old does availability have to be in order to get purged -->
<data ID="55" PROPERTY_KEY="AVAILABILITY_PURGE" PROPERTY_VALUE="31536000000"
DEFAULT_PROPERTY_VALUE="31536000000" FREAD_ONLY="FALSE"/>
+
+ <data ID="56" PROPERTY_KEY="RESOURCE_GENERIC_PROPERTIES_UPGRADE" PROPERTY_VALUE="false"
+ DEFAULT_PROPERTY_VALUE="false" FREAD_ONLY="FALSE"/>
</table>
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
index 71aa297..ad53803 100644
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@ -2994,6 +2994,14 @@
</schema-directSQL>
</schemaSpec>
+ <schemaSpec version="2.88">
+ <schema-directSQL>
+ <statement desc="Adding 'Allow Agent Plugins To Upgrade Generic Resource Properties' system configuration setting">
+ INSERT INTO rhq_system_config (id, property_key, property_value, default_property_value)
+ VALUES (56, 'RESOURCE_GENERIC_PROPERTIES_UPGRADE', 'false', 'false')
+ </statement>
+ </schema-directSQL>
+ </schemaSpec>
</dbupgrade>
</target>
</project>
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
index 979c456..0f9db04 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
@@ -41,7 +41,6 @@ public class ResourceUpgradeReport implements Serializable {
private static final long serialVersionUID = 1L;
- private int resourceId;
private String newResourceKey;
private String newName;
@@ -62,22 +61,6 @@ public class ResourceUpgradeReport implements Serializable {
}
- /**
- * The server-side id of the resource being upgraded.
- * The discovery components don't need to assign this value.
- */
- public int getResourceId() {
- return resourceId;
- }
-
- /**
- * The server-side id of the resource being upgraded.
- * The discovery components don't need to assign this value.
- */
- public void setResourceId(int resourceId) {
- this.resourceId = resourceId;
- }
-
public String getNewResourceKey() {
return newResourceKey;
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 6c3d26a..b5f5f00 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -55,6 +55,8 @@ import org.rhq.core.clientapi.agent.configuration.ConfigurationUtility;
import org.rhq.core.clientapi.agent.discovery.DiscoveryAgentService;
import org.rhq.core.clientapi.agent.discovery.InvalidPluginConfigurationClientException;
import org.rhq.core.clientapi.agent.metadata.PluginMetadataManager;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeResponse;
import org.rhq.core.clientapi.server.discovery.DiscoveryServerService;
import org.rhq.core.clientapi.server.discovery.InvalidInventoryReportException;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
@@ -92,7 +94,7 @@ import org.rhq.core.pc.plugin.CanonicalResourceKey;
import org.rhq.core.pc.plugin.PluginComponentFactory;
import org.rhq.core.pc.plugin.PluginManager;
import org.rhq.core.pc.upgrade.ResourceUpgradeExecutor;
-import org.rhq.core.pc.upgrade.ResourceUpgradeRequest;
+import org.rhq.core.pc.upgrade.ResourceUpgradePendingRequest;
import org.rhq.core.pc.util.DiscoveryComponentProxyFactory;
import org.rhq.core.pc.util.FacetLockType;
import org.rhq.core.pc.util.LoggingThreadFactory;
@@ -1178,31 +1180,31 @@ public class InventoryManager extends AgentService implements ContainerService,
return resourceContainer.updateAvailability(availabilityType);
}
- public boolean mergeResourceFromUpgrade(Set<ResourceUpgradeReport> upgradeReports) {
- boolean serverUpdated = false;
+ public void mergeResourceFromUpgrade(Set<ResourceUpgradeRequest> upgradeReports) {
+ Set<ResourceUpgradeResponse> serverUpdates = null;
try {
ServerServices serverServices = this.configuration.getServerServices();
if (serverServices != null) {
DiscoveryServerService discoveryServerService = serverServices.getDiscoveryServerService();
- serverUpdated = discoveryServerService.upgradeResources(upgradeReports);
+ serverUpdates = discoveryServerService.upgradeResources(upgradeReports);
}
} catch (Exception e) {
log.error("Failed to process resource upgrades on the server.", e);
}
- if (serverUpdated) {
- for (ResourceUpgradeReport upgradeReport : upgradeReports) {
- String resourceKey = upgradeReport.getNewResourceKey();
- String name = upgradeReport.getNewName();
+ if (serverUpdates != null) {
+ for (ResourceUpgradeResponse upgradeResponse : serverUpdates) {
+ String resourceKey = upgradeResponse.getUpgradedResourceKey();
+ String name = upgradeResponse.getUpgradedResourceName();
//String version = upgradeReport.getNewVersion();
- String description = upgradeReport.getNewDescription();
+ String description = upgradeResponse.getUpgradedResourceDescription();
//Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
//Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
//only bother if there's something to upgrade at all on this resource.
if (resourceKey != null || name != null || description != null) {
- ResourceContainer existingResourceContainer = getResourceContainer(upgradeReport.getResourceId());
+ ResourceContainer existingResourceContainer = getResourceContainer(upgradeResponse.getResourceId());
if (existingResourceContainer != null) {
Resource existingResource = existingResourceContainer.getResource();
@@ -1241,13 +1243,11 @@ public class InventoryManager extends AgentService implements ContainerService,
log.info(logMessage.toString());
} else {
- log.error("Upgraded a resource that is not present on the agent. This should not happen. The id of the missing resource is " + upgradeReport.getResourceId());
+ log.error("Upgraded a resource that is not present on the agent. This should not happen. The id of the missing resource is " + upgradeResponse.getResourceId());
}
}
}
}
-
- return serverUpdated;
}
public Resource mergeResourceFromDiscovery(Resource resource, Resource parent) throws PluginContainerException {
@@ -2173,7 +2173,7 @@ public class InventoryManager extends AgentService implements ContainerService,
}
if (resourceUpgradeExecutor.isEnabled()) {
- resourceUpgradeExecutor.processAndQueue(new ResourceUpgradeRequest(newResources, context, parentResource.getId()), newResources);
+ resourceUpgradeExecutor.processAndQueue(new ResourceUpgradePendingRequest(newResources, context, parentResource.getId()), newResources);
}
} catch (Throwable e) {
// TODO GH: Add server/parent - up/down semantics so this won't happen just because a server is not up
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
index bb20054..f344900 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
@@ -29,7 +29,6 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -37,6 +36,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rhq.core.clientapi.agent.PluginContainerException;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
@@ -69,11 +69,11 @@ public class ResourceUpgradeExecutor implements Runnable {
private InventoryManager inventoryManager;
- private ConcurrentLinkedQueue<ResourceUpgradeReport> reports;
+ private ConcurrentLinkedQueue<ResourceUpgradeRequest> requests;
public ResourceUpgradeExecutor(InventoryManager inventoryManager) {
this.inventoryManager = inventoryManager;
- reports = new ConcurrentLinkedQueue<ResourceUpgradeReport>();
+ requests = new ConcurrentLinkedQueue<ResourceUpgradeRequest>();
}
/**
@@ -92,9 +92,9 @@ public class ResourceUpgradeExecutor implements Runnable {
* @param discoveredResources the set of discovered resources that this method can optionally remove some elements from.
*/
public <T extends ResourceComponent> Map<ResourceUpgradeContext<T>, ResourceUpgradeReport> processAndQueue(
- ResourceUpgradeRequest<T> request, Set<Resource> discoveredResources) {
+ ResourceUpgradePendingRequest<T> request, Set<Resource> discoveredResources) {
- return enabled.get() ? executeResourceUpgradeAndStoreReport(request, discoveredResources) : null;
+ return enabled.get() ? executeResourceUpgradeAndStoreRequest(request, discoveredResources) : null;
}
/**
@@ -109,10 +109,10 @@ public class ResourceUpgradeExecutor implements Runnable {
* all the upgrade requests.
*/
public void sendRequests() {
- if (enabled.get() && reports.size() > 0) {
- HashSet<ResourceUpgradeReport> currentCopy = new HashSet<ResourceUpgradeReport>(reports);
+ if (enabled.get() && requests.size() > 0) {
+ HashSet<ResourceUpgradeRequest> currentCopy = new HashSet<ResourceUpgradeRequest>(requests);
inventoryManager.mergeResourceFromUpgrade(currentCopy);
- reports.removeAll(currentCopy);
+ requests.removeAll(currentCopy);
}
}
@@ -148,7 +148,7 @@ public class ResourceUpgradeExecutor implements Runnable {
this.enabled.set(false);
//clear up so that we don't hold unnecessary instances.
- reports.clear();
+ requests.clear();
if (log.isDebugEnabled()) {
log.debug("Resource upgrade finished.");
@@ -171,8 +171,8 @@ public class ResourceUpgradeExecutor implements Runnable {
*
* @throws PluginContainerException
*/
- private <T extends ResourceComponent> Map<ResourceUpgradeContext<T>, ResourceUpgradeReport> executeResourceUpgradeAndStoreReport(
- ResourceUpgradeRequest<T> request, Set<Resource> discoveredResources) {
+ private <T extends ResourceComponent> Map<ResourceUpgradeContext<T>, ResourceUpgradeReport> executeResourceUpgradeAndStoreRequest(
+ ResourceUpgradePendingRequest<T> request, Set<Resource> discoveredResources) {
ResourceDiscoveryContext<T> discoveryContext = request.getDiscoveryContext();
Set<Resource> newResources = request.getDiscoveredResources();
@@ -267,14 +267,12 @@ public class ResourceUpgradeExecutor implements Runnable {
results = inventoryManager.invokeDiscoveryComponentResourceUpgradeFacet(resourceType,
discoveryComponent, siblingContexts, parentUpgradeContext, newResourceContexts);
- //now go through the results and upgrade the resources as needed.
+ //now go through the results and create the upgrade requests.
for (Map.Entry<ResourceUpgradeContext<T>, ResourceUpgradeReport> upgradeEntry : results.entrySet()) {
Resource siblingToUpgrade = siblingContextToResource.get(upgradeEntry.getKey());
- ResourceUpgradeReport newData = upgradeEntry.getValue();
+ ResourceUpgradeRequest newData = new ResourceUpgradeRequest(siblingToUpgrade.getId(), upgradeEntry.getValue());
- //upgrade the data on the server first
- newData.setResourceId(siblingToUpgrade.getId());
- reports.add(newData);
+ requests.add(newData);
//if there was a resource key upgrade, remove a resource with the same resource key
//from the discovery results. Otherwise we'd end up with 2 sibling resources with
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradePendingRequest.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradePendingRequest.java
new file mode 100644
index 0000000..1099643
--- /dev/null
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradePendingRequest.java
@@ -0,0 +1,35 @@
+package org.rhq.core.pc.upgrade;
+
+import java.util.Set;
+
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+
+/**
+ * This class is used to store the requests for resource upgrade that originate in
+ * the discovery workflow, but can only be executed after an inventory sync.
+ */
+public class ResourceUpgradePendingRequest<T extends ResourceComponent> {
+ private Set<Resource> discoveredResources;
+ private ResourceDiscoveryContext<T> discoveryContext;
+ private Integer parentResourceId;
+
+ public ResourceUpgradePendingRequest(Set<Resource> discoveredResources, ResourceDiscoveryContext<T> discoveryContext, Integer parentResourceId) {
+ this.discoveredResources = discoveredResources;
+ this.discoveryContext = discoveryContext;
+ this.parentResourceId = parentResourceId;
+ }
+
+ public Set<Resource> getDiscoveredResources() {
+ return discoveredResources;
+ }
+
+ public ResourceDiscoveryContext<T> getDiscoveryContext() {
+ return discoveryContext;
+ }
+
+ public Integer getParentResourceId() {
+ return parentResourceId;
+ }
+}
\ No newline at end of file
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeRequest.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeRequest.java
deleted file mode 100644
index 25178ee..0000000
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeRequest.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.rhq.core.pc.upgrade;
-
-import java.util.Set;
-
-import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.pluginapi.inventory.ResourceComponent;
-import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
-
-/**
- * This class is used to store the requests for resource upgrade that originate in
- * the discovery workflow, but can only be executed after an inventory sync.
- */
-public class ResourceUpgradeRequest<T extends ResourceComponent> {
- private Set<Resource> discoveredResources;
- private ResourceDiscoveryContext<T> discoveryContext;
- private Integer parentResourceId;
-
- public ResourceUpgradeRequest(Set<Resource> discoveredResources, ResourceDiscoveryContext<T> discoveryContext, Integer parentResourceId) {
- this.discoveredResources = discoveredResources;
- this.discoveryContext = discoveryContext;
- this.parentResourceId = parentResourceId;
- }
-
- public Set<Resource> getDiscoveredResources() {
- return discoveredResources;
- }
-
- public ResourceDiscoveryContext<T> getDiscoveryContext() {
- return discoveryContext;
- }
-
- public Integer getParentResourceId() {
- return parentResourceId;
- }
-}
\ No newline at end of file
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
index 4341e3a..c3bdbf4 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
@@ -37,15 +37,17 @@ import java.util.Set;
import org.jmock.api.Invocation;
import org.jmock.lib.action.CustomAction;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeResponse;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
import org.rhq.core.domain.discovery.ResourceSyncInfo;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
-import org.rhq.core.domain.resource.ResourceUpgradeReport;
/**
- *
+ * This class represents a server side database store of the inventory for the purposes
+ * of the ResourceUpgradeTest unit test.
*
* @author Lukas Krejci
*/
@@ -89,28 +91,36 @@ public class FakeServerInventory {
return new CustomAction("upgradeServerSideInventory") {
@SuppressWarnings({"serial", "unchecked"})
public Object invoke(Invocation invocation) throws Throwable {
- Set<ResourceUpgradeReport> reports = (Set<ResourceUpgradeReport>) invocation.getParameter(0);
-
- for (final ResourceUpgradeReport report : reports) {
+ Set<ResourceUpgradeRequest> requests = (Set<ResourceUpgradeRequest>) invocation.getParameter(0);
+ Set<ResourceUpgradeResponse> responses = new HashSet<ResourceUpgradeResponse>();
+
+ for (final ResourceUpgradeRequest request : requests) {
Resource resource = findResource(platform, new Resource() {
public int getId() {
- return report.getResourceId();
+ return request.getResourceId();
}
}, ID_COMPARATOR);
if (resource != null) {
- if (report.getNewDescription() != null) {
- resource.setDescription(report.getNewDescription());
+ if (request.getNewDescription() != null) {
+ resource.setDescription(request.getNewDescription());
}
- if (report.getNewName() != null) {
- resource.setName(report.getNewName());
+ if (request.getNewName() != null) {
+ resource.setName(request.getNewName());
}
- if (report.getNewResourceKey() != null) {
- resource.setResourceKey(report.getNewResourceKey());
+ if (request.getNewResourceKey() != null) {
+ resource.setResourceKey(request.getNewResourceKey());
}
+
+ ResourceUpgradeResponse resp = new ResourceUpgradeResponse();
+ resp.setResourceId(resource.getId());
+ resp.setUpgradedResourceName(resource.getName());
+ resp.setUpgradedResourceKey(resource.getResourceKey());
+ resp.setUpgradedResourceDescription(resource.getDescription());
+ responses.add(resp);
}
}
- return true;
+ return responses;
}
};
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/RHQConstants.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/RHQConstants.java
index 7bb1d72..fff7872 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/RHQConstants.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/RHQConstants.java
@@ -110,5 +110,8 @@ public class RHQConstants {
// Syslog Actions enabled
public static final String SyslogActionsEnabled = "CAM_SYSLOG_ACTIONS_ENABLED";
+
+ //allow plugin initiated resource name & description upgrades (resource key is always upgradable)
+ public static final String AllowResourceGenericPropertiesUpgrade = "RESOURCE_GENERIC_PROPERTIES_UPGRADE";
}
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index fd59590..329f476 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -20,8 +20,10 @@ package org.rhq.enterprise.server.discovery;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -43,6 +45,8 @@ import org.jetbrains.annotations.Nullable;
import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.agent.discovery.InvalidPluginConfigurationClientException;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeResponse;
import org.rhq.core.clientapi.server.discovery.InvalidInventoryReportException;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
import org.rhq.core.domain.auth.Subject;
@@ -75,6 +79,7 @@ import org.rhq.enterprise.server.resource.ResourceAvailabilityManagerLocal;
import org.rhq.enterprise.server.resource.ResourceManagerLocal;
import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal;
import org.rhq.enterprise.server.resource.group.ResourceGroupManagerLocal;
+import org.rhq.enterprise.server.system.SystemManagerLocal;
/**
* SLSB that provides the interface point to the discovery subsystem for the UI layer and the discovery server service.
@@ -107,6 +112,8 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
private SubjectManagerLocal subjectManager;
@EJB
private ProductVersionManagerLocal productVersionManager;
+ @EJB
+ private SystemManagerLocal systemManager;
public ResourceSyncInfo mergeInventoryReport(InventoryReport report) throws InvalidInventoryReportException {
validateInventoryReport(report);
@@ -407,20 +414,19 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
}
}
- public boolean upgradeResources(Set<ResourceUpgradeReport> upgradeReports) {
- for (ResourceUpgradeReport report : upgradeReports) {
- Resource existingResource = this.entityManager.find(Resource.class, report.getResourceId());
+ public Set<ResourceUpgradeResponse> upgradeResources(Set<ResourceUpgradeRequest> upgradeRequests) {
+ Set<ResourceUpgradeResponse> result = new HashSet<ResourceUpgradeResponse>();
+
+ boolean allowGenericPropertiesUpgrade = Boolean.parseBoolean(systemManager.getSystemConfiguration().getProperty(RHQConstants.AllowResourceGenericPropertiesUpgrade, "false"));
+
+ for (ResourceUpgradeRequest request : upgradeRequests) {
+ Resource existingResource = this.entityManager.find(Resource.class, request.getResourceId());
if (existingResource != null) {
- boolean changed = upgradeResource(existingResource, report);
- if (changed) {
- this.entityManager.merge(existingResource);
- }
- } else {
- this.entityManager.getTransaction().setRollbackOnly();
- return false;
+ ResourceUpgradeResponse upgradedData = upgradeResource(existingResource, request, allowGenericPropertiesUpgrade);
+ result.add(upgradedData);
}
}
- return true;
+ return result;
}
/**
@@ -471,40 +477,46 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
/**
* @param existingResource
* @param upgradeReport
+ * @param allowGenericPropertiesUpgrade name and description are only upgraded if this is true
* @return true if the resource was changed, false otherwise
*/
- private boolean upgradeResource(Resource resource, ResourceUpgradeReport upgradeReport) {
- if (resource != null) {
- String resourceKey = upgradeReport.getNewResourceKey();
- String name = upgradeReport.getNewName();
+ private ResourceUpgradeResponse upgradeResource(@NotNull Resource resource, ResourceUpgradeReport upgradeReport, boolean allowGenericPropertiesUpgrade) {
+ ResourceUpgradeResponse ret = new ResourceUpgradeResponse();
+ ret.setResourceId(resource.getId());
+
+ String resourceKey = upgradeReport.getNewResourceKey();
+ String name = upgradeReport.getNewName();
// String version = upgradeReport.getNewVersion();
- String description = upgradeReport.getNewDescription();
+ String description = upgradeReport.getNewDescription();
// Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
// Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
+
+ if (resourceKey != null || name != null || description != null) {
+ StringBuilder logMessage = new StringBuilder("Resource [")
+ .append(resource.toString()).append("] upgraded its ");
+
+ if (needsUpgrade(resource.getResourceKey(), resourceKey)) {
+ resource.setResourceKey(resourceKey);
+ logMessage.append("resourceKey, ");
+ }
+ ret.setUpgradedResourceKey(resource.getResourceKey());
+
+ if (allowGenericPropertiesUpgrade && needsUpgrade(resource.getName(), name)) {
+ resource.setName(name);
+ logMessage.append("name, ");
+ }
+ ret.setUpgradedResourceName(resource.getName());
- if (resourceKey != null || name != null || description != null) {
- StringBuilder logMessage = new StringBuilder("Resource [")
- .append(resource.toString()).append("] upgraded its ");
-
- if (needsUpgrade(resource.getResourceKey(), resourceKey)) {
- resource.setResourceKey(resourceKey);
- logMessage.append("resourceKey, ");
- }
-
- if (needsUpgrade(resource.getName(), name)) {
- resource.setName(name);
- logMessage.append("name, ");
- }
-
// if (version != null) {
// changed = updateResourceVersion(resource, version) || changed;
// }
-
- if (needsUpgrade(resource.getDescription(), description)) {
- resource.setDescription(description);
- logMessage.append("description, ");
- }
-
+
+ if (allowGenericPropertiesUpgrade && needsUpgrade(resource.getDescription(), description)) {
+ resource.setDescription(description);
+ logMessage.append("description, ");
+ }
+ ret.setUpgradedResourceDescription(resource.getDescription());
+
// if (pluginConfiguration != null) {
// if (!equalOrNull(pluginConfiguration, resource.getPluginConfiguration())) {
// log.info("Resource [" + resource + "] upgraded its plugin configuration from [" +
@@ -525,16 +537,13 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
// resource.setResourceConfiguration(resourceConfiguration);
// }
// }
-
- logMessage.replace(logMessage.length() - 1, logMessage.length(),
- "to become [").append(resource.toString()).append("]");
- log.info(logMessage.toString());
-
- return true;
- }
+ logMessage.replace(logMessage.length() - 1, logMessage.length(),
+ "to become [").append(resource.toString()).append("]");
+
+ log.info(logMessage.toString());
}
- return false;
+ return ret;
}
private void validateInventoryReport(InventoryReport report) throws InvalidInventoryReportException {
@@ -651,9 +660,21 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
*/
ResourceType resourceType = resource.getResourceType();
Resource parent = resource;
+ Subject overlord = subjectManager.getOverlord();
while (parent != null && existingResource == null) {
parent = parent.getParentResource();
- existingResource = resourceManager.getResourceByParentAndKey(subjectManager.getOverlord(), parent,
+ //check if the parent itself is inventoried. This might not be the case
+ //during initial sync-up for resource upgrade.
+ Resource existingParent = null;
+ if (parent != null) {
+ existingParent = entityManager.find(Resource.class, parent.getId());
+ if (existingParent == null) {
+ //well, this parent is not known to the server, so there's no
+ //point in trying to find a child of it...
+ continue;
+ }
+ }
+ existingResource = resourceManager.getResourceByParentAndKey(overlord, existingParent,
resource.getResourceKey(), resourceType.getPlugin(), resourceType.getName());
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
index af518eb..c9208fc 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
@@ -29,6 +29,8 @@ import org.jetbrains.annotations.NotNull;
import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.agent.discovery.InvalidPluginConfigurationClientException;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeResponse;
import org.rhq.core.clientapi.server.discovery.InvalidInventoryReportException;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
import org.rhq.core.domain.auth.Subject;
@@ -181,9 +183,11 @@ public interface DiscoveryBossLocal extends DiscoveryBossRemote {
/**
* Upgrades the data of the resources according to the provided reports.
+ * The server is free to ignore or modify the requests and will provide the
+ * true changes made to the resources on the server-side in the result of this method.
*
- * @param upgradeReports contains the information about the upgrade of individual resources.
- * @return true if the upgrade succeeded, false otherwise.
+ * @param upgradeRequests contains the information about the upgrade of individual resources.
+ * @return details on what resources have been upgraded with what data.
*/
- boolean upgradeResources(Set<ResourceUpgradeReport> upgradeReports);
+ Set<ResourceUpgradeResponse> upgradeResources(Set<ResourceUpgradeRequest> upgradeRequest);
}
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
index 0f90cdc..5dbe59a 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
@@ -25,6 +25,8 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeRequest;
+import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeResponse;
import org.rhq.core.clientapi.server.discovery.DiscoveryServerService;
import org.rhq.core.clientapi.server.discovery.InvalidInventoryReportException;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
@@ -177,9 +179,9 @@ public class DiscoveryServerServiceImpl implements DiscoveryServerService {
return discoveryBoss.updateResourceVersion(resourceId, version);
}
- public boolean upgradeResources(Set<ResourceUpgradeReport> upgradeReports) {
+ public Set<ResourceUpgradeResponse> upgradeResources(Set<ResourceUpgradeRequest> upgradeRequests) {
DiscoveryBossLocal discoveryBoss = LookupUtil.getDiscoveryBoss();
- return discoveryBoss.upgradeResources(upgradeReports);
+ return discoveryBoss.upgradeResources(upgradeRequests);
}
private static Resource convertToPojoResource(Resource resource, boolean includeDescendants) {
commit a479fd3591a15b7422b378a000f213a21b9bf750
Merge: ab45b75... f595c48...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Jun 18 21:19:23 2010 +0200
Merge branch 'release-3.0.0' into resource-upgrade
commit ab45b7518ec6b740899c694c3229746cd0490fd6
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Jun 18 20:25:56 2010 +0200
Basic unit tests of the resource upgrade workflow along with some minor changes in the PC to handle the hardcoded test platform in a normal connected-like scenarios.
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/PluginMetadataManager.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/PluginMetadataManager.java
index 63072db..0c5e0b6 100644
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/PluginMetadataManager.java
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/PluginMetadataManager.java
@@ -55,7 +55,7 @@ public class PluginMetadataManager {
private Object typesLock = new Object();
private Map<String, PluginMetadataParser> parsersByPlugin = new HashMap<String, PluginMetadataParser>();
-
+
public PluginMetadataManager() {
}
@@ -177,6 +177,9 @@ public class PluginMetadataManager {
@Nullable
public ResourceType getType(ResourceType resourceType) {
+ if (TEST_PLATFORM_TYPE.equals(resourceType)) {
+ return TEST_PLATFORM_TYPE;
+ }
return getType(resourceType.getName(), resourceType.getPlugin());
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index dbee063..1433120 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -1369,12 +1369,6 @@ public class InventoryManager extends AgentService implements ContainerService,
resourceContainer.setSynchronizationState(ResourceContainer.SynchronizationState.SYNCHRONIZED);
}
this.resourceContainers.put(resource.getUuid(), resourceContainer);
- if (resource.getParentResource() == null) {
- // no parent - must be the top level platform - do some things needed for unit tests
- if (this.platform.getResourceType().equals(PluginMetadataManager.TEST_PLATFORM_TYPE)) {
- resourceContainer.setResourceComponent(createTestPlatformComponent());
- }
- }
} else {
// container already exists, but make sure the classloader exists too
if (resourceContainer.getResourceClassLoader() == null) {
@@ -1800,6 +1794,13 @@ public class InventoryManager extends AgentService implements ContainerService,
Set<DiscoveredResourceDetails> allDiscoveredPlatforms = new HashSet<DiscoveredResourceDetails>(2);
if ((platformTypes != null) && (platformTypes.size() > 0)) {
+
+ //check for fake testing type. If the test platform type is being used, it is always going to be
+ //the sole platform type available.
+ if (platformTypes.size() == 1 && platformTypes.contains(PluginMetadataManager.TEST_PLATFORM_TYPE)) {
+ return getTestPlatform();
+ }
+
// Go through all the platform types that are supported and see if they can detect our platform.
for (ResourceType platformType : platformTypes) {
try {
@@ -1828,7 +1829,7 @@ public class InventoryManager extends AgentService implements ContainerService,
.error("Missing platform plugin(s) - falling back to dummy platform impl; this should only occur in tests!");
// TODO: Set sysprop (e.g. rhq.test.mode=true) in integration tests,
// and throw a runtime exception here if that sysprop is not set.
- return createTestPlatform();
+ return getTestPlatform();
}
if (allDiscoveredPlatforms.isEmpty()) {
@@ -1870,9 +1871,13 @@ public class InventoryManager extends AgentService implements ContainerService,
* resource. This is normally only used during tests.
* @return A dummy platform for testing purposes only.
*/
- private Resource createTestPlatform() {
+ private Resource getTestPlatform() {
ResourceType type = PluginContainer.getInstance().getPluginManager().getMetadataManager().addTestPlatformType();
+ if (this.platform != null && this.platform.getResourceType() == type) {
+ return this.platform;
+ }
Resource platform = new Resource("testkey" + configuration.getContainerName(), "testplatform", type);
+ platform.setUuid(UUID.randomUUID().toString());
platform.setAgent(this.agent);
return platform;
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginComponentFactory.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginComponentFactory.java
index 4176353..b9d9cf3 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginComponentFactory.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginComponentFactory.java
@@ -30,6 +30,7 @@ import org.apache.commons.logging.LogFactory;
import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.agent.metadata.PluginMetadataManager;
+import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.pc.ContainerService;
@@ -39,6 +40,7 @@ import org.rhq.core.pc.inventory.InventoryManager;
import org.rhq.core.pc.inventory.ResourceContainer;
import org.rhq.core.pluginapi.inventory.ClassLoaderFacet;
import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
/**
@@ -129,6 +131,19 @@ public class PluginComponentFactory implements ContainerService {
*/
public ResourceComponent buildResourceComponent(Resource resource) throws PluginContainerException {
ResourceType resourceType = resource.getResourceType();
+ if (PluginMetadataManager.TEST_PLATFORM_TYPE.equals(resourceType)) {
+ return new ResourceComponent() {
+ public AvailabilityType getAvailability() {
+ return AvailabilityType.UP;
+ }
+
+ public void start(ResourceContext context) {
+ }
+
+ public void stop() {
+ }
+ };
+ }
String className = getPluginManager().getMetadataManager().getComponentClass(resourceType);
ClassLoader resourceClassloader = getResourceClassloader(resource);
ResourceComponent component = (ResourceComponent) instantiateClass(resourceClassloader, className);
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
new file mode 100644
index 0000000..4341e3a
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
@@ -0,0 +1,272 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.rhq.core.pc.upgrade;
+
+import static org.testng.Assert.fail;
+
+import java.lang.reflect.Field;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.jmock.api.Invocation;
+import org.jmock.lib.action.CustomAction;
+
+import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.domain.discovery.ResourceSyncInfo;
+import org.rhq.core.domain.resource.InventoryStatus;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
+
+/**
+ *
+ *
+ * @author Lukas Krejci
+ */
+public class FakeServerInventory {
+
+ private Resource platform;
+ private Map<String, Resource> resourceStore = new HashMap<String, Resource>();
+ private int counter;
+
+ private static final Comparator<Resource> ID_COMPARATOR = new Comparator<Resource>() {
+ public int compare(Resource o1, Resource o2) {
+ return o1.getId() - o2.getId();
+ }
+ };
+
+ private static final Comparator<Resource> RESOURCE_TYPE_COMPARATOR = new Comparator<Resource>() {
+ public int compare(Resource o1, Resource o2) {
+ return o1.getResourceType().equals(o2.getResourceType()) ? 0 : o1.getId() - o2.getId();
+ }
+ };
+
+ //need to synchronize, because resource upgrade is async and can overlap with
+ //resource discovery.
+ public synchronized CustomAction mergeInventoryReport(final InventoryStatus requiredInventoryStatus) {
+ return new CustomAction("updateServerSideInventory") {
+ public Object invoke(Invocation invocation) throws Throwable {
+ InventoryReport inventoryReport = (InventoryReport) invocation.getParameter(0);
+
+ for(Resource res : inventoryReport.getAddedRoots()) {
+ if (res.getParentResource() == Resource.ROOT) {
+ platform = fakePersist(res, requiredInventoryStatus, new HashSet<String>());
+ break;
+ }
+ }
+ return getSyncInfo();
+ }
+ };
+ }
+
+ public synchronized CustomAction upgradeResources() {
+ return new CustomAction("upgradeServerSideInventory") {
+ @SuppressWarnings({"serial", "unchecked"})
+ public Object invoke(Invocation invocation) throws Throwable {
+ Set<ResourceUpgradeReport> reports = (Set<ResourceUpgradeReport>) invocation.getParameter(0);
+
+ for (final ResourceUpgradeReport report : reports) {
+ Resource resource = findResource(platform, new Resource() {
+ public int getId() {
+ return report.getResourceId();
+ }
+ }, ID_COMPARATOR);
+ if (resource != null) {
+ if (report.getNewDescription() != null) {
+ resource.setDescription(report.getNewDescription());
+ }
+ if (report.getNewName() != null) {
+ resource.setName(report.getNewName());
+ }
+
+ if (report.getNewResourceKey() != null) {
+ resource.setResourceKey(report.getNewResourceKey());
+ }
+ }
+ }
+ return true;
+ }
+ };
+ }
+
+ public synchronized CustomAction getResources() {
+ return new CustomAction("getResources") {
+ @SuppressWarnings("unchecked")
+ public Object invoke(Invocation invocation) throws Throwable {
+ Set<Integer> resourceIds = (Set<Integer>)invocation.getParameter(0);
+ boolean includeDescendants = (Boolean) invocation.getParameter(1);
+
+ return getResources(resourceIds, includeDescendants);
+ }
+ };
+ }
+
+ @SuppressWarnings("serial")
+ public synchronized Set<Resource> findResourcesByType(final ResourceType type) {
+ Set<Resource> result = new HashSet<Resource>();
+ if (platform != null) {
+ findResources(platform, new Resource() {
+ public ResourceType getResourceType() {
+ return type;
+ }
+ }, result, RESOURCE_TYPE_COMPARATOR);
+ }
+ return result;
+ }
+
+ @SuppressWarnings("serial")
+ private Set<Resource> getResources(Set<Integer> resourceIds, boolean includeDescendants) {
+ Set<Resource> result = new HashSet<Resource>();
+
+ for(final Integer id : resourceIds) {
+ Resource r = findResource(platform, new Resource() {
+ public int getId() {
+ return id;
+ }
+ }, ID_COMPARATOR);
+ if (r != null) {
+ result.add(r);
+
+ if (includeDescendants) {
+ for(Resource child : r.getChildResources()) {
+ result.addAll(getResources(Collections.singleton(child.getId()), true));
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private Resource fakePersist(Resource agentSideResource, InventoryStatus requiredInventoryStatus, Set<String> inProgressUUIds) {
+ Resource persisted = resourceStore.get(agentSideResource.getUuid());
+ if (!inProgressUUIds.add(agentSideResource.getUuid())) {
+ return persisted;
+ }
+ if (persisted == null) {
+ persisted = new Resource();
+ persisted.setId(++counter);
+ persisted.setUuid(agentSideResource.getUuid());
+ resourceStore.put(persisted.getUuid(), persisted);
+ }
+ persisted.setAgent(agentSideResource.getAgent());
+ persisted.setCurrentAvailability(agentSideResource.getCurrentAvailability());
+ persisted.setDescription(agentSideResource.getDescription());
+ persisted.setName(agentSideResource.getName());
+ persisted.setPluginConfiguration(agentSideResource.getPluginConfiguration().clone());
+ persisted.setResourceConfiguration(agentSideResource.getResourceConfiguration().clone());
+ persisted.setVersion(agentSideResource.getVersion());
+ persisted.setInventoryStatus(requiredInventoryStatus);
+ persisted.setResourceKey(agentSideResource.getResourceKey());
+ persisted.setResourceType(agentSideResource.getResourceType());
+
+ Resource parent = agentSideResource.getParentResource();
+ if (parent != null && parent != Resource.ROOT) {
+ persisted.setParentResource(fakePersist(agentSideResource.getParentResource(), requiredInventoryStatus, inProgressUUIds));
+ } else {
+ persisted.setParentResource(parent);
+ }
+
+ Set<Resource> childResources = new HashSet<Resource>();
+ persisted.setChildResources(childResources);
+ for(Resource child : agentSideResource.getChildResources()) {
+ childResources.add(fakePersist(child, requiredInventoryStatus, inProgressUUIds));
+ }
+
+ inProgressUUIds.remove(agentSideResource.getUuid());
+
+ return persisted;
+ }
+
+ private ResourceSyncInfo getSyncInfo() {
+ return platform != null ? convert(platform) : null;
+ }
+
+ private static ResourceSyncInfo convert(Resource root) {
+ try {
+ ResourceSyncInfo ret = new ResourceSyncInfo();
+
+ Class<ResourceSyncInfo> clazz = ResourceSyncInfo.class;
+
+ getPrivateField(clazz, "id").set(ret, root.getId());
+ getPrivateField(clazz, "uuid").set(ret, root.getUuid());
+ getPrivateField(clazz, "mtime").set(ret, root.getMtime());
+ getPrivateField(clazz, "inventoryStatus").set(ret, root.getInventoryStatus());
+ getPrivateField(clazz, "parent").set(ret, null);
+
+ Set<ResourceSyncInfo> children = new LinkedHashSet<ResourceSyncInfo>();
+ for(Resource child : root.getChildResources()) {
+ ResourceSyncInfo syncChild = convert(child);
+ getPrivateField(clazz, "parent").set(syncChild, ret);
+
+ children.add(convert(child));
+ }
+ getPrivateField(clazz, "childSyncInfos").set(ret, children);
+
+ return ret;
+ } catch (Exception e) {
+ fail("Failed to convert resource " + root + " to a ResourceSyncInfo. This should not happen.", e);
+ return null;
+ }
+ }
+
+ private static Field getPrivateField(Class<?> clazz, String fieldName) throws NoSuchFieldException {
+ Field field = clazz.getDeclaredField(fieldName);
+ if (!field.isAccessible()) {
+ field.setAccessible(true);
+ }
+
+ return field;
+ }
+
+ private static Resource findResource(Resource root, Resource template, Comparator<Resource> comparator) {
+ if (root == null) return null;
+ if (comparator.compare(root, template) == 0) {
+ return root;
+ } else {
+ for(Resource child : root.getChildResources()) {
+ Resource found = findResource(child, template, comparator);
+ if (found != null) return found;
+ }
+ }
+
+ return null;
+ }
+
+ private static void findResources(Resource root, Resource template, Set<Resource> result, Comparator<Resource> comparator) {
+ if (root == null) return;
+ if (comparator.compare(root, template) == 0) {
+ result.add(root);
+ } else {
+ for(Resource child : root.getChildResources()) {
+ findResources(child, template, result, comparator);
+ }
+ }
+ }
+}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
new file mode 100644
index 0000000..46d069c
--- /dev/null
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -0,0 +1,345 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.rhq.core.pc.upgrade;
+
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertEquals;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Set;
+
+import org.apache.commons.io.FileUtils;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import org.rhq.core.clientapi.server.bundle.BundleServerService;
+import org.rhq.core.clientapi.server.configuration.ConfigurationServerService;
+import org.rhq.core.clientapi.server.content.ContentServerService;
+import org.rhq.core.clientapi.server.core.CoreServerService;
+import org.rhq.core.clientapi.server.discovery.DiscoveryServerService;
+import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.clientapi.server.event.EventServerService;
+import org.rhq.core.clientapi.server.inventory.ResourceFactoryServerService;
+import org.rhq.core.clientapi.server.measurement.MeasurementServerService;
+import org.rhq.core.clientapi.server.operation.OperationServerService;
+import org.rhq.core.domain.resource.InventoryStatus;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.pc.PluginContainer;
+import org.rhq.core.pc.PluginContainerConfiguration;
+import org.rhq.core.pc.ServerServices;
+import org.rhq.core.pc.inventory.InventoryManager;
+import org.rhq.core.pc.inventory.ResourceContainer;
+import org.rhq.core.pc.plugin.FileSystemPluginFinder;
+
+/**
+ * Test cases for resource upgrade.
+ *
+ * @author Lukas Krejci
+ */
+public class ResourceUpgradeTest {
+
+ private static final String PLUGIN_V1_FILENAME = "resource-upgrade-test-plugin-1.0.0.jar";
+ private static final String PLUGIN_V2_FILENAME = "resource-upgrade-test-plugin-2.0.0.jar";
+
+ private static final String PLUGINS_DIR_NAME = "plugins";
+ private static final String DATA_DIR_NAME = "data";
+ private static final String TMP_DIR_NAME = "tmp";
+
+ private File tmpDir;
+ private File pluginDir;
+ private File dataDir;
+
+ private BundleServerService currentBundleServerService;
+ private ConfigurationServerService currentConfigurationServerService;
+ private ContentServerService currentContentServerService;
+ private CoreServerService currentCoreServerService;
+ private DiscoveryServerService currentDiscoveryServerService;
+ private EventServerService currentEventServerService;
+ private MeasurementServerService currentMeasurementServerService;
+ private OperationServerService currentOperationServerService;
+ private ResourceFactoryServerService currentResourceFactoryServerService;
+
+ private FakeServerInventory currentServerSideInventory;
+
+ @AfterClass
+ public void undeployPlugins() throws IOException {
+ FileUtils.deleteDirectory(tmpDir);
+ }
+
+ @BeforeClass
+ public void sanityCheck() {
+ verifyPluginExists(PLUGIN_V1_FILENAME);
+ verifyPluginExists(PLUGIN_V2_FILENAME);
+ }
+
+ @BeforeClass
+ public void init() {
+ tmpDir = getTmpDirectory();
+ pluginDir = new File(tmpDir, PLUGINS_DIR_NAME);
+ assertTrue(pluginDir.mkdir(), "Could not create plugin deploy directory.");
+ dataDir = new File(tmpDir, DATA_DIR_NAME);
+ assertTrue(dataDir.mkdir(), "Could not create plugin container data directory.");
+ }
+
+ @Test
+ public void testInitialSyncAndDiscoveryWithoutCommit() throws Exception {
+ testInitialSyncAndDiscovery(InventoryStatus.NEW);
+ }
+
+ @Test(dependsOnMethods = "testInitialSyncAndDiscoveryWithoutCommit")
+ public void testIgnoreUncommittedResources() throws Exception {
+ TestPayload testNoChange = new TestPayload() {
+ public void test(Resource discoveredResource) {
+ assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
+ assertEquals(discoveredResource.getName(), "resource-name-v1");
+ assertEquals(discoveredResource.getDescription(), "resource-description-v1");
+ }
+
+ @SuppressWarnings("unchecked")
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineIgnoredExpectations(this);
+
+ between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+
+ allowing(currentDiscoveryServerService).getResources(with(any(Set.class)), with(any(boolean.class)));
+ will(currentServerSideInventory.getResources());
+ }
+ };
+ }
+ };
+
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, testNoChange);
+ }
+
+ //make the tests run serially, so that they don't overwrite the currentServerSideInventory
+ //variable concurrently
+ @Test(dependsOnMethods = "testIgnoreUncommittedResources")
+ public void testInitialSyncAndDiscoveryWithCommit() throws Exception {
+ testInitialSyncAndDiscovery(InventoryStatus.COMMITTED);
+ }
+
+ @Test(dependsOnMethods = "testInitialSyncAndDiscoveryWithCommit")
+ public void testUpgradeData() throws Exception {
+ //we are keeping the currentServerSideInventory from the previous test
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V2_FILENAME), false, new TestPayload() {
+ public void test(Resource discoveredResource) {
+ assertEquals(discoveredResource.getResourceKey(), "resource-key-v2");
+ assertEquals(discoveredResource.getName(), "resource-name-v2");
+ assertEquals(discoveredResource.getDescription(), "resource-description-v2");
+
+ ResourceContainer container = PluginContainer.getInstance().getInventoryManager().getResourceContainer(discoveredResource);
+ File dataDir = container.getResourceContext().getDataDirectory();
+
+ File marker = new File(dataDir, "upgrade-succeeded");
+
+ assertTrue(marker.exists(), "The upgrade success marker file wasn't found. This means the upgrade didn't actually run.");
+ }
+
+ @SuppressWarnings("unchecked")
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineIgnoredExpectations(this);
+
+ between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(currentServerSideInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+
+ oneOf(currentDiscoveryServerService).upgradeResources(with(any(Set.class)));
+ will(currentServerSideInventory.upgradeResources());
+
+ allowing(currentDiscoveryServerService).getResources(with(any(Set.class)), with(any(boolean.class)));
+ will(currentServerSideInventory.getResources());
+ }
+ };
+ }
+ });
+ }
+
+ private void testInitialSyncAndDiscovery(final InventoryStatus requiredInventoryStatus) throws Exception {
+ currentServerSideInventory = new FakeServerInventory();
+ executeTestWithPlugins(Collections.singleton(PLUGIN_V1_FILENAME), true, new TestPayload() {
+ public void test(Resource discoveredResource) {
+ assertEquals(discoveredResource.getResourceKey(), "resource-key-v1");
+ assertEquals(discoveredResource.getName(), "resource-name-v1");
+ assertEquals(discoveredResource.getDescription(), "resource-description-v1");
+ }
+
+ @SuppressWarnings("unchecked")
+ public Expectations getExpectations(Mockery context) throws Exception {
+ return new Expectations() {
+ {
+ defineIgnoredExpectations(this);
+
+ between(1, 4).of(currentDiscoveryServerService).mergeInventoryReport(with(any(InventoryReport.class)));
+ will(currentServerSideInventory.mergeInventoryReport(requiredInventoryStatus));
+
+ allowing(currentDiscoveryServerService).getResources(with(any(Set.class)), with(any(boolean.class)));
+ will(currentServerSideInventory.getResources());
+ }
+ };
+ }
+ });
+
+ }
+
+ private PluginContainerConfiguration createPluginContainerConfiguration(Mockery context) throws Exception {
+ PluginContainerConfiguration conf = new PluginContainerConfiguration();
+
+ conf.setPluginDirectory(new File(tmpDir, PLUGINS_DIR_NAME));
+ conf.setDataDirectory(new File(tmpDir, DATA_DIR_NAME));
+ conf.setTemporaryDirectory(new File(tmpDir, TMP_DIR_NAME));
+ conf.setInsideAgent(true); //pc must think it's inside an agent so that it persists the inventory between restarts
+ conf.setPluginFinder(new FileSystemPluginFinder(conf.getPluginDirectory()));
+ conf.setCreateResourceClassloaders(false);
+
+ currentBundleServerService = context.mock(BundleServerService.class);
+ currentConfigurationServerService = context.mock(ConfigurationServerService.class);
+ currentContentServerService = context.mock(ContentServerService.class);
+ currentCoreServerService = context.mock(CoreServerService.class);
+ currentDiscoveryServerService = context.mock(DiscoveryServerService.class);
+ currentEventServerService = context.mock(EventServerService.class);
+ currentMeasurementServerService = context.mock(MeasurementServerService.class);
+ currentOperationServerService = context.mock(OperationServerService.class);
+ currentResourceFactoryServerService = context.mock(ResourceFactoryServerService.class);
+
+ ServerServices serverServices = new ServerServices();
+ serverServices.setBundleServerService(currentBundleServerService);
+ serverServices.setConfigurationServerService(currentConfigurationServerService);
+ serverServices.setContentServerService(currentContentServerService);
+ serverServices.setCoreServerService(currentCoreServerService);
+ serverServices.setDiscoveryServerService(currentDiscoveryServerService);
+ serverServices.setEventServerService(currentEventServerService);
+ serverServices.setMeasurementServerService(currentMeasurementServerService);
+ serverServices.setOperationServerService(currentOperationServerService);
+ serverServices.setResourceFactoryServerService(currentResourceFactoryServerService);
+
+ conf.setServerServices(serverServices);
+
+ return conf;
+ }
+
+ /**
+ * @param pluginResourcePath
+ */
+ private void verifyPluginExists(String pluginResourcePath) {
+ URL url = getClass().getResource(pluginResourcePath);
+
+ File pluginFile = FileUtils.toFile(url);
+
+ assertTrue(pluginFile.exists(), pluginFile.getAbsoluteFile() + " plugin jar could not be found.");
+ }
+
+ private void copyPlugin(String pluginResourcePath, File pluginDirectory) throws IOException {
+ URL pluginUrl = getClass().getResource(pluginResourcePath);
+
+ File pluginFile = new File(pluginResourcePath);
+ String pluginFileName = pluginFile.getName();
+
+ FileUtils.copyURLToFile(pluginUrl, new File(pluginDirectory, pluginFileName));
+ }
+
+ private static File getTmpDirectory() {
+ File ret = new File(System.getProperty("java.io.tmpdir"), "resource-upgrade-test" + System.currentTimeMillis());
+
+ while (ret.exists() || !ret.mkdir()) {
+ ret = new File(System.getProperty("java.io.tmpdir"), "resource-upgrade-test" + System.currentTimeMillis());
+ }
+
+ return ret;
+ }
+
+ private interface TestPayload {
+ Expectations getExpectations(Mockery context) throws Exception;
+ void test(Resource resourceUpgradeTestResource);
+ }
+
+ private Set<Resource> getTestingResources() {
+ ResourceType resType = PluginContainer.getInstance().getPluginManager().getMetadataManager().getType("Resource", "ResourceUpgradeTest");
+
+ return currentServerSideInventory.findResourcesByType(resType);
+ }
+
+ private void executeTestWithPlugins(Set<String> pluginResourcePaths, boolean clearInventoryDat, TestPayload test) throws Exception {
+ FileUtils.cleanDirectory(new File(tmpDir, PLUGINS_DIR_NAME));
+
+ for(String pluginResourcePath : pluginResourcePaths) {
+ copyPlugin(pluginResourcePath, pluginDir);
+ }
+
+ Mockery context = new Mockery();
+
+ PluginContainerConfiguration pcConfig = createPluginContainerConfiguration(context);
+
+ if (clearInventoryDat) {
+ File inventoryDat = new File(pcConfig.getDataDirectory(), "inventory.dat");
+ inventoryDat.delete();
+ }
+
+ context.checking(test.getExpectations(context));
+
+ PluginContainer.getInstance().setConfiguration(pcConfig);
+ PluginContainer.getInstance().initialize();
+
+ //give the pc the time to finish resource upgrade
+ Thread.sleep(1000);
+
+ //execute full discovery
+ InventoryManager im = PluginContainer.getInstance().getInventoryManager();
+ im.executeServerScanImmediately();
+ im.executeServiceScanImmediately();
+
+ Set<Resource> resources = getTestingResources();
+
+ assertEquals(resources.size(), 1, "There should be only a single testing resource but " + resources + " were found.");
+
+ Resource discoveredResource = resources.iterator().next();
+
+ test.test(discoveredResource);
+
+ PluginContainer.getInstance().shutdown();
+
+ context.assertIsSatisfied();
+ }
+
+ private void defineIgnoredExpectations(Expectations expectations) {
+ expectations.ignoring(currentBundleServerService);
+ expectations.ignoring(currentConfigurationServerService);
+ expectations.ignoring(currentContentServerService);
+ expectations.ignoring(currentCoreServerService);
+ expectations.ignoring(currentEventServerService);
+ expectations.ignoring(currentMeasurementServerService);
+ expectations.ignoring(currentOperationServerService);
+ expectations.ignoring(currentResourceFactoryServerService);
+ }
+}
diff --git a/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-1.0.0.jar b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-1.0.0.jar
new file mode 100644
index 0000000..33a79c0
Binary files /dev/null and b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-1.0.0.jar differ
diff --git a/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar
new file mode 100644
index 0000000..412ae00
Binary files /dev/null and b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/upgrade/resource-upgrade-test-plugin-2.0.0.jar differ
commit 8dae62e89bc703cf2b8e16272b8d9ebc912606dd
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Jun 18 20:22:33 2010 +0200
Correctly handle the upgrade sync up when the agent is connected to the server for the very first time.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 54c6bcc..dbee063 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -900,7 +900,6 @@ public class InventoryManager extends AgentService implements ContainerService,
*/
public boolean handleReport(InventoryReport report, boolean forceServerRoundtrip) {
if (!configuration.isInsideAgent()) {
- //TODO how does resource upgrade behave in the embedded scenario?
return true;
}
@@ -943,7 +942,14 @@ public class InventoryManager extends AgentService implements ContainerService,
return false;
}
- synchInventory(syncInfo);
+ //sync info can be null if the server hasn't received a full inventory report
+ //from us yet. This can happen if this method is being invoked from inside the
+ //resource upgrade executor to sync up with the server side inventory *JUST AFTER*
+ //this agent registered with the server for the very first time. In that case
+ //the server hasn't received any info from us yet.
+ if (syncInfo != null) {
+ synchInventory(syncInfo);
+ }
return true;
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index 76d6265..fd59590 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -156,7 +156,13 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
// Prepare the ResourceSyncInfo tree which contains all the info the PC needs to sync itself up with us.
Resource platform = this.resourceManager.getPlatform(knownAgent);
- ResourceSyncInfo syncInfo = this.entityManager.find(ResourceSyncInfo.class, platform.getId());
+
+ //the platform can be null in only one scenario.. a brand new agent has connected to the server
+ //and that agent is currently trying to upgrade its resources. For that it asks us to send down
+ //the current inventory on the server side. But at this point there isn't any since that very
+ //agent just registered and is starting up for the very first time and therefore hasn't had
+ //a chance yet to send us its full inventory report.
+ ResourceSyncInfo syncInfo = platform != null ? this.entityManager.find(ResourceSyncInfo.class, platform.getId()) : null;
if (log.isDebugEnabled()) {
log.debug("Inventory merge completed in (" + (System.currentTimeMillis() - start) + ")ms");
commit a9622206993586ce28df9e586206cbf981cc7c3b
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri May 28 18:09:24 2010 +0200
Filter out not-commited resources from the upgrade process.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
index 3397e76..bb20054 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
@@ -26,6 +26,7 @@ package org.rhq.core.pc.upgrade;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -37,6 +38,7 @@ import org.apache.commons.logging.LogFactory;
import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.ResourceUpgradeReport;
@@ -203,6 +205,15 @@ public class ResourceUpgradeExecutor implements Runnable {
Set<Resource> siblings = parentResource == null ? Collections.singleton(inventoryManager.getPlatform())
: inventoryManager.getResourcesWithType(resourceType, parentResource.getChildResources());
+ //filter out not committed resources
+ //XXX what about uninventoried or ignored ones? is it correct to not upgrade those?
+ Iterator<Resource> siblingsIterator = siblings.iterator();
+ while (siblingsIterator.hasNext()) {
+ if (siblingsIterator.next().getInventoryStatus() != InventoryStatus.COMMITTED) {
+ siblingsIterator.remove();
+ }
+ }
+
//get the upgrade context of the parent resource so that it can be passed to the upgrade method
//of the discovery component.
ResourceUpgradeContext<?> parentUpgradeContext = null;
commit df4ffc41f2554332ba870eaeb69e20017ea25240
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri May 28 18:08:53 2010 +0200
Improve resource upgrade logging on both agent and server side.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index ba5f316..54c6bcc 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -1194,36 +1194,50 @@ public class InventoryManager extends AgentService implements ContainerService,
//Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
//Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
- ResourceContainer existingResourceContainer = getResourceContainer(upgradeReport.getResourceId());
- if (existingResourceContainer != null) {
- Resource existingResource = existingResourceContainer.getResource();
- if (resourceKey != null) {
- existingResource.setResourceKey(resourceKey);
- }
-
- if (name != null) {
- existingResource.setName(name);
- }
-
-// if (version != null) {
-// existingResource.setVersion(version);
-// }
-
- if (description != null) {
- existingResource.setDescription(description);
+ //only bother if there's something to upgrade at all on this resource.
+ if (resourceKey != null || name != null || description != null) {
+ ResourceContainer existingResourceContainer = getResourceContainer(upgradeReport.getResourceId());
+ if (existingResourceContainer != null) {
+ Resource existingResource = existingResourceContainer.getResource();
+
+ StringBuilder logMessage = new StringBuilder("Resource [")
+ .append(existingResource.toString()).append("] upgraded its ");
+
+ if (resourceKey != null) {
+ existingResource.setResourceKey(resourceKey);
+ logMessage.append("resourceKey, ");
+ }
+
+ if (name != null) {
+ existingResource.setName(name);
+ logMessage.append("name, ");
+ }
+
+// if (version != null) {
+// existingResource.setVersion(version);
+// }
+
+ if (description != null) {
+ existingResource.setDescription(description);
+ logMessage.append("description, ");
+ }
+
+// if (pluginConfiguration != null) {
+// existingResource.setPluginConfiguration(pluginConfiguration);
+// }
+//
+// if (resourceConfiguration != null) {
+// existingResource.setResourceConfiguration(resourceConfiguration);
+// }
+
+ logMessage.replace(logMessage.length() - 1, logMessage.length(),
+ "to become [").append(existingResource.toString()).append("]");
+
+ log.info(logMessage.toString());
+ } else {
+ log.error("Upgraded a resource that is not present on the agent. This should not happen. The id of the missing resource is " + upgradeReport.getResourceId());
}
-
-// if (pluginConfiguration != null) {
-// existingResource.setPluginConfiguration(pluginConfiguration);
-// }
-//
-// if (resourceConfiguration != null) {
-// existingResource.setResourceConfiguration(resourceConfiguration);
-// }
- } else {
- log.error("Upgraded a resource that is not present on the agent. This should not happen. The id of the missing resource is " + upgradeReport.getResourceId());
}
-
}
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index 1101199..76d6265 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -465,65 +465,70 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
/**
* @param existingResource
* @param upgradeReport
- * @return
+ * @return true if the resource was changed, false otherwise
*/
private boolean upgradeResource(Resource resource, ResourceUpgradeReport upgradeReport) {
- boolean changed = false;
if (resource != null) {
String resourceKey = upgradeReport.getNewResourceKey();
String name = upgradeReport.getNewName();
- //String version = upgradeReport.getNewVersion();
+// String version = upgradeReport.getNewVersion();
String description = upgradeReport.getNewDescription();
// Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
// Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
- if (needsUpgrade(resource.getResourceKey(), resourceKey)) {
- log.info("Resource [" + resource + "] upgraded its resource key from [" +
- resource.getResourceKey() + "] to [" + resourceKey + "]");
- changed = true;
- resource.setResourceKey(resourceKey);
- }
-
- if (needsUpgrade(resource.getName(), name)) {
- log.info("Resource [" + resource + "] upgraded its name from [" +
- resource.getName() + "] to [" + name + "]");
- changed = true;
- resource.setName(name);
- }
-
-// if (version != null) {
-// changed = updateResourceVersion(resource, version) || changed;
-// }
-
- if (needsUpgrade(resource.getDescription(), description)) {
- log.info("Resource [" + resource + "] upgraded its description from [" +
- resource.getDescription() + "] to [" + description + "]");
- changed = true;
- resource.setDescription(description);
- }
-
-// if (pluginConfiguration != null) {
-// if (!equalOrNull(pluginConfiguration, resource.getPluginConfiguration())) {
-// log.info("Resource [" + resource + "] upgraded its plugin configuration from [" +
-// resource.getPluginConfiguration() + "] to [" + pluginConfiguration + "]");
-// changed = true;
-// resource.setPluginConfiguration(pluginConfiguration);
+ if (resourceKey != null || name != null || description != null) {
+ StringBuilder logMessage = new StringBuilder("Resource [")
+ .append(resource.toString()).append("] upgraded its ");
+
+ if (needsUpgrade(resource.getResourceKey(), resourceKey)) {
+ resource.setResourceKey(resourceKey);
+ logMessage.append("resourceKey, ");
+ }
+
+ if (needsUpgrade(resource.getName(), name)) {
+ resource.setName(name);
+ logMessage.append("name, ");
+ }
+
+// if (version != null) {
+// changed = updateResourceVersion(resource, version) || changed;
// }
-// }
-//
-// if (resourceConfiguration != null) {
-// if (!equalOrNull(resourceConfiguration, resource.getResourceConfiguration())) {
-// //XXX Will this create a new history entry?
-//
-// log.info("Resource [" + resource + "] upgraded its resource configuration from [" +
-// resource.getResourceConfiguration() + "] to [" + resourceConfiguration + "]");
-//
-// changed = true;
-// resource.setResourceConfiguration(resourceConfiguration);
+
+ if (needsUpgrade(resource.getDescription(), description)) {
+ resource.setDescription(description);
+ logMessage.append("description, ");
+ }
+
+// if (pluginConfiguration != null) {
+// if (!equalOrNull(pluginConfiguration, resource.getPluginConfiguration())) {
+// log.info("Resource [" + resource + "] upgraded its plugin configuration from [" +
+// resource.getPluginConfiguration() + "] to [" + pluginConfiguration + "]");
+// changed = true;
+// resource.setPluginConfiguration(pluginConfiguration);
+// }
// }
-// }
+//
+// if (resourceConfiguration != null) {
+// if (!equalOrNull(resourceConfiguration, resource.getResourceConfiguration())) {
+// //XXX Will this create a new history entry?
+//
+// log.info("Resource [" + resource + "] upgraded its resource configuration from [" +
+// resource.getResourceConfiguration() + "] to [" + resourceConfiguration + "]");
+//
+// changed = true;
+// resource.setResourceConfiguration(resourceConfiguration);
+// }
+// }
+
+ logMessage.replace(logMessage.length() - 1, logMessage.length(),
+ "to become [").append(resource.toString()).append("]");
+
+ log.info(logMessage.toString());
+
+ return true;
+ }
}
- return changed;
+ return false;
}
private void validateInventoryReport(InventoryReport report) throws InvalidInventoryReportException {
@@ -875,18 +880,6 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
updateInventoryStatus(subject, platforms, servers, target);
}
- private static <T> boolean equalOrNull(T a, T b) {
- if (a == null) {
- return b == null;
- } else {
- if (b == null) {
- return false;
- } else {
- return a.equals(b);
- }
- }
- }
-
private static <T> boolean needsUpgrade(T oldValue, T newValue) {
return newValue != null && (oldValue == null || !newValue.equals(oldValue));
}
commit d896c3792ebf8b45938972eb2ff2f45bd990be83
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri May 28 18:08:16 2010 +0200
Run a method in a new thread only if it originates in the interface that is being proxied.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/DiscoveryComponentProxyFactory.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/DiscoveryComponentProxyFactory.java
index f8d1267..4c68970 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/DiscoveryComponentProxyFactory.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/DiscoveryComponentProxyFactory.java
@@ -81,7 +81,7 @@ public class DiscoveryComponentProxyFactory {
// This is the handler that will actually invoke the method calls.
ResourceDiscoveryComponentInvocationHandler handler = new ResourceDiscoveryComponentInvocationHandler(type,
- component, timeout, pluginClassLoader);
+ component, timeout, pluginClassLoader, componentInterface);
// This is the proxy that will look like the discovery component object that the caller will use.
T proxy = (T) Proxy.newProxyInstance(pluginClassLoader, new Class<?>[] { componentInterface }, handler);
@@ -167,9 +167,10 @@ public class DiscoveryComponentProxyFactory {
private final long timeout;
private final ResourceType resourceType;
private final ClassLoader pluginClassLoader;
-
+ private Class<?> componentInterface;
+
public ResourceDiscoveryComponentInvocationHandler(ResourceType type, ResourceDiscoveryComponent component,
- long timeout, ClassLoader pluginClassLoader) {
+ long timeout, ClassLoader pluginClassLoader, Class<?> componentInterface) {
if (timeout <= 0) {
throw new IllegalArgumentException("timeout value is not positive.");
}
@@ -181,6 +182,7 @@ public class DiscoveryComponentProxyFactory {
this.component = component;
this.timeout = timeout;
this.pluginClassLoader = pluginClassLoader;
+ this.componentInterface = componentInterface;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
@@ -189,7 +191,7 @@ public class DiscoveryComponentProxyFactory {
+ "] has been blacklisted and can no longer be invoked.");
}
- if (method.getDeclaringClass().getPackage().getName().startsWith("org.rhq")) {
+ if (componentInterface.isAssignableFrom(method.getDeclaringClass())) {
return invokeInNewThread(method, args);
} else {
// toString(), etc.
commit 708dee442c2519ecc9d27c723e79239b14b25455
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu May 27 19:04:32 2010 +0200
Fixing a stupid bug that would cause no initial sync to happen during upgrade.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 83743d9..ba5f316 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -883,13 +883,22 @@ public class InventoryManager extends AgentService implements ContainerService,
}
/**
+ * @see #handleReport(InventoryReport, boolean)
+ * @param report
+ * @return
+ */
+ public boolean handleReport(InventoryReport report) {
+ return handleReport(report, false);
+ }
+
+ /**
* Send an inventory report to the Server.
*
* @param report the inventory report to be sent
- *
+ * @param forceServerRoundtrip whether to report to the server even if there are no resources to report.
* @return true if sending the report to the Server succeeded, or false otherwise
*/
- public boolean handleReport(InventoryReport report) {
+ public boolean handleReport(InventoryReport report, boolean forceServerRoundtrip) {
if (!configuration.isInsideAgent()) {
//TODO how does resource upgrade behave in the embedded scenario?
return true;
@@ -905,7 +914,7 @@ public class InventoryManager extends AgentService implements ContainerService,
resourceUpgradeExecutor.sendRequests();
}
- if (report.getAddedRoots().isEmpty()) {
+ if (report.getAddedRoots().isEmpty() && !forceServerRoundtrip) {
return true; // nothing to do
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
index f0721cb..3397e76 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
@@ -130,7 +130,7 @@ public class ResourceUpgradeExecutor implements Runnable {
//pull the inventory down from the server.
//this will ensure that we have an up-to-date info on the
//server inventory before we try to upgrade.
- boolean syncResult = inventoryManager.handleReport(new InventoryReport(inventoryManager.getAgent()));
+ boolean syncResult = inventoryManager.handleReport(new InventoryReport(inventoryManager.getAgent()), true);
if (!syncResult) {
log.warn("Resource upgrade failed to sync up the inventory with the server.");
return;
commit c9b82d93170e03e564ef2db2c50a007f4d1176dc
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu May 27 18:39:32 2010 +0200
Make the ResourceUpgradeExecutor thread safe (even though it probably shouldn't have to be) and make sure it can only be run once.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java
index 21da6bc..4d61e93 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java
@@ -264,7 +264,7 @@ public class PluginContainer implements ContainerService {
//fire off the resource upgrade as soon as possible. It will run only once per plugin container
//lifetime.
- inventoryManager.executeResourceUpgradeImmediately();
+ inventoryManager.fireResourceUpgrade();
return;
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 7fcfd6e..83743d9 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -507,8 +507,13 @@ public class InventoryManager extends AgentService implements ContainerService,
}
}
- public void executeResourceUpgradeImmediately() {
- resourceUpgradeExecutor.execute();
+ /**
+ * Executes the resource upgrade asynchronously.
+ */
+ public void fireResourceUpgrade() {
+ Thread resourceUpgradeThread = new Thread(resourceUpgradeExecutor, "Resource Upgrade Thread");
+ resourceUpgradeThread.setDaemon(true);
+ resourceUpgradeThread.start();
}
public InventoryReport executeServerScanImmediately() {
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
index d15a1c2..f0721cb 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
@@ -27,9 +27,10 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
-import java.util.Queue;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -55,21 +56,22 @@ import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
*
* @author Lukas Krejci
*/
-public class ResourceUpgradeExecutor {
+public class ResourceUpgradeExecutor implements Runnable {
private static final Log log = LogFactory.getLog(ResourceUpgradeExecutor.class);
/**
* The upgrade runs only once in its lifetime.
*/
- private boolean enabled = true;
-
+ private AtomicBoolean enabled = new AtomicBoolean(true);
+ private AtomicBoolean started = new AtomicBoolean(false);
+
private InventoryManager inventoryManager;
- private Set<ResourceUpgradeReport> reports;
+ private ConcurrentLinkedQueue<ResourceUpgradeReport> reports;
public ResourceUpgradeExecutor(InventoryManager inventoryManager) {
this.inventoryManager = inventoryManager;
- reports = new HashSet<ResourceUpgradeReport>();
+ reports = new ConcurrentLinkedQueue<ResourceUpgradeReport>();
}
/**
@@ -90,14 +92,14 @@ public class ResourceUpgradeExecutor {
public <T extends ResourceComponent> Map<ResourceUpgradeContext<T>, ResourceUpgradeReport> processAndQueue(
ResourceUpgradeRequest<T> request, Set<Resource> discoveredResources) {
- return enabled ? executeResourceUpgradeAndStoreReport(request, discoveredResources) : null;
+ return enabled.get() ? executeResourceUpgradeAndStoreReport(request, discoveredResources) : null;
}
/**
* @return true if the executor is ready to perform the upgrade, false otherwise.
*/
public boolean isEnabled() {
- return enabled;
+ return enabled.get();
}
/**
@@ -105,9 +107,10 @@ public class ResourceUpgradeExecutor {
* all the upgrade requests.
*/
public void sendRequests() {
- if (enabled && reports.size() > 0) {
- inventoryManager.mergeResourceFromUpgrade(reports);
- reports.clear();
+ if (enabled.get() && reports.size() > 0) {
+ HashSet<ResourceUpgradeReport> currentCopy = new HashSet<ResourceUpgradeReport>(reports);
+ inventoryManager.mergeResourceFromUpgrade(currentCopy);
+ reports.removeAll(currentCopy);
}
}
@@ -117,8 +120,8 @@ public class ResourceUpgradeExecutor {
* After that a full discovery is performed and both the upgrade report and discovery report
* are sent to the server.
*/
- public void execute() {
- if (enabled) {
+ public void run() {
+ if (!started.getAndSet(true)) {
if (log.isDebugEnabled()) {
log.debug("Starting resource upgrade.");
}
@@ -140,7 +143,7 @@ public class ResourceUpgradeExecutor {
log.warn("Resource upgrade failed.", t);
} finally {
//make sure to switch off the upgrade...
- this.enabled = false;
+ this.enabled.set(false);
//clear up so that we don't hold unnecessary instances.
reports.clear();
commit 760871c264eca5adf2cf322a48614b3cd68a3640
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu May 27 18:11:49 2010 +0200
Avoid deadlock by invoking the resource upgrade only after all services are initialized, removing the ability to perform plugin/resource configuration upgrades, generally made stuff work.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
index bfeba0d..979c456 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
@@ -44,9 +44,18 @@ public class ResourceUpgradeReport implements Serializable {
private int resourceId;
private String newResourceKey;
private String newName;
- private String newVersion;
- private Configuration newPluginConfiguration;
- private Configuration newResourceConfiguration;
+
+// version changes are handled differently.
+// private String newVersion;
+
+// upgrading configurations would have large consequences.
+// it would be difficult to synchronize the upgrade process
+// with the agent or server initiated configuration updates.
+// It could also be difficult for the UI to reflect more complicated
+// structural changes as currently, it is assumed that
+// the configurations are kept backwards compatible.
+// private Configuration newPluginConfiguration;
+// private Configuration newResourceConfiguration;
private String newDescription;
public ResourceUpgradeReport() {
@@ -85,29 +94,29 @@ public class ResourceUpgradeReport implements Serializable {
this.newName = newName;
}
- public String getNewVersion() {
- return newVersion;
- }
-
- public void setNewVersion(String newVersion) {
- this.newVersion = newVersion;
- }
-
- public Configuration getNewPluginConfiguration() {
- return newPluginConfiguration;
- }
-
- public void setNewPluginConfiguration(Configuration newPluginConfiguration) {
- this.newPluginConfiguration = newPluginConfiguration;
- }
-
- public Configuration getNewResourceConfiguration() {
- return newResourceConfiguration;
- }
-
- public void setNewResourceConfiguration(Configuration newResourceConfiguration) {
- this.newResourceConfiguration = newResourceConfiguration;
- }
+// public String getNewVersion() {
+// return newVersion;
+// }
+//
+// public void setNewVersion(String newVersion) {
+// this.newVersion = newVersion;
+// }
+//
+// public Configuration getNewPluginConfiguration() {
+// return newPluginConfiguration;
+// }
+//
+// public void setNewPluginConfiguration(Configuration newPluginConfiguration) {
+// this.newPluginConfiguration = newPluginConfiguration;
+// }
+//
+// public Configuration getNewResourceConfiguration() {
+// return newResourceConfiguration;
+// }
+//
+// public void setNewResourceConfiguration(Configuration newResourceConfiguration) {
+// this.newResourceConfiguration = newResourceConfiguration;
+// }
public String getNewDescription() {
return newDescription;
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java
index 8970404..21da6bc 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/PluginContainer.java
@@ -262,6 +262,10 @@ public class PluginContainer implements ContainerService {
releaseLock(lock);
}
+ //fire off the resource upgrade as soon as possible. It will run only once per plugin container
+ //lifetime.
+ inventoryManager.executeResourceUpgradeImmediately();
+
return;
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 044aa25..7fcfd6e 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -250,16 +250,7 @@ public class InventoryManager extends AgentService implements ContainerService,
.getServiceDiscoveryInitialDelay(), configuration.getServiceDiscoveryPeriod(), TimeUnit.SECONDS);
}
- //try to perform the full resource upgrade now.
- //The initialization time is ideal for this because inventory manager
- //is the first plugin container service to start and hence we can
- //be sure that no under concurrent updates to the resources are happening.
- //Because PC doesn't support online updates of plugins and needs to be restarted
- //in order to pick up the changed plugins, we can be sure that running the
- //upgrade only once at the PC start up is enough for the lifetime of
- //plugin container (and hence this instance of InventoryManager).
resourceUpgradeExecutor = new ResourceUpgradeExecutor(this);
- resourceUpgradeExecutor.execute();
} finally {
inventoryLock.writeLock().unlock();
}
@@ -516,6 +507,10 @@ public class InventoryManager extends AgentService implements ContainerService,
}
}
+ public void executeResourceUpgradeImmediately() {
+ resourceUpgradeExecutor.execute();
+ }
+
public InventoryReport executeServerScanImmediately() {
try {
return inventoryThreadPoolExecutor.submit((Callable<InventoryReport>) this.serverScanExecutor).get();
@@ -1180,10 +1175,10 @@ public class InventoryManager extends AgentService implements ContainerService,
for (ResourceUpgradeReport upgradeReport : upgradeReports) {
String resourceKey = upgradeReport.getNewResourceKey();
String name = upgradeReport.getNewName();
- String version = upgradeReport.getNewVersion();
+ //String version = upgradeReport.getNewVersion();
String description = upgradeReport.getNewDescription();
- Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
- Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
+ //Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
+ //Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
ResourceContainer existingResourceContainer = getResourceContainer(upgradeReport.getResourceId());
if (existingResourceContainer != null) {
@@ -1196,21 +1191,21 @@ public class InventoryManager extends AgentService implements ContainerService,
existingResource.setName(name);
}
- if (version != null) {
- existingResource.setVersion(version);
- }
+// if (version != null) {
+// existingResource.setVersion(version);
+// }
if (description != null) {
existingResource.setDescription(description);
}
- if (pluginConfiguration != null) {
- existingResource.setPluginConfiguration(pluginConfiguration);
- }
-
- if (resourceConfiguration != null) {
- existingResource.setResourceConfiguration(resourceConfiguration);
- }
+// if (pluginConfiguration != null) {
+// existingResource.setPluginConfiguration(pluginConfiguration);
+// }
+//
+// if (resourceConfiguration != null) {
+// existingResource.setResourceConfiguration(resourceConfiguration);
+// }
} else {
log.error("Upgraded a resource that is not present on the agent. This should not happen. The id of the missing resource is " + upgradeReport.getResourceId());
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
index b00dfd4..d15a1c2 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
@@ -69,6 +69,7 @@ public class ResourceUpgradeExecutor {
public ResourceUpgradeExecutor(InventoryManager inventoryManager) {
this.inventoryManager = inventoryManager;
+ reports = new HashSet<ResourceUpgradeReport>();
}
/**
@@ -104,8 +105,9 @@ public class ResourceUpgradeExecutor {
* all the upgrade requests.
*/
public void sendRequests() {
- if (enabled) {
+ if (enabled && reports.size() > 0) {
inventoryManager.mergeResourceFromUpgrade(reports);
+ reports.clear();
}
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index 44f79a2..1101199 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -472,67 +472,56 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
if (resource != null) {
String resourceKey = upgradeReport.getNewResourceKey();
String name = upgradeReport.getNewName();
- String version = upgradeReport.getNewVersion();
+ //String version = upgradeReport.getNewVersion();
String description = upgradeReport.getNewDescription();
- Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
- Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
+// Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
+// Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
- if (resourceKey != null) {
- if (!equalOrNull(resourceKey, resource.getResourceKey())) {
- log.info("Resource [" + resource + "] upgraded its resource key from [" +
- resource.getResourceKey() + "] to [" + resourceKey + "]");
- changed = true;
- resource.setResourceKey(resourceKey);
- }
- }
-
- if (name != null) {
- if (!equalOrNull(name, resource.getName())) {
- log.info("Resource [" + resource + "] upgraded its name from [" +
- resource.getName() + "] to [" + name + "]");
- changed = true;
- resource.setName(name);
- }
- }
-
- if (version != null) {
- changed = updateResourceVersion(resource, version) || changed;
+ if (needsUpgrade(resource.getResourceKey(), resourceKey)) {
+ log.info("Resource [" + resource + "] upgraded its resource key from [" +
+ resource.getResourceKey() + "] to [" + resourceKey + "]");
+ changed = true;
+ resource.setResourceKey(resourceKey);
}
- if (description != null) {
- if (!equalOrNull(description, resource.getDescription())) {
- log.info("Resource [" + resource + "] upgraded its description from [" +
- resource.getDescription() + "] to [" + description + "]");
- changed = true;
- resource.setDescription(description);
- }
+ if (needsUpgrade(resource.getName(), name)) {
+ log.info("Resource [" + resource + "] upgraded its name from [" +
+ resource.getName() + "] to [" + name + "]");
+ changed = true;
+ resource.setName(name);
}
- if (pluginConfiguration != null) {
- if (!equalOrNull(pluginConfiguration, resource.getPluginConfiguration())) {
- log.info("Resource [" + resource + "] upgraded its plugin configuration from [" +
- resource.getPluginConfiguration() + "] to [" + pluginConfiguration + "]");
- changed = true;
- resource.setPluginConfiguration(pluginConfiguration);
- }
- }
+// if (version != null) {
+// changed = updateResourceVersion(resource, version) || changed;
+// }
- if (resourceConfiguration != null) {
- if (!equalOrNull(resourceConfiguration, resource.getResourceConfiguration())) {
- //XXX Will this create a new history entry?
-
- log.info("Resource [" + resource + "] upgraded its resource configuration from [" +
- resource.getResourceConfiguration() + "] to [" + resourceConfiguration + "]");
-
- changed = true;
- resource.setResourceConfiguration(resourceConfiguration);
- }
+ if (needsUpgrade(resource.getDescription(), description)) {
+ log.info("Resource [" + resource + "] upgraded its description from [" +
+ resource.getDescription() + "] to [" + description + "]");
+ changed = true;
+ resource.setDescription(description);
}
- // If the resource was marked as deleted, reactivate it again.
- if (resource.getInventoryStatus() == InventoryStatus.DELETED) {
- resource.setInventoryStatus(InventoryStatus.COMMITTED);
- }
+// if (pluginConfiguration != null) {
+// if (!equalOrNull(pluginConfiguration, resource.getPluginConfiguration())) {
+// log.info("Resource [" + resource + "] upgraded its plugin configuration from [" +
+// resource.getPluginConfiguration() + "] to [" + pluginConfiguration + "]");
+// changed = true;
+// resource.setPluginConfiguration(pluginConfiguration);
+// }
+// }
+//
+// if (resourceConfiguration != null) {
+// if (!equalOrNull(resourceConfiguration, resource.getResourceConfiguration())) {
+// //XXX Will this create a new history entry?
+//
+// log.info("Resource [" + resource + "] upgraded its resource configuration from [" +
+// resource.getResourceConfiguration() + "] to [" + resourceConfiguration + "]");
+//
+// changed = true;
+// resource.setResourceConfiguration(resourceConfiguration);
+// }
+// }
}
return changed;
}
@@ -897,4 +886,8 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
}
}
}
+
+ private static <T> boolean needsUpgrade(T oldValue, T newValue) {
+ return newValue != null && (oldValue == null || !newValue.equals(oldValue));
+ }
}
\ No newline at end of file
commit 1fe97fb0bb997c5e6c023adca8bb94da0fca7c79
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu May 27 16:18:21 2010 +0200
Actually call out back to inv manager to perform the upgrade.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
index f0f2b43..b00dfd4 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
@@ -105,7 +105,7 @@ public class ResourceUpgradeExecutor {
*/
public void sendRequests() {
if (enabled) {
- //TODO implement
+ inventoryManager.mergeResourceFromUpgrade(reports);
}
}
commit d0d2e582e00344b1720ee9d01a730fa1d1c3cb46
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu May 27 15:58:35 2010 +0200
reimplemented the upgrade process on the agent to happen only at init time. the server receives a full batch of upgrades, not one upgrade after another.
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
index cfa2459..61e5084 100644
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
@@ -138,13 +138,12 @@ public interface DiscoveryServerService {
boolean updateResourceVersion(int resourceId, String version);
/**
- * Upgrades the data of the resource according to the provided report.
+ * Upgrades the data of the resources according to the provided reports.
*
- * @param resourceId the id of the resource to be upgraded
- * @param upgradeReport contains the information about the upgrade
+ * @param upgradeReports contains the information about the upgrade of individual resources.
* @return true if the upgrade succeeded, false otherwise.
*/
- boolean upgradeResource(int resourceId, ResourceUpgradeReport upgradeReport);
+ boolean upgradeResources(Set<ResourceUpgradeReport> upgradeReports);
/**
* Gives the server a chance to apply any necessary post-processing that's needed for newly committed resources
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
index 52acf09..bfeba0d 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
@@ -41,6 +41,7 @@ public class ResourceUpgradeReport implements Serializable {
private static final long serialVersionUID = 1L;
+ private int resourceId;
private String newResourceKey;
private String newName;
private String newVersion;
@@ -52,6 +53,22 @@ public class ResourceUpgradeReport implements Serializable {
}
+ /**
+ * The server-side id of the resource being upgraded.
+ * The discovery components don't need to assign this value.
+ */
+ public int getResourceId() {
+ return resourceId;
+ }
+
+ /**
+ * The server-side id of the resource being upgraded.
+ * The discovery components don't need to assign this value.
+ */
+ public void setResourceId(int resourceId) {
+ this.resourceId = resourceId;
+ }
+
public String getNewResourceKey() {
return newResourceKey;
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 032256b..044aa25 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -33,9 +33,11 @@ import java.util.IdentityHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
+import java.util.Queue;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@@ -89,6 +91,8 @@ import org.rhq.core.pc.plugin.BlacklistedException;
import org.rhq.core.pc.plugin.CanonicalResourceKey;
import org.rhq.core.pc.plugin.PluginComponentFactory;
import org.rhq.core.pc.plugin.PluginManager;
+import org.rhq.core.pc.upgrade.ResourceUpgradeExecutor;
+import org.rhq.core.pc.upgrade.ResourceUpgradeRequest;
import org.rhq.core.pc.util.DiscoveryComponentProxyFactory;
import org.rhq.core.pc.util.FacetLockType;
import org.rhq.core.pc.util.LoggingThreadFactory;
@@ -186,6 +190,11 @@ public class InventoryManager extends AgentService implements ContainerService,
*/
private AvailabilityCollectorThreadPool availabilityCollectors;
+ /**
+ * Handles the resource upgrade during the initialization of the inventory manager.
+ */
+ private ResourceUpgradeExecutor resourceUpgradeExecutor;
+
public InventoryManager() {
super(DiscoveryAgentService.class);
}
@@ -240,6 +249,17 @@ public class InventoryManager extends AgentService implements ContainerService,
inventoryThreadPoolExecutor.scheduleWithFixedDelay(serviceScanExecutor, configuration
.getServiceDiscoveryInitialDelay(), configuration.getServiceDiscoveryPeriod(), TimeUnit.SECONDS);
}
+
+ //try to perform the full resource upgrade now.
+ //The initialization time is ideal for this because inventory manager
+ //is the first plugin container service to start and hence we can
+ //be sure that no under concurrent updates to the resources are happening.
+ //Because PC doesn't support online updates of plugins and needs to be restarted
+ //in order to pick up the changed plugins, we can be sure that running the
+ //upgrade only once at the PC start up is enough for the lifetime of
+ //plugin container (and hence this instance of InventoryManager).
+ resourceUpgradeExecutor = new ResourceUpgradeExecutor(this);
+ resourceUpgradeExecutor.execute();
} finally {
inventoryLock.writeLock().unlock();
}
@@ -356,6 +376,23 @@ public class InventoryManager extends AgentService implements ContainerService,
return results;
}
+ public <T extends ResourceComponent> Map<ResourceUpgradeContext<T>, ResourceUpgradeReport> invokeDiscoveryComponentResourceUpgradeFacet(
+ ResourceType resourceType, ResourceDiscoveryComponent<T> component,
+ Set<ResourceUpgradeContext<T>> inventoriedSiblings, ResourceUpgradeContext<?> parent,
+ Set<ResourceUpgradeContext<T>> discoveredResources) throws Throwable {
+
+ long timeout = getDiscoveryComponentTimeout(resourceType);
+ try {
+ @SuppressWarnings("unchecked")
+ ResourceUpgradeFacet<T> proxy = this.discoveryComponentProxyFactory.getDiscoveryComponentProxy(resourceType, component, timeout, ResourceUpgradeFacet.class);
+
+ return proxy.upgrade(inventoriedSiblings, parent, discoveredResources);
+ } catch (BlacklistedException e) {
+ log.debug(e);
+ return Collections.emptyMap();
+ }
+ }
+
public DiscoveryComponentProxyFactory getDiscoveryComponentProxyFactory() {
return this.discoveryComponentProxyFactory;
}
@@ -854,8 +891,20 @@ public class InventoryManager extends AgentService implements ContainerService,
*/
public boolean handleReport(InventoryReport report) {
if (!configuration.isInsideAgent()) {
+ //TODO how does resource upgrade behave in the embedded scenario?
return true;
}
+
+ //finish the resource upgrade.
+ //by now all the resource upgrade requests have been processed
+ //by the executor, which means that the inventory report
+ //we got already only contains the "correct" new resources and
+ //that the executor has all the upgrade requests queued up
+ //to be sent to the server in a batch.
+ if (resourceUpgradeExecutor.isEnabled()) {
+ resourceUpgradeExecutor.sendRequests();
+ }
+
if (report.getAddedRoots().isEmpty()) {
return true; // nothing to do
}
@@ -925,6 +974,7 @@ public class InventoryManager extends AgentService implements ContainerService,
log.debug(String.format("DONE syncing local inventory [%d] ms.",
(System.currentTimeMillis() - startTime)));
}
+
// If we synced any Resources, one or more Resource components were probably started,
// so run an avail check to report on their availabilities immediately. Also kick off
// a service scan to scan those Resources for new child Resources. Kick both tasks off
@@ -941,7 +991,7 @@ public class InventoryManager extends AgentService implements ContainerService,
throw new RuntimeException(t);
}
}
-
+
private void getAllUuids(ResourceSyncInfo syncInfo, Set<String> allServerSideUuids) {
allServerSideUuids.add(syncInfo.getUuid());
for (ResourceSyncInfo child : syncInfo.getChildSyncInfos()) {
@@ -1113,49 +1163,58 @@ public class InventoryManager extends AgentService implements ContainerService,
return resourceContainer.updateAvailability(availabilityType);
}
- private boolean mergeResourceFromUpgrade(Resource existingResource, ResourceUpgradeReport upgradeReport) {
- String resourceKey = upgradeReport.getNewResourceKey();
- String name = upgradeReport.getNewName();
- String version = upgradeReport.getNewVersion();
- String description = upgradeReport.getNewDescription();
- Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
- Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
-
+ public boolean mergeResourceFromUpgrade(Set<ResourceUpgradeReport> upgradeReports) {
boolean serverUpdated = false;
try {
ServerServices serverServices = this.configuration.getServerServices();
if (serverServices != null) {
DiscoveryServerService discoveryServerService = serverServices.getDiscoveryServerService();
- serverUpdated = discoveryServerService.upgradeResource(existingResource.getId(), upgradeReport);
+ serverUpdated = discoveryServerService.upgradeResources(upgradeReports);
}
} catch (Exception e) {
- log.error("Failed to upgrade the resource [" + existingResource + "] on the server.", e);
+ log.error("Failed to process resource upgrades on the server.", e);
}
if (serverUpdated) {
- if (resourceKey != null) {
- existingResource.setResourceKey(resourceKey);
- }
-
- if (name != null) {
- existingResource.setName(name);
- }
-
- if (version != null) {
- existingResource.setVersion(version);
- }
-
- if (description != null) {
- existingResource.setDescription(description);
- }
-
- if (pluginConfiguration != null) {
- existingResource.setPluginConfiguration(pluginConfiguration);
- }
-
- if (resourceConfiguration != null) {
- existingResource.setResourceConfiguration(resourceConfiguration);
+ for (ResourceUpgradeReport upgradeReport : upgradeReports) {
+ String resourceKey = upgradeReport.getNewResourceKey();
+ String name = upgradeReport.getNewName();
+ String version = upgradeReport.getNewVersion();
+ String description = upgradeReport.getNewDescription();
+ Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
+ Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
+
+ ResourceContainer existingResourceContainer = getResourceContainer(upgradeReport.getResourceId());
+ if (existingResourceContainer != null) {
+ Resource existingResource = existingResourceContainer.getResource();
+ if (resourceKey != null) {
+ existingResource.setResourceKey(resourceKey);
+ }
+
+ if (name != null) {
+ existingResource.setName(name);
+ }
+
+ if (version != null) {
+ existingResource.setVersion(version);
+ }
+
+ if (description != null) {
+ existingResource.setDescription(description);
+ }
+
+ if (pluginConfiguration != null) {
+ existingResource.setPluginConfiguration(pluginConfiguration);
+ }
+
+ if (resourceConfiguration != null) {
+ existingResource.setResourceConfiguration(resourceConfiguration);
+ }
+ } else {
+ log.error("Upgraded a resource that is not present on the agent. This should not happen. The id of the missing resource is " + upgradeReport.getResourceId());
+ }
+
}
}
@@ -1453,6 +1512,23 @@ public class InventoryManager extends AgentService implements ContainerService,
this.configuration.getPluginContainerDeployment()); // helps components make determinations of what to do
}
+ public <T extends ResourceComponent> ResourceUpgradeContext<T> createResourceUpgradeContext(Resource resource, T parentComponent, ResourceDiscoveryComponent<T> discoveryComponent) {
+ File pluginDataDir = new File(this.configuration.getDataDirectory(), resource.getResourceType().getPlugin());
+
+ return new ResourceUpgradeContext<T>(resource, // the resource itself
+ parentComponent, // its parent component
+ discoveryComponent, // the discovery component (this is actually the proxy to it)
+ SystemInfoFactory.createSystemInfo(), // for native access
+ this.configuration.getTemporaryDirectory(), // location for plugin to write temp files
+ pluginDataDir, // location for plugin to write data files
+ this.configuration.getContainerName(), // the name of the agent/PC
+ getEventContext(resource), // for event access
+ getOperationContext(resource), // for operation manager access
+ getContentContext(resource), // for content manager access
+ this.availabilityCollectors, // for components that want to perform async avail checking
+ this.configuration.getPluginContainerDeployment()); // helps components make determinations of what to do
+ }
+
/**
* This will send a resource error to the server (if applicable) to indicate that the given resource could not be
* connected to due to an invalid plugin configuration.
@@ -1536,7 +1612,7 @@ public class InventoryManager extends AgentService implements ContainerService,
return getResourcesWithType(serverType, this.platform.getChildResources());
}
- private Set<Resource> getResourcesWithType(ResourceType serverType, Set<Resource> resources) {
+ public Set<Resource> getResourcesWithType(ResourceType serverType, Set<Resource> resources) {
Set<Resource> servers = new HashSet<Resource>();
if (resources == null) {
@@ -2061,76 +2137,10 @@ public class InventoryManager extends AgentService implements ContainerService,
newResources.add(newResource);
}
}
-
- //check if the discovery component supports resource upgrade
- //if it does, perform the resource upgrade straight away here during the discovery process.
- if (discoveryComponent instanceof ResourceUpgradeFacet) {
- ResourceUpgradeFacet resourceUpgrade = (ResourceUpgradeFacet) discoveryComponent;
-
- //the siblings are the resources of the type that is currently being discovered that are already
- //present in the inventory. These are the candidate resources for the upgrade.
- Set<Resource> siblings = getResourcesWithType(resourceType, parentResource.getChildResources());
-
- ResourceUpgradeContext<?> parentUpgradeContext = null;
-
- //get the upgrade context of the parent resource so that it can be passed to the upgrade method
- //of the discovery component.
- if (parentResource != null) {
- Resource grandParent = parentResource.getParentResource();
- ResourceContainer grandParentContainer = grandParent == null ? null : getResourceContainer(grandParent);
- ResourceDiscoveryComponent parentDiscoveryComponent = PluginContainer.getInstance().getPluginComponentFactory()
- .getDiscoveryComponent(parentResource.getResourceType(), grandParentContainer);
-
- parentUpgradeContext = new ResourceUpgradeContext(parentResource, parentDiscoveryComponent, parentResourceContext, availabilityCollectors);
- }
-
- //convert the sibling resources into upgrade context objects so that the plugin methods don't access the
- //domain objects directly.
- Set<ResourceUpgradeContext> siblingContexts = new HashSet<ResourceUpgradeContext>(siblings.size());
-
- //but we are going to need to update the resources in the end, so map the contexts with the resources.
- Map<ResourceUpgradeContext, Resource> siblingContextToResource = new HashMap<ResourceUpgradeContext, Resource>();
-
- for (Resource sibling : siblings) {
- ResourceUpgradeContext siblingContext = new ResourceUpgradeContext(sibling, discoveryComponent, getResourceContainer(sibling).getResourceContext(), availabilityCollectors);
- siblingContexts.add(siblingContext);
- siblingContextToResource.put(siblingContext, sibling);
- }
-
- //covert the new resources into contexts.
- //map the resources by resource key so that we can later check for uniqueness of the reported results.
- Set<ResourceUpgradeContext> newResourceContexts = new HashSet<ResourceUpgradeContext>();
- Map<String, Resource> newResourceKeyToResource = new HashMap<String, Resource>();
-
- for (Resource newResource : newResources) {
- ResourceUpgradeContext newUpgradeContext = new ResourceUpgradeContext(newResource, discoveryComponent, createResourceContext(newResource, parentComponent, discoveryComponent), availabilityCollectors);
- newResourceContexts.add(newUpgradeContext);
- newResourceKeyToResource.put(newResource.getResourceKey(), newResource);
- }
-
- //ask the discovery component to upgrade the siblings.
- Map<ResourceUpgradeContext, ResourceUpgradeReport> results = resourceUpgrade.upgrade(siblingContexts, parentUpgradeContext, newResourceContexts);
-
- //now go through the results and upgrade the resources as needed.
- for(Map.Entry<ResourceUpgradeContext, ResourceUpgradeReport> upgradeEntry : results.entrySet()) {
- Resource siblingToUpgrade = siblingContextToResource.get(upgradeEntry.getKey());
- ResourceUpgradeReport newData = upgradeEntry.getValue();
-
- //upgrade the data on the server first
- mergeResourceFromUpgrade(siblingToUpgrade, newData);
-
- //if there was a resource key upgrade, remove a resource with the same resource key
- //from the discovery results. Otherwise we'd end up with 2 sibling resources with
- //the same resource key, which is illegal.
- if (newData.getNewResourceKey() != null) {
- Resource newResourceToRemove = newResourceKeyToResource.get(newData.getNewResourceKey());
- if (newResourceToRemove != null) {
- newResources.remove(newResourceToRemove);
- }
- }
- }
- }
+ if (resourceUpgradeExecutor.isEnabled()) {
+ resourceUpgradeExecutor.processAndQueue(new ResourceUpgradeRequest(newResources, context, parentResource.getId()), newResources);
+ }
} catch (Throwable e) {
// TODO GH: Add server/parent - up/down semantics so this won't happen just because a server is not up
long elapsedTime = System.currentTimeMillis() - startTime;
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
new file mode 100644
index 0000000..f0f2b43
--- /dev/null
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeExecutor.java
@@ -0,0 +1,285 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.rhq.core.pc.upgrade;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.clientapi.agent.PluginContainerException;
+import org.rhq.core.clientapi.server.discovery.InventoryReport;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
+import org.rhq.core.pc.PluginContainer;
+import org.rhq.core.pc.inventory.InventoryManager;
+import org.rhq.core.pc.inventory.ResourceContainer;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
+
+/**
+ * This class is responsible for performing the resource upgrade on behalf on of {@link InventoryManager}.
+ * Despite its name, it is not an {@link java.util.concurrent.Executor} implementation.
+ *
+ * @author Lukas Krejci
+ */
+public class ResourceUpgradeExecutor {
+ private static final Log log = LogFactory.getLog(ResourceUpgradeExecutor.class);
+
+ /**
+ * The upgrade runs only once in its lifetime.
+ */
+ private boolean enabled = true;
+
+ private InventoryManager inventoryManager;
+
+ private Set<ResourceUpgradeReport> reports;
+
+ public ResourceUpgradeExecutor(InventoryManager inventoryManager) {
+ this.inventoryManager = inventoryManager;
+ }
+
+ /**
+ * This method is called from within the {@link InventoryManager} during the
+ * discovery process as individual upgrade requests are generated.
+ * <p>
+ * This method calls the appropriate discovery component to perform the upgrade and
+ * at the same time stores off the results so that they can be sent to the server
+ * at the end of the discovery in one big batch.
+ * <p>
+ * The provided set of discovery results is updated if this method detects that an existing
+ * resource upgrade would result in a resource key collision with some of the newly discovered
+ * resources.
+ *
+ * @param request the upgrade request
+ * @param discoveredResources the set of discovered resources that this method can optionally remove some elements from.
+ */
+ public <T extends ResourceComponent> Map<ResourceUpgradeContext<T>, ResourceUpgradeReport> processAndQueue(
+ ResourceUpgradeRequest<T> request, Set<Resource> discoveredResources) {
+
+ return enabled ? executeResourceUpgradeAndStoreReport(request, discoveredResources) : null;
+ }
+
+ /**
+ * @return true if the executor is ready to perform the upgrade, false otherwise.
+ */
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ /**
+ * This method is called from within the {@link InventoryManager} once it's collected
+ * all the upgrade requests.
+ */
+ public void sendRequests() {
+ if (enabled) {
+ //TODO implement
+ }
+ }
+
+ /**
+ * Performs the resource upgrade. First, a full inventory report is pulled down from the
+ * server to ensure we have an up-to-date picture of the inventory.
+ * After that a full discovery is performed and both the upgrade report and discovery report
+ * are sent to the server.
+ */
+ public void execute() {
+ if (enabled) {
+ if (log.isDebugEnabled()) {
+ log.debug("Starting resource upgrade.");
+ }
+
+ try {
+ //pull the inventory down from the server.
+ //this will ensure that we have an up-to-date info on the
+ //server inventory before we try to upgrade.
+ boolean syncResult = inventoryManager.handleReport(new InventoryReport(inventoryManager.getAgent()));
+ if (!syncResult) {
+ log.warn("Resource upgrade failed to sync up the inventory with the server.");
+ return;
+ }
+
+ //fire off the full discovery
+ inventoryManager.executeServerScanImmediately();
+ inventoryManager.executeServiceScanImmediately();
+ } catch (Throwable t) {
+ log.warn("Resource upgrade failed.", t);
+ } finally {
+ //make sure to switch off the upgrade...
+ this.enabled = false;
+
+ //clear up so that we don't hold unnecessary instances.
+ reports.clear();
+
+ if (log.isDebugEnabled()) {
+ log.debug("Resource upgrade finished.");
+ }
+ }
+
+ } else {
+ if (log.isDebugEnabled()) {
+ log.debug("ResourceUpgradeExecutor already ran before. Skipping the execution.");
+ }
+ }
+ }
+
+ /**
+ * Executes the resource upgrade request on the agent (if the appropriate discovery component support {@link ResourceUpgradeFacet}).
+ *
+ * @param request the upgrade request to execute on the agent.
+ * @param discoveredResources the set of the discovered resources that this method can remove some elements from
+ * @return the resulting upgrade map as reported by the plugin from {@link ResourceUpgradeFacet#upgrade(Set, ResourceUpgradeContext, Set)} method.
+ *
+ * @throws PluginContainerException
+ */
+ private <T extends ResourceComponent> Map<ResourceUpgradeContext<T>, ResourceUpgradeReport> executeResourceUpgradeAndStoreReport(
+ ResourceUpgradeRequest<T> request, Set<Resource> discoveredResources) {
+
+ ResourceDiscoveryContext<T> discoveryContext = request.getDiscoveryContext();
+ Set<Resource> newResources = request.getDiscoveredResources();
+ Integer parentResourceId = request.getParentResourceId();
+
+ try {
+ ResourceType resourceType = discoveryContext.getResourceType();
+ ResourceContainer parentResourceContainer = null;
+ Resource parentResource = null;
+ if (parentResourceId != null) {
+ parentResourceContainer = inventoryManager.getResourceContainer(parentResourceId);
+ if (parentResourceContainer != null) {
+ parentResource = parentResourceContainer.getResource();
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ ResourceDiscoveryComponent<T> discoveryComponent = PluginContainer.getInstance()
+ .getPluginComponentFactory().getDiscoveryComponent(resourceType, parentResourceContainer);
+
+ ResourceContext<?> parentResourceContext = discoveryContext.getParentResourceContext();
+
+ T parentComponent = discoveryContext.getParentResourceComponent();
+
+ //check if the discovery component supports resource upgrade
+ //if it does, perform the resource upgrade straight away here during the discovery process.
+ if (discoveryComponent instanceof ResourceUpgradeFacet) {
+ //the siblings are the resources of the type that is currently being discovered that are already
+ //present in the inventory. These are the candidate resources for the upgrade.
+ Set<Resource> siblings = parentResource == null ? Collections.singleton(inventoryManager.getPlatform())
+ : inventoryManager.getResourcesWithType(resourceType, parentResource.getChildResources());
+
+ //get the upgrade context of the parent resource so that it can be passed to the upgrade method
+ //of the discovery component.
+ ResourceUpgradeContext<?> parentUpgradeContext = null;
+
+ if (parentResource != null) {
+ Resource grandParent = parentResource.getParentResource();
+ ResourceContainer grandParentContainer = grandParent == null ? null : inventoryManager
+ .getResourceContainer(grandParent);
+
+ @SuppressWarnings("unchecked")
+ ResourceDiscoveryComponent<ResourceComponent> parentDiscoveryComponent = PluginContainer
+ .getInstance().getPluginComponentFactory().getDiscoveryComponent(
+ parentResource.getResourceType(), grandParentContainer);
+
+ ResourceComponent<?> grandParentResourceComponent = grandParentContainer == null ? null
+ : grandParentContainer.getResourceComponent();
+
+ parentUpgradeContext = inventoryManager.createResourceUpgradeContext(parentResource,
+ grandParentResourceComponent, parentDiscoveryComponent);
+ }
+
+ //convert the sibling resources into upgrade context objects so that the plugin methods don't access the
+ //domain objects directly.
+ Set<ResourceUpgradeContext<T>> siblingContexts = new HashSet<ResourceUpgradeContext<T>>(siblings.size());
+
+ //but we are going to need to update the resources in the end, so map the contexts with the resources.
+ Map<ResourceUpgradeContext<T>, Resource> siblingContextToResource = new HashMap<ResourceUpgradeContext<T>, Resource>();
+
+ for (Resource sibling : siblings) {
+ ResourceUpgradeContext<T> siblingContext = inventoryManager.createResourceUpgradeContext(sibling,
+ parentComponent, discoveryComponent);
+ siblingContexts.add(siblingContext);
+ siblingContextToResource.put(siblingContext, sibling);
+ }
+
+ //convert the new resources into contexts.
+ //map the resources by resource key so that we can later check for uniqueness of the reported results.
+ Set<ResourceUpgradeContext<T>> newResourceContexts = new HashSet<ResourceUpgradeContext<T>>();
+ Map<String, Resource> newResourceKeyToResource = new HashMap<String, Resource>();
+
+ for (Resource newResource : newResources) {
+ ResourceUpgradeContext<T> newUpgradeContext = inventoryManager.createResourceUpgradeContext(
+ newResource, parentComponent, discoveryComponent);
+ newResourceContexts.add(newUpgradeContext);
+ newResourceKeyToResource.put(newResource.getResourceKey(), newResource);
+ }
+
+ //ask the discovery component to upgrade the siblings.
+ Map<ResourceUpgradeContext<T>, ResourceUpgradeReport> results;
+ try {
+ results = inventoryManager.invokeDiscoveryComponentResourceUpgradeFacet(resourceType,
+ discoveryComponent, siblingContexts, parentUpgradeContext, newResourceContexts);
+
+ //now go through the results and upgrade the resources as needed.
+ for (Map.Entry<ResourceUpgradeContext<T>, ResourceUpgradeReport> upgradeEntry : results.entrySet()) {
+ Resource siblingToUpgrade = siblingContextToResource.get(upgradeEntry.getKey());
+ ResourceUpgradeReport newData = upgradeEntry.getValue();
+
+ //upgrade the data on the server first
+ newData.setResourceId(siblingToUpgrade.getId());
+ reports.add(newData);
+
+ //if there was a resource key upgrade, remove a resource with the same resource key
+ //from the discovery results. Otherwise we'd end up with 2 sibling resources with
+ //the same resource key, which is illegal.
+ if (newData.getNewResourceKey() != null) {
+ Resource newResourceToRemove = newResourceKeyToResource.get(newData.getNewResourceKey());
+ if (newResourceToRemove != null) {
+ discoveredResources.remove(newResourceToRemove);
+ }
+ }
+ }
+
+ return results;
+ } catch (Throwable t) {
+ log.warn("Exception in discovery component " + discoveryComponent.getClass() + " upgrade method.",
+ t);
+ }
+ }
+ } catch (PluginContainerException e) {
+ log.warn("Failed resource upgrade of children of resource id " + parentResourceId, e);
+ }
+ return null;
+ }
+}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeRequest.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeRequest.java
new file mode 100644
index 0000000..25178ee
--- /dev/null
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/upgrade/ResourceUpgradeRequest.java
@@ -0,0 +1,35 @@
+package org.rhq.core.pc.upgrade;
+
+import java.util.Set;
+
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+
+/**
+ * This class is used to store the requests for resource upgrade that originate in
+ * the discovery workflow, but can only be executed after an inventory sync.
+ */
+public class ResourceUpgradeRequest<T extends ResourceComponent> {
+ private Set<Resource> discoveredResources;
+ private ResourceDiscoveryContext<T> discoveryContext;
+ private Integer parentResourceId;
+
+ public ResourceUpgradeRequest(Set<Resource> discoveredResources, ResourceDiscoveryContext<T> discoveryContext, Integer parentResourceId) {
+ this.discoveredResources = discoveredResources;
+ this.discoveryContext = discoveryContext;
+ this.parentResourceId = parentResourceId;
+ }
+
+ public Set<Resource> getDiscoveredResources() {
+ return discoveredResources;
+ }
+
+ public ResourceDiscoveryContext<T> getDiscoveryContext() {
+ return discoveryContext;
+ }
+
+ public Integer getParentResourceId() {
+ return parentResourceId;
+ }
+}
\ No newline at end of file
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/DiscoveryComponentProxyFactory.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/DiscoveryComponentProxyFactory.java
index 57b9874..f8d1267 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/DiscoveryComponentProxyFactory.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/DiscoveryComponentProxyFactory.java
@@ -189,7 +189,7 @@ public class DiscoveryComponentProxyFactory {
+ "] has been blacklisted and can no longer be invoked.");
}
- if (method.getDeclaringClass().equals(ResourceDiscoveryComponent.class)) {
+ if (method.getDeclaringClass().getPackage().getName().startsWith("org.rhq")) {
return invokeInNewThread(method, args);
} else {
// toString(), etc.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index 2d3e9e6..44f79a2 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -401,17 +401,20 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
}
}
- public boolean upgradeResource(int resourceId, ResourceUpgradeReport upgradeReport) {
- Resource existingResource = this.entityManager.find(Resource.class, resourceId);
- if (existingResource != null) {
- boolean changed = upgradeResource(existingResource, upgradeReport);
- if (changed) {
- this.entityManager.merge(existingResource);
+ public boolean upgradeResources(Set<ResourceUpgradeReport> upgradeReports) {
+ for (ResourceUpgradeReport report : upgradeReports) {
+ Resource existingResource = this.entityManager.find(Resource.class, report.getResourceId());
+ if (existingResource != null) {
+ boolean changed = upgradeResource(existingResource, report);
+ if (changed) {
+ this.entityManager.merge(existingResource);
+ }
+ } else {
+ this.entityManager.getTransaction().setRollbackOnly();
+ return false;
}
- return true;
- } else {
- return false;
}
+ return true;
}
/**
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
index 4e60ffb..af518eb 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
@@ -21,6 +21,7 @@ package org.rhq.enterprise.server.discovery;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import javax.ejb.Local;
@@ -179,11 +180,10 @@ public interface DiscoveryBossLocal extends DiscoveryBossRemote {
boolean updateResourceVersion(int resourceId, String version);
/**
- * Upgrades the data of the resource according to the provided report.
+ * Upgrades the data of the resources according to the provided reports.
*
- * @param resourceId the id of the resource to be upgraded
- * @param upgradeReport contains the information about the upgrade
+ * @param upgradeReports contains the information about the upgrade of individual resources.
* @return true if the upgrade succeeded, false otherwise.
*/
- boolean upgradeResource(int resourceId, ResourceUpgradeReport upgradeReport);
+ boolean upgradeResources(Set<ResourceUpgradeReport> upgradeReports);
}
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
index 720465e..0f90cdc 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
@@ -177,9 +177,9 @@ public class DiscoveryServerServiceImpl implements DiscoveryServerService {
return discoveryBoss.updateResourceVersion(resourceId, version);
}
- public boolean upgradeResource(int resourceId, ResourceUpgradeReport upgradeReport) {
+ public boolean upgradeResources(Set<ResourceUpgradeReport> upgradeReports) {
DiscoveryBossLocal discoveryBoss = LookupUtil.getDiscoveryBoss();
- return discoveryBoss.upgradeResource(resourceId, upgradeReport);
+ return discoveryBoss.upgradeResources(upgradeReports);
}
private static Resource convertToPojoResource(Resource resource, boolean includeDescendants) {
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
index fc001f9..2f3431b 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
@@ -170,10 +170,10 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
return discoveredResources;
}
- public Map<ResourceUpgradeContext, ResourceUpgradeReport> upgrade(Set<ResourceUpgradeContext> inventoriedSiblings,
- ResourceUpgradeContext<PlatformComponent> parentContext, Set<ResourceUpgradeContext> discoveryResults) {
+ public Map<ResourceUpgradeContext<PlatformComponent>, ResourceUpgradeReport> upgrade(Set<ResourceUpgradeContext<PlatformComponent>> inventoriedSiblings,
+ ResourceUpgradeContext<?> parentContext, Set<ResourceUpgradeContext<PlatformComponent>> discoveryResults) {
- Map<ResourceUpgradeContext, ResourceUpgradeReport> ret = new HashMap<ResourceUpgradeContext, ResourceUpgradeReport>();
+ Map<ResourceUpgradeContext<PlatformComponent>, ResourceUpgradeReport> ret = new HashMap<ResourceUpgradeContext<PlatformComponent>, ResourceUpgradeReport>();
for (ResourceUpgradeContext context : inventoriedSiblings) {
String inventoriedResourceKey = context.getResourceKey();
commit 15ee2d7c543480cb636eb0b2c68a773d0728fe78
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu May 27 12:11:54 2010 +0200
Small interface correction.
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
index cea777a..914641c 100644
--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
@@ -37,7 +37,6 @@ import org.rhq.core.pluginapi.inventory.ResourceComponent;
*
* @author Lukas Krejci
*/
-@SuppressWarnings("unchecked")
public interface ResourceUpgradeFacet<T extends ResourceComponent> {
/**
@@ -54,5 +53,5 @@ public interface ResourceUpgradeFacet<T extends ResourceComponent> {
* inventoriedSiblings set, the values are the upgrade reports detailing what the data of the
* corresponding siblings should be upgraded to.
*/
- Map<ResourceUpgradeContext, ResourceUpgradeReport> upgrade(Set<ResourceUpgradeContext> inventoriedSiblings, ResourceUpgradeContext<T> parentContext, Set<ResourceUpgradeContext> discoveryResults);
+ Map<ResourceUpgradeContext<T>, ResourceUpgradeReport> upgrade(Set<ResourceUpgradeContext<T>> inventoriedSiblings, ResourceUpgradeContext<? extends ResourceComponent> parentContext, Set<ResourceUpgradeContext<T>> discoveryResults);
}
commit df9228b55e6fdd293be1b1b030a00fb109fd649c
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed May 26 15:06:37 2010 +0200
added some comments, fixed typos and one possible NPE.
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
index b68b5df..cea777a 100644
--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
@@ -45,7 +45,7 @@ public interface ResourceUpgradeFacet<T extends ResourceComponent> {
* The exact same discovery results are passed to this method along with the set of resources
* that already exist in the inventory.
*
- * @param inventoriedSimblings the existing resources
+ * @param inventoriedSiblings the existing resources
* @param parentContext the parent of both the newly discovered and existing resources
* @param discoveryResults the discovered resources. The resources from this set that have
* the same resource key as one of the inventoried siblings (after upgrade using the results of this method) won't
@@ -54,5 +54,5 @@ public interface ResourceUpgradeFacet<T extends ResourceComponent> {
* inventoriedSiblings set, the values are the upgrade reports detailing what the data of the
* corresponding siblings should be upgraded to.
*/
- Map<ResourceUpgradeContext, ResourceUpgradeReport> upgrade(Set<ResourceUpgradeContext> inventoriedSimblings, ResourceUpgradeContext<T> parentContext, Set<ResourceUpgradeContext> discoveryResults);
+ Map<ResourceUpgradeContext, ResourceUpgradeReport> upgrade(Set<ResourceUpgradeContext> inventoriedSiblings, ResourceUpgradeContext<T> parentContext, Set<ResourceUpgradeContext> discoveryResults);
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 866fd79..032256b 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -2062,21 +2062,33 @@ public class InventoryManager extends AgentService implements ContainerService,
}
}
- //check for upgrade support
+ //check if the discovery component supports resource upgrade
+ //if it does, perform the resource upgrade straight away here during the discovery process.
if (discoveryComponent instanceof ResourceUpgradeFacet) {
ResourceUpgradeFacet resourceUpgrade = (ResourceUpgradeFacet) discoveryComponent;
+ //the siblings are the resources of the type that is currently being discovered that are already
+ //present in the inventory. These are the candidate resources for the upgrade.
Set<Resource> siblings = getResourcesWithType(resourceType, parentResource.getChildResources());
- Resource grandParent = parentResource.getParentResource();
- ResourceContainer grandParentContainer = grandParent == null ? null : getResourceContainer(grandParent);
- ResourceDiscoveryComponent parentDiscoveryComponent = PluginContainer.getInstance().getPluginComponentFactory()
- .getDiscoveryComponent(parentResource.getResourceType(), grandParentContainer);
-
- ResourceUpgradeContext<?> parentUpgradeContext = new ResourceUpgradeContext(parentResource, parentDiscoveryComponent, parentResourceContext, availabilityCollectors);
+ ResourceUpgradeContext<?> parentUpgradeContext = null;
+
+ //get the upgrade context of the parent resource so that it can be passed to the upgrade method
+ //of the discovery component.
+ if (parentResource != null) {
+ Resource grandParent = parentResource.getParentResource();
+ ResourceContainer grandParentContainer = grandParent == null ? null : getResourceContainer(grandParent);
+ ResourceDiscoveryComponent parentDiscoveryComponent = PluginContainer.getInstance().getPluginComponentFactory()
+ .getDiscoveryComponent(parentResource.getResourceType(), grandParentContainer);
+
+ parentUpgradeContext = new ResourceUpgradeContext(parentResource, parentDiscoveryComponent, parentResourceContext, availabilityCollectors);
+ }
+ //convert the sibling resources into upgrade context objects so that the plugin methods don't access the
+ //domain objects directly.
Set<ResourceUpgradeContext> siblingContexts = new HashSet<ResourceUpgradeContext>(siblings.size());
+ //but we are going to need to update the resources in the end, so map the contexts with the resources.
Map<ResourceUpgradeContext, Resource> siblingContextToResource = new HashMap<ResourceUpgradeContext, Resource>();
for (Resource sibling : siblings) {
@@ -2085,6 +2097,8 @@ public class InventoryManager extends AgentService implements ContainerService,
siblingContextToResource.put(siblingContext, sibling);
}
+ //covert the new resources into contexts.
+ //map the resources by resource key so that we can later check for uniqueness of the reported results.
Set<ResourceUpgradeContext> newResourceContexts = new HashSet<ResourceUpgradeContext>();
Map<String, Resource> newResourceKeyToResource = new HashMap<String, Resource>();
@@ -2094,12 +2108,15 @@ public class InventoryManager extends AgentService implements ContainerService,
newResourceKeyToResource.put(newResource.getResourceKey(), newResource);
}
+ //ask the discovery component to upgrade the siblings.
Map<ResourceUpgradeContext, ResourceUpgradeReport> results = resourceUpgrade.upgrade(siblingContexts, parentUpgradeContext, newResourceContexts);
+ //now go through the results and upgrade the resources as needed.
for(Map.Entry<ResourceUpgradeContext, ResourceUpgradeReport> upgradeEntry : results.entrySet()) {
Resource siblingToUpgrade = siblingContextToResource.get(upgradeEntry.getKey());
ResourceUpgradeReport newData = upgradeEntry.getValue();
+ //upgrade the data on the server first
mergeResourceFromUpgrade(siblingToUpgrade, newData);
//if there was a resource key upgrade, remove a resource with the same resource key
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
index 45887f6..fc001f9 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
@@ -170,12 +170,12 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
return discoveredResources;
}
- public Map<ResourceUpgradeContext, ResourceUpgradeReport> upgrade(Set<ResourceUpgradeContext> inventoriedSimblings,
+ public Map<ResourceUpgradeContext, ResourceUpgradeReport> upgrade(Set<ResourceUpgradeContext> inventoriedSiblings,
ResourceUpgradeContext<PlatformComponent> parentContext, Set<ResourceUpgradeContext> discoveryResults) {
Map<ResourceUpgradeContext, ResourceUpgradeReport> ret = new HashMap<ResourceUpgradeContext, ResourceUpgradeReport>();
- for (ResourceUpgradeContext context : inventoriedSimblings) {
+ for (ResourceUpgradeContext context : inventoriedSiblings) {
String inventoriedResourceKey = context.getResourceKey();
File inventoriedResourceKeyAsPath = new File(inventoriedResourceKey);
commit 3c7d8241ea85fdceb317049664886b204f4d9cba
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed May 26 14:49:03 2010 +0200
renamed the org.rhq.core.pluginapi.migration package to org.rhq.core.pluginapi.upgrade to make it use the "upgrade" notion used by the classes in it.
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeContext.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeContext.java
deleted file mode 100644
index e8c5f03..0000000
--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeContext.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2010 Red Hat, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation, and/or the GNU Lesser
- * General Public License, version 2.1, also as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License and the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * and the GNU Lesser General Public License along with this program;
- * if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-package org.rhq.core.pluginapi.migration;
-
-import java.io.File;
-import java.util.concurrent.Executor;
-
-import org.rhq.core.domain.configuration.Configuration;
-import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.pluginapi.content.ContentContext;
-import org.rhq.core.pluginapi.event.EventContext;
-import org.rhq.core.pluginapi.inventory.PluginContainerDeployment;
-import org.rhq.core.pluginapi.inventory.ResourceComponent;
-import org.rhq.core.pluginapi.inventory.ResourceContext;
-import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
-import org.rhq.core.pluginapi.operation.OperationContext;
-import org.rhq.core.system.SystemInfo;
-
-/**
- * Represents a resource during the resource upgrade phase of discovery.
- *
- * @see ResourceUpgradeFacet
- *
- * @author Lukas Krejci
- */
-@SuppressWarnings("unchecked")
-public class ResourceUpgradeContext<T extends ResourceComponent> extends ResourceContext<T> {
-
- private final Configuration resourceConfiguration;
- private final String name;
- private final String description;
-
- /**
- * @see ResourceContext#ResourceContext(Resource, ResourceComponent, ResourceDiscoveryComponent, SystemInfo, File, File, String, EventContext, OperationContext, ContentContext, Executor, PluginContainerDeployment)
- */
- public ResourceUpgradeContext(Resource resource, T parentResourceComponent,
- ResourceDiscoveryComponent resourceDiscoveryComponent, SystemInfo systemInfo, File temporaryDirectory,
- File dataDirectory, String pluginContainerName, EventContext eventContext, OperationContext operationContext,
- ContentContext contentContext, Executor availCollectorThreadPool,
- PluginContainerDeployment pluginContainerDeployment) {
-
- super(resource, parentResourceComponent, resourceDiscoveryComponent, systemInfo, temporaryDirectory, dataDirectory,
- pluginContainerName, eventContext, operationContext, contentContext, availCollectorThreadPool,
- pluginContainerDeployment);
-
- this.resourceConfiguration = resource.getResourceConfiguration();
- this.name = resource.getName();
- this.description = resource.getDescription();
- }
-
- public ResourceUpgradeContext(Resource resource, ResourceDiscoveryComponent discoveryComponent, ResourceContext<T> context, Executor availCollectorThreadPool) {
- this(resource, context.getParentResourceComponent(), discoveryComponent, context.getSystemInformation(), context.getTemporaryDirectory(),
- context.getDataDirectory(), context.getPluginContainerName(), context.getEventContext(), context.getOperationContext(),
- context.getContentContext(), availCollectorThreadPool, context.getPluginContainerDeployment());
- }
-
- public Configuration getResourceConfiguration() {
- return resourceConfiguration;
- }
-
- public String getName() {
- return name;
- }
-
- public String getDescription() {
- return description;
- }
-}
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeFacet.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeFacet.java
deleted file mode 100644
index df372bf..0000000
--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeFacet.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2010 Red Hat, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation, and/or the GNU Lesser
- * General Public License, version 2.1, also as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License and the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * and the GNU Lesser General Public License along with this program;
- * if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-package org.rhq.core.pluginapi.migration;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.rhq.core.domain.resource.ResourceUpgradeReport;
-import org.rhq.core.pluginapi.inventory.ResourceComponent;
-
-/**
- * This interface is to be implemented by discovery classes if they want to support
- * upgrading the existing resources to a new format needed by an updated resource component.
- * This is useful for example in the case when a new version of plugin redefined a resource
- * key generation algorithm and wants to upgrade the legacy resources to use the new format.
- *
- * @author Lukas Krejci
- */
-@SuppressWarnings("unchecked")
-public interface ResourceUpgradeFacet<T extends ResourceComponent> {
-
- /**
- * This method is called on the discovery component straight after it has finished the discovery.
- * The exact same discovery results are passed to this method along with the set of resources
- * that already exist in the inventory.
- *
- * @param inventoriedSimblings the existing resources
- * @param parentContext the parent of both the newly discovered and existing resources
- * @param discoveryResults the discovered resources. The resources from this set that have
- * the same resource key as one of the inventoried siblings (after upgrade using the results of this method) won't
- * be reported.
- * @return the mapping of old resources to the newly desired data. The keys are instances from the
- * inventoriedSiblings set, the values are the upgrade reports detailing what the data of the
- * corresponding siblings should be upgraded to.
- */
- Map<ResourceUpgradeContext, ResourceUpgradeReport> upgrade(Set<ResourceUpgradeContext> inventoriedSimblings, ResourceUpgradeContext<T> parentContext, Set<ResourceUpgradeContext> discoveryResults);
-}
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeContext.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeContext.java
new file mode 100644
index 0000000..35f5029
--- /dev/null
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeContext.java
@@ -0,0 +1,89 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.rhq.core.pluginapi.upgrade;
+
+import java.io.File;
+import java.util.concurrent.Executor;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.pluginapi.content.ContentContext;
+import org.rhq.core.pluginapi.event.EventContext;
+import org.rhq.core.pluginapi.inventory.PluginContainerDeployment;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.operation.OperationContext;
+import org.rhq.core.system.SystemInfo;
+
+/**
+ * Represents a resource during the resource upgrade phase of discovery.
+ *
+ * @see ResourceUpgradeFacet
+ *
+ * @author Lukas Krejci
+ */
+@SuppressWarnings("unchecked")
+public class ResourceUpgradeContext<T extends ResourceComponent> extends ResourceContext<T> {
+
+ private final Configuration resourceConfiguration;
+ private final String name;
+ private final String description;
+
+ /**
+ * @see ResourceContext#ResourceContext(Resource, ResourceComponent, ResourceDiscoveryComponent, SystemInfo, File, File, String, EventContext, OperationContext, ContentContext, Executor, PluginContainerDeployment)
+ */
+ public ResourceUpgradeContext(Resource resource, T parentResourceComponent,
+ ResourceDiscoveryComponent resourceDiscoveryComponent, SystemInfo systemInfo, File temporaryDirectory,
+ File dataDirectory, String pluginContainerName, EventContext eventContext, OperationContext operationContext,
+ ContentContext contentContext, Executor availCollectorThreadPool,
+ PluginContainerDeployment pluginContainerDeployment) {
+
+ super(resource, parentResourceComponent, resourceDiscoveryComponent, systemInfo, temporaryDirectory, dataDirectory,
+ pluginContainerName, eventContext, operationContext, contentContext, availCollectorThreadPool,
+ pluginContainerDeployment);
+
+ this.resourceConfiguration = resource.getResourceConfiguration();
+ this.name = resource.getName();
+ this.description = resource.getDescription();
+ }
+
+ public ResourceUpgradeContext(Resource resource, ResourceDiscoveryComponent discoveryComponent, ResourceContext<T> context, Executor availCollectorThreadPool) {
+ this(resource, context.getParentResourceComponent(), discoveryComponent, context.getSystemInformation(), context.getTemporaryDirectory(),
+ context.getDataDirectory(), context.getPluginContainerName(), context.getEventContext(), context.getOperationContext(),
+ context.getContentContext(), availCollectorThreadPool, context.getPluginContainerDeployment());
+ }
+
+ public Configuration getResourceConfiguration() {
+ return resourceConfiguration;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+}
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
new file mode 100644
index 0000000..b68b5df
--- /dev/null
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeFacet.java
@@ -0,0 +1,58 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.rhq.core.pluginapi.upgrade;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+
+/**
+ * This interface is to be implemented by discovery classes if they want to support
+ * upgrading the existing resources to a new format needed by an updated resource component.
+ * This is useful for example in the case when a new version of plugin redefined a resource
+ * key generation algorithm and wants to upgrade the legacy resources to use the new format.
+ *
+ * @author Lukas Krejci
+ */
+@SuppressWarnings("unchecked")
+public interface ResourceUpgradeFacet<T extends ResourceComponent> {
+
+ /**
+ * This method is called on the discovery component straight after it has finished the discovery.
+ * The exact same discovery results are passed to this method along with the set of resources
+ * that already exist in the inventory.
+ *
+ * @param inventoriedSimblings the existing resources
+ * @param parentContext the parent of both the newly discovered and existing resources
+ * @param discoveryResults the discovered resources. The resources from this set that have
+ * the same resource key as one of the inventoried siblings (after upgrade using the results of this method) won't
+ * be reported.
+ * @return the mapping of old resources to the newly desired data. The keys are instances from the
+ * inventoriedSiblings set, the values are the upgrade reports detailing what the data of the
+ * corresponding siblings should be upgraded to.
+ */
+ Map<ResourceUpgradeContext, ResourceUpgradeReport> upgrade(Set<ResourceUpgradeContext> inventoriedSimblings, ResourceUpgradeContext<T> parentContext, Set<ResourceUpgradeContext> discoveryResults);
+}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index feb2d81..866fd79 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -105,10 +105,10 @@ import org.rhq.core.pluginapi.inventory.ResourceComponent;
import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
-import org.rhq.core.pluginapi.migration.ResourceUpgradeContext;
-import org.rhq.core.pluginapi.migration.ResourceUpgradeFacet;
import org.rhq.core.pluginapi.operation.OperationContext;
import org.rhq.core.pluginapi.operation.OperationServices;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
import org.rhq.core.system.SystemInfo;
import org.rhq.core.system.SystemInfoFactory;
import org.rhq.core.util.exception.ThrowableUtil;
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/RuntimeDiscoveryExecutor.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/RuntimeDiscoveryExecutor.java
index c60d4a8..e31ffda 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/RuntimeDiscoveryExecutor.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/RuntimeDiscoveryExecutor.java
@@ -46,8 +46,8 @@ import org.rhq.core.pc.plugin.PluginComponentFactory;
import org.rhq.core.pluginapi.inventory.ProcessScanResult;
import org.rhq.core.pluginapi.inventory.ResourceComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
-import org.rhq.core.pluginapi.migration.ResourceUpgradeContext;
-import org.rhq.core.pluginapi.migration.ResourceUpgradeFacet;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
import org.rhq.core.util.exception.ExceptionPackage;
import org.rhq.core.util.exception.Severity;
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
index 4d80ac1..45887f6 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
@@ -46,8 +46,8 @@ import org.rhq.core.pluginapi.inventory.ProcessScanResult;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
import org.rhq.core.pluginapi.inventory.ManualAddFacet;
-import org.rhq.core.pluginapi.migration.ResourceUpgradeContext;
-import org.rhq.core.pluginapi.migration.ResourceUpgradeFacet;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
import org.rhq.core.pluginapi.util.FileUtils;
import org.rhq.core.system.ProcessInfo;
import org.rhq.plugins.apache.parser.ApacheConfigReader;
commit 15bea470c93d5a59c69cd8bea3dc0f0c2a728a37
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue May 25 18:17:02 2010 +0200
Update the resource with upgrade data only if the upgrade data is not null.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 8cc5280..feb2d81 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -1134,12 +1134,29 @@ public class InventoryManager extends AgentService implements ContainerService,
}
if (serverUpdated) {
- existingResource.setResourceKey(resourceKey);
- existingResource.setName(name);
- existingResource.setVersion(version);
- existingResource.setDescription(description);
- existingResource.setPluginConfiguration(pluginConfiguration);
- existingResource.setResourceConfiguration(resourceConfiguration);
+ if (resourceKey != null) {
+ existingResource.setResourceKey(resourceKey);
+ }
+
+ if (name != null) {
+ existingResource.setName(name);
+ }
+
+ if (version != null) {
+ existingResource.setVersion(version);
+ }
+
+ if (description != null) {
+ existingResource.setDescription(description);
+ }
+
+ if (pluginConfiguration != null) {
+ existingResource.setPluginConfiguration(pluginConfiguration);
+ }
+
+ if (resourceConfiguration != null) {
+ existingResource.setResourceConfiguration(resourceConfiguration);
+ }
}
return serverUpdated;
commit 5c77f642a72f50fcb0c89613def447c39fcd1308
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue May 25 14:10:02 2010 +0200
First version of plugin-driven resource upgrade.
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
index f542f57..cfa2459 100644
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
@@ -37,6 +37,7 @@ import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.domain.resource.ResourceErrorType;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
/**
* The interface to a JON server's resource discovery subsystem.
@@ -137,6 +138,15 @@ public interface DiscoveryServerService {
boolean updateResourceVersion(int resourceId, String version);
/**
+ * Upgrades the data of the resource according to the provided report.
+ *
+ * @param resourceId the id of the resource to be upgraded
+ * @param upgradeReport contains the information about the upgrade
+ * @return true if the upgrade succeeded, false otherwise.
+ */
+ boolean upgradeResource(int resourceId, ResourceUpgradeReport upgradeReport);
+
+ /**
* Gives the server a chance to apply any necessary post-processing that's needed for newly committed resources
* that have been successfully synchronized on the agent.
*
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
new file mode 100644
index 0000000..52acf09
--- /dev/null
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceUpgradeReport.java
@@ -0,0 +1,102 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.rhq.core.domain.resource;
+
+import java.io.Serializable;
+
+import org.rhq.core.domain.configuration.Configuration;
+
+/**
+ * Represents the changes that should be applied to the existing resource
+ * in order to upgrade it to conform to the new requirements set by the
+ * changed resource component.
+ * <p>
+ * Null values of the properties mean no change, non-null values represent
+ * the desired new values.
+ *
+ * @author Lukas Krejci
+ */
+public class ResourceUpgradeReport implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private String newResourceKey;
+ private String newName;
+ private String newVersion;
+ private Configuration newPluginConfiguration;
+ private Configuration newResourceConfiguration;
+ private String newDescription;
+
+ public ResourceUpgradeReport() {
+
+ }
+
+ public String getNewResourceKey() {
+ return newResourceKey;
+ }
+
+ public void setNewResourceKey(String newResourceKey) {
+ this.newResourceKey = newResourceKey;
+ }
+
+ public String getNewName() {
+ return newName;
+ }
+
+ public void setNewName(String newName) {
+ this.newName = newName;
+ }
+
+ public String getNewVersion() {
+ return newVersion;
+ }
+
+ public void setNewVersion(String newVersion) {
+ this.newVersion = newVersion;
+ }
+
+ public Configuration getNewPluginConfiguration() {
+ return newPluginConfiguration;
+ }
+
+ public void setNewPluginConfiguration(Configuration newPluginConfiguration) {
+ this.newPluginConfiguration = newPluginConfiguration;
+ }
+
+ public Configuration getNewResourceConfiguration() {
+ return newResourceConfiguration;
+ }
+
+ public void setNewResourceConfiguration(Configuration newResourceConfiguration) {
+ this.newResourceConfiguration = newResourceConfiguration;
+ }
+
+ public String getNewDescription() {
+ return newDescription;
+ }
+
+ public void setNewDescription(String newDescription) {
+ this.newDescription = newDescription;
+ }
+}
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeContext.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeContext.java
new file mode 100644
index 0000000..e8c5f03
--- /dev/null
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeContext.java
@@ -0,0 +1,89 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.rhq.core.pluginapi.migration;
+
+import java.io.File;
+import java.util.concurrent.Executor;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.pluginapi.content.ContentContext;
+import org.rhq.core.pluginapi.event.EventContext;
+import org.rhq.core.pluginapi.inventory.PluginContainerDeployment;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.operation.OperationContext;
+import org.rhq.core.system.SystemInfo;
+
+/**
+ * Represents a resource during the resource upgrade phase of discovery.
+ *
+ * @see ResourceUpgradeFacet
+ *
+ * @author Lukas Krejci
+ */
+@SuppressWarnings("unchecked")
+public class ResourceUpgradeContext<T extends ResourceComponent> extends ResourceContext<T> {
+
+ private final Configuration resourceConfiguration;
+ private final String name;
+ private final String description;
+
+ /**
+ * @see ResourceContext#ResourceContext(Resource, ResourceComponent, ResourceDiscoveryComponent, SystemInfo, File, File, String, EventContext, OperationContext, ContentContext, Executor, PluginContainerDeployment)
+ */
+ public ResourceUpgradeContext(Resource resource, T parentResourceComponent,
+ ResourceDiscoveryComponent resourceDiscoveryComponent, SystemInfo systemInfo, File temporaryDirectory,
+ File dataDirectory, String pluginContainerName, EventContext eventContext, OperationContext operationContext,
+ ContentContext contentContext, Executor availCollectorThreadPool,
+ PluginContainerDeployment pluginContainerDeployment) {
+
+ super(resource, parentResourceComponent, resourceDiscoveryComponent, systemInfo, temporaryDirectory, dataDirectory,
+ pluginContainerName, eventContext, operationContext, contentContext, availCollectorThreadPool,
+ pluginContainerDeployment);
+
+ this.resourceConfiguration = resource.getResourceConfiguration();
+ this.name = resource.getName();
+ this.description = resource.getDescription();
+ }
+
+ public ResourceUpgradeContext(Resource resource, ResourceDiscoveryComponent discoveryComponent, ResourceContext<T> context, Executor availCollectorThreadPool) {
+ this(resource, context.getParentResourceComponent(), discoveryComponent, context.getSystemInformation(), context.getTemporaryDirectory(),
+ context.getDataDirectory(), context.getPluginContainerName(), context.getEventContext(), context.getOperationContext(),
+ context.getContentContext(), availCollectorThreadPool, context.getPluginContainerDeployment());
+ }
+
+ public Configuration getResourceConfiguration() {
+ return resourceConfiguration;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+}
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeFacet.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeFacet.java
new file mode 100644
index 0000000..df372bf
--- /dev/null
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/migration/ResourceUpgradeFacet.java
@@ -0,0 +1,58 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.rhq.core.pluginapi.migration;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
+import org.rhq.core.pluginapi.inventory.ResourceComponent;
+
+/**
+ * This interface is to be implemented by discovery classes if they want to support
+ * upgrading the existing resources to a new format needed by an updated resource component.
+ * This is useful for example in the case when a new version of plugin redefined a resource
+ * key generation algorithm and wants to upgrade the legacy resources to use the new format.
+ *
+ * @author Lukas Krejci
+ */
+@SuppressWarnings("unchecked")
+public interface ResourceUpgradeFacet<T extends ResourceComponent> {
+
+ /**
+ * This method is called on the discovery component straight after it has finished the discovery.
+ * The exact same discovery results are passed to this method along with the set of resources
+ * that already exist in the inventory.
+ *
+ * @param inventoriedSimblings the existing resources
+ * @param parentContext the parent of both the newly discovered and existing resources
+ * @param discoveryResults the discovered resources. The resources from this set that have
+ * the same resource key as one of the inventoried siblings (after upgrade using the results of this method) won't
+ * be reported.
+ * @return the mapping of old resources to the newly desired data. The keys are instances from the
+ * inventoriedSiblings set, the values are the upgrade reports detailing what the data of the
+ * corresponding siblings should be upgraded to.
+ */
+ Map<ResourceUpgradeContext, ResourceUpgradeReport> upgrade(Set<ResourceUpgradeContext> inventoriedSimblings, ResourceUpgradeContext<T> parentContext, Set<ResourceUpgradeContext> discoveryResults);
+}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AutoDiscoveryExecutor.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AutoDiscoveryExecutor.java
index b84cdbc..e8abbbf 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AutoDiscoveryExecutor.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/AutoDiscoveryExecutor.java
@@ -183,7 +183,7 @@ public class AutoDiscoveryExecutor implements Runnable, Callable<InventoryReport
List<ProcessScanResult> scanResults = performProcessScans(processInfos, serverType);
Set<Resource> discoveredServers = this.inventoryManager.executeComponentDiscovery(serverType,
- component, platformComponent, platformContainer.getResourceContext(), scanResults);
+ component, platformContainer, scanResults);
for (Resource discoveredServer : discoveredServers) {
log.debug("Detected server " + discoveredServer);
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 8944b99..8cc5280 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -70,6 +70,7 @@ import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceCreationDataType;
import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.domain.resource.ResourceErrorType;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.pc.ContainerService;
import org.rhq.core.pc.PluginContainer;
@@ -104,6 +105,8 @@ import org.rhq.core.pluginapi.inventory.ResourceComponent;
import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+import org.rhq.core.pluginapi.migration.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.migration.ResourceUpgradeFacet;
import org.rhq.core.pluginapi.operation.OperationContext;
import org.rhq.core.pluginapi.operation.OperationServices;
import org.rhq.core.system.SystemInfo;
@@ -1110,6 +1113,38 @@ public class InventoryManager extends AgentService implements ContainerService,
return resourceContainer.updateAvailability(availabilityType);
}
+ private boolean mergeResourceFromUpgrade(Resource existingResource, ResourceUpgradeReport upgradeReport) {
+ String resourceKey = upgradeReport.getNewResourceKey();
+ String name = upgradeReport.getNewName();
+ String version = upgradeReport.getNewVersion();
+ String description = upgradeReport.getNewDescription();
+ Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
+ Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
+
+ boolean serverUpdated = false;
+ try {
+ ServerServices serverServices = this.configuration.getServerServices();
+ if (serverServices != null) {
+ DiscoveryServerService discoveryServerService = serverServices.getDiscoveryServerService();
+
+ serverUpdated = discoveryServerService.upgradeResource(existingResource.getId(), upgradeReport);
+ }
+ } catch (Exception e) {
+ log.error("Failed to upgrade the resource [" + existingResource + "] on the server.", e);
+ }
+
+ if (serverUpdated) {
+ existingResource.setResourceKey(resourceKey);
+ existingResource.setName(name);
+ existingResource.setVersion(version);
+ existingResource.setDescription(description);
+ existingResource.setPluginConfiguration(pluginConfiguration);
+ existingResource.setResourceConfiguration(resourceConfiguration);
+ }
+
+ return serverUpdated;
+ }
+
public Resource mergeResourceFromDiscovery(Resource resource, Resource parent) throws PluginContainerException {
// If the Resource is already in inventory, make sure its version is up-to-date, then simply return the
// existing Resource.
@@ -1336,20 +1371,8 @@ public class InventoryManager extends AgentService implements ContainerService,
parentComponent = getResourceComponent(resource.getParentResource());
}
- File pluginDataDir = new File(this.configuration.getDataDirectory(), resource.getResourceType().getPlugin());
-
- ResourceContext context = new ResourceContext(resource, // the resource itself
- parentComponent, // its parent component
- discoveryComponent, // the discovery component (this is actually the proxy to it)
- SystemInfoFactory.createSystemInfo(), // for native access
- this.configuration.getTemporaryDirectory(), // location for plugin to write temp files
- pluginDataDir, // location for plugin to write data files
- this.configuration.getContainerName(), // the name of the agent/PC
- getEventContext(resource), // for event access
- getOperationContext(resource), // for operation manager access
- getContentContext(resource), // for content manager access
- this.availabilityCollectors, // for components that want to perform async avail checking
- this.configuration.getPluginContainerDeployment()); // helps components make determinations of what to do
+ ResourceContext context = createResourceContext(resource, parentComponent, discoveryComponent);
+
container.setResourceContext(context);
// Wrap the component in a proxy that will provide locking and a timeout for the call to start().
@@ -1396,6 +1419,23 @@ public class InventoryManager extends AgentService implements ContainerService,
}
}
+ private <T extends ResourceComponent> ResourceContext<T> createResourceContext(Resource resource, T parentComponent, ResourceDiscoveryComponent<T> discoveryComponent) {
+ File pluginDataDir = new File(this.configuration.getDataDirectory(), resource.getResourceType().getPlugin());
+
+ return new ResourceContext<T>(resource, // the resource itself
+ parentComponent, // its parent component
+ discoveryComponent, // the discovery component (this is actually the proxy to it)
+ SystemInfoFactory.createSystemInfo(), // for native access
+ this.configuration.getTemporaryDirectory(), // location for plugin to write temp files
+ pluginDataDir, // location for plugin to write data files
+ this.configuration.getContainerName(), // the name of the agent/PC
+ getEventContext(resource), // for event access
+ getOperationContext(resource), // for operation manager access
+ getContentContext(resource), // for content manager access
+ this.availabilityCollectors, // for components that want to perform async avail checking
+ this.configuration.getPluginContainerDeployment()); // helps components make determinations of what to do
+ }
+
/**
* This will send a resource error to the server (if applicable) to indicate that the given resource could not be
* connected to due to an invalid plugin configuration.
@@ -1960,8 +2000,12 @@ public class InventoryManager extends AgentService implements ContainerService,
@NotNull
Set<Resource> executeComponentDiscovery(ResourceType resourceType, ResourceDiscoveryComponent discoveryComponent,
- ResourceComponent parentComponent, ResourceContext parentResourceContext,
- List<ProcessScanResult> processScanResults) {
+ ResourceContainer parentContainer, List<ProcessScanResult> processScanResults) {
+
+ ResourceContext parentResourceContext = parentContainer.getResourceContext();
+ ResourceComponent parentComponent = parentContainer.getResourceComponent();
+ Resource parentResource = parentContainer.getResource();
+
long startTime = System.currentTimeMillis();
log.debug("Executing discovery for [" + resourceType.getName() + "] Resources...");
Set<Resource> newResources;
@@ -2000,6 +2044,59 @@ public class InventoryManager extends AgentService implements ContainerService,
newResources.add(newResource);
}
}
+
+ //check for upgrade support
+ if (discoveryComponent instanceof ResourceUpgradeFacet) {
+ ResourceUpgradeFacet resourceUpgrade = (ResourceUpgradeFacet) discoveryComponent;
+
+ Set<Resource> siblings = getResourcesWithType(resourceType, parentResource.getChildResources());
+
+ Resource grandParent = parentResource.getParentResource();
+ ResourceContainer grandParentContainer = grandParent == null ? null : getResourceContainer(grandParent);
+ ResourceDiscoveryComponent parentDiscoveryComponent = PluginContainer.getInstance().getPluginComponentFactory()
+ .getDiscoveryComponent(parentResource.getResourceType(), grandParentContainer);
+
+ ResourceUpgradeContext<?> parentUpgradeContext = new ResourceUpgradeContext(parentResource, parentDiscoveryComponent, parentResourceContext, availabilityCollectors);
+
+ Set<ResourceUpgradeContext> siblingContexts = new HashSet<ResourceUpgradeContext>(siblings.size());
+
+ Map<ResourceUpgradeContext, Resource> siblingContextToResource = new HashMap<ResourceUpgradeContext, Resource>();
+
+ for (Resource sibling : siblings) {
+ ResourceUpgradeContext siblingContext = new ResourceUpgradeContext(sibling, discoveryComponent, getResourceContainer(sibling).getResourceContext(), availabilityCollectors);
+ siblingContexts.add(siblingContext);
+ siblingContextToResource.put(siblingContext, sibling);
+ }
+
+ Set<ResourceUpgradeContext> newResourceContexts = new HashSet<ResourceUpgradeContext>();
+ Map<String, Resource> newResourceKeyToResource = new HashMap<String, Resource>();
+
+ for (Resource newResource : newResources) {
+ ResourceUpgradeContext newUpgradeContext = new ResourceUpgradeContext(newResource, discoveryComponent, createResourceContext(newResource, parentComponent, discoveryComponent), availabilityCollectors);
+ newResourceContexts.add(newUpgradeContext);
+ newResourceKeyToResource.put(newResource.getResourceKey(), newResource);
+ }
+
+ Map<ResourceUpgradeContext, ResourceUpgradeReport> results = resourceUpgrade.upgrade(siblingContexts, parentUpgradeContext, newResourceContexts);
+
+ for(Map.Entry<ResourceUpgradeContext, ResourceUpgradeReport> upgradeEntry : results.entrySet()) {
+ Resource siblingToUpgrade = siblingContextToResource.get(upgradeEntry.getKey());
+ ResourceUpgradeReport newData = upgradeEntry.getValue();
+
+ mergeResourceFromUpgrade(siblingToUpgrade, newData);
+
+ //if there was a resource key upgrade, remove a resource with the same resource key
+ //from the discovery results. Otherwise we'd end up with 2 sibling resources with
+ //the same resource key, which is illegal.
+ if (newData.getNewResourceKey() != null) {
+ Resource newResourceToRemove = newResourceKeyToResource.get(newData.getNewResourceKey());
+ if (newResourceToRemove != null) {
+ newResources.remove(newResourceToRemove);
+ }
+ }
+ }
+ }
+
} catch (Throwable e) {
// TODO GH: Add server/parent - up/down semantics so this won't happen just because a server is not up
long elapsedTime = System.currentTimeMillis() - startTime;
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/RuntimeDiscoveryExecutor.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/RuntimeDiscoveryExecutor.java
index c16ba56..c60d4a8 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/RuntimeDiscoveryExecutor.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/RuntimeDiscoveryExecutor.java
@@ -43,8 +43,11 @@ import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.pc.PluginContainer;
import org.rhq.core.pc.PluginContainerConfiguration;
import org.rhq.core.pc.plugin.PluginComponentFactory;
+import org.rhq.core.pluginapi.inventory.ProcessScanResult;
import org.rhq.core.pluginapi.inventory.ResourceComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.migration.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.migration.ResourceUpgradeFacet;
import org.rhq.core.util.exception.ExceptionPackage;
import org.rhq.core.util.exception.Severity;
@@ -237,8 +240,8 @@ public class RuntimeDiscoveryExecutor implements Runnable, Callable<InventoryRep
+ childResourceType + "]");
}
Set<Resource> childResources = this.inventoryManager.executeComponentDiscovery(childResourceType,
- discoveryComponent, parentComponent, parentContainer.getResourceContext(), Collections.EMPTY_LIST);
-
+ discoveryComponent, parentContainer, Collections.<ProcessScanResult>emptyList());
+
// For each discovered resource, update it in the inventory manager and recursively discover its child resources
Map<String, Resource> mergedResources = new HashMap<String, Resource>();
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index cded63b..2d3e9e6 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -56,6 +56,7 @@ import org.rhq.core.domain.resource.ProductVersion;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.domain.util.PageOrdering;
@@ -400,6 +401,19 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
}
}
+ public boolean upgradeResource(int resourceId, ResourceUpgradeReport upgradeReport) {
+ Resource existingResource = this.entityManager.find(Resource.class, resourceId);
+ if (existingResource != null) {
+ boolean changed = upgradeResource(existingResource, upgradeReport);
+ if (changed) {
+ this.entityManager.merge(existingResource);
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
/**
* Convienence method that looks at <code>resource</code> and if its version is not
* the same as <code>newVersion</code>, its version string will be set to it. If
@@ -445,6 +459,81 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
return versionChanged;
}
+ /**
+ * @param existingResource
+ * @param upgradeReport
+ * @return
+ */
+ private boolean upgradeResource(Resource resource, ResourceUpgradeReport upgradeReport) {
+ boolean changed = false;
+ if (resource != null) {
+ String resourceKey = upgradeReport.getNewResourceKey();
+ String name = upgradeReport.getNewName();
+ String version = upgradeReport.getNewVersion();
+ String description = upgradeReport.getNewDescription();
+ Configuration pluginConfiguration = upgradeReport.getNewPluginConfiguration();
+ Configuration resourceConfiguration = upgradeReport.getNewResourceConfiguration();
+
+ if (resourceKey != null) {
+ if (!equalOrNull(resourceKey, resource.getResourceKey())) {
+ log.info("Resource [" + resource + "] upgraded its resource key from [" +
+ resource.getResourceKey() + "] to [" + resourceKey + "]");
+ changed = true;
+ resource.setResourceKey(resourceKey);
+ }
+ }
+
+ if (name != null) {
+ if (!equalOrNull(name, resource.getName())) {
+ log.info("Resource [" + resource + "] upgraded its name from [" +
+ resource.getName() + "] to [" + name + "]");
+ changed = true;
+ resource.setName(name);
+ }
+ }
+
+ if (version != null) {
+ changed = updateResourceVersion(resource, version) || changed;
+ }
+
+ if (description != null) {
+ if (!equalOrNull(description, resource.getDescription())) {
+ log.info("Resource [" + resource + "] upgraded its description from [" +
+ resource.getDescription() + "] to [" + description + "]");
+ changed = true;
+ resource.setDescription(description);
+ }
+ }
+
+ if (pluginConfiguration != null) {
+ if (!equalOrNull(pluginConfiguration, resource.getPluginConfiguration())) {
+ log.info("Resource [" + resource + "] upgraded its plugin configuration from [" +
+ resource.getPluginConfiguration() + "] to [" + pluginConfiguration + "]");
+ changed = true;
+ resource.setPluginConfiguration(pluginConfiguration);
+ }
+ }
+
+ if (resourceConfiguration != null) {
+ if (!equalOrNull(resourceConfiguration, resource.getResourceConfiguration())) {
+ //XXX Will this create a new history entry?
+
+ log.info("Resource [" + resource + "] upgraded its resource configuration from [" +
+ resource.getResourceConfiguration() + "] to [" + resourceConfiguration + "]");
+
+ changed = true;
+ resource.setResourceConfiguration(resourceConfiguration);
+ }
+ }
+
+ // If the resource was marked as deleted, reactivate it again.
+ if (resource.getInventoryStatus() == InventoryStatus.DELETED) {
+ resource.setInventoryStatus(InventoryStatus.COMMITTED);
+ }
+ }
+ return changed;
+ }
+
private void validateInventoryReport(InventoryReport report) throws InvalidInventoryReportException {
for (Resource root : report.getAddedRoots()) {
validateResource(root);
@@ -793,4 +882,16 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
updateInventoryStatus(subject, platforms, servers, target);
}
+
+ private static <T> boolean equalOrNull(T a, T b) {
+ if (a == null) {
+ return b == null;
+ } else {
+ if (b == null) {
+ return false;
+ } else {
+ return a.equals(b);
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
index 01394b9..4e60ffb 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
@@ -38,6 +38,7 @@ import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
@@ -176,4 +177,13 @@ public interface DiscoveryBossLocal extends DiscoveryBossRemote {
* <code>false</code> if the Resource was not in inventory
*/
boolean updateResourceVersion(int resourceId, String version);
+
+ /**
+ * Upgrades the data of the resource according to the provided report.
+ *
+ * @param resourceId the id of the resource to be upgraded
+ * @param upgradeReport contains the information about the upgrade
+ * @return true if the upgrade succeeded, false otherwise.
+ */
+ boolean upgradeResource(int resourceId, ResourceUpgradeReport upgradeReport);
}
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
index d692ad8..720465e 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
@@ -37,6 +37,7 @@ import org.rhq.core.domain.resource.Agent;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceError;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.util.collection.ArrayUtils;
import org.rhq.core.util.exception.ThrowableUtil;
import org.rhq.enterprise.server.alert.AlertDefinitionCreationException;
@@ -176,6 +177,11 @@ public class DiscoveryServerServiceImpl implements DiscoveryServerService {
return discoveryBoss.updateResourceVersion(resourceId, version);
}
+ public boolean upgradeResource(int resourceId, ResourceUpgradeReport upgradeReport) {
+ DiscoveryBossLocal discoveryBoss = LookupUtil.getDiscoveryBoss();
+ return discoveryBoss.upgradeResource(resourceId, upgradeReport);
+ }
+
private static Resource convertToPojoResource(Resource resource, boolean includeDescendants) {
Resource pojoResource = new Resource(resource.getId());
pojoResource.setUuid(resource.getUuid());
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
index 8f6deb7..4d80ac1 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
@@ -21,8 +21,10 @@ package org.rhq.plugins.apache;
import java.io.File;
import java.io.IOException;
import java.net.URI;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
@@ -36,12 +38,16 @@ import org.rhq.augeas.util.GlobFilter;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.Property;
import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.domain.resource.ResourceUpgradeReport;
import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
import org.rhq.core.pluginapi.inventory.ManualAddFacet;
import org.rhq.core.pluginapi.inventory.ProcessScanResult;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+import org.rhq.core.pluginapi.inventory.ManualAddFacet;
+import org.rhq.core.pluginapi.migration.ResourceUpgradeContext;
+import org.rhq.core.pluginapi.migration.ResourceUpgradeFacet;
import org.rhq.core.pluginapi.util.FileUtils;
import org.rhq.core.system.ProcessInfo;
import org.rhq.plugins.apache.parser.ApacheConfigReader;
@@ -63,7 +69,8 @@ import org.rhq.rhqtransform.impl.PluginDescriptorBasedAugeasConfiguration;
* @author Ian Springer
* @author Lukas Krejci
*/
-public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponent<PlatformComponent>, ManualAddFacet<PlatformComponent> {
+public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponent<PlatformComponent>, ManualAddFacet<PlatformComponent>,
+ ResourceUpgradeFacet<PlatformComponent> {
private static final String PRODUCT_DESCRIPTION = "Apache Web Server";
private static final Log log = LogFactory.getLog(ApacheServerDiscoveryComponent.class);
@@ -163,7 +170,46 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
return discoveredResources;
}
-
+ public Map<ResourceUpgradeContext, ResourceUpgradeReport> upgrade(Set<ResourceUpgradeContext> inventoriedSimblings,
+ ResourceUpgradeContext<PlatformComponent> parentContext, Set<ResourceUpgradeContext> discoveryResults) {
+
+ Map<ResourceUpgradeContext, ResourceUpgradeReport> ret = new HashMap<ResourceUpgradeContext, ResourceUpgradeReport>();
+
+ for (ResourceUpgradeContext context : inventoriedSimblings) {
+ String inventoriedResourceKey = context.getResourceKey();
+ File inventoriedResourceKeyAsPath = new File(inventoriedResourceKey);
+
+ //the resource key we use now is a full path to the httpdconf.
+ //in the old version, it was the server root.
+ //so if the inventoried resource key is a path to a file,
+ //we know it's a new style resource key.
+ if (inventoriedResourceKeyAsPath.isFile()) {
+ continue;
+ }
+
+ Configuration pluginConfiguration = context.getPluginConfiguration();
+
+ String serverRoot = pluginConfiguration.getSimpleValue("serverRoot", null);
+ String httpdConf = pluginConfiguration.getSimpleValue("configFile", null);
+
+ String resourceKey = null;
+
+ if (httpdConf != null) {
+ File httpdConfFile = new File(httpdConf);
+ if (!httpdConfFile.isAbsolute()) {
+ httpdConfFile = new File(serverRoot, httpdConf);
+ }
+
+ resourceKey = httpdConfFile.getPath();
+
+ ResourceUpgradeReport rep = new ResourceUpgradeReport();
+ rep.setNewResourceKey(resourceKey);
+
+ ret.put(context, rep);
+ }
+ }
+ return ret;
+ }
public DiscoveredResourceDetails discoverResource(Configuration pluginConfig,
ResourceDiscoveryContext<PlatformComponent> discoveryContext)
13 years, 7 months
[rhq] Branch 'resource-upgrade' - 3 commits - modules/plugins
by lkrejci
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java | 173 ++++------
1 file changed, 77 insertions(+), 96 deletions(-)
New commits:
commit 4969aa53cf7f5ff45fbb1510d2f110560f3f6a8f
Merge: 065319e... 1b86f3a...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Oct 5 14:18:01 2010 +0200
Merge branch '_resource-upgrade' into resource-upgrade
commit 1b86f3abaf44ebb4e0d62cb75a559b130500cd9f
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Oct 5 14:17:46 2010 +0200
BZ 593270 - the new style resource key for apache is <server-root>||<httpd-conf>. Implemented the ResourceUpgradeFacet to upgrade existing resources to that new format.
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
index 660f727..ca8f972 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
@@ -170,38 +170,24 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
public ResourceUpgradeReport upgrade(ResourceUpgradeContext<PlatformComponent> context) {
String inventoriedResourceKey = context.getResourceKey();
- File inventoriedResourceKeyAsPath = new File(inventoriedResourceKey);
- //the resource key we use now is a full path to the httpd.conf.
- //in the old version, it was the server root.
- //so if the inventoried resource key is a path to a file,
- //we know it's a new style resource key.
- if (inventoriedResourceKeyAsPath.isFile()) {
+ //check if the inventoried resource has the old format of the resource key.
+ //the old format was "server-root", while the new format
+ //is "server-root||httpd-conf". Checking for "||" in the resource key is therefore
+ //enough.
+ if (inventoriedResourceKey.contains("||")) {
return null;
}
+
+ //all the information we need for the new style resource key is
+ //actually present in the plugin configuration of the existing resource
+ //already, so let's just generate the new style resource key from it.
+ String resourceKey = formatResourceKey(context.getPluginConfiguration());
- Configuration pluginConfiguration = context.getPluginConfiguration();
+ ResourceUpgradeReport rep = new ResourceUpgradeReport();
+ rep.setNewResourceKey(resourceKey);
- String serverRoot = pluginConfiguration.getSimpleValue("serverRoot", null);
- String httpdConf = pluginConfiguration.getSimpleValue("configFile", null);
-
- String resourceKey = null;
-
- if (httpdConf != null) {
- File httpdConfFile = new File(httpdConf);
- if (!httpdConfFile.isAbsolute()) {
- httpdConfFile = new File(serverRoot, httpdConf);
- }
-
- resourceKey = httpdConfFile.getPath();
-
- ResourceUpgradeReport rep = new ResourceUpgradeReport();
- rep.setNewResourceKey(resourceKey);
-
- return rep;
- }
-
- return null;
+ return rep;
}
public DiscoveredResourceDetails discoverResource(Configuration pluginConfig,
@@ -256,15 +242,7 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
name = uri.getHost() + ":" + uri.getPort();
}
- String serverRoot = pluginConfig.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_SERVER_ROOT)
- .getStringValue();
-
- String key = FileUtils.getCanonicalPath(serverRoot);
-
- //BZ 612189 - reverting to the serverRoot as the resource key temporarily until we have the resource
- //upgrade functionality ready (BZ 592038). Uncommenting the line below will make the resource key totally unique
- //(see BZ 593270).
- //key += "|" + httpdConf;
+ String key = formatResourceKey(pluginConfig);
DiscoveredResourceDetails resourceDetails = new DiscoveredResourceDetails(discoveryContext.getResourceType(),
key, name, version, PRODUCT_DESCRIPTION, pluginConfig, processInfo);
@@ -455,4 +433,14 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
}
return null;
}
+
+ private static String formatResourceKey(Configuration pluginConfiguration) {
+ String serverRoot = pluginConfiguration.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_SERVER_ROOT).getStringValue();
+ String httpdConf = pluginConfiguration.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_HTTPD_CONF).getStringValue();
+
+ serverRoot = FileUtils.getCanonicalPath(serverRoot);
+ httpdConf = FileUtils.getCanonicalPath(httpdConf);
+
+ return serverRoot + "||" + httpdConf;
+ }
}
commit a0edcceda8b63f23cc6570fb1da34251f245f3c0
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Oct 5 13:35:57 2010 +0200
code formatting
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
index c305ec4..660f727 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
@@ -21,18 +21,14 @@ package org.rhq.plugins.apache;
import java.io.File;
import java.io.IOException;
import java.net.URI;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.rhq.augeas.node.AugeasNode;
-import org.rhq.augeas.tree.AugeasTree;
import org.rhq.augeas.util.Glob;
import org.rhq.augeas.util.GlobFilter;
import org.rhq.core.domain.configuration.Configuration;
@@ -45,7 +41,6 @@ import org.rhq.core.pluginapi.inventory.ManualAddFacet;
import org.rhq.core.pluginapi.inventory.ProcessScanResult;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
-import org.rhq.core.pluginapi.inventory.ManualAddFacet;
import org.rhq.core.pluginapi.upgrade.ResourceUpgradeContext;
import org.rhq.core.pluginapi.upgrade.ResourceUpgradeFacet;
import org.rhq.core.pluginapi.util.FileUtils;
@@ -58,8 +53,8 @@ import org.rhq.plugins.apache.parser.ApacheParserImpl;
import org.rhq.plugins.apache.util.ApacheBinaryInfo;
import org.rhq.plugins.apache.util.AugeasNodeValueUtil;
import org.rhq.plugins.apache.util.HttpdAddressUtility;
-import org.rhq.plugins.apache.util.OsProcessUtility;
import org.rhq.plugins.apache.util.HttpdAddressUtility.Address;
+import org.rhq.plugins.apache.util.OsProcessUtility;
import org.rhq.plugins.platform.PlatformComponent;
import org.rhq.rhqtransform.impl.PluginDescriptorBasedAugeasConfiguration;
@@ -69,13 +64,14 @@ import org.rhq.rhqtransform.impl.PluginDescriptorBasedAugeasConfiguration;
* @author Ian Springer
* @author Lukas Krejci
*/
-public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponent<PlatformComponent>, ManualAddFacet<PlatformComponent>,
- ResourceUpgradeFacet<PlatformComponent> {
+public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponent<PlatformComponent>,
+ ManualAddFacet<PlatformComponent>, ResourceUpgradeFacet<PlatformComponent> {
private static final String PRODUCT_DESCRIPTION = "Apache Web Server";
private static final Log log = LogFactory.getLog(ApacheServerDiscoveryComponent.class);
- public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext<PlatformComponent> discoveryContext) throws Exception {
+ public Set<DiscoveredResourceDetails>
+ discoverResources(ResourceDiscoveryContext<PlatformComponent> discoveryContext) throws Exception {
Set<DiscoveredResourceDetails> discoveredResources = new HashSet<DiscoveredResourceDetails>();
// Process any PC-discovered OS processes...
@@ -89,16 +85,16 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
continue;
}
if (!executablePath.isAbsolute()) {
- log.error("Executable path (" + executablePath + ") is not absolute for Apache [" +
- process.getProcessInfo() + "]." +
- "Please restart Apache specifying an absolute path for the executable.");
+ log.error("Executable path (" + executablePath + ") is not absolute for Apache ["
+ + process.getProcessInfo() + "]."
+ + "Please restart Apache specifying an absolute path for the executable.");
continue;
}
log.debug("Apache executable path: " + executablePath);
ApacheBinaryInfo binaryInfo;
try {
- binaryInfo = ApacheBinaryInfo.getInfo(executablePath.getPath(),
- discoveryContext.getSystemInformation());
+ binaryInfo = ApacheBinaryInfo
+ .getInfo(executablePath.getPath(), discoveryContext.getSystemInformation());
} catch (Exception e) {
log.error("'" + executablePath + "' is not a valid Apache executable (" + e + ").");
continue;
@@ -130,38 +126,40 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
PropertySimple configFile = new PropertySimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_HTTPD_CONF,
serverConfigFile);
pluginConfig.put(configFile);
-
- PropertySimple inclusionGlobs = new PropertySimple(PluginDescriptorBasedAugeasConfiguration.INCLUDE_GLOBS_PROP, serverConfigFile);
+
+ PropertySimple inclusionGlobs = new PropertySimple(
+ PluginDescriptorBasedAugeasConfiguration.INCLUDE_GLOBS_PROP, serverConfigFile);
pluginConfig.put(inclusionGlobs);
-
- ApacheDirectiveTree serverConfig = loadParser(serverConfigFile.getAbsolutePath(),serverRoot);
-
+
+ ApacheDirectiveTree serverConfig = loadParser(serverConfigFile.getAbsolutePath(), serverRoot);
+
String serverUrl = null;
String vhostsGlobInclude = null;
-
+
//now check if the httpd.conf doesn't redefine the ServerRoot
List<ApacheDirective> serverRoots = serverConfig.search("/ServerRoot");
if (!serverRoots.isEmpty()) {
serverRoot = AugeasNodeValueUtil.unescape(serverRoots.get(0).getValuesAsString());
serverRootProp.setValue(serverRoot);
- }
+ }
+
+ serverUrl = getUrl(serverConfig, binaryInfo.getVersion());
+ vhostsGlobInclude = scanForGlobInclude(serverConfig);
- serverUrl = getUrl(serverConfig, binaryInfo.getVersion());
- vhostsGlobInclude = scanForGlobInclude(serverConfig);
-
if (serverUrl != null) {
Property urlProp = new PropertySimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_URL, serverUrl);
- pluginConfig.put(urlProp);
+ pluginConfig.put(urlProp);
}
-
+
if (vhostsGlobInclude != null) {
- pluginConfig.put(new PropertySimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_VHOST_FILES_MASK, vhostsGlobInclude));
- }else
- {
+ pluginConfig.put(new PropertySimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_VHOST_FILES_MASK,
+ vhostsGlobInclude));
+ } else {
if (serverConfigFile.exists())
- pluginConfig.put(new PropertySimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_VHOST_FILES_MASK, serverConfigFile.getParent()+File.separator+"*"));
+ pluginConfig.put(new PropertySimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_VHOST_FILES_MASK,
+ serverConfigFile.getParent() + File.separator + "*"));
}
-
+
discoveredResources.add(createResourceDetails(discoveryContext, pluginConfig, process.getProcessInfo(),
binaryInfo));
}
@@ -202,18 +200,16 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
return rep;
}
-
+
return null;
}
public DiscoveredResourceDetails discoverResource(Configuration pluginConfig,
- ResourceDiscoveryContext<PlatformComponent> discoveryContext)
- throws InvalidPluginConfigurationException {
+ ResourceDiscoveryContext<PlatformComponent> discoveryContext) throws InvalidPluginConfigurationException {
validateServerRootAndServerConfigFile(pluginConfig);
- String executablePath = pluginConfig
- .getSimpleValue(ApacheServerComponent.PLUGIN_CONFIG_PROP_EXECUTABLE_PATH,
- ApacheServerComponent.DEFAULT_EXECUTABLE_PATH);
+ String executablePath = pluginConfig.getSimpleValue(ApacheServerComponent.PLUGIN_CONFIG_PROP_EXECUTABLE_PATH,
+ ApacheServerComponent.DEFAULT_EXECUTABLE_PATH);
String absoluteExecutablePath = ApacheServerComponent.resolvePathRelativeToServerRoot(pluginConfig,
executablePath).getPath();
ApacheBinaryInfo binaryInfo;
@@ -222,13 +218,12 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
} catch (Exception e) {
throw new InvalidPluginConfigurationException("'" + absoluteExecutablePath
+ "' is not a valid Apache executable (" + e + "). Please make sure the '"
- + ApacheServerComponent.PLUGIN_CONFIG_PROP_EXECUTABLE_PATH
- + "' connection property is set correctly.");
+ + ApacheServerComponent.PLUGIN_CONFIG_PROP_EXECUTABLE_PATH + "' connection property is set correctly.");
}
if (!isSupportedVersion(binaryInfo.getVersion())) {
- throw new InvalidPluginConfigurationException("Version of Apache executable ("
- + binaryInfo.getVersion() + ") is not a supported version; supported versions are 1.3.x and 2.x.");
+ throw new InvalidPluginConfigurationException("Version of Apache executable (" + binaryInfo.getVersion()
+ + ") is not a supported version; supported versions are 1.3.x and 2.x.");
}
ProcessInfo processInfo = null;
@@ -236,8 +231,7 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
DiscoveredResourceDetails resourceDetails = createResourceDetails(discoveryContext, pluginConfig,
processInfo, binaryInfo);
return resourceDetails;
- }
- catch (Exception e) {
+ } catch (Exception e) {
throw new RuntimeException("Failed to create resource details during manual add.");
}
}
@@ -247,8 +241,9 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
return (version != null) && (version.startsWith("1.3") || version.startsWith("2."));
}
- private DiscoveredResourceDetails createResourceDetails(ResourceDiscoveryContext<PlatformComponent> discoveryContext,
- Configuration pluginConfig, ProcessInfo processInfo, ApacheBinaryInfo binaryInfo) throws Exception {
+ private DiscoveredResourceDetails createResourceDetails(
+ ResourceDiscoveryContext<PlatformComponent> discoveryContext, Configuration pluginConfig,
+ ProcessInfo processInfo, ApacheBinaryInfo binaryInfo) throws Exception {
String httpdConf = pluginConfig.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_HTTPD_CONF).getStringValue();
String version = binaryInfo.getVersion();
String serverUrl = pluginConfig.getSimpleValue(ApacheServerComponent.PLUGIN_CONFIG_PROP_URL, null);
@@ -258,19 +253,19 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
name = httpdConf;
} else {
URI uri = new URI(serverUrl);
- name = uri.getHost() + ":" + uri.getPort();
+ name = uri.getHost() + ":" + uri.getPort();
}
String serverRoot = pluginConfig.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_SERVER_ROOT)
.getStringValue();
-
+
String key = FileUtils.getCanonicalPath(serverRoot);
//BZ 612189 - reverting to the serverRoot as the resource key temporarily until we have the resource
//upgrade functionality ready (BZ 592038). Uncommenting the line below will make the resource key totally unique
//(see BZ 593270).
//key += "|" + httpdConf;
-
+
DiscoveredResourceDetails resourceDetails = new DiscoveredResourceDetails(discoveryContext.getResourceType(),
key, name, version, PRODUCT_DESCRIPTION, pluginConfig, processInfo);
log.debug("Apache Server resource details created: " + resourceDetails);
@@ -290,7 +285,6 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
return addr == null ? null : "http://" + addr.host + ":" + addr.port + "/";
}
-
@Nullable
private String getServerRoot(@NotNull ApacheBinaryInfo binaryInfo, @NotNull ProcessInfo processInfo) {
// First see if -d was specified on the httpd command line.
@@ -315,12 +309,12 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
currentWorkingDir = processInfo.getCurrentWorkingDirectory();
} catch (Exception e) {
log.error("Unable to determine current working directory of Apache process [" + processInfo
- + "], which is needed to determine the server root of the Apache instance.", e);
+ + "], which is needed to determine the server root of the Apache instance.", e);
return null;
}
if (currentWorkingDir == null) {
log.error("Unable to determine current working directory of Apache process [" + processInfo
- + "], which is needed to determine the server root of the Apache instance.");
+ + "], which is needed to determine the server root of the Apache instance.");
return null;
} else {
rootFile = new File(currentWorkingDir, root);
@@ -396,12 +390,12 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
}
private static void validateServerRootAndServerConfigFile(Configuration pluginConfig) {
- String serverRoot = pluginConfig.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_SERVER_ROOT).getStringValue();
+ String serverRoot = pluginConfig.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_SERVER_ROOT)
+ .getStringValue();
File serverRootFile;
try {
serverRootFile = new File(serverRoot).getCanonicalFile(); // this will resolve symlinks
- }
- catch (IOException e) {
+ } catch (IOException e) {
serverRootFile = null;
}
if (serverRootFile == null || !serverRootFile.isDirectory()) {
@@ -413,8 +407,7 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
File httpdConfFile;
try {
httpdConfFile = new File(httpdConf).getCanonicalFile(); // this will resolve symlinks
- }
- catch (IOException e) {
+ } catch (IOException e) {
httpdConfFile = null;
}
if (httpdConfFile == null || !httpdConfFile.isFile()) {
@@ -423,15 +416,15 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
+ ApacheServerComponent.PLUGIN_CONFIG_PROP_HTTPD_CONF + "' connection property is set correctly.");
}
}
-
- private static ApacheDirectiveTree loadParser(String path,String serverRoot) throws Exception{
+
+ private static ApacheDirectiveTree loadParser(String path, String serverRoot) throws Exception {
ApacheDirectiveTree tree = new ApacheDirectiveTree();
- ApacheParser parser = new ApacheParserImpl(tree,serverRoot);
+ ApacheParser parser = new ApacheParserImpl(tree, serverRoot);
ApacheConfigReader.buildTree(path, parser);
return tree;
}
-
+
public static String scanForGlobInclude(ApacheDirectiveTree tree) {
try {
List<ApacheDirective> includes = tree.search("/Include");
@@ -440,9 +433,9 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
if (Glob.isWildcard(include)) {
//we only take the '*.something' into account here
//so that we have a useful mask to base the file names on.
-
+
//the only special glob character allowed is *.
- for(char specialChar : GlobFilter.WILDCARD_CHARS) {
+ for (char specialChar : GlobFilter.WILDCARD_CHARS) {
if (specialChar == '*') {
if (include.indexOf(specialChar) != include.lastIndexOf(specialChar)) {
//more than 1 star... that's too much
@@ -462,4 +455,4 @@ public class ApacheServerDiscoveryComponent implements ResourceDiscoveryComponen
}
return null;
}
-}
\ No newline at end of file
+}
13 years, 7 months
[rhq] Branch 'resource-upgrade' - 14 commits - modules/core modules/enterprise
by lkrejci
modules/core/domain/src/main/java/org/rhq/core/domain/criteria/RoleCriteria.java | 12
modules/core/domain/src/main/java/org/rhq/core/domain/criteria/SubjectCriteria.java | 12
modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java | 20
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java | 4
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java | 12
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java | 3
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml | 13
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/UserSessionManager.java | 22
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/AbstractNotificationSenderForm.java | 2
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java | 12
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SimpleNotificationSenderForm.java | 19
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SystemRolesNotificationSenderForm.java | 202 ++++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SystemUsersNotificationSenderForm.java | 203 ++++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/create/BundleUploadDataStep.java | 3
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java | 429 ++++++----
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/GWTServiceLookup.java | 21
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ResourceConfigurationEditView.java | 2
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/inventory/PluginConfigurationEditView.java | 2
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationFactory.java | 4
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationView.java | 37
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/ErrorHandler.java | 41
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/Message.java | 45 -
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AbstractGWTServiceImpl.java | 30
modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css | 6
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/TestConfigurationFactory.java | 4
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBean.java | 2
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBeanTest.java | 142 +--
modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v1.xml | 41
modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v2.xml | 47 +
modules/enterprise/server/plugins/alert-roles/src/main/java/org/rhq/enterprise/server/plugins/alertRoles/RolesBackingBean.java | 83 -
modules/enterprise/server/plugins/alert-roles/src/main/resources/META-INF/rhq-serverplugin.xml | 12
modules/enterprise/server/plugins/alert-roles/src/main/resources/roles.xhtml | 22
modules/enterprise/server/plugins/alert-subject/pom.xml | 21
modules/enterprise/server/plugins/alert-subject/src/main/java/org/rhq/enterprise/server/plugins/alertSubject/SubjectsBackingBean.java | 84 -
modules/enterprise/server/plugins/alert-subject/src/main/resources/META-INF/rhq-serverplugin.xml | 14
modules/enterprise/server/plugins/alert-subject/src/main/resources/subjects.xhtml | 22
36 files changed, 1073 insertions(+), 577 deletions(-)
New commits:
commit 065319e2048376d93509e31dd526789b26947b4f
Merge: 98a4d17... 297cc73...
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Oct 5 12:49:38 2010 +0200
Merge branch 'master' into resource-upgrade
commit 98a4d17665d0fed83e0fd2c28770545178b00150
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Oct 5 12:48:12 2010 +0200
making the getResourcesWithType(ResourceType, Set<Resource>) private again.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index c5004dd..351f751 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -1668,7 +1668,7 @@ public class InventoryManager extends AgentService implements ContainerService,
return getResourcesWithType(serverType, this.platform.getChildResources());
}
- public Set<Resource> getResourcesWithType(ResourceType serverType, Set<Resource> resources) {
+ private Set<Resource> getResourcesWithType(ResourceType serverType, Set<Resource> resources) {
Set<Resource> servers = new HashSet<Resource>();
if (resources == null) {
commit 297cc733d3b5567a444131892c4766d6852fa80e
Author: Joseph Marques <joseph(a)redhat.com>
Date: Tue Oct 5 01:22:58 2010 -0400
add todos for future infrastructure work
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/GWTServiceLookup.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/GWTServiceLookup.java
index a779117..d0760d2 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/GWTServiceLookup.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/GWTServiceLookup.java
@@ -139,9 +139,15 @@ public class GWTServiceLookup {
public static class SessionRpcRequestBuilder extends RpcRequestBuilder {
+ private static int RPC_TIMEOUT = 10000;
+
@Override
- protected void doFinish(RequestBuilder rb) {
- super.doFinish(rb);
+ protected RequestBuilder doCreate(String serviceEntryPoint) {
+ RequestBuilder rb = super.doCreate(serviceEntryPoint);
+
+ // TODO: alter callback handlers to capture timeout failure and retry (at least once)
+ // to add resilience to gwt service calls
+ rb.setTimeoutMillis(RPC_TIMEOUT);
// TODO Don't use the expensive determineName except in dev mode
rb.setCallback(new MonitoringRequestCallback(determineName(), rb.getCallback()));
@@ -155,6 +161,8 @@ public class GWTServiceLookup {
.error("SessionRpcRequestBuilder constructed without a value for "
+ UserSessionManager.SESSION_NAME);
}
+
+ return rb;
}
public String determineName() {
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AbstractGWTServiceImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AbstractGWTServiceImpl.java
index c9da68a..364140f 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AbstractGWTServiceImpl.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AbstractGWTServiceImpl.java
@@ -19,6 +19,7 @@
package org.rhq.enterprise.gui.coregui.server.gwt;
import java.io.IOException;
+import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@@ -49,6 +50,9 @@ public abstract class AbstractGWTServiceImpl extends RemoteServiceServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ if (Log.isTraceEnabled()) {
+ printHeaders(req);
+ }
String sid = req.getHeader(UserSessionManager.SESSION_NAME);
if (sid != null) {
SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
@@ -62,8 +66,22 @@ public abstract class AbstractGWTServiceImpl extends RemoteServiceServlet {
Log.error("Failed to validate request: sessionId missing, requestURL=" + req.getRequestURL());
}
+ // TODO: only execute this if the session lookup was successful, otherwise fail in some deterministic fashion
+ // alter callback handlers to capture expected failure and retry (at least once)
+ // to add resilience to gwt service calls
long id = HibernatePerformanceMonitor.get().start();
super.service(req, resp);
HibernatePerformanceMonitor.get().stop(id, "GWT Service Request");
}
+
+ @SuppressWarnings("unchecked")
+ private void printHeaders(HttpServletRequest req) {
+ // TODO: figure out why SESSION_NAME header and other GWT-specific headers are missing occasionally
+ // seems to only happen on polling for recent alerts when there is no user activity for a few minutes
+ Enumeration<String> headerNames = req.getHeaderNames();
+ Log.trace(req.getRequestURL().toString());
+ while (headerNames.hasMoreElements()) {
+ Log.trace(" " + headerNames.nextElement());
+ }
+ }
}
commit 83c0317378f20d3a9aa1bf92bcf645a771a41e84
Author: Joseph Marques <joseph(a)redhat.com>
Date: Mon Oct 4 23:29:01 2010 -0400
fix z-index so log_DivLogger can be used if developers so choose
diff --git a/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css b/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css
index 85d1b83..54cc3a9 100644
--- a/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css
+++ b/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css
@@ -317,11 +317,9 @@ a:hover {
-moz-box-sizing: border-box;
overflow: hidden;
cursor: auto;
- z-index: 9999999;
}
.gwtMenu, .gwt-MenuBarPopup, .gwt-MenuPopup {
- z-index: 9999999;
background-color: white;
}
@@ -387,3 +385,7 @@ a:hover {
background-color: #FF6666; /* slightly darker light red */
border-color: #EE1111; /* slightly darker medium red */
}
+
+.log-panel {
+ z-index: 9999999 !important;
+}
commit 84ae15fae55dbaf217217cb4bb1c0edc58c4c907
Author: Joseph Marques <joseph(a)redhat.com>
Date: Mon Oct 4 17:41:07 2010 -0400
better logging around request-response workflow and user session management
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/UserSessionManager.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/UserSessionManager.java
index ecbd719..65faa6d 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/UserSessionManager.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/UserSessionManager.java
@@ -56,7 +56,7 @@ import org.rhq.enterprise.gui.coregui.client.util.preferences.UserPreferences;
public class UserSessionManager {
private static int SESSION_TIMEOUT = 29 * 60 * 1000; // 29 mins, just shorter than the 30-min web session timeout
- private static int LOGOUT_DELAY = 15 * 1000; // wait 15 seconds for in-flight requests to complete before logout
+ private static int LOGOUT_DELAY = 5 * 1000; // wait 5 seconds for in-flight requests to complete before logout
public static final String SESSION_NAME = "RHQ_Sesssion";
private static Subject sessionSubject;
@@ -88,7 +88,7 @@ public class UserSessionManager {
try {
b.setCallback(new RequestCallback() {
public void onResponseReceived(final Request request, final Response response) {
- com.allen_sauer.gwt.log.client.Log.info("response text = " + response.getText());
+ Log.info("response text = " + response.getText());
String sessionIdString = response.getText();
if (sessionIdString != null && sessionIdString.length() > 0) {
@@ -96,20 +96,20 @@ public class UserSessionManager {
final int subjectId = Integer.parseInt(parts[0]);
final String sessionId = parts[1]; // not null
final long lastAccess = Long.parseLong(parts[2]);
- com.allen_sauer.gwt.log.client.Log.info("sessionAccess-subjectId: " + subjectId);
- com.allen_sauer.gwt.log.client.Log.info("sessionAccess-sessionId: " + sessionId);
- com.allen_sauer.gwt.log.client.Log.info("sessionAccess-lastAccess: " + lastAccess);
+ Log.info("sessionAccess-subjectId: " + subjectId);
+ Log.info("sessionAccess-sessionId: " + sessionId);
+ Log.info("sessionAccess-lastAccess: " + lastAccess);
String previousSessionId = getPreviousSessionId(); // may be null
- com.allen_sauer.gwt.log.client.Log.info("sessionAccess-previousSessionId: " + previousSessionId);
+ Log.info("sessionAccess-previousSessionId: " + previousSessionId);
if (previousSessionId == null || previousSessionId.equals(sessionId) == false) {
// persist sessionId if different from previously saved sessionId
- com.allen_sauer.gwt.log.client.Log.info("sessionAccess-savingSessionId: " + sessionId);
+ Log.info("sessionAccess-savingSessionId: " + sessionId);
saveSessionId(sessionId);
// new sessions get the full 29 minutes to expire
- com.allen_sauer.gwt.log.client.Log.info("sessionAccess-schedulingSessionTimeout: " + SESSION_TIMEOUT);
+ Log.info("sessionAccess-schedulingSessionTimeout: " + SESSION_TIMEOUT);
sessionTimer.schedule(SESSION_TIMEOUT);
} else {
@@ -124,7 +124,7 @@ public class UserSessionManager {
expiryMillis = SESSION_TIMEOUT; // guarantees maximum is 29 minutes
}
- com.allen_sauer.gwt.log.client.Log.info("sessionAccess-reschedulingSessionTimeout: " + expiryMillis);
+ Log.info("sessionAccess-reschedulingSessionTimeout: " + expiryMillis);
sessionTimer.schedule((int) expiryMillis);
}
@@ -143,7 +143,7 @@ public class UserSessionManager {
public void onFailure(Throwable caught) {
CoreGUI.getErrorHandler().handleError(
"UserSessionManager: Failed to load user's subject", caught);
- com.allen_sauer.gwt.log.client.Log.info("Failed to load user's subject");
+ Log.info("Failed to load user's subject");
new LoginView().showLoginDialog();
}
@@ -260,10 +260,12 @@ public class UserSessionManager {
public static String getSessionId() {
if (sessionSubject == null) {
+ Log.error("UserSessionManager: sessionSubject is null");
return null;
}
Integer sessionId = sessionSubject.getSessionId();
if (sessionId == null) {
+ Log.error("UserSessionManager: sessionId is null");
return null;
}
return sessionId.toString();
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/GWTServiceLookup.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/GWTServiceLookup.java
index 4a9c639..a779117 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/GWTServiceLookup.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/GWTServiceLookup.java
@@ -18,6 +18,7 @@
*/
package org.rhq.enterprise.gui.coregui.client.gwt;
+import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.user.client.rpc.RpcRequestBuilder;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
@@ -139,11 +140,6 @@ public class GWTServiceLookup {
public static class SessionRpcRequestBuilder extends RpcRequestBuilder {
@Override
- protected void doSetRequestData(RequestBuilder rb, String data) {
- super.doSetRequestData(rb, data); // TODO: Implement this method.
- }
-
- @Override
protected void doFinish(RequestBuilder rb) {
super.doFinish(rb);
@@ -152,7 +148,12 @@ public class GWTServiceLookup {
String sessionId = UserSessionManager.getSessionId();
if (sessionId != null) {
+ Log.info("SessionRpcRequestBuilder is adding sessionId to request: " + sessionId);
rb.setHeader(UserSessionManager.SESSION_NAME, sessionId);
+ } else {
+ Log
+ .error("SessionRpcRequestBuilder constructed without a value for "
+ + UserSessionManager.SESSION_NAME);
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AbstractGWTServiceImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AbstractGWTServiceImpl.java
index ae1e85b..c9da68a 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AbstractGWTServiceImpl.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AbstractGWTServiceImpl.java
@@ -24,6 +24,7 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import org.rhq.core.domain.auth.Subject;
@@ -34,9 +35,12 @@ import org.rhq.enterprise.server.util.LookupUtil;
/**
* @author Greg Hinkle
+ * @author Joseph Marques
*/
public abstract class AbstractGWTServiceImpl extends RemoteServiceServlet {
+ private static final long serialVersionUID = 1L;
+
private ThreadLocal<Subject> sessionSubject = new ThreadLocal<Subject>();
protected Subject getSessionSubject() {
@@ -46,20 +50,20 @@ public abstract class AbstractGWTServiceImpl extends RemoteServiceServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String sid = req.getHeader(UserSessionManager.SESSION_NAME);
- Subject subject = null;
if (sid != null) {
SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
try {
- subject = subjectManager.getSubjectBySessionId(Integer.parseInt(sid));
+ Subject subject = subjectManager.getSubjectBySessionId(Integer.parseInt(sid));
+ sessionSubject.set(subject);
} catch (Exception e) {
- throw new RuntimeException("Failed to validate session", e);
+ Log.error("Failed to validate request: sessionId was '" + sid + "', requestURL=" + req.getRequestURL());
}
+ } else {
+ Log.error("Failed to validate request: sessionId missing, requestURL=" + req.getRequestURL());
}
- sessionSubject.set(subject);
long id = HibernatePerformanceMonitor.get().start();
super.service(req, resp);
HibernatePerformanceMonitor.get().stop(id, "GWT Service Request");
}
-
}
commit 34d44ee66ec927b1dbb1d96fc15de3250622e7e4
Author: Joseph Marques <joseph(a)redhat.com>
Date: Mon Oct 4 14:07:42 2010 -0400
remove duplicate servlet definitions, alphabetize the rest
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml
index c486f1d..ecfac0b 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml
@@ -80,8 +80,11 @@
<servlet path="/AuthorizationGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.AuthorizationGWTServiceImpl"/>
<servlet path="/AvailabilityGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.AvailabilityGWTServiceImpl"/>
<servlet path="/BundleGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.BundleGWTServiceImpl"/>
+ <servlet path="/ClusterGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.ClusterGWTServiceImpl"/>
<servlet path="/ConfigurationGwtService" class="org.rhq.enterprise.gui.coregui.server.gwt.ConfigurationGWTServiceImpl"/>
<servlet path="/ContentGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.ContentGWTServiceImpl"/>
+ <servlet path="/DashboardGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.DashboardGWTServiceImpl"/>
+ <servlet path="/EventGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.EventGWTServiceImpl"/>
<servlet path="/MeasurementDataGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.MeasurementDataGWTServiceImpl"/>
<servlet path="/OperationGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.OperationGWTServiceImpl"/>
<servlet path="/RemoteInstallGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.RemoteInstallGWTServiceImpl"/>
@@ -95,11 +98,5 @@
<servlet path="/SubjectGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.SubjectGWTServiceImpl"/>
<servlet path="/SystemGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.SystemGWTServiceImpl"/>
<servlet path="/TagGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.TagGWTServiceImpl"/>
- <servlet path="/RemoteInstallGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.RemoteInstallGWTServiceImpl"/>
- <servlet path="/RepoGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.RepoGWTServiceImpl"/>
- <servlet path="/ContentGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.ContentGWTServiceImpl"/>
- <servlet path="/DashboardGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.DashboardGWTServiceImpl"/>
- <servlet path="/EventGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.EventGWTServiceImpl"/>
- <servlet path="/ClusterGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.ClusterGWTServiceImpl"/>
-</module>
\ No newline at end of file
+</module>
commit 01bb66ff5713c644f2f7bb4d46763a0866276eb5
Author: Joseph Marques <joseph(a)redhat.com>
Date: Mon Oct 4 14:03:50 2010 -0400
show as much detail in the message center as possible
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/create/BundleUploadDataStep.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/create/BundleUploadDataStep.java
index 34e343e..e62b908 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/create/BundleUploadDataStep.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/create/BundleUploadDataStep.java
@@ -204,8 +204,7 @@ public class BundleUploadDataStep extends AbstractWizardStep {
uploadForm.addFormSubmitFailedHandler(new FormSubmitFailedHandler() {
public void onFormSubmitFailed(FormSubmitFailedEvent event) {
allFilesStatus.put(uploadForm.getName(), Boolean.FALSE);
- CoreGUI.getMessageCenter().notify(
- new Message("Failed to upload file", null, Message.Severity.Error));
+ CoreGUI.getMessageCenter().notify(new Message("Failed to upload file", Message.Severity.Error));
}
});
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/ErrorHandler.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/ErrorHandler.java
index 49bb67e..1b97a65 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/ErrorHandler.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/ErrorHandler.java
@@ -18,11 +18,14 @@
*/
package org.rhq.enterprise.gui.coregui.client.util;
+import java.util.ArrayList;
+
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.util.message.Message;
/**
* @author Greg Hinkle
+ * @author Joseph Marques
*/
public class ErrorHandler {
public void handleError(String message) {
@@ -30,7 +33,7 @@ public class ErrorHandler {
}
public void handleError(String message, Throwable t) {
- Message errorMessage = new Message(message, (t == null) ? null : t.toString(), Message.Severity.Fatal);
+ Message errorMessage = new Message(message, t, Message.Severity.Fatal);
CoreGUI.getMessageCenter().notify(errorMessage);
if (t != null) {
@@ -38,4 +41,40 @@ public class ErrorHandler {
t.printStackTrace();
}
}
+
+ public static String getAllMessages(Throwable t) {
+ StringBuffer results = new StringBuffer();
+
+ if (t != null) {
+ String[] msgs = getAllMessagesArray(t);
+ results.append(msgs[0]);
+
+ String indent = " ";
+ for (int i = 1; i < msgs.length; i++) {
+ results.append("\n").append(indent);
+ results.append(msgs[i]);
+ indent = indent + " ";
+ }
+ } else {
+ results.append(">> exception was null <<");
+ }
+
+ return results.toString();
+ }
+
+ public static String[] getAllMessagesArray(Throwable t) {
+ ArrayList<String> list = new ArrayList<String>();
+
+ if (t != null) {
+ list.add(t.getClass().getName() + ":" + t.getMessage());
+
+ while ((t.getCause() != null) && (t != t.getCause())) {
+ t = t.getCause();
+
+ list.add(t.getClass().getName() + ":" + t.getMessage());
+ }
+ }
+
+ return list.toArray(new String[list.size()]);
+ }
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/Message.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/Message.java
index 3a0b464..a9e94c2 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/Message.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/Message.java
@@ -21,13 +21,14 @@ package org.rhq.enterprise.gui.coregui.client.util.message;
import java.util.Date;
import java.util.EnumSet;
+import org.rhq.enterprise.gui.coregui.client.util.ErrorHandler;
+
/**
* A message to be displayed to the user in one or more places.
*
* @author Greg Hinkle
* @author Ian Springer
*/
-@SuppressWarnings({"UnnecessarySemicolon"})
public class Message {
protected String conciseMessage;
protected String detailedMessage;
@@ -36,21 +37,30 @@ public class Message {
protected EnumSet<Option> options;
// TODO: Add Debug severity?
- public enum Severity { Info, Warning, Error, Fatal };
- public enum Option { Transient, Sticky, BackgroundJobResult };
+ public enum Severity {
+ Info, Warning, Error, Fatal
+ };
+
+ public enum Option {
+ Transient, Sticky, BackgroundJobResult
+ };
public Message(String conciseMessage) {
- this(conciseMessage, (Severity)null);
+ this(conciseMessage, (Severity) null);
}
public Message(String conciseMessage, Severity severity) {
- this(conciseMessage, null, severity);
+ this(conciseMessage, (String) null, severity);
}
public Message(String conciseMessage, String detailedMessage) {
this(conciseMessage, detailedMessage, null);
}
+ public Message(String conciseMessage, Throwable details) {
+ this(conciseMessage, details, null);
+ }
+
public Message(String conciseMessage, EnumSet<Option> options) {
this(conciseMessage, null, options);
}
@@ -59,8 +69,16 @@ public class Message {
this(conciseMessage, detailedMessage, severity, null);
}
+ public Message(String conciseMessage, Throwable details, Severity severity) {
+ this(conciseMessage, details, severity, null);
+ }
+
public Message(String conciseMessage, Severity severity, EnumSet<Option> options) {
- this(conciseMessage, null, severity, options);
+ this(conciseMessage, (String) null, severity, options);
+ }
+
+ public Message(String conciseMessage, Throwable details, Severity severity, EnumSet<Option> options) {
+ this(conciseMessage, ErrorHandler.getAllMessages(details), severity, options);
}
public Message(String conciseMessage, String detailedMessage, Severity severity, EnumSet<Option> options) {
@@ -97,15 +115,14 @@ public class Message {
public boolean isBackgroundJobResult() {
return options.contains(Option.BackgroundJobResult);
}
-
+
@Override
public String toString() {
- return "Message{" +
- "conciseMessage='" + this.conciseMessage + '\'' +
- ", detailedMessage='" + this.detailedMessage + '\'' +
- ", fired=" + this.fired +
- ", severity=" + this.severity +
- ", options=" + this.options +
- '}';
+ return "Message{" //
+ + "conciseMessage='" + this.conciseMessage + '\'' //
+ + ", detailedMessage='" + this.detailedMessage + '\'' //
+ + ", fired=" + this.fired //
+ + ", severity=" + this.severity //
+ + ", options=" + this.options + '}';
}
}
commit 25ccc993e3a166cbad9e03bf609343cb3b744c5a
Author: Ian Springer <ian.springer(a)redhat.com>
Date: Mon Oct 4 21:30:38 2010 -0400
finish support for lists of maps in config editor
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java
index d9c3dd7..fc63830 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java
@@ -147,12 +147,14 @@ import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
*/
@SuppressWarnings({"UnnecessarySemicolon"})
public class ConfigurationEditor extends LocatableVLayout {
+ private static final String RHQ_PROPERTY_ATTRIBUTE_NAME = "rhq:property";
+
private ConfigurationGWTServiceAsync configurationService = GWTServiceLookup.getConfigurationService();
private TabSet tabSet;
private LocatableToolStrip toolStrip;
- private ConfigurationDefinition definition;
+ private ConfigurationDefinition configurationDefinition;
private Configuration configuration;
private Configuration originalConfiguration;
@@ -169,7 +171,7 @@ public class ConfigurationEditor extends LocatableVLayout {
private boolean readOnly = false;
private Set<String> invalidPropertyNames = new HashSet<String>();
- private Set<PropertyValueChangeListener> validationStateChangeListeners =
+ private Set<PropertyValueChangeListener> propertyValueChangeListeners =
new HashSet<PropertyValueChangeListener>();
public static enum ConfigType {
@@ -193,10 +195,11 @@ public class ConfigurationEditor extends LocatableVLayout {
setOverflow(Overflow.AUTO);
}
- public ConfigurationEditor(String locatorId, ConfigurationDefinition definition, Configuration configuration) {
+ public ConfigurationEditor(String locatorId, ConfigurationDefinition configurationDefinition,
+ Configuration configuration) {
super(locatorId);
this.configuration = configuration;
- this.definition = definition;
+ this.configurationDefinition = configurationDefinition;
}
public Configuration getConfiguration() {
@@ -227,8 +230,8 @@ public class ConfigurationEditor extends LocatableVLayout {
return this.valuesManager.hasErrors();
}
- public void addValidationStateChangeListener(PropertyValueChangeListener validationStateChangeListener) {
- this.validationStateChangeListeners.add(validationStateChangeListener);
+ public void addPropertyValueChangeListener(PropertyValueChangeListener propertyValueChangeListener) {
+ this.propertyValueChangeListeners.add(propertyValueChangeListener);
}
@Override
@@ -240,7 +243,7 @@ public class ConfigurationEditor extends LocatableVLayout {
final long start = System.currentTimeMillis();
- if (definition == null || configuration == null) {
+ if (configurationDefinition == null || configuration == null) {
if (configType == ConfigType.resource) {
configurationService.getResourceConfiguration(resourceId, new AsyncCallback<Configuration>() {
@@ -260,8 +263,8 @@ public class ConfigurationEditor extends LocatableVLayout {
new ResourceTypeRepository.TypesLoadedCallback() {
public void onTypesLoaded(Map<Integer, ResourceType> types) {
com.allen_sauer.gwt.log.client.Log.debug("ConfigDef retreived in: " + (System.currentTimeMillis() - start));
- definition = types.get(resourceTypeId).getResourceConfigurationDefinition();
- if (definition == null) {
+ configurationDefinition = types.get(resourceTypeId).getResourceConfigurationDefinition();
+ if (configurationDefinition == null) {
loadingLabel.hide();
showError("Configuration is not supported by this Resource.");
}
@@ -286,8 +289,8 @@ public class ConfigurationEditor extends LocatableVLayout {
new ResourceTypeRepository.TypesLoadedCallback() {
public void onTypesLoaded(Map<Integer, ResourceType> types) {
com.allen_sauer.gwt.log.client.Log.debug("ConfigDef retreived in: " + (System.currentTimeMillis() - start));
- definition = types.get(resourceTypeId).getPluginConfigurationDefinition();
- if (definition == null) {
+ configurationDefinition = types.get(resourceTypeId).getPluginConfigurationDefinition();
+ if (configurationDefinition == null) {
showError("Connection settings are not supported by this Resource.");
}
reload();
@@ -300,7 +303,7 @@ public class ConfigurationEditor extends LocatableVLayout {
}
public void reload() {
- if (definition == null || configuration == null) {
+ if (configurationDefinition == null || configuration == null) {
// Wait for both to load
return;
}
@@ -309,16 +312,16 @@ public class ConfigurationEditor extends LocatableVLayout {
tabSet = new LocatableTabSet(getLocatorId());
- if (definition.getConfigurationFormat() == ConfigurationFormat.RAW
- || definition.getConfigurationFormat() == ConfigurationFormat.STRUCTURED_AND_RAW) {
+ if (configurationDefinition.getConfigurationFormat() == ConfigurationFormat.RAW
+ || configurationDefinition.getConfigurationFormat() == ConfigurationFormat.STRUCTURED_AND_RAW) {
com.allen_sauer.gwt.log.client.Log.info("Loading files view...");
Tab tab = new LocatableTab("Files", "Files");
tab.setPane(buildRawPane());
tabSet.addTab(tab);
}
- if (definition.getConfigurationFormat() == ConfigurationFormat.STRUCTURED
- || definition.getConfigurationFormat() == ConfigurationFormat.STRUCTURED_AND_RAW) {
+ if (configurationDefinition.getConfigurationFormat() == ConfigurationFormat.STRUCTURED
+ || configurationDefinition.getConfigurationFormat() == ConfigurationFormat.STRUCTURED_AND_RAW) {
com.allen_sauer.gwt.log.client.Log.info("Loading properties view...");
Tab tab = new LocatableTab("Properties", "Properties");
tab.setPane(buildStructuredPane());
@@ -391,7 +394,7 @@ public class ConfigurationEditor extends LocatableVLayout {
protected VLayout buildStructuredPane() {
LocatableVLayout layout = new LocatableVLayout(extendLocatorId("Structured"));
- List<PropertyGroupDefinition> definitions = definition.getGroupDefinitions();
+ List<PropertyGroupDefinition> definitions = configurationDefinition.getGroupDefinitions();
final SectionStack sectionStack = new LocatableSectionStack(layout.extendLocatorId("Sections"));
sectionStack.setVisibilityMode(VisibilityMode.MULTIPLE);
@@ -400,7 +403,7 @@ public class ConfigurationEditor extends LocatableVLayout {
sectionStack.setScrollSectionIntoView(true);
sectionStack.setOverflow(Overflow.AUTO);
- if (definition.getNonGroupedProperties().size() > 0) {
+ if (configurationDefinition.getNonGroupedProperties().size() > 0) {
sectionStack.addSection(buildGroupSection(layout.extendLocatorId("NoGroup"), null));
}
@@ -481,8 +484,8 @@ public class ConfigurationEditor extends LocatableVLayout {
section.setExpanded(!group.isDefaultHidden());
}
- List<PropertyDefinition> propertyDefinitions = new ArrayList<PropertyDefinition>(((group == null) ? definition
- .getNonGroupedProperties() : definition.getPropertiesInGroup(group.getName())));
+ List<PropertyDefinition> propertyDefinitions = new ArrayList<PropertyDefinition>(((group == null) ? configurationDefinition
+ .getNonGroupedProperties() : configurationDefinition.getPropertiesInGroup(group.getName())));
DynamicForm form = buildPropertiesForm(locatorId + "_Props", propertyDefinitions, configuration);
@@ -748,6 +751,7 @@ public class ConfigurationEditor extends LocatableVLayout {
PropertySimple prop = propertyMap.getSimple(propertyName);
if (prop == null) {
prop = new PropertySimple(propertyName, null);
+ propertyMap.put(prop);
}
String value = record.getAttribute("Value");
prop.setStringValue(value);
@@ -778,14 +782,30 @@ public class ConfigurationEditor extends LocatableVLayout {
summaryTable.setOverflow(Overflow.VISIBLE);
summaryTable.setAutoFitData(Autofit.HORIZONTAL);
- ArrayList<ListGridField> fieldsList = new ArrayList<ListGridField>();
- ArrayList<PropertyDefinition> definitions = new ArrayList<PropertyDefinition>(memberPropertyDefinitionMap
+ summaryTable.addCellSavedHandler(new CellSavedHandler() {
+ public void onCellSaved(CellSavedEvent cellSavedEvent) {
+ Record record = cellSavedEvent.getRecord();
+ PropertyMap propertyMap = (PropertyMap)record.getAttributeAsObject(RHQ_PROPERTY_ATTRIBUTE_NAME);
+ for (String memberPropertyName : memberPropertyDefinitionMap.getPropertyDefinitions().keySet()) {
+ PropertySimple memberProperty = propertyMap.getSimple(memberPropertyName);
+ if (memberProperty == null) {
+ memberProperty = new PropertySimple(memberPropertyName, null);
+ propertyMap.put(memberProperty);
+ }
+ String newValue = record.getAttribute(memberPropertyName);
+ memberProperty.setStringValue(newValue);
+ }
+ }
+ });
+
+ List<ListGridField> fieldsList = new ArrayList<ListGridField>();
+ List<PropertyDefinition> definitions = new ArrayList<PropertyDefinition>(memberPropertyDefinitionMap
.getPropertyDefinitions().values());
Collections.sort(definitions, new PropertyDefinitionComparator());
for (PropertyDefinition subDef : definitions) {
if (subDef.isSummary()) {
- ListGridField field = new ListGridField(subDef.getName(), subDef.getDisplayName());
+ ListGridField field = new ListGridField(subDef.getName(), subDef.getDisplayName(), 90);
PropertyDefinitionSimple defSimple = (PropertyDefinitionSimple) subDef;
if (defSimple.getType() == PropertySimpleType.INTEGER) {
@@ -798,7 +818,7 @@ public class ConfigurationEditor extends LocatableVLayout {
}
}
- if (fieldsList.size() == 0) {
+ if (fieldsList.isEmpty()) {
// An extra "feature of the config system". If no fields are labeled summary, all are considered summary.
for (PropertyDefinition subDef : definitions) {
ListGridField field = new ListGridField(subDef.getName(), subDef.getDisplayName());
@@ -809,7 +829,6 @@ public class ConfigurationEditor extends LocatableVLayout {
} else if (defSimple.getType() == PropertySimpleType.FLOAT) {
field.setType(ListGridFieldType.FLOAT);
}
-
}
}
@@ -823,10 +842,11 @@ public class ConfigurationEditor extends LocatableVLayout {
editField.setCanHide(false);
editField.addRecordClickHandler(new RecordClickHandler() {
public void onRecordClick(RecordClickEvent recordClickEvent) {
- com.allen_sauer.gwt.log.client.Log.info("You want to edit: " + recordClickEvent.getRecord());
+ Log.info("You want to edit: " + recordClickEvent.getRecord());
+ PropertyMap memberPropertyMap = (PropertyMap)recordClickEvent.getRecord().getAttributeAsObject(
+ RHQ_PROPERTY_ATTRIBUTE_NAME);
displayMapEditor(locatorId + "_MapEdit", summaryTable, recordClickEvent.getRecord(),
- memberPropertyDefinitionMap, propertyList, (PropertyMap) recordClickEvent.getRecord().getAttributeAsObject(
- "_RHQ_PROPERTY"));
+ memberPropertyDefinitionMap, propertyList, memberPropertyMap);
}
});
fieldsList.add(editField);
@@ -845,7 +865,7 @@ public class ConfigurationEditor extends LocatableVLayout {
removeField.addRecordClickHandler(new RecordClickHandler() {
public void onRecordClick(final RecordClickEvent recordClickEvent) {
- com.allen_sauer.gwt.log.client.Log.info("You want to delete: " + recordClickEvent.getRecordNum());
+ Log.info("You want to delete: " + recordClickEvent.getRecordNum());
SC.confirm("Are you sure you want to delete this row?", new BooleanCallback() {
public void execute(Boolean aBoolean) {
if (aBoolean) {
@@ -862,6 +882,7 @@ public class ConfigurationEditor extends LocatableVLayout {
summaryTable.setFields(fieldsList.toArray(new ListGridField[fieldsList.size()]));
+ // Now add rows containing the actual data (i.e. member property values).
ListGridRecord[] rows = buildSummaryRecords(propertyList, definitions);
summaryTable.setData(rows);
@@ -886,7 +907,7 @@ public class ConfigurationEditor extends LocatableVLayout {
return item;
}
- private ListGridRecord[] buildSummaryRecords(PropertyList propertyList, ArrayList<PropertyDefinition> definitions) {
+ private ListGridRecord[] buildSummaryRecords(PropertyList propertyList, List<PropertyDefinition> definitions) {
ListGridRecord[] rows = new ListGridRecord[propertyList == null ? 0 : propertyList.getList().size()];
int i = 0;
for (Property row : propertyList.getList()) {
@@ -897,11 +918,11 @@ public class ConfigurationEditor extends LocatableVLayout {
return rows;
}
- private ListGridRecord buildSummaryRecord(List<PropertyDefinition> definitions, PropertyMap rowMap) {
+ private ListGridRecord buildSummaryRecord(List<PropertyDefinition> memberPropertyDefinitions, PropertyMap memberPropertyMap) {
ListGridRecord record = new ListGridRecord();
- for (PropertyDefinition subDef : definitions) {
+ for (PropertyDefinition subDef : memberPropertyDefinitions) {
PropertyDefinitionSimple subDefSimple = (PropertyDefinitionSimple) subDef;
- PropertySimple propertySimple = ((PropertySimple) rowMap.get(subDefSimple.getName()));
+ PropertySimple propertySimple = ((PropertySimple) memberPropertyMap.get(subDefSimple.getName()));
if (propertySimple.getStringValue() != null) {
record.setAttribute(subDefSimple.getName(), propertySimple.getStringValue());
@@ -930,13 +951,12 @@ public class ConfigurationEditor extends LocatableVLayout {
}
}
- record.setAttribute("_RHQ_PROPERTY", rowMap);
+ record.setAttribute(RHQ_PROPERTY_ATTRIBUTE_NAME, memberPropertyMap);
return record;
}
private FormItem buildSimpleField(final PropertyDefinitionSimple propertyDefinition,
- final PropertySimple propertySimple
- ) {
+ final PropertySimple propertySimple) {
Log.debug("Building simple field for " + propertySimple + "...");
FormItem valueItem = null;
@@ -1004,6 +1024,7 @@ public class ConfigurationEditor extends LocatableVLayout {
List<Validator> validators = buildValidators(propertyDefinition, propertySimple);
valueItem.setValidators(validators.toArray(new Validator[validators.size()]));
+ valueItem.setDisabled(isReadOnly(propertyDefinition) || isUnset(propertyDefinition, propertySimple));
/*
Click handlers seem to be turned off for disabled fields... need an alternative
valueItem.addClickHandler(new com.smartgwt.client.widgets.form.fields.events.ClickHandler() {
@@ -1017,27 +1038,29 @@ public class ConfigurationEditor extends LocatableVLayout {
*/
valueItem.setShowTitle(false);
- valueItem.setDisabled(isReadOnly(propertyDefinition) || isUnset(propertyDefinition, propertySimple));
valueItem.setWidth(220);
final FormItem finalValueItem = valueItem;
finalValueItem.addChangedHandler(new ChangedHandler() {
public void onChanged(ChangedEvent changedEvent) {
- boolean wasValidBefore = ConfigurationEditor.this.invalidPropertyNames.isEmpty();
propertySimple.setErrorMessage(null);
+
+ boolean wasValidBefore = ConfigurationEditor.this.invalidPropertyNames.isEmpty();
+ Property topLevelProperty = getTopLevelProperty(propertySimple);
if (changedEvent.getItem().validate()) {
- ConfigurationEditor.this.invalidPropertyNames.remove(propertySimple.getName());
- propertySimple.setValue(changedEvent.getValue());
+ ConfigurationEditor.this.invalidPropertyNames.remove(topLevelProperty.getName());
+ propertySimple.setValue(changedEvent.getValue());
} else {
- ConfigurationEditor.this.invalidPropertyNames.add(propertySimple.getName());
+ ConfigurationEditor.this.invalidPropertyNames.add(topLevelProperty.getName());
}
boolean isValidNow = ConfigurationEditor.this.invalidPropertyNames.isEmpty();
+
boolean validationStateChanged = (isValidNow != wasValidBefore);
- for (PropertyValueChangeListener validationStateChangeListener : ConfigurationEditor.this.validationStateChangeListeners) {
+ for (PropertyValueChangeListener propertyValueChangeListener : ConfigurationEditor.this.propertyValueChangeListeners) {
PropertyValueChangeEvent event = new PropertyValueChangeEvent(propertySimple, propertyDefinition,
validationStateChanged, ConfigurationEditor.this.invalidPropertyNames);
- validationStateChangeListener.propertyValueChanged(event);
+ propertyValueChangeListener.propertyValueChanged(event);
}
}
});
@@ -1045,9 +1068,19 @@ public class ConfigurationEditor extends LocatableVLayout {
return valueItem;
}
- private boolean isUnset(PropertyDefinitionSimple propertyDefinition, PropertySimple propertySimple) {
- return (!propertyDefinition.isRequired() &&
- (propertySimple == null || propertySimple.getStringValue() == null));
+ private static Property getTopLevelProperty(PropertySimple propertySimple) {
+ Property currentProperty = propertySimple;
+ while (currentProperty.getConfiguration() == null) {
+ if (currentProperty.getParentList() != null) {
+ currentProperty = currentProperty.getParentList();
+ } else if (currentProperty.getParentMap() != null) {
+ currentProperty = currentProperty.getParentMap();
+ } else {
+ Log.error("Property " + currentProperty + " has no parent.");
+ break;
+ }
+ }
+ return currentProperty;
}
private FormItem buildUnsetItem(PropertyDefinitionSimple propertyDefinition, final PropertySimple property,
@@ -1083,6 +1116,11 @@ public class ConfigurationEditor extends LocatableVLayout {
return item;
}
+ private boolean isUnset(PropertyDefinitionSimple propertyDefinition, PropertySimple propertySimple) {
+ return (!propertyDefinition.isRequired() &&
+ (propertySimple == null || propertySimple.getStringValue() == null));
+ }
+
private boolean isReadOnly(PropertyDefinition propertyDefinition) {
return propertyDefinition.isReadOnly() || this.readOnly;
}
@@ -1131,14 +1169,14 @@ public class ConfigurationEditor extends LocatableVLayout {
private void displayMapEditor(String locatorId, final ListGrid summaryTable, final Record existingRecord,
PropertyDefinitionMap definition, final PropertyList list, PropertyMap map) {
- final List<PropertyDefinition> definitions = new ArrayList<PropertyDefinition>(definition
+ final List<PropertyDefinition> memberDefinitions = new ArrayList<PropertyDefinition>(definition
.getPropertyDefinitions().values());
-
- Collections.sort(definitions, new PropertyDefinitionComparator());
+ Collections.sort(memberDefinitions, new PropertyDefinitionComparator());
final boolean newRow = map == null;
- if (newRow)
+ if (newRow) {
map = new PropertyMap(definition.getName());
+ }
final PropertyMap finalMap = map;
final PropertyMap copy = finalMap.deepCopy(true);
@@ -1146,7 +1184,7 @@ public class ConfigurationEditor extends LocatableVLayout {
LocatableVLayout layout = new LocatableVLayout(locatorId);
layout.setHeight100();
- DynamicForm childForm = buildPropertiesForm(locatorId + "_Child", definitions, finalMap);
+ final DynamicForm childForm = buildPropertiesForm(locatorId + "_Child", memberDefinitions, finalMap);
childForm.setHeight100();
layout.addMember(childForm);
@@ -1159,24 +1197,21 @@ public class ConfigurationEditor extends LocatableVLayout {
popup.setShowCloseButton(false);
popup.centerInPage();
- final IButton saveButton = new IButton("Save");
+ final IButton okButton = new IButton("OK");
+ okButton.disable();
// saveButton.setID("config_structured_button_save");
- saveButton.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() {
+ okButton.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() {
public void onClick(ClickEvent clickEvent) {
-
if (newRow) {
list.add(finalMap);
- ListGridRecord record = buildSummaryRecord(definitions, finalMap);
-
- com.allen_sauer.gwt.log.client.Log.info("here");
+ ListGridRecord record = buildSummaryRecord(memberDefinitions, finalMap);
try {
summaryTable.addData(record);
- com.allen_sauer.gwt.log.client.Log.info("there");
} catch (Exception e) {
e.printStackTrace();
}
} else {
- for (PropertyDefinition subDef : definitions) {
+ for (PropertyDefinition subDef : memberDefinitions) {
PropertyDefinitionSimple subDefSimple = (PropertyDefinitionSimple) subDef;
PropertySimple propertySimple = ((PropertySimple) finalMap.get(subDefSimple.getName()));
existingRecord.setAttribute(subDefSimple.getName(), propertySimple != null ? propertySimple
@@ -1191,7 +1226,13 @@ public class ConfigurationEditor extends LocatableVLayout {
// summaryTable.redraw();
// summaryTable.addData();
popup.destroy();
+ }
+ });
+ // Only enable the OK button if all properties are valid.
+ childForm.addItemChangedHandler(new ItemChangedHandler() {
+ public void onItemChanged(ItemChangedEvent itemChangedEvent) {
+ okButton.setDisabled(!childForm.validate());
}
});
@@ -1208,13 +1249,12 @@ public class ConfigurationEditor extends LocatableVLayout {
HLayout buttons = new HLayout();
buttons.setAlign(Alignment.CENTER);
buttons.setMembersMargin(10);
- buttons.setMembers(saveButton, cancelButton);
+ buttons.setMembers(okButton, cancelButton);
layout.addMember(buttons);
popup.addItem(layout);
popup.show();
-
}
private static class PropertyDefinitionComparator implements Comparator<PropertyDefinition> {
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ResourceConfigurationEditView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ResourceConfigurationEditView.java
index f5afb2c..3f9f225 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ResourceConfigurationEditView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ResourceConfigurationEditView.java
@@ -101,7 +101,7 @@ public class ResourceConfigurationEditView extends LocatableVLayout implements P
editor = new ConfigurationEditor(this.extendLocatorId("Editor"), resource.getId(),
resource.getResourceType().getId());
editor.setOverflow(Overflow.AUTO);
- editor.addValidationStateChangeListener(this);
+ editor.addPropertyValueChangeListener(this);
editor.setReadOnly(!this.resourcePermission.isConfigureWrite());
addMember(editor);
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/inventory/PluginConfigurationEditView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/inventory/PluginConfigurationEditView.java
index 116e1ad..1f1cc52 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/inventory/PluginConfigurationEditView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/inventory/PluginConfigurationEditView.java
@@ -101,7 +101,7 @@ public class PluginConfigurationEditView extends LocatableVLayout implements Pro
editor = new ConfigurationEditor(extendLocatorId("Editor"), resource.getId(),
resource.getResourceType().getId(), ConfigurationEditor.ConfigType.plugin);
editor.setOverflow(Overflow.AUTO);
- editor.addValidationStateChangeListener(this);
+ editor.addPropertyValueChangeListener(this);
editor.setReadOnly(!this.resourcePermission.isInventory());
addMember(editor);
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationFactory.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationFactory.java
index bfcb322..cc71a2c 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationFactory.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationFactory.java
@@ -244,11 +244,11 @@ public abstract class TestConfigurationFactory {
propMap3.put(new PropertySimple("Integer", Integer.MAX_VALUE));
configuration.put(new PropertyList("ListOfMaps", propMap2, propMap3));
- PropertyMap propMap4 = new PropertyMap("MapOfSimples");
+ PropertyMap propMap4 = new PropertyMap("MapOfSimplesInReadOnlyList");
propMap4.put(new PropertySimple("String1", "A"));
propMap4.put(new PropertySimple("String2", "B"));
propMap4.put(new PropertySimple("Integer", 999));
- PropertyMap propMap5 = new PropertyMap("MapOfSimples");
+ PropertyMap propMap5 = new PropertyMap("MapOfSimplesInReadOnlyList");
propMap5.put(new PropertySimple("String1", "a"));
propMap5.put(new PropertySimple("String2", "b"));
propMap5.put(new PropertySimple("Integer", 0));
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationView.java
index 0349718..2fd5dfa 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationView.java
@@ -86,24 +86,6 @@ public class TestConfigurationView
reloadConfiguration();
}
- private void reloadConfiguration() {
- this.saveButton.disable();
- if (editor != null) {
- editor.destroy();
- removeMember(editor);
- }
-
- editor = new ConfigurationEditor(extendLocatorId("Editor"), this.configurationDefinition, this.configuration);
- editor.setOverflow(Overflow.AUTO);
- editor.addValidationStateChangeListener(this);
- addMember(editor);
- }
-
- private void save() {
- CoreGUI.getMessageCenter().notify(
- new Message("Configuration updated.", "Test configuration updated."));
- }
-
@Override
public void propertyValueChanged(PropertyValueChangeEvent event) {
MessageCenter messageCenter = CoreGUI.getMessageCenter();
@@ -126,4 +108,23 @@ public class TestConfigurationView
this.saveButton.enable();
}
}
+
+ private void reloadConfiguration() {
+ this.saveButton.disable();
+ if (editor != null) {
+ editor.destroy();
+ removeMember(editor);
+ }
+
+ editor = new ConfigurationEditor(extendLocatorId("Editor"), this.configurationDefinition, this.configuration);
+ editor.setOverflow(Overflow.AUTO);
+ editor.addPropertyValueChangeListener(this);
+ addMember(editor);
+ }
+
+ private void save() {
+ CoreGUI.getMessageCenter().notify(
+ new Message("Configuration updated.", "Test configuration updated."));
+ reloadConfiguration();
+ }
}
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/TestConfigurationFactory.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/TestConfigurationFactory.java
index 37dddbb..ccc5eeb 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/TestConfigurationFactory.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/TestConfigurationFactory.java
@@ -236,11 +236,11 @@ public abstract class TestConfigurationFactory {
propMap3.put(new PropertySimple("Integer", Integer.MAX_VALUE));
configuration.put(new PropertyList("ListOfMaps", propMap2, propMap3));
- PropertyMap propMap4 = new PropertyMap("MapOfSimples");
+ PropertyMap propMap4 = new PropertyMap("MapOfSimplesInReadOnlyList");
propMap4.put(new PropertySimple("String1", "A"));
propMap4.put(new PropertySimple("String2", "B"));
propMap4.put(new PropertySimple("Integer", 999));
- PropertyMap propMap5 = new PropertyMap("MapOfSimples");
+ PropertyMap propMap5 = new PropertyMap("MapOfSimplesInReadOnlyList");
propMap5.put(new PropertySimple("String1", "a"));
propMap5.put(new PropertySimple("String2", "b"));
propMap5.put(new PropertySimple("Integer", 0));
commit 978b466848e1bd299f191f370ca8c10e57f0f557
Author: John Sanda <jsanda(a)redhat.com>
Date: Mon Oct 4 20:07:50 2010 -0400
Adding test to verify options are added to an upgraded property
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBeanTest.java
index 2324a43..1f72c06 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBeanTest.java
@@ -35,6 +35,7 @@ import org.rhq.core.clientapi.descriptor.plugin.PluginDescriptor;
import org.rhq.core.clientapi.descriptor.plugin.ServerDescriptor;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.domain.configuration.definition.PropertyDefinition;
+import org.rhq.core.domain.configuration.definition.PropertyDefinitionEnumeration;
import org.rhq.core.domain.configuration.definition.PropertyDefinitionList;
import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap;
import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
@@ -109,6 +110,21 @@ public class ConfigurationMetadataManagerBeanTest extends AbstractEJB3Test {
}
@Test
+ public void updatePropertyWithAddedOptions() {
+ initConfigDefs("servers[name='ServerWithAddedOptions']", "UpdatedPropertyWithAddedOptions");
+
+ String propertyName = "mySimple";
+ PropertyDefinitionSimple expectedProperty = updatedConfigDef.getPropertyDefinitionSimple(propertyName);
+ List<PropertyDefinitionEnumeration> expected = expectedProperty.getEnumeratedValues();
+
+ PropertyDefinitionSimple actualProperty = originalConfigDef.getPropertyDefinitionSimple(propertyName);
+ List<PropertyDefinitionEnumeration> actual = actualProperty.getEnumeratedValues();
+
+ // TODO Need to verify order here as well
+ AssertUtils.assertCollectionEqualsNoOrder(expected, actual, "Options should have been added to property");
+ }
+
+ @Test
public void addNewGroup() {
initConfigDefs("servers[name='GroupTests']", "GroupTests");
diff --git a/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v1.xml b/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v1.xml
index 23f3a1b..5a1fe11 100644
--- a/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v1.xml
+++ b/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v1.xml
@@ -19,6 +19,12 @@
</plugin-configuration>
</server>
+ <server name="ServerWithAddedOptions">
+ <plugin-configuration>
+ <c:simple-property name="mySimple"/>
+ </plugin-configuration>
+ </server>
+
<server name="GroupTests">
<plugin-configuration>
<c:group name="existingGroup">
diff --git a/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v2.xml b/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v2.xml
index 4c61512..564c68c 100644
--- a/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v2.xml
+++ b/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v2.xml
@@ -26,6 +26,17 @@
</plugin-configuration>
</server>
+ <server name="ServerWithAddedOptions">
+ <plugin-configuration>
+ <c:simple-property name="mySimple">
+ <c:property-options>
+ <c:option name="x" value="1"/>
+ <c:option name="y" value="2"/>
+ </c:property-options>
+ </c:simple-property>
+ </plugin-configuration>
+ </server>
+
<server name="GroupTests">
<plugin-configuration>
<c:group name="existingGroup">
commit 885a5f526a3868a44d3f07f61c5df1ed1ef4ae16
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Mon Oct 4 17:02:47 2010 -0400
implement the new alert-role server plugin notification editor. this needs to be tested to make sure the sender still works. but the notification configuration is consistent with how it was before so it should work
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/RoleCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/RoleCriteria.java
index 3237c49..2d18670 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/RoleCriteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/RoleCriteria.java
@@ -22,10 +22,13 @@
*/
package org.rhq.core.domain.criteria;
+import java.util.List;
+
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import org.rhq.core.domain.authz.Role;
+import org.rhq.core.domain.util.CriteriaUtils;
import org.rhq.core.domain.util.PageOrdering;
/**
@@ -39,7 +42,8 @@ public class RoleCriteria extends Criteria {
private Integer filterId;
private String filterDescription;
private String filterName;
- private Integer filterSubjectId;
+ private Integer filterSubjectId; // needs overrides
+ private List<Integer> filterIds; // needs overrides
private boolean fetchPermissions;
private boolean fetchResourceGroups;
@@ -54,6 +58,8 @@ public class RoleCriteria extends Criteria {
+ " FROM Role innerRole " //
+ " JOIN innerRole.subjects innerSubject " //
+ " WHERE innerSubject.id = ? )");
+
+ filterOverrides.put("ids", "id IN ( ? )");
}
@Override
@@ -77,6 +83,10 @@ public class RoleCriteria extends Criteria {
this.filterSubjectId = filterSubjectId;
}
+ public void addFilterIds(Integer... filterIds) {
+ this.filterIds = CriteriaUtils.getListIgnoringNulls(filterIds);
+ }
+
/**
* Requires MANAGE_SECURITY
* @param fetchSubjects
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java
index 7d8745d..40bd990 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java
@@ -220,7 +220,7 @@ public class NewNotificationEditor extends LocatableDynamicForm {
if ("System Users".equals(sender)) {
newCanvas = new SystemUsersNotificationSenderForm(newLocatorId, notificationToEdit, sender);
} else if ("System Roles".equals(sender)) {
- newCanvas = null; // TODO
+ newCanvas = new SystemRolesNotificationSenderForm(newLocatorId, notificationToEdit, sender);
} else if ("Resource Operations".equals(sender)) {
newCanvas = null; // TODO
} else {
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SystemRolesNotificationSenderForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SystemRolesNotificationSenderForm.java
new file mode 100644
index 0000000..fe4cf36
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SystemRolesNotificationSenderForm.java
@@ -0,0 +1,202 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.rhq.enterprise.gui.coregui.client.alert.definitions;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.data.Criteria;
+import com.smartgwt.client.widgets.form.DynamicForm;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+
+import org.rhq.core.domain.alert.notification.AlertNotification;
+import org.rhq.core.domain.authz.Role;
+import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.domain.criteria.RoleCriteria;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.admin.roles.RolesDataSource;
+import org.rhq.enterprise.gui.coregui.client.components.selector.AbstractSelector;
+import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
+
+/**
+ * This notification form will be used for the System Roles sender. This form lets
+ * you pick roles that the sender will send notifications to.
+ *
+ * @author John Mazzitelli
+ */
+public class SystemRolesNotificationSenderForm extends AbstractNotificationSenderForm {
+
+ // the alert configuration property name where the IDs are stored in |-separated form
+ private static final String PROPNAME = "roleId";
+
+ private RoleSelector selector;
+
+ public SystemRolesNotificationSenderForm(String locatorId, AlertNotification notif, String sender) {
+ super(locatorId, notif, sender);
+ }
+
+ @Override
+ protected void onInit() {
+ super.onInit();
+
+ String roleIds = getConfiguration().getSimpleValue(PROPNAME, ""); // we know the role plugin defines this
+ if (roleIds != null && roleIds.length() > 0) {
+ try {
+ List<Integer> ids = unfence(roleIds, Integer.class);
+ RoleCriteria criteria = new RoleCriteria();
+ criteria.addFilterIds(ids.toArray(new Integer[ids.size()]));
+ GWTServiceLookup.getRoleService().findRolesByCriteria(criteria, new AsyncCallback<PageList<Role>>() {
+ @Override
+ public void onSuccess(PageList<Role> result) {
+ createNewSelector(result);
+ }
+
+ @Override
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler()
+ .handleError("Cannot determine current roles - starting empty", caught);
+ createNewSelector(null);
+ }
+ });
+ } catch (Exception e) {
+ CoreGUI.getErrorHandler().handleError("Cannot use current roles - starting empty", e);
+ createNewSelector(null);
+ }
+ } else {
+ createNewSelector(null);
+ }
+ }
+
+ private void createNewSelector(Collection<Role> preselectedRoles) {
+ String selectorLocatorId = extendLocatorId("roleSelector");
+ selector = new RoleSelector(selectorLocatorId, preselectedRoles);
+ selector.setWidth(400);
+ selector.setHeight(300);
+ addMember(selector);
+ markForRedraw();
+ }
+
+ @Override
+ public boolean validate() {
+ if (selector != null) {
+ try {
+ HashSet<Integer> selectedIds = selector.getSelection();
+ String newPropValue = fence(selectedIds);
+ getConfiguration().put(new PropertySimple(PROPNAME, newPropValue));
+ return true;
+ } catch (Exception e) {
+ CoreGUI.getErrorHandler().handleError("Cannot save the selected roles", e);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T> List<T> unfence(String fencedData, Class<T> type) {
+ String delimiter = "\\|";
+ String[] elements = fencedData.split(delimiter);
+ List<T> results = new ArrayList<T>(elements.length);
+
+ if (Integer.class.equals(type)) {
+ for (String next : elements) {
+ if (next.length() != 0) {
+ results.add((T) Integer.valueOf(next));
+ }
+ }
+ } else if (String.class.equals(type)) {
+ for (String next : elements) {
+ if (next.length() != 0) {
+ results.add((T) next);
+ }
+ }
+ } else {
+ throw new IllegalArgumentException("No support for unfencing data of type " + type);
+ }
+ return results;
+ }
+
+ /**
+ * Takes the list of elements e1, e2, e3 and fences
+ * them with '|' delimiters such that the result looks
+ * like "|e1|e2|e3|"
+ */
+ private String fence(Collection<?> elements) {
+ if (elements.size() == 0) {
+ return "";
+ }
+ StringBuilder builder = new StringBuilder();
+ builder.append('|');
+ for (Object next : elements) {
+ builder.append(String.valueOf(next)).append('|');
+ }
+ return builder.toString();
+ }
+
+ private class RoleSelector extends AbstractSelector<Role> {
+
+ public RoleSelector(String id, Collection<Role> roles) {
+ super(id);
+ if (roles != null) {
+ ListGridRecord[] data = (new RolesDataSource()).buildRecords(roles);
+ setAssigned(data);
+ }
+ }
+
+ @Override
+ protected RPCDataSource<Role> getDataSource() {
+ return new SelectedRolesDataSource();
+ }
+
+ @Override
+ protected DynamicForm getAvailableFilterForm() {
+ return null; // No Filters Currently
+ }
+
+ @Override
+ protected Criteria getLatestCriteria(DynamicForm availableFilterForm) {
+ return null; // No Filters Currently
+ }
+
+ public class SelectedRolesDataSource extends RolesDataSource {
+
+ @Override
+ public ListGridRecord[] buildRecords(Collection<Role> roles) {
+ ListGridRecord[] records = super.buildRecords(roles);
+ for (ListGridRecord record : records) {
+ if (selection.contains(record.getAttributeAsInt("id"))) {
+ record.setEnabled(false);
+ }
+ }
+ return records;
+ }
+ }
+
+ }
+}
diff --git a/modules/enterprise/server/plugins/alert-roles/src/main/java/org/rhq/enterprise/server/plugins/alertRoles/RolesBackingBean.java b/modules/enterprise/server/plugins/alert-roles/src/main/java/org/rhq/enterprise/server/plugins/alertRoles/RolesBackingBean.java
deleted file mode 100644
index a7f556e..0000000
--- a/modules/enterprise/server/plugins/alert-roles/src/main/java/org/rhq/enterprise/server/plugins/alertRoles/RolesBackingBean.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2009 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.plugins.alertRoles;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.rhq.core.domain.authz.Role;
-import org.rhq.core.domain.configuration.PropertySimple;
-import org.rhq.core.domain.util.PageControl;
-import org.rhq.enterprise.server.plugin.pc.alert.AlertSender;
-import org.rhq.enterprise.server.plugin.pc.alert.CustomAlertSenderBackingBean;
-import org.rhq.enterprise.server.util.LookupUtil;
-
-/**
- * Backing Bean for the roles sender alert sender plugin custom UI
- * @author Joseph Marques
- */
-public class RolesBackingBean extends CustomAlertSenderBackingBean {
-
- private Map<String, String> available;
- private List<String> currentRoles;
- private static final String ROLE_ID = "roleId";
-
- @Override
- public void loadView() {
- // get available/all subjects
- List<Role> allRoles = LookupUtil.getRoleManager().findRoles(new PageControl());
- available = new HashMap<String, String>();
- for (Role role : allRoles) {
- String roleId = String.valueOf(role.getId());
- available.put(role.getName(), roleId);
- }
-
- // get current subjects
- String subjectString = alertParameters.getSimpleValue(ROLE_ID, "");
- currentRoles = AlertSender.unfence(subjectString, String.class);
- }
-
- @Override
- public void saveView() {
- String roleIds = AlertSender.fence(currentRoles);
-
- PropertySimple p = alertParameters.getSimple(ROLE_ID);
- if (p == null) {
- p = new PropertySimple(ROLE_ID, roleIds);
- alertParameters.put(p);
- } else {
- p.setStringValue(roleIds);
- }
-
- alertParameters = persistConfiguration(alertParameters);
- }
-
- public List<String> getCurrentRoles() {
- return currentRoles;
- }
-
- public void setCurrentRoles(List<String> currentRoles) {
- this.currentRoles = currentRoles;
- }
-
- public Map<String, String> getAvailableRolesMap() {
- return available;
- }
-}
diff --git a/modules/enterprise/server/plugins/alert-roles/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/alert-roles/src/main/resources/META-INF/rhq-serverplugin.xml
index 7d7551c..4e50100 100644
--- a/modules/enterprise/server/plugins/alert-roles/src/main/resources/META-INF/rhq-serverplugin.xml
+++ b/modules/enterprise/server/plugins/alert-roles/src/main/resources/META-INF/rhq-serverplugin.xml
@@ -14,19 +14,13 @@
Used to send notifications to all users in the selected system roles.
</serverplugin:help>
- <!-- startup & tear down listener, + scheduled jobs
- <serverplugin:plugin-component class="Foo" />
- -->
-
<!-- How does this sender show up in drop downs etc -->
<short-name>System Roles</short-name>
<!-- Class that does the actual sending -->
<plugin-class>RolesSender</plugin-class>
- <custom-ui>
- <ui-snippet-name>roles.xhtml</ui-snippet-name>
- <backing-bean-class>RolesBackingBean</backing-bean-class>
- <backing-bean-name>rolesBean</backing-bean-name>
- </custom-ui>
+ <alert-configuration>
+ <c:simple-property name="roleId" type="string" required="true" description="The roles (ids are |-separated) to be notified"/>
+ </alert-configuration>
</alert-plugin>
\ No newline at end of file
diff --git a/modules/enterprise/server/plugins/alert-roles/src/main/resources/roles.xhtml b/modules/enterprise/server/plugins/alert-roles/src/main/resources/roles.xhtml
deleted file mode 100644
index f807414..0000000
--- a/modules/enterprise/server/plugins/alert-roles/src/main/resources/roles.xhtml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<html xmlns="http://www.w3.org/1999/xhtml"
- xmlns:h="http://java.sun.com/jsf/html"
- xmlns:f="http://java.sun.com/jsf/core"
- xmlns:ui="http://java.sun.com/jsf/facelets"
- xmlns:c="http://java.sun.com/jstl/core"
- xmlns:a4j="https://richfaces.org/a4j"
- xmlns:rich="http://richfaces.ajax4jsf.org/rich">
-
-<body>
- <rich:pickList fastMoveControlsVisible="false"
- sourceListWidth="200px"
- targetListWidth="200px"
- copyControlLabel="Add Roles"
- removeControlLabel="Remove Roles"
- value="#{rolesBean.currentRoles}">
- <f:selectItems value="#{rolesBean.availableRolesMap}" />
- </rich:pickList>
-</body>
-
-</html>
\ No newline at end of file
commit c1145e500bd70a985a0b609de0f42655902d23a6
Author: Ian Springer <ian.springer(a)redhat.com>
Date: Mon Oct 4 16:58:21 2010 -0400
finish support for top-level maps - both static and dynamic/open; disable window logger
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml
index ed2ce42..c486f1d 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml
@@ -38,7 +38,9 @@
2. In hosted mode, the windows are not automatically closed,
although you can easily close them manually in the usual way
-->
+ <!--
<set-property name="log_WindowLogger" value="ENABLED" />
+ -->
<!--
You probably will want to disable the default `DivLogger` as well:
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java
index fdc2d9c..d9c3dd7 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java
@@ -19,6 +19,7 @@
package org.rhq.enterprise.gui.coregui.client.components.configuration;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumSet;
@@ -29,6 +30,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.types.Alignment;
@@ -138,9 +140,12 @@ import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableTreeGrid;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
/**
+ * A SmartGWT widget for editing an RHQ {@link Configuration}, which conforms to a {@link ConfigurationDefinition}.
+ *
* @author Greg Hinkle
* @author Ian Springer
*/
+@SuppressWarnings({"UnnecessarySemicolon"})
public class ConfigurationEditor extends LocatableVLayout {
private ConfigurationGWTServiceAsync configurationService = GWTServiceLookup.getConfigurationService();
@@ -170,7 +175,6 @@ public class ConfigurationEditor extends LocatableVLayout {
public static enum ConfigType {
plugin, resource
}
-
; // Need this extra semicolon for the qdox parser
public ConfigurationEditor(String locatorId) {
@@ -330,6 +334,11 @@ public class ConfigurationEditor extends LocatableVLayout {
this.markForRedraw();
}
+ public void reset() {
+ this.configuration = this.originalConfiguration;
+ reload();
+ }
+
protected HLayout buildRawPane() {
LocatableHLayout layout = new LocatableHLayout(extendLocatorId("Raw"));
@@ -457,7 +466,6 @@ public class ConfigurationEditor extends LocatableVLayout {
}
public SectionStackSection buildGroupSection(String locatorId, PropertyGroupDefinition group) {
-
SectionStackSection section;
if (group == null) {
section = new SectionStackSection("General Properties");
@@ -473,18 +481,25 @@ public class ConfigurationEditor extends LocatableVLayout {
section.setExpanded(!group.isDefaultHidden());
}
- ArrayList<PropertyDefinition> definitions = new ArrayList<PropertyDefinition>(((group == null) ? definition
- .getNonGroupedProperties() : definition.getPropertiesInGroup(group.getName())));
- Collections.sort(definitions, new PropertyDefinitionComparator());
+ List<PropertyDefinition> propertyDefinitions = new ArrayList<PropertyDefinition>(((group == null) ? definition
+ .getNonGroupedProperties() : definition.getPropertiesInGroup(group.getName())));
- DynamicForm form = buildPropertiesForm(locatorId + "_Props", definitions, configuration);
+ DynamicForm form = buildPropertiesForm(locatorId + "_Props", propertyDefinitions, configuration);
section.addItem(form);
return section;
}
- private DynamicForm buildPropertiesForm(String locatorId, List<PropertyDefinition> definitions,
+ private DynamicForm buildPropertiesForm(String locatorId, Collection<PropertyDefinition> propertyDefinitions,
AbstractPropertyMap propertyMap) {
+ List<PropertyDefinition> propertyDefinitionsList;
+ if (!(propertyDefinitions instanceof List)) {
+ propertyDefinitionsList = new ArrayList<PropertyDefinition>(propertyDefinitions);
+ } else {
+ propertyDefinitionsList = (List<PropertyDefinition>)propertyDefinitions;
+ }
+ Collections.sort(propertyDefinitionsList, new PropertyDefinitionComparator());
+
LocatableDynamicForm form = new LocatableDynamicForm(locatorId);
form.setValuesManager(valuesManager);
form.setValidateOnChange(true);
@@ -503,11 +518,17 @@ public class ConfigurationEditor extends LocatableVLayout {
form.setCellPadding(5);
form.setColWidths(190, 28, 210);
- ArrayList<FormItem> fields = new ArrayList<FormItem>();
+ List<FormItem> fields = new ArrayList<FormItem>();
+ addItemsForPropertiesRecursively(locatorId, propertyDefinitionsList, propertyMap, fields);
+ form.setFields(fields.toArray(new FormItem[fields.size()]));
+
+ return form;
+ }
+ private void addItemsForPropertiesRecursively(String locatorId, Collection<PropertyDefinition> propertyDefinitions,
+ AbstractPropertyMap propertyMap, List<FormItem> fields) {
boolean odd = true;
-
- for (PropertyDefinition propertyDefinition : definitions) {
+ for (PropertyDefinition propertyDefinition : propertyDefinitions) {
Property property = propertyMap.get(propertyDefinition.getName());
if (property == null) {
if (propertyDefinition instanceof PropertyDefinitionSimple) {
@@ -515,17 +536,17 @@ public class ConfigurationEditor extends LocatableVLayout {
propertyMap.put(property);
}
}
- addItems(locatorId + "_" + propertyDefinition.getName(), fields, propertyDefinition, property, odd);
+ addItemsForPropertyRecursively(locatorId + "_" + propertyDefinition.getName(), propertyDefinition, property,
+ odd, fields);
odd = !odd;
}
-
- form.setFields(fields.toArray(new FormItem[fields.size()]));
-
- return form;
}
- public void addItems(String locatorId, ArrayList<FormItem> fields, PropertyDefinition propertyDefinition,
- Property property, boolean oddRow) {
+ public void addItemsForPropertyRecursively(String locatorId, PropertyDefinition propertyDefinition,
+ Property property,
+ boolean oddRow,
+ List<FormItem> fields) {
+ List<FormItem> fieldsForThisProperty = new ArrayList<FormItem>();
StaticTextItem nameItem = new StaticTextItem();
nameItem.setStartRow(true);
@@ -534,30 +555,50 @@ public class ConfigurationEditor extends LocatableVLayout {
.getName()) + "</b>";
nameItem.setValue(title);
nameItem.setShowTitle(false);
- nameItem.setCellStyle(oddRow ? "OddRow" : "EvenRow");
+ fieldsForThisProperty.add(nameItem);
fields.add(nameItem);
FormItem valueItem;
if (propertyDefinition instanceof PropertyDefinitionSimple) {
- valueItem = buildSimpleField(fields, (PropertyDefinitionSimple) propertyDefinition, oddRow, property);
+ PropertyDefinitionSimple propertyDefinitionSimple = (PropertyDefinitionSimple)propertyDefinition;
+ PropertySimple propertySimple = (PropertySimple)property;
+
+ valueItem = buildSimpleField(propertyDefinitionSimple, propertySimple);
+
+ FormItem unsetItem = buildUnsetItem(propertyDefinitionSimple, propertySimple, valueItem);
+ fieldsForThisProperty.add(unsetItem);
+ fields.add(unsetItem);
+
+ fieldsForThisProperty.add(valueItem);
fields.add(valueItem);
StaticTextItem descriptionItem = new StaticTextItem();
descriptionItem.setValue(propertyDefinition.getDescription());
descriptionItem.setShowTitle(false);
descriptionItem.setEndRow(true);
- descriptionItem.setCellStyle(oddRow ? "OddRow" : "EvenRow");
+ fieldsForThisProperty.add(descriptionItem);
fields.add(descriptionItem);
} else if (propertyDefinition instanceof PropertyDefinitionList) {
if (((PropertyDefinitionList) propertyDefinition).getMemberDefinition() instanceof PropertyDefinitionMap) {
// List of Maps is a specially supported case with summary fields as columns in a table
- buildListOfMapsField(locatorId, fields,
- (PropertyDefinitionMap) ((PropertyDefinitionList) propertyDefinition).getMemberDefinition(),
- oddRow, (PropertyList) property);
+ // Note: This field spans 3 columns.
+ CanvasItem listOfMapsItem = buildListOfMapsField(locatorId,
+ (PropertyDefinitionMap)((PropertyDefinitionList)propertyDefinition).getMemberDefinition(),
+ oddRow, (PropertyList)property);
+ fields.add(listOfMapsItem);
}
+ // TODO (ips): Add support for lists of simples.
} else if (propertyDefinition instanceof PropertyDefinitionMap) {
- buildMapsField(fields, (PropertyDefinitionMap) propertyDefinition, (PropertyMap) property);
+ // Note: This field spans 3 columns.
+ FormItem mapField =
+ buildMapField(locatorId, (PropertyDefinitionMap)propertyDefinition, (PropertyMap)property);
+ fields.add(mapField);
+ }
+
+ // Set row background color.
+ for (FormItem field : fieldsForThisProperty) {
+ field.setCellStyle(oddRow ? "OddRow" : "EvenRow");
}
}
@@ -565,13 +606,39 @@ public class ConfigurationEditor extends LocatableVLayout {
return this.invalidPropertyNames;
}
- private void buildMapsField(ArrayList<FormItem> fields, PropertyDefinitionMap propertyDefinitionMap,
- final PropertyMap propertyMap) {
+ private FormItem buildMapField(String parentLocatorId, PropertyDefinitionMap propertyDefinitionMap,
+ final PropertyMap propertyMap) {
+ Canvas canvas;
+ Map<String, PropertyDefinition> memberPropertyDefinitions = propertyDefinitionMap.getPropertyDefinitions();
+ String locatorId = parentLocatorId + "_" + propertyDefinitionMap.getName();
+ if (memberPropertyDefinitions == null || memberPropertyDefinitions.isEmpty()) {
+ canvas = buildDynamicMapField(locatorId, propertyDefinitionMap, propertyMap);
+ } else {
+ canvas = buildStaticMapField(locatorId, propertyDefinitionMap, propertyMap);
+ }
+ CanvasItem canvasItem = buildComplexPropertyField(canvas);
+
+ return canvasItem;
+ }
+
+ private CanvasItem buildComplexPropertyField(Canvas canvas) {
+ CanvasItem canvasItem = new CanvasItem();
+ canvasItem.setCanvas(canvas);
+ canvasItem.setColSpan(3);
+ canvasItem.setEndRow(true);
+ canvasItem.setShowTitle(false);
+ return canvasItem;
+ }
+
+ private Canvas buildDynamicMapField(String parentLocatorId, PropertyDefinitionMap propertyDefinitionMap,
+ final PropertyMap propertyMap) {
+ Log.debug("Building dynamic map field for " + propertyMap + "...");
+
// create the property grid
final PropertyGrid propertyGrid = new PropertyGrid();
propertyGrid.getNameField().setName("Name");
propertyGrid.getValuesField().setName("Value");
-
+
// create the editors
Map<String, FormItem> editorsMap = new HashMap<String, FormItem>();
TextItem textEditor = new TextItem();
@@ -580,27 +647,26 @@ public class ConfigurationEditor extends LocatableVLayout {
// set the editors and attribute name where to find the record type
propertyGrid.setEditorsMap("fieldType", editorsMap);
- if (propertyDefinitionMap != null) {
- ListGridRecord[] records = new ListGridRecord[propertyDefinitionMap.getPropertyDefinitions().size()];
- int i = 0;
- // TODO (ips): For open maps, create the records based on props, not propDefs.
- // TODO (ips): Render unset checkboxes amd descriptions for member props, just as we would for top-level simples.
- for (PropertyDefinition propDef : propertyDefinitionMap.getPropertyDefinitions().values()) {
- ListGridRecord record = new ListGridRecord();
- String propertyName = propDef.getName();
- record.setAttribute("Name", propertyName);
- PropertySimple prop = propertyMap.getSimple(propertyName);
- String value = (prop != null) ? prop.getStringValue() : null;
- record.setAttribute("Value", value);
- record.setAttribute("fieldType", "simpleText");
- record.setAttribute("readOnly", propDef.isReadOnly());
- records[i++] = record;
+ ListGridRecord[] records = new ListGridRecord[propertyMap.getMap().size()];
+ int i = 0;
+ for (Property prop : propertyMap.getMap().values()) {
+ if (!(prop instanceof PropertySimple)) {
+ Log.warn("Unsupported Configuration permutation: PropertyMap " + propertyMap
+ + " contains non-simple member Property " + prop + " - skipping...");
+ continue;
}
- propertyGrid.setData(records);
+ PropertySimple propSimple = (PropertySimple)prop;
+ ListGridRecord record = new ListGridRecord();
+ String propertyName = prop.getName();
+ record.setAttribute("Name", propertyName);
+ String value = propSimple.getStringValue();
+ record.setAttribute("Value", value);
+ record.setAttribute("fieldType", "simpleText");
+ records[i++] = record;
}
+ propertyGrid.setData(records);
VLayout canvas = new VLayout();
-
canvas.addMember(propertyGrid);
// Footer
@@ -610,8 +676,8 @@ public class ConfigurationEditor extends LocatableVLayout {
footer.setMembersMargin(15);
canvas.addMember(footer);
- // Properties can only be added to or deleted from non-read-only "open" maps.
- if (propertyDefinitionMap.getPropertyDefinitions().isEmpty() && !propertyDefinitionMap.isReadOnly()) {
+ // Properties can only be added to or deleted from non-read-only dynamic maps.
+ if (!propertyDefinitionMap.isReadOnly()) {
final IButton deleteButton = new LocatableIButton(extendLocatorId(propertyMap.getName()), "Delete");
deleteButton.setDisabled(true);
deleteButton.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() {
@@ -688,19 +754,21 @@ public class ConfigurationEditor extends LocatableVLayout {
}
});
- propertyGrid.draw();
-
- CanvasItem canvasItem = new CanvasItem();
- canvasItem.setCanvas(canvas);
- // item.setHeight(500);
- canvasItem.setColSpan(3);
- canvasItem.setEndRow(true);
- canvasItem.setShowTitle(false);
- fields.add(canvasItem);
+ return canvas;
+ }
+
+ private Canvas buildStaticMapField(String parentLocatorId, PropertyDefinitionMap propertyDefinitionMap,
+ PropertyMap propertyMap) {
+ Log.debug("Building static map field for " + propertyMap + "...");
+
+ return buildPropertiesForm(parentLocatorId, propertyDefinitionMap.getPropertyDefinitions().values(), propertyMap);
+
}
- private void buildListOfMapsField(final String locatorId, ArrayList<FormItem> fields,
- final PropertyDefinitionMap propertyDefinition, boolean oddRow, final PropertyList propertyList) {
+ private CanvasItem buildListOfMapsField(final String locatorId,
+ final PropertyDefinitionMap memberPropertyDefinitionMap, boolean oddRow,
+ final PropertyList propertyList) {
+ Log.debug("Building list-of-maps field for " + propertyList + "...");
final ListGrid summaryTable = new ListGrid();
// summaryTable.setID("config_summaryTable_" + propertyDefinition.getName());
@@ -711,7 +779,7 @@ public class ConfigurationEditor extends LocatableVLayout {
summaryTable.setAutoFitData(Autofit.HORIZONTAL);
ArrayList<ListGridField> fieldsList = new ArrayList<ListGridField>();
- ArrayList<PropertyDefinition> definitions = new ArrayList<PropertyDefinition>(propertyDefinition
+ ArrayList<PropertyDefinition> definitions = new ArrayList<PropertyDefinition>(memberPropertyDefinitionMap
.getPropertyDefinitions().values());
Collections.sort(definitions, new PropertyDefinitionComparator());
@@ -757,7 +825,7 @@ public class ConfigurationEditor extends LocatableVLayout {
public void onRecordClick(RecordClickEvent recordClickEvent) {
com.allen_sauer.gwt.log.client.Log.info("You want to edit: " + recordClickEvent.getRecord());
displayMapEditor(locatorId + "_MapEdit", summaryTable, recordClickEvent.getRecord(),
- propertyDefinition, propertyList, (PropertyMap) recordClickEvent.getRecord().getAttributeAsObject(
+ memberPropertyDefinitionMap, propertyList, (PropertyMap) recordClickEvent.getRecord().getAttributeAsObject(
"_RHQ_PROPERTY"));
}
});
@@ -805,7 +873,7 @@ public class ConfigurationEditor extends LocatableVLayout {
addRowButton.setIcon(Window.getImgURL("[SKIN]/actions/add.png"));
addRowButton.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() {
public void onClick(ClickEvent clickEvent) {
- displayMapEditor(locatorId + "_MapEdit", summaryTable, null, propertyDefinition, propertyList, null);
+ displayMapEditor(locatorId + "_MapEdit", summaryTable, null, memberPropertyDefinitionMap, propertyList, null);
}
});
@@ -813,13 +881,9 @@ public class ConfigurationEditor extends LocatableVLayout {
summaryTableHolder.setMembers(summaryTable, toolStrip);
- CanvasItem item = new CanvasItem();
- item.setCanvas(summaryTableHolder);
- // item.setHeight(500);
- item.setColSpan(3);
- item.setEndRow(true);
- item.setShowTitle(false);
- fields.add(item);
+ CanvasItem item = buildComplexPropertyField(summaryTableHolder);
+
+ return item;
}
private ListGridRecord[] buildSummaryRecords(PropertyList propertyList, ArrayList<PropertyDefinition> definitions) {
@@ -827,7 +891,6 @@ public class ConfigurationEditor extends LocatableVLayout {
int i = 0;
for (Property row : propertyList.getList()) {
PropertyMap rowMap = (PropertyMap) row;
-
ListGridRecord record = buildSummaryRecord(definitions, rowMap);
rows[i++] = record;
}
@@ -871,32 +934,13 @@ public class ConfigurationEditor extends LocatableVLayout {
return record;
}
- private FormItem buildSimpleField(ArrayList<FormItem> fields, final PropertyDefinitionSimple propertyDefinition,
- boolean oddRow, final Property property) {
- final PropertySimple propertySimple = (PropertySimple) property;
+ private FormItem buildSimpleField(final PropertyDefinitionSimple propertyDefinition,
+ final PropertySimple propertySimple
+ ) {
+ Log.debug("Building simple field for " + propertySimple + "...");
FormItem valueItem = null;
- boolean isUnset = (property == null || propertySimple.getStringValue() == null)
- && propertyDefinition.isRequired() == false;
-
- CheckboxItem unsetItem = null;
- if (!propertyDefinition.isRequired()) {
- unsetItem = new CheckboxItem();
- unsetItem.setValue(isUnset);
- unsetItem.setDisabled(readOnly);
- unsetItem.setShowLabel(false);
- unsetItem.setShowTitle(false);
- unsetItem.setLabelAsTitle(false);
- unsetItem.setColSpan(1);
- unsetItem.setCellStyle(oddRow ? "OddRow" : "EvenRow");
- fields.add(unsetItem);
- } else {
- SpacerItem spacer = new SpacerItem();
- spacer.setCellStyle(oddRow ? "OddRow" : "EvenRow");
- fields.add(spacer);
- }
-
List<PropertyDefinitionEnumeration> enumeratedValues = propertyDefinition.getEnumeratedValues();
if (enumeratedValues != null && !enumeratedValues.isEmpty()) {
@@ -911,7 +955,7 @@ public class ConfigurationEditor extends LocatableVLayout {
valueItem = new RadioGroupItem();
}
valueItem.setValueMap(valueOptions);
- if (property != null) {
+ if (propertySimple != null) {
valueItem.setValue(propertySimple.getStringValue());
}
} else {
@@ -921,15 +965,15 @@ public class ConfigurationEditor extends LocatableVLayout {
case FILE:
case DIRECTORY:
valueItem = new TextItem();
- valueItem.setValue(property == null ? "" : propertySimple.getStringValue());
+ valueItem.setValue(propertySimple == null ? "" : propertySimple.getStringValue());
break;
case LONG_STRING:
valueItem = new TextAreaItem();
- valueItem.setValue(property == null ? "" : propertySimple.getStringValue());
+ valueItem.setValue(propertySimple == null ? "" : propertySimple.getStringValue());
break;
case PASSWORD:
valueItem = new PasswordItem();
- valueItem.setValue(property == null ? "" : propertySimple.getStringValue());
+ valueItem.setValue(propertySimple == null ? "" : propertySimple.getStringValue());
break;
case BOOLEAN:
valueItem = new RadioGroupItem();
@@ -937,19 +981,19 @@ public class ConfigurationEditor extends LocatableVLayout {
valMap.put("true", "Yes");
valMap.put("false", "No");
valueItem.setValueMap(valMap);
- valueItem.setValue(property == null || propertySimple.getStringValue() == null ? false : propertySimple
+ valueItem.setValue(propertySimple == null || propertySimple.getStringValue() == null ? false : propertySimple
.getBooleanValue());
break;
case INTEGER:
case LONG:
valueItem = new IntegerItem();
- if (property != null && propertySimple.getStringValue() != null)
+ if (propertySimple != null && propertySimple.getStringValue() != null)
valueItem.setValue(propertySimple.getLongValue());
break;
case FLOAT:
case DOUBLE:
valueItem = new FloatItem();
- valueItem.setValue(property == null || propertySimple.getStringValue() == null ? 0 : propertySimple
+ valueItem.setValue(propertySimple == null || propertySimple.getStringValue() == null ? 0 : propertySimple
.getDoubleValue());
break;
}
@@ -957,7 +1001,7 @@ public class ConfigurationEditor extends LocatableVLayout {
valueItem.setRequired(propertyDefinition.isRequired());
- List<Validator> validators = buildValidators(propertyDefinition, property);
+ List<Validator> validators = buildValidators(propertyDefinition, propertySimple);
valueItem.setValidators(validators.toArray(new Validator[validators.size()]));
/*
@@ -973,9 +1017,8 @@ public class ConfigurationEditor extends LocatableVLayout {
*/
valueItem.setShowTitle(false);
- valueItem.setDisabled(isUnset || readOnly);
+ valueItem.setDisabled(isReadOnly(propertyDefinition) || isUnset(propertyDefinition, propertySimple));
valueItem.setWidth(220);
- valueItem.setCellStyle(oddRow ? "OddRow" : "EvenRow");
final FormItem finalValueItem = valueItem;
@@ -992,30 +1035,56 @@ public class ConfigurationEditor extends LocatableVLayout {
boolean isValidNow = ConfigurationEditor.this.invalidPropertyNames.isEmpty();
boolean validationStateChanged = (isValidNow != wasValidBefore);
for (PropertyValueChangeListener validationStateChangeListener : ConfigurationEditor.this.validationStateChangeListeners) {
- PropertyValueChangeEvent event = new PropertyValueChangeEvent(property, propertyDefinition,
+ PropertyValueChangeEvent event = new PropertyValueChangeEvent(propertySimple, propertyDefinition,
validationStateChanged, ConfigurationEditor.this.invalidPropertyNames);
validationStateChangeListener.propertyValueChanged(event);
}
}
});
- if (unsetItem != null) {
+ return valueItem;
+ }
+
+ private boolean isUnset(PropertyDefinitionSimple propertyDefinition, PropertySimple propertySimple) {
+ return (!propertyDefinition.isRequired() &&
+ (propertySimple == null || propertySimple.getStringValue() == null));
+ }
+
+ private FormItem buildUnsetItem(PropertyDefinitionSimple propertyDefinition, final PropertySimple property,
+ final FormItem valueItem) {
+ FormItem item;
+ if (!propertyDefinition.isRequired()) {
+ CheckboxItem unsetItem = new CheckboxItem();
+ boolean unset = isUnset(propertyDefinition, property);
+ unsetItem.setValue(unset);
+ unsetItem.setDisabled(isReadOnly(propertyDefinition));
+ unsetItem.setShowLabel(false);
+ unsetItem.setShowTitle(false);
+ unsetItem.setLabelAsTitle(false);
+ unsetItem.setColSpan(1);
+
unsetItem.addChangeHandler(new ChangeHandler() {
public void onChange(ChangeEvent changeEvent) {
Boolean isUnset = (Boolean) changeEvent.getValue();
if (isUnset) {
- finalValueItem.setDisabled(true);
- finalValueItem.setValue((String) null);
+ valueItem.setDisabled(true);
+ valueItem.setValue((String) null);
} else {
- finalValueItem.setDisabled(false);
- finalValueItem.focusInItem();
+ valueItem.setDisabled(false);
+ valueItem.focusInItem();
}
- propertySimple.setValue(finalValueItem.getValue());
+ property.setValue(valueItem.getValue());
}
});
+ item = unsetItem;
+ } else {
+ item = new SpacerItem();
}
+ return item;
+ }
- return valueItem;
+ private boolean isReadOnly(PropertyDefinition propertyDefinition) {
+ return propertyDefinition.isReadOnly() || this.readOnly;
}
private List<Validator> buildValidators(PropertyDefinitionSimple propertyDefinition, Property property) {
commit 5e74d53f806d7d87fa769647a5be15827077806f
Author: John Sanda <jsanda(a)redhat.com>
Date: Mon Oct 4 16:02:31 2010 -0400
Adding more tests, and adding call to set type on updated property definition
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBean.java
index 04a3995..f46c7a4 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBean.java
@@ -367,6 +367,8 @@ public class ConfigurationMetadataManagerBean implements ConfigurationMetadataMa
if (newProperty instanceof PropertyDefinitionSimple) {
PropertyDefinitionSimple newPDS = (PropertyDefinitionSimple) newProperty;
+ existingPDS.setType(newPDS.getType());
+
// handle <property-options>?
List<PropertyDefinitionEnumeration> existingOptions = existingPDS.getEnumeratedValues();
List<PropertyDefinitionEnumeration> newOptions = newPDS.getEnumeratedValues();
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBeanTest.java
index 5e2913b..2324a43 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBeanTest.java
@@ -23,6 +23,8 @@
package org.rhq.enterprise.server.configuration.metadata;
+import java.util.List;
+
import javax.persistence.EntityManager;
import javax.transaction.SystemException;
@@ -32,6 +34,9 @@ import org.testng.annotations.Test;
import org.rhq.core.clientapi.descriptor.plugin.PluginDescriptor;
import org.rhq.core.clientapi.descriptor.plugin.ServerDescriptor;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
+import org.rhq.core.domain.configuration.definition.PropertyDefinition;
+import org.rhq.core.domain.configuration.definition.PropertyDefinitionList;
+import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap;
import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
import org.rhq.core.domain.configuration.definition.PropertyGroupDefinition;
import org.rhq.enterprise.server.test.AbstractEJB3Test;
@@ -40,7 +45,17 @@ import org.rhq.test.AssertUtils;
import static org.rhq.enterprise.server.configuration.metadata.PluginDescriptorUtil.loadPluginConfigDefFor;
import static org.rhq.enterprise.server.configuration.metadata.PluginDescriptorUtil.loadPluginDescriptor;
-
+import static java.util.Arrays.asList;
+
+/**
+ * These are data-driven tests that exercise the plugin upgrade functionality around configurations such as plugin
+ * configurations and resource configurations. The data sets that are used are defined in two plugin descriptors. One
+ * is the original version and the other is the upgraded version. In order to avoid inter-dependencies between test
+ * methods, a separate plugin configuration should be used for each test method. A separate resource type is declared
+ * for each test, further documenting and delinating where each configuration is used. In the test methods, the
+ * original and updated coniguration definitions are initialized with an xpath expression that specifies the owning
+ * resource type.
+ */
public class ConfigurationMetadataManagerBeanTest extends AbstractEJB3Test {
PluginDescriptor originalDescriptor;
@@ -62,7 +77,7 @@ public class ConfigurationMetadataManagerBeanTest extends AbstractEJB3Test {
}
@Test
- public void addNewUngroupedPropertyDef() {
+ public void addNewUngroupedSimplePropertyDef() {
initConfigDefs("servers[name='MyServer1']", "test");
String propertyName = "newUngroupedProperty";
@@ -93,13 +108,7 @@ public class ConfigurationMetadataManagerBeanTest extends AbstractEJB3Test {
"not change", expected, actual);
}
- // This test fails with,
- //
- // PersistentObjectException: detached entity passed to persist
- //
- // I get the exception with both PropertyGroupDefinition and PropertyDefinitionSimple when I have tried various
- // approaches to get past the exception.
- @Test(enabled = false)
+ @Test
public void addNewGroup() {
initConfigDefs("servers[name='GroupTests']", "GroupTests");
@@ -107,14 +116,50 @@ public class ConfigurationMetadataManagerBeanTest extends AbstractEJB3Test {
findGroup("newGroup", originalConfigDef));
}
-// void assertGroupDefinitionExists() {
-// for (PropertyGroupDefinition groupDef : originalConfigurationDef.getGroupDefinitions()) {
-// if (groupDef.getName().equals("groupToBeRemoved")) {
-// assertTrue(groupDef.getId() != 0);
-// assertNotNull(entityMgr.find(PropertyGroupDefinition.class, groupDef.getId()));
-// }
-// }
-// }
+ @Test
+ public void replaceMemberDefinitionOfPropertyList() {
+ initConfigDefs("servers[name='UpdatedPropertyList']", "ReplaceMemberDefinitionOfPropertyList");
+
+ String propertyName = "myList";
+ PropertyDefinitionList expectedList = updatedConfigDef.getPropertyDefinitionList(propertyName);
+ PropertyDefinitionList actualList = originalConfigDef.getPropertyDefinitionList(propertyName);
+
+ assertPropertyDefinitionMatches("The member definition should be replaced with the new version", expectedList, actualList);
+ }
+
+ // Test is currently failing with,
+ //
+ // IllegalArgumentException: Removing a detached instance org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple
+ //
+ // I beleive that this is a problem with the test environment and not with production code.
+ @Test(enabled = false)
+ public void updateMapWithRemovedProperty() {
+ initConfigDefs("servers[name='UpdatedMapWithRemovedProperty']", "UpdateMapWithRemovedProperty");
+
+ String propertyName = "myMap";
+ PropertyDefinitionMap map = originalConfigDef.getPropertyDefinitionMap(propertyName);
+ assertEquals("Expected property to be removed when it is removed from parent map", 0,
+ map.getPropertyDefinitions().size());
+ }
+
+ @Test
+ public void updateMapWithUpdatedProperty() {
+ initConfigDefs("servers[name='UpdatedMapWithUpdatedProperty']", "UpdateMapWithUpdatedProperty");
+
+ String propertyName = "propertyToUpdate";
+ String mapPropertyName = "myMap";
+
+ PropertyDefinitionMap expectedMap = updatedConfigDef.getPropertyDefinitionMap(mapPropertyName);
+ PropertyDefinitionSimple expected = expectedMap.getPropertyDefinitionSimple(propertyName);
+
+ PropertyDefinitionMap actualMap = originalConfigDef.getPropertyDefinitionMap(mapPropertyName);
+ PropertyDefinitionSimple actual = actualMap.getPropertyDefinitionSimple(propertyName);
+
+ List<String> ignoredProperties = asList("id", "parentPropertyMapDefinition");
+
+ assertPropertyDefinitionMatches("Expected property who is a child of map to get updated and remain in the map",
+ expected, actual, ignoredProperties);
+ }
private void initConfigDefs(String path, String configName) {
loadAndPersistConfigDefs(path, configName);
@@ -132,8 +177,6 @@ public class ConfigurationMetadataManagerBeanTest extends AbstractEJB3Test {
EntityManager entityMgr = getEntityManager();
entityMgr.persist(originalConfigDef);
- //entityMgr.persist(updatedConfigDef);
-
getTransactionManager().commit();
} catch (Exception e) {
try {
@@ -146,21 +189,8 @@ public class ConfigurationMetadataManagerBeanTest extends AbstractEJB3Test {
}
private void updateConfigDef() {
- try {
- getTransactionManager().begin();
-
- ConfigurationMetadataManagerLocal configMetadataMgr = LookupUtil.getConfigurationMetadataManager();
- configMetadataMgr.updateConfigurationDefinition(updatedConfigDef, originalConfigDef);
-
- getTransactionManager().commit();
- } catch (Exception e) {
- try {
- getTransactionManager().rollback();
- } catch (SystemException e1) {
- throw new RuntimeException(e1);
- }
- throw new RuntimeException(e);
- }
+ ConfigurationMetadataManagerLocal configMetadataMgr = LookupUtil.getConfigurationMetadataManager();
+ configMetadataMgr.updateConfigurationDefinition(updatedConfigDef, originalConfigDef);
}
private String getPackagePath() {
@@ -176,33 +206,13 @@ public class ConfigurationMetadataManagerBeanTest extends AbstractEJB3Test {
return null;
}
- void assertPropertyDefinitionMatches(String msg, PropertyDefinitionSimple expected,
- PropertyDefinitionSimple actual) {
+ void assertPropertyDefinitionMatches(String msg, PropertyDefinition expected, PropertyDefinition actual) {
AssertUtils.assertPropertiesMatch(msg, expected, actual, "id", "configurationDefinition");
}
- @Test(enabled = false)
- public void existingUngroupedPropertyDefShouldBeUpdated() throws Exception {
- PropertyDefinitionSimple expected = updatedConfigDef.getPropertyDefinitionSimple("foo");
- PropertyDefinitionSimple actual = originalConfigDef.getPropertyDefinitionSimple("foo");
-
- assertPropertyDefinitionMatches("Existing ungrouped property defs should be updated", expected, actual);
- }
-
- @Test(enabled = false)
- public void propertyDefNotInNewConfigurationDefShouldBeRemoved() throws Exception {
- assertNull(
- "A property def in the original configuration def that is removed in the new configuration def should be deleted",
- originalConfigDef.getPropertyDefinitionSimple("propertyToBeRemoved")
- );
+ void assertPropertyDefinitionMatches(String msg, PropertyDefinition expected, PropertyDefinition actual,
+ List<String> ignoredProperties) {
+ AssertUtils.assertPropertiesMatch(msg, expected, actual, ignoredProperties);
}
- @Test(enabled = false)
- public void propertyGroupDefNotInNewConfigurationDefShouldBeRemoved() throws Exception {
- for (PropertyGroupDefinition def : originalConfigDef.getGroupDefinitions()) {
- if (def.getName().equals("groupToBeRemoved")) {
- fail("Expected property group 'groupToBeRemoved' to be deleted since it is not in the new configuration def.");
- }
- }
- }
}
diff --git a/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v1.xml b/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v1.xml
index dd8fcfa..23f3a1b 100644
--- a/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v1.xml
+++ b/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v1.xml
@@ -26,4 +26,39 @@
</c:group>
</plugin-configuration>
</server>
+
+ <server name="UpdatedPropertyList">
+ <plugin-configuration>
+ <c:list-property name="myList"
+ displayName="My Test List"
+ readOnly="false"
+ description="Update Property List Test"
+ required="true"
+ min="1"
+ max="5">
+ <c:simple-property name="myListMember"
+ type="double"
+ default="3.14"
+ description="PI"/>
+ </c:list-property>
+ </plugin-configuration>
+ </server>
+
+ <server name="UpdatedMapWithRemovedProperty">
+ <plugin-configuration>
+ <c:map-property name="myMap">
+ <c:simple-property name="propertyToRemove"/>
+ </c:map-property>
+ </plugin-configuration>
+ </server>
+
+ <server name="UpdatedMapWithUpdatedProperty">
+ <plugin-configuration>
+ <c:map-property name="myMap">
+ <c:simple-property name="propertyToUpdate"
+ default="ten"
+ required="false"/>
+ </c:map-property>
+ </plugin-configuration>
+ </server>
</plugin>
diff --git a/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v2.xml b/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v2.xml
index d090e76..4c61512 100644
--- a/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v2.xml
+++ b/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v2.xml
@@ -42,4 +42,40 @@
</c:group>
</plugin-configuration>
</server>
+
+ <server name="UpdatedPropertyList">
+ <plugin-configuration>
+ <c:list-property name="myList"
+ displayName="My Test List"
+ readOnly="false"
+ description="Update Property List Test"
+ required="true"
+ min="1"
+ max="5">
+ <c:map-property name="myMap">
+ <c:simple-property name="myListMember"
+ type="double"
+ default="3.14"
+ description="PI"/>
+ </c:map-property>
+ </c:list-property>
+ </plugin-configuration>
+ </server>
+
+ <server name="UpdatedMapWithRemovedProperty">
+ <plugin-configuration>
+ <c:map-property name="myMap"/>
+ </plugin-configuration>
+ </server>
+
+ <server name="UpdatedMapWithUpdatedProperty">
+ <plugin-configuration>
+ <c:map-property name="myMap">
+ <c:simple-property name="propertyToUpdate"
+ type="integer"
+ default="10"
+ required="true"/>
+ </c:map-property>
+ </plugin-configuration>
+ </server>
</plugin>
commit 51ddbfc1c712a4e7cad1812007e77ef17de3e3ba
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Mon Oct 4 15:25:22 2010 -0400
implement the new alert-subject server plugin notification editor. this needs to be tested to make sure the sender still works. but the notification configuration is consistent with how it was before so it should work
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/SubjectCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/SubjectCriteria.java
index 4e9418c..af0882f 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/SubjectCriteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/SubjectCriteria.java
@@ -22,10 +22,13 @@
*/
package org.rhq.core.domain.criteria;
+import java.util.List;
+
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.util.CriteriaUtils;
import org.rhq.core.domain.util.PageOrdering;
/**
@@ -45,7 +48,8 @@ public class SubjectCriteria extends Criteria {
private String filterPhoneNumber;
private String filterDepartment;
private Boolean filterFactive;
- private Integer filterRoleId;
+ private Integer filterRoleId; // needs overrides
+ private List<Integer> filterIds; // needs overrides
private boolean fetchConfiguration;
private boolean fetchRoles;
@@ -64,6 +68,8 @@ public class SubjectCriteria extends Criteria {
+ " FROM Subject innerSubject " //
+ " JOIN innerSubject.roles innerRole " //
+ " WHERE innerRole.id = ? )");
+
+ filterOverrides.put("ids", "id IN ( ? )");
}
@Override
@@ -111,6 +117,10 @@ public class SubjectCriteria extends Criteria {
this.filterRoleId = filterRoleId;
}
+ public void addFilterIds(Integer... filterIds) {
+ this.filterIds = CriteriaUtils.getListIgnoringNulls(filterIds);
+ }
+
public void fetchConfiguration(boolean fetchConfiguration) {
this.fetchConfiguration = fetchConfiguration;
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/AbstractNotificationSenderForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/AbstractNotificationSenderForm.java
index 5b8b0b4..0dabe26 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/AbstractNotificationSenderForm.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/AbstractNotificationSenderForm.java
@@ -99,4 +99,6 @@ public abstract class AbstractNotificationSenderForm extends LocatableVLayout {
public void setExtraConfiguration(Configuration extraConfiguration) {
this.extraConfiguration = extraConfiguration;
}
+
+ public abstract boolean validate();
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java
index 390357c..7d8745d 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java
@@ -147,8 +147,12 @@ public class NewNotificationEditor extends LocatableDynamicForm {
@Override
public void onClick(ClickEvent event) {
if (validate(false)) {
- saveNewNotification();
- closeFunction.run();
+ AbstractNotificationSenderForm senderForm = (AbstractNotificationSenderForm) senderCanvasItem
+ .getCanvas();
+ if (senderForm.validate()) {
+ saveNewNotification();
+ closeFunction.run();
+ }
}
}
});
@@ -214,7 +218,7 @@ public class NewNotificationEditor extends LocatableDynamicForm {
// For those that want to write their own custom alert plugins, you are restricted to
// using configuration definitions as the only way to configure the sender.
if ("System Users".equals(sender)) {
- newCanvas = null; // TODO
+ newCanvas = new SystemUsersNotificationSenderForm(newLocatorId, notificationToEdit, sender);
} else if ("System Roles".equals(sender)) {
newCanvas = null; // TODO
} else if ("Resource Operations".equals(sender)) {
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SimpleNotificationSenderForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SimpleNotificationSenderForm.java
index 4a16380..65ddcd9 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SimpleNotificationSenderForm.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SimpleNotificationSenderForm.java
@@ -41,6 +41,8 @@ import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
*/
public class SimpleNotificationSenderForm extends AbstractNotificationSenderForm {
+ private ConfigurationEditor configEditor;
+
public SimpleNotificationSenderForm(String locatorId, AlertNotification notif, String sender) {
super(locatorId, notif, sender);
}
@@ -53,10 +55,10 @@ public class SimpleNotificationSenderForm extends AbstractNotificationSenderForm
new AsyncCallback<ConfigurationDefinition>() {
@Override
public void onSuccess(ConfigurationDefinition configDef) {
- ConfigurationEditor configEditor = new ConfigurationEditor(extendLocatorId("configEditor"),
- configDef, getConfiguration());
- configEditor.setHeight(500);
- configEditor.setWidth(500);
+ configEditor = new ConfigurationEditor(extendLocatorId("configEditor"), configDef,
+ getConfiguration());
+ configEditor.setHeight(400);
+ configEditor.setWidth(600);
addMember(configEditor);
markForRedraw();
}
@@ -72,4 +74,13 @@ public class SimpleNotificationSenderForm extends AbstractNotificationSenderForm
}
});
}
+
+ @Override
+ public boolean validate() {
+ if (configEditor != null) {
+ return configEditor.validate();
+ }
+ return true;
+ }
+
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SystemUsersNotificationSenderForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SystemUsersNotificationSenderForm.java
new file mode 100644
index 0000000..cdbaedf
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SystemUsersNotificationSenderForm.java
@@ -0,0 +1,203 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.rhq.enterprise.gui.coregui.client.alert.definitions;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.data.Criteria;
+import com.smartgwt.client.widgets.form.DynamicForm;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+
+import org.rhq.core.domain.alert.notification.AlertNotification;
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.domain.criteria.SubjectCriteria;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.admin.users.UsersDataSource;
+import org.rhq.enterprise.gui.coregui.client.components.selector.AbstractSelector;
+import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
+
+/**
+ * This notification form will be used for the System Users sender. This form lets
+ * you pick users that the sender will send notifications to.
+ *
+ * @author John Mazzitelli
+ */
+public class SystemUsersNotificationSenderForm extends AbstractNotificationSenderForm {
+
+ // the alert configuration property name where the IDs are stored in |-separated form
+ private static final String PROPNAME = "subjectId";
+
+ private SubjectSelector selector;
+
+ public SystemUsersNotificationSenderForm(String locatorId, AlertNotification notif, String sender) {
+ super(locatorId, notif, sender);
+ }
+
+ @Override
+ protected void onInit() {
+ super.onInit();
+
+ String subjectIds = getConfiguration().getSimpleValue(PROPNAME, ""); // we know the subject plugin defines this
+ if (subjectIds != null && subjectIds.length() > 0) {
+ try {
+ List<Integer> ids = unfence(subjectIds, Integer.class);
+ SubjectCriteria criteria = new SubjectCriteria();
+ criteria.addFilterIds(ids.toArray(new Integer[ids.size()]));
+ GWTServiceLookup.getSubjectService().findSubjectsByCriteria(criteria,
+ new AsyncCallback<PageList<Subject>>() {
+ @Override
+ public void onSuccess(PageList<Subject> result) {
+ createNewSelector(result);
+ }
+
+ @Override
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Cannot determine current users - starting empty",
+ caught);
+ createNewSelector(null);
+ }
+ });
+ } catch (Exception e) {
+ CoreGUI.getErrorHandler().handleError("Cannot use current users - starting empty", e);
+ createNewSelector(null);
+ }
+ } else {
+ createNewSelector(null);
+ }
+ }
+
+ private void createNewSelector(Collection<Subject> preselectedSubjects) {
+ String selectorLocatorId = extendLocatorId("userSelector");
+ selector = new SubjectSelector(selectorLocatorId, preselectedSubjects);
+ selector.setWidth(400);
+ selector.setHeight(300);
+ addMember(selector);
+ markForRedraw();
+ }
+
+ @Override
+ public boolean validate() {
+ if (selector != null) {
+ try {
+ HashSet<Integer> selectedIds = selector.getSelection();
+ String newPropValue = fence(selectedIds);
+ getConfiguration().put(new PropertySimple(PROPNAME, newPropValue));
+ return true;
+ } catch (Exception e) {
+ CoreGUI.getErrorHandler().handleError("Cannot save the selected users", e);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T> List<T> unfence(String fencedData, Class<T> type) {
+ String delimiter = "\\|";
+ String[] elements = fencedData.split(delimiter);
+ List<T> results = new ArrayList<T>(elements.length);
+
+ if (Integer.class.equals(type)) {
+ for (String next : elements) {
+ if (next.length() != 0) {
+ results.add((T) Integer.valueOf(next));
+ }
+ }
+ } else if (String.class.equals(type)) {
+ for (String next : elements) {
+ if (next.length() != 0) {
+ results.add((T) next);
+ }
+ }
+ } else {
+ throw new IllegalArgumentException("No support for unfencing data of type " + type);
+ }
+ return results;
+ }
+
+ /**
+ * Takes the list of elements e1, e2, e3 and fences
+ * them with '|' delimiters such that the result looks
+ * like "|e1|e2|e3|"
+ */
+ private String fence(Collection<?> elements) {
+ if (elements.size() == 0) {
+ return "";
+ }
+ StringBuilder builder = new StringBuilder();
+ builder.append('|');
+ for (Object next : elements) {
+ builder.append(String.valueOf(next)).append('|');
+ }
+ return builder.toString();
+ }
+
+ private class SubjectSelector extends AbstractSelector<Subject> {
+
+ public SubjectSelector(String id, Collection<Subject> subjects) {
+ super(id);
+ if (subjects != null) {
+ ListGridRecord[] data = (new UsersDataSource()).buildRecords(subjects);
+ setAssigned(data);
+ }
+ }
+
+ @Override
+ protected RPCDataSource<Subject> getDataSource() {
+ return new SelectedSubjectsDataSource();
+ }
+
+ @Override
+ protected DynamicForm getAvailableFilterForm() {
+ return null; // No Filters Currently
+ }
+
+ @Override
+ protected Criteria getLatestCriteria(DynamicForm availableFilterForm) {
+ return null; // No Filters Currently
+ }
+
+ public class SelectedSubjectsDataSource extends UsersDataSource {
+
+ @Override
+ public ListGridRecord[] buildRecords(Collection<Subject> subjects) {
+ ListGridRecord[] records = super.buildRecords(subjects);
+ for (ListGridRecord record : records) {
+ if (selection.contains(record.getAttributeAsInt("id"))) {
+ record.setEnabled(false);
+ }
+ }
+ return records;
+ }
+ }
+
+ }
+}
diff --git a/modules/enterprise/server/plugins/alert-subject/pom.xml b/modules/enterprise/server/plugins/alert-subject/pom.xml
index 09f2ddc..03e4631 100644
--- a/modules/enterprise/server/plugins/alert-subject/pom.xml
+++ b/modules/enterprise/server/plugins/alert-subject/pom.xml
@@ -23,31 +23,10 @@
<properties>
<scm.module.path>modules/enterprise/server/plugins/alert-subject/</scm.module.path>
- <seam.version>2.1.0.SP1</seam.version>
</properties>
<dependencies>
- <dependency>
- <groupId>org.jboss.seam</groupId>
- <artifactId>jboss-seam</artifactId>
- <version>${seam.version}</version>
- <exclusions>
- <exclusion>
- <groupId>xml-apis</groupId>
- <artifactId>xml-apis</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
-
-
- <dependency>
- <groupId>jboss.jboss-embeddable-ejb3</groupId>
- <artifactId>jboss-ejb3-all</artifactId>
- <version>1.0.0.Alpha9</version>
- <scope>compile</scope>
- </dependency>
-
</dependencies>
<build>
diff --git a/modules/enterprise/server/plugins/alert-subject/src/main/java/org/rhq/enterprise/server/plugins/alertSubject/SubjectsBackingBean.java b/modules/enterprise/server/plugins/alert-subject/src/main/java/org/rhq/enterprise/server/plugins/alertSubject/SubjectsBackingBean.java
deleted file mode 100644
index b98bb1b..0000000
--- a/modules/enterprise/server/plugins/alert-subject/src/main/java/org/rhq/enterprise/server/plugins/alertSubject/SubjectsBackingBean.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2009 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.plugins.alertSubject;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.rhq.core.domain.auth.Subject;
-import org.rhq.core.domain.configuration.PropertySimple;
-import org.rhq.core.domain.util.PageControl;
-import org.rhq.enterprise.server.plugin.pc.alert.AlertSender;
-import org.rhq.enterprise.server.plugin.pc.alert.CustomAlertSenderBackingBean;
-import org.rhq.enterprise.server.util.LookupUtil;
-
-/**
- * Backing Bean for the subjects sender alert sender plugin custom UI
- * @author Joseph Marques
- */
-public class SubjectsBackingBean extends CustomAlertSenderBackingBean {
-
- private Map<String, String> available;
- private List<String> currentSubjects;
- private static final String SUBJECT_ID = "subjectId";
-
- @Override
- public void loadView() {
- // get available/all subjects
- List<Subject> allSubjects = LookupUtil.getSubjectManager().findAllSubjects(new PageControl());
- available = new HashMap<String, String>();
- for (Subject subject : allSubjects) {
- String subjectId = String.valueOf(subject.getId());
- available.put(subject.getName(), subjectId);
- }
-
- // get current subjects
- String subjectString = alertParameters.getSimpleValue(SUBJECT_ID, "");
- currentSubjects = AlertSender.unfence(subjectString, String.class);
- }
-
- @Override
- public void saveView() {
- String subjectIds = AlertSender.fence(currentSubjects);
-
- PropertySimple p = alertParameters.getSimple(SUBJECT_ID);
- if (p == null) {
- p = new PropertySimple(SUBJECT_ID, subjectIds);
- alertParameters.put(p);
- } else {
- p.setStringValue(subjectIds);
- }
-
- alertParameters = persistConfiguration(alertParameters);
- }
-
- public List<String> getCurrentSubjects() {
- return currentSubjects;
- }
-
- public void setCurrentSubjects(List<String> currentSubjects) {
- this.currentSubjects = currentSubjects;
- }
-
- public Map<String, String> getAvailableSubjectsMap() {
- return available;
- }
-
-}
diff --git a/modules/enterprise/server/plugins/alert-subject/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/alert-subject/src/main/resources/META-INF/rhq-serverplugin.xml
index 6260aa4..277df97 100644
--- a/modules/enterprise/server/plugins/alert-subject/src/main/resources/META-INF/rhq-serverplugin.xml
+++ b/modules/enterprise/server/plugins/alert-subject/src/main/resources/META-INF/rhq-serverplugin.xml
@@ -15,21 +15,13 @@
Used to send notifications to registered users in the system.
</serverplugin:help>
- <!-- startup & tear down listener, + scheduled jobs
- <serverplugin:plugin-component class="Foo" />
- -->
-
-
-
<!-- How does this sender show up in drop downs etc -->
<short-name>System Users</short-name>
<!-- Class that does the actual sending -->
<plugin-class>SubjectsSender</plugin-class>
- <custom-ui>
- <ui-snippet-name>subjects.xhtml</ui-snippet-name>
- <backing-bean-class>SubjectsBackingBean</backing-bean-class>
- <backing-bean-name>subjectsBean</backing-bean-name>
- </custom-ui>
+ <alert-configuration>
+ <c:simple-property name="subjectId" type="string" required="true" description="The subjects (ids are |-separated) to be notified"/>
+ </alert-configuration>
</alert-plugin>
\ No newline at end of file
diff --git a/modules/enterprise/server/plugins/alert-subject/src/main/resources/subjects.xhtml b/modules/enterprise/server/plugins/alert-subject/src/main/resources/subjects.xhtml
deleted file mode 100644
index 39d86e8..0000000
--- a/modules/enterprise/server/plugins/alert-subject/src/main/resources/subjects.xhtml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<html xmlns="http://www.w3.org/1999/xhtml"
- xmlns:h="http://java.sun.com/jsf/html"
- xmlns:f="http://java.sun.com/jsf/core"
- xmlns:ui="http://java.sun.com/jsf/facelets"
- xmlns:c="http://java.sun.com/jstl/core"
- xmlns:a4j="https://richfaces.org/a4j"
- xmlns:rich="http://richfaces.ajax4jsf.org/rich">
-
-<body>
- <rich:pickList fastMoveControlsVisible="false"
- sourceListWidth="200px"
- targetListWidth="200px"
- copyControlLabel="Add Subjects"
- removeControlLabel="Remove Subjects"
- value="#{subjectsBean.currentSubjects}">
- <f:selectItems value="#{subjectsBean.availableSubjectsMap}" />
- </rich:pickList>
-</body>
-
-</html>
\ No newline at end of file
commit 98ab21b9a9348520b30fae149d67d39af7553373
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Oct 4 18:58:14 2010 +0200
Getting the InventoryManager.handleReport(InventoryReport) inline with the version in master, updating the upgrade tests to accommodate for the changed behavior.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index ec40b0c..c5004dd 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -932,30 +932,16 @@ public class InventoryManager extends AgentService implements ContainerService,
}
/**
- * @see #handleReport(InventoryReport, boolean)
- * @param report
- * @return
- */
- public boolean handleReport(InventoryReport report) {
- return handleReport(report, false);
- }
-
- /**
* Send an inventory report to the Server.
*
* @param report the inventory report to be sent
- * @param forceServerRoundtrip whether to report to the server even if there are no resources to report.
* @return true if sending the report to the Server succeeded, or false otherwise
*/
- public boolean handleReport(InventoryReport report, boolean forceServerRoundtrip) {
+ public boolean handleReport(InventoryReport report) {
if (!configuration.isInsideAgent()) {
return true;
}
- if (report.getAddedRoots().isEmpty() && !forceServerRoundtrip) {
- return true; // nothing to do
- }
-
ResourceSyncInfo syncInfo;
try {
String reportType = (report.isRuntimeReport()) ? "runtime" : "server";
@@ -2659,7 +2645,7 @@ public class InventoryManager extends AgentService implements ContainerService,
log.debug("Executing resource upgrade.");
- boolean syncResult = handleReport(new InventoryReport(getAgent()), true);
+ boolean syncResult = handleReport(new InventoryReport(getAgent()));
if (!syncResult) {
log.warn("Resource upgrade failed to sync up the inventory with the server.");
return;
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
index ebb73be..ab1cd2b 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java
@@ -342,10 +342,6 @@ public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase
expectations.allowing(getCurrentDiscoveryServerService()).upgradeResources(
expectations.with(Expectations.any(Set.class)));
expectations.will(getCurrentServerSideInventory().upgradeResources());
-
- expectations.allowing(getCurrentDiscoveryServerService()).postProcessNewlyCommittedResources(
- expectations.with(Expectations.any(Set.class)));
-
} catch (InvalidInventoryReportException e) {
//this is not going to happen because we're mocking the invocation
}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 8b966c3..e2a8a84 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -93,7 +93,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
{
defineDefaultExpectations(this);
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ allowing(getCurrentDiscoveryServerService()).mergeInventoryReport(
with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
@@ -144,7 +144,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
{
defineDefaultExpectations(this);
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ allowing(getCurrentDiscoveryServerService()).mergeInventoryReport(
with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
@@ -197,7 +197,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
//the rest of the inventory merges are executed by discoveries, so let's import the
//discovered stuff into the server-side inventory.
- between(1, 3).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ allowing(getCurrentDiscoveryServerService()).mergeInventoryReport(
with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
@@ -242,7 +242,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
{
defineDefaultExpectations(this);
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ allowing(getCurrentDiscoveryServerService()).mergeInventoryReport(
with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
@@ -276,7 +276,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
{
defineDefaultExpectations(this);
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ allowing(getCurrentDiscoveryServerService()).mergeInventoryReport(
with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(requiredInventoryStatus));
}
@@ -317,7 +317,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
{
defineDefaultExpectations(this);
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport(
+ allowing(getCurrentDiscoveryServerService()).mergeInventoryReport(
with(any(InventoryReport.class)));
will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
index 0aefafd..c299cce 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java
@@ -402,6 +402,9 @@ public abstract class ResourceUpgradeTestBase {
expectations.allowing(getCurrentDiscoveryServerService()).getResources(
expectations.with(Expectations.any(Set.class)), expectations.with(Expectations.any(boolean.class)));
expectations.will(getCurrentServerSideInventory().getResources());
+
+ expectations.allowing(getCurrentDiscoveryServerService()).postProcessNewlyCommittedResources(
+ expectations.with(Expectations.any(Set.class)));
}
protected void cleanDataDir() throws IOException {
13 years, 7 months
[rhq] 5 commits - modules/enterprise
by Joseph Marques
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml | 11 --
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/UserSessionManager.java | 22 ++--
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/create/BundleUploadDataStep.java | 3
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/GWTServiceLookup.java | 21 +++-
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/ErrorHandler.java | 41 ++++++++-
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/Message.java | 45 ++++++----
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AbstractGWTServiceImpl.java | 30 +++++-
modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css | 6 -
8 files changed, 133 insertions(+), 46 deletions(-)
New commits:
commit 297cc733d3b5567a444131892c4766d6852fa80e
Author: Joseph Marques <joseph(a)redhat.com>
Date: Tue Oct 5 01:22:58 2010 -0400
add todos for future infrastructure work
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/GWTServiceLookup.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/GWTServiceLookup.java
index a779117..d0760d2 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/GWTServiceLookup.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/GWTServiceLookup.java
@@ -139,9 +139,15 @@ public class GWTServiceLookup {
public static class SessionRpcRequestBuilder extends RpcRequestBuilder {
+ private static int RPC_TIMEOUT = 10000;
+
@Override
- protected void doFinish(RequestBuilder rb) {
- super.doFinish(rb);
+ protected RequestBuilder doCreate(String serviceEntryPoint) {
+ RequestBuilder rb = super.doCreate(serviceEntryPoint);
+
+ // TODO: alter callback handlers to capture timeout failure and retry (at least once)
+ // to add resilience to gwt service calls
+ rb.setTimeoutMillis(RPC_TIMEOUT);
// TODO Don't use the expensive determineName except in dev mode
rb.setCallback(new MonitoringRequestCallback(determineName(), rb.getCallback()));
@@ -155,6 +161,8 @@ public class GWTServiceLookup {
.error("SessionRpcRequestBuilder constructed without a value for "
+ UserSessionManager.SESSION_NAME);
}
+
+ return rb;
}
public String determineName() {
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AbstractGWTServiceImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AbstractGWTServiceImpl.java
index c9da68a..364140f 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AbstractGWTServiceImpl.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AbstractGWTServiceImpl.java
@@ -19,6 +19,7 @@
package org.rhq.enterprise.gui.coregui.server.gwt;
import java.io.IOException;
+import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@@ -49,6 +50,9 @@ public abstract class AbstractGWTServiceImpl extends RemoteServiceServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ if (Log.isTraceEnabled()) {
+ printHeaders(req);
+ }
String sid = req.getHeader(UserSessionManager.SESSION_NAME);
if (sid != null) {
SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
@@ -62,8 +66,22 @@ public abstract class AbstractGWTServiceImpl extends RemoteServiceServlet {
Log.error("Failed to validate request: sessionId missing, requestURL=" + req.getRequestURL());
}
+ // TODO: only execute this if the session lookup was successful, otherwise fail in some deterministic fashion
+ // alter callback handlers to capture expected failure and retry (at least once)
+ // to add resilience to gwt service calls
long id = HibernatePerformanceMonitor.get().start();
super.service(req, resp);
HibernatePerformanceMonitor.get().stop(id, "GWT Service Request");
}
+
+ @SuppressWarnings("unchecked")
+ private void printHeaders(HttpServletRequest req) {
+ // TODO: figure out why SESSION_NAME header and other GWT-specific headers are missing occasionally
+ // seems to only happen on polling for recent alerts when there is no user activity for a few minutes
+ Enumeration<String> headerNames = req.getHeaderNames();
+ Log.trace(req.getRequestURL().toString());
+ while (headerNames.hasMoreElements()) {
+ Log.trace(" " + headerNames.nextElement());
+ }
+ }
}
commit 83c0317378f20d3a9aa1bf92bcf645a771a41e84
Author: Joseph Marques <joseph(a)redhat.com>
Date: Mon Oct 4 23:29:01 2010 -0400
fix z-index so log_DivLogger can be used if developers so choose
diff --git a/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css b/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css
index 85d1b83..54cc3a9 100644
--- a/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css
+++ b/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css
@@ -317,11 +317,9 @@ a:hover {
-moz-box-sizing: border-box;
overflow: hidden;
cursor: auto;
- z-index: 9999999;
}
.gwtMenu, .gwt-MenuBarPopup, .gwt-MenuPopup {
- z-index: 9999999;
background-color: white;
}
@@ -387,3 +385,7 @@ a:hover {
background-color: #FF6666; /* slightly darker light red */
border-color: #EE1111; /* slightly darker medium red */
}
+
+.log-panel {
+ z-index: 9999999 !important;
+}
commit 84ae15fae55dbaf217217cb4bb1c0edc58c4c907
Author: Joseph Marques <joseph(a)redhat.com>
Date: Mon Oct 4 17:41:07 2010 -0400
better logging around request-response workflow and user session management
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/UserSessionManager.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/UserSessionManager.java
index ecbd719..65faa6d 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/UserSessionManager.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/UserSessionManager.java
@@ -56,7 +56,7 @@ import org.rhq.enterprise.gui.coregui.client.util.preferences.UserPreferences;
public class UserSessionManager {
private static int SESSION_TIMEOUT = 29 * 60 * 1000; // 29 mins, just shorter than the 30-min web session timeout
- private static int LOGOUT_DELAY = 15 * 1000; // wait 15 seconds for in-flight requests to complete before logout
+ private static int LOGOUT_DELAY = 5 * 1000; // wait 5 seconds for in-flight requests to complete before logout
public static final String SESSION_NAME = "RHQ_Sesssion";
private static Subject sessionSubject;
@@ -88,7 +88,7 @@ public class UserSessionManager {
try {
b.setCallback(new RequestCallback() {
public void onResponseReceived(final Request request, final Response response) {
- com.allen_sauer.gwt.log.client.Log.info("response text = " + response.getText());
+ Log.info("response text = " + response.getText());
String sessionIdString = response.getText();
if (sessionIdString != null && sessionIdString.length() > 0) {
@@ -96,20 +96,20 @@ public class UserSessionManager {
final int subjectId = Integer.parseInt(parts[0]);
final String sessionId = parts[1]; // not null
final long lastAccess = Long.parseLong(parts[2]);
- com.allen_sauer.gwt.log.client.Log.info("sessionAccess-subjectId: " + subjectId);
- com.allen_sauer.gwt.log.client.Log.info("sessionAccess-sessionId: " + sessionId);
- com.allen_sauer.gwt.log.client.Log.info("sessionAccess-lastAccess: " + lastAccess);
+ Log.info("sessionAccess-subjectId: " + subjectId);
+ Log.info("sessionAccess-sessionId: " + sessionId);
+ Log.info("sessionAccess-lastAccess: " + lastAccess);
String previousSessionId = getPreviousSessionId(); // may be null
- com.allen_sauer.gwt.log.client.Log.info("sessionAccess-previousSessionId: " + previousSessionId);
+ Log.info("sessionAccess-previousSessionId: " + previousSessionId);
if (previousSessionId == null || previousSessionId.equals(sessionId) == false) {
// persist sessionId if different from previously saved sessionId
- com.allen_sauer.gwt.log.client.Log.info("sessionAccess-savingSessionId: " + sessionId);
+ Log.info("sessionAccess-savingSessionId: " + sessionId);
saveSessionId(sessionId);
// new sessions get the full 29 minutes to expire
- com.allen_sauer.gwt.log.client.Log.info("sessionAccess-schedulingSessionTimeout: " + SESSION_TIMEOUT);
+ Log.info("sessionAccess-schedulingSessionTimeout: " + SESSION_TIMEOUT);
sessionTimer.schedule(SESSION_TIMEOUT);
} else {
@@ -124,7 +124,7 @@ public class UserSessionManager {
expiryMillis = SESSION_TIMEOUT; // guarantees maximum is 29 minutes
}
- com.allen_sauer.gwt.log.client.Log.info("sessionAccess-reschedulingSessionTimeout: " + expiryMillis);
+ Log.info("sessionAccess-reschedulingSessionTimeout: " + expiryMillis);
sessionTimer.schedule((int) expiryMillis);
}
@@ -143,7 +143,7 @@ public class UserSessionManager {
public void onFailure(Throwable caught) {
CoreGUI.getErrorHandler().handleError(
"UserSessionManager: Failed to load user's subject", caught);
- com.allen_sauer.gwt.log.client.Log.info("Failed to load user's subject");
+ Log.info("Failed to load user's subject");
new LoginView().showLoginDialog();
}
@@ -260,10 +260,12 @@ public class UserSessionManager {
public static String getSessionId() {
if (sessionSubject == null) {
+ Log.error("UserSessionManager: sessionSubject is null");
return null;
}
Integer sessionId = sessionSubject.getSessionId();
if (sessionId == null) {
+ Log.error("UserSessionManager: sessionId is null");
return null;
}
return sessionId.toString();
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/GWTServiceLookup.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/GWTServiceLookup.java
index 4a9c639..a779117 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/GWTServiceLookup.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/GWTServiceLookup.java
@@ -18,6 +18,7 @@
*/
package org.rhq.enterprise.gui.coregui.client.gwt;
+import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.user.client.rpc.RpcRequestBuilder;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
@@ -139,11 +140,6 @@ public class GWTServiceLookup {
public static class SessionRpcRequestBuilder extends RpcRequestBuilder {
@Override
- protected void doSetRequestData(RequestBuilder rb, String data) {
- super.doSetRequestData(rb, data); // TODO: Implement this method.
- }
-
- @Override
protected void doFinish(RequestBuilder rb) {
super.doFinish(rb);
@@ -152,7 +148,12 @@ public class GWTServiceLookup {
String sessionId = UserSessionManager.getSessionId();
if (sessionId != null) {
+ Log.info("SessionRpcRequestBuilder is adding sessionId to request: " + sessionId);
rb.setHeader(UserSessionManager.SESSION_NAME, sessionId);
+ } else {
+ Log
+ .error("SessionRpcRequestBuilder constructed without a value for "
+ + UserSessionManager.SESSION_NAME);
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AbstractGWTServiceImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AbstractGWTServiceImpl.java
index ae1e85b..c9da68a 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AbstractGWTServiceImpl.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AbstractGWTServiceImpl.java
@@ -24,6 +24,7 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import org.rhq.core.domain.auth.Subject;
@@ -34,9 +35,12 @@ import org.rhq.enterprise.server.util.LookupUtil;
/**
* @author Greg Hinkle
+ * @author Joseph Marques
*/
public abstract class AbstractGWTServiceImpl extends RemoteServiceServlet {
+ private static final long serialVersionUID = 1L;
+
private ThreadLocal<Subject> sessionSubject = new ThreadLocal<Subject>();
protected Subject getSessionSubject() {
@@ -46,20 +50,20 @@ public abstract class AbstractGWTServiceImpl extends RemoteServiceServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String sid = req.getHeader(UserSessionManager.SESSION_NAME);
- Subject subject = null;
if (sid != null) {
SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
try {
- subject = subjectManager.getSubjectBySessionId(Integer.parseInt(sid));
+ Subject subject = subjectManager.getSubjectBySessionId(Integer.parseInt(sid));
+ sessionSubject.set(subject);
} catch (Exception e) {
- throw new RuntimeException("Failed to validate session", e);
+ Log.error("Failed to validate request: sessionId was '" + sid + "', requestURL=" + req.getRequestURL());
}
+ } else {
+ Log.error("Failed to validate request: sessionId missing, requestURL=" + req.getRequestURL());
}
- sessionSubject.set(subject);
long id = HibernatePerformanceMonitor.get().start();
super.service(req, resp);
HibernatePerformanceMonitor.get().stop(id, "GWT Service Request");
}
-
}
commit 34d44ee66ec927b1dbb1d96fc15de3250622e7e4
Author: Joseph Marques <joseph(a)redhat.com>
Date: Mon Oct 4 14:07:42 2010 -0400
remove duplicate servlet definitions, alphabetize the rest
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml
index c486f1d..ecfac0b 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml
@@ -80,8 +80,11 @@
<servlet path="/AuthorizationGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.AuthorizationGWTServiceImpl"/>
<servlet path="/AvailabilityGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.AvailabilityGWTServiceImpl"/>
<servlet path="/BundleGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.BundleGWTServiceImpl"/>
+ <servlet path="/ClusterGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.ClusterGWTServiceImpl"/>
<servlet path="/ConfigurationGwtService" class="org.rhq.enterprise.gui.coregui.server.gwt.ConfigurationGWTServiceImpl"/>
<servlet path="/ContentGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.ContentGWTServiceImpl"/>
+ <servlet path="/DashboardGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.DashboardGWTServiceImpl"/>
+ <servlet path="/EventGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.EventGWTServiceImpl"/>
<servlet path="/MeasurementDataGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.MeasurementDataGWTServiceImpl"/>
<servlet path="/OperationGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.OperationGWTServiceImpl"/>
<servlet path="/RemoteInstallGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.RemoteInstallGWTServiceImpl"/>
@@ -95,11 +98,5 @@
<servlet path="/SubjectGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.SubjectGWTServiceImpl"/>
<servlet path="/SystemGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.SystemGWTServiceImpl"/>
<servlet path="/TagGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.TagGWTServiceImpl"/>
- <servlet path="/RemoteInstallGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.RemoteInstallGWTServiceImpl"/>
- <servlet path="/RepoGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.RepoGWTServiceImpl"/>
- <servlet path="/ContentGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.ContentGWTServiceImpl"/>
- <servlet path="/DashboardGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.DashboardGWTServiceImpl"/>
- <servlet path="/EventGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.EventGWTServiceImpl"/>
- <servlet path="/ClusterGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.ClusterGWTServiceImpl"/>
-</module>
\ No newline at end of file
+</module>
commit 01bb66ff5713c644f2f7bb4d46763a0866276eb5
Author: Joseph Marques <joseph(a)redhat.com>
Date: Mon Oct 4 14:03:50 2010 -0400
show as much detail in the message center as possible
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/create/BundleUploadDataStep.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/create/BundleUploadDataStep.java
index 34e343e..e62b908 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/create/BundleUploadDataStep.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/create/BundleUploadDataStep.java
@@ -204,8 +204,7 @@ public class BundleUploadDataStep extends AbstractWizardStep {
uploadForm.addFormSubmitFailedHandler(new FormSubmitFailedHandler() {
public void onFormSubmitFailed(FormSubmitFailedEvent event) {
allFilesStatus.put(uploadForm.getName(), Boolean.FALSE);
- CoreGUI.getMessageCenter().notify(
- new Message("Failed to upload file", null, Message.Severity.Error));
+ CoreGUI.getMessageCenter().notify(new Message("Failed to upload file", Message.Severity.Error));
}
});
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/ErrorHandler.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/ErrorHandler.java
index 49bb67e..1b97a65 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/ErrorHandler.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/ErrorHandler.java
@@ -18,11 +18,14 @@
*/
package org.rhq.enterprise.gui.coregui.client.util;
+import java.util.ArrayList;
+
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.util.message.Message;
/**
* @author Greg Hinkle
+ * @author Joseph Marques
*/
public class ErrorHandler {
public void handleError(String message) {
@@ -30,7 +33,7 @@ public class ErrorHandler {
}
public void handleError(String message, Throwable t) {
- Message errorMessage = new Message(message, (t == null) ? null : t.toString(), Message.Severity.Fatal);
+ Message errorMessage = new Message(message, t, Message.Severity.Fatal);
CoreGUI.getMessageCenter().notify(errorMessage);
if (t != null) {
@@ -38,4 +41,40 @@ public class ErrorHandler {
t.printStackTrace();
}
}
+
+ public static String getAllMessages(Throwable t) {
+ StringBuffer results = new StringBuffer();
+
+ if (t != null) {
+ String[] msgs = getAllMessagesArray(t);
+ results.append(msgs[0]);
+
+ String indent = " ";
+ for (int i = 1; i < msgs.length; i++) {
+ results.append("\n").append(indent);
+ results.append(msgs[i]);
+ indent = indent + " ";
+ }
+ } else {
+ results.append(">> exception was null <<");
+ }
+
+ return results.toString();
+ }
+
+ public static String[] getAllMessagesArray(Throwable t) {
+ ArrayList<String> list = new ArrayList<String>();
+
+ if (t != null) {
+ list.add(t.getClass().getName() + ":" + t.getMessage());
+
+ while ((t.getCause() != null) && (t != t.getCause())) {
+ t = t.getCause();
+
+ list.add(t.getClass().getName() + ":" + t.getMessage());
+ }
+ }
+
+ return list.toArray(new String[list.size()]);
+ }
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/Message.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/Message.java
index 3a0b464..a9e94c2 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/Message.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/Message.java
@@ -21,13 +21,14 @@ package org.rhq.enterprise.gui.coregui.client.util.message;
import java.util.Date;
import java.util.EnumSet;
+import org.rhq.enterprise.gui.coregui.client.util.ErrorHandler;
+
/**
* A message to be displayed to the user in one or more places.
*
* @author Greg Hinkle
* @author Ian Springer
*/
-@SuppressWarnings({"UnnecessarySemicolon"})
public class Message {
protected String conciseMessage;
protected String detailedMessage;
@@ -36,21 +37,30 @@ public class Message {
protected EnumSet<Option> options;
// TODO: Add Debug severity?
- public enum Severity { Info, Warning, Error, Fatal };
- public enum Option { Transient, Sticky, BackgroundJobResult };
+ public enum Severity {
+ Info, Warning, Error, Fatal
+ };
+
+ public enum Option {
+ Transient, Sticky, BackgroundJobResult
+ };
public Message(String conciseMessage) {
- this(conciseMessage, (Severity)null);
+ this(conciseMessage, (Severity) null);
}
public Message(String conciseMessage, Severity severity) {
- this(conciseMessage, null, severity);
+ this(conciseMessage, (String) null, severity);
}
public Message(String conciseMessage, String detailedMessage) {
this(conciseMessage, detailedMessage, null);
}
+ public Message(String conciseMessage, Throwable details) {
+ this(conciseMessage, details, null);
+ }
+
public Message(String conciseMessage, EnumSet<Option> options) {
this(conciseMessage, null, options);
}
@@ -59,8 +69,16 @@ public class Message {
this(conciseMessage, detailedMessage, severity, null);
}
+ public Message(String conciseMessage, Throwable details, Severity severity) {
+ this(conciseMessage, details, severity, null);
+ }
+
public Message(String conciseMessage, Severity severity, EnumSet<Option> options) {
- this(conciseMessage, null, severity, options);
+ this(conciseMessage, (String) null, severity, options);
+ }
+
+ public Message(String conciseMessage, Throwable details, Severity severity, EnumSet<Option> options) {
+ this(conciseMessage, ErrorHandler.getAllMessages(details), severity, options);
}
public Message(String conciseMessage, String detailedMessage, Severity severity, EnumSet<Option> options) {
@@ -97,15 +115,14 @@ public class Message {
public boolean isBackgroundJobResult() {
return options.contains(Option.BackgroundJobResult);
}
-
+
@Override
public String toString() {
- return "Message{" +
- "conciseMessage='" + this.conciseMessage + '\'' +
- ", detailedMessage='" + this.detailedMessage + '\'' +
- ", fired=" + this.fired +
- ", severity=" + this.severity +
- ", options=" + this.options +
- '}';
+ return "Message{" //
+ + "conciseMessage='" + this.conciseMessage + '\'' //
+ + ", detailedMessage='" + this.detailedMessage + '\'' //
+ + ", fired=" + this.fired //
+ + ", severity=" + this.severity //
+ + ", options=" + this.options + '}';
}
}
13 years, 7 months
[rhq] modules/enterprise
by ips
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java | 162 ++++++----
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ResourceConfigurationEditView.java | 2
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/inventory/PluginConfigurationEditView.java | 2
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationFactory.java | 4
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationView.java | 37 +-
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/TestConfigurationFactory.java | 4
6 files changed, 126 insertions(+), 85 deletions(-)
New commits:
commit 25ccc993e3a166cbad9e03bf609343cb3b744c5a
Author: Ian Springer <ian.springer(a)redhat.com>
Date: Mon Oct 4 21:30:38 2010 -0400
finish support for lists of maps in config editor
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java
index d9c3dd7..fc63830 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java
@@ -147,12 +147,14 @@ import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
*/
@SuppressWarnings({"UnnecessarySemicolon"})
public class ConfigurationEditor extends LocatableVLayout {
+ private static final String RHQ_PROPERTY_ATTRIBUTE_NAME = "rhq:property";
+
private ConfigurationGWTServiceAsync configurationService = GWTServiceLookup.getConfigurationService();
private TabSet tabSet;
private LocatableToolStrip toolStrip;
- private ConfigurationDefinition definition;
+ private ConfigurationDefinition configurationDefinition;
private Configuration configuration;
private Configuration originalConfiguration;
@@ -169,7 +171,7 @@ public class ConfigurationEditor extends LocatableVLayout {
private boolean readOnly = false;
private Set<String> invalidPropertyNames = new HashSet<String>();
- private Set<PropertyValueChangeListener> validationStateChangeListeners =
+ private Set<PropertyValueChangeListener> propertyValueChangeListeners =
new HashSet<PropertyValueChangeListener>();
public static enum ConfigType {
@@ -193,10 +195,11 @@ public class ConfigurationEditor extends LocatableVLayout {
setOverflow(Overflow.AUTO);
}
- public ConfigurationEditor(String locatorId, ConfigurationDefinition definition, Configuration configuration) {
+ public ConfigurationEditor(String locatorId, ConfigurationDefinition configurationDefinition,
+ Configuration configuration) {
super(locatorId);
this.configuration = configuration;
- this.definition = definition;
+ this.configurationDefinition = configurationDefinition;
}
public Configuration getConfiguration() {
@@ -227,8 +230,8 @@ public class ConfigurationEditor extends LocatableVLayout {
return this.valuesManager.hasErrors();
}
- public void addValidationStateChangeListener(PropertyValueChangeListener validationStateChangeListener) {
- this.validationStateChangeListeners.add(validationStateChangeListener);
+ public void addPropertyValueChangeListener(PropertyValueChangeListener propertyValueChangeListener) {
+ this.propertyValueChangeListeners.add(propertyValueChangeListener);
}
@Override
@@ -240,7 +243,7 @@ public class ConfigurationEditor extends LocatableVLayout {
final long start = System.currentTimeMillis();
- if (definition == null || configuration == null) {
+ if (configurationDefinition == null || configuration == null) {
if (configType == ConfigType.resource) {
configurationService.getResourceConfiguration(resourceId, new AsyncCallback<Configuration>() {
@@ -260,8 +263,8 @@ public class ConfigurationEditor extends LocatableVLayout {
new ResourceTypeRepository.TypesLoadedCallback() {
public void onTypesLoaded(Map<Integer, ResourceType> types) {
com.allen_sauer.gwt.log.client.Log.debug("ConfigDef retreived in: " + (System.currentTimeMillis() - start));
- definition = types.get(resourceTypeId).getResourceConfigurationDefinition();
- if (definition == null) {
+ configurationDefinition = types.get(resourceTypeId).getResourceConfigurationDefinition();
+ if (configurationDefinition == null) {
loadingLabel.hide();
showError("Configuration is not supported by this Resource.");
}
@@ -286,8 +289,8 @@ public class ConfigurationEditor extends LocatableVLayout {
new ResourceTypeRepository.TypesLoadedCallback() {
public void onTypesLoaded(Map<Integer, ResourceType> types) {
com.allen_sauer.gwt.log.client.Log.debug("ConfigDef retreived in: " + (System.currentTimeMillis() - start));
- definition = types.get(resourceTypeId).getPluginConfigurationDefinition();
- if (definition == null) {
+ configurationDefinition = types.get(resourceTypeId).getPluginConfigurationDefinition();
+ if (configurationDefinition == null) {
showError("Connection settings are not supported by this Resource.");
}
reload();
@@ -300,7 +303,7 @@ public class ConfigurationEditor extends LocatableVLayout {
}
public void reload() {
- if (definition == null || configuration == null) {
+ if (configurationDefinition == null || configuration == null) {
// Wait for both to load
return;
}
@@ -309,16 +312,16 @@ public class ConfigurationEditor extends LocatableVLayout {
tabSet = new LocatableTabSet(getLocatorId());
- if (definition.getConfigurationFormat() == ConfigurationFormat.RAW
- || definition.getConfigurationFormat() == ConfigurationFormat.STRUCTURED_AND_RAW) {
+ if (configurationDefinition.getConfigurationFormat() == ConfigurationFormat.RAW
+ || configurationDefinition.getConfigurationFormat() == ConfigurationFormat.STRUCTURED_AND_RAW) {
com.allen_sauer.gwt.log.client.Log.info("Loading files view...");
Tab tab = new LocatableTab("Files", "Files");
tab.setPane(buildRawPane());
tabSet.addTab(tab);
}
- if (definition.getConfigurationFormat() == ConfigurationFormat.STRUCTURED
- || definition.getConfigurationFormat() == ConfigurationFormat.STRUCTURED_AND_RAW) {
+ if (configurationDefinition.getConfigurationFormat() == ConfigurationFormat.STRUCTURED
+ || configurationDefinition.getConfigurationFormat() == ConfigurationFormat.STRUCTURED_AND_RAW) {
com.allen_sauer.gwt.log.client.Log.info("Loading properties view...");
Tab tab = new LocatableTab("Properties", "Properties");
tab.setPane(buildStructuredPane());
@@ -391,7 +394,7 @@ public class ConfigurationEditor extends LocatableVLayout {
protected VLayout buildStructuredPane() {
LocatableVLayout layout = new LocatableVLayout(extendLocatorId("Structured"));
- List<PropertyGroupDefinition> definitions = definition.getGroupDefinitions();
+ List<PropertyGroupDefinition> definitions = configurationDefinition.getGroupDefinitions();
final SectionStack sectionStack = new LocatableSectionStack(layout.extendLocatorId("Sections"));
sectionStack.setVisibilityMode(VisibilityMode.MULTIPLE);
@@ -400,7 +403,7 @@ public class ConfigurationEditor extends LocatableVLayout {
sectionStack.setScrollSectionIntoView(true);
sectionStack.setOverflow(Overflow.AUTO);
- if (definition.getNonGroupedProperties().size() > 0) {
+ if (configurationDefinition.getNonGroupedProperties().size() > 0) {
sectionStack.addSection(buildGroupSection(layout.extendLocatorId("NoGroup"), null));
}
@@ -481,8 +484,8 @@ public class ConfigurationEditor extends LocatableVLayout {
section.setExpanded(!group.isDefaultHidden());
}
- List<PropertyDefinition> propertyDefinitions = new ArrayList<PropertyDefinition>(((group == null) ? definition
- .getNonGroupedProperties() : definition.getPropertiesInGroup(group.getName())));
+ List<PropertyDefinition> propertyDefinitions = new ArrayList<PropertyDefinition>(((group == null) ? configurationDefinition
+ .getNonGroupedProperties() : configurationDefinition.getPropertiesInGroup(group.getName())));
DynamicForm form = buildPropertiesForm(locatorId + "_Props", propertyDefinitions, configuration);
@@ -748,6 +751,7 @@ public class ConfigurationEditor extends LocatableVLayout {
PropertySimple prop = propertyMap.getSimple(propertyName);
if (prop == null) {
prop = new PropertySimple(propertyName, null);
+ propertyMap.put(prop);
}
String value = record.getAttribute("Value");
prop.setStringValue(value);
@@ -778,14 +782,30 @@ public class ConfigurationEditor extends LocatableVLayout {
summaryTable.setOverflow(Overflow.VISIBLE);
summaryTable.setAutoFitData(Autofit.HORIZONTAL);
- ArrayList<ListGridField> fieldsList = new ArrayList<ListGridField>();
- ArrayList<PropertyDefinition> definitions = new ArrayList<PropertyDefinition>(memberPropertyDefinitionMap
+ summaryTable.addCellSavedHandler(new CellSavedHandler() {
+ public void onCellSaved(CellSavedEvent cellSavedEvent) {
+ Record record = cellSavedEvent.getRecord();
+ PropertyMap propertyMap = (PropertyMap)record.getAttributeAsObject(RHQ_PROPERTY_ATTRIBUTE_NAME);
+ for (String memberPropertyName : memberPropertyDefinitionMap.getPropertyDefinitions().keySet()) {
+ PropertySimple memberProperty = propertyMap.getSimple(memberPropertyName);
+ if (memberProperty == null) {
+ memberProperty = new PropertySimple(memberPropertyName, null);
+ propertyMap.put(memberProperty);
+ }
+ String newValue = record.getAttribute(memberPropertyName);
+ memberProperty.setStringValue(newValue);
+ }
+ }
+ });
+
+ List<ListGridField> fieldsList = new ArrayList<ListGridField>();
+ List<PropertyDefinition> definitions = new ArrayList<PropertyDefinition>(memberPropertyDefinitionMap
.getPropertyDefinitions().values());
Collections.sort(definitions, new PropertyDefinitionComparator());
for (PropertyDefinition subDef : definitions) {
if (subDef.isSummary()) {
- ListGridField field = new ListGridField(subDef.getName(), subDef.getDisplayName());
+ ListGridField field = new ListGridField(subDef.getName(), subDef.getDisplayName(), 90);
PropertyDefinitionSimple defSimple = (PropertyDefinitionSimple) subDef;
if (defSimple.getType() == PropertySimpleType.INTEGER) {
@@ -798,7 +818,7 @@ public class ConfigurationEditor extends LocatableVLayout {
}
}
- if (fieldsList.size() == 0) {
+ if (fieldsList.isEmpty()) {
// An extra "feature of the config system". If no fields are labeled summary, all are considered summary.
for (PropertyDefinition subDef : definitions) {
ListGridField field = new ListGridField(subDef.getName(), subDef.getDisplayName());
@@ -809,7 +829,6 @@ public class ConfigurationEditor extends LocatableVLayout {
} else if (defSimple.getType() == PropertySimpleType.FLOAT) {
field.setType(ListGridFieldType.FLOAT);
}
-
}
}
@@ -823,10 +842,11 @@ public class ConfigurationEditor extends LocatableVLayout {
editField.setCanHide(false);
editField.addRecordClickHandler(new RecordClickHandler() {
public void onRecordClick(RecordClickEvent recordClickEvent) {
- com.allen_sauer.gwt.log.client.Log.info("You want to edit: " + recordClickEvent.getRecord());
+ Log.info("You want to edit: " + recordClickEvent.getRecord());
+ PropertyMap memberPropertyMap = (PropertyMap)recordClickEvent.getRecord().getAttributeAsObject(
+ RHQ_PROPERTY_ATTRIBUTE_NAME);
displayMapEditor(locatorId + "_MapEdit", summaryTable, recordClickEvent.getRecord(),
- memberPropertyDefinitionMap, propertyList, (PropertyMap) recordClickEvent.getRecord().getAttributeAsObject(
- "_RHQ_PROPERTY"));
+ memberPropertyDefinitionMap, propertyList, memberPropertyMap);
}
});
fieldsList.add(editField);
@@ -845,7 +865,7 @@ public class ConfigurationEditor extends LocatableVLayout {
removeField.addRecordClickHandler(new RecordClickHandler() {
public void onRecordClick(final RecordClickEvent recordClickEvent) {
- com.allen_sauer.gwt.log.client.Log.info("You want to delete: " + recordClickEvent.getRecordNum());
+ Log.info("You want to delete: " + recordClickEvent.getRecordNum());
SC.confirm("Are you sure you want to delete this row?", new BooleanCallback() {
public void execute(Boolean aBoolean) {
if (aBoolean) {
@@ -862,6 +882,7 @@ public class ConfigurationEditor extends LocatableVLayout {
summaryTable.setFields(fieldsList.toArray(new ListGridField[fieldsList.size()]));
+ // Now add rows containing the actual data (i.e. member property values).
ListGridRecord[] rows = buildSummaryRecords(propertyList, definitions);
summaryTable.setData(rows);
@@ -886,7 +907,7 @@ public class ConfigurationEditor extends LocatableVLayout {
return item;
}
- private ListGridRecord[] buildSummaryRecords(PropertyList propertyList, ArrayList<PropertyDefinition> definitions) {
+ private ListGridRecord[] buildSummaryRecords(PropertyList propertyList, List<PropertyDefinition> definitions) {
ListGridRecord[] rows = new ListGridRecord[propertyList == null ? 0 : propertyList.getList().size()];
int i = 0;
for (Property row : propertyList.getList()) {
@@ -897,11 +918,11 @@ public class ConfigurationEditor extends LocatableVLayout {
return rows;
}
- private ListGridRecord buildSummaryRecord(List<PropertyDefinition> definitions, PropertyMap rowMap) {
+ private ListGridRecord buildSummaryRecord(List<PropertyDefinition> memberPropertyDefinitions, PropertyMap memberPropertyMap) {
ListGridRecord record = new ListGridRecord();
- for (PropertyDefinition subDef : definitions) {
+ for (PropertyDefinition subDef : memberPropertyDefinitions) {
PropertyDefinitionSimple subDefSimple = (PropertyDefinitionSimple) subDef;
- PropertySimple propertySimple = ((PropertySimple) rowMap.get(subDefSimple.getName()));
+ PropertySimple propertySimple = ((PropertySimple) memberPropertyMap.get(subDefSimple.getName()));
if (propertySimple.getStringValue() != null) {
record.setAttribute(subDefSimple.getName(), propertySimple.getStringValue());
@@ -930,13 +951,12 @@ public class ConfigurationEditor extends LocatableVLayout {
}
}
- record.setAttribute("_RHQ_PROPERTY", rowMap);
+ record.setAttribute(RHQ_PROPERTY_ATTRIBUTE_NAME, memberPropertyMap);
return record;
}
private FormItem buildSimpleField(final PropertyDefinitionSimple propertyDefinition,
- final PropertySimple propertySimple
- ) {
+ final PropertySimple propertySimple) {
Log.debug("Building simple field for " + propertySimple + "...");
FormItem valueItem = null;
@@ -1004,6 +1024,7 @@ public class ConfigurationEditor extends LocatableVLayout {
List<Validator> validators = buildValidators(propertyDefinition, propertySimple);
valueItem.setValidators(validators.toArray(new Validator[validators.size()]));
+ valueItem.setDisabled(isReadOnly(propertyDefinition) || isUnset(propertyDefinition, propertySimple));
/*
Click handlers seem to be turned off for disabled fields... need an alternative
valueItem.addClickHandler(new com.smartgwt.client.widgets.form.fields.events.ClickHandler() {
@@ -1017,27 +1038,29 @@ public class ConfigurationEditor extends LocatableVLayout {
*/
valueItem.setShowTitle(false);
- valueItem.setDisabled(isReadOnly(propertyDefinition) || isUnset(propertyDefinition, propertySimple));
valueItem.setWidth(220);
final FormItem finalValueItem = valueItem;
finalValueItem.addChangedHandler(new ChangedHandler() {
public void onChanged(ChangedEvent changedEvent) {
- boolean wasValidBefore = ConfigurationEditor.this.invalidPropertyNames.isEmpty();
propertySimple.setErrorMessage(null);
+
+ boolean wasValidBefore = ConfigurationEditor.this.invalidPropertyNames.isEmpty();
+ Property topLevelProperty = getTopLevelProperty(propertySimple);
if (changedEvent.getItem().validate()) {
- ConfigurationEditor.this.invalidPropertyNames.remove(propertySimple.getName());
- propertySimple.setValue(changedEvent.getValue());
+ ConfigurationEditor.this.invalidPropertyNames.remove(topLevelProperty.getName());
+ propertySimple.setValue(changedEvent.getValue());
} else {
- ConfigurationEditor.this.invalidPropertyNames.add(propertySimple.getName());
+ ConfigurationEditor.this.invalidPropertyNames.add(topLevelProperty.getName());
}
boolean isValidNow = ConfigurationEditor.this.invalidPropertyNames.isEmpty();
+
boolean validationStateChanged = (isValidNow != wasValidBefore);
- for (PropertyValueChangeListener validationStateChangeListener : ConfigurationEditor.this.validationStateChangeListeners) {
+ for (PropertyValueChangeListener propertyValueChangeListener : ConfigurationEditor.this.propertyValueChangeListeners) {
PropertyValueChangeEvent event = new PropertyValueChangeEvent(propertySimple, propertyDefinition,
validationStateChanged, ConfigurationEditor.this.invalidPropertyNames);
- validationStateChangeListener.propertyValueChanged(event);
+ propertyValueChangeListener.propertyValueChanged(event);
}
}
});
@@ -1045,9 +1068,19 @@ public class ConfigurationEditor extends LocatableVLayout {
return valueItem;
}
- private boolean isUnset(PropertyDefinitionSimple propertyDefinition, PropertySimple propertySimple) {
- return (!propertyDefinition.isRequired() &&
- (propertySimple == null || propertySimple.getStringValue() == null));
+ private static Property getTopLevelProperty(PropertySimple propertySimple) {
+ Property currentProperty = propertySimple;
+ while (currentProperty.getConfiguration() == null) {
+ if (currentProperty.getParentList() != null) {
+ currentProperty = currentProperty.getParentList();
+ } else if (currentProperty.getParentMap() != null) {
+ currentProperty = currentProperty.getParentMap();
+ } else {
+ Log.error("Property " + currentProperty + " has no parent.");
+ break;
+ }
+ }
+ return currentProperty;
}
private FormItem buildUnsetItem(PropertyDefinitionSimple propertyDefinition, final PropertySimple property,
@@ -1083,6 +1116,11 @@ public class ConfigurationEditor extends LocatableVLayout {
return item;
}
+ private boolean isUnset(PropertyDefinitionSimple propertyDefinition, PropertySimple propertySimple) {
+ return (!propertyDefinition.isRequired() &&
+ (propertySimple == null || propertySimple.getStringValue() == null));
+ }
+
private boolean isReadOnly(PropertyDefinition propertyDefinition) {
return propertyDefinition.isReadOnly() || this.readOnly;
}
@@ -1131,14 +1169,14 @@ public class ConfigurationEditor extends LocatableVLayout {
private void displayMapEditor(String locatorId, final ListGrid summaryTable, final Record existingRecord,
PropertyDefinitionMap definition, final PropertyList list, PropertyMap map) {
- final List<PropertyDefinition> definitions = new ArrayList<PropertyDefinition>(definition
+ final List<PropertyDefinition> memberDefinitions = new ArrayList<PropertyDefinition>(definition
.getPropertyDefinitions().values());
-
- Collections.sort(definitions, new PropertyDefinitionComparator());
+ Collections.sort(memberDefinitions, new PropertyDefinitionComparator());
final boolean newRow = map == null;
- if (newRow)
+ if (newRow) {
map = new PropertyMap(definition.getName());
+ }
final PropertyMap finalMap = map;
final PropertyMap copy = finalMap.deepCopy(true);
@@ -1146,7 +1184,7 @@ public class ConfigurationEditor extends LocatableVLayout {
LocatableVLayout layout = new LocatableVLayout(locatorId);
layout.setHeight100();
- DynamicForm childForm = buildPropertiesForm(locatorId + "_Child", definitions, finalMap);
+ final DynamicForm childForm = buildPropertiesForm(locatorId + "_Child", memberDefinitions, finalMap);
childForm.setHeight100();
layout.addMember(childForm);
@@ -1159,24 +1197,21 @@ public class ConfigurationEditor extends LocatableVLayout {
popup.setShowCloseButton(false);
popup.centerInPage();
- final IButton saveButton = new IButton("Save");
+ final IButton okButton = new IButton("OK");
+ okButton.disable();
// saveButton.setID("config_structured_button_save");
- saveButton.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() {
+ okButton.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() {
public void onClick(ClickEvent clickEvent) {
-
if (newRow) {
list.add(finalMap);
- ListGridRecord record = buildSummaryRecord(definitions, finalMap);
-
- com.allen_sauer.gwt.log.client.Log.info("here");
+ ListGridRecord record = buildSummaryRecord(memberDefinitions, finalMap);
try {
summaryTable.addData(record);
- com.allen_sauer.gwt.log.client.Log.info("there");
} catch (Exception e) {
e.printStackTrace();
}
} else {
- for (PropertyDefinition subDef : definitions) {
+ for (PropertyDefinition subDef : memberDefinitions) {
PropertyDefinitionSimple subDefSimple = (PropertyDefinitionSimple) subDef;
PropertySimple propertySimple = ((PropertySimple) finalMap.get(subDefSimple.getName()));
existingRecord.setAttribute(subDefSimple.getName(), propertySimple != null ? propertySimple
@@ -1191,7 +1226,13 @@ public class ConfigurationEditor extends LocatableVLayout {
// summaryTable.redraw();
// summaryTable.addData();
popup.destroy();
+ }
+ });
+ // Only enable the OK button if all properties are valid.
+ childForm.addItemChangedHandler(new ItemChangedHandler() {
+ public void onItemChanged(ItemChangedEvent itemChangedEvent) {
+ okButton.setDisabled(!childForm.validate());
}
});
@@ -1208,13 +1249,12 @@ public class ConfigurationEditor extends LocatableVLayout {
HLayout buttons = new HLayout();
buttons.setAlign(Alignment.CENTER);
buttons.setMembersMargin(10);
- buttons.setMembers(saveButton, cancelButton);
+ buttons.setMembers(okButton, cancelButton);
layout.addMember(buttons);
popup.addItem(layout);
popup.show();
-
}
private static class PropertyDefinitionComparator implements Comparator<PropertyDefinition> {
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ResourceConfigurationEditView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ResourceConfigurationEditView.java
index f5afb2c..3f9f225 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ResourceConfigurationEditView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ResourceConfigurationEditView.java
@@ -101,7 +101,7 @@ public class ResourceConfigurationEditView extends LocatableVLayout implements P
editor = new ConfigurationEditor(this.extendLocatorId("Editor"), resource.getId(),
resource.getResourceType().getId());
editor.setOverflow(Overflow.AUTO);
- editor.addValidationStateChangeListener(this);
+ editor.addPropertyValueChangeListener(this);
editor.setReadOnly(!this.resourcePermission.isConfigureWrite());
addMember(editor);
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/inventory/PluginConfigurationEditView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/inventory/PluginConfigurationEditView.java
index 116e1ad..1f1cc52 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/inventory/PluginConfigurationEditView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/inventory/PluginConfigurationEditView.java
@@ -101,7 +101,7 @@ public class PluginConfigurationEditView extends LocatableVLayout implements Pro
editor = new ConfigurationEditor(extendLocatorId("Editor"), resource.getId(),
resource.getResourceType().getId(), ConfigurationEditor.ConfigType.plugin);
editor.setOverflow(Overflow.AUTO);
- editor.addValidationStateChangeListener(this);
+ editor.addPropertyValueChangeListener(this);
editor.setReadOnly(!this.resourcePermission.isInventory());
addMember(editor);
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationFactory.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationFactory.java
index bfcb322..cc71a2c 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationFactory.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationFactory.java
@@ -244,11 +244,11 @@ public abstract class TestConfigurationFactory {
propMap3.put(new PropertySimple("Integer", Integer.MAX_VALUE));
configuration.put(new PropertyList("ListOfMaps", propMap2, propMap3));
- PropertyMap propMap4 = new PropertyMap("MapOfSimples");
+ PropertyMap propMap4 = new PropertyMap("MapOfSimplesInReadOnlyList");
propMap4.put(new PropertySimple("String1", "A"));
propMap4.put(new PropertySimple("String2", "B"));
propMap4.put(new PropertySimple("Integer", 999));
- PropertyMap propMap5 = new PropertyMap("MapOfSimples");
+ PropertyMap propMap5 = new PropertyMap("MapOfSimplesInReadOnlyList");
propMap5.put(new PropertySimple("String1", "a"));
propMap5.put(new PropertySimple("String2", "b"));
propMap5.put(new PropertySimple("Integer", 0));
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationView.java
index 0349718..2fd5dfa 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationView.java
@@ -86,24 +86,6 @@ public class TestConfigurationView
reloadConfiguration();
}
- private void reloadConfiguration() {
- this.saveButton.disable();
- if (editor != null) {
- editor.destroy();
- removeMember(editor);
- }
-
- editor = new ConfigurationEditor(extendLocatorId("Editor"), this.configurationDefinition, this.configuration);
- editor.setOverflow(Overflow.AUTO);
- editor.addValidationStateChangeListener(this);
- addMember(editor);
- }
-
- private void save() {
- CoreGUI.getMessageCenter().notify(
- new Message("Configuration updated.", "Test configuration updated."));
- }
-
@Override
public void propertyValueChanged(PropertyValueChangeEvent event) {
MessageCenter messageCenter = CoreGUI.getMessageCenter();
@@ -126,4 +108,23 @@ public class TestConfigurationView
this.saveButton.enable();
}
}
+
+ private void reloadConfiguration() {
+ this.saveButton.disable();
+ if (editor != null) {
+ editor.destroy();
+ removeMember(editor);
+ }
+
+ editor = new ConfigurationEditor(extendLocatorId("Editor"), this.configurationDefinition, this.configuration);
+ editor.setOverflow(Overflow.AUTO);
+ editor.addPropertyValueChangeListener(this);
+ addMember(editor);
+ }
+
+ private void save() {
+ CoreGUI.getMessageCenter().notify(
+ new Message("Configuration updated.", "Test configuration updated."));
+ reloadConfiguration();
+ }
}
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/TestConfigurationFactory.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/TestConfigurationFactory.java
index 37dddbb..ccc5eeb 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/TestConfigurationFactory.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/TestConfigurationFactory.java
@@ -236,11 +236,11 @@ public abstract class TestConfigurationFactory {
propMap3.put(new PropertySimple("Integer", Integer.MAX_VALUE));
configuration.put(new PropertyList("ListOfMaps", propMap2, propMap3));
- PropertyMap propMap4 = new PropertyMap("MapOfSimples");
+ PropertyMap propMap4 = new PropertyMap("MapOfSimplesInReadOnlyList");
propMap4.put(new PropertySimple("String1", "A"));
propMap4.put(new PropertySimple("String2", "B"));
propMap4.put(new PropertySimple("Integer", 999));
- PropertyMap propMap5 = new PropertyMap("MapOfSimples");
+ PropertyMap propMap5 = new PropertyMap("MapOfSimplesInReadOnlyList");
propMap5.put(new PropertySimple("String1", "a"));
propMap5.put(new PropertySimple("String2", "b"));
propMap5.put(new PropertySimple("Integer", 0));
13 years, 7 months
[rhq] modules/enterprise
by John Sanda
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBeanTest.java | 16 ++++++++++
modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v1.xml | 6 +++
modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v2.xml | 11 ++++++
3 files changed, 33 insertions(+)
New commits:
commit 978b466848e1bd299f191f370ca8c10e57f0f557
Author: John Sanda <jsanda(a)redhat.com>
Date: Mon Oct 4 20:07:50 2010 -0400
Adding test to verify options are added to an upgraded property
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBeanTest.java
index 2324a43..1f72c06 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBeanTest.java
@@ -35,6 +35,7 @@ import org.rhq.core.clientapi.descriptor.plugin.PluginDescriptor;
import org.rhq.core.clientapi.descriptor.plugin.ServerDescriptor;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.domain.configuration.definition.PropertyDefinition;
+import org.rhq.core.domain.configuration.definition.PropertyDefinitionEnumeration;
import org.rhq.core.domain.configuration.definition.PropertyDefinitionList;
import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap;
import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
@@ -109,6 +110,21 @@ public class ConfigurationMetadataManagerBeanTest extends AbstractEJB3Test {
}
@Test
+ public void updatePropertyWithAddedOptions() {
+ initConfigDefs("servers[name='ServerWithAddedOptions']", "UpdatedPropertyWithAddedOptions");
+
+ String propertyName = "mySimple";
+ PropertyDefinitionSimple expectedProperty = updatedConfigDef.getPropertyDefinitionSimple(propertyName);
+ List<PropertyDefinitionEnumeration> expected = expectedProperty.getEnumeratedValues();
+
+ PropertyDefinitionSimple actualProperty = originalConfigDef.getPropertyDefinitionSimple(propertyName);
+ List<PropertyDefinitionEnumeration> actual = actualProperty.getEnumeratedValues();
+
+ // TODO Need to verify order here as well
+ AssertUtils.assertCollectionEqualsNoOrder(expected, actual, "Options should have been added to property");
+ }
+
+ @Test
public void addNewGroup() {
initConfigDefs("servers[name='GroupTests']", "GroupTests");
diff --git a/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v1.xml b/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v1.xml
index 23f3a1b..5a1fe11 100644
--- a/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v1.xml
+++ b/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v1.xml
@@ -19,6 +19,12 @@
</plugin-configuration>
</server>
+ <server name="ServerWithAddedOptions">
+ <plugin-configuration>
+ <c:simple-property name="mySimple"/>
+ </plugin-configuration>
+ </server>
+
<server name="GroupTests">
<plugin-configuration>
<c:group name="existingGroup">
diff --git a/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v2.xml b/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v2.xml
index 4c61512..564c68c 100644
--- a/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v2.xml
+++ b/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v2.xml
@@ -26,6 +26,17 @@
</plugin-configuration>
</server>
+ <server name="ServerWithAddedOptions">
+ <plugin-configuration>
+ <c:simple-property name="mySimple">
+ <c:property-options>
+ <c:option name="x" value="1"/>
+ <c:option name="y" value="2"/>
+ </c:property-options>
+ </c:simple-property>
+ </plugin-configuration>
+ </server>
+
<server name="GroupTests">
<plugin-configuration>
<c:group name="existingGroup">
13 years, 7 months