SLING-4272 : Issues in handling of configurations wrt update handling and write back
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1648985 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/test/java/org/apache/sling/installer/it/ConfigInstallTest.java b/src/test/java/org/apache/sling/installer/it/ConfigInstallTest.java
index 1dfc9f0..a972d5f 100644
--- a/src/test/java/org/apache/sling/installer/it/ConfigInstallTest.java
+++ b/src/test/java/org/apache/sling/installer/it/ConfigInstallTest.java
@@ -151,7 +151,7 @@
}
@Test
- public void testInstallUpdateRemoveConfig() throws Exception {
+ public void testInstallUpdateRemoveConfigResource() throws Exception {
final Dictionary<String, Object> cfgData = new Hashtable<String, Object>();
cfgData.put("foo", "bar");
final String cfgPid = getClass().getSimpleName() + "." + uniqueID();
@@ -189,7 +189,7 @@
}
@Test
- public void testInstallUpdateRemoveTemplateConfig() throws Exception {
+ public void testInstallUpdateRemoveTemplateConfigResource() throws Exception {
final Dictionary<String, Object> cfgData = new Hashtable<String, Object>();
cfgData.put("foo", "bar");
cfgData.put(InstallableResource.RESOURCE_IS_TEMPLATE, "true");
@@ -228,6 +228,85 @@
}
@Test
+ public void testInstallUpdateRemoveConfigFactoryResource() throws Exception {
+ final Dictionary<String, Object> cfgData = new Hashtable<String, Object>();
+ cfgData.put("foo", "bar");
+ final String cfgFactoryPid = getClass().getSimpleName() + "." + uniqueID();
+ final String alias = "alias" + uniqueID();
+ assertNull("Factory config " + cfgFactoryPid + " must not be found before test", findFactoryConfiguration(cfgFactoryPid));
+
+ // install factory config
+ final InstallableResource rsrc = new InstallableResource("/configA/" + cfgFactoryPid + "-" + alias,
+ null, cfgData, null, InstallableResource.TYPE_PROPERTIES, 10);
+ installer.updateResources(URL_SCHEME, new InstallableResource[] {rsrc}, null);
+
+ // get factory config
+ final Configuration cfg = waitForFactoryConfiguration("After installing", cfgFactoryPid, TIMEOUT, true);
+ assertEquals("Config value must match", "bar", cfg.getProperties().get("foo"));
+
+ // create second factory configuration with same alias
+ final Dictionary<String, Object> secondData = new Hashtable<String, Object>();
+ secondData.put("foo", "bla");
+ final InstallableResource rsrc2 = new InstallableResource("/configB/" + cfgFactoryPid + "-" + alias,
+ null, secondData, null, InstallableResource.TYPE_PROPERTIES, 20);
+ installer.updateResources(URL_SCHEME, new InstallableResource[] {rsrc2}, null);
+
+ sleep(200);
+
+ // get updated factory config
+ final Configuration secondCfg = waitForFactoryConfiguration("After updating", cfgFactoryPid, TIMEOUT, true);
+ assertEquals("Config value must match", "bla", secondCfg.getProperties().get("foo"));
+
+ // remove factory config
+ installer.updateResources(URL_SCHEME, null, new String[] {"/configB/" + cfgFactoryPid + "-" + alias});
+
+ sleep(200);
+
+ final Configuration origCfg = waitForFactoryConfiguration("After deleting", cfgFactoryPid, TIMEOUT, true);
+ assertEquals("Config value must match", "bar", origCfg.getProperties().get("foo"));
+ }
+
+ @Test
+ public void testInstallUpdateRemoveTemplateConfigFactoryResource() throws Exception {
+ final Dictionary<String, Object> cfgData = new Hashtable<String, Object>();
+ cfgData.put("foo", "bar");
+ cfgData.put(InstallableResource.RESOURCE_IS_TEMPLATE, "true");
+ final String cfgFactoryPid = getClass().getSimpleName() + "." + uniqueID();
+ final String alias = "alias" + uniqueID();
+ assertNull("Factory config " + cfgFactoryPid + " must not be found before test", findFactoryConfiguration(cfgFactoryPid));
+
+ // install factory config
+ final InstallableResource rsrc = new InstallableResource("/configA/" + cfgFactoryPid + "-" + alias,
+ null, cfgData, null, InstallableResource.TYPE_PROPERTIES, 10);
+ installer.updateResources(URL_SCHEME, new InstallableResource[] {rsrc}, null);
+
+ // get factory config
+ final Configuration cfg = waitForFactoryConfiguration("After installing", cfgFactoryPid, TIMEOUT, true);
+ assertEquals("Config value must match", "bar", cfg.getProperties().get("foo"));
+
+ // create second factory configuration
+ final Dictionary<String, Object> secondData = new Hashtable<String, Object>();
+ secondData.put("foo", "bla");
+ final InstallableResource rsrc2 = new InstallableResource("/configB/" + cfgFactoryPid + "-" + alias,
+ null, secondData, null, InstallableResource.TYPE_PROPERTIES, 20);
+ installer.updateResources(URL_SCHEME, new InstallableResource[] {rsrc2}, null);
+
+ sleep(200);
+
+ // get updated factory config
+ final Configuration secondCfg = waitForFactoryConfiguration("After updating", cfgFactoryPid, TIMEOUT, true);
+ assertEquals("Config value must match", "bla", secondCfg.getProperties().get("foo"));
+
+ // remove config
+ installer.updateResources(URL_SCHEME, null, new String[] {"/configB/" + cfgFactoryPid + "-" + alias});
+
+ sleep(200);
+
+ final Configuration noCfg = waitForFactoryConfiguration("After deleting", cfgFactoryPid, TIMEOUT, false);
+ assertNull("Factory configuration should be removed", noCfg);
+ }
+
+ @Test
public void testDeferredConfigInstall() throws Exception {
// get config admin bundle and wait for service
final Bundle configAdmin = this.getConfigAdminBundle();
diff --git a/src/test/java/org/apache/sling/installer/it/OsgiInstallerTestBase.java b/src/test/java/org/apache/sling/installer/it/OsgiInstallerTestBase.java
index 6ce5595..d35b954 100644
--- a/src/test/java/org/apache/sling/installer/it/OsgiInstallerTestBase.java
+++ b/src/test/java/org/apache/sling/installer/it/OsgiInstallerTestBase.java
@@ -187,23 +187,51 @@
}
}
- protected Configuration findConfiguration(String pid) throws Exception {
+ /**
+ * Encode the value for the ldap filter: \, *, (, and ) should be escaped.
+ */
+ private static String encode(final String value) {
+ return value.replace("\\", "\\\\")
+ .replace("*", "\\*")
+ .replace("(", "\\(")
+ .replace(")", "\\)");
+ }
+
+ /**
+ * Find the configuration with the given pid.
+ */
+ protected Configuration findConfiguration(final String pid) throws Exception {
final ConfigurationAdmin ca = this.waitForConfigAdmin(true);
if (ca != null) {
- final Configuration[] cfgs = ca.listConfigurations(null);
- if (cfgs != null) {
- for(Configuration cfg : cfgs) {
- try {
- if(cfg.getPid().equals(pid)) {
- return cfg;
- }
- } catch (IllegalStateException e) {}
- }
+ final Configuration[] cfgs = ca.listConfigurations("(" + Constants.SERVICE_PID + "=" + encode(pid) + ")");
+ if (cfgs != null && cfgs.length > 0 ) {
+ if ( cfgs.length == 1 ) {
+ return cfgs[0];
+ }
+ throw new IllegalStateException("More than one configuration for " + pid);
}
}
return null;
}
+ /**
+ * Find the configuration with the given factory pid.
+ */
+ protected Configuration findFactoryConfiguration(final String factoryPid) throws Exception {
+ final ConfigurationAdmin ca = this.waitForConfigAdmin(true);
+ if (ca != null) {
+ final Configuration[] cfgs = ca.listConfigurations("("
+ + ConfigurationAdmin.SERVICE_FACTORYPID + "=" + encode(factoryPid) + ")");
+ if (cfgs != null && cfgs.length > 0 ) {
+ if ( cfgs.length == 1 ) {
+ return cfgs[0];
+ }
+ throw new IllegalStateException("More than one factory configuration for " + factoryPid);
+ }
+ }
+ return null;
+ }
+
protected void waitForCondition(String info, long timeoutMsec, Condition c) throws Exception {
final long end = System.currentTimeMillis() + timeoutMsec;
do {
@@ -262,6 +290,40 @@
return result;
}
+ protected Configuration waitForFactoryConfiguration(final String info,
+ final String factoryPid,
+ final long timeoutMsec,
+ final boolean shouldBePresent)
+ throws Exception {
+ String msg;
+ if (info == null) {
+ msg = "";
+ } else {
+ msg = info + ": ";
+ }
+
+ Configuration result = null;
+ final long start = System.currentTimeMillis();
+ final long end = start + timeoutMsec;
+ log(LogService.LOG_DEBUG, "Starting factory config check at " + start + "; ending by " + end);
+ do {
+ result = findFactoryConfiguration(factoryPid);
+ if ((shouldBePresent && result != null) ||
+ (!shouldBePresent && result == null)) {
+ break;
+ }
+ log(LogService.LOG_DEBUG, "Config check failed at " + System.currentTimeMillis() + "; sleeping");
+ sleep(25);
+ } while(System.currentTimeMillis() < end);
+
+ if (shouldBePresent && result == null) {
+ fail(msg + "Factory Configuration not found (" + factoryPid + ")");
+ } else if (!shouldBePresent && result != null) {
+ fail(msg + "Factory Configuration is still present (" + factoryPid + ")");
+ }
+ return result;
+ }
+
protected Bundle findBundle(String symbolicName) {
for(Bundle b : bundleContext.getBundles()) {
if (symbolicName.equals(b.getSymbolicName())) {