You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2019/06/20 15:33:52 UTC
[sling-org-apache-sling-feature-launcher] branch master updated:
SLING-8525 : Provide a Configuration PersistenceManager
This is an automated email from the ASF dual-hosted git repository.
cziegeler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-launcher.git
The following commit(s) were added to refs/heads/master by this push:
new e3e69f1 SLING-8525 : Provide a Configuration PersistenceManager
e3e69f1 is described below
commit e3e69f1fe5f700a32ee1f413a7fc983a1fb0c7bb
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Thu Jun 20 17:33:42 2019 +0200
SLING-8525 : Provide a Configuration PersistenceManager
---
.../launcher/impl/launchers/AbstractRunner.java | 138 +++++++++++++++++----
1 file changed, 113 insertions(+), 25 deletions(-)
diff --git a/src/main/java/org/apache/sling/feature/launcher/impl/launchers/AbstractRunner.java b/src/main/java/org/apache/sling/feature/launcher/impl/launchers/AbstractRunner.java
index 4229e49..d3c35b8 100644
--- a/src/main/java/org/apache/sling/feature/launcher/impl/launchers/AbstractRunner.java
+++ b/src/main/java/org/apache/sling/feature/launcher/impl/launchers/AbstractRunner.java
@@ -20,6 +20,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
@@ -42,7 +43,9 @@ import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
import org.osgi.framework.launch.Framework;
import org.osgi.framework.startlevel.BundleStartLevel;
import org.osgi.util.tracker.ServiceTracker;
@@ -55,6 +58,19 @@ import org.slf4j.LoggerFactory;
*/
public abstract class AbstractRunner implements Callable<Integer> {
+ /**
+ * Configuration property for Apache Felix Configuration Admin persistence
+ * manager.
+ */
+ private static final String CM_CONFIG_PM = "felix.cm.pm";
+
+ /** Name of the feature launcher persistence manager. */
+ private static final String PM_FEATURE_LAUNCHER = "featurelauncher";
+
+ /** Filter expression to get the memory persistence manager. */
+ private static final String PM_MEMORY_FILTER = "(&(" + Constants.OBJECTCLASS
+ + "=org.apache.felix.cm.PersistenceManager)(name=memory))";
+
private volatile ServiceTracker<Object, Object> configAdminTracker;
private volatile ServiceTracker<Object, Object> installerTracker;
@@ -68,40 +84,112 @@ public abstract class AbstractRunner implements Callable<Integer> {
public AbstractRunner(final List<Object[]> configurations, final List<URL> installables) {
this.configurations = new ArrayList<>(configurations);
this.installables = installables;
- logger = LoggerFactory.getLogger("launcher");
+ this.logger = LoggerFactory.getLogger("launcher");
}
protected void setupFramework(final Framework framework, final Map<Integer, List<URL>> bundlesMap) throws BundleException {
if ( !configurations.isEmpty() ) {
- this.configAdminTracker = new ServiceTracker<>(framework.getBundleContext(),
- "org.osgi.service.cm.ConfigurationAdmin",
- new ServiceTrackerCustomizer<Object, Object>() {
+ // check for Apache Felix CM persistence manager config
+ final String pm = framework.getBundleContext().getProperty(CM_CONFIG_PM);
+ if (PM_FEATURE_LAUNCHER.equals(pm)) {
+ logger.info("Using feature launcher configuration admin persistence manager");
+ try {
+ // we start a tracker for the memory PM
+ this.configAdminTracker = new ServiceTracker<>(framework.getBundleContext(),
+ framework.getBundleContext().createFilter(PM_MEMORY_FILTER),
+
+ new ServiceTrackerCustomizer<Object, Object>() {
+ private volatile ServiceRegistration<?> reg;
+
+ @Override
+ public Object addingService(final ServiceReference<Object> reference) {
+ // get memory pm
+ final Object memoryPM = framework.getBundleContext().getService(reference);
+ if (memoryPM != null) {
+ try {
+ // we re use the memory PM (it is not used anyway)
+ // and simply store the configs there using reflection
+ final Method storeMethod = memoryPM.getClass().getDeclaredMethod("store",
+ String.class, Dictionary.class);
+ for (final Object[] obj : configurations) {
+ @SuppressWarnings("unchecked")
+ final Dictionary<String, Object> props = (Dictionary<String, Object>) obj[2];
+ final String pid;
+ if (obj[1] != null) {
+ final String factoryPid = (String) obj[1];
+ pid = factoryPid.concat("~").concat((String) obj[0]);
+ props.put("service.factoryPid", factoryPid);
+ } else {
+ pid = (String) obj[0];
+ }
+ props.put(Constants.SERVICE_PID, pid);
+ storeMethod.invoke(memoryPM, pid, props);
+ }
+ // register feature launcher pm
+ final Dictionary<String, Object> properties = new Hashtable<>();
+ properties.put("name", PM_FEATURE_LAUNCHER);
+ reg = reference.getBundle().getBundleContext().registerService(
+ "org.apache.felix.cm.PersistenceManager", memoryPM, properties);
+ } catch (IllegalAccessException | IllegalArgumentException
+ | InvocationTargetException | NoSuchMethodException
+ | SecurityException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return memoryPM;
+ }
- @Override
- public Object addingService(final ServiceReference<Object> reference) {
- // get config admin
- final Object cm = framework.getBundleContext().getService(reference);
- if ( cm != null ) {
- try {
- configure(cm);
- } finally {
- framework.getBundleContext().ungetService(reference);
+ @Override
+ public void modifiedService(ServiceReference<Object> reference, Object service) {
+ // nothing to do
+ }
+
+ @Override
+ public void removedService(ServiceReference<Object> reference, Object service) {
+ if (reg != null) {
+ reg.unregister();
+ reg = null;
+ }
+ reference.getBundle().getBundleContext().ungetService(reference);
}
+ });
+ } catch (final InvalidSyntaxException e) {
+ // the filter is constant so this should really not happen
+ throw new RuntimeException(e);
+ }
+ this.configAdminTracker.open();
+
+ } else {
+ this.configAdminTracker = new ServiceTracker<>(framework.getBundleContext(),
+ "org.osgi.service.cm.ConfigurationAdmin",
+ new ServiceTrackerCustomizer<Object, Object>() {
+
+ @Override
+ public Object addingService(final ServiceReference<Object> reference) {
+ // get config admin
+ final Object cm = framework.getBundleContext().getService(reference);
+ if ( cm != null ) {
+ try {
+ configure(cm);
+ } finally {
+ framework.getBundleContext().ungetService(reference);
+ }
+ }
+ return null;
}
- return null;
- }
- @Override
- public void modifiedService(ServiceReference<Object> reference, Object service) {
- // nothing to do
- }
+ @Override
+ public void modifiedService(ServiceReference<Object> reference, Object service) {
+ // nothing to do
+ }
- @Override
- public void removedService(ServiceReference<Object> reference, Object service) {
- // nothing to do
- }
- });
- this.configAdminTracker.open();
+ @Override
+ public void removedService(ServiceReference<Object> reference, Object service) {
+ // nothing to do
+ }
+ });
+ this.configAdminTracker.open();
+ }
}
if ( !installables.isEmpty() ) {
this.installerTracker = new ServiceTracker<>(framework.getBundleContext(),