[rhq] modules/core
by John Sanda
modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java | 32 ++-
modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftDetectorTest.java | 95 ++++++++++
2 files changed, 120 insertions(+), 7 deletions(-)
New commits:
commit 786eb9d50b9c8beebf5a9a7edf18e8ba82ef79cd
Author: John Sanda <jsanda(a)redhat.com>
Date: Wed Sep 28 15:07:35 2011 -0400
[BZ 727959] Check to make sure files are readable during drift detection
When generating the initial change set, if a file is not readable, it is
skipped and excluded from the change set since we cannot compute the SHA
for the file.
When generating a drift change set, if we detect a new file that is not
readable, we skip it as well since we cannot compute the SHA. Now if an
existing file that is already being monitored for drift has its
permissions changed such that it is no longer readable, then it is
treated and recorded as a deleted file entry.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
index 4f2ea30..1aedea3 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftDetector.java
@@ -163,7 +163,6 @@ public class DriftDetector implements Runnable {
final Set<File> processedFiles = new HashSet<File>();
final List<FileEntry> snapshotEntries = new LinkedList<FileEntry>();
final List<FileEntry> deltaEntries = new LinkedList<FileEntry>();
- int currentVersion = coverageReader.getHeaders().getVersion();
int newVersion = coverageReader.getHeaders().getVersion() + 1;
// First look for files that have either been modified or deleted
@@ -171,16 +170,22 @@ public class DriftDetector implements Runnable {
File file = new File(basedir, entry.getFile());
if (!file.exists()) {
// The file has been deleted since the last scan
- if (log.isInfoEnabled()) {
- log.info("Detected deleted file for " + schedule + " --> " + file.getAbsolutePath());
+ if (log.isDebugEnabled()) {
+ log.debug("Detected deleted file for " + schedule + " --> " + file.getAbsolutePath());
+ }
+ deltaEntries.add(removedFileEntry(entry.getFile(), entry.getNewSHA()));
+ } else if (!file.canRead()) {
+ processedFiles.add(file);
+ if (log.isDebugEnabled()) {
+ log.debug(file.getPath() + " is no longer readable. Treating it as a deleted file.");
}
deltaEntries.add(removedFileEntry(entry.getFile(), entry.getNewSHA()));
} else {
processedFiles.add(file);
String currentSHA = sha256(file);
if (!currentSHA.equals(entry.getNewSHA())) {
- if (log.isInfoEnabled()) {
- log.info("Detected modified file for " + schedule + " --> " + file.getAbsolutePath());
+ if (log.isDebugEnabled()) {
+ log.debug("Detected modified file for " + schedule + " --> " + file.getAbsolutePath());
}
FileEntry modifiedEntry = changedFileEntry(entry.getFile(), entry.getNewSHA(), currentSHA);
deltaEntries.add(modifiedEntry);
@@ -204,6 +209,13 @@ public class DriftDetector implements Runnable {
return;
}
+ if (!file.canRead()) {
+ if (log.isDebugEnabled()) {
+ log.debug("Skipping " + file.getPath() + " since it is not readable.");
+ return;
+ }
+ }
+
if (log.isInfoEnabled()) {
log.info("Detected added file for " + schedule + " --> " + file.getAbsolutePath());
}
@@ -274,8 +286,14 @@ public class DriftDetector implements Runnable {
@Override
public void visit(File file) {
try {
- if (log.isInfoEnabled()) {
- log.info("Adding " + file.getPath() + " to coverage change set for " + schedule);
+ if (!file.canRead()) {
+ if (log.isDebugEnabled()) {
+ log.debug("Skipping " + file.getPath() + " since it is not readable.");
+ }
+ return;
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("Adding " + file.getPath() + " to coverage change set for " + schedule);
}
writer.write(addedFileEntry(relativePath(basedir, file), sha256(file)));
} catch (IOException e) {
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftDetectorTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftDetectorTest.java
index 0b97ba6..4811044 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftDetectorTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftDetectorTest.java
@@ -518,6 +518,101 @@ public class DriftDetectorTest extends DriftTest {
"only the initial change set has been generated and sending change send report to server fails");
}
+ @Test
+ public void ignoreFilesThatAreNotReadableForCoverageChangeSet() throws Exception {
+ DriftConfiguration config = driftConfiguration("nonreadable-files-coverage", resourcesDir.getAbsolutePath());
+
+ File confDir = mkdir(resourceDir, "conf");
+ File server1Conf = createRandomFile(confDir, "server-1.conf");
+ File server2Conf = createRandomFile(confDir, "server-2.conf");
+ assertTrue(server2Conf.setReadable(false), "Failed to make " + server2Conf.getPath() + " write only");
+
+ scheduleQueue.addSchedule(new DriftDetectionSchedule(resourceId(), config));
+ detector.run();
+
+ File changeSet = changeSet(config.getName(), COVERAGE);
+ List<FileEntry> entries = asList(addedFileEntry("conf/server-1.conf", sha256(server1Conf)));
+
+ assertHeaderEquals(changeSet, createHeaders(config, COVERAGE));
+ assertFileEntriesMatch("Files that are non-readable should be skipped but other, readable file should still " +
+ "be included in the change set", entries, changeSet);
+ }
+
+ @Test
+ public void ignoreNewFilesThatAreNotReadableForDriftChangeSet() throws Exception {
+ DriftConfiguration config = driftConfiguration("nonreadable-files-drfit", resourceDir.getAbsolutePath());
+ DriftDetectionSchedule schedule = new DriftDetectionSchedule(resourceId(), config);
+
+ File confDir = mkdir(resourceDir, "conf");
+ File server1Conf = createRandomFile(confDir, "server-1.conf");
+ String oldServer1Hash = sha256(server1Conf);
+
+ scheduleQueue.addSchedule(schedule);
+ detector.run();
+
+ // create some drift that includes a new file that is not readable
+ server1Conf.delete();
+ server1Conf = createRandomFile(confDir, "server-1.conf");
+ String newServer1Hash = sha256(server1Conf);
+
+ File server2Conf = createRandomFile(confDir, "server-2.conf");
+ assertTrue(server2Conf.setReadable(false), "Failed to make " + server2Conf.getPath() + " write only");
+
+ schedule.resetSchedule();
+ detector.run();
+
+ File driftChangeSet = changeSet(config.getName(), DRIFT);
+ List<FileEntry> driftEntries = asList(changedFileEntry("conf/server-1.conf", oldServer1Hash, newServer1Hash));
+
+ // verify that the drift change set was generated
+ assertTrue(driftChangeSet.exists(), "Expected to find drift change set " + driftChangeSet.getPath());
+ assertHeaderEquals(driftChangeSet, createHeaders(config, DRIFT, 1));
+ assertFileEntriesMatch("The drift change set does not match the expected values", driftEntries, driftChangeSet);
+
+ // verify that the coverage change set was updated
+ File coverageChangeSet = changeSet(config.getName(), COVERAGE);
+ List<FileEntry> coverageEntries = asList(changedFileEntry("conf/server-1.conf", oldServer1Hash, newServer1Hash));
+
+ assertHeaderEquals(coverageChangeSet, createHeaders(config, COVERAGE, 1));
+ assertFileEntriesMatch("The coverage change set was not updated as expected", coverageEntries,
+ coverageChangeSet);
+ }
+
+ @Test
+ public void markFileUnderDriftDetectionAsRemovedWhenItIsMadeNonReadable() throws Exception {
+ DriftConfiguration config = driftConfiguration("file-made-nonreadable", resourceDir.getAbsolutePath());
+ DriftDetectionSchedule schedule = new DriftDetectionSchedule(resourceId(), config);
+
+ File confDir = mkdir(resourceDir, "conf");
+ File server1Conf = createRandomFile(confDir, "server-1.conf");
+ String server1Hash = sha256(server1Conf);
+
+ scheduleQueue.addSchedule(schedule);
+ detector.run();
+
+ // make the file non-readable and run the detector again
+ assertTrue(server1Conf.setReadable(false), "Failed to make " + server1Conf.getPath() + " write only");
+
+ schedule.resetSchedule();
+ detector.run();
+
+ File driftChangeSet = changeSet(config.getName(), DRIFT);
+ List<FileEntry> driftEntries = asList(removedFileEntry("conf/server-1.conf", server1Hash));
+
+ // verify that the drift change set was generated
+ assertTrue(driftChangeSet.exists(), "Expected to find drift change set " + driftChangeSet.getPath());
+ assertHeaderEquals(driftChangeSet, createHeaders(config, DRIFT, 1));
+ assertFileEntriesMatch("The drift change set does not match the expected values", driftEntries, driftChangeSet);
+
+ // verify that the coverage change set was updated
+ File coverageChangeSet = changeSet(config.getName(), COVERAGE);
+ List<FileEntry> coverageEntries = emptyList();
+
+ assertHeaderEquals(coverageChangeSet, createHeaders(config, COVERAGE, 1));
+ assertFileEntriesMatch("The coverage change set was not updated as expected", coverageEntries,
+ coverageChangeSet);
+ }
+
void assertHeaderEquals(File changeSet, Headers expected) throws Exception {
ChangeSetReader reader = new ChangeSetReaderImpl(new BufferedReader(new FileReader(changeSet)));
Headers actual = reader.getHeaders();
12 years, 8 months
[rhq] modules/core
by John Sanda
modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java | 7 +
modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/DriftSyncManager.java | 48 +++++++---
modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/DriftSynchronizer.java | 12 ++
modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/RuntimeSynchronizer.java | 5 +
modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/StartupSynchronizer.java | 4
modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java | 4
6 files changed, 66 insertions(+), 14 deletions(-)
New commits:
commit c9509c58604f383ff1ed516c6c1c4edddb99f673
Author: John Sanda <jsanda(a)redhat.com>
Date: Wed Sep 28 13:47:20 2011 -0400
Resend change set content during inventory sync
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java
index 2dbd0b5..8fd065f 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java
@@ -222,7 +222,12 @@ public class DriftManager extends AgentService implements DriftAgentService, Dri
}
}
- private void scanForContentToResend() {
+ /**
+ * Scans the changesets directory for any change set content zip files. This method
+ * assumes that any content zip files found have not been received or persisted by the
+ * server. Each content zip file is resent to the server.
+ */
+ public void scanForContentToResend() {
log.info("Scanning for change set content to resend...");
for (File resourceDir : changeSetsDir.listFiles()) {
for (File configDir : resourceDir.listFiles()) {
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/DriftSyncManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/DriftSyncManager.java
index b9df2ce..434ddc1 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/DriftSyncManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/DriftSyncManager.java
@@ -37,9 +37,9 @@ import org.rhq.core.pc.inventory.InventoryManager;
import static org.rhq.core.domain.drift.DriftConfigurationComparator.CompareMode.BOTH_BASE_INFO_AND_DIRECTORY_SPECIFICATIONS;
/**
- * This class handles syncing drift configurations during inventory sync. This class is
- * intended to server as the public interface (so to speak) to {@link InventoryManager} for
- * syncing drift configurations.
+ * This class handles syncing drift configurations and drift content during inventory sync.
+ * This class is intended to server as the public interface (so to speak) to
+ * {@link InventoryManager} for syncing drift configurations and content.
* <br/><br/>
* Please review the docs for each of the setter methods to determine which properties
* should be set before invoking any business logic methods.
@@ -89,13 +89,19 @@ public class DriftSyncManager {
dataDir = dataDirectory;
}
- public void syncConfigsWithServer(Set<Integer> resourceIds) {
- log.info("Starting server sync for drift configurations...");
- long startTime = System.currentTimeMillis();
-
- Map<Integer, List<DriftConfiguration>> configs = driftServer.getDriftConfigurations(resourceIds);
- DriftConfigurationComparator comparator = new DriftConfigurationComparator(
- BOTH_BASE_INFO_AND_DIRECTORY_SPECIFICATIONS);
+ /**
+ * Synchronized both drift configurations and drift content with the server. The drift
+ * configuration sync goes from server to agent in that the drift configurations in the
+ * local inventory are updated to match the drift configurations on the server
+ * inventory.
+ * <br/><br/>
+ * The content sync works as follows. Any change set content zip files found locally
+ * resent to the server under the assumption that the content has not been persisted on
+ * the server.
+ *
+ * @param resourceIds The ids of resources that need to be synced.
+ */
+ public void syncWithServer(Set<Integer> resourceIds) {
DriftSynchronizerFactory synchronizerFactory = new DriftSynchronizerFactory();
DriftSynchronizer synchronizer;
@@ -105,6 +111,18 @@ public class DriftSyncManager {
synchronizer = synchronizerFactory.getRuntimeSynchronizer(driftMgr);
}
+ syncConfigs(synchronizer, resourceIds);
+ syncContent(synchronizer);
+ }
+
+ private void syncConfigs(DriftSynchronizer synchronizer, Set<Integer> resourceIds) {
+ log.info("Starting server sync for drift configurations...");
+ long startTime = System.currentTimeMillis();
+
+ Map<Integer, List<DriftConfiguration>> configs = driftServer.getDriftConfigurations(resourceIds);
+ DriftConfigurationComparator comparator = new DriftConfigurationComparator(
+ BOTH_BASE_INFO_AND_DIRECTORY_SPECIFICATIONS);
+
int totalDeleted = 0;
int totalAdded = 0;
@@ -130,6 +148,16 @@ public class DriftSyncManager {
}
}
+ private void syncContent(DriftSynchronizer synchronizer) {
+ log.info("Starting drift content sync...");
+ long startTime = System.currentTimeMillis();
+ synchronizer.syncChangeSetContent();
+ long endTime = System.currentTimeMillis();
+ if (log.isInfoEnabled()) {
+ log.info("Finished drift content sync in " + (endTime - startTime) + " ms");
+ }
+ }
+
/**
* This method determines whether or not this is a sync being done at start up (or
* more precisely during PC initialization). It does by checking to see if
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/DriftSynchronizer.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/DriftSynchronizer.java
index 757abe6..90c4955 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/DriftSynchronizer.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/DriftSynchronizer.java
@@ -33,7 +33,9 @@ public interface DriftSynchronizer {
/**
* Determines which drift configurations for a resource have been deleted on the server
* and need to be purged from the local inventory. This method should not make any
- * changes to the local inventory.
+ * changes to the local inventory. It also handles syncing content with the server. Any
+ * change set content found on the agent and that is not known to be on the server
+ * should be sent to the server.
*
* @param resourceId
* @param configurationsFromServer A set of drift configurations belonging to the
@@ -81,4 +83,12 @@ public interface DriftSynchronizer {
* @param configurations The drift configurations to add to the local inventory.
*/
void addToLocalInventory(int resourceId, List<DriftConfiguration> configurations);
+
+ /**
+ * This is an optional operation as it can only be performed when
+ * {@link org.rhq.core.pc.drift.DriftManager DriftManager} is fully initialized.
+ * Implementations are responsible for detecting any change set content that may not be
+ * on the server and then sending that content to the server.
+ */
+ void syncChangeSetContent();
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/RuntimeSynchronizer.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/RuntimeSynchronizer.java
index 9fe0a7b..94cea4c 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/RuntimeSynchronizer.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/RuntimeSynchronizer.java
@@ -121,6 +121,11 @@ class RuntimeSynchronizer implements DriftSynchronizer {
}
}
+ @Override
+ public void syncChangeSetContent() {
+ driftMgr.scanForContentToResend();
+ }
+
private String toString(int rid, DriftConfiguration c) {
return "DriftConfiguration[id: " + c.getId() + ", name: " + c.getName() + ", resourceId: " + rid + "]";
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/StartupSynchronizer.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/StartupSynchronizer.java
index 7a472ad..0e8ed59 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/StartupSynchronizer.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/StartupSynchronizer.java
@@ -131,6 +131,10 @@ class StartupSynchronizer implements DriftSynchronizer {
}
}
+ @Override
+ public void syncChangeSetContent() {
+ }
+
private String toString(int rid, DriftConfiguration c) {
return "DriftConfiguration[id: " + c.getId() + ", name: " + c.getName() + ", resourceId: " + rid + "]";
}
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 5d03d0c..bfdb2a3 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
@@ -2036,7 +2036,7 @@ public class InventoryManager extends AgentService implements ContainerService,
}
DriftSyncManager driftSyncMgr = createDriftSyncManager();
- driftSyncMgr.syncConfigsWithServer(resourceIds);
+ driftSyncMgr.syncWithServer(resourceIds);
}
private boolean supportsDriftManagement(Resource r) {
@@ -2083,7 +2083,7 @@ public class InventoryManager extends AgentService implements ContainerService,
}
DriftSyncManager driftSyncMgr = createDriftSyncManager();
- driftSyncMgr.syncConfigsWithServer(committedResourceIds);
+ driftSyncMgr.syncWithServer(committedResourceIds);
}
private void postProcessNewlyCommittedResources(Set<Resource> resources) {
12 years, 8 months
[rhq] modules/core
by John Sanda
modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java | 73 ++++++----
1 file changed, 51 insertions(+), 22 deletions(-)
New commits:
commit 0f67cf2bd3aa8aa9d54abdfbda3c0002dc9f23ba
Author: John Sanda <jsanda(a)redhat.com>
Date: Wed Sep 28 11:47:54 2011 -0400
Scan for change set content at start up that needs to be resent to server
During initialization DriftManager now scans the changesets directory
for content zip files. DriftManager will resend them to the server since
presumably the server did not already get/persist the content.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java
index ab83351..2dbd0b5 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java
@@ -23,6 +23,7 @@ import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
@@ -42,7 +43,6 @@ import org.rhq.core.clientapi.server.drift.DriftServerService;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.drift.Drift;
import org.rhq.core.domain.drift.DriftConfiguration;
-import org.rhq.core.domain.drift.DriftConfigurationComparator;
import org.rhq.core.domain.drift.DriftFile;
import org.rhq.core.domain.drift.DriftSnapshot;
import org.rhq.core.domain.resource.Resource;
@@ -59,7 +59,6 @@ import static org.rhq.common.drift.FileEntry.addedFileEntry;
import static org.rhq.common.drift.FileEntry.changedFileEntry;
import static org.rhq.common.drift.FileEntry.removedFileEntry;
import static org.rhq.core.domain.drift.DriftChangeSetCategory.COVERAGE;
-import static org.rhq.core.domain.drift.DriftConfigurationComparator.CompareMode.BOTH_BASE_INFO_AND_DIRECTORY_SPECIFICATIONS;
import static org.rhq.core.util.file.FileUtil.purge;
public class DriftManager extends AgentService implements DriftAgentService, DriftClient, ContainerService {
@@ -95,6 +94,7 @@ public class DriftManager extends AgentService implements DriftAgentService, Dri
@Override
public void initialize() {
+ long initStartTime = System.currentTimeMillis();
changeSetsDir.mkdir();
changeSetMgr = new ChangeSetManagerImpl(changeSetsDir);
@@ -107,8 +107,12 @@ public class DriftManager extends AgentService implements DriftAgentService, Dri
long startTime = System.currentTimeMillis();
initSchedules(inventoryMgr.getPlatform(), inventoryMgr);
long endTime = System.currentTimeMillis();
- log.info("Finished initializing drift detection schedules in " + (endTime - startTime) + " ms");
+ if (log.isInfoEnabled()) {
+ log.info("Finished initializing drift detection schedules in " + (endTime - startTime) + " ms");
+ }
+
+ scanForContentToResend();
purgeDeletedDriftConfigDirs();
driftThreadPool = new ScheduledThreadPoolExecutor(5);
@@ -123,6 +127,10 @@ public class DriftManager extends AgentService implements DriftAgentService, Dri
}
initialized = true;
+ long initEndTime = System.currentTimeMillis();
+ if (log.isInfoEnabled()) {
+ log.info("Finished initialization in " + (initEndTime - initStartTime) + " ms");
+ }
}
private void initSchedules(Resource r, InventoryManager inventoryMgr) {
@@ -199,8 +207,6 @@ public class DriftManager extends AgentService implements DriftAgentService, Dri
private void purgeDeletedDriftConfigDirs() {
log.info("Checking for deleted drift configurations");
- DriftConfigurationComparator comparator = new DriftConfigurationComparator(
- BOTH_BASE_INFO_AND_DIRECTORY_SPECIFICATIONS);
for (File resourceDir : changeSetsDir.listFiles()) {
int resourceId = Integer.parseInt(resourceDir.getName());
for (File configDir : resourceDir.listFiles()) {
@@ -216,6 +222,20 @@ public class DriftManager extends AgentService implements DriftAgentService, Dri
}
}
+ private void scanForContentToResend() {
+ log.info("Scanning for change set content to resend...");
+ for (File resourceDir : changeSetsDir.listFiles()) {
+ for (File configDir : resourceDir.listFiles()) {
+ for (File contentZipFile : configDir.listFiles(new ZipFileNameFilter("content_"))) {
+ if (log.isDebugEnabled()) {
+ log.debug("Resending " + contentZipFile.getPath());
+ }
+ sendContentZipFile(Integer.parseInt(resourceDir.getName()), configDir.getName(), contentZipFile);
+ }
+ }
+ }
+ }
+
private String toString(Resource r, DriftConfiguration c) {
return toString(r.getId(), c);
}
@@ -338,9 +358,10 @@ public class DriftManager extends AgentService implements DriftAgentService, Dri
}
stream.close();
- DriftServerService driftServer = pluginContainerConfiguration.getServerServices().getDriftServerService();
- driftServer.sendFilesZip(resourceId, driftConfigurationName, timestamp, zipFile.length(),
- remoteInputStream(new BufferedInputStream(new FileInputStream(zipFile))));
+// DriftServerService driftServer = pluginContainerConfiguration.getServerServices().getDriftServerService();
+// driftServer.sendFilesZip(resourceId, driftConfigurationName, timestamp, zipFile.length(),
+// remoteInputStream(new BufferedInputStream(new FileInputStream(zipFile))));
+ sendContentZipFile(resourceId, driftConfigurationName, zipFile);
} catch (IOException e) {
log.error("An error occurred while trying to send content for changeset[resourceId: " + resourceId
+ ", driftConfiguration: " + driftConfigurationName + "]", e);
@@ -353,6 +374,21 @@ public class DriftManager extends AgentService implements DriftAgentService, Dri
}
}
+ private void sendContentZipFile(int resourceId, String driftConfigName, File contentZipFile) {
+ try {
+ int startIndex = "content_".length();
+ int endIndex = contentZipFile.getName().indexOf(".");
+ String token = contentZipFile.getName().substring(startIndex, endIndex);
+
+ DriftServerService driftServer = pluginContainerConfiguration.getServerServices().getDriftServerService();
+ driftServer.sendFilesZip(resourceId, driftConfigName, token, contentZipFile.length(),
+ remoteInputStream(new BufferedInputStream(new FileInputStream(contentZipFile))));
+ } catch (FileNotFoundException e) {
+ log.error("An error occurred while trying to send change set content zip file " +
+ contentZipFile.getPath() + " to server.", e);
+ }
+ }
+
@Override
public void detectDrift(int resourceId, DriftConfiguration driftConfiguration) {
if (log.isInfoEnabled()) {
@@ -524,13 +560,7 @@ public class DriftManager extends AgentService implements DriftAgentService, Dri
}
private void deleteZipFiles(File dir, final String prefix) {
- File[] files = dir.listFiles(new FilenameFilter() {
- @Override
- public boolean accept(File dir, String name) {
- return name.startsWith(prefix) && name.endsWith(".zip");
- }
- });
- for (File file : files) {
+ for (File file : dir.listFiles(new ZipFileNameFilter(prefix))) {
file.delete();
}
}
@@ -629,17 +659,16 @@ public class DriftManager extends AgentService implements DriftAgentService, Dri
return PluginContainer.getInstance().getMeasurementManager();
}
- private static class DeleteFile implements Runnable {
+ private static class ZipFileNameFilter implements FilenameFilter {
+ private String prefix;
- private File file;
-
- public DeleteFile(File file) {
- this.file = file;
+ public ZipFileNameFilter(String prefix) {
+ this.prefix = prefix;
}
@Override
- public void run() {
- file.delete();
+ public boolean accept(File dir, String name) {
+ return name.startsWith(prefix) && name.endsWith(".zip");
}
}
}
12 years, 8 months
[rhq] modules/enterprise
by mazz
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerBean.java | 17 ++++++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerRemote.java | 19 +++++++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java | 27 ++++------
3 files changed, 49 insertions(+), 14 deletions(-)
New commits:
commit 3787402100e5afe67b710b4024775880ab4ba078
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Wed Sep 28 11:29:09 2011 -0400
[BZ 681708] allow upload of bundle distro files as byte array to support CLI. note this requires the file to be loaded in memory which can cause OOM in either the server OR the CLI.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerBean.java
index ee3a1ba..d08c625 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerBean.java
@@ -552,6 +552,23 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
@Override
@RequiredPermission(Permission.MANAGE_BUNDLE)
@TransactionAttribute(TransactionAttributeType.NEVER)
+ public BundleVersion createBundleVersionViaByteArray(Subject subject, byte[] fileBytes) throws Exception {
+
+ File tmpFile = File.createTempFile("bundleDistroBits", ".zip");
+ try {
+ StreamUtil.copy(new ByteArrayInputStream(fileBytes), new FileOutputStream(tmpFile));
+ BundleVersion bundleVersion = createBundleVersionViaFile(subject, tmpFile);
+ return bundleVersion;
+ } finally {
+ if (tmpFile != null) {
+ tmpFile.delete();
+ }
+ }
+ }
+
+ @Override
+ @RequiredPermission(Permission.MANAGE_BUNDLE)
+ @TransactionAttribute(TransactionAttributeType.NEVER)
public BundleVersion createBundleVersionViaURL(Subject subject, String distributionFileUrl) throws Exception {
// validate by immediately creating a URL
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerRemote.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerRemote.java
index 41ec97c..c15c44e 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerRemote.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerRemote.java
@@ -100,6 +100,8 @@ public interface BundleManagerRemote {
/**
* A convenience method taking a byte array as opposed to a stream for the file bits.
+ * WARNING: obviously, this requires the entire bundle file to have been loaded fully in memory.
+ * For very large files, this could cause OutOfMemoryErrors.
*
* @see {@link addBundleFile(Subject, int, String, String, Architecture, InputStream, boolean)}
*/
@@ -220,6 +222,23 @@ public interface BundleManagerRemote {
@WebParam(name = "distributionFile") File distributionFile) throws Exception;
/**
+ * Creates a bundle version based on the actual bytes of a Bundle Distribution file. This is essentially
+ * the same as {@link #createBundleVersionViaFile(Subject, File)} but the caller is providing the actual
+ * bytes of the file as opposed to the file itself.
+ * WARNING: obviously, this requires the entire distribution file to have been loaded fully in memory.
+ * For very large distribution files, this could cause OutOfMemoryErrors.
+ *
+ * @param subject
+ * @param fileBytes the file bits that make up the entire bundle distribution file
+ * @return the persisted BundleVersion with alot of the internal relationships filled in to help the caller
+ * understand all that this method did. Bundle files specifically are returned.
+ */
+ @WebMethod
+ BundleVersion createBundleVersionViaByteArray( //
+ @WebParam(name = "subject") Subject subject, //
+ @WebParam(name = "fileBytes") byte[] fileBytes) throws Exception;
+
+ /**
* Creates a bundle version based on a Bundle Distribution file. Typically a zip file, the bundle distribution
* contains the recipe for a supported bundle type, along with 0, 1 or more bundle files that will be associated
* with the bundle version. The recipe specifies the bundle name, version, version name and version description.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
index 9f204d1..0258dbb 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
@@ -80,8 +80,6 @@ import org.rhq.core.domain.criteria.BundleFileCriteria;
import org.rhq.core.domain.criteria.BundleResourceDeploymentCriteria;
import org.rhq.core.domain.criteria.BundleVersionCriteria;
import org.rhq.core.domain.criteria.Criteria;
-import org.rhq.core.domain.criteria.DriftChangeSetCriteria;
-import org.rhq.core.domain.criteria.DriftCriteria;
import org.rhq.core.domain.criteria.EventCriteria;
import org.rhq.core.domain.criteria.GroupOperationHistoryCriteria;
import org.rhq.core.domain.criteria.InstalledPackageCriteria;
@@ -98,9 +96,6 @@ import org.rhq.core.domain.criteria.ResourceOperationHistoryCriteria;
import org.rhq.core.domain.criteria.ResourceTypeCriteria;
import org.rhq.core.domain.criteria.RoleCriteria;
import org.rhq.core.domain.criteria.SubjectCriteria;
-import org.rhq.core.domain.drift.Drift;
-import org.rhq.core.domain.drift.DriftChangeSet;
-import org.rhq.core.domain.drift.DriftSnapshot;
import org.rhq.core.domain.event.Event;
import org.rhq.core.domain.event.EventSeverity;
import org.rhq.core.domain.measurement.Availability;
@@ -218,7 +213,7 @@ public class WebservicesManagerBean implements WebservicesRemote {
private SupportManagerLocal supportManager = LookupUtil.getSupportManager();
private SystemManagerLocal systemManager = LookupUtil.getSystemManager();
private SynchronizationManagerLocal synchronizationManager = LookupUtil.getSynchronizationManager();
-
+
//ALERTMANAGER: BEGIN ------------------------------------------
public PageList<Alert> findAlertsByCriteria(Subject subject, AlertCriteria criteria) {
return alertManager.findAlertsByCriteria(subject, criteria);
@@ -331,6 +326,10 @@ public class WebservicesManagerBean implements WebservicesRemote {
return bundleManager.createBundleVersionViaFile(subject, distributionFile);
}
+ public BundleVersion createBundleVersionViaByteArray(Subject subject, byte[] fileBytes) throws Exception {
+ return bundleManager.createBundleVersionViaByteArray(subject, fileBytes);
+ }
+
public BundleVersion createBundleVersionViaURL(Subject subject, String distributionFileUrl) throws Exception {
return bundleManager.createBundleVersionViaURL(subject, distributionFileUrl);
}
@@ -1197,28 +1196,28 @@ public class WebservicesManagerBean implements WebservicesRemote {
//SYSTEMMANAGER: END ------------------------------------
//SYNCHRONIZATIONMANANGER: BEGIN -------------------------
-
+
public ExportReport exportAllSubsystems(Subject subject) {
return synchronizationManager.exportAllSubsystems(subject);
}
-
+
public void validate(Subject subject, byte[] exportFile) throws ValidationException {
synchronizationManager.validate(subject, exportFile);
}
-
+
public List<ImportConfigurationDefinition> getImportConfigurationDefinitionOfAllSynchronizers() {
return synchronizationManager.getImportConfigurationDefinitionOfAllSynchronizers();
}
-
+
public ImportConfigurationDefinition getImportConfigurationDefinition(String importerClass) {
return synchronizationManager.getImportConfigurationDefinition(importerClass);
}
-
- public void importAllSubsystems(Subject subject, byte[] exportFile,
- List<ImportConfiguration> importerConfigurations) throws ValidationException, ImportException {
+
+ public void importAllSubsystems(Subject subject, byte[] exportFile, List<ImportConfiguration> importerConfigurations)
+ throws ValidationException, ImportException {
synchronizationManager.importAllSubsystems(subject, exportFile, importerConfigurations);
}
-
+
//SYNCHRONIZATIONMANANGER: END -------------------------
private void checkParametersPassedIn(Subject subject, Criteria criteria) {
if (subject == null) {
12 years, 8 months
[rhq] modules/core modules/enterprise
by John Sanda
modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/drift/DriftAgentService.java | 27 +++
modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/drift/DriftServerService.java | 77 ++++++++--
modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java | 42 +++--
modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftManagerTest.java | 32 +---
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftFileBean.java | 4
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerBean.java | 18 ++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerLocal.java | 7
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftServerServiceImpl.java | 5
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftUploadRequest.java | 19 ++
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/drift/DriftManagerBeanTest.java | 4
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/TestAgentClient.java | 4
11 files changed, 189 insertions(+), 50 deletions(-)
New commits:
commit 339d435bb20f550567ec68d87eeb2fbb8171a98b
Author: John Sanda <jsanda(a)redhat.com>
Date: Wed Sep 28 10:12:19 2011 -0400
Server now sends acknowledgement to agent when change set content is persisted
This commit adds some error handling around sending change set content
from agent to server. Previously, if the server failed to receive or
persist content, the agent would never know. Now the server sends an
explicit ackowledgement.
In a future commit, I will add support for resending content during
inventory sync for anything that has not been acked.
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/drift/DriftAgentService.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/drift/DriftAgentService.java
index 6d39431..d58c766 100644
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/drift/DriftAgentService.java
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/drift/DriftAgentService.java
@@ -104,5 +104,32 @@ public interface DriftAgentService {
*/
void updateDriftDetection(int resourceId, DriftConfiguration driftConfiguration);
+ /**
+ * This method is invoked to inform the agent that the server has successfully
+ * persisted the last change set sent to the server for the specified drift
+ * configuration. The agent will proceed to purge the older, previous snapshot
+ * as well as the the change set zip file.
+ * <br/><br/>
+ * <strong>Note:</strong> The agent will not resume drift detection for this drift
+ * configuration until the server has acknowledged the last change set sent.
+ *
+ * @param resourceId The id of the resource to which the acknowledged change set
+ * belongs.
+ * @param driftConfigName The name of the drift configuration to which the change set
+ * belongs.
+ */
void ackChangeSet(int resourceId, String driftConfigName);
+
+ /**
+ * This method is invoked to inform the agent that the server has successfully
+ * persisted change set content that was previously sent to the server. The agent
+ * will proceed to purge the referenced content zip file.
+ *
+ * @param resourceId The id of the resource to which the referenced drift configuration
+ * belongs.
+ * @param driftConfigName The name of the drift configuration to which the content
+ * belongs.
+ * @param token A token that is used to identify the content zip file
+ */
+ void ackChangeSetContent(int resourceId, String driftConfigName, String token);
}
\ No newline at end of file
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/drift/DriftServerService.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/drift/DriftServerService.java
index c31514d..4f1deef 100644
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/drift/DriftServerService.java
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/drift/DriftServerService.java
@@ -29,6 +29,9 @@ import org.rhq.core.domain.drift.DriftConfiguration;
import org.rhq.core.domain.drift.DriftSnapshot;
/**
+ * This class defines the drift server API that the agent uses for things like sending
+ * change set reports, sending change set content, and performing inventory sync.
+ *
* @author Jay Shaughnessy
* @author John Sanda
*/
@@ -37,26 +40,82 @@ public interface DriftServerService {
// note that this guaranteed delivery is weak because most likely the stream will be dead if it
// doesn't work the first time.
/**
- * The ChangeSet file is of the format described in ChangeSetReader.
+ * The agent invokes this method to send a change set in a zip file. The agent will call
+ * this method to report the initial change set when starting drift detection and
+ * subsequently whenever drift is detected. The format of the change set report is
+ * described in {@link org.rhq.common.drift.ChangeSetWriter ChangeSetWriter}. This
+ * method starts the following work flow:
+ * <ul>
+ * <li>
+ * A request is sent to JMS queue so that the change set can be processed
+ * asynchronously allowing control to return back to the agent as quickly as
+ * possible. It also allows the server to be able to more quickly service other
+ * agent and/or web requests.
+ * </li>
+ * <li>The server streams and persists the change set.</li>
+ * <li>
+ * The server sends an acknowledgement to the agent to let it know that the change
+ * set was successfully persisted. The agent will refrain from sending any more
+ * change sets until this step has completed.
+ * </li>
+ * <li>
+ * The server sends a request to the agent for any content referenced in the change
+ * set that is not yet in the database.
+ * </li>
+ * </ul>
+ *
+ * Note that because the change set bits are streamed out of band, if any errors occur
+ * during the streaming, exception will not be propagated back up the call stack on the
+ * agent side in the thread that initiated the call. This is the reason for the
+ * acknowledgement step.
*
- * @param resourceId
- * @param zipSize
- * @param zipStream A RemoteStream
+ * @param resourceId The id of the resource to which this change set belongs. This
+ * parameter may obsolete since the resource id is specified in the change set headers.
+ * @param zipSize The total number of bytes to be streamed
+ * @param zipStream A RemoteInputStream
*/
+ // TODO is the resourceId param needed since it is also included in the change set headers?
void sendChangesetZip(int resourceId, long zipSize, InputStream zipStream);
// note that this guaranteed delivery is weak because most likely the stream will be dead if it
// doesn't work the first time.
/**
- * The name of each zip entry should be the sha256. The filenames and paths are not relevant as this
- * is only a store of content and the content is identified ony by the sha.
+ * The agent invokes this method to send change set content to the server. The content
+ * are files referenced in a change set that the agent previously sent to the server.
+ * The zip file is assumed to be flat, that is it contains only files, no directories.
+ * The name of each file should be the SHA hash of the file contents. File names and
+ * paths are not relevant as the server only stores content which is identified by the
+ * SHA hashes. This method starts the following work flow:
+ * <ul>
+ * <li>
+ * A request is sent to a JMS queue so that the work can be performed asynchronously
+ * allowing control to return back to the agent as quickly as possible. It also
+ * allows the server to more quickly service other agent and/or web requests.
+ * </li>
+ * <li>The server streams and persists each file.</li>
+ * <li>
+ * The server sends an acknowledgement to the agent to let it know that the content
+ * has been successfully persisted.
+ * </li>
+ * </ul>
+ *
+ * Note that that the guaranteed delivery on this method is weak due to the streaming
+ * being done asynchronously. If the first attempt at streaming fails the stream will
+ * likey be dead and subsequent retries will fail as well. Because the streaming is
+ * done out of band, any network IO errors will not be propagated back up the call stack
+ * on the agent side in the thread that initiated this method call. This is the reaosn
+ * for the acknowledgement step.
*
- * @param resourceId
- * @param zipSize
+ * @param resourceId The id of the resource to which the change set content belongs
+ * @param driftConfigName The drift configuration name. This is needed for the
+ * acknowledgement step.
+ * @param token A token needed for the acknowledgement step that allows the agent to
+ * uniquely identify the zip file that was sent.
+ * @param zipSize The total number of bytes to be streamed.
* @param zipStream A RemoteStream
*/
@Asynchronous(guaranteedDelivery = true)
- void sendFilesZip(int resourceId, long zipSize, InputStream zipStream);
+ void sendFilesZip(int resourceId, String driftConfigName, String token, long zipSize, InputStream zipStream);
Map<Integer, List<DriftConfiguration>> getDriftConfigurations(Set<Integer> resourceIds);
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java
index 400a63a..ab83351 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java
@@ -325,7 +325,8 @@ public class DriftManager extends AgentService implements DriftAgentService, Dri
@Override
public void sendChangeSetContentToServer(int resourceId, String driftConfigurationName, final File contentDir) {
try {
- String contentFileName = "content_" + System.currentTimeMillis() + ".zip";
+ String timestamp = Long.toString(System.currentTimeMillis());
+ String contentFileName = "content_" + timestamp + ".zip";
final File zipFile = new File(contentDir.getParentFile(), contentFileName);
ZipOutputStream stream = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile)));
@@ -337,19 +338,9 @@ public class DriftManager extends AgentService implements DriftAgentService, Dri
}
stream.close();
- // We want to clean up after we send the zip file to the server. We do this by
- // deleting the files in the content directory and the content zip itself. They
- // are no longer needed after being sent to the server. We cannot immediately
- // delete the content zip file though because it is sent asynchronously, and we
- // wind up deleting it before it is sent. The following approach allows us to
- // safely delete it when the comm layer closes the remote input stream.
- //
- // jsanda
- DriftInputStream inputStream = new DriftInputStream(new BufferedInputStream(new FileInputStream(zipFile)),
- new DeleteFile(zipFile));
-
DriftServerService driftServer = pluginContainerConfiguration.getServerServices().getDriftServerService();
- driftServer.sendFilesZip(resourceId, zipFile.length(), remoteInputStream(inputStream));
+ driftServer.sendFilesZip(resourceId, driftConfigurationName, timestamp, zipFile.length(),
+ remoteInputStream(new BufferedInputStream(new FileInputStream(zipFile))));
} catch (IOException e) {
log.error("An error occurred while trying to send content for changeset[resourceId: " + resourceId
+ ", driftConfiguration: " + driftConfigurationName + "]", e);
@@ -503,7 +494,7 @@ public class DriftManager extends AgentService implements DriftAgentService, Dri
File changeSetDir = new File(resourceDir, driftConfigName);
if (!changeSetDir.exists()) {
- log.warn("Cannot ack change set. Change set directory " + changeSetDir.getPath() +
+ log.warn("Cannot complete acknowledgement. Change set directory " + changeSetDir.getPath() +
" does not exist.");
return;
}
@@ -512,14 +503,31 @@ public class DriftManager extends AgentService implements DriftAgentService, Dri
File previousSnapshot = new File(snapshot.getParentFile(), snapshot.getName() + ".previous");
previousSnapshot.delete();
- deleteZipFiles(changeSetDir);
+ deleteZipFiles(changeSetDir, "changeset_");
+ }
+
+ @Override
+ public void ackChangeSetContent(int resourceId, String driftConfigName, String token) {
+ log.info("Received server change set content ack for [resourceId: " + resourceId +
+ ", driftConfigurationName: " + driftConfigName + "]");
+
+ File resourceDir = new File(changeSetsDir, Integer.toString(resourceId));
+ File changeSetDir = new File(resourceDir, driftConfigName);
+
+ if (!changeSetDir.exists()) {
+ log.warn("Cannot complete acknowledgement. Change set directory " + changeSetDir.getPath() +
+ " does not exist.");
+ return;
+ }
+
+ deleteZipFiles(changeSetDir, "content_" + token);
}
- private void deleteZipFiles(File dir) {
+ private void deleteZipFiles(File dir, final String prefix) {
File[] files = dir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
- return name.endsWith(".zip");
+ return name.startsWith(prefix) && name.endsWith(".zip");
}
});
for (File file : files) {
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftManagerTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftManagerTest.java
index cac5ea8..ae3a940 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftManagerTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/drift/DriftManagerTest.java
@@ -183,30 +183,23 @@ public class DriftManagerTest extends DriftTest {
});
driftMgr.sendChangeSetContentToServer(resourceId(), configName, contentDir);
+
+ // verify that the content directory is purged
+ assertThatDirectoryIsEmpty(contentDir);
}
@Test
- public void cleanUpAfterSendingContentToServer() throws Exception {
- String configName = "clean-up-after-sending-content";
+ public void cleanUpWhenServerAcksChangeSetContent() throws Exception {
+ String configName = "cleanup-when-server-acks-content";
File changeSetDir = changeSetDir(configName);
File contentDir = mkdir(changeSetDir, "content");
- createRandomFile(contentDir, "content-1");
- createRandomFile(contentDir, "content-2");
-
- driftMgr.sendChangeSetContentToServer(resourceId(), configName, contentDir);
-
- // clean up should not happen until after the input stream is closed. The remote
- // input stream is consumed asynchronously; so, we have to wait until the stream
- // is closed. We could otherwise disrupt the transmission of bits.
- File contentZipFile = assertThatZipFileExists(changeSetDir, "content_",
- "Expected to find content zip file in " +
- changeSetDir.getPath() + ". The file name should have a pattern of content_integer_timestamp>.zip");
+ String token = Long.toString(System.currentTimeMillis());
+ File contentZipFile = createRandomFile(changeSetDir, "content_" + token + ".zip");
- driftServerService.inputStream.close();
+ driftMgr.ackChangeSetContent(resourceId(), configName, token);
- assertFalse(contentZipFile.exists(), "The content zip should be deleted when the remote input stream is closed");
- assertThatDirectoryIsEmpty(contentDir);
+ assertFalse(contentZipFile.exists(), "Content zip file should be purged after server sends content ack");
}
@Test
@@ -367,6 +360,8 @@ public class DriftManagerTest extends DriftTest {
private static class TestDriftServerService implements DriftServerService {
public int resourceId;
+ public String driftConfigName;
+ public String token;
public long fileSize;
public InputStream inputStream;
@@ -384,8 +379,11 @@ public class DriftManagerTest extends DriftTest {
}
@Override
- public void sendFilesZip(int resourceId, long zipSize, InputStream zipStream) {
+ public void sendFilesZip(int resourceId, String driftConfigName, String token, long zipSize,
+ InputStream zipStream) {
this.resourceId = resourceId;
+ this.driftConfigName = driftConfigName;
+ this.token = token;
fileSize = zipSize;
inputStream = zipStream;
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftFileBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftFileBean.java
index 6c639e4..4d7bebf 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftFileBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftFileBean.java
@@ -84,8 +84,8 @@ public class DriftFileBean implements MessageListener {
+ "]");
}
- driftManager.saveChangeSetFiles(subjectManager.getOverlord(), tempFile);
-
+ driftManager.saveChangeSetContent(subjectManager.getOverlord(), request.getResourceId(),
+ request.getDriftConfigName(), request.getToken(), tempFile);
} catch (IOException e) {
log.error(e);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerBean.java
index d848e1b..aafd0bb 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerBean.java
@@ -27,6 +27,7 @@ import java.util.Set;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
+import javax.ejb.TransactionAttributeType;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.MessageProducer;
@@ -194,17 +195,30 @@ public class DriftManagerBean implements DriftManagerLocal, DriftManagerRemote {
// http://management-platform.blogspot.com/2008/11/transaction-recovery-in-j...
@Override
@TransactionAttribute(REQUIRES_NEW)
- public void addFiles(int resourceId, long zipSize, InputStream zipStream) throws Exception {
+ public void addFiles(int resourceId, String driftConfigName, String token, long zipSize, InputStream zipStream)
+ throws Exception {
Connection connection = factory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(fileQueue);
- ObjectMessage msg = session.createObjectMessage(new DriftUploadRequest(resourceId, zipSize, zipStream));
+ ObjectMessage msg = session.createObjectMessage(new DriftUploadRequest(resourceId, driftConfigName, token,
+ zipSize, zipStream));
producer.send(msg);
connection.close();
}
@Override
+ @TransactionAttribute(TransactionAttributeType.SUPPORTS)
+ public void saveChangeSetContent(Subject subject, int resourceId, String driftConfigName, String token,
+ File changeSetFilesZip) throws Exception {
+ saveChangeSetFiles(subject, changeSetFilesZip);
+
+ AgentClient agent = agentManager.getAgentClient(subjectManager.getOverlord(), resourceId);
+ DriftAgentService driftService = agent.getDriftAgentService();
+ driftService.ackChangeSetContent(resourceId, driftConfigName, token);
+ }
+
+ @Override
@TransactionAttribute(NOT_SUPPORTED)
public DriftSnapshot createSnapshot(Subject subject, DriftChangeSetCriteria criteria) {
DriftServerPluginFacet driftServerPlugin = getServerPlugin();
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerLocal.java
index 9d8a883..c11482e 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftManagerLocal.java
@@ -19,6 +19,7 @@
*/
package org.rhq.enterprise.server.drift;
+import java.io.File;
import java.io.InputStream;
import javax.ejb.Local;
@@ -57,7 +58,11 @@ public interface DriftManagerLocal extends DriftServerPluginFacet, DriftManagerR
* @param zipStream The drift files zip file stream
* @throws Exception
*/
- void addFiles(int resourceId, long zipSize, InputStream zipStream) throws Exception;
+ void addFiles(int resourceId, String driftConfigName, String token, long zipSize, InputStream zipStream)
+ throws Exception;
+
+ void saveChangeSetContent(Subject subject, int resourceId, String driftConfigName, String token,
+ File changeSetFilesZip) throws Exception;
/**
* Remove the provided driftConfig (identified by name) on the specified entityContext.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftServerServiceImpl.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftServerServiceImpl.java
index 7af5163..c017ca3 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftServerServiceImpl.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftServerServiceImpl.java
@@ -51,10 +51,11 @@ public class DriftServerServiceImpl implements DriftServerService {
}
@Override
- public void sendFilesZip(int resourceId, long zipSize, InputStream zipStream) {
+ public void sendFilesZip(int resourceId, String driftConfigName, String token, long zipSize,
+ InputStream zipStream) {
try {
DriftManagerLocal driftManager = getDriftManager();
- driftManager.addFiles(resourceId, zipSize, zipStream);
+ driftManager.addFiles(resourceId, driftConfigName, token, zipSize, zipStream);
} catch (Exception e) {
throw new RuntimeException(e);
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftUploadRequest.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftUploadRequest.java
index 6ef7ba2..3c5a31e 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftUploadRequest.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftUploadRequest.java
@@ -27,12 +27,23 @@ public class DriftUploadRequest implements Serializable {
private int resourceId;
+ private String driftConfigName;
+
+ private String token;
+
private long dataSize;
private InputStream dataStream;
public DriftUploadRequest(int resourceId, long dataSize, InputStream dataStream) {
+ this(resourceId, null, null, dataSize, dataStream);
+ }
+
+ public DriftUploadRequest(int resourceId, String driftConfigName, String token, long dataSize,
+ InputStream dataStream) {
this.resourceId = resourceId;
+ this.driftConfigName = driftConfigName;
+ this.token = token;
this.dataSize = dataSize;
this.dataStream = dataStream;
}
@@ -41,6 +52,14 @@ public class DriftUploadRequest implements Serializable {
return resourceId;
}
+ public String getDriftConfigName() {
+ return driftConfigName;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
public long getDataSize() {
return dataSize;
}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/drift/DriftManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/drift/DriftManagerBeanTest.java
index 244d332..ab84ce5 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/drift/DriftManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/drift/DriftManagerBeanTest.java
@@ -451,5 +451,9 @@ public class DriftManagerBeanTest extends AbstractEJB3Test {
@Override
public void ackChangeSet(int resourceId, String driftConfigName) {
}
+
+ @Override
+ public void ackChangeSetContent(int resourceId, String driftConfigName, String token) {
+ }
}
}
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/TestAgentClient.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/TestAgentClient.java
index 5940b6a..43d0ded 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/TestAgentClient.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/TestAgentClient.java
@@ -354,4 +354,8 @@ public class TestAgentClient implements AgentClient, BundleAgentService, DriftAg
@Override
public void ackChangeSet(int resourceId, String driftConfigName) {
}
+
+ @Override
+ public void ackChangeSetContent(int resourceId, String driftConfigName, String token) {
+ }
}
12 years, 8 months
[rhq] modules/core
by Heiko W. Rupp
modules/core/dbutils/src/main/java/org/rhq/core/db/Postgresql91DatabaseType.java | 16 +++++++++-
modules/core/dbutils/src/test/java/org/rhq/core/db/AbstractDatabaseTestUtil.java | 2 -
modules/core/dbutils/src/test/java/org/rhq/core/db/DatabaseTest.java | 16 ++++++++--
3 files changed, 30 insertions(+), 4 deletions(-)
New commits:
commit cc09ffea0ecd929349f5f4720a7e088d053bf276
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Wed Sep 28 10:46:13 2011 +0200
BZ 741855 - use standard conforming escapes in Postgres 9.1+
diff --git a/modules/core/dbutils/src/main/java/org/rhq/core/db/Postgresql91DatabaseType.java b/modules/core/dbutils/src/main/java/org/rhq/core/db/Postgresql91DatabaseType.java
index d4f97cc..ce5728e 100644
--- a/modules/core/dbutils/src/main/java/org/rhq/core/db/Postgresql91DatabaseType.java
+++ b/modules/core/dbutils/src/main/java/org/rhq/core/db/Postgresql91DatabaseType.java
@@ -19,7 +19,7 @@
package org.rhq.core.db;
/**
- * Postgres 9.1 database which extends the Postgres 8.4 database.
+ * Postgres 9.1 database which extends the Postgres database.
* It is important to extend 8.3+ and not any previous version as the
* code will enable async commit in some place for instanceof 8.3
*
@@ -43,4 +43,18 @@ public class Postgresql91DatabaseType extends Postgresql90DatabaseType {
public String getVersion() {
return "9.1";
}
+
+ /**
+ * Postgres 9.1 is using a standard conforming escape character out of the box
+ * unlike earlier versions of Postgres, which means we need to follow this convention
+ * here.
+ * @return escape char
+ */
+ @Override
+ public String getEscapeCharacter() {
+ String result = System.getProperty("rhq.server.database.escape-character");
+
+ return (null == result) ? "\\" : result;
+ }
+
}
\ No newline at end of file
diff --git a/modules/core/dbutils/src/test/java/org/rhq/core/db/AbstractDatabaseTestUtil.java b/modules/core/dbutils/src/test/java/org/rhq/core/db/AbstractDatabaseTestUtil.java
index 656d5a6..ed15de6 100644
--- a/modules/core/dbutils/src/test/java/org/rhq/core/db/AbstractDatabaseTestUtil.java
+++ b/modules/core/dbutils/src/test/java/org/rhq/core/db/AbstractDatabaseTestUtil.java
@@ -188,7 +188,7 @@ public class AbstractDatabaseTestUtil {
e);
}
- System.err.println(database + " is not available. DatabaseTest.nofail is set - skipping test");
+ System.err.println(database + " is not available (" + e.toString() + "). DatabaseTest.nofail is set - skipping test");
}
// just do some simple things with the connection to make sure we can use this
diff --git a/modules/core/dbutils/src/test/java/org/rhq/core/db/DatabaseTest.java b/modules/core/dbutils/src/test/java/org/rhq/core/db/DatabaseTest.java
index c2bb4f5..c1953e8 100644
--- a/modules/core/dbutils/src/test/java/org/rhq/core/db/DatabaseTest.java
+++ b/modules/core/dbutils/src/test/java/org/rhq/core/db/DatabaseTest.java
@@ -259,6 +259,8 @@ public class DatabaseTest extends AbstractDatabaseTestUtil {
DatabaseType oracle10 = new Oracle10DatabaseType();
DatabaseType postgres7 = new Postgresql7DatabaseType();
DatabaseType postgres8 = new Postgresql8DatabaseType();
+ DatabaseType postgres90 = new Postgresql90DatabaseType();
+ DatabaseType postgres91 = new Postgresql91DatabaseType();
DatabaseType h2_11 = new H2v11DatabaseType();
assert DatabaseTypeFactory.isOracle(oracle8);
@@ -274,10 +276,19 @@ public class DatabaseTest extends AbstractDatabaseTestUtil {
assert DatabaseTypeFactory.isPostgres(postgres7);
assert !DatabaseTypeFactory.isOracle(postgres7);
assert !DatabaseTypeFactory.isH2(postgres7);
+
assert DatabaseTypeFactory.isPostgres(postgres8);
assert !DatabaseTypeFactory.isOracle(postgres8);
assert !DatabaseTypeFactory.isH2(postgres8);
+ assert DatabaseTypeFactory.isPostgres(postgres90);
+ assert !DatabaseTypeFactory.isOracle(postgres90);
+ assert !DatabaseTypeFactory.isH2(postgres8);
+
+ assert DatabaseTypeFactory.isPostgres(postgres91);
+ assert !DatabaseTypeFactory.isOracle(postgres91);
+ assert !DatabaseTypeFactory.isH2(postgres91);
+
assert DatabaseTypeFactory.isH2(h2_11);
assert !DatabaseTypeFactory.isPostgres(h2_11);
assert !DatabaseTypeFactory.isOracle(h2_11);
@@ -341,8 +352,9 @@ public class DatabaseTest extends AbstractDatabaseTestUtil {
assert DatabaseTypeFactory.isPostgres(conn);
assert DatabaseTypeFactory.isPostgres(dbtype);
assert dbtype.getVendor().equals("postgresql") : dbtype;
- assert dbtype.getVersion().startsWith("8") : dbtype;
- assert dbtype.getName().startsWith("postgresql8") : dbtype;
+ String version = dbtype.getVersion();
+ assert version.startsWith("8") || version.startsWith("9") : dbtype;
+ assert dbtype.getName().startsWith("postgresql") : dbtype;
assertPostgresTypes(dbtype);
}
12 years, 8 months
[rhq] Branch 'mod_cluster_plugin' - modules/plugins
by snegrea
modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml | 38 +++++++++-
1 file changed, 36 insertions(+), 2 deletions(-)
New commits:
commit db9415c0ecc8cd12ef479448148b36da9375d0db
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Tue Sep 27 22:44:44 2011 -0500
Add SSL configuration for JBoss 5.x and 6.0. Without this configuration the SSL boolean property is not usable.
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index 35330f2..2e54f29 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -179,7 +179,6 @@
<c:simple-property name="proxyList" type="string" required="false" description="Comma separated list of address:port listing the httpd servers where mod_cluster is running." />
<c:simple-property name="proxyURL" type="string" required="false" description="URL prefix to send with commands to mod_cluster. Default is no prefix." />
<c:simple-property name="socketTimeout" type="integer" required="false" description="Connection timeout for communication with the proxy." />
- <c:simple-property name="ssl" type="boolean" description="Whether to use SSL to communicate with mod_cluster. Note this has nothing to do with handling of https requests by JBoss Web" />
<c:simple-property name="excludedContexts" type="string" required="false" description="Comma delimited list of contexts that should *not* be auto-registered with httpd. Contexts may be qualified by host using a colon, e.g. host1:context1. If no host is defined, localhost is assumed." />
<c:simple-property name="autoEnableContexts" type="boolean" required="false" default="true" description="Toggle for context auto-enable during mod_cluster startup." />
@@ -199,6 +198,24 @@
<c:simple-property name="stickySessionForce" type="boolean" description="Return an error when the request cannot be routed to the right node." />
<c:simple-property name="workerTimeout" type="integer" description="Timeout to wait for an available worker (default is no wait)." />
<c:simple-property name="maxAttempts" type="integer" description="Maximum number of attempts to send the request to the backend server." />
+
+ <!-- SSL Configuration -->
+ <c:simple-property name="ssl" type="boolean" description="Whether to use SSL to communicate with mod_cluster. Note this has nothing to do with handling of https requests by JBoss Web" />
+ <c:simple-property name="sslCiphers" type="string" required="false" description="SSL ciphers." />
+ <c:simple-property name="sslProtocol" type="string" required="false" description="SSL protocol." />
+ <c:simple-property name="sslCertificateEncodingAlgorithm" type="string" required="false" description="Certificate encoding algorithm." />
+ <c:simple-property name="sslKeyStore" type="string" required="false" description="SSL keystore." />
+ <c:simple-property name="sslKeyStorePassword" type="string" required="false" description="SSL keystore password." />
+ <c:simple-property name="sslKeyStoreType" type="string" required="false" description="SSL keystore type." />
+ <c:simple-property name="sslKeyStoreProvider" type="string" required="false" description="SSL keystore provider." />
+ <c:simple-property name="sslTrustAlgorithm" type="string" required="false" description="Truststore algorithm." />
+ <c:simple-property name="sslKeyAlias" type="string" required="false" description="Key alias." />
+ <c:simple-property name="sslCrlFile" type="string" required="false" description="Certificate revocation list." />
+ <c:simple-property name="sslTrustMaxCertLength" type="string" required="false" description="Trust max certificate length." />
+ <c:simple-property name="sslTrustStore" type="string" required="false" description="Trust store file." />
+ <c:simple-property name="sslTrustStorePassword" type="string" required="false" description="Trust store password." />
+ <c:simple-property name="sslTrustStoreType" type="string" required="false" description="Trust store type." />
+ <c:simple-property name="sslTrustStoreProvider" type="string" required="false" description="Trust store provider." />
</resource-configuration>
</service>
<!-- End - Configuration for HAModClusterService -->
@@ -307,7 +324,6 @@
<c:simple-property name="proxyList" type="string" required="false" description="Comma separated list of address:port listing the httpd servers where mod_cluster is running." />
<c:simple-property name="proxyURL" type="string" required="false" description="URL prefix to send with commands to mod_cluster. Default is no prefix." />
<c:simple-property name="socketTimeout" type="integer" required="false" description="Connection timeout for communication with the proxy." />
- <c:simple-property name="ssl" type="boolean" description="Whether to use SSL to communicate with mod_cluster. Note this has nothing to do with handling of https requests by JBoss Web" />
<c:simple-property name="excludedContexts" type="string" required="false"
description="Comma delimited list of contexts that should *not* be auto-registered with httpd. Contexts may be qualified by host using a colon, e.g. host1:context1. If no host is defined, localhost is assumed." />
<c:simple-property name="autoEnableContexts" type="boolean" required="false" default="true" description="Toggle for context auto-enable during mod_cluster startup." />
@@ -328,6 +344,24 @@
<c:simple-property name="stickySessionForce" type="boolean" description="Return an error when the request cannot be routed to the right node." />
<c:simple-property name="workerTimeout" type="integer" description="Timeout to wait for an available worker (default is no wait)." />
<c:simple-property name="maxAttempts" type="integer" description="Maximum number of attempts to send the request to the backend server." />
+
+ <!-- SSL Configuration -->
+ <c:simple-property name="ssl" type="boolean" description="Whether to use SSL to communicate with mod_cluster. Note this has nothing to do with handling of https requests by JBoss Web" />
+ <c:simple-property name="sslCiphers" type="string" required="false" description="SSL ciphers." />
+ <c:simple-property name="sslProtocol" type="string" required="false" description="SSL protocol." />
+ <c:simple-property name="sslCertificateEncodingAlgorithm" type="string" required="false" description="Certificate encoding algorithm." />
+ <c:simple-property name="sslKeyStore" type="string" required="false" description="SSL keystore." />
+ <c:simple-property name="sslKeyStorePassword" type="string" required="false" description="SSL keystore password." />
+ <c:simple-property name="sslKeyStoreType" type="string" required="false" description="SSL keystore type." />
+ <c:simple-property name="sslKeyStoreProvider" type="string" required="false" description="SSL keystore provider." />
+ <c:simple-property name="sslTrustAlgorithm" type="string" required="false" description="Truststore algorithm." />
+ <c:simple-property name="sslKeyAlias" type="string" required="false" description="Key alias." />
+ <c:simple-property name="sslCrlFile" type="string" required="false" description="Certificate revocation list." />
+ <c:simple-property name="sslTrustMaxCertLength" type="string" required="false" description="Trust max certificate length." />
+ <c:simple-property name="sslTrustStore" type="string" required="false" description="Trust store file." />
+ <c:simple-property name="sslTrustStorePassword" type="string" required="false" description="Trust store password." />
+ <c:simple-property name="sslTrustStoreType" type="string" required="false" description="Trust store type." />
+ <c:simple-property name="sslTrustStoreProvider" type="string" required="false" description="Trust store provider." />
</resource-configuration>
</service>
<!-- End - Configuration for ModClusterService -->
12 years, 8 months
[rhq] Branch 'mod_cluster_plugin' - 2 commits - modules/integration-tests modules/plugins
by snegrea
modules/integration-tests/mod_cluster-plugin-test/pom.xml | 442 ++++------
modules/integration-tests/mod_cluster-plugin-test/src/test/java/org/rhq/plugins/modcluster/test/ModClusterPluginIntegrationTest.java | 43
modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ClassNameMBeanComponent.java | 1
modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/WebappContextDiscoveryComponent.java | 15
modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml | 3
5 files changed, 252 insertions(+), 252 deletions(-)
New commits:
commit 90c95c6bbf13e1dfbd67c1d6552860e28bc65ee5
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Tue Sep 27 20:20:00 2011 -0500
Enable mod_cluster plugin for Tomcat. Also added a couple of integration tests for the resource.
diff --git a/modules/integration-tests/mod_cluster-plugin-test/pom.xml b/modules/integration-tests/mod_cluster-plugin-test/pom.xml
index bae660c..4e29e2b 100644
--- a/modules/integration-tests/mod_cluster-plugin-test/pom.xml
+++ b/modules/integration-tests/mod_cluster-plugin-test/pom.xml
@@ -58,6 +58,13 @@
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
+
+ <dependency>
+ <groupId>org.jboss.on</groupId>
+ <artifactId>jopr-tomcat-plugin</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
<dependency>
<groupId>${rhq.groupId}</groupId>
@@ -288,6 +295,7 @@
<include name="org/rhq/rhq-jmx-plugin/${project.version}/rhq-jmx-plugin-${project.version}.jar" />
<include name="org/jboss/on/jopr-jboss-as-plugin/${project.version}/jopr-jboss-as-plugin-${project.version}.jar" />
<include name="org/jboss/on/jopr-jboss-as-5-plugin/${project.version}/jopr-jboss-as-5-plugin-${project.version}.jar" />
+ <include name="org/jboss/on/jopr-tomcat-plugin/${project.version}/jopr-tomcat-plugin-${project.version}.jar" />
<include name="org/rhq/modcluster-plugin/${project.version}/modcluster-plugin-${project.version}.jar" />
</fileset>
<fileset dir="${rhq.deploymentDir}">
diff --git a/modules/integration-tests/mod_cluster-plugin-test/src/test/java/org/rhq/plugins/modcluster/test/ModClusterPluginIntegrationTest.java b/modules/integration-tests/mod_cluster-plugin-test/src/test/java/org/rhq/plugins/modcluster/test/ModClusterPluginIntegrationTest.java
index 625163b..44cf9f3 100644
--- a/modules/integration-tests/mod_cluster-plugin-test/src/test/java/org/rhq/plugins/modcluster/test/ModClusterPluginIntegrationTest.java
+++ b/modules/integration-tests/mod_cluster-plugin-test/src/test/java/org/rhq/plugins/modcluster/test/ModClusterPluginIntegrationTest.java
@@ -120,11 +120,28 @@ public class ModClusterPluginIntegrationTest {
} else if (resource.getResourceType().getName().equals("HA Service")) {
testServiceMeasurement(resource);
testServiceMethodInvocation(resource);
+ testServiceSimpleMethodInvocation(resource);
+ } else if (resource.getResourceType().getName().equals("Catalina Service")) {
+ testServiceSimpleMethodInvocation(resource);
}
}
}
}
+ private void testServiceSimpleMethodInvocation(Resource resource) throws InterruptedException, Exception {
+ ResourceComponent resourceComponent = PluginContainer.getInstance().getInventoryManager()
+ .getResourceComponent(resource);
+
+ Configuration config = new Configuration();
+ OperationResult result = ((OperationFacet) resourceComponent).invokeOperation("enable", config);
+ log.info("Result of operation enable was: " + result.getSimpleResult());
+ assert result.getSimpleResult().equals("true") : "The operation execution failed!";
+
+ result = ((OperationFacet) resourceComponent).invokeOperation("disable", config);
+ log.info("Result of operation disable was: " + result.getSimpleResult());
+ assert result.getSimpleResult().equals("true") : "The operation execution failed!";
+ }
+
private void testServiceMethodInvocation(Resource resource) throws InterruptedException, Exception {
ResourceComponent resourceComponent = PluginContainer.getInstance().getInventoryManager()
.getResourceComponent(resource);
@@ -133,7 +150,7 @@ public class ModClusterPluginIntegrationTest {
config.put(new PropertySimple("p1", "1"));
config.put(new PropertySimple("p2", java.util.concurrent.TimeUnit.SECONDS));
OperationResult result = ((OperationFacet) resourceComponent).invokeOperation("stop", config);
- log.info("Result of operation stopContext was: " + result.getSimpleResult());
+ log.info("Result of operation stop was: " + result.getSimpleResult());
}
private void testLoadServiceConfiguration(Resource resource) throws Exception {
@@ -165,13 +182,14 @@ public class ModClusterPluginIntegrationTest {
.getResourceComponent(resource);
if (resourceComponent instanceof OperationFacet) {
- OperationResult result = null;
-
- result = ((OperationFacet) resourceComponent).invokeOperation("reset", new Configuration());
- log.info("Result of operation test was: " + result);
+ for (String operationName : new String[] { "reset", "refresh" }) {
+ OperationResult result = ((OperationFacet) resourceComponent).invokeOperation(operationName,
+ new Configuration());
+ log.info("Result of operation " + operationName + " was: " + result);
- result = ((OperationFacet) resourceComponent).invokeOperation("refresh", new Configuration());
- log.info("Result of operation test was: " + result);
+ //need to wait for the reset to finish, this is a long operation
+ Thread.sleep(5000);
+ }
}
}
@@ -187,15 +205,18 @@ public class ModClusterPluginIntegrationTest {
Configuration config = new Configuration();
config.put(new PropertySimple("timeout", "1"));
config.put(new PropertySimple("unit", java.util.concurrent.TimeUnit.SECONDS));
+
result = ((OperationFacet) resourceComponent).invokeOperation("stopContext", config);
log.info("Result of operation stopContext was: " + result.getSimpleResult());
+ assert result.getSimpleResult().equals("true") : "The operation execution failed!";
result = ((OperationFacet) resourceComponent).invokeOperation("enableContext", null);
log.info("Result of operation enableContext was: " + result.getSimpleResult());
+ assert result.getSimpleResult().equals("true") : "The operation execution failed!";
result = ((OperationFacet) resourceComponent).invokeOperation("disableContext", null);
log.info("Result of operation disableContext was: " + result.getSimpleResult());
-
+ assert result.getSimpleResult().equals("true") : "The operation execution failed!";
} catch (Exception e) {
log.info("Operation failed. ", e);
}
@@ -204,7 +225,7 @@ public class ModClusterPluginIntegrationTest {
}
private Set<Resource> findResource(Resource parent) {
- Set<Resource> found = new HashSet<Resource>();
+ Set<Resource> foundResources = new HashSet<Resource>();
Queue<Resource> discoveryQueue = new LinkedList<Resource>();
discoveryQueue.add(parent);
@@ -214,7 +235,7 @@ public class ModClusterPluginIntegrationTest {
log.info("Discovered resource of type: " + currentResource.getResourceType().getName());
if (currentResource.getResourceType().getPlugin().equals(PLUGIN_NAME)) {
- found.add(currentResource);
+ foundResources.add(currentResource);
}
if (currentResource.getChildResources() != null) {
@@ -224,6 +245,6 @@ public class ModClusterPluginIntegrationTest {
}
}
- return found;
+ return foundResources;
}
}
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ClassNameMBeanComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ClassNameMBeanComponent.java
index 2d0b55e..34a8841 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ClassNameMBeanComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/ClassNameMBeanComponent.java
@@ -33,7 +33,6 @@ import org.rhq.plugins.jmx.MBeanResourceComponent;
@SuppressWarnings({ "deprecation" })
public class ClassNameMBeanComponent extends MBeanResourceComponent<JMXComponent<?>> {
private static final Log log = LogFactory.getLog(WebappContextComponent.class);
-
private static final String CLASS_NAME = "className";
@Override
diff --git a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/WebappContextDiscoveryComponent.java b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/WebappContextDiscoveryComponent.java
index faa9795..075633b 100644
--- a/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/WebappContextDiscoveryComponent.java
+++ b/modules/plugins/mod-cluster/src/main/java/org/rhq/plugins/modcluster/WebappContextDiscoveryComponent.java
@@ -73,10 +73,17 @@ public class WebappContextDiscoveryComponent implements ResourceDiscoveryCompone
*/
private String getJvmRoute(ResourceDiscoveryContext<MBeanResourceComponent<?>> context) {
Configuration pluginConfig = context.getParentResourceComponent().getResourceContext().getPluginConfiguration();
- String engineObjectName = pluginConfig.getSimple(ENGINE_OBJECT_NAME).getStringValue();
- EmsBean engineBean = this.loadBean(engineObjectName, context.getParentResourceComponent());
- return (String) engineBean.getAttribute(JVM_ROUTE_PROPERTY).refresh().toString();
+ String[] engineObjectNames = pluginConfig.getSimple(ENGINE_OBJECT_NAME).getStringValue().split("\\|");
+
+ for (String engineObjectName : engineObjectNames) {
+ EmsBean engineBean = this.loadBean(engineObjectName, context.getParentResourceComponent());
+ if (engineBean != null) {
+ return engineBean.getAttribute(JVM_ROUTE_PROPERTY).refresh().toString();
+ }
+ }
+
+ return null;
}
/**
@@ -87,7 +94,7 @@ public class WebappContextDiscoveryComponent implements ResourceDiscoveryCompone
* @param objectName the name of the bean to load
* @return the bean that is loaded
*/
- protected EmsBean loadBean(String objectName, MBeanResourceComponent context) {
+ protected EmsBean loadBean(String objectName, MBeanResourceComponent<?> context) {
EmsConnection emsConnection = context.getEmsConnection();
EmsBean bean = emsConnection.getBean(objectName);
if (bean == null) {
diff --git a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
index 536e747..35330f2 100644
--- a/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/mod-cluster/src/main/resources/META-INF/rhq-plugin.xml
@@ -13,11 +13,12 @@
<runs-inside>
<parent-resource-type name="JBossAS Server" plugin="JBossAS" />
<parent-resource-type name="JBossAS Server" plugin="JBossAS5" />
+ <parent-resource-type name="Tomcat Server" plugin="Tomcat" />
</runs-inside>
<plugin-configuration>
<c:simple-property name="objectName" readOnly="true" default="Catalina:type=ModClusterListener,*|jboss.web:service=ModCluster" />
- <c:simple-property name="engineObjectName" readOnly="true" default="jboss.web:type=Engine" />
+ <c:simple-property name="engineObjectName" readOnly="true" default="jboss.web:type=Engine|Catalina:type=Engine" />
<c:simple-property name="nameTemplate" default="mod_cluster" />
<c:simple-property name="serverHomeDir"/>
</plugin-configuration>
commit 9ace270b8eabb2b5e8644f19dc6f9356d9cb3117
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Tue Sep 27 16:17:44 2011 -0500
Format messy pom.xml file in preparation for more updates.
diff --git a/modules/integration-tests/mod_cluster-plugin-test/pom.xml b/modules/integration-tests/mod_cluster-plugin-test/pom.xml
index 32d5429..bae660c 100644
--- a/modules/integration-tests/mod_cluster-plugin-test/pom.xml
+++ b/modules/integration-tests/mod_cluster-plugin-test/pom.xml
@@ -14,47 +14,43 @@
<name>RHQ mod_cluster Plugin Integration Test</name>
<description>Integration tests for mod_cluster RHQ Agent plugin</description>
-
+
<properties>
- <scm.module.path>modules/integration-tests/mod_cluster-plugin-test</scm.module.path>
- <!-- jbossas.version>6.0.0.20100429-M3</jbossas.version-->
- <!-- jbossas.version>6.0.0.M1</jbossas.version-->
- <jbossas.version>6.0.0.Final</jbossas.version>
-
- </properties>
-
- <dependencyManagement>
- <dependencies>
- <dependency>
+ <scm.module.path>modules/integration-tests/mod_cluster-plugin-test</scm.module.path>
+ <!-- jbossas.version>6.0.0.20100429-M3</jbossas.version -->
+ <!-- jbossas.version>6.0.0.M1</jbossas.version -->
+ <jbossas.version>6.0.0.Final</jbossas.version>
+
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
<groupId>org.jboss.jbossas</groupId>
- <artifactId>jboss-as-parent</artifactId>
- <version>${jbossas.version}</version>
+ <artifactId>jboss-as-parent</artifactId>
+ <version>${jbossas.version}</version>
<type>pom</type>
<scope>import</scope>
- </dependency>
- <dependency>
+ </dependency>
+ <dependency>
<groupId>org.jboss.jbossas</groupId>
<artifactId>jboss-as-component-matrix</artifactId>
<version>${jbossas.version}</version>
<type>pom</type>
<scope>import</scope>
- </dependency>
- </dependencies>
- </dependencyManagement>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
<dependencies>
- <dependency>
+ <dependency>
<groupId>org.jboss.on</groupId>
<artifactId>jopr-jboss-as-5-plugin</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
-
- <!-- dependency>
- <groupId>org.jboss.integration</groupId>
- <artifactId>jboss-profileservice-spi</artifactId>
- <scope>provided</scope>
- </dependency-->
+
+ <!-- dependency> <groupId>org.jboss.integration</groupId> <artifactId>jboss-profileservice-spi</artifactId> <scope>provided</scope> </dependency -->
<dependency>
<groupId>${rhq.groupId}</groupId>
@@ -62,7 +58,7 @@
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
-
+
<dependency>
<groupId>${rhq.groupId}</groupId>
<artifactId>modcluster-plugin</artifactId>
@@ -76,213 +72,181 @@
<version>1.2.14</version>
<scope>provided</scope>
</dependency>
-
- <dependency>
- <groupId>org.jboss.naming</groupId>
- <artifactId>jnp-client</artifactId>
- <scope>test</scope>
- </dependency>
-
- <!--dependency>
- <groupId>org.jboss.microcontainer</groupId>
- <artifactId>jboss-kernel</artifactId>
- <scope>test</scope>
- </dependency-->
-
- <dependency>
- <groupId>org.jboss.jbossas</groupId>
- <artifactId>jboss-as-aspects</artifactId>
- <version>5.1.0.CR1</version>
- <classifier>jboss-aspect-jdk50-client</classifier>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>trove</groupId>
- <artifactId>trove</artifactId>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>javassist</groupId>
- <artifactId>javassist</artifactId>
- <scope>test</scope>
- </dependency>
-
- <!-- dependency>
- <groupId>org.jboss.security</groupId>
- <artifactId>jboss-security-spi</artifactId>
- <scope>test</scope>
- </dependency-->
-
- <!-- dependency>
- <groupId>org.jboss.javaee</groupId>
- <artifactId>jboss-javaee</artifactId>
- <scope>test</scope>
- </dependency-->
-
- <dependency>
- <groupId>oswego-concurrent</groupId>
- <artifactId>concurrent</artifactId>
- <version>1.3.4-jboss</version>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.jbossas</groupId>
- <artifactId>jboss-as-server</artifactId>
- <classifier>client</classifier>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.jboss</groupId>
- <artifactId>jboss-mdr</artifactId>
- <scope>test</scope>
- </dependency>
-
- <!-- dependency>
- <groupId>org.jboss.logging</groupId>
- <artifactId>jboss-logging-spi</artifactId>
- <scope>test</scope>
- </dependency-->
-
- <!-- dependency>
- <groupId>org.jboss.logging</groupId>
- <artifactId>jboss-logging-log4j</artifactId>
- <scope>test</scope>
- </dependency-->
-
- <dependency>
- <groupId>org.jboss.jbossas</groupId>
- <artifactId>jboss-as-security</artifactId>
- <version>5.1.0.CR1</version>
- <classifier>client</classifier>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.integration</groupId>
- <artifactId>jboss-transaction-spi</artifactId>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.ejb3</groupId>
- <artifactId>jboss-ejb3-common</artifactId>
- <classifier>client</classifier>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.ejb3</groupId>
- <artifactId>jboss-ejb3-core</artifactId>
- <classifier>client</classifier>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.ejb3</groupId>
- <artifactId>jboss-ejb3-ext-api</artifactId>
- <version>1.0.0</version>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.ejb3</groupId>
- <artifactId>jboss-ejb3-proxy-spi</artifactId>
- <classifier>client</classifier>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.ejb3</groupId>
- <artifactId>jboss-ejb3-proxy-impl</artifactId>
- <classifier>client</classifier>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.ejb3</groupId>
- <artifactId>jboss-ejb3-security</artifactId>
- <classifier>client</classifier>
- <scope>test</scope>
- </dependency>
-
- <!-- dependency>
- <groupId>org.jboss.microcontainer</groupId>
- <artifactId>jboss-dependency</artifactId>
- <scope>test</scope>
- </dependency-->
-
- <!-- dependency>
- <groupId>org.jboss.security</groupId>
- <artifactId>jbosssx-client</artifactId>
- <scope>test</scope>
- </dependency-->
-
- <dependency>
- <groupId>org.jboss.aspects</groupId>
- <artifactId>jboss-security-aspects</artifactId>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.aop</groupId>
- <artifactId>jboss-aop</artifactId>
- <classifier>client</classifier>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.jboss</groupId>
- <artifactId>jboss-common-core</artifactId>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.jboss</groupId>
- <artifactId>jboss-reflect</artifactId>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>jboss</groupId>
- <artifactId>jboss-serialization</artifactId>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.deployers</groupId>
- <artifactId>jboss-deployers-core-spi</artifactId>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.deployers</groupId>
- <artifactId>jboss-deployers-client-spi</artifactId>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.jbossas</groupId>
- <artifactId>jboss-as-profileservice</artifactId>
- <classifier>client</classifier>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.jboss.jbossas</groupId>
- <artifactId>jboss-as-server</artifactId>
- <classifier>jmx-invoker-adaptor-client</classifier>
- <scope>test</scope>
- </dependency>
+ <dependency>
+ <groupId>org.jboss.naming</groupId>
+ <artifactId>jnp-client</artifactId>
+ <scope>test</scope>
+ </dependency>
- <!-- dependency>
- <groupId>jboss.messaging</groupId>
- <artifactId>jboss-messaging-client</artifactId>
- <scope>test</scope>
- </dependency-->
+ <!--dependency> <groupId>org.jboss.microcontainer</groupId> <artifactId>jboss-kernel</artifactId> <scope>test</scope> </dependency -->
+
+ <dependency>
+ <groupId>org.jboss.jbossas</groupId>
+ <artifactId>jboss-as-aspects</artifactId>
+ <version>5.1.0.CR1</version>
+ <classifier>jboss-aspect-jdk50-client</classifier>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>trove</groupId>
+ <artifactId>trove</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>javassist</groupId>
+ <artifactId>javassist</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <!-- dependency> <groupId>org.jboss.security</groupId> <artifactId>jboss-security-spi</artifactId> <scope>test</scope> </dependency -->
+
+ <!-- dependency> <groupId>org.jboss.javaee</groupId> <artifactId>jboss-javaee</artifactId> <scope>test</scope> </dependency -->
+
+ <dependency>
+ <groupId>oswego-concurrent</groupId>
+ <artifactId>concurrent</artifactId>
+ <version>1.3.4-jboss</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.jbossas</groupId>
+ <artifactId>jboss-as-server</artifactId>
+ <classifier>client</classifier>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss</groupId>
+ <artifactId>jboss-mdr</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <!-- dependency> <groupId>org.jboss.logging</groupId> <artifactId>jboss-logging-spi</artifactId> <scope>test</scope> </dependency -->
+
+ <!-- dependency> <groupId>org.jboss.logging</groupId> <artifactId>jboss-logging-log4j</artifactId> <scope>test</scope> </dependency -->
+
+ <dependency>
+ <groupId>org.jboss.jbossas</groupId>
+ <artifactId>jboss-as-security</artifactId>
+ <version>5.1.0.CR1</version>
+ <classifier>client</classifier>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.integration</groupId>
+ <artifactId>jboss-transaction-spi</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.ejb3</groupId>
+ <artifactId>jboss-ejb3-common</artifactId>
+ <classifier>client</classifier>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.ejb3</groupId>
+ <artifactId>jboss-ejb3-core</artifactId>
+ <classifier>client</classifier>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.ejb3</groupId>
+ <artifactId>jboss-ejb3-ext-api</artifactId>
+ <version>1.0.0</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.ejb3</groupId>
+ <artifactId>jboss-ejb3-proxy-spi</artifactId>
+ <classifier>client</classifier>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.ejb3</groupId>
+ <artifactId>jboss-ejb3-proxy-impl</artifactId>
+ <classifier>client</classifier>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.ejb3</groupId>
+ <artifactId>jboss-ejb3-security</artifactId>
+ <classifier>client</classifier>
+ <scope>test</scope>
+ </dependency>
+
+ <!-- dependency> <groupId>org.jboss.microcontainer</groupId> <artifactId>jboss-dependency</artifactId> <scope>test</scope> </dependency -->
+
+ <!-- dependency> <groupId>org.jboss.security</groupId> <artifactId>jbosssx-client</artifactId> <scope>test</scope> </dependency -->
+
+ <dependency>
+ <groupId>org.jboss.aspects</groupId>
+ <artifactId>jboss-security-aspects</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.aop</groupId>
+ <artifactId>jboss-aop</artifactId>
+ <classifier>client</classifier>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss</groupId>
+ <artifactId>jboss-common-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss</groupId>
+ <artifactId>jboss-reflect</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>jboss</groupId>
+ <artifactId>jboss-serialization</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.deployers</groupId>
+ <artifactId>jboss-deployers-core-spi</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.deployers</groupId>
+ <artifactId>jboss-deployers-client-spi</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.jbossas</groupId>
+ <artifactId>jboss-as-profileservice</artifactId>
+ <classifier>client</classifier>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.jbossas</groupId>
+ <artifactId>jboss-as-server</artifactId>
+ <classifier>jmx-invoker-adaptor-client</classifier>
+ <scope>test</scope>
+ </dependency>
+
+ <!-- dependency> <groupId>jboss.messaging</groupId> <artifactId>jboss-messaging-client</artifactId> <scope>test</scope> </dependency -->
</dependencies>
@@ -316,7 +280,7 @@
<echo>Setting up plugin dependencies...</echo>
<property name="settings.localRepository" location="${user.home}/.m2/repository" />
<mkdir dir="target/testsetup" />
-
+
<mkdir dir="target/testsetup/plugins" />
<copy toDir="target/testsetup/plugins" flatten="true">
<fileset dir="${settings.localRepository}/">
@@ -330,7 +294,7 @@
<include name="${project.artifactId}-${project.version}.jar" />
</fileset>
</copy>
-
+
<mkdir dir="target/testsetup/lib" />
<unzip dest="target/testsetup/lib">
<fileset dir="${settings.localRepository}/org/hyperic/sigar-dist/${sigar.version}" includes="*.zip" />
@@ -355,10 +319,10 @@
<goal>run</goal>
</goals>
</execution>
- </executions>
+ </executions>
</plugin>
-
- <plugin>
+
+ <plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
12 years, 8 months
[rhq] 2 commits - modules/enterprise
by ips
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupCompositeDataSource.java | 19 ++----
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupDataSourceField.java | 8 +-
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupListView.java | 31 ++++------
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java | 2
4 files changed, 29 insertions(+), 31 deletions(-)
New commits:
commit 9d8f5bc97d535a3213b56b1bcb28b2be74dab3fe
Author: Ian Springer <ian.springer(a)redhat.com>
Date: Tue Sep 27 19:38:37 2011 -0400
[BZ 737121] fix sorting bug for Type, Children, and Descendants columns on Resource group list views (https://bugzilla.redhat.com/show_bug.cgi?id=737121)
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupCompositeDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupCompositeDataSource.java
index 584e652..17b2b56 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupCompositeDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupCompositeDataSource.java
@@ -18,12 +18,6 @@
*/
package org.rhq.enterprise.gui.coregui.client.inventory.groups;
-import static org.rhq.enterprise.gui.coregui.client.inventory.groups.ResourceGroupDataSourceField.CATEGORY;
-import static org.rhq.enterprise.gui.coregui.client.inventory.groups.ResourceGroupDataSourceField.DESCRIPTION;
-import static org.rhq.enterprise.gui.coregui.client.inventory.groups.ResourceGroupDataSourceField.NAME;
-import static org.rhq.enterprise.gui.coregui.client.inventory.groups.ResourceGroupDataSourceField.PLUGIN;
-import static org.rhq.enterprise.gui.coregui.client.inventory.groups.ResourceGroupDataSourceField.TYPE;
-
import java.util.List;
import com.google.gwt.user.client.rpc.AsyncCallback;
@@ -49,6 +43,8 @@ import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGroupGWTServiceAsync;
import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
import org.rhq.enterprise.gui.coregui.client.util.message.Message;
+import static org.rhq.enterprise.gui.coregui.client.inventory.groups.ResourceGroupDataSourceField.*;
+
/**
* @author Joseph Marques
*/
@@ -145,15 +141,14 @@ public class ResourceGroupCompositeDataSource extends RPCDataSource<ResourceGrou
String nameAttrib = from.getAttribute(NAME.propertyName());
String descriptionAttrib = from.getAttribute(DESCRIPTION.propertyName());
String typeNameAttrib = from.getAttribute(TYPE.propertyName());
- String pluginNameAttrib = from.getAttribute(PLUGIN.propertyName());
- ResourceType rt = null;
ResourceGroup rg = new ResourceGroup(nameAttrib);
rg.setId(idAttrib);
rg.setDescription(descriptionAttrib);
- if (null != typeNameAttrib) {
- rt = new ResourceType();
+ if (typeNameAttrib != null) {
+ ResourceType rt = new ResourceType();
rt.setName(typeNameAttrib);
+ String pluginNameAttrib = from.getAttribute(PLUGIN.propertyName());
rt.setPlugin(pluginNameAttrib);
rg.setResourceType(rt);
}
@@ -183,8 +178,8 @@ public class ResourceGroupCompositeDataSource extends RPCDataSource<ResourceGrou
record.setAttribute("implicitUp", String.valueOf(from.getImplicitUp()));
record.setAttribute("implicitDown", String.valueOf(from.getImplicitDown()));
- record.setAttribute("availabilityChildren", getExplicitFormatted(from));
- record.setAttribute("availabilityDescendents", getImplicitFormatted(from));
+ record.setAttribute(AVAIL_CHILDREN.propertyName(), getExplicitFormatted(from));
+ record.setAttribute(AVAIL_DESCENDANTS.propertyName(), getImplicitFormatted(from));
if (from.getResourceGroup().getResourceType() != null) {
record.setAttribute("resourceType", from.getResourceGroup().getResourceType());
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupDataSourceField.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupDataSourceField.java
index 743db43..c2a93ec 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupDataSourceField.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupDataSourceField.java
@@ -33,11 +33,15 @@ public enum ResourceGroupDataSourceField {
DESCRIPTION("description", CoreGUI.getMessages().common_title_description()),
- TYPE("typeName", CoreGUI.getMessages().common_title_type()),
+ TYPE("resourceTypeName", CoreGUI.getMessages().common_title_type()),
PLUGIN("pluginName", CoreGUI.getMessages().common_title_plugin()),
- CATEGORY("groupCategory", CoreGUI.getMessages().common_title_category());
+ CATEGORY("groupCategory", CoreGUI.getMessages().common_title_category()),
+
+ AVAIL_CHILDREN("availabilityChildren", CoreGUI.getMessages().view_inventory_groups_children()),
+
+ AVAIL_DESCENDANTS("availabilityDescendants", CoreGUI.getMessages().view_inventory_groups_descendants());
/**
* Corresponds to a property name of Resource
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupListView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupListView.java
index bf022a0..024dcc5 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupListView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupListView.java
@@ -18,12 +18,6 @@
*/
package org.rhq.enterprise.gui.coregui.client.inventory.groups;
-import static org.rhq.enterprise.gui.coregui.client.inventory.groups.ResourceGroupDataSourceField.CATEGORY;
-import static org.rhq.enterprise.gui.coregui.client.inventory.groups.ResourceGroupDataSourceField.DESCRIPTION;
-import static org.rhq.enterprise.gui.coregui.client.inventory.groups.ResourceGroupDataSourceField.NAME;
-import static org.rhq.enterprise.gui.coregui.client.inventory.groups.ResourceGroupDataSourceField.PLUGIN;
-import static org.rhq.enterprise.gui.coregui.client.inventory.groups.ResourceGroupDataSourceField.TYPE;
-
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.data.Criteria;
import com.smartgwt.client.types.Alignment;
@@ -59,6 +53,8 @@ import org.rhq.enterprise.gui.coregui.client.util.message.Message.Severity;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableWindow;
import org.rhq.enterprise.gui.coregui.client.util.selenium.SeleniumUtility;
+import static org.rhq.enterprise.gui.coregui.client.inventory.groups.ResourceGroupDataSourceField.*;
+
/**
* @author Greg Hinkle
* @author Joseph Marques
@@ -105,8 +101,7 @@ public class ResourceGroupListView extends Table<ResourceGroupCompositeDataSourc
ListGridField idField = new ListGridField("id", MSG.common_title_id());
idField.setWidth(50);
- ListGridField categoryField = new ListGridField(CATEGORY.propertyName());
- categoryField.setTitle(" ");
+ ListGridField categoryField = new ListGridField(CATEGORY.propertyName(), CATEGORY.title());
categoryField.setWidth(25);
categoryField.setAlign(Alignment.CENTER);
categoryField.setCellFormatter(new CellFormatter() {
@@ -121,7 +116,7 @@ public class ResourceGroupListView extends Table<ResourceGroupCompositeDataSourc
categoryField.setHoverCustomizer(new HoverCustomizer() {
@Override
public String hoverHTML(Object value, ListGridRecord record, int rowNum, int colNum) {
- String categoryName = record.getAttribute(CATEGORY.propertyName());
+ String categoryName = record.getAttribute(CATEGORY.name());
GroupCategory category = GroupCategory.valueOf(categoryName);
String displayName = null;
switch (category) {
@@ -148,21 +143,25 @@ public class ResourceGroupListView extends Table<ResourceGroupCompositeDataSourc
});
ListGridField descriptionField = new ListGridField(DESCRIPTION.propertyName(), DESCRIPTION.title());
- descriptionField.setWidth("30%");
+ descriptionField.setWidth("28%");
ListGridField typeNameField = new ListGridField(TYPE.propertyName(), TYPE.title());
- typeNameField.setWidth("10%");
+ typeNameField.setWidth("14%");
ListGridField pluginNameField = new ListGridField(PLUGIN.propertyName(), PLUGIN.title());
- pluginNameField.setWidth("10%");
+ pluginNameField.setWidth("8%");
- ListGridField availabilityChildrenField = new ListGridField("availabilityChildren", MSG
- .view_inventory_groups_children(), 120); // 120 due to the html in ResourceGroupCompositeDataSource.getAlignedAvailabilityResults
+ ListGridField availabilityChildrenField = new ListGridField(AVAIL_CHILDREN.propertyName(),
+ AVAIL_CHILDREN.title(), 110); // 110 due to the html in ResourceGroupCompositeDataSource.getAlignedAvailabilityResults
+ availabilityChildrenField.setCanSortClientOnly(true);
+ availabilityChildrenField.setCanGroupBy(false);
availabilityChildrenField.setWrap(false);
availabilityChildrenField.setAlign(Alignment.CENTER);
- ListGridField availabilityDescendantsField = new ListGridField("availabilityDescendents", MSG
- .view_inventory_groups_descendants(), 120); // 120 due to the html in ResourceGroupCompositeDataSource.getAlignedAvailabilityResults
+ ListGridField availabilityDescendantsField = new ListGridField(AVAIL_DESCENDANTS.propertyName(),
+ AVAIL_DESCENDANTS.title(), 110); // 110 due to the html in ResourceGroupCompositeDataSource.getAlignedAvailabilityResults
+ availabilityDescendantsField.setCanSortClientOnly(true);
+ availabilityDescendantsField.setCanGroupBy(false);
availabilityDescendantsField.setWrap(false);
availabilityDescendantsField.setAlign(Alignment.CENTER);
commit e54d99073bde2530b55107987b0bfd60e3fb9b3d
Author: Ian Springer <ian.springer(a)redhat.com>
Date: Tue Sep 27 19:37:17 2011 -0400
fix typo in comment
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java
index 4bf2bae..af2d800 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java
@@ -370,7 +370,7 @@ public final class CriteriaQueryGenerator {
/*
* do not prefix the alias when:
*
- * 1) if the suffix is numerical, which allows usto sort by column ordinal
+ * 1) if the suffix is numerical, which allows us to sort by column ordinal
* 2) if the user wants full control and has explicitly chosen to disable alias prepending
*/
boolean doNotPrefixAlias = isNumber(suffix) || criteria.hasCustomizedSorting();
12 years, 8 months
[rhq] 3 commits - modules/enterprise modules/helpers
by lkrejci
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/DefaultImportConfigurationDescriptor.java | 2
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/ExportingInputStream.java | 100 -
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationConstants.java | 112 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerBean.java | 81 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/system/SystemManagerBean.java | 10
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/ExportingInputStreamTest.java | 23
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateExporterTest.java | 9
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SynchronizationManagerBeanTest.java | 534 ++++++++
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SystemSettingsExporterTest.java | 5
modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/ConfigurationInstanceDescriptorUtil.java | 650 ++++++----
modules/enterprise/server/xml-schemas/src/test/java/org/rhq/enterprise/server/xmlschema/ConfigurationInstanceDescriptorUtilTest.java | 212 +++
modules/helpers/perftest-support/data.sh | 2
modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/Exporter.java | 13
modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/dbsetup/DbSetup.java | 15
modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/dbunit/EntityRelationshipFilter.java | 98 +
modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/jpa/mapping/MappingTranslator.java | 4
modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/testng/DatabaseSetupInterceptor.java | 8
17 files changed, 1471 insertions(+), 407 deletions(-)
New commits:
commit 72430377515c26d205d7664485fcb69d19db14e4
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Sep 9 16:25:55 2011 +0200
BZ-735810 - make sure to reload the system config cache after its update.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/system/SystemManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/system/SystemManagerBean.java
index 86b690a..0dd0e72 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/system/SystemManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/system/SystemManagerBean.java
@@ -269,8 +269,6 @@ public class SystemManagerBean implements SystemManagerLocal, SystemManagerRemot
existingConfigMap.put(config.getPropertyKey(), config);
}
- Properties newCacheProperties = new Properties(); // create our own object - we don't want to reuse the caller's
-
// verify each new setting and persist them to the database
// note that if a new setting is the same as the old one, we do nothing - leave the old entity as is
for (Object key : properties.keySet()) {
@@ -281,8 +279,6 @@ public class SystemManagerBean implements SystemManagerLocal, SystemManagerRemot
verifyNewSystemConfigurationProperty(name, value, properties);
}
- newCacheProperties.setProperty(name, value);
-
SystemConfiguration existingConfig = existingConfigMap.get(name);
if (existingConfig == null) {
existingConfig = new SystemConfiguration(name, value);
@@ -301,7 +297,11 @@ public class SystemManagerBean implements SystemManagerLocal, SystemManagerRemot
}
}
- systemConfigurationCache = newCacheProperties;
+ //let the cache be reloaded once it's needed.
+ //we can't assume that the caller provided the full set of properties we
+ //have in the database, so let's just make sure we reinit the cache
+ //from there...
+ systemConfigurationCache = null;
}
@RequiredPermission(Permission.MANAGE_SETTINGS)
commit 23dbbe7d190dca3d25016ae0fdc0b833512ba806
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Sep 27 21:49:45 2011 +0200
Some amendments to the perftest-support database state export algorithms:
In case of no IDs specified from a table, explicitly read all the PK values from it. Don't try to optimize using "load-all" flag, because it just doesn't work well with figuring out relationships.
Some small optimizations to speed the slow data export process a little bit up.
Correctly handle @OneToOne
diff --git a/modules/helpers/perftest-support/data.sh b/modules/helpers/perftest-support/data.sh
index e7cccdf..b69805f 100755
--- a/modules/helpers/perftest-support/data.sh
+++ b/modules/helpers/perftest-support/data.sh
@@ -1,3 +1,3 @@
#!/bin/sh
-java -cp 'target/dependency/*':target/perftest-support-4.0.0-SNAPSHOT.jar org.rhq.helpers.perftest.support.Main $@
+java $JAVA_OPTS -cp 'target/dependency/*':target/perftest-support-4.1.0-SNAPSHOT.jar org.rhq.helpers.perftest.support.Main $@
diff --git a/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/Exporter.java b/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/Exporter.java
index e5cf3db..7e3c8fb 100644
--- a/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/Exporter.java
+++ b/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/Exporter.java
@@ -23,6 +23,8 @@ import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -36,6 +38,7 @@ import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.ReplacementDataSet;
import org.dbunit.dataset.stream.DataSetProducerAdapter;
import org.dbunit.dataset.stream.IDataSetConsumer;
+
import org.rhq.helpers.perftest.support.config.Entity;
import org.rhq.helpers.perftest.support.config.ExportConfiguration;
import org.rhq.helpers.perftest.support.dbunit.DbUnitUtil;
@@ -104,16 +107,14 @@ public class Exporter {
Set<ColumnValues> ret = new HashSet<ColumnValues>();
- if (query == null) {
- return null;
- }
-
IDataSet data = connection.createDataSet(new String[] { table });
-
Column[] tablePks = data.getTableMetaData(table).getPrimaryKeys();
-
String pkName = tablePks[0].getColumnName();
+ if (query == null) {
+ query = "SELECT " + pkName + " FROM " + table;
+ }
+
//the connection shouldn't be closed here, because we're just reusing an already existing one.
Connection jdbcConnection = connection.getConnection();
diff --git a/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/dbsetup/DbSetup.java b/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/dbsetup/DbSetup.java
index 3059c58..69ad14d 100644
--- a/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/dbsetup/DbSetup.java
+++ b/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/dbsetup/DbSetup.java
@@ -136,14 +136,17 @@ public class DbSetup {
private void setup() throws Exception {
DBSetup dbSetup = new DBSetup(connection);
- File schema = getFileFromResource(MINIMAL_VERSION_OF_SCHEMA, getClass().getClassLoader());
-
+ File minimalSchema = getFileFromResource(MINIMAL_VERSION_OF_SCHEMA, getClass().getClassLoader());
+ File currentSchema = getFileFromDbUtils("db-schema-combined.xml");
+
try {
- replaceTokensInFile(schema);
- dbSetup.uninstall(schema.getAbsolutePath());
- dbSetup.setup(schema.getAbsolutePath());
+ replaceTokensInFile(minimalSchema);
+ replaceTokensInFile(currentSchema);
+ dbSetup.uninstall(currentSchema.getAbsolutePath());
+ dbSetup.setup(minimalSchema.getAbsolutePath());
} finally {
- schema.delete();
+ minimalSchema.delete();
+ currentSchema.delete();
}
File data = getFileFromResource(MINIMAL_VERSION_OF_DATA, getClass().getClassLoader());
diff --git a/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/dbunit/EntityRelationshipFilter.java b/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/dbunit/EntityRelationshipFilter.java
index 0d6bf9a..e21719c 100644
--- a/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/dbunit/EntityRelationshipFilter.java
+++ b/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/dbunit/EntityRelationshipFilter.java
@@ -23,6 +23,7 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
+import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
@@ -177,7 +178,9 @@ public class EntityRelationshipFilter extends DatabaseSequenceFilter {
}
}
- resolvedPks.getOrCreate(node.getTranslation().getTableName()).addAll(unresolvedPks);
+ if (unresolvedPks != null) {
+ resolvedPks.getOrCreate(node.getTranslation().getTableName()).addAll(unresolvedPks);
+ }
for (Edge e : node.getOutgoingEdges()) {
//only include the dependents if the relationship
@@ -271,6 +274,24 @@ public class EntityRelationshipFilter extends DatabaseSequenceFilter {
}
}
+ //now translate the foreign keys into primary keys
+ //but first check if we even need to do it by comparing the column names
+ boolean columnsDiffer = false;
+ Set<String> pkColumns = new HashSet<String>(Arrays.asList(edge.getTo().getTranslation().getPkColumns()));
+
+ for(String col : translation.getToColumns()) {
+ if (!pkColumns.contains(col)) {
+ columnsDiffer = true;
+ break;
+ }
+ }
+
+ if (columnsDiffer) {
+ columnValues =
+ getValuesFromTable(connection, edge.getTo().getTranslation().getTableName(), edge.getTo()
+ .getTranslation().getPkColumns(), removeValuesWithNullColumn(columnValues));
+ }
+
Set<ColumnValues> ret = getValuesFromTable(connection, edge.getTo().getTranslation().getTableName(), edge
.getTo().getTranslation().getPkColumns(), columnValues);
@@ -299,11 +320,25 @@ public class EntityRelationshipFilter extends DatabaseSequenceFilter {
}
}
- //now translate the foreign keys into primary keys
EntityTranslation fromTranslation = edge.getFrom().getTranslation();
- columnValues = getValuesFromTable(connection, fromTranslation.getTableName(),
- fromTranslation.getPkColumns(), removeValuesWithNullColumn(columnValues));
+ //now translate the foreign keys into primary keys
+ //but first check if we even need to do it by comparing the column names
+ boolean columnsDiffer = false;
+ Set<String> pkColumns = new HashSet<String>(Arrays.asList(fromTranslation.getPkColumns()));
+
+ for(String col : translation.getFromColumns()) {
+ if (!pkColumns.contains(col)) {
+ columnsDiffer = true;
+ break;
+ }
+ }
+
+ if (columnsDiffer) {
+ columnValues = getValuesFromTable(connection, fromTranslation.getTableName(),
+ fromTranslation.getPkColumns(), removeValuesWithNullColumn(columnValues));
+ }
+
return removeValuesWithNullColumn(columnValues);
} else {
//only bother with one-to-many relationships. A many-to-many
@@ -408,47 +443,50 @@ public class EntityRelationshipFilter extends DatabaseSequenceFilter {
private static Set<ColumnValues> getValuesFromTable(IDatabaseConnection connection, String tableName,
String[] valueColumns, Set<ColumnValues> knownlColumns) throws SQLException {
- //I know, doing this one by one is super lame, but prevents the 1000 IN clause members limit of Oracle
- StringBuilder sqlCommon = new StringBuilder("SELECT ").append(colNamesToSql(valueColumns)).append(" FROM ")
+ StringBuilder sql = new StringBuilder("SELECT ").append(colNamesToSql(valueColumns)).append(" FROM ")
.append(tableName).append(" WHERE ");
Set<ColumnValues> ret = new HashSet<ColumnValues>();
-
+
for (ColumnValues cols : knownlColumns) {
- StringBuilder sql = new StringBuilder(sqlCommon);
+ sql.append("(");
for (ColumnValues.Column c : cols) {
sql.append(c.getName()).append(" = ? AND ");
}
- sql.replace(sql.length() - 4, sql.length(), "");
-
- PreparedStatement st = null;
- try {
- st = connection.getConnection().prepareStatement(sql.toString());
- int idx = 1;
+ sql.replace(sql.length() - 5, sql.length(), ") OR ");
+ }
+
+ sql.replace(sql.length() - 4, sql.length(), "");
+
+ PreparedStatement st = null;
+ try {
+ st = connection.getConnection().prepareStatement(sql.toString());
+ int idx = 1;
+ for (ColumnValues cols : knownlColumns) {
for (ColumnValues.Column c : cols) {
st.setObject(idx++, c.getValue());
}
+ }
+
+ ResultSet rs = st.executeQuery();
- ResultSet rs = st.executeQuery();
-
- ResultSetMetaData rsmd = rs.getMetaData();
-
- while (rs.next()) {
- ColumnValues vals = new ColumnValues();
+ ResultSetMetaData rsmd = rs.getMetaData();
- for (int i = 1; i <= rsmd.getColumnCount(); ++i) {
- String columnName = rsmd.getColumnName(i);
- Object value = rs.getObject(i);
- vals.add(columnName, value);
- }
+ while (rs.next()) {
+ ColumnValues vals = new ColumnValues();
- ret.add(vals);
- }
- } finally {
- if (st != null) {
- st.close();
+ for (int i = 1; i <= rsmd.getColumnCount(); ++i) {
+ String columnName = rsmd.getColumnName(i);
+ Object value = rs.getObject(i);
+ vals.add(columnName, value);
}
+
+ ret.add(vals);
+ }
+ } finally {
+ if (st != null) {
+ st.close();
}
}
diff --git a/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/jpa/mapping/MappingTranslator.java b/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/jpa/mapping/MappingTranslator.java
index 2d7f566..4a15734 100644
--- a/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/jpa/mapping/MappingTranslator.java
+++ b/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/jpa/mapping/MappingTranslator.java
@@ -304,8 +304,8 @@ public class MappingTranslator {
}
} else if (refCol.isEmpty()) {
//bidirectional with no referenced column definition.
- //the fkey is in the target table
- tCols[i] = fkey;
+ //the fkey is in the from table, referencing the pk in the target table
+ fCols[i] = fkey;
} else {
//bidirectional with referenced column definition.
//the fkey is in the from table, referencing the refCol
diff --git a/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/testng/DatabaseSetupInterceptor.java b/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/testng/DatabaseSetupInterceptor.java
index 52d0565..c4c7b8a 100644
--- a/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/testng/DatabaseSetupInterceptor.java
+++ b/modules/helpers/perftest-support/src/main/java/org/rhq/helpers/perftest/support/testng/DatabaseSetupInterceptor.java
@@ -168,6 +168,12 @@ public class DatabaseSetupInterceptor implements IInvokedMethodListener {
}
}
+/* Dropping the tables explicitly is a workaround around a problem in the perf tests
+ * but otherwise it should not be necessary at all.
+ * Even then, dropping the table in the beforeInvocation() should be enough and we
+ * shouldn't have to drop it again in the afterInvocation(). That is going to leave
+ * the database corrupted because it is going to miss this table altogether.
+ */
public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
DatabaseState state = getRequiredDatabaseState(method);
@@ -202,7 +208,7 @@ public class DatabaseSetupInterceptor implements IInvokedMethodListener {
}
-
+
/**
* Obtain the required database state by looking for the @DatabaseState annotation.
* Lookup is first done at method level and if not found done at class level.
commit 263a0f5cb9ba3eb562cc924460494f7f30757a8c
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Sep 27 21:12:18 2011 +0200
Added support for using the import configuration specified in the export
file during import.
To achieve that the export file schema now includes a new
"configuration-instance" schema, which is a combination of the existing
configuration definition schema and an ability to specify values
conforming to that definition.
Added unit tests and refactored the constants from ExportingInputStream
into a separate file so that they are in a more logical place.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/DefaultImportConfigurationDescriptor.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/DefaultImportConfigurationDescriptor.java
index 6b13150..f19aa18 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/DefaultImportConfigurationDescriptor.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/DefaultImportConfigurationDescriptor.java
@@ -28,7 +28,7 @@ import org.rhq.enterprise.server.xmlschema.generated.configuration.instance.Conf
*
* @author Lukas Krejci
*/
-@XmlRootElement(name = "default-configuration", namespace = ExportingInputStream.EXPORT_NAMESPACE)
+@XmlRootElement(name = "default-configuration", namespace = SynchronizationConstants.EXPORT_NAMESPACE)
public class DefaultImportConfigurationDescriptor extends ConfigurationInstanceDescriptor {
public DefaultImportConfigurationDescriptor() {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/ExportingInputStream.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/ExportingInputStream.java
index 49dc6bf..19734f6 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/ExportingInputStream.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/ExportingInputStream.java
@@ -26,15 +26,11 @@ import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.util.ArrayList;
-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.zip.GZIPOutputStream;
-import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
@@ -66,20 +62,6 @@ public class ExportingInputStream extends InputStream {
private static final Log LOG = LogFactory.getLog(ExportingInputStream.class);
- public static final String CONFIGURATION_NAMESPACE = "urn:xmlns:rhq-configuration";
- public static final String EXPORT_NAMESPACE = "urn:xmlns:rhq-configuration-export";
-
- public static final String CONFIGURATION_EXPORT_ELEMENT = "configuration-export";
- public static final String ENTITIES_EXPORT_ELEMENT = "entities";
- public static final String ENTITY_EXPORT_ELEMENT = "entity";
- public static final String ERROR_MESSAGE_ELEMENT = "error-message";
- public static final String NOTES_ELEMENT = "notes";
- public static final String DATA_ELEMENT = "data";
- public static final String VALIDATOR_ELEMENT = "validator";
- public static final String DEFAULT_CONFIGURATION_ELEMENT = "default-configuration";
- public static final String ID_ATTRIBUTE = "id";
- public static final String CLASS_ATTRIBUTE = "class";
-
private Set<Synchronizer<?, ?>> synchronizers;
private Map<String, ExporterMessages> messagesPerExporter;
private PipedInputStream inputStream;
@@ -255,67 +237,19 @@ public class ExportingInputStream extends InputStream {
* @throws XMLStreamException
*/
private void exportPrologue(XMLStreamWriter wrt) throws XMLStreamException {
- wrt.setDefaultNamespace(EXPORT_NAMESPACE);
- wrt.setPrefix(XMLConstants.DEFAULT_NS_PREFIX, EXPORT_NAMESPACE);
- wrt.setPrefix("ci", ConfigurationInstanceDescriptorUtil.NS_CONFIGURATION_INSTANCE);
- wrt.setPrefix("c", CONFIGURATION_NAMESPACE);
+ wrt.setDefaultNamespace(SynchronizationConstants.EXPORT_NAMESPACE);
+ wrt.setPrefix(SynchronizationConstants.EXPORT_NAMESPACE_PREFIX, SynchronizationConstants.EXPORT_NAMESPACE);
+ wrt.setPrefix(SynchronizationConstants.CONFIGURATION_INSTANCE_NAMESPACE_PREFIX, SynchronizationConstants.CONFIGURATION_INSTANCE_NAMESPACE);
+ wrt.setPrefix(SynchronizationConstants.CONFIGURATION_NAMESPACE_PREFIX, SynchronizationConstants.CONFIGURATION_NAMESPACE);
- NamespaceContext nsContext = new NamespaceContext() {
-
- //this map has to correspond to the namespaces defined in the code above
- private final Map<String, String> PREFIXES = new HashMap<String, String>();
- {
- PREFIXES.put(XMLConstants.DEFAULT_NS_PREFIX, EXPORT_NAMESPACE);
- PREFIXES.put("ci", ConfigurationInstanceDescriptorUtil.NS_CONFIGURATION_INSTANCE);
- PREFIXES.put("c", CONFIGURATION_NAMESPACE);
- }
-
- @Override
- public Iterator<String> getPrefixes(String namespaceURI) {
- String prefix = getPrefix(namespaceURI);
- if (prefix == null) {
- return Collections.<String> emptySet().iterator();
- } else {
- return Collections.singleton(prefix).iterator();
- }
- }
-
- @Override
- public String getPrefix(String namespaceURI) {
- if (namespaceURI == null) {
- throw new IllegalArgumentException();
- } else if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(namespaceURI)) {
- return XMLConstants.XMLNS_ATTRIBUTE;
- } else if (XMLConstants.XML_NS_URI.equals(namespaceURI)) {
- return XMLConstants.XML_NS_PREFIX;
- } else {
- String prefix = null;
- for (Map.Entry<String, String> e : PREFIXES.entrySet()) {
- String p = e.getKey();
- String namespace = e.getValue();
-
- if (namespaceURI.equals(namespace)) {
- prefix = p;
- break;
- }
- }
-
- return prefix;
- }
- }
-
- @Override
- public String getNamespaceURI(String prefix) {
- return PREFIXES.get(prefix);
- }
- };
+ NamespaceContext nsContext = SynchronizationConstants.createConfigurationExportNamespaceContext();
wrt.setNamespaceContext(nsContext);
wrt.writeStartDocument();
- wrt.writeStartElement(EXPORT_NAMESPACE, CONFIGURATION_EXPORT_ELEMENT);
- wrt.writeNamespace("ci", ConfigurationInstanceDescriptorUtil.NS_CONFIGURATION_INSTANCE);
- wrt.writeNamespace("c", CONFIGURATION_NAMESPACE);
+ wrt.writeStartElement(SynchronizationConstants.EXPORT_NAMESPACE, SynchronizationConstants.CONFIGURATION_EXPORT_ELEMENT);
+ wrt.writeNamespace(SynchronizationConstants.CONFIGURATION_INSTANCE_NAMESPACE_PREFIX, ConfigurationInstanceDescriptorUtil.NS_CONFIGURATION_INSTANCE);
+ wrt.writeNamespace(SynchronizationConstants.CONFIGURATION_NAMESPACE_PREFIX, SynchronizationConstants.CONFIGURATION_NAMESPACE);
writeValidators(wrt);
}
@@ -331,8 +265,8 @@ public class ExportingInputStream extends InputStream {
}
for (ConsistencyValidator cv : allValidators) {
- wrt.writeStartElement(VALIDATOR_ELEMENT);
- wrt.writeAttribute(CLASS_ATTRIBUTE, cv.getClass().getName());
+ wrt.writeStartElement(SynchronizationConstants.VALIDATOR_ELEMENT);
+ wrt.writeAttribute(SynchronizationConstants.CLASS_ATTRIBUTE, cv.getClass().getName());
cv.exportState(new ExportWriter(wrt));
wrt.writeEndElement();
}
@@ -357,8 +291,8 @@ public class ExportingInputStream extends InputStream {
messagesPerExporter.put(syn.getClass().getName(), messages);
- wrt.writeStartElement(EXPORT_NAMESPACE, ENTITIES_EXPORT_ELEMENT);
- wrt.writeAttribute(ID_ATTRIBUTE, syn.getClass().getName());
+ wrt.writeStartElement(SynchronizationConstants.EXPORT_NAMESPACE, SynchronizationConstants.ENTITIES_EXPORT_ELEMENT);
+ wrt.writeAttribute(SynchronizationConstants.ID_ATTRIBUTE, syn.getClass().getName());
Exporter<?, ?> exp = syn.getExporter();
ExportingIterator<?> it = exp.getExportingIterator();
@@ -379,9 +313,9 @@ public class ExportingInputStream extends InputStream {
while (it.hasNext()) {
it.next();
- wrt.writeStartElement(EXPORT_NAMESPACE, ENTITY_EXPORT_ELEMENT);
+ wrt.writeStartElement(SynchronizationConstants.EXPORT_NAMESPACE, SynchronizationConstants.ENTITY_EXPORT_ELEMENT);
- wrt.writeStartElement(EXPORT_NAMESPACE, DATA_ELEMENT);
+ wrt.writeStartElement(SynchronizationConstants.EXPORT_NAMESPACE, SynchronizationConstants.DATA_ELEMENT);
Exception exportError = null;
try {
@@ -400,14 +334,14 @@ public class ExportingInputStream extends InputStream {
if (notes != null) {
messages.getPerEntityNotes().add(notes);
- wrt.writeStartElement(EXPORT_NAMESPACE, NOTES_ELEMENT);
+ wrt.writeStartElement(SynchronizationConstants.EXPORT_NAMESPACE, SynchronizationConstants.NOTES_ELEMENT);
wrt.writeCharacters(notes);
wrt.writeEndElement();
}
} else {
String message = ThrowableUtil.getStackAsString(exportError);
messages.getPerEntityErrorMessages().add(message);
- wrt.writeStartElement(EXPORT_NAMESPACE, ERROR_MESSAGE_ELEMENT);
+ wrt.writeStartElement(SynchronizationConstants.EXPORT_NAMESPACE, SynchronizationConstants.ERROR_MESSAGE_ELEMENT);
wrt.writeCharacters(message);
wrt.writeEndElement();
}
@@ -420,7 +354,7 @@ public class ExportingInputStream extends InputStream {
messages.setExporterNotes(notes);
if (notes != null) {
- wrt.writeStartElement(EXPORT_NAMESPACE, NOTES_ELEMENT);
+ wrt.writeStartElement(SynchronizationConstants.EXPORT_NAMESPACE, SynchronizationConstants.NOTES_ELEMENT);
wrt.writeCharacters(notes);
wrt.writeEndElement();
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationConstants.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationConstants.java
new file mode 100644
index 0000000..c8be2dd
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationConstants.java
@@ -0,0 +1,112 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.enterprise.server.sync;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.NamespaceContext;
+
+import org.rhq.enterprise.server.xmlschema.ConfigurationInstanceDescriptorUtil;
+
+/**
+ *
+ *
+ * @author Lukas Krejci
+ */
+public final class SynchronizationConstants {
+
+ public static final String CONFIGURATION_NAMESPACE = "urn:xmlns:rhq-configuration";
+ public static final String CONFIGURATION_NAMESPACE_PREFIX = "c";
+ public static final String CONFIGURATION_INSTANCE_NAMESPACE =
+ ConfigurationInstanceDescriptorUtil.NS_CONFIGURATION_INSTANCE;
+ public static final String CONFIGURATION_INSTANCE_NAMESPACE_PREFIX = "ci";
+ public static final String EXPORT_NAMESPACE = "urn:xmlns:rhq-configuration-export";
+ public static final String EXPORT_NAMESPACE_PREFIX = XMLConstants.DEFAULT_NS_PREFIX;
+ public static final String CONFIGURATION_EXPORT_ELEMENT = "configuration-export";
+ public static final String ENTITIES_EXPORT_ELEMENT = "entities";
+ public static final String ENTITY_EXPORT_ELEMENT = "entity";
+ public static final String ERROR_MESSAGE_ELEMENT = "error-message";
+ public static final String NOTES_ELEMENT = "notes";
+ public static final String DATA_ELEMENT = "data";
+ public static final String VALIDATOR_ELEMENT = "validator";
+ public static final String DEFAULT_CONFIGURATION_ELEMENT = "default-configuration";
+ public static final String ID_ATTRIBUTE = "id";
+ public static final String CLASS_ATTRIBUTE = "class";
+
+ private SynchronizationConstants() {
+
+ }
+
+ public static NamespaceContext createConfigurationExportNamespaceContext() {
+ return new NamespaceContext() {
+
+ //this map has to correspond to the namespaces defined in the code above
+ private final Map<String, String> PREFIXES = new HashMap<String, String>();
+ {
+ PREFIXES.put(EXPORT_NAMESPACE_PREFIX, EXPORT_NAMESPACE);
+ PREFIXES.put(CONFIGURATION_INSTANCE_NAMESPACE_PREFIX, CONFIGURATION_INSTANCE_NAMESPACE);
+ PREFIXES.put(CONFIGURATION_NAMESPACE_PREFIX, CONFIGURATION_NAMESPACE);
+ }
+
+ @Override
+ public Iterator<String> getPrefixes(String namespaceURI) {
+ String prefix = getPrefix(namespaceURI);
+ if (prefix == null) {
+ return Collections.<String> emptySet().iterator();
+ } else {
+ return Collections.singleton(prefix).iterator();
+ }
+ }
+
+ @Override
+ public String getPrefix(String namespaceURI) {
+ if (namespaceURI == null) {
+ throw new IllegalArgumentException();
+ } else if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(namespaceURI)) {
+ return XMLConstants.XMLNS_ATTRIBUTE;
+ } else if (XMLConstants.XML_NS_URI.equals(namespaceURI)) {
+ return XMLConstants.XML_NS_PREFIX;
+ } else {
+ String prefix = null;
+ for (Map.Entry<String, String> e : PREFIXES.entrySet()) {
+ String p = e.getKey();
+ String namespace = e.getValue();
+
+ if (namespaceURI.equals(namespace)) {
+ prefix = p;
+ break;
+ }
+ }
+
+ return prefix;
+ }
+ }
+
+ @Override
+ public String getNamespaceURI(String prefix) {
+ return PREFIXES.get(prefix);
+ }
+ };
+ }
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerBean.java
index c036dd6..af848b1 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/sync/SynchronizationManagerBean.java
@@ -42,6 +42,9 @@ import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
@@ -66,6 +69,7 @@ import org.rhq.enterprise.server.sync.importers.ExportedEntityMatcher;
import org.rhq.enterprise.server.sync.importers.Importer;
import org.rhq.enterprise.server.sync.validators.ConsistencyValidator;
import org.rhq.enterprise.server.sync.validators.InconsistentStateException;
+import org.rhq.enterprise.server.xmlschema.ConfigurationInstanceDescriptorUtil;
/**
*
@@ -80,6 +84,16 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
@PersistenceContext(unitName = RHQConstants.PERSISTENCE_UNIT_NAME)
private EntityManager entityManager;
+ private JAXBContext defaultImportConfigurationJAXBContext;
+
+ public SynchronizationManagerBean() {
+ try {
+ defaultImportConfigurationJAXBContext = JAXBContext.newInstance(DefaultImportConfigurationDescriptor.class);
+ } catch (JAXBException e) {
+ throw new IllegalStateException("Failed to create DefaultImportConfigurationDescriptor unmarshaller. This should never happen.");
+ }
+ }
+
@Override
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
@RequiredPermission(Permission.MANAGE_INVENTORY)
@@ -241,9 +255,9 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
switch (rdr.next()) {
case XMLStreamConstants.START_ELEMENT:
String tagName = rdr.getName().getLocalPart();
- if (ExportingInputStream.VALIDATOR_ELEMENT.equals(tagName)) {
+ if (SynchronizationConstants.VALIDATOR_ELEMENT.equals(tagName)) {
ConsistencyValidator validator = null;
- String validatorClass = rdr.getAttributeValue(null, ExportingInputStream.CLASS_ATTRIBUTE);
+ String validatorClass = rdr.getAttributeValue(null, SynchronizationConstants.CLASS_ATTRIBUTE);
try {
validator = validateSingle(rdr, subject);
} catch (Exception e) {
@@ -253,10 +267,10 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
if (validator != null) {
executedValidators.add(validator);
}
- } else if (ExportingInputStream.ENTITIES_EXPORT_ELEMENT.equals(tagName)) {
+ } else if (SynchronizationConstants.ENTITIES_EXPORT_ELEMENT.equals(tagName)) {
//all the validators preceed the importers in the export file so we can now check if the
//validator was already run
- String synchronizerClass = rdr.getAttributeValue(null, ExportingInputStream.ID_ATTRIBUTE);
+ String synchronizerClass = rdr.getAttributeValue(null, SynchronizationConstants.ID_ATTRIBUTE);
try {
failures.addAll(validateEntities(rdr, subject, executedValidators));
} catch (Exception e) {
@@ -278,7 +292,7 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
private Set<ConsistencyValidatorFailureReport> validateEntities(XMLStreamReader rdr, Subject subject,
Set<ConsistencyValidator> executedValidators) throws Exception {
- String synchronizerClass = rdr.getAttributeValue(null, ExportingInputStream.ID_ATTRIBUTE);
+ String synchronizerClass = rdr.getAttributeValue(null, SynchronizationConstants.ID_ATTRIBUTE);
HashSet<ConsistencyValidatorFailureReport> ret = new HashSet<ConsistencyValidatorFailureReport>();
Synchronizer<?, ?> synchronizer = instantiate(synchronizerClass, Synchronizer.class,
@@ -309,7 +323,7 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
boolean bailout = false;
switch (rdr.next()) {
case XMLStreamConstants.START_ELEMENT:
- if (ExportingInputStream.DATA_ELEMENT.equals(rdr.getName().getLocalPart())) {
+ if (SynchronizationConstants.DATA_ELEMENT.equals(rdr.getName().getLocalPart())) {
rdr.nextTag();
Object exportedEntity = importer.unmarshallExportedEntity(new ExportReader(rdr));
Class<?> exportedEntityClass = exportedEntity.getClass();
@@ -340,7 +354,7 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
}
break;
case XMLStreamConstants.END_ELEMENT:
- if (ExportingInputStream.ENTITIES_EXPORT_ELEMENT.equals(rdr.getName().getLocalPart())) {
+ if (SynchronizationConstants.ENTITIES_EXPORT_ELEMENT.equals(rdr.getName().getLocalPart())) {
bailout = true;
}
}
@@ -361,7 +375,7 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
switch (rdr.next()) {
case XMLStreamReader.START_ELEMENT:
String tagName = rdr.getName().getLocalPart();
- if (ExportingInputStream.ENTITIES_EXPORT_ELEMENT.equals(tagName)) {
+ if (SynchronizationConstants.ENTITIES_EXPORT_ELEMENT.equals(tagName)) {
try {
importSingle(subject, importerConfigs, rdr);
} catch (Exception e) {
@@ -380,7 +394,7 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
private ConsistencyValidator validateSingle(XMLStreamReader rdr, Subject subject) throws InstantiationException,
IllegalAccessException, ClassNotFoundException, XMLStreamException, InconsistentStateException {
- String validatorClassName = rdr.getAttributeValue(null, ExportingInputStream.CLASS_ATTRIBUTE);
+ String validatorClassName = rdr.getAttributeValue(null, SynchronizationConstants.CLASS_ATTRIBUTE);
ConsistencyValidator validator = instantiate(
validatorClassName,
ConsistencyValidator.class,
@@ -398,7 +412,7 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
private <E, X> void importSingle(Subject subject, Map<String, Configuration> importConfigs, XMLStreamReader rdr)
throws Exception {
- String synchronizerClassName = rdr.getAttributeValue(null, ExportingInputStream.ID_ATTRIBUTE);
+ String synchronizerClassName = rdr.getAttributeValue(null, SynchronizationConstants.ID_ATTRIBUTE);
@SuppressWarnings("unchecked")
Synchronizer<E, X> synchronizer = instantiate(synchronizerClassName, Synchronizer.class,
@@ -407,15 +421,39 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
synchronizer.initialize(subject, entityManager);
Importer<E, X> importer = synchronizer.getImporter();
- importer.configure(importConfigs.get(synchronizerClassName));
- ExportedEntityMatcher<E, X> matcher = importer.getExportedEntityMatcher();
+ ExportedEntityMatcher<E, X> matcher = null; //this will be initialized once the importer is configured
+ boolean configured = false;
+ Configuration importConfiguration = importConfigs.get(synchronizerClassName);
+
+ //the passed in configuration has precedence over the default one inlined in
+ //the config file.
+ if (importConfiguration != null) {
+ importer.configure(importConfiguration);
+ matcher = importer.getExportedEntityMatcher();
+ configured = true;
+ }
+
while (rdr.hasNext()) {
boolean bailout = false;
switch (rdr.next()) {
case XMLStreamConstants.START_ELEMENT:
- if (ExportingInputStream.DATA_ELEMENT.equals(rdr.getName().getLocalPart())) {
+ if (SynchronizationConstants.DEFAULT_CONFIGURATION_ELEMENT.equals(rdr.getName().getLocalPart())) {
+ if (!configured) {
+ importConfiguration = getDefaultConfiguration(rdr);
+ }
+ } else if (SynchronizationConstants.DATA_ELEMENT.equals(rdr.getName().getLocalPart())) {
+
+ //first check if the configure method has been called
+ if (!configured) {
+ importer.configure(importConfiguration);
+ matcher = importer.getExportedEntityMatcher();
+ configured = true;
+ }
+
+ //now do the import
+
rdr.nextTag();
X exportedEntity = importer.unmarshallExportedEntity(new ExportReader(rdr));
E entity = matcher == null ? null : matcher.findMatch(exportedEntity);
@@ -423,7 +461,7 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
}
break;
case XMLStreamConstants.END_ELEMENT:
- if (ExportingInputStream.ENTITIES_EXPORT_ELEMENT.equals(rdr.getName().getLocalPart())) {
+ if (SynchronizationConstants.ENTITIES_EXPORT_ELEMENT.equals(rdr.getName().getLocalPart())) {
bailout = true;
}
}
@@ -433,6 +471,12 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
}
}
+ //we might have had no data and because we configure the importer lazily, it might
+ //be left unconfigured by the above loop.
+ if (!configured) {
+ importer.configure(importConfiguration);
+ }
+
importer.finishImport();
}
@@ -466,4 +510,13 @@ public class SynchronizationManagerBean implements SynchronizationManagerLocal,
return ret;
}
+
+ private Configuration getDefaultConfiguration(XMLStreamReader rdr) throws JAXBException {
+ Unmarshaller unmarshaller = defaultImportConfigurationJAXBContext.createUnmarshaller();
+ DefaultImportConfigurationDescriptor descriptor = (DefaultImportConfigurationDescriptor) unmarshaller.unmarshal(rdr);
+
+ ConfigurationInstanceDescriptorUtil.ConfigurationAndDefinition ccd = ConfigurationInstanceDescriptorUtil.createConfigurationAndDefinition(descriptor);
+
+ return ccd.configuration;
+ }
}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/ExportingInputStreamTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/ExportingInputStreamTest.java
index 1359bee..975e6d3 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/ExportingInputStreamTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/ExportingInputStreamTest.java
@@ -57,6 +57,7 @@ import org.rhq.enterprise.server.sync.ExportReader;
import org.rhq.enterprise.server.sync.ExportWriter;
import org.rhq.enterprise.server.sync.ExportingInputStream;
import org.rhq.enterprise.server.sync.NoSingleEntity;
+import org.rhq.enterprise.server.sync.SynchronizationConstants;
import org.rhq.enterprise.server.sync.Synchronizer;
import org.rhq.enterprise.server.sync.exporters.AbstractDelegatingExportingIterator;
import org.rhq.enterprise.server.sync.exporters.Exporter;
@@ -207,9 +208,9 @@ public class ExportingInputStreamTest extends JMockTest {
Element root = doc.getDocumentElement();
- assertEquals(ExportingInputStream.CONFIGURATION_EXPORT_ELEMENT, root.getNodeName());
+ assertEquals(SynchronizationConstants.CONFIGURATION_EXPORT_ELEMENT, root.getNodeName());
- NodeList entities = root.getElementsByTagName(ExportingInputStream.ENTITIES_EXPORT_ELEMENT);
+ NodeList entities = root.getElementsByTagName(SynchronizationConstants.ENTITIES_EXPORT_ELEMENT);
assertEquals(entities.getLength(), 2, "Unexpected number of entities elements");
Element export1 = (Element) entities.item(0);
@@ -228,32 +229,32 @@ public class ExportingInputStreamTest extends JMockTest {
Element entitiesElement = (Element) node;
- assertEquals(entitiesElement.getNodeName(), ExportingInputStream.ENTITIES_EXPORT_ELEMENT);
+ assertEquals(entitiesElement.getNodeName(), SynchronizationConstants.ENTITIES_EXPORT_ELEMENT);
- NodeList errorMessages = entitiesElement.getElementsByTagName(ExportingInputStream.ERROR_MESSAGE_ELEMENT);
+ NodeList errorMessages = entitiesElement.getElementsByTagName(SynchronizationConstants.ERROR_MESSAGE_ELEMENT);
assertEquals(errorMessages.getLength(), 0, "Unexpected number of error message elements in an entities export.");
- Node note = getDirectChildByTagName(entitiesElement, ExportingInputStream.NOTES_ELEMENT);
+ Node note = getDirectChildByTagName(entitiesElement, SynchronizationConstants.NOTES_ELEMENT);
assertNotNull(note, "Couldn't find exporter notes.");
String notesText = ((Element)note).getTextContent();
assertEquals(notesText, expectedNotes[elementIndex], "Unexpected notes for entities.");
- NodeList entityElements = entitiesElement.getElementsByTagName(ExportingInputStream.ENTITY_EXPORT_ELEMENT);
+ NodeList entityElements = entitiesElement.getElementsByTagName(SynchronizationConstants.ENTITY_EXPORT_ELEMENT);
assertEquals(entityElements.getLength(), 3, "Unexpected number of exported entities.");
for(int j = 0; j < entityElements.getLength(); ++j) {
Element entityElement = (Element) entityElements.item(j);
- errorMessages = entityElement.getElementsByTagName(ExportingInputStream.ERROR_MESSAGE_ELEMENT);
+ errorMessages = entityElement.getElementsByTagName(SynchronizationConstants.ERROR_MESSAGE_ELEMENT);
assertEquals(errorMessages.getLength(), 0, "Unexpected number of error message elements in an entity.");
- note = getDirectChildByTagName(entityElement, ExportingInputStream.NOTES_ELEMENT);
+ note = getDirectChildByTagName(entityElement, SynchronizationConstants.NOTES_ELEMENT);
assertNotNull(note, "Could not find notes for an exported entity.");
- Node data = getDirectChildByTagName(entityElement, ExportingInputStream.DATA_ELEMENT);
+ Node data = getDirectChildByTagName(entityElement, SynchronizationConstants.DATA_ELEMENT);
assertNotNull(data, "Could not find data element in the entity.");
String dataText = ((Element)data).getTextContent();
@@ -404,13 +405,13 @@ public class ExportingInputStreamTest extends JMockTest {
Element root = doc.getDocumentElement();
- NodeList entities = root.getElementsByTagName(ExportingInputStream.ENTITY_EXPORT_ELEMENT);
+ NodeList entities = root.getElementsByTagName(SynchronizationConstants.ENTITY_EXPORT_ELEMENT);
assertEquals(entities.getLength(), 2, "Unexpected number of exported elements");
//get the entity with the error
Element failedEntity = (Element) entities.item(1);
- Node errorMessage = getDirectChildByTagName(failedEntity, ExportingInputStream.ERROR_MESSAGE_ELEMENT);
+ Node errorMessage = getDirectChildByTagName(failedEntity, SynchronizationConstants.ERROR_MESSAGE_ELEMENT);
assertNotNull(errorMessage, "Could not find the error-message element at the entity that failed to export.");
}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateExporterTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateExporterTest.java
index 70819af..34de39e 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateExporterTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/MetricTemplateExporterTest.java
@@ -60,6 +60,7 @@ import org.rhq.enterprise.server.measurement.MeasurementScheduleManagerLocal;
import org.rhq.enterprise.server.resource.metadata.PluginManagerLocal;
import org.rhq.enterprise.server.sync.ExportingInputStream;
import org.rhq.enterprise.server.sync.MetricTemplateSynchronizer;
+import org.rhq.enterprise.server.sync.SynchronizationConstants;
import org.rhq.enterprise.server.sync.Synchronizer;
import org.rhq.enterprise.server.sync.validators.ConsistencyValidator;
import org.rhq.test.JMockTest;
@@ -131,14 +132,14 @@ public class MetricTemplateExporterTest extends JMockTest {
Element root = doc.getDocumentElement();
- List<Node> validators = getDirectChildrenByTagName(root, ExportingInputStream.VALIDATOR_ELEMENT);
+ List<Node> validators = getDirectChildrenByTagName(root, SynchronizationConstants.VALIDATOR_ELEMENT);
Set<ConsistencyValidator> declaredValidators = exporter.getRequiredValidators();
assertEquals(validators.size(), declaredValidators.size(), "Unexpected number of validators in the export xml");
for (Node v : validators) {
Element validator = (Element) v;
- String cls = validator.getAttribute(ExportingInputStream.CLASS_ATTRIBUTE);
+ String cls = validator.getAttribute(SynchronizationConstants.CLASS_ATTRIBUTE);
boolean found = false;
for (ConsistencyValidator dv : declaredValidators) {
@@ -152,9 +153,9 @@ public class MetricTemplateExporterTest extends JMockTest {
+ ", but one such appeared in the export");
}
- Element entities = (Element) getFirstDirectChildByTagName(root, ExportingInputStream.ENTITIES_EXPORT_ELEMENT);
+ Element entities = (Element) getFirstDirectChildByTagName(root, SynchronizationConstants.ENTITIES_EXPORT_ELEMENT);
- assertEquals(entities.getAttribute(ExportingInputStream.ID_ATTRIBUTE), MetricTemplateSynchronizer.class.getName(), "Unexpected id of the entities element.");
+ assertEquals(entities.getAttribute(SynchronizationConstants.ID_ATTRIBUTE), MetricTemplateSynchronizer.class.getName(), "Unexpected id of the entities element.");
NodeList metricTemplates = entities.getElementsByTagName("metricTemplate");
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SynchronizationManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SynchronizationManagerBeanTest.java
new file mode 100644
index 0000000..5338913
--- /dev/null
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SynchronizationManagerBeanTest.java
@@ -0,0 +1,534 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.enterprise.server.sync.test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.UUID;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+import javax.persistence.EntityManager;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathFactory;
+
+import org.testng.annotations.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.criteria.MeasurementDefinitionCriteria;
+import org.rhq.core.domain.criteria.ResourceCriteria;
+import org.rhq.core.domain.measurement.DataType;
+import org.rhq.core.domain.measurement.DisplayType;
+import org.rhq.core.domain.measurement.MeasurementCategory;
+import org.rhq.core.domain.measurement.MeasurementDefinition;
+import org.rhq.core.domain.measurement.MeasurementSchedule;
+import org.rhq.core.domain.measurement.MeasurementUnits;
+import org.rhq.core.domain.resource.InventoryStatus;
+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.sync.ExportReport;
+import org.rhq.core.domain.sync.ImportConfiguration;
+import org.rhq.core.domain.util.PageControl;
+import org.rhq.enterprise.server.auth.SubjectManagerLocal;
+import org.rhq.enterprise.server.authz.PermissionException;
+import org.rhq.enterprise.server.measurement.MeasurementDefinitionManagerLocal;
+import org.rhq.enterprise.server.measurement.MeasurementScheduleManagerLocal;
+import org.rhq.enterprise.server.resource.ResourceManagerLocal;
+import org.rhq.enterprise.server.sync.MetricTemplateSynchronizer;
+import org.rhq.enterprise.server.sync.SynchronizationConstants;
+import org.rhq.enterprise.server.sync.SynchronizationManagerLocal;
+import org.rhq.enterprise.server.sync.SystemSettingsSynchronizer;
+import org.rhq.enterprise.server.system.SystemManagerLocal;
+import org.rhq.enterprise.server.test.AbstractEJB3Test;
+import org.rhq.enterprise.server.util.LookupUtil;
+
+/**
+ * Tests the SynchronizationManagerBean on a live dataset.
+ *
+ * @author Lukas Krejci
+ */
+@Test
+public class SynchronizationManagerBeanTest extends AbstractEJB3Test {
+
+ private SynchronizationManagerLocal synchronizationManager;
+ private Subject user;
+ private ExportReport export;
+
+ private static final String RESOURCE_TYPE_NAME = "SynchronizationManagerBeanTest";
+ private static final String PLUGIN_NAME = "SynchronizationManagerBeanTest";
+ private static final String METRIC_NAME = "SynchronizationManagerBeanTest";
+
+ private static class DBChanges {
+ public Properties systemSettings;
+ public ResourceType fakeType;
+ public Resource fakePlatform;
+ }
+
+ private DBChanges dbChanges;
+
+ //I just don't get why this can't be a @BeforeTest
+ //but when it was declared as such (together with tearDown() being an @AfterTest)
+ //no tests would work. I have no idea why...
+ private void setup() throws Exception {
+ dbChanges = new DBChanges();
+ getTransactionManager().begin();
+ try {
+ EntityManager em = getEntityManager();
+
+ //add our new metric template that we are going to perform the tests with
+ dbChanges.fakeType = new ResourceType(RESOURCE_TYPE_NAME, PLUGIN_NAME, ResourceCategory.PLATFORM, null);
+
+ MeasurementDefinition mdef =
+ new MeasurementDefinition(METRIC_NAME, MeasurementCategory.PERFORMANCE, MeasurementUnits.NONE,
+ DataType.MEASUREMENT, true, 600000, DisplayType.SUMMARY);
+ dbChanges.fakeType.addMetricDefinition(mdef);
+
+ em.persist(dbChanges.fakeType);
+
+ dbChanges.fakePlatform = new Resource(RESOURCE_TYPE_NAME, RESOURCE_TYPE_NAME, dbChanges.fakeType);
+ dbChanges.fakePlatform.setUuid(UUID.randomUUID().toString());
+ dbChanges.fakePlatform.setInventoryStatus(InventoryStatus.COMMITTED);
+
+ MeasurementSchedule sched = new MeasurementSchedule(mdef, dbChanges.fakePlatform);
+ sched.setInterval(600000);
+
+ dbChanges.fakePlatform.addSchedule(sched);
+
+ em.persist(dbChanges.fakePlatform);
+
+ em.persist(sched);
+
+ em.flush();
+
+ getTransactionManager().commit();
+ } catch (Exception e) {
+ getTransactionManager().rollback();
+ throw e;
+ }
+
+ synchronizationManager = LookupUtil.getSynchronizationManager();
+
+ SystemManagerLocal systemManager = LookupUtil.getSystemManager();
+ //make sure the system manager is in sync w/ the db we just changed in dbsetup
+ systemManager.loadSystemConfigurationCache();
+
+ dbChanges.systemSettings = systemManager.getSystemConfiguration(freshUser());
+ export = synchronizationManager.exportAllSubsystems(freshUser());
+ }
+
+ private void tearDown() throws Exception {
+ getTransactionManager().begin();
+ try {
+ LookupUtil.getSystemManager().setSystemConfiguration(freshUser(), dbChanges.systemSettings, true);
+
+ EntityManager em = getEntityManager();
+
+ MeasurementSchedule sched =
+ em.find(MeasurementSchedule.class, dbChanges.fakePlatform.getSchedules().iterator().next().getId());
+ em.remove(sched);
+
+ Resource attachedPlatform = em.find(Resource.class, dbChanges.fakePlatform.getId());
+ em.remove(attachedPlatform);
+
+ ResourceType attachedType = em.find(ResourceType.class, dbChanges.fakeType.getId());
+ em.remove(attachedType);
+
+ getTransactionManager().commit();
+ } catch (Exception e) {
+ getTransactionManager().rollback();
+ throw e;
+ }
+
+ export = null;
+ dbChanges = null;
+ synchronizationManager = null;
+ }
+
+ public void testExport() throws Exception {
+ setup();
+ try {
+ assertNull("Export shouldn't generate an error message.", export.getErrorMessage());
+ assertTrue("The export should contain some data.", export.getExportFile().length > 0);
+ } finally {
+ tearDown();
+ }
+ }
+
+ public void testImportWithDefaultConfiguration() throws Exception {
+ setup();
+
+ try {
+ SystemManagerLocal systemManager = LookupUtil.getSystemManager();
+ MeasurementDefinitionManagerLocal measurementDefinitionManager =
+ LookupUtil.getMeasurementDefinitionManager();
+
+ Properties beforeSystemSettings = systemManager.getSystemConfiguration(freshUser());
+ MeasurementDefinitionCriteria criteria = new MeasurementDefinitionCriteria();
+ criteria.setPageControl(PageControl.getUnlimitedInstance());
+ criteria.fetchResourceType(true);
+
+ List<MeasurementDefinition> beforeMeasurementDefinitions =
+ measurementDefinitionManager.findMeasurementDefinitionsByCriteria(freshUser(), criteria);
+
+ synchronizationManager.importAllSubsystems(freshUser(), export.getExportFile(), null);
+
+ //this is to work around BZ 735810
+ systemManager.loadSystemConfigurationCache();
+
+ Properties afterSystemSettings = systemManager.getSystemConfiguration(freshUser());
+ List<MeasurementDefinition> afterMeasurementDefinitions =
+ measurementDefinitionManager.findMeasurementDefinitionsByCriteria(freshUser(), criteria);
+
+ assertEquals("System settings unexpectedly differ", beforeSystemSettings, afterSystemSettings);
+
+ //make sure we don't fail on simple order differences, which are not important here..
+ Set<MeasurementDefinition> beforeDefsToCheck =
+ new HashSet<MeasurementDefinition>(beforeMeasurementDefinitions);
+ Set<MeasurementDefinition> afterDefsToCheck =
+ new HashSet<MeasurementDefinition>(afterMeasurementDefinitions);
+ assertEquals("Measurement definitions unexpectedly differ", beforeDefsToCheck, afterDefsToCheck);
+ } finally {
+ tearDown();
+ }
+ }
+
+ public void testImportWithRedefinedConfigurationInExportFile() throws Exception {
+ setup();
+
+ try {
+ String exportXML = getExportData();
+
+ exportXML = updateSystemSettingsImportConfiguration(exportXML);
+ exportXML = updateMetricTemplatesImportConfiguration(exportXML);
+
+ ByteArrayOutputStream compressed = new ByteArrayOutputStream();
+ OutputStreamWriter wrt = new OutputStreamWriter(new GZIPOutputStream(compressed), "UTF-8");
+ try {
+ wrt.write(exportXML);
+ } finally {
+ wrt.close();
+ }
+
+ InputStream exportData = new ByteArrayInputStream(compressed.toByteArray());
+
+ try {
+ synchronizationManager.importAllSubsystems(freshUser(), exportData, null);
+ } finally {
+ exportData.close();
+ }
+
+ //now check that everything got imported according to the changed configuration
+ SystemManagerLocal systemManager = LookupUtil.getSystemManager();
+ Properties settings = systemManager.getSystemConfiguration(freshUser());
+
+ assertEquals(settings.getProperty("CAM_BASE_URL"), "http://testing.domain:7080");
+
+ MeasurementDefinitionManagerLocal measurementDefinitionManager =
+ LookupUtil.getMeasurementDefinitionManager();
+ MeasurementDefinitionCriteria crit = new MeasurementDefinitionCriteria();
+ crit.addFilterResourceTypeName(RESOURCE_TYPE_NAME);
+ crit.addFilterName(METRIC_NAME);
+ MeasurementDefinition mdef =
+ measurementDefinitionManager.findMeasurementDefinitionsByCriteria(freshUser(), crit).get(0);
+
+ assertEquals("The " + METRIC_NAME + " metric should have been updated with default interval of 30s",
+ Long.valueOf(30000), new Long(mdef.getDefaultInterval()));
+
+ //ok, and now test that the platform resource schedule was updated as well
+
+ //get the resource id first
+ ResourceManagerLocal resourceManager = LookupUtil.getResourceManager();
+ ResourceCriteria rcrit = new ResourceCriteria();
+ rcrit.addFilterResourceTypeName(RESOURCE_TYPE_NAME);
+ List<Resource> platforms = resourceManager.findResourcesByCriteria(freshUser(), rcrit);
+
+ assertEquals("Unexpected number of platform resources found.", 1, platforms.size());
+
+ int platformResourceId = platforms.get(0).getId();
+
+ //now find the schedule for the measurement
+ MeasurementScheduleManagerLocal measurementScheduleManager = LookupUtil.getMeasurementScheduleManager();
+ List<MeasurementSchedule> schedules =
+ measurementScheduleManager.findSchedulesByResourceIdAndDefinitionIds(freshUser(), platformResourceId,
+ new int[] { mdef.getId() });
+
+ assertEquals("Unexpected number of '" + METRIC_NAME + "' schedules found.", 1, schedules.size());
+
+ assertEquals("The schedule should have been updated along with the definition during the config sync",
+ 30000, schedules.get(0).getInterval());
+
+ } finally {
+ tearDown();
+ }
+ }
+
+ public void testManuallyPassedImportConfigurationHasPrecendenceOverTheInlinedOne() throws Exception {
+ setup();
+
+ try {
+ //let's read the original values from the database, so that we know what to compare against
+ SystemManagerLocal systemManager = LookupUtil.getSystemManager();
+ Properties settings = systemManager.getSystemConfiguration(freshUser());
+
+ String originalBaseUrl = settings.getProperty("CAM_BASE_URL");
+
+ MeasurementDefinitionManagerLocal measurementDefinitionManager =
+ LookupUtil.getMeasurementDefinitionManager();
+ MeasurementDefinitionCriteria crit = new MeasurementDefinitionCriteria();
+ crit.addFilterResourceTypeName(RESOURCE_TYPE_NAME);
+ crit.addFilterName(METRIC_NAME);
+ MeasurementDefinition distroNameDef =
+ measurementDefinitionManager.findMeasurementDefinitionsByCriteria(freshUser(), crit).get(0);
+
+ long originalInterval = distroNameDef.getDefaultInterval();
+
+ //now modify the default configuration in the export file
+ String exportXML = getExportData();
+
+ exportXML = updateSystemSettingsImportConfiguration(exportXML);
+ exportXML = updateMetricTemplatesImportConfiguration(exportXML);
+
+ ByteArrayOutputStream compressed = new ByteArrayOutputStream();
+ OutputStreamWriter wrt = new OutputStreamWriter(new GZIPOutputStream(compressed), "UTF-8");
+ try {
+ wrt.write(exportXML);
+ } finally {
+ wrt.close();
+ }
+
+ InputStream exportData = new ByteArrayInputStream(compressed.toByteArray());
+
+ //let's just use the default configs so that we don't apply the changes suggested in
+ //the changed default configs created above
+ ImportConfiguration systemSettingsConfiguration =
+ new ImportConfiguration(SystemSettingsSynchronizer.class.getName(), new SystemSettingsSynchronizer()
+ .getImporter().getImportConfigurationDefinition().getDefaultTemplate().createConfiguration());
+ ImportConfiguration metricTemplatesConfiguration =
+ new ImportConfiguration(MetricTemplateSynchronizer.class.getName(), new MetricTemplateSynchronizer()
+ .getImporter().getImportConfigurationDefinition().getDefaultTemplate().createConfiguration());
+
+ try {
+ synchronizationManager.importAllSubsystems(freshUser(), exportData,
+ Arrays.asList(systemSettingsConfiguration, metricTemplatesConfiguration));
+ } finally {
+ exportData.close();
+ }
+
+ //now check that we import using the manually create configurations, not the inlined ones
+ settings = systemManager.getSystemConfiguration(freshUser());
+
+ assertEquals(settings.getProperty("CAM_BASE_URL"), originalBaseUrl);
+
+ measurementDefinitionManager = LookupUtil.getMeasurementDefinitionManager();
+ distroNameDef = measurementDefinitionManager.findMeasurementDefinitionsByCriteria(freshUser(), crit).get(0);
+
+ //the definition should have been updated by the data from the export file
+ assertEquals("The " + METRIC_NAME + " metric shouldn't have changed its default interval", 30000,
+ distroNameDef.getDefaultInterval());
+
+ //ok, and now test that the platform resource schedule was NOT updated because it was configured not to.
+
+ //get the resource id first
+ ResourceManagerLocal resourceManager = LookupUtil.getResourceManager();
+ ResourceCriteria rcrit = new ResourceCriteria();
+ rcrit.addFilterResourceTypeName(RESOURCE_TYPE_NAME);
+ List<Resource> platforms = resourceManager.findResourcesByCriteria(freshUser(), rcrit);
+
+ assertEquals("Unexpected number of platform resources found.", 1, platforms.size());
+
+ int platformResourceId = platforms.get(0).getId();
+
+ //now find the schedule for the measurement
+ MeasurementScheduleManagerLocal measurementScheduleManager = LookupUtil.getMeasurementScheduleManager();
+ List<MeasurementSchedule> schedules =
+ measurementScheduleManager.findSchedulesByResourceIdAndDefinitionIds(freshUser(), platformResourceId,
+ new int[] { distroNameDef.getId() });
+
+ assertEquals("Unexpected number of '" + METRIC_NAME + "' schedules found.", 1, schedules.size());
+
+ assertEquals("The schedule should have been updated along with the definition during the config sync",
+ originalInterval, schedules.get(0).getInterval());
+
+ } finally {
+ tearDown();
+ }
+ }
+
+ private String getExportData() throws IOException {
+ InputStreamReader str =
+ new InputStreamReader(new GZIPInputStream(new ByteArrayInputStream(export.getExportFile())), "UTF-8");
+ try {
+ char[] buf = new char[32768];
+ StringBuilder bld = new StringBuilder();
+
+ int cnt = 0;
+ while ((cnt = str.read(buf)) >= 0) {
+ bld.append(buf, 0, cnt);
+ }
+
+ return bld.toString();
+ } finally {
+ str.close();
+ }
+ }
+
+ private static String documentToString(Document document) throws TransformerFactoryConfigurationError,
+ TransformerException, IOException {
+
+ StringWriter ret = new StringWriter();
+ try {
+ Source source = new DOMSource(document);
+ Result result = new StreamResult(ret);
+
+ Transformer xformer = TransformerFactory.newInstance().newTransformer();
+ xformer.transform(source, result);
+
+ return ret.toString();
+ } finally {
+ ret.close();
+ }
+ }
+
+ private String updateSystemSettingsImportConfiguration(String exportXML) throws Exception {
+ XPath xpath = XPathFactory.newInstance().newXPath();
+ xpath.setNamespaceContext(SynchronizationConstants.createConfigurationExportNamespaceContext());
+
+ XPathExpression systemSettingsConfigurationPath =
+ xpath
+ .compile("/:configuration-export/:entities[@id='org.rhq.enterprise.server.sync.SystemSettingsSynchronizer']/:default-configuration/ci:simple-property[@name='propertiesToImport']");
+
+ XPathExpression baseUrlSettingPath =
+ xpath
+ .compile("/:configuration-export/:entities[@id='org.rhq.enterprise.server.sync.SystemSettingsSynchronizer']/:entity/:data/systemSettings/entry[@key='CAM_BASE_URL']");
+
+ Element systemSettingsConfiguration =
+ (Element) systemSettingsConfigurationPath.evaluate(new InputSource(new StringReader(exportXML)),
+ XPathConstants.NODE);
+ String propsToImport = systemSettingsConfiguration.getAttribute("value");
+
+ propsToImport += ", CAM_BASE_URL";
+
+ systemSettingsConfiguration.setAttribute("value", propsToImport);
+
+ exportXML = documentToString(systemSettingsConfiguration.getOwnerDocument());
+
+ Element baseUrlSetting =
+ (Element) baseUrlSettingPath.evaluate(new InputSource(new StringReader(exportXML)), XPathConstants.NODE);
+
+ baseUrlSetting.setTextContent("http://testing.domain:7080");
+
+ return documentToString(baseUrlSetting.getOwnerDocument());
+ }
+
+ private String updateMetricTemplatesImportConfiguration(String exportXML) throws Exception {
+ XPath xpath = XPathFactory.newInstance().newXPath();
+ xpath.setNamespaceContext(SynchronizationConstants.createConfigurationExportNamespaceContext());
+
+ XPathExpression overridesPath =
+ xpath
+ .compile("/:configuration-export/:entities[@id='org.rhq.enterprise.server.sync.MetricTemplateSynchronizer']/:default-configuration/ci:list-property[@name='metricUpdateOverrides']");
+
+ Element overrides =
+ (Element) overridesPath.evaluate(new InputSource(new StringReader(exportXML)), XPathConstants.NODE);
+
+ Document doc = overrides.getOwnerDocument();
+
+ String ns = SynchronizationConstants.CONFIGURATION_INSTANCE_NAMESPACE;
+ String prefix = SynchronizationConstants.CONFIGURATION_INSTANCE_NAMESPACE_PREFIX;
+
+ Element values = doc.createElementNS(ns, prefix + ":values");
+ overrides.appendChild(values);
+
+ Element mapValue = doc.createElementNS(ns, prefix + ":map-value");
+ values.appendChild(mapValue);
+
+ addSimpleValue(mapValue, "metricName", METRIC_NAME);
+ addSimpleValue(mapValue, "resourceTypeName", RESOURCE_TYPE_NAME);
+ addSimpleValue(mapValue, "resourceTypePlugin", PLUGIN_NAME);
+ addSimpleValue(mapValue, "updateSchedules", "true");
+
+ exportXML = documentToString(doc);
+
+ //now redefine the collection interval of the above metric so that we can see the change after the import
+ XPathExpression distroNameMetricPath =
+ xpath
+ .compile("/:configuration-export/:entities[@id='org.rhq.enterprise.server.sync.MetricTemplateSynchronizer']/:entity/:data/metricTemplate[@metricName='"
+ + METRIC_NAME + "']");
+
+ Element metric =
+ (Element) distroNameMetricPath.evaluate(new InputSource(new StringReader(exportXML)), XPathConstants.NODE);
+
+ doc = metric.getOwnerDocument();
+
+ metric.setAttribute("defaultInterval", "30000");
+
+ return documentToString(doc);
+ }
+
+ private static void addSimpleValue(Element parent, String propertyName, String value) {
+ String ns = SynchronizationConstants.CONFIGURATION_INSTANCE_NAMESPACE;
+ String prefix = SynchronizationConstants.CONFIGURATION_INSTANCE_NAMESPACE_PREFIX;
+ Element simpleValue = parent.getOwnerDocument().createElementNS(ns, prefix + ":simple-value");
+ simpleValue.setAttribute("property-name", propertyName);
+ simpleValue.setAttribute("value", value);
+
+ parent.appendChild(simpleValue);
+ }
+
+ private Subject freshUser() {
+ SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
+
+ if (user != null) {
+ try {
+ subjectManager.logout(user);
+ } catch (PermissionException e) {
+ //we can safely ignore a permission exception during logout...
+ }
+ }
+
+ user = subjectManager.getOverlord();
+ return user;
+ }
+}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SystemSettingsExporterTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SystemSettingsExporterTest.java
index 2f8aa26..2837982 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SystemSettingsExporterTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/sync/test/SystemSettingsExporterTest.java
@@ -49,6 +49,7 @@ import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.sync.ExporterMessages;
import org.rhq.core.domain.sync.entity.SystemSettings;
import org.rhq.enterprise.server.sync.ExportingInputStream;
+import org.rhq.enterprise.server.sync.SynchronizationConstants;
import org.rhq.enterprise.server.sync.Synchronizer;
import org.rhq.enterprise.server.sync.SystemSettingsSynchronizer;
import org.rhq.enterprise.server.system.SystemManagerLocal;
@@ -105,9 +106,9 @@ public class SystemSettingsExporterTest extends JMockTest {
Element root = doc.getDocumentElement();
- Element entities = (Element) getFirstDirectChildByTagName(root, ExportingInputStream.ENTITIES_EXPORT_ELEMENT);
+ Element entities = (Element) getFirstDirectChildByTagName(root, SynchronizationConstants.ENTITIES_EXPORT_ELEMENT);
- assertEquals(entities.getAttribute(ExportingInputStream.ID_ATTRIBUTE), SystemSettingsSynchronizer.class.getName(),
+ assertEquals(entities.getAttribute(SynchronizationConstants.ID_ATTRIBUTE), SystemSettingsSynchronizer.class.getName(),
"Unexpected id of the entities element.");
NodeList systemSettings = entities.getElementsByTagName("systemSettings");
diff --git a/modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/ConfigurationInstanceDescriptorUtil.java b/modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/ConfigurationInstanceDescriptorUtil.java
index b2f9ae3..56abf6b 100644
--- a/modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/ConfigurationInstanceDescriptorUtil.java
+++ b/modules/enterprise/server/xml-schemas/src/main/java/org/rhq/enterprise/server/xmlschema/ConfigurationInstanceDescriptorUtil.java
@@ -31,6 +31,9 @@ import javax.xml.namespace.QName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.rhq.core.clientapi.agent.metadata.ConfigurationMetadataParser;
+import org.rhq.core.clientapi.agent.metadata.InvalidPluginDescriptorException;
+import org.rhq.core.clientapi.descriptor.configuration.ConfigurationDescriptor;
import org.rhq.core.clientapi.descriptor.configuration.ConfigurationProperty;
import org.rhq.core.clientapi.descriptor.configuration.ListProperty;
import org.rhq.core.clientapi.descriptor.configuration.MapProperty;
@@ -78,61 +81,12 @@ public class ConfigurationInstanceDescriptorUtil {
}
- /**
- * A configuration instance is a combination of a configuration definition and a concrete
- * configuration instance with defined values. This is used during the config synchronization
- * to output the default configuration of an importer directly in the export file so that the
- * users have an easy way of modifying that configuration.
- *
- * @param definition
- * @param configuration
- * @return
- */
- public static ConfigurationInstanceDescriptor createConfigurationInstance(ConfigurationDefinition definition,
- Configuration configuration) {
-
- ConfigurationInstanceDescriptor ret = new ConfigurationInstanceDescriptor();
-
- addAll(ret.getConfigurationProperty(), definition.getPropertyDefinitions(), configuration.getMap());
-
- return ret;
- }
-
- private static void addAll(List<JAXBElement<?>> descriptors, Map<String, PropertyDefinition> defs, Map<String, Property> props) {
- for(Map.Entry<String, PropertyDefinition> e : defs.entrySet()) {
- String propName = e.getKey();
- PropertyDefinition def = e.getValue();
- Property prop = props.get(propName);
-
- addSingle(descriptors, def, prop);
- }
- }
-
- private static void addSingle(List<JAXBElement<?>> descriptors, PropertyDefinition def, Property prop) {
- ConfigurationProperty descriptor = null;
- QName tagName = null;
-
- descriptor = createDescriptor(def, prop);
- tagName = getTagName(descriptor);
-
- addToJAXBElementList(descriptors, Object.class, descriptor, tagName);
+ public static class ConfigurationAndDefinition {
+ public Configuration configuration;
+ public ConfigurationDefinition definition;
}
- private static ConfigurationProperty createDescriptor(PropertyDefinition def, Property prop) {
- ConfigurationProperty ret = null;
-
- if (def instanceof PropertyDefinitionSimple) {
- ret = createSimple((PropertyDefinitionSimple) def, (PropertySimple) prop);
- } else if (def instanceof PropertyDefinitionList) {
- ret = createList((PropertyDefinitionList) def, (PropertyList) prop);
- } else if (def instanceof PropertyDefinitionMap) {
- ret = createMap((PropertyDefinitionMap) def, (PropertyMap) prop);
- }
-
- return ret;
- }
-
- private static QName getTagName(ConfigurationProperty descriptor) {
+ protected static QName getTagName(ConfigurationProperty descriptor) {
if (descriptor instanceof SimplePropertyInstanceDescriptor) {
return new QName(NS_CONFIGURATION_INSTANCE, "simple-property");
} else if (descriptor instanceof ListPropertyInstanceDescriptor) {
@@ -161,246 +115,460 @@ public class ConfigurationInstanceDescriptorUtil {
throw new IllegalArgumentException("Unknown value descriptor type: " + value.getClass());
}
-
- private static SimplePropertyInstanceDescriptor createSimple(PropertyDefinitionSimple def, PropertySimple prop) {
- SimplePropertyInstanceDescriptor ret = new SimplePropertyInstanceDescriptor();
- setCommonProps(ret, def, true);
- //these are prohibited, because they make no sense on the property instance
- //ret.setDefaultValue(def.getDefaultValue());
- //ret.setInitialValue(prop.getStringValue());
- //ret.setActivationPolicy(pds.getActivationPolicy());
- ret.setPropertyOptions(convert(def.getEnumeratedValues()));
- ret.setType(convert(def.getType()));
- ret.setUnits(convert(def.getUnits()));
+ private static class ToDescriptor {
- if (prop != null) {
- ret.setValue(prop.getStringValue());
+ public static ConfigurationInstanceDescriptor createConfigurationInstance(ConfigurationDefinition definition,
+ Configuration configuration) {
+
+ ConfigurationInstanceDescriptor ret = new ConfigurationInstanceDescriptor();
+
+ addAll(ret.getConfigurationProperty(), definition.getPropertyDefinitions(), configuration.getMap());
+
+ return ret;
}
- return ret;
- }
-
- private static ListPropertyInstanceDescriptor createList(PropertyDefinitionList def, PropertyList prop) {
- ListPropertyInstanceDescriptor ret = new ListPropertyInstanceDescriptor();
+ private static void addAll(List<JAXBElement<?>> descriptors, Map<String, PropertyDefinition> defs, Map<String, Property> props) {
+ for(Map.Entry<String, PropertyDefinition> e : defs.entrySet()) {
+ String propName = e.getKey();
+ PropertyDefinition def = e.getValue();
+ Property prop = props.get(propName);
+
+ addSingle(descriptors, def, prop);
+ }
+ }
- setCommonProps(ret, def, true);
+ private static void addSingle(List<JAXBElement<?>> descriptors, PropertyDefinition def, Property prop) {
+ ConfigurationProperty descriptor = null;
+ QName tagName = null;
+
+ descriptor = createDescriptor(def, prop);
+ tagName = getTagName(descriptor);
+
+ addToJAXBElementList(descriptors, Object.class, descriptor, tagName);
+ }
- ConfigurationProperty memberDef = convertDefinition(def.getMemberDefinition());
- ret.setConfigurationProperty(new JAXBElement<ConfigurationProperty>(getTagName(memberDef), ConfigurationProperty.class, memberDef));
+ private static ConfigurationProperty createDescriptor(PropertyDefinition def, Property prop) {
+ ConfigurationProperty ret = null;
+
+ if (def instanceof PropertyDefinitionSimple) {
+ ret = createSimple((PropertyDefinitionSimple) def, (PropertySimple) prop);
+ } else if (def instanceof PropertyDefinitionList) {
+ ret = createList((PropertyDefinitionList) def, (PropertyList) prop);
+ } else if (def instanceof PropertyDefinitionMap) {
+ ret = createMap((PropertyDefinitionMap) def, (PropertyMap) prop);
+ }
+
+ return ret;
+ }
- if (prop != null) {
- PropertyValuesDescriptor values = new PropertyValuesDescriptor();
+ private static SimplePropertyInstanceDescriptor createSimple(PropertyDefinitionSimple def, PropertySimple prop) {
+ SimplePropertyInstanceDescriptor ret = new SimplePropertyInstanceDescriptor();
+ setCommonProps(ret, def, true);
- ret.setValues(values);
+ //these are prohibited, because they make no sense on the property instance
+ //ret.setDefaultValue(def.getDefaultValue());
+ //ret.setInitialValue(prop.getStringValue());
+ //ret.setActivationPolicy(pds.getActivationPolicy());
+ ret.setPropertyOptions(convert(def.getEnumeratedValues()));
+ ret.setType(convert(def.getType()));
+ ret.setUnits(convert(def.getUnits()));
- for(Property el : prop.getList()) {
- ComplexValueDescriptor value = convertValue(el);
+ if (prop != null) {
+ ret.setValue(prop.getStringValue());
+ }
+
+ return ret;
+ }
+
+ private static ListPropertyInstanceDescriptor createList(PropertyDefinitionList def, PropertyList prop) {
+ ListPropertyInstanceDescriptor ret = new ListPropertyInstanceDescriptor();
+
+ setCommonProps(ret, def, true);
+
+ ConfigurationProperty memberDef = convertDefinition(def.getMemberDefinition());
+ ret.setConfigurationProperty(new JAXBElement<ConfigurationProperty>(getTagName(memberDef), ConfigurationProperty.class, memberDef));
+
+ if (prop != null) {
+ PropertyValuesDescriptor values = new PropertyValuesDescriptor();
- //we don't need the property-name in lists, because the list has just a single member definition
- value.setPropertyName(null);
+ ret.setValues(values);
- addToJAXBElementList(values.getComplexValue(), Object.class, value, getTagName(value));
+ for(Property el : prop.getList()) {
+ ComplexValueDescriptor value = convertValue(el);
+
+ //we don't need the property-name in lists, because the list has just a single member definition
+ value.setPropertyName(null);
+
+ addToJAXBElementList(values.getComplexValue(), Object.class, value, getTagName(value));
+ }
}
+
+ return ret;
}
- return ret;
- }
-
- private static MapPropertyInstanceDescriptor createMap(PropertyDefinitionMap def, PropertyMap prop) {
- MapPropertyInstanceDescriptor ret = new MapPropertyInstanceDescriptor();
-
- setCommonProps(ret, def, true);
+ private static MapPropertyInstanceDescriptor createMap(PropertyDefinitionMap def, PropertyMap prop) {
+ MapPropertyInstanceDescriptor ret = new MapPropertyInstanceDescriptor();
+
+ setCommonProps(ret, def, true);
+
+ for(PropertyDefinition mem : def.getPropertyDefinitions().values()) {
+ ConfigurationProperty memDef = convertDefinition(mem);
+
+ addToJAXBElementList(ret.getConfigurationProperty(), ConfigurationProperty.class, memDef, getTagName(memDef));
+ }
+
+ if (prop != null) {
+ PropertyValuesDescriptor values = new PropertyValuesDescriptor();
+
+ ret.setValues(values);
- for(PropertyDefinition mem : def.getPropertyDefinitions().values()) {
- ConfigurationProperty memDef = convertDefinition(mem);
+ for(Property el : prop.getMap().values()) {
+ ComplexValueDescriptor value = convertValue(el);
+ addToJAXBElementList(values.getComplexValue(), Object.class, value, getTagName(value));
+ }
+ }
- addToJAXBElementList(ret.getConfigurationProperty(), ConfigurationProperty.class, memDef, getTagName(memDef));
+ return ret;
}
- if (prop != null) {
- PropertyValuesDescriptor values = new PropertyValuesDescriptor();
+ private static void setCommonProps(ConfigurationProperty target, PropertyDefinition source, boolean creatingInstance) {
+ target.setName(source.getName());
+ //let's always use long description
+ //target.setDescription(source.getDescription());
+ target.setLongDescription(source.getDescription());
+ target.setDisplayName(source.getDisplayName());
- ret.setValues(values);
-
- for(Property el : prop.getMap().values()) {
- ComplexValueDescriptor value = convertValue(el);
- addToJAXBElementList(values.getComplexValue(), Object.class, value, getTagName(value));
+ //these are prohibited on the instance because they make no sense there
+ if (!creatingInstance) {
+ target.setRequired(source.isRequired());
+ target.setReadOnly(source.isReadOnly());
+ target.setSummary(source.isSummary());
}
}
- return ret;
- }
-
- private static void setCommonProps(ConfigurationProperty target, PropertyDefinition source, boolean creatingInstance) {
- target.setName(source.getName());
- //let's always use long description
- //target.setDescription(source.getDescription());
- target.setLongDescription(source.getDescription());
- target.setDisplayName(source.getDisplayName());
-
- //these are prohibited on the instance because they make no sense there
- if (!creatingInstance) {
- target.setRequired(source.isRequired());
- target.setReadOnly(source.isReadOnly());
- target.setSummary(source.isSummary());
- }
- }
-
- private static PropertyOptions convert(List<PropertyDefinitionEnumeration> options) {
- if (options.isEmpty()) {
- return null;
+ private static PropertyOptions convert(List<PropertyDefinitionEnumeration> options) {
+ if (options.isEmpty()) {
+ return null;
+ }
+
+ PropertyOptions ret = new PropertyOptions();
+
+ ArrayList<PropertyDefinitionEnumeration> opts = new ArrayList<PropertyDefinitionEnumeration>(options);
+
+ Collections.sort(opts, new Comparator<PropertyDefinitionEnumeration>() {
+ public int compare(PropertyDefinitionEnumeration o1, PropertyDefinitionEnumeration o2) {
+ return o1.getOrderIndex() - o2.getOrderIndex();
+ }
+ });
+
+ for(PropertyDefinitionEnumeration option : opts) {
+ ret.getOption().add(convert(option));
+ }
+
+ return ret;
}
- PropertyOptions ret = new PropertyOptions();
-
- ArrayList<PropertyDefinitionEnumeration> opts = new ArrayList<PropertyDefinitionEnumeration>(options);
+ private static Option convert(PropertyDefinitionEnumeration option) {
+ Option ret = new Option();
+ ret.setName(option.getName());
+ ret.setValue(option.getValue());
+ return ret;
+ }
- Collections.sort(opts, new Comparator<PropertyDefinitionEnumeration>() {
- public int compare(PropertyDefinitionEnumeration o1, PropertyDefinitionEnumeration o2) {
- return o1.getOrderIndex() - o2.getOrderIndex();
+ private static PropertyType convert(PropertySimpleType type) {
+ if (type == null) {
+ return null;
+ }
+
+ try {
+ return PropertyType.valueOf(type.name());
+ } catch (IllegalArgumentException e) {
+ LOG.warn("Failed to convert a PropertySimpleType instance '" + type.name() + "' into a PropertyType.", e);
+ throw e;
}
- });
-
- for(PropertyDefinitionEnumeration option : opts) {
- ret.getOption().add(convert(option));
}
- return ret;
- }
-
- private static Option convert(PropertyDefinitionEnumeration option) {
- Option ret = new Option();
- ret.setName(option.getName());
- ret.setValue(option.getValue());
- return ret;
- }
-
- private static PropertyType convert(PropertySimpleType type) {
- if (type == null) {
- return null;
+ private static MeasurementUnitsDescriptor convert(MeasurementUnits unit) {
+ //XXX there actually are some differences in the available values for these
+ //two enums:
+ //Missing in MeasurementUnitsDescriptor:
+ //MeasurementUnits.JIFFY, MeasurementUnits.PETA_BYTES
+
+ if (unit == null) {
+ return null;
+ }
+
+ String value = unit.name();
+
+ try {
+ return MeasurementUnitsDescriptor.valueOf(value);
+ } catch (IllegalArgumentException e) {
+ LOG.warn("Failed to convert a MeasurementUnits instance '" + unit.getName() + "' into a MeasurementUnitsDescriptor.", e);
+ throw e;
+ }
}
- try {
- return PropertyType.valueOf(type.name());
- } catch (IllegalArgumentException e) {
- LOG.warn("Failed to convert a PropertySimpleType instance '" + type.name() + "' into a PropertyType.", e);
- throw e;
+ private static ConfigurationProperty convertDefinition(PropertyDefinition def) {
+ if (def instanceof PropertyDefinitionSimple) {
+ return convertSimple((PropertyDefinitionSimple) def);
+ } else if (def instanceof PropertyDefinitionList) {
+ return convertList((PropertyDefinitionList) def);
+ } else if (def instanceof PropertyDefinitionMap) {
+ return convertMap((PropertyDefinitionMap) def);
+ }
+
+ throw new IllegalArgumentException("Unsupported property definition type: " + def.getClass());
}
- }
-
- private static MeasurementUnitsDescriptor convert(MeasurementUnits unit) {
- //XXX there actually are some differences in the available values for these
- //two enums:
- //Missing in MeasurementUnitsDescriptor:
- //MeasurementUnits.JIFFY, MeasurementUnits.PETA_BYTES
- if (unit == null) {
- return null;
+ private static SimpleProperty convertSimple(PropertyDefinitionSimple def) {
+ SimpleProperty ret = new SimpleProperty();
+ setCommonProps(ret, def, false);
+ ret.setDefaultValue(def.getDefaultValue());
+ ret.setPropertyOptions(convert(def.getEnumeratedValues()));
+ ret.setType(convert(def.getType()));
+ ret.setUnits(convert(def.getUnits()));
+
+ return ret;
}
- String value = unit.name();
-
- try {
- return MeasurementUnitsDescriptor.valueOf(value);
- } catch (IllegalArgumentException e) {
- LOG.warn("Failed to convert a MeasurementUnits instance '" + unit.getName() + "' into a MeasurementUnitsDescriptor.", e);
- throw e;
- }
- }
-
- private static ConfigurationProperty convertDefinition(PropertyDefinition def) {
- if (def instanceof PropertyDefinitionSimple) {
- return convertSimple((PropertyDefinitionSimple) def);
- } else if (def instanceof PropertyDefinitionList) {
- return convertList((PropertyDefinitionList) def);
- } else if (def instanceof PropertyDefinitionMap) {
- return convertMap((PropertyDefinitionMap) def);
+ private static ListProperty convertList(PropertyDefinitionList def) {
+ ListProperty ret = new ListProperty();
+ setCommonProps(ret, def, false);
+ ConfigurationProperty memberDefinition = convertDefinition(def.getMemberDefinition());
+ ret.setConfigurationProperty(new JAXBElement<ConfigurationProperty>(getTagName(memberDefinition), ConfigurationProperty.class, memberDefinition));
+
+ return ret;
}
- throw new IllegalArgumentException("Unsupported property definition type: " + def.getClass());
- }
-
- private static SimpleProperty convertSimple(PropertyDefinitionSimple def) {
- SimpleProperty ret = new SimpleProperty();
- setCommonProps(ret, def, false);
- ret.setDefaultValue(def.getDefaultValue());
- ret.setPropertyOptions(convert(def.getEnumeratedValues()));
- ret.setType(convert(def.getType()));
- ret.setUnits(convert(def.getUnits()));
+ private static MapProperty convertMap(PropertyDefinitionMap def) {
+ MapProperty ret = new MapProperty();
+ setCommonProps(ret, def, false);
+
+ List<JAXBElement<? extends ConfigurationProperty>> elements = ret.getConfigurationProperty();
+ for(PropertyDefinition el : def.getPropertyDefinitions().values()) {
+ ConfigurationProperty prop = convertDefinition(el);
+ QName tagName = getTagName(prop);
+ addToJAXBElementList(elements, ConfigurationProperty.class, prop, tagName);
+ }
+
+ return ret;
+ }
- return ret;
- }
-
- private static ListProperty convertList(PropertyDefinitionList def) {
- ListProperty ret = new ListProperty();
- setCommonProps(ret, def, false);
- ConfigurationProperty memberDefinition = convertDefinition(def.getMemberDefinition());
- ret.setConfigurationProperty(new JAXBElement<ConfigurationProperty>(getTagName(memberDefinition), ConfigurationProperty.class, memberDefinition));
+ private static ComplexValueDescriptor convertValue(Property prop) {
+ if (prop instanceof PropertySimple) {
+ return convertSimpleValue((PropertySimple) prop);
+ } else if (prop instanceof PropertyList) {
+ return convertListValue((PropertyList) prop);
+ } else if (prop instanceof PropertyMap) {
+ return convertMapValue((PropertyMap) prop);
+ }
+
+ throw new IllegalArgumentException("Unsupported property type to convert to a value descriptor: " + prop.getClass());
+ }
- return ret;
- }
-
- private static MapProperty convertMap(PropertyDefinitionMap def) {
- MapProperty ret = new MapProperty();
- setCommonProps(ret, def, false);
+ private static ComplexValueSimpleDescriptor convertSimpleValue(PropertySimple prop) {
+ ComplexValueSimpleDescriptor ret = new ComplexValueSimpleDescriptor();
+ ret.setPropertyName(prop.getName());
+ ret.setValue(prop.getStringValue());
+
+ return ret;
+ }
- List<JAXBElement<? extends ConfigurationProperty>> elements = ret.getConfigurationProperty();
- for(PropertyDefinition el : def.getPropertyDefinitions().values()) {
- ConfigurationProperty prop = convertDefinition(el);
- QName tagName = getTagName(prop);
- addToJAXBElementList(elements, ConfigurationProperty.class, prop, tagName);
+ private static ComplexValueListDescriptor convertListValue(PropertyList prop) {
+ ComplexValueListDescriptor ret = new ComplexValueListDescriptor();
+ ret.setPropertyName(prop.getName());
+
+ for(Property el : prop.getList()) {
+ ComplexValueDescriptor value = convertValue(el);
+ addToJAXBElementList(ret.getComplexValue(), Object.class, value, getTagName(value));
+ }
+
+ return ret;
}
- return ret;
- }
-
- private static ComplexValueDescriptor convertValue(Property prop) {
- if (prop instanceof PropertySimple) {
- return convertSimpleValue((PropertySimple) prop);
- } else if (prop instanceof PropertyList) {
- return convertListValue((PropertyList) prop);
- } else if (prop instanceof PropertyMap) {
- return convertMapValue((PropertyMap) prop);
+ private static ComplexValueMapDescriptor convertMapValue(PropertyMap prop) {
+ ComplexValueMapDescriptor ret = new ComplexValueMapDescriptor();
+ ret.setPropertyName(prop.getName());
+
+ for (Property el : prop.getMap().values()) {
+ ComplexValueDescriptor value = convertValue(el);
+ addToJAXBElementList(ret.getComplexValue(), Object.class, value, getTagName(value));
+ }
+
+ return ret;
}
- throw new IllegalArgumentException("Unsupported property type to convert to a value descriptor: " + prop.getClass());
+ private static <T> void addToJAXBElementList(List<JAXBElement<? extends T>> list, Class<T> baseClass, T property, QName tagName) {
+ JAXBElement<? extends T> el = new JAXBElement<T>(tagName, baseClass, property);
+ list.add(el);
+ }
}
- private static ComplexValueSimpleDescriptor convertSimpleValue(PropertySimple prop) {
- ComplexValueSimpleDescriptor ret = new ComplexValueSimpleDescriptor();
- ret.setPropertyName(prop.getName());
- ret.setValue(prop.getStringValue());
+ private static class ToConfigurationAndDefinition {
- return ret;
- }
-
- private static ComplexValueListDescriptor convertListValue(PropertyList prop) {
- ComplexValueListDescriptor ret = new ComplexValueListDescriptor();
- ret.setPropertyName(prop.getName());
+ public static ConfigurationAndDefinition createConfigurationAndDefinition(ConfigurationInstanceDescriptor descriptor) {
+ ConfigurationAndDefinition ret = new ConfigurationAndDefinition();
+ Configuration configuration = new Configuration();
+ ConfigurationDefinition definition = new ConfigurationDefinition(null, null);
+
+ ret.configuration = configuration;
+ ret.definition = definition;
+
+ for(JAXBElement<?> el : descriptor.getConfigurationProperty()) {
+ Object childDescriptor = el.getValue();
+ add(definition, configuration, null, null, childDescriptor);
+ }
+
+ return ret;
+ }
- for(Property el : prop.getList()) {
- ComplexValueDescriptor value = convertValue(el);
- addToJAXBElementList(ret.getComplexValue(), Object.class, value, getTagName(value));
+ private static void add(ConfigurationDefinition configurationDefinition, Configuration configuration, PropertyDefinition parentDef, Property parentProp, Object propertyInstance) {
+ Property prop = null;
+ PropertyDefinition def = null;
+
+ if (propertyInstance instanceof SimplePropertyInstanceDescriptor) {
+ def = convert((ConfigurationProperty)propertyInstance);
+ def.setConfigurationDefinition(configurationDefinition);
+
+ SimplePropertyInstanceDescriptor simpleInstance = (SimplePropertyInstanceDescriptor) propertyInstance;
+
+ PropertySimple simpleProp = new PropertySimple(simpleInstance.getName(), simpleInstance.getValue());
+ prop = simpleProp;
+ } else if (propertyInstance instanceof ListPropertyInstanceDescriptor) {
+ def = convert((ConfigurationProperty)propertyInstance);
+ def.setConfigurationDefinition(configurationDefinition);
+
+ ListPropertyInstanceDescriptor listInstance = (ListPropertyInstanceDescriptor) propertyInstance;
+ PropertyList listProp = new PropertyList(listInstance.getName());
+
+ PropertyDefinition memberDefinition = ((PropertyDefinitionList)def).getMemberDefinition();
+
+ if (listInstance.getValues() != null) {
+ for(JAXBElement<?> val : listInstance.getValues().getComplexValue()) {
+ ComplexValueDescriptor valDesc = (ComplexValueDescriptor) val.getValue();
+ Property child = convert(memberDefinition, valDesc);
+ listProp.add(child);
+ }
+ }
+
+ prop = listProp;
+ } else if (propertyInstance instanceof MapPropertyInstanceDescriptor) {
+ def = convert((ConfigurationProperty)propertyInstance);
+ def.setConfigurationDefinition(configurationDefinition);
+
+ MapPropertyInstanceDescriptor mapInstance = (MapPropertyInstanceDescriptor) propertyInstance;
+ PropertyMap mapProp = new PropertyMap(mapInstance.getName());
+
+ if (mapInstance.getValues() != null) {
+ for(JAXBElement<?> val : mapInstance.getValues().getComplexValue()) {
+ ComplexValueDescriptor valueDesc = (ComplexValueDescriptor) val.getValue();
+ PropertyDefinition valueDefinition = ((PropertyDefinitionMap)def).get(valueDesc.getPropertyName());
+
+ Property child = convert(valueDefinition, valueDesc);
+ mapProp.put(child);
+ }
+ }
+
+ prop = mapProp;
+ } else {
+ throw new IllegalArgumentException("Unsupported property instance type: " + propertyInstance.getClass());
+ }
+
+ if (parentDef != null) {
+ if (parentDef instanceof PropertyDefinitionList) {
+ def.setParentPropertyListDefinition((PropertyDefinitionList) parentDef);
+ } else if (parentDef instanceof PropertyDefinitionMap) {
+ def.setParentPropertyMapDefinition((PropertyDefinitionMap) parentDef);
+ }
+ } else {
+ configurationDefinition.put(def);
+ }
+
+ prop.setConfiguration(configuration);
+ if (parentProp != null) {
+ if (parentProp instanceof PropertyList) {
+ prop.setParentList((PropertyList) parentProp);
+ } else if (parentProp instanceof PropertyMap) {
+ prop.setParentMap((PropertyMap) parentProp);
+ }
+ } else {
+ configuration.put(prop);
+ }
+ }
+
+ private static PropertyDefinition convert(ConfigurationProperty def) {
+ try {
+ ConfigurationDescriptor tmp = new ConfigurationDescriptor();
+ tmp.getConfigurationProperty().add(new JAXBElement<ConfigurationProperty>(getTagName(def), ConfigurationProperty.class, def));
+ ConfigurationDefinition configDef = ConfigurationMetadataParser.parse(null, tmp);
+
+ return configDef.getPropertyDefinitions().values().iterator().next();
+ } catch (InvalidPluginDescriptorException e) {
+ throw new IllegalArgumentException(e);
+ }
}
- return ret;
+ private static Property convert(PropertyDefinition definition, ComplexValueDescriptor value) {
+ Property ret = null;
+
+ if (value instanceof ComplexValueSimpleDescriptor) {
+ ret = new PropertySimple(value.getPropertyName(), ((ComplexValueSimpleDescriptor) value).getValue());
+ } else if (value instanceof ComplexValueListDescriptor) {
+ ComplexValueListDescriptor listValue = (ComplexValueListDescriptor) value;
+
+ PropertyDefinitionList listDefinition = (PropertyDefinitionList) definition;
+
+ PropertyList list = new PropertyList(value.getPropertyName());
+
+ for(JAXBElement<?> val : listValue.getComplexValue()) {
+ Property child = convert(listDefinition.getMemberDefinition(), (ComplexValueDescriptor) val.getValue());
+
+ list.add(child);
+ }
+ ret = list;
+ } else if (value instanceof ComplexValueMapDescriptor) {
+ ComplexValueMapDescriptor mapValue = (ComplexValueMapDescriptor) value;
+
+ PropertyMap map = new PropertyMap(value.getPropertyName());
+ PropertyDefinitionMap mapDefinition = (PropertyDefinitionMap) definition;
+
+ for(JAXBElement<?> val : mapValue.getComplexValue()) {
+ ComplexValueDescriptor childDesc = (ComplexValueDescriptor) val.getValue();
+
+ PropertyDefinition childDefinition = mapDefinition.get(childDesc.getPropertyName());
+
+ Property child = convert(childDefinition, childDesc);
+ map.put(child);
+ }
+
+ ret = map;
+ }
+
+ if (ret.getName() == null) {
+ ret.setName(definition.getName());
+ }
+
+ return ret;
+ }
}
- private static ComplexValueMapDescriptor convertMapValue(PropertyMap prop) {
- ComplexValueMapDescriptor ret = new ComplexValueMapDescriptor();
- ret.setPropertyName(prop.getName());
-
- for (Property el : prop.getMap().values()) {
- ComplexValueDescriptor value = convertValue(el);
- addToJAXBElementList(ret.getComplexValue(), Object.class, value, getTagName(value));
- }
-
- return ret;
+ /**
+ * A configuration instance is a combination of a configuration definition and a concrete
+ * configuration instance with defined values. This is used during the config synchronization
+ * to output the default configuration of an importer directly in the export file so that the
+ * users have an easy way of modifying that configuration.
+ *
+ * @param definition
+ * @param configuration
+ * @return
+ */
+ public static ConfigurationInstanceDescriptor createConfigurationInstance(ConfigurationDefinition definition,
+ Configuration configuration) {
+ return ToDescriptor.createConfigurationInstance(definition, configuration);
}
- private static <T> void addToJAXBElementList(List<JAXBElement<? extends T>> list, Class<T> baseClass, T property, QName tagName) {
- JAXBElement<? extends T> el = new JAXBElement<T>(tagName, baseClass, property);
- list.add(el);
+ public static ConfigurationAndDefinition createConfigurationAndDefinition(ConfigurationInstanceDescriptor descriptor) {
+ return ToConfigurationAndDefinition.createConfigurationAndDefinition(descriptor);
}
}
diff --git a/modules/enterprise/server/xml-schemas/src/test/java/org/rhq/enterprise/server/xmlschema/ConfigurationInstanceDescriptorUtilTest.java b/modules/enterprise/server/xml-schemas/src/test/java/org/rhq/enterprise/server/xmlschema/ConfigurationInstanceDescriptorUtilTest.java
index 2105e7f..02cd29a 100644
--- a/modules/enterprise/server/xml-schemas/src/test/java/org/rhq/enterprise/server/xmlschema/ConfigurationInstanceDescriptorUtilTest.java
+++ b/modules/enterprise/server/xml-schemas/src/test/java/org/rhq/enterprise/server/xmlschema/ConfigurationInstanceDescriptorUtilTest.java
@@ -21,8 +21,10 @@ package org.rhq.enterprise.server.xmlschema;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertNotNull;
import java.io.IOException;
+import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
@@ -30,6 +32,7 @@ import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlRootElement;
import org.apache.commons.logging.Log;
@@ -39,10 +42,12 @@ import org.testng.annotations.Test;
import org.rhq.core.clientapi.descriptor.configuration.MapProperty;
import org.rhq.core.clientapi.descriptor.configuration.SimpleProperty;
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.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;
@@ -73,10 +78,12 @@ public class ConfigurationInstanceDescriptorUtilTest {
}
private static final Marshaller CONFIGURATION_INSTANCE_MARSHALLER;
+ private static final Unmarshaller CONFIGURATION_INSTANCE_UNMARSHALLER;
static {
try {
JAXBContext context = JAXBContext.newInstance(StandaloneConfigurationInstance.class);
CONFIGURATION_INSTANCE_MARSHALLER = context.createMarshaller();
+ CONFIGURATION_INSTANCE_UNMARSHALLER = context.createUnmarshaller();
} catch (Exception e) {
throw new IllegalStateException("Failed to initialize the configuration instance marshaller.", e);
}
@@ -216,6 +223,211 @@ public class ConfigurationInstanceDescriptorUtilTest {
//TODO implement
}
+ public void testReverseSimplePropertyConversion() throws Exception {
+ String xml = "" +
+ "<standaloneConfigurationInstance xmlns:ci='urn:xmlns:rhq-configuration-instance' xmlns:c='urn:xmlns:rhq-configuration'>" +
+ " <ci:simple-property value='42' name='my-name' type='integer'/>" +
+ "</standaloneConfigurationInstance>";
+
+ ConfigurationInstanceDescriptor descriptor = (ConfigurationInstanceDescriptor) CONFIGURATION_INSTANCE_UNMARSHALLER.unmarshal(new StringReader(xml));
+
+ ConfigurationInstanceDescriptorUtil.ConfigurationAndDefinition ccd = ConfigurationInstanceDescriptorUtil.createConfigurationAndDefinition(descriptor);
+
+ ConfigurationDefinition def = ccd.definition;
+ Configuration conf = ccd.configuration;
+
+ assertEquals(def.getPropertyDefinitions().size(), 1, "Unexpected number of defined properties");
+ assertEquals(conf.getProperties().size(), 1, "Unexpected number of properties");
+
+ PropertyDefinition propDef = def.get("my-name");
+ Property prop = conf.get("my-name");
+
+ assertNotNull(propDef, "Could not find the expected property definition");
+ assertNotNull(prop, "Could not find the expected property");
+
+ assertEquals(propDef.getClass(), PropertyDefinitionSimple.class, "Unexpected type of the property definition");
+ assertEquals(prop.getClass(), PropertySimple.class, "Unexpecetd type of the property");
+
+ PropertyDefinitionSimple simpleDef = (PropertyDefinitionSimple) propDef;
+ PropertySimple simpleProp = (PropertySimple) prop;
+
+ assertEquals(simpleDef.getType(), PropertySimpleType.INTEGER, "Unexpected type of the simple property definition");
+ assertEquals(simpleProp.getIntegerValue(), Integer.valueOf(42), "Unexpected value of the simple property");
+ }
+
+ public void testReverseListPropertyConversion() throws Exception {
+ String xml = "" +
+ "<standaloneConfigurationInstance xmlns:ci='urn:xmlns:rhq-configuration-instance' xmlns:c='urn:xmlns:rhq-configuration'>" +
+ " <ci:list-property name='list'>" +
+ " <c:simple-property name='member' type='integer'/>" +
+ " <ci:values>" +
+ " <ci:simple-value value='1'/>" +
+ " <ci:simple-value value='2'/>" +
+ " <ci:simple-value value='3'/>" +
+ " </ci:values>" +
+ " </ci:list-property>" +
+ "</standaloneConfigurationInstance>";
+
+ ConfigurationInstanceDescriptor descriptor = (ConfigurationInstanceDescriptor) CONFIGURATION_INSTANCE_UNMARSHALLER.unmarshal(new StringReader(xml));
+
+ ConfigurationInstanceDescriptorUtil.ConfigurationAndDefinition ccd = ConfigurationInstanceDescriptorUtil.createConfigurationAndDefinition(descriptor);
+
+ ConfigurationDefinition def = ccd.definition;
+ Configuration conf = ccd.configuration;
+
+ assertEquals(def.getPropertyDefinitions().size(), 1, "Unexpected number of defined properties");
+ assertEquals(conf.getProperties().size(), 1, "Unexpected number of properties");
+
+ PropertyDefinition propDef = def.get("list");
+ Property prop = conf.get("list");
+
+ assertNotNull(propDef, "Could not find the expected property definition");
+ assertNotNull(prop, "Could not find the expected property");
+
+ assertEquals(propDef.getClass(), PropertyDefinitionList.class, "Unexpected type of the property definition");
+ assertEquals(prop.getClass(), PropertyList.class, "Unexpecetd type of the property");
+
+ PropertyDefinitionList listDef = (PropertyDefinitionList) propDef;
+ PropertyList listProp = (PropertyList) prop;
+
+ PropertyDefinition memberDef = listDef.getMemberDefinition();
+ assertEquals(memberDef.getClass(), PropertyDefinitionSimple.class, "Unexpected type of the list member property definition");
+
+ PropertyDefinitionSimple memberSimpleDef = (PropertyDefinitionSimple) memberDef;
+ assertEquals(memberSimpleDef.getName(), "member");
+ assertEquals(memberSimpleDef.getType(), PropertySimpleType.INTEGER);
+
+ assertEquals(listProp.getList().size(), 3, "Unexpected number of list members");
+
+ for(int i = 0; i < 3; ++i) {
+ Property memberProp = listProp.getList().get(i);
+ assertEquals(memberProp.getClass(), PropertySimple.class, "Unexpected type of the property in the list on index " + i);
+ assertEquals(memberProp.getName(), "member");
+ assertEquals(((PropertySimple)memberProp).getIntegerValue(), Integer.valueOf(i + 1));
+ }
+ }
+
+ public void testReverseMapPropertyConversion() throws Exception {
+ String xml = "" +
+ "<standaloneConfigurationInstance xmlns:ci='urn:xmlns:rhq-configuration-instance' xmlns:c='urn:xmlns:rhq-configuration'>" +
+ " <ci:map-property name='map'>" +
+ " <c:simple-property name='m1' type='integer'/>" +
+ " <c:simple-property name='m2' type='string'/>" +
+ " <ci:values>" +
+ " <ci:simple-value property-name='m1' value='1'/>" +
+ " <ci:simple-value property-name='m2' value='v'/>" +
+ " </ci:values>" +
+ " </ci:map-property>" +
+ "</standaloneConfigurationInstance>";
+
+ ConfigurationInstanceDescriptor descriptor = (ConfigurationInstanceDescriptor) CONFIGURATION_INSTANCE_UNMARSHALLER.unmarshal(new StringReader(xml));
+
+ ConfigurationInstanceDescriptorUtil.ConfigurationAndDefinition ccd = ConfigurationInstanceDescriptorUtil.createConfigurationAndDefinition(descriptor);
+
+ ConfigurationDefinition def = ccd.definition;
+ Configuration conf = ccd.configuration;
+
+ assertEquals(def.getPropertyDefinitions().size(), 1, "Unexpected number of defined properties");
+ assertEquals(conf.getProperties().size(), 1, "Unexpected number of properties");
+
+ PropertyDefinition propDef = def.get("map");
+ Property prop = conf.get("map");
+
+ assertNotNull(propDef, "Could not find the expected property definition");
+ assertNotNull(prop, "Could not find the expected property");
+
+ assertEquals(propDef.getClass(), PropertyDefinitionMap.class, "Unexpected type of the property definition");
+ assertEquals(prop.getClass(), PropertyMap.class, "Unexpecetd type of the property");
+
+ PropertyDefinitionMap mapDef = (PropertyDefinitionMap) propDef;
+ PropertyMap mapProp = (PropertyMap) prop;
+
+ assertEquals(mapDef.getPropertyDefinitions().size(), 2, "Unexpected number of map member definitions");
+ assertEquals(mapProp.getMap().size(), 2, "Unexpected number of map members");
+
+ PropertyDefinition m1Def = mapDef.get("m1");
+ PropertyDefinition m2Def = mapDef.get("m2");
+ Property m1Prop = mapProp.get("m1");
+ Property m2Prop = mapProp.get("m2");
+
+ assertEquals(m1Def.getClass(), PropertyDefinitionSimple.class);
+ assertEquals(m2Def.getClass(), PropertyDefinitionSimple.class);
+ assertEquals(m1Prop.getClass(), PropertySimple.class);
+ assertEquals(m2Prop.getClass(), PropertySimple.class);
+
+ PropertyDefinitionSimple m1SimpleDef = (PropertyDefinitionSimple) m1Def;
+ PropertyDefinitionSimple m2SimpleDef = (PropertyDefinitionSimple) m2Def;
+ PropertySimple m1SimpleProp = (PropertySimple) m1Prop;
+ PropertySimple m2SimpleProp = (PropertySimple) m2Prop;
+
+ assertEquals(m1SimpleDef.getName(), "m1");
+ assertEquals(m2SimpleDef.getName(), "m2");
+ assertEquals(m1SimpleDef.getType(), PropertySimpleType.INTEGER);
+ assertEquals(m2SimpleDef.getType(), PropertySimpleType.STRING);
+
+ assertEquals(m1SimpleProp.getName(), "m1");
+ assertEquals(m2SimpleProp.getName(), "m2");
+ assertEquals(m1SimpleProp.getIntegerValue(), Integer.valueOf(1));
+ assertEquals(m2SimpleProp.getStringValue(), "v");
+ }
+
+ public void testReverseListOfMapsConversion() throws Exception {
+ String xml = "" +
+ "<standaloneConfigurationInstance xmlns:ci='urn:xmlns:rhq-configuration-instance' xmlns:c='urn:xmlns:rhq-configuration'>" +
+ " <ci:list-property name='list'>" +
+ " <c:map-property name='map'>" +
+ " <c:simple-property name='m1' type='integer'/>" +
+ " <c:simple-property name='m2' type='string'/>" +
+ " </c:map-property>" +
+ " <ci:values>" +
+ " <ci:map-value>" +
+ " <ci:simple-value property-name='m1' value='1'/>" +
+ " <ci:simple-value property-name='m2' value='m1'/>" +
+ " </ci:map-value>" +
+ " <ci:map-value>" +
+ " <ci:simple-value property-name='m1' value='2'/>" +
+ " <ci:simple-value property-name='m2' value='m2'/>" +
+ " </ci:map-value>" +
+ " </ci:values>" +
+ " </ci:list-property>" +
+ "</standaloneConfigurationInstance>";
+
+ ConfigurationInstanceDescriptor descriptor = (ConfigurationInstanceDescriptor) CONFIGURATION_INSTANCE_UNMARSHALLER.unmarshal(new StringReader(xml));
+
+ ConfigurationInstanceDescriptorUtil.ConfigurationAndDefinition ccd = ConfigurationInstanceDescriptorUtil.createConfigurationAndDefinition(descriptor);
+
+ ConfigurationDefinition def = ccd.definition;
+ Configuration conf = ccd.configuration;
+
+ assertEquals(def.getPropertyDefinitions().size(), 1, "Unexpected number of defined properties");
+ assertEquals(conf.getProperties().size(), 1, "Unexpected number of properties");
+
+ PropertyDefinitionList listDef = (PropertyDefinitionList) def.get("list");
+ PropertyList listProp = (PropertyList) conf.get("list");
+
+ PropertyDefinitionMap mapDef = (PropertyDefinitionMap) listDef.getMemberDefinition();
+ PropertyDefinitionSimple m1Def = (PropertyDefinitionSimple) mapDef.get("m1");
+ PropertyDefinitionSimple m2Def = (PropertyDefinitionSimple) mapDef.get("m2");
+
+ assertEquals(mapDef.getName(), "map");
+ assertEquals(m1Def.getType(), PropertySimpleType.INTEGER);
+ assertEquals(m2Def.getType(), PropertySimpleType.STRING);
+
+ assertEquals(listProp.getList().size(), 2, "Unexpected number of maps in the list");
+
+ PropertyMap firstMapValue = (PropertyMap) listProp.getList().get(0);
+ PropertyMap secondMapValue = (PropertyMap) listProp.getList().get(1);
+
+ assertEquals(firstMapValue.getName(), "map");
+ assertEquals(secondMapValue.getName(), "map");
+
+ assertEquals(firstMapValue.getSimpleValue("m1", null), "1", "Unexpected value of m1 property in the first map.");
+ assertEquals(firstMapValue.getSimpleValue("m2", null), "m1", "Unexpected value of m2 property in the first map.");
+
+ assertEquals(secondMapValue.getSimpleValue("m1", null), "2", "Unexpected value of m1 property in the second map.");
+ assertEquals(secondMapValue.getSimpleValue("m2", null), "m2", "Unexpected value of m2 property in the second map.");
+ }
+
private static void logInstance(String message, ConfigurationInstanceDescriptor instance) throws JAXBException,
IOException {
StringWriter wrt = new StringWriter();
12 years, 8 months