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 80ffa27 SLING-9413 : Provide the Ability for the Launcher to start
with Feature Archive(s)
80ffa27 is described below
commit 80ffa27a832989fbdf42cde2181cbdcde2826601
Author: Carsten Ziegeler <[email protected]>
AuthorDate: Fri May 1 14:40:33 2020 +0200
SLING-9413 : Provide the Ability for the Launcher to start with Feature
Archive(s)
---
pom.xml | 28 +++++---
.../sling/feature/launcher/impl/Bootstrap.java | 5 +-
.../feature/launcher/impl/FeatureProcessor.java | 79 +++++++++++++++++-----
.../sling/feature/launcher/impl/Installation.java | 1 -
.../feature/launcher/impl/LauncherConfig.java | 10 +--
.../apache/sling/feature/launcher/impl/Main.java | 15 ++--
.../launcher/impl/launchers/FrameworkLauncher.java | 1 +
7 files changed, 98 insertions(+), 41 deletions(-)
diff --git a/pom.xml b/pom.xml
index 5a039e3..0f5f5f1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -56,7 +56,7 @@
<outputDirectory>${project.build.directory}/classes</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
-
<includeArtifactIds>osgi.core,commons-text,org.apache.sling.feature,org.apache.sling.feature.io,org.apache.sling.commons.johnzon,org.apache.felix.converter,commons-cli,slf4j-api,slf4j-simple</includeArtifactIds>
+
<includeArtifactIds>osgi.core,commons-text,commons-lang3,org.apache.sling.feature,org.osgi.util.function,org.apache.felix.cm.json,org.apache.sling.commons.johnzon,org.apache.felix.converter,commons-cli,slf4j-api,slf4j-simple</includeArtifactIds>
</configuration>
</execution>
</executions>
@@ -95,6 +95,12 @@
<scope>provided</scope>
</dependency>
<dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <version>3.10</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.core</artifactId>
<version>7.0.0</version>
@@ -113,19 +119,25 @@
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.feature</artifactId>
- <version>1.1.8</version>
+ <version>1.2.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.feature.io</artifactId>
- <version>1.3.0</version>
- <scope>provided</scope>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.util.function</artifactId>
+ <version>1.0.0</version>
+ <scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.converter</artifactId>
- <version>1.0.12</version>
+ <version>1.0.14</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.cm.json</artifactId>
+ <version>1.0.2</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -137,7 +149,7 @@
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.commons.johnzon</artifactId>
- <version>1.1.0</version>
+ <version>1.2.2</version>
<scope>provided</scope>
</dependency>
diff --git
a/src/main/java/org/apache/sling/feature/launcher/impl/Bootstrap.java
b/src/main/java/org/apache/sling/feature/launcher/impl/Bootstrap.java
index 47ee97c..e736d8d 100644
--- a/src/main/java/org/apache/sling/feature/launcher/impl/Bootstrap.java
+++ b/src/main/java/org/apache/sling/feature/launcher/impl/Bootstrap.java
@@ -19,7 +19,6 @@ package org.apache.sling.feature.launcher.impl;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
-import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
@@ -126,7 +125,7 @@ public class Bootstrap {
this.logger.info("Assembling provisioning model...");
try {
- boolean restart = this.config.getFeatureFiles().length == 0;
+ final boolean restart =
this.config.getFeatureFiles().isEmpty();
Map<ArtifactId, Feature> loadedFeatures = new HashMap<>();
final Feature app = assemble(artifactManager, loadedFeatures);
@@ -188,7 +187,7 @@ public class Bootstrap {
private Feature assemble(final ArtifactManager artifactManager,
Map<ArtifactId, Feature> loadedFeatures) throws IOException
{
- if (this.config.getFeatureFiles().length == 0) {
+ if (this.config.getFeatureFiles().isEmpty() ) {
File application = getApplicationFeatureFile(this.config);
if (application.isFile()) {
this.config.addFeatureFiles(application.toURI().toURL().toString());
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 764afab..ac1815b 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
@@ -16,8 +16,12 @@
*/
package org.apache.sling.feature.launcher.impl;
+import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.InputStreamReader;
+import java.io.OutputStream;
import java.io.Reader;
import java.net.URL;
import java.util.ArrayList;
@@ -32,12 +36,15 @@ import org.apache.sling.feature.Artifact;
import org.apache.sling.feature.ArtifactId;
import org.apache.sling.feature.Configuration;
import org.apache.sling.feature.Extension;
+import org.apache.sling.feature.ExtensionState;
import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.builder.ArtifactProvider;
import org.apache.sling.feature.builder.BuilderContext;
import org.apache.sling.feature.builder.FeatureBuilder;
import org.apache.sling.feature.builder.MergeHandler;
import org.apache.sling.feature.builder.PostProcessHandler;
import org.apache.sling.feature.io.IOUtils;
+import org.apache.sling.feature.io.archive.ArchiveReader;
import org.apache.sling.feature.io.artifacts.ArtifactHandler;
import org.apache.sling.feature.io.artifacts.ArtifactManager;
import org.apache.sling.feature.io.json.FeatureJSONReader;
@@ -71,16 +78,22 @@ public class FeatureProcessor {
return null;
}
});
- builderContext.setArtifactProvider(id -> {
- try {
- final ArtifactHandler handler =
artifactManager.getArtifactHandler(id.toMvnUrl());
- return handler.getLocalURL();
- } catch (final IOException e) {
- // ignore
- return null;
+ final ArtifactProvider provider = new ArtifactProvider() {
+
+ @Override
+ public URL provide(final ArtifactId id) {
+ try {
+ final ArtifactHandler handler =
artifactManager.getArtifactHandler(id.toMvnUrl());
+ return handler.getLocalURL();
+ } catch (final IOException e) {
+ // ignore
+ return null;
+ }
}
- });
-
builderContext.addArtifactsOverrides(config.getArtifactClashOverrides());
+ };
+ builderContext.setArtifactProvider(provider);
+
+ config.getArtifactClashOverrides().stream().forEach(id ->
builderContext.addArtifactsOverride(id));
builderContext.addConfigsOverrides(config.getConfigClashOverrides());
builderContext.addVariablesOverrides(config.getVariables());
builderContext.addFrameworkPropertiesOverrides(config.getInstallation().getFrameworkProperties());
@@ -95,16 +108,46 @@ public class FeatureProcessor {
}
List<Feature> features = new ArrayList<>();
+ final byte[] buffer = new byte[1024*1024*256];
for (final String featureFile : config.getFeatureFiles()) {
for (final String initFile :
IOUtils.getFeatureFiles(config.getHomeDirectory(), featureFile)) {
- logger.debug("Reading feature file {}", initFile);
- final ArtifactHandler featureArtifact =
artifactManager.getArtifactHandler(initFile);
- try (final Reader r = new
InputStreamReader(featureArtifact.getLocalURL().openStream(), "UTF-8")) {
- final Feature f = FeatureJSONReader.read(r,
featureArtifact.getUrl());
- loadedFeatures.put(f.getId(), f);
- features.add(f);
- } catch (Exception ex) {
- throw new IOException("Error reading feature: " +
initFile, ex);
+ if ( initFile.endsWith(IOUtils.EXTENSION_FEATURE_ARCHIVE) ) {
+ logger.debug("Reading feature archive {}", initFile);
+ final ArtifactHandler featureArtifact =
artifactManager.getArtifactHandler(initFile);
+ try (final InputStream is =
featureArtifact.getLocalURL().openStream()) {
+ for(final Feature feature : ArchiveReader.read(is,
(id, stream) -> {
+
+ if ( provider.provide(id) == null ) {
+ final File artifactFile = new
File(config.getCacheDirectory(),
+ id.toMvnPath().replace('/',
File.separatorChar));
+ if (!artifactFile.exists()) {
+ artifactFile.getParentFile().mkdirs();
+ try (final OutputStream os = new
FileOutputStream(artifactFile)) {
+ int l = 0;
+ while ((l = stream.read(buffer)) >
0) {
+ os.write(buffer, 0, l);
+ }
+ }
+ }
+ }
+ })) {
+
+ features.add(feature);
+ loadedFeatures.put(feature.getId(), feature);
+ }
+ } catch (final IOException ioe) {
+ logger.info("Unable to read feature archive from " +
initFile, ioe);
+ }
+ } else {
+ logger.debug("Reading feature file {}", initFile);
+ final ArtifactHandler featureArtifact =
artifactManager.getArtifactHandler(initFile);
+ try (final Reader r = new
InputStreamReader(featureArtifact.getLocalURL().openStream(), "UTF-8")) {
+ final Feature f = FeatureJSONReader.read(r,
featureArtifact.getUrl());
+ loadedFeatures.put(f.getId(), f);
+ features.add(f);
+ } catch (Exception ex) {
+ throw new IOException("Error reading feature: " +
initFile, ex);
+ }
}
}
}
@@ -170,7 +213,7 @@ public class FeatureProcessor {
continue extensions;
}
}
- if ( ext.isRequired() ) {
+ if ( ext.getState() == ExtensionState.REQUIRED ) {
throw new Exception("Unknown required extension " +
ext.getName());
}
}
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 9a32143..f1945b3 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
@@ -16,7 +16,6 @@
*/
package org.apache.sling.feature.launcher.impl;
-import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Dictionary;
diff --git
a/src/main/java/org/apache/sling/feature/launcher/impl/LauncherConfig.java
b/src/main/java/org/apache/sling/feature/launcher/impl/LauncherConfig.java
index bacb449..5766046 100644
--- a/src/main/java/org/apache/sling/feature/launcher/impl/LauncherConfig.java
+++ b/src/main/java/org/apache/sling/feature/launcher/impl/LauncherConfig.java
@@ -19,12 +19,14 @@ package org.apache.sling.feature.launcher.impl;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
+import org.apache.sling.feature.ArtifactId;
import org.apache.sling.feature.io.artifacts.ArtifactManagerConfig;
import org.apache.sling.feature.io.artifacts.spi.ArtifactProviderContext;
@@ -39,7 +41,7 @@ public class LauncherConfig
private static final String CACHE_DIR = "cache";
- private final List<String> artifactClashOverrides = new ArrayList<>();
+ private final List<ArtifactId> artifactClashOverrides = new ArrayList<>();
private final Map<String,String> configClashOverrides = new
LinkedHashMap<>();
@@ -66,7 +68,7 @@ public class LauncherConfig
this.setCacheDirectory(new File(getHomeDirectory(), CACHE_DIR));
}
- public List<String> getArtifactClashOverrides() {
+ public List<ArtifactId> getArtifactClashOverrides() {
return this.artifactClashOverrides;
}
@@ -90,8 +92,8 @@ public class LauncherConfig
* Get the list of feature files.
* @return The array of names.
*/
- public String[] getFeatureFiles() {
- return this.featureFiles.toArray(new String[0]);
+ public Collection<String> getFeatureFiles() {
+ return this.featureFiles;
}
/**
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 0ecef1f..0267c4d 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
@@ -16,6 +16,12 @@
*/
package org.apache.sling.feature.launcher.impl;
+import java.io.File;
+import java.util.AbstractMap;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
import org.apache.commons.cli.BasicParser;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
@@ -23,15 +29,10 @@ import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
+import org.apache.sling.feature.ArtifactId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.File;
-import java.util.AbstractMap;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
/**
* This is the launcher main class.
* It parses command line parameters and prepares the launcher.
@@ -118,7 +119,7 @@ public class Main {
}
if ( cl.hasOption(artifactClashOverride.getOpt()) ) {
for(final String override :
cl.getOptionValues(artifactClashOverride.getOpt())) {
- config.getArtifactClashOverrides().add(override);
+
config.getArtifactClashOverrides().add(ArtifactId.parse(override));
}
}
if ( cl.hasOption(configClashOverride.getOpt()) ) {
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 197f360..2aa9599 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
@@ -94,6 +94,7 @@ public class FrameworkLauncher implements Launcher {
final Constructor<?> constructor =
runnerClass.getDeclaredConstructor(Map.class, Map.class, List.class,
List.class);
constructor.setAccessible(true);
+ @SuppressWarnings("unchecked")
Callable<Integer> restart = (Callable<Integer>)
constructor.newInstance(properties, context.getBundleMap(),
context.getConfigurations(),
context.getInstallableArtifacts());