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:31 UTC

[sling-org-apache-sling-feature-modelconverter] 13/40: Preserve variables when converting prov model to feature

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 9398062a3c6d447ebb1e89a3847a7adea9a92049
Author: David Bosschaert <da...@gmail.com>
AuthorDate: Tue Mar 20 14:14:05 2018 +0000

    Preserve variables when converting prov model to feature
---
 .../modelconverter/impl/ProvisioningToFeature.java | 70 +++++++--------
 .../modelconverter/impl/ModelConverterTest.java    | 99 ++++++++++++++++++++--
 2 files changed, 129 insertions(+), 40 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 0df66db..a521780 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
@@ -104,24 +104,22 @@ public class ProvisioningToFeature {
         Model model = null;
         for(final File initFile : files) {
             try {
-                model = processModel(model, initFile, includeModelInfo);
+                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 + "}";
+                        }
+                    })
+                );
             } catch ( final IOException iae) {
                 LOGGER.error("Unable to read provisioning model {} : {}", initFile, iae.getMessage(), iae);
                 System.exit(1);
             }
         }
 
-        final Model effectiveModel = ModelUtility.getEffectiveModel(model, new ResolverOptions().variableResolver(new VariableResolver() {
-
-            @Override
-            public String resolve(Feature feature, String name) {
-                if ( "sling.home".equals(name) ) {
-                    return "${sling.home}";
-                }
-                return feature.getVariables().get(name);
-            }
-        }));
-        final Map<Traceable, String> errors = ModelUtility.validate(effectiveModel);
+        final Map<Traceable, String> errors = ModelUtility.validate(model);
         if ( errors != null ) {
             LOGGER.error("Invalid assembled provisioning model.");
             for(final Map.Entry<Traceable, String> entry : errors.entrySet()) {
@@ -129,11 +127,11 @@ public class ProvisioningToFeature {
             }
             System.exit(1);
         }
-        final Set<String> modes = calculateRunModes(effectiveModel, runModes);
+        final Set<String> modes = calculateRunModes(model, runModes);
 
-        removeInactiveFeaturesAndRunModes(effectiveModel, modes);
+        removeInactiveFeaturesAndRunModes(model, modes);
 
-        return effectiveModel;
+        return model;
     }
 
     /**
@@ -145,19 +143,22 @@ public class ProvisioningToFeature {
      * @throws IOException If reading fails
      */
     private static Model processModel(Model model,
-            final File modelFile, boolean includeModelInfo) throws IOException {
+            File modelFile, boolean includeModelInfo) throws IOException {
+        return processModel(model, modelFile, includeModelInfo,
+            new ResolverOptions().variableResolver(new VariableResolver() {
+                @Override
+                public String resolve(final Feature feature, final String name) {
+                    return name;
+                }
+            })
+        );
+    }
+
+    private static Model processModel(Model model,
+            File modelFile, boolean includeModelInfo, ResolverOptions options) throws IOException {
         LOGGER.info("- reading model {}", modelFile);
 
         final Model nextModel = readProvisioningModel(modelFile);
-        // resolve references to other models
-        final ResolverOptions options = new ResolverOptions().variableResolver(new VariableResolver() {
-
-            @Override
-            public String resolve(final Feature feature, final String name) {
-                return name;
-            }
-        });
-
 
         final Model effectiveModel = ModelUtility.getEffectiveModel(nextModel, options);
         for(final Feature feature : effectiveModel.getFeatures()) {
@@ -210,11 +211,10 @@ public class ProvisioningToFeature {
     /**
      * Read the provisioning model
      */
-    public static Model readProvisioningModel(final File file)
+    private static Model readProvisioningModel(final File file)
     throws IOException {
         try (final FileReader is = new FileReader(file)) {
-            final Model m = ModelReader.read(is, file.getAbsolutePath());
-            return m;
+            return ModelReader.read(is, file.getAbsolutePath());
         }
     }
 
@@ -393,14 +393,14 @@ public class ProvisioningToFeature {
                             cpExtension.getArtifacts().add(newArtifact);
                         } else {
                             int startLevel = group.getStartLevel();
-                            if ( ModelConstants.FEATURE_BOOT.equals(feature.getName()) ) {
-                                startLevel = 1;
-                            } else if ( startLevel == 0 ) {
-                                startLevel = 20;
+                            if ( startLevel == 0) {
+                                if ( ModelConstants.FEATURE_BOOT.equals(feature.getName()) ) {
+                                    startLevel = 1;
+                                } else if ( startLevel == 0 ) {
+                                    startLevel = 20;
+                                }
                             }
-
-                            // TODO this is probably not correct
-                            // newArtifact.getMetadata().put(org.apache.sling.feature.Artifact.KEY_START_ORDER, String.valueOf(startLevel));
+                            newArtifact.getMetadata().put("start-level", String.valueOf(startLevel));
 
                             bundles.add(newArtifact);
                         }
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 1572e9a..bf35578 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
@@ -16,8 +16,12 @@
  */
 package org.apache.sling.feature.modelconverter.impl;
 
+import org.apache.sling.feature.Bundles;
+import org.apache.sling.feature.Configurations;
 import org.apache.sling.feature.support.ArtifactManager;
 import org.apache.sling.feature.support.ArtifactManagerConfig;
+import org.apache.sling.feature.support.FeatureUtil;
+import org.apache.sling.feature.support.json.FeatureJSONReader.SubstituteVariables;
 import org.apache.sling.provisioning.model.Artifact;
 import org.apache.sling.provisioning.model.ArtifactGroup;
 import org.apache.sling.provisioning.model.Configuration;
@@ -27,11 +31,13 @@ import org.apache.sling.provisioning.model.Model;
 import org.apache.sling.provisioning.model.ModelConstants;
 import org.apache.sling.provisioning.model.RunMode;
 import org.apache.sling.provisioning.model.Section;
+import org.apache.sling.provisioning.model.io.ModelReader;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
 import java.io.File;
+import java.io.FileReader;
 import java.io.IOException;
 import java.net.URISyntaxException;
 import java.nio.file.Files;
@@ -43,6 +49,7 @@ import java.util.Dictionary;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.regex.Pattern;
@@ -76,10 +83,10 @@ public class ModelConverterTest {
         testConvertToProvisioningModel("/boot.json", "/boot.txt");
     }
 
-    /* @Test
+    @Test
     public void testBootToFeature() throws Exception {
         testConvertToFeature("/boot.txt", "/boot.json");
-    } */
+    }
 
     @Test
     public void testOak() throws Exception {
@@ -90,7 +97,13 @@ public class ModelConverterTest {
         File inFile = new File(getClass().getResource(originalProvModel).toURI());
         File outFile = new File(tempDir.toFile(), expectedJSON + ".generated");
 
-        ProvisioningToFeature.convert(inFile, outFile.getAbsolutePath());
+        String outPath = outFile.getAbsolutePath();
+        ProvisioningToFeature.convert(inFile, outPath);
+
+        String expectedFile = new File(getClass().getResource(expectedJSON).toURI()).getAbsolutePath();
+        org.apache.sling.feature.Feature expected = FeatureUtil.getFeature(expectedFile, artifactManager, SubstituteVariables.NONE);
+        org.apache.sling.feature.Feature actual = FeatureUtil.getFeature(outPath, artifactManager, SubstituteVariables.NONE);
+        assertFeaturesEqual(expected, actual);
     }
 
     public void testConvertToProvisioningModel(String originalJSON, String expectedProvModel) throws URISyntaxException, IOException {
@@ -101,11 +114,63 @@ public class ModelConverterTest {
                 artifactManager);
 
         File expectedFile = new File(getClass().getResource(expectedProvModel).toURI());
-        Model expected = ProvisioningToFeature.readProvisioningModel(expectedFile);
-        Model actual = ProvisioningToFeature.readProvisioningModel(outFile);
+        Model expected = readProvisioningModel(expectedFile);
+        Model actual = readProvisioningModel(outFile);
         assertModelsEqual(expected, actual);
     }
 
+    private static Model readProvisioningModel(File modelFile) throws IOException {
+        try (final FileReader is = new FileReader(modelFile)) {
+            return ModelReader.read(is, modelFile.getAbsolutePath());
+        }
+    }
+
+    private void assertFeaturesEqual(org.apache.sling.feature.Feature expected, org.apache.sling.feature.Feature actual) {
+        assertEquals(expected.getTitle(), actual.getTitle());
+        assertEquals(expected.getDescription(), actual.getDescription());
+        assertEquals(expected.getVendor(), actual.getVendor());
+        assertEquals(expected.getLicense(), actual.getLicense());
+
+        assertFeatureKVMapEquals(expected.getVariables(), actual.getVariables());
+        assertBundlesEqual(expected.getBundles(), actual.getBundles());
+        assertConfigurationsEqual(expected.getConfigurations(), actual.getConfigurations());
+        assertFeatureKVMapEquals(expected.getFrameworkProperties(), actual.getFrameworkProperties());
+
+        // Ignore caps and reqs, includes and extensions here since they cannot come from the prov model.
+    }
+
+    private void assertBundlesEqual(Bundles expected, Bundles actual) {
+        for (Iterator<org.apache.sling.feature.Artifact> it = expected.iterator(); it.hasNext(); ) {
+            org.apache.sling.feature.Artifact ex = it.next();
+
+            boolean found = false;
+            for (Iterator<org.apache.sling.feature.Artifact> it2 = actual.iterator(); it2.hasNext(); ) {
+                org.apache.sling.feature.Artifact ac = it2.next();
+                if (ac.getId().equals(ex.getId())) {
+                    found = true;
+                    assertFeatureKVMapEquals(ex.getMetadata(), ac.getMetadata());
+                }
+            }
+            assertTrue(found);
+        }
+    }
+
+    private void assertConfigurationsEqual(Configurations expected, Configurations actual) {
+        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())) {
+                    found = true;
+                    assertEquals(ex.getProperties(), ac.getProperties());
+                }
+            }
+            assertTrue(found);
+        }
+    }
+
     private void assertModelsEqual(Model expected, Model actual) {
         for (int i=0; i<expected.getFeatures().size(); i++) {
             Feature expectedFeature = expected.getFeatures().get(i);
@@ -189,6 +254,15 @@ public class ModelConverterTest {
                 }
                 found = true;
 
+                if (cfg1.getFactoryPid() == null) {
+                    if (cfg2.getFactoryPid() != null)
+                        return false;
+                } else {
+                    if (!cfg1.getFactoryPid().equals(cfg2.getFactoryPid())) {
+                        return false;
+                    }
+                }
+
                 Map<String, Object> m1 = cfgMap(cfg1.getProperties());
                 Map<String, Object> m2 = cfgMap(cfg2.getProperties());
                 if (!m1.equals(m2)) {
@@ -240,6 +314,16 @@ public class ModelConverterTest {
         return m;
     }
 
+    private Map<String, String> featureKvToMap(org.apache.sling.feature.KeyValueMap kvm) {
+        Map<String, String> m = new HashMap<>();
+
+        for (Map.Entry<String, String> entry : kvm) {
+            m.put(entry.getKey(), entry.getValue());
+        }
+
+        return m;
+    }
+
     private boolean artifactGroupsEquals(String featureName, ArtifactGroup g1, ArtifactGroup g2) {
         int sl1 = effectiveStartLevel(featureName, g1.getStartLevel());
         int sl2 = effectiveStartLevel(featureName, g2.getStartLevel());
@@ -276,6 +360,11 @@ public class ModelConverterTest {
         assertEquals(kvToMap(expected), kvToMap(actual));
     }
 
+    private void assertFeatureKVMapEquals(org.apache.sling.feature.KeyValueMap expected,
+            org.apache.sling.feature.KeyValueMap actual) {
+        assertEquals(featureKvToMap(expected), featureKvToMap(actual));
+    }
+
     private void assertSectionsEqual(List<Section> expected, List<Section> actual) {
         assertEquals(expected.size(), actual.size());
 

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