You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by da...@apache.org on 2018/04/27 10:01:32 UTC

[sling-org-apache-sling-feature-modelconverter] 14/40: Write configurations associated with artifacts alongside these

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

davidb pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-modelconverter.git

commit 0e38227cb7de4506eacd622bfb5f9f687fc49021
Author: David Bosschaert <da...@gmail.com>
AuthorDate: Wed Mar 21 16:24:39 2018 +0000

    Write configurations associated with artifacts alongside these
---
 .../modelconverter/impl/ProvisioningToFeature.java | 73 +++++++++++++++-----
 .../modelconverter/impl/ModelConverterTest.java    | 78 ++++++++++++++++++++--
 2 files changed, 128 insertions(+), 23 deletions(-)

diff --git a/src/main/java/org/apache/sling/feature/modelconverter/impl/ProvisioningToFeature.java b/src/main/java/org/apache/sling/feature/modelconverter/impl/ProvisioningToFeature.java
index a521780..5d0ac7c 100644
--- a/src/main/java/org/apache/sling/feature/modelconverter/impl/ProvisioningToFeature.java
+++ b/src/main/java/org/apache/sling/feature/modelconverter/impl/ProvisioningToFeature.java
@@ -30,6 +30,7 @@ import org.apache.sling.feature.support.ArtifactManagerConfig;
 import org.apache.sling.feature.support.FeatureUtil;
 import org.apache.sling.feature.support.json.ApplicationJSONWriter;
 import org.apache.sling.feature.support.json.FeatureJSONWriter;
+import org.apache.sling.feature.support.json.WriteOption;
 import org.apache.sling.provisioning.model.Artifact;
 import org.apache.sling.provisioning.model.ArtifactGroup;
 import org.apache.sling.provisioning.model.Configuration;
@@ -52,6 +53,7 @@ import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashSet;
@@ -67,7 +69,7 @@ public class ProvisioningToFeature {
     private static Logger LOGGER = LoggerFactory.getLogger(ProvisioningToFeature.class);
 
     public static void convert(File file, String output) {
-        Model model = createModel(Collections.singletonList(file), null, false);
+        Model model = createModel(Collections.singletonList(file), null, true, false);
         final List<org.apache.sling.feature.Feature> features = buildFeatures(model);
         if (features.size() != 1)
             throw new IllegalStateException("TODO");
@@ -77,7 +79,7 @@ public class ProvisioningToFeature {
 
     public static void convert(List<File> files,  String outputFile, String runModes, boolean createApp,
             boolean includeModelInfo, String propsFile) {
-        final Model model = createModel(files, runModes, includeModelInfo);
+        final Model model = createModel(files, runModes, false, includeModelInfo);
 
         if ( createApp ) {
             final Application app = buildApplication(model, propsFile);
@@ -99,27 +101,28 @@ public class ProvisioningToFeature {
      * @param includeModelInfo
      */
     private static Model createModel(final List<File> files,
-            final String runModes, boolean includeModelInfo) {
+            final String runModes, boolean allRunModes, boolean includeModelInfo) {
         LOGGER.info("Assembling model...");
+        ResolverOptions variableResolver = new ResolverOptions().variableResolver(new VariableResolver() {
+            @Override
+            public String resolve(final Feature feature, final String name) {
+                // Keep variables as-is in the model
+                return "${" + name + "}";
+            }
+        });
+
         Model model = null;
         for(final File initFile : files) {
             try {
-                model = processModel(model, initFile, includeModelInfo,
-                    new ResolverOptions().variableResolver(new VariableResolver() {
-                        @Override
-                        public String resolve(final Feature feature, final String name) {
-                            // Keep variables as-is in the model
-                            return "${" + name + "}";
-                        }
-                    })
-                );
+                model = processModel(model, initFile, includeModelInfo, variableResolver);
             } catch ( final IOException iae) {
                 LOGGER.error("Unable to read provisioning model {} : {}", initFile, iae.getMessage(), iae);
                 System.exit(1);
             }
         }
 
-        final Map<Traceable, String> errors = ModelUtility.validate(model);
+        final Model effectiveModel = ModelUtility.getEffectiveModel(model, variableResolver);
+        final Map<Traceable, String> errors = ModelUtility.validate(effectiveModel);
         if ( errors != null ) {
             LOGGER.error("Invalid assembled provisioning model.");
             for(final Map.Entry<Traceable, String> entry : errors.entrySet()) {
@@ -127,11 +130,24 @@ public class ProvisioningToFeature {
             }
             System.exit(1);
         }
-        final Set<String> modes = calculateRunModes(model, runModes);
+        final Set<String> modes;
+        if (allRunModes) {
+            modes = new HashSet<>();
+            for (Feature f : effectiveModel.getFeatures()) {
+                for (RunMode rm : f.getRunModes()) {
+                    String[] names = rm.getNames();
+                    if (names != null) {
+                        modes.addAll(Arrays.asList(names));
+                    }
+                }
+            }
+        } else {
+            modes = calculateRunModes(effectiveModel, runModes);
+        }
 
-        removeInactiveFeaturesAndRunModes(model, modes);
+        removeInactiveFeaturesAndRunModes(effectiveModel, modes);
 
-        return model;
+        return effectiveModel;
     }
 
     /**
@@ -420,6 +436,29 @@ public class ProvisioningToFeature {
                     final String key = keys.nextElement();
                     newCfg.getProperties().put(key, cfg.getProperties().get(key));
                 }
+
+                String[] runModeNames = runMode.getNames();
+                if (runModeNames != null) {
+                    // If this configuration is associated with a runmode other than null, attach it to a bundle
+                    // that has the same runmodes
+                    Artifact art = null;
+                    for (ArtifactGroup group : runMode.getArtifactGroups()) {
+                        if (art != null)
+                            break;
+
+                        for (Artifact artifact : group) {
+                            art = artifact;
+                            break;
+                        }
+                    }
+                    if (art == null) {
+                        throw new IllegalStateException("Should have at least one artifact in runmodes " +
+                                Arrays.toString(runModeNames) + " to attach configuration to");
+                    }
+
+                    newCfg.getProperties().put(org.apache.sling.feature.Configuration.PROP_ARTIFACT, art.toMvnUrl());
+                }
+
                 configurations.add(newCfg);
             }
 
@@ -491,7 +530,7 @@ public class ProvisioningToFeature {
 
         final File file = new File(out);
         try ( final FileWriter writer = new FileWriter(file)) {
-            FeatureJSONWriter.write(writer, f);
+            FeatureJSONWriter.write(writer, f, WriteOption.OLD_STYLE_FACTORY_CONFIGS);
         } catch ( final IOException ioe) {
             LOGGER.error("Unable to write feature to {} : {}", out, ioe.getMessage(), ioe);
             System.exit(1);
diff --git a/src/test/java/org/apache/sling/feature/modelconverter/impl/ModelConverterTest.java b/src/test/java/org/apache/sling/feature/modelconverter/impl/ModelConverterTest.java
index bf35578..6facd22 100644
--- a/src/test/java/org/apache/sling/feature/modelconverter/impl/ModelConverterTest.java
+++ b/src/test/java/org/apache/sling/feature/modelconverter/impl/ModelConverterTest.java
@@ -93,6 +93,11 @@ public class ModelConverterTest {
         testConvertToProvisioningModel("/oak.json", "/oak.txt");
     }
 
+    @Test
+    public void testOakToFeature() throws Exception {
+        testConvertToFeature("/oak.txt", "/oak.json");
+    }
+
     public void testConvertToFeature(String originalProvModel, String expectedJSON) throws Exception {
         File inFile = new File(getClass().getResource(originalProvModel).toURI());
         File outFile = new File(tempDir.toFile(), expectedJSON + ".generated");
@@ -133,7 +138,7 @@ public class ModelConverterTest {
 
         assertFeatureKVMapEquals(expected.getVariables(), actual.getVariables());
         assertBundlesEqual(expected.getBundles(), actual.getBundles());
-        assertConfigurationsEqual(expected.getConfigurations(), actual.getConfigurations());
+        assertConfigurationsEqual(expected.getConfigurations(), actual.getConfigurations(), expected.getBundles(), actual.getBundles());
         assertFeatureKVMapEquals(expected.getFrameworkProperties(), actual.getFrameworkProperties());
 
         // Ignore caps and reqs, includes and extensions here since they cannot come from the prov model.
@@ -149,26 +154,86 @@ public class ModelConverterTest {
                 if (ac.getId().equals(ex.getId())) {
                     found = true;
                     assertFeatureKVMapEquals(ex.getMetadata(), ac.getMetadata());
+                    break;
                 }
             }
-            assertTrue(found);
+            assertTrue("Not found: " + ex, found);
         }
     }
 
-    private void assertConfigurationsEqual(Configurations expected, Configurations actual) {
+    private void assertConfigurationsEqual(Configurations expected, Configurations actual, Bundles exBundles, Bundles acBundles) {
         for (Iterator<org.apache.sling.feature.Configuration> it = expected.iterator(); it.hasNext(); ) {
             org.apache.sling.feature.Configuration ex = it.next();
 
             boolean found = false;
             for (Iterator<org.apache.sling.feature.Configuration> it2 = actual.iterator(); it2.hasNext(); ) {
                 org.apache.sling.feature.Configuration ac = it2.next();
-                if (ac.getPid().equals(ex.getPid())) {
+                if (ex.getPid() != null) {
+                    if (ex.getPid().equals(ac.getPid())) {
+                        found = true;
+                        assertConfigProps(ex, ac, exBundles, acBundles);
+                    }
+                } else {
+                    if (ex.getFactoryPid().equals(ac.getFactoryPid())) {
+                        found = true;
+                        assertConfigProps(ex, ac, exBundles, acBundles);
+                    }
+                }
+            }
+            assertTrue(found);
+        }
+    }
+
+    private void assertConfigProps(org.apache.sling.feature.Configuration expected, org.apache.sling.feature.Configuration actual, Bundles exBundles, Bundles acBundles) {
+        // If the configuration is associated with an artifact, it's considered equal
+        // if both artifacts have the same runmode (as the configuration is really
+        // associated with the runmode.
+        Object art = expected.getProperties().remove(org.apache.sling.feature.Configuration.PROP_ARTIFACT);
+        if (art instanceof String) {
+            String expectedArtifact = (String) art;
+            String actualArtifact = (String) actual.getProperties().remove(org.apache.sling.feature.Configuration.PROP_ARTIFACT);
+
+            String expectedRunmodes = null;
+            for(Iterator<org.apache.sling.feature.Artifact> it = exBundles.iterator(); it.hasNext(); ) {
+                org.apache.sling.feature.Artifact a = it.next();
+                if (a.getId().toMvnId().equals(expectedArtifact)) {
+                    expectedRunmodes = a.getMetadata().get("run-modes");
+                }
+            }
+
+            boolean found = false;
+            for(Iterator<org.apache.sling.feature.Artifact> it = acBundles.iterator(); it.hasNext(); ) {
+                org.apache.sling.feature.Artifact a = it.next();
+                if (a.getId().toMvnId().equals(actualArtifact)) {
                     found = true;
-                    assertEquals(ex.getProperties(), ac.getProperties());
+                    assertEquals(expectedRunmodes, a.getMetadata().get("run-modes"));
+                    break;
                 }
             }
             assertTrue(found);
         }
+
+        assertTrue("Configurations not equal: " + expected.getProperties() + " vs " + actual.getProperties(),
+                configPropsEqual(expected.getProperties(), actual.getProperties()));
+    }
+
+    private boolean configPropsEqual(Dictionary<String, Object> d1, Dictionary<String, Object> d2) {
+        if (d1.size() != d2.size()) {
+            return false;
+        }
+
+        for (Enumeration<String> e = d1.keys(); e.hasMoreElements(); ) {
+            String k = e.nextElement();
+            Object v = d1.get(k);
+            if (v instanceof Object[]) {
+                if (!Arrays.equals((Object[]) v, (Object[]) d2.get(k)))
+                    return false;
+            } else {
+                if (!v.equals(d2.get(k)))
+                    return false;
+            }
+        }
+        return true;
     }
 
     private void assertModelsEqual(Model expected, Model actual) {
@@ -279,6 +344,7 @@ public class ModelConverterTest {
         return m1.equals(m2);
     }
 
+    // TODO can this one go?
     private Map<String, Object> cfgMap(Dictionary<String, Object> properties) {
         Map<String, Object> m = new HashMap<>();
         for (Enumeration<String> e = properties.keys(); e.hasMoreElements(); ) {
@@ -292,7 +358,7 @@ public class ModelConverterTest {
 
                     String[] kv = line.trim().split("=");
                     if (kv.length >= 2) {
-                        String v = kv[1].trim().replaceAll("[" +Pattern.quote("[") + "]\\s+[\"]", "[\"");
+                        String v = kv[1].trim().replaceAll("[" + Pattern.quote("[") + "]\\s+[\"]", "[\"");
                         v = v.replaceAll("[\"][,]\\s*[]]","\"]");
                         m.put(kv[0].trim(), v.trim());
                     }

-- 
To stop receiving notification emails like this one, please contact
davidb@apache.org.