You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2022/06/13 14:13:47 UTC

[sling-feature-launcher-maven-plugin] branch issue/SLING-11387 created (now 843f625)

This is an automated email from the ASF dual-hosted git repository.

rombert pushed a change to branch issue/SLING-11387
in repository https://gitbox.apache.org/repos/asf/sling-feature-launcher-maven-plugin.git


      at 843f625  SLING-11387 - Allow overriding the version selected artifact ids when launching

This branch includes the following new commits:

     new 843f625  SLING-11387 - Allow overriding the version selected artifact ids when launching

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[sling-feature-launcher-maven-plugin] 01/01: SLING-11387 - Allow overriding the version selected artifact ids when launching

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch issue/SLING-11387
in repository https://gitbox.apache.org/repos/asf/sling-feature-launcher-maven-plugin.git

commit 843f625b1b23efbb050d7547be14786b94bc9911
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Mon Jun 13 16:05:54 2022 +0200

    SLING-11387 - Allow overriding the version selected artifact ids when launching
    
    Add an 'additionalBundles' configuration section that can be used to
    configure extra bundles and ensures that the defined version is used.
---
 .../sling/maven/feature/launcher/Launch.java       | 29 ++++---
 .../maven/feature/launcher/LauncherArguments.java  |  4 +-
 .../sling/maven/feature/launcher/StartMojo.java    | 94 +++++++++++++++++-----
 src/main/resources/override-bundles-template.json  |  6 ++
 4 files changed, 100 insertions(+), 33 deletions(-)

diff --git a/src/main/java/org/apache/sling/maven/feature/launcher/Launch.java b/src/main/java/org/apache/sling/maven/feature/launcher/Launch.java
index a0c3d10..6fba085 100644
--- a/src/main/java/org/apache/sling/maven/feature/launcher/Launch.java
+++ b/src/main/java/org/apache/sling/maven/feature/launcher/Launch.java
@@ -18,15 +18,17 @@
  */
 package org.apache.sling.maven.feature.launcher;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.regex.Pattern;
 
 import org.apache.maven.model.Dependency;
 
 public class Launch {
-    
+
     private static final Pattern ID_PATTERN = Pattern.compile("[a-zA-Z0-9_\\-\\.]+");
 
     private String id;
@@ -35,6 +37,7 @@ public class Launch {
     private int startTimeoutSeconds = 30;
     private boolean skip = false;
     private Map<String,String> environmentVariables = new HashMap<>();
+    private List<String> additionalBundles = new ArrayList<>();
 
     public String getId() {
         return id;
@@ -59,11 +62,11 @@ public class Launch {
     public void setLauncherArguments(LauncherArguments launcherArguments) {
         this.launcherArguments = launcherArguments;
     }
-    
+
     public int getStartTimeoutSeconds() {
         return startTimeoutSeconds;
     }
-    
+
     public void setStartTimeoutSeconds(int startTimeoutSeconds) {
         this.startTimeoutSeconds = startTimeoutSeconds;
     }
@@ -86,23 +89,31 @@ public class Launch {
         this.environmentVariables = environmentVariables;
     }
 
+    public List<String> getAdditionalBundles() {
+        return additionalBundles;
+    }
+
+    public void setAdditionalBundles(List<String> additionalBundles) {
+        this.additionalBundles = additionalBundles;
+    }
+
     public void validate() {
-        if ( id == null || id.trim().isEmpty() ) 
+        if ( id == null || id.trim().isEmpty() )
             throw new IllegalArgumentException("Missing id");
-        
+
         if ( !ID_PATTERN.matcher(id).matches() )
             throw new IllegalArgumentException("Invalid id '" + id + "'. Allowed characters are digits, numbers, '-','_' and '.'.");
-        
+
         if ( startTimeoutSeconds < 0 )
             throwInvalid("startTimeout value '" + startTimeoutSeconds + "' is negative" );
-        
+
         if ( feature == null )
             throwInvalid("required field 'feature' is missing");
-        
+
         if ( ! "slingosgifeature".equals(feature.getType()) )
             throwInvalid("type must be 'slingosgifeature' but is '" + feature.getType()+"'");
     }
-    
+
     private void throwInvalid(String reason) {
         throw new IllegalArgumentException("Invalid launch '" + id + "': " + reason);
     }
diff --git a/src/main/java/org/apache/sling/maven/feature/launcher/LauncherArguments.java b/src/main/java/org/apache/sling/maven/feature/launcher/LauncherArguments.java
index 3693172..e70c68f 100644
--- a/src/main/java/org/apache/sling/maven/feature/launcher/LauncherArguments.java
+++ b/src/main/java/org/apache/sling/maven/feature/launcher/LauncherArguments.java
@@ -26,7 +26,7 @@ public class LauncherArguments {
     private String[] vmOptions = new String[0];
     private Map<String, String> frameworkProperties = new HashMap<>();
     private Map<String, String> variables = new HashMap<>();
-    
+
     public String[] getVmOptions() {
         return vmOptions;
     }
@@ -38,7 +38,7 @@ public class LauncherArguments {
     public Map<String, String> getFrameworkProperties() {
         return frameworkProperties;
     }
-    
+
     public void setFrameworkProperties(Map<String, String> frameworkProperties) {
         this.frameworkProperties = frameworkProperties;
     }
diff --git a/src/main/java/org/apache/sling/maven/feature/launcher/StartMojo.java b/src/main/java/org/apache/sling/maven/feature/launcher/StartMojo.java
index b25849e..b8965a8 100644
--- a/src/main/java/org/apache/sling/maven/feature/launcher/StartMojo.java
+++ b/src/main/java/org/apache/sling/maven/feature/launcher/StartMojo.java
@@ -22,14 +22,20 @@ package org.apache.sling.maven.feature.launcher;
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.lang.ProcessBuilder.Redirect;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.maven.execution.MavenSession;
 import org.apache.maven.model.Dependency;
 import org.apache.maven.plugin.AbstractMojo;
@@ -51,7 +57,7 @@ import org.eclipse.aether.resolution.ArtifactResult;
 
 @Mojo( name = "start", defaultPhase = LifecyclePhase.PRE_INTEGRATION_TEST )
 public class StartMojo extends AbstractMojo {
-    
+
     /**
      * Location of the file.
      */
@@ -60,10 +66,10 @@ public class StartMojo extends AbstractMojo {
 
     @Parameter( required = true, defaultValue = "1.1.4")
     private String featureLauncherVersion;
-    
+
     @Parameter(required = true)
     private List<Launch> launches;
-    
+
     // <launches>
     //   <launch>
     //     <id>...</id>
@@ -92,13 +98,15 @@ public class StartMojo extends AbstractMojo {
 
     @Parameter(property = "session", readonly = true, required = true)
     protected MavenSession mavenSession;
-    
+
     @Component
     private ProcessTracker processes;
-    
+
+    @Override
     public void execute() throws MojoExecutionException, MojoFailureException {
 
         Artifact launcherArtifact = new DefaultArtifact("org.apache.sling:org.apache.sling.feature.launcher:" + featureLauncherVersion);
+        List<Path> cleanupPaths = new ArrayList<>();
 
         try {
             RepositorySystemSession repositorySession = mavenSession.getRepositorySession();
@@ -106,10 +114,10 @@ public class StartMojo extends AbstractMojo {
                 .resolveArtifact(repositorySession, new ArtifactRequest(launcherArtifact, remoteRepos, null))
                 .getArtifact()
                 .getFile();
-            
+
             File workDir = new File(outputDirectory, "launchers");
             workDir.mkdirs();
-            
+
             for ( Launch launch : launches ) {
                 if (launch.isSkip()) {
                     getLog().info("Skipping starting launch with id " + launch.getId());
@@ -119,10 +127,10 @@ public class StartMojo extends AbstractMojo {
                 launch.validate();
 
                 Artifact artifact = toArtifact(launch.getFeature());
-                
+
                 ArtifactResult result = resolver.resolveArtifact(repositorySession, new ArtifactRequest(artifact, remoteRepos, null));
                 File featureFile = result.getArtifact().getFile();
-                
+
                 List<String> args = new ArrayList<>();
                 String javahome = System.getenv("JAVA_HOME");
                 if (javahome == null || javahome.isEmpty()) {
@@ -133,25 +141,36 @@ public class StartMojo extends AbstractMojo {
                 args.add(javahome + File.separatorChar + "bin" + File.separatorChar + "java");
                 // SLING-9994 - if any extra vm options were supplied, apply them here
                 String[] vmOptions = launch.getLauncherArguments().getVmOptions();
-                if (vmOptions != null) {
-                    for (String vmOption : vmOptions) {
-                        if (vmOption != null && !vmOption.isEmpty()) {
-                            args.add(vmOption);
-                        }
+                for (String vmOption : vmOptions) {
+                    if (vmOption != null && !vmOption.isEmpty()) {
+                        args.add(vmOption);
                     }
                 }
                 args.add("-jar");
                 args.add(launcher.getAbsolutePath());
                 args.add("-f");
-                args.add(featureFile.getAbsolutePath());
+                if ( ! launch.getAdditionalBundles().isEmpty() ) {
+                    Path overridePath = createOverrideFeatureFile(launch.getAdditionalBundles(), cleanupPaths);
+                    args.add(featureFile.getAbsolutePath() + "," + overridePath.toString());
+                } else {
+                    args.add(featureFile.getAbsolutePath());
+                }
+
+                launch.getAdditionalBundles().stream()
+                    .map( DefaultArtifact::new )
+                    .forEach( a -> {
+                        args.add("-C");
+                        args.add(a.getGroupId() + ":" + a.getArtifactId() + ":*:*:LATEST");
+                });
+
                 args.add("-p");
                 args.add(launch.getId());
-                
+
                 for ( Map.Entry<String, String> frameworkProperty : launch.getLauncherArguments().getFrameworkProperties().entrySet() ) {
                     args.add("-D");
                     args.add(frameworkProperty.getKey()+"="+frameworkProperty.getValue());
                 }
-                
+
                 for ( Map.Entry<String, String> variable : launch.getLauncherArguments().getVariables().entrySet() ) {
                     args.add("-V");
                     args.add(variable.getKey()+"="+variable.getValue());
@@ -164,13 +183,13 @@ public class StartMojo extends AbstractMojo {
                 pb.directory(workDir);
                 launch.getEnvironmentVariables().entrySet()
                     .forEach( e -> pb.environment().put(e.getKey(), e.getValue()) );
-                
+
                 getLog().info("Starting launch with id '" + launch.getId() + "', args=" + args);
-                
+
                 CountDownLatch latch = new CountDownLatch(1);
-                
+
                 Process process = pb.start();
-                
+
                 Thread monitor = new Thread("launch-monitor-" + launch.getId()) {
                     @Override
                     public void run() {
@@ -196,7 +215,7 @@ public class StartMojo extends AbstractMojo {
                     ProcessTracker.stop(process);
                     throw new MojoExecutionException("Launch " + launch.getId() + " failed to start in " + launch.getStartTimeoutSeconds() + " seconds.");
                 }
-                
+
                 processes.startTracking(launch.getId(), process);
             }
 
@@ -205,7 +224,38 @@ public class StartMojo extends AbstractMojo {
         } catch ( InterruptedException e ) {
             Thread.currentThread().interrupt();
             throw new MojoExecutionException("Execution interrupted", e);
+        } finally {
+            for ( Path cleanupPath : cleanupPaths ) {
+                try {
+                    if ( cleanupPath.toFile().exists() )
+                        Files.delete(cleanupPath);
+                } catch (IOException e) {
+                    getLog().warn("Failed deleting " + cleanupPath, e);
+                }
+            }
+        }
+    }
+
+    // we strive to not pull in dependencies on the feature model and only retrieve it at runtime
+    // therefore we don't use the feature model API here
+    private Path createOverrideFeatureFile(List<String> overrideArtifacts, List<Path> cleanupPaths) throws IOException {
+        Path overridePath = Files.createTempFile("launcher-override-", ".json");
+        cleanupPaths.add(overridePath);
+        String jsonFragment = overrideArtifacts.stream()
+            .map( a -> "{ \"id\": \"" + a + "\" }\n"  )
+            .collect(Collectors.joining(","));
+
+
+        try ( InputStream inputStream = getClass().getResourceAsStream("/override-bundles-template.json") ) {
+            if ( inputStream == null )
+                throw new IllegalArgumentException("Failed to locate feature template for artifact override");
+            List<String> inputLines = IOUtils.readLines(inputStream, StandardCharsets.UTF_8);
+            List<String> outputLines = inputLines.stream()
+                .map( s -> s.replace("##BUNDLES##", jsonFragment) )
+                .collect(Collectors.toList());
+            Files.write(overridePath, outputLines);
         }
+        return overridePath;
     }
 
     private Artifact toArtifact(Dependency dependency) {
diff --git a/src/main/resources/override-bundles-template.json b/src/main/resources/override-bundles-template.json
new file mode 100644
index 0000000..510bfce
--- /dev/null
+++ b/src/main/resources/override-bundles-template.json
@@ -0,0 +1,6 @@
+{
+  "id":"org.apache.sling:org.apache.sling.tmp.synthetic-feature:slingosgifeature:1-SNAPSHOT",
+  "bundles":[
+    ##BUNDLES##
+  ]
+}
\ No newline at end of file