This is an automated email from the ASF dual-hosted git repository.
davidb pushed a commit to branch features-service
in repository
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-launcher.git
The following commit(s) were added to refs/heads/features-service by this push:
new 734180e Make the launcher capable of configuring additional services
734180e is described below
commit 734180e2d7e137cf34e66dc5bcfc495a7d5ee994
Author: David Bosschaert <[email protected]>
AuthorDate: Thu Jul 12 22:18:59 2018 +0200
Make the launcher capable of configuring additional services
---
.../feature/launcher/impl/FeatureProcessor.java | 100 ++-------------------
.../sling/feature/launcher/impl/Installation.java | 9 ++
.../apache/sling/feature/launcher/impl/Main.java | 1 +
.../launcher/impl/launchers/AbstractRunner.java | 28 +++++-
.../launcher/impl/launchers/FrameworkLauncher.java | 6 +-
.../launcher/impl/launchers/FrameworkRunner.java | 5 +-
.../feature/launcher/spi/LauncherRunContext.java | 6 ++
7 files changed, 55 insertions(+), 100 deletions(-)
diff --git
a/src/main/java/org/apache/sling/feature/launcher/impl/FeatureProcessor.java
b/src/main/java/org/apache/sling/feature/launcher/impl/FeatureProcessor.java
index 123f957..053f7d0 100644
--- a/src/main/java/org/apache/sling/feature/launcher/impl/FeatureProcessor.java
+++ b/src/main/java/org/apache/sling/feature/launcher/impl/FeatureProcessor.java
@@ -27,33 +27,22 @@ import org.apache.sling.feature.io.ArtifactManager;
import org.apache.sling.feature.io.json.ApplicationJSONReader;
import org.apache.sling.feature.io.json.ApplicationJSONWriter;
import org.apache.sling.feature.launcher.impl.LauncherConfig.StartupMode;
-import org.osgi.framework.Constants;
-import org.osgi.util.converter.Converter;
-import org.osgi.util.converter.Converters;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.Hashtable;
import java.util.List;
import java.util.Map;
-import java.util.jar.Attributes;
-import java.util.jar.JarFile;
-import java.util.stream.Collectors;
import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonObject;
import javax.json.JsonReader;
-import javax.json.JsonValue;
-import javax.json.JsonValue.ValueType;
public class FeatureProcessor {
- private static final String FEATURES_SERVICE_PID =
"org.apache.sling.feature.service.impl.FeaturesServiceImpl";
+ private static final String FEATURES_SERVICE_FACTORY =
"org.apache.sling.feature.service.FeaturesFactory";
private static final String WHITELIST_ENFORCER_PID =
"org.apache.sling.feature.whitelist.impl.WhitelistEnforcer";
/**
@@ -107,44 +96,14 @@ public class FeatureProcessor {
public static void prepareLauncher(final LauncherConfig config,
final ArtifactManager artifactManager,
final Application app) throws Exception {
- Dictionary<String, Object> bundleFeatureMap = new Hashtable<>();
- Converter converter = Converters.standardConverter();
-
- List<String> featureIDs =
- app.getFeatureIds().stream().map(i ->
i.toMvnId()).collect(Collectors.toList());
-
for(final Map.Entry<Integer, List<Artifact>> entry :
app.getBundles().getBundlesByStartOrder().entrySet()) {
for(final Artifact a : entry.getValue()) {
final ArtifactHandler handler =
artifactManager.getArtifactHandler(":" + a.getId().toMvnPath());
final File artifactFile = handler.getFile();
- String bsn = getBsn(artifactFile);
config.getInstallation().addBundle(entry.getKey(),
artifactFile);
-
- String ff = a.getMetadata().get("from-feature");
- if (ff != null) {
- String[] fl = ff.split(",");
- Object cfg = null;
- if (fl.length != 1) {
- List<String> fids = new ArrayList<>();
- for(String foid : fl) {
- int fidx = converter.convert(foid).to(int.class);
- if (featureIDs.size() > fidx) {
- fids.add(featureIDs.get(fidx));
- }
- }
- cfg = fids;
- } else {
- int fidx = converter.convert(fl[0]).to(int.class);
- if (featureIDs.size() > fidx) {
- cfg = featureIDs.get(fidx);
- }
- }
- bundleFeatureMap.put(bsn, cfg);
- }
}
}
- config.getInstallation().addConfiguration(FEATURES_SERVICE_PID, null,
bundleFeatureMap);
int index = 1;
for(final Extension ext : app.getExtensions()) {
@@ -182,51 +141,13 @@ public class FeatureProcessor {
index++;
cfg.getProperties().put("scripts", text);
config.getInstallation().addConfiguration(cfg.getName(),
cfg.getFactoryPid(), cfg.getProperties());
- } else if (
ext.getName().equals(FeatureConstants.EXTENSION_NAME_API_REGION) ) {
- Dictionary<String, List<String>> whitelistConfiguration = new
Hashtable<>();
+ } else if ( ext.getName().equals("bundle-feature-mapping") ) {
try (JsonReader reader = Json.createReader(new
StringReader(ext.getJSON()))) {
- JsonArray array = reader.readArray();
- for (JsonValue jv : array) {
- if (jv instanceof JsonObject) {
- JsonObject jo = (JsonObject) jv;
- String name = jo.getString("name");
- String featureIdx = jo.getString("from-feature");
- JsonArray exports = jo.getJsonArray("exports");
- int fidx =
converter.convert(featureIdx).to(int.class);
- if (featureIDs.size() > fidx) {
- String featureID = featureIDs.get(fidx);
- if (featureID != null) {
- String featureKey = "whitelist.feature." +
featureID;
- List<String> regions =
whitelistConfiguration.get(featureKey);
- if (regions == null) {
- regions = new ArrayList<>();
- whitelistConfiguration.put(featureKey,
regions);
- }
- if (!regions.contains(name)) {
- regions.add(name);
- }
- }
- }
-
- String packagesKey = "whitelist.region." + name;
- List<String> packages =
whitelistConfiguration.get(packagesKey);
- if (packages == null) {
- packages = new ArrayList<>();
- whitelistConfiguration.put(packagesKey,
packages);
- }
- for (JsonValue pkg : exports) {
- if (pkg.getValueType() == ValueType.STRING) {
- String p = pkg.toString();
- if (!packages.contains(p)) {
- packages.add(p);
- }
- }
- }
- }
- }
+ JsonArray array = reader.readArray();
+ JsonObject jo = array.getJsonObject(0);
+
config.getInstallation().getAdditionalOptions().put(FEATURES_SERVICE_FACTORY,
jo);
}
-
config.getInstallation().addConfiguration(WHITELIST_ENFORCER_PID, null,
whitelistConfiguration);
} else {
if ( ext.isRequired() ) {
throw new Exception("Unknown required extension " +
ext.getName());
@@ -248,15 +169,4 @@ public class FeatureProcessor {
}
}
}
-
- private static String getBsn(File artifactFile) throws IOException {
- try (JarFile jf = new JarFile(artifactFile)) {
- Attributes attrs = jf.getManifest().getMainAttributes();
- String bsn = attrs.getValue(Constants.BUNDLE_SYMBOLICNAME);
- String version = attrs.getValue(Constants.BUNDLE_VERSION);
- if (version == null)
- version = "0.0.0";
- return bsn + ":" + version;
- }
- }
}
diff --git
a/src/main/java/org/apache/sling/feature/launcher/impl/Installation.java
b/src/main/java/org/apache/sling/feature/launcher/impl/Installation.java
index 1f9eafc..54a124f 100644
--- a/src/main/java/org/apache/sling/feature/launcher/impl/Installation.java
+++ b/src/main/java/org/apache/sling/feature/launcher/impl/Installation.java
@@ -45,6 +45,9 @@ public class Installation implements LauncherRunContext {
/** The list of app jars. */
private final List<File> appJars = new ArrayList<>();
+ /** Additional options. */
+ private final Map<String, Object> additionalOptions = new HashMap<>();
+
/**
* Add an application jar.
* @param jar The application jar
@@ -125,6 +128,11 @@ public class Installation implements LauncherRunContext {
return this.installables;
}
+ @Override
+ public Map<String, Object> getAdditionalOptions() {
+ return this.additionalOptions;
+ }
+
/**
* Clear all in-memory objects
*/
@@ -133,5 +141,6 @@ public class Installation implements LauncherRunContext {
this.fwkProperties.clear();
this.bundleMap.clear();
this.installables.clear();
+ this.additionalOptions.clear();
}
}
diff --git a/src/main/java/org/apache/sling/feature/launcher/impl/Main.java
b/src/main/java/org/apache/sling/feature/launcher/impl/Main.java
index 7b2c7ca..6c52e8d 100644
--- a/src/main/java/org/apache/sling/feature/launcher/impl/Main.java
+++ b/src/main/java/org/apache/sling/feature/launcher/impl/Main.java
@@ -216,6 +216,7 @@ public class Main {
launcherConfig.getInstallation().getBundleMap().clear();
launcherConfig.getInstallation().getConfigurations().clear();
launcherConfig.getInstallation().getInstallableArtifacts().clear();
+ launcherConfig.getInstallation().getAdditionalOptions().clear();
}
try {
run(launcherConfig);
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 33781ab..9a3433c 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
@@ -75,6 +75,8 @@ public abstract class AbstractRunner implements
Callable<Integer> {
private final List<File> installables;
+ private final Map<String, ?> options;
+
private final int targetStartlevel;
private final AtomicInteger waitRequested = new AtomicInteger(0);
@@ -82,9 +84,10 @@ public abstract class AbstractRunner implements
Callable<Integer> {
private volatile boolean install;
public AbstractRunner(final Map<String, String> frameworkProperties, final
List<Object[]> configurations,
- final List<File> installables) {
+ final List<File> installables, final Map<String, ?> options) {
this.configurations = new ArrayList<>(configurations);
this.installables = installables;
+ this.options = options;
String target =
frameworkProperties.get(Constants.FRAMEWORK_BEGINNING_STARTLEVEL);
if (target != null) {
@@ -165,6 +168,29 @@ public abstract class AbstractRunner implements
Callable<Integer> {
});
this.installerTracker.open();
}
+ for (Map.Entry<String, ?> entry : options.entrySet()) {
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ ServiceTracker tracker = new
ServiceTracker(framework.getBundleContext(), entry.getKey(), null) {
+ @Override
+ public Object addingService(ServiceReference reference) {
+ close(); // Stop tracking additional services
+
+ Object svc = super.addingService(reference);
+ for (Method m : svc.getClass().getMethods()) {
+ if ("initialize".equals(m.getName())) {
+ try {
+ m.setAccessible(true);
+ m.invoke(svc, entry.getValue());
+ } catch (Exception e) {
+ throw new RuntimeException("Cannot initialize
service " + entry.getKey(), e);
+ }
+ }
+ }
+ return svc;
+ }
+ };
+ tracker.open();
+ }
try {
this.install(framework, bundlesMap);
diff --git
a/src/main/java/org/apache/sling/feature/launcher/impl/launchers/FrameworkLauncher.java
b/src/main/java/org/apache/sling/feature/launcher/impl/launchers/FrameworkLauncher.java
index d5790ee..6db8626 100644
---
a/src/main/java/org/apache/sling/feature/launcher/impl/launchers/FrameworkLauncher.java
+++
b/src/main/java/org/apache/sling/feature/launcher/impl/launchers/FrameworkLauncher.java
@@ -109,12 +109,14 @@ public class FrameworkLauncher implements Launcher {
}
final Class<?> runnerClass =
cl.loadClass(FrameworkRunner.class.getName());
- final Constructor<?> constructor =
runnerClass.getDeclaredConstructor(Map.class, Map.class, List.class,
List.class);
+ final Constructor<?> constructor = runnerClass.getDeclaredConstructor(
+ Map.class, Map.class, List.class, List.class, Map.class);
constructor.setAccessible(true);
Callable<Integer> restart = (Callable<Integer>)
constructor.newInstance(properties,
context.getBundleMap(),
context.getConfigurations(),
- context.getInstallableArtifacts());
+ context.getInstallableArtifacts(),
+ context.getAdditionalOptions());
return restart.call();
// nothing else to do, constructor starts everything
diff --git
a/src/main/java/org/apache/sling/feature/launcher/impl/launchers/FrameworkRunner.java
b/src/main/java/org/apache/sling/feature/launcher/impl/launchers/FrameworkRunner.java
index 25ce117..7877c7c 100644
---
a/src/main/java/org/apache/sling/feature/launcher/impl/launchers/FrameworkRunner.java
+++
b/src/main/java/org/apache/sling/feature/launcher/impl/launchers/FrameworkRunner.java
@@ -39,8 +39,9 @@ public class FrameworkRunner extends AbstractRunner {
public FrameworkRunner(final Map<String, String> frameworkProperties,
final Map<Integer, List<File>> bundlesMap,
final List<Object[]> configurations,
- final List<File> installables) throws Exception {
- super(frameworkProperties, configurations, installables);
+ final List<File> installables,
+ final Map<String, ?> options) throws Exception {
+ super(frameworkProperties, configurations, installables, options);
final ServiceLoader<FrameworkFactory> loader =
ServiceLoader.load(FrameworkFactory.class);
FrameworkFactory factory = null;
diff --git
a/src/main/java/org/apache/sling/feature/launcher/spi/LauncherRunContext.java
b/src/main/java/org/apache/sling/feature/launcher/spi/LauncherRunContext.java
index 20c95a9..e2169a0 100644
---
a/src/main/java/org/apache/sling/feature/launcher/spi/LauncherRunContext.java
+++
b/src/main/java/org/apache/sling/feature/launcher/spi/LauncherRunContext.java
@@ -55,4 +55,10 @@ public interface LauncherRunContext {
* @return The list of files. The list might be empty.
*/
List<File> getInstallableArtifacts();
+
+ /**
+ * Additional data used by the launcher
+ * @return The map of additional data
+ */
+ Map<String, Object> getAdditionalOptions();
}