You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by si...@apache.org on 2018/11/08 16:15:31 UTC

[sling-slingfeature-maven-plugin] branch SLING-8032 created (now 23959e8)

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

simonetripodi pushed a change to branch SLING-8032
in repository https://gitbox.apache.org/repos/asf/sling-slingfeature-maven-plugin.git.


      at 23959e8  SLING-8032 - Add a MOJO which is able to validate JSON Feature file against the JSON Schema

This branch includes the following new commits:

     new 23959e8  SLING-8032 - Add a MOJO which is able to validate JSON Feature file against the JSON Schema

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-slingfeature-maven-plugin] 01/01: SLING-8032 - Add a MOJO which is able to validate JSON Feature file against the JSON Schema

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

simonetripodi pushed a commit to branch SLING-8032
in repository https://gitbox.apache.org/repos/asf/sling-slingfeature-maven-plugin.git

commit 23959e83d63c36b313fba44362a6eb59863f6968
Author: Simo Tripodi <st...@adobe.com>
AuthorDate: Thu Nov 8 17:15:13 2018 +0100

    SLING-8032 - Add a MOJO which is able to validate JSON Feature file
    against the JSON Schema
    
    JSON schema validation moved from MOJO to Preprocessor
---
 pom.xml                                            | 11 +++
 src/it/schema-validation-ko/invoker.properties     | 18 +++++
 src/it/schema-validation-ko/pom.xml                | 44 ++++++++++++
 .../src/main/features/invalid-feature.json         |  5 ++
 src/it/schema-validation-ko/verify.bsh             | 42 ++++++++++++
 .../apache/sling/feature/maven/Preprocessor.java   | 80 ++++++++++++++++++----
 6 files changed, 186 insertions(+), 14 deletions(-)

diff --git a/pom.xml b/pom.xml
index 32c0684..e8e3826 100644
--- a/pom.xml
+++ b/pom.xml
@@ -232,6 +232,17 @@
             <artifactId>maven-filtering</artifactId>
             <version>3.1.1</version>
         </dependency>
+        <!-- schema validation -->
+        <dependency>
+            <groupId>com.github.java-json-tools</groupId>
+            <artifactId>json-schema-validator</artifactId>
+            <version>2.2.10</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
+            <version>2.2.3</version>
+        </dependency>
         <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-all</artifactId>
diff --git a/src/it/schema-validation-ko/invoker.properties b/src/it/schema-validation-ko/invoker.properties
new file mode 100644
index 0000000..57af569
--- /dev/null
+++ b/src/it/schema-validation-ko/invoker.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+invoker.goals = clean validate
+invoker.buildResult = failure
+invoker.debug = true
diff --git a/src/it/schema-validation-ko/pom.xml b/src/it/schema-validation-ko/pom.xml
new file mode 100644
index 0000000..185ab58
--- /dev/null
+++ b/src/it/schema-validation-ko/pom.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+    agreements. See the NOTICE file distributed with this work for additional information
+    regarding copyright ownership. The ASF licenses this file to you under the Apache License,
+    Version 2.0 (the "License"); you may not use this file except in compliance with the
+    License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software distributed under the
+    License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+    either express or implied. See the License for the specific language governing permissions
+    and limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache.sling</groupId>
+  <artifactId>slingfeature-maven-plugin-test</artifactId>
+  <packaging>jar</packaging>
+  <version>1.0.0-SNAPSHOT</version>
+
+  <name>Apache Sling Features Maven plugin test</name>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>@project.groupId@</groupId>
+        <artifactId>@project.artifactId@</artifactId>
+        <version>@project.version@</version>
+        <extensions>true</extensions>
+        <executions>
+          <execution>
+            <id>analyze</id>
+            <phase>validate</phase>
+            <goals>
+              <goal>features-schema-validation</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+</project>
diff --git a/src/it/schema-validation-ko/src/main/features/invalid-feature.json b/src/it/schema-validation-ko/src/main/features/invalid-feature.json
new file mode 100644
index 0000000..59ff8cc
--- /dev/null
+++ b/src/it/schema-validation-ko/src/main/features/invalid-feature.json
@@ -0,0 +1,5 @@
+{
+  "id":"org.apache.sling:slingfeature-maven-plugin-test:1.0.0-SNAPSHOT",
+  "model-version": 5,
+  "bundles": [ false ]
+}
diff --git a/src/it/schema-validation-ko/verify.bsh b/src/it/schema-validation-ko/verify.bsh
new file mode 100644
index 0000000..e41e362
--- /dev/null
+++ b/src/it/schema-validation-ko/verify.bsh
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ import java.io.*;
+import java.util.*;
+ import org.codehaus.plexus.util.*;
+     boolean check() {
+        File file = new File(basedir, "build.log");
+        String log = FileUtils.fileRead(file);
+         String[] values = {
+            " * /definitions/Bundle: instance type (boolean) does not match any allowed primitive type (allowed: [\"object\",\"string\"])",
+            " * /properties/model-version: instance type (integer) does not match any allowed primitive type (allowed: [\"string\"])"
+        };
+         for (String value : values) {
+            if (log.indexOf(value) < 0) {
+                System.out.println("FAILED!");
+                return false;
+            }
+        }
+         return true;
+    }
+     try {
+      return check();
+    }
+    catch(Throwable t) {
+      t.printStackTrace();
+      return false;
+    }
+     return true;
diff --git a/src/main/java/org/apache/sling/feature/maven/Preprocessor.java b/src/main/java/org/apache/sling/feature/maven/Preprocessor.java
index 6e03c84..931c5d7 100644
--- a/src/main/java/org/apache/sling/feature/maven/Preprocessor.java
+++ b/src/main/java/org/apache/sling/feature/maven/Preprocessor.java
@@ -16,20 +16,6 @@
  */
 package org.apache.sling.feature.maven;
 
-import org.apache.maven.model.Dependency;
-import org.apache.maven.project.MavenProject;
-import org.apache.maven.shared.utils.io.DirectoryScanner;
-import org.apache.sling.feature.Artifact;
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.Extension;
-import org.apache.sling.feature.ExtensionType;
-import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.builder.BuilderContext;
-import org.apache.sling.feature.builder.FeatureBuilder;
-import org.apache.sling.feature.builder.FeatureProvider;
-import org.apache.sling.feature.io.json.FeatureJSONReader;
-import org.codehaus.plexus.logging.Logger;
-
 import java.io.File;
 import java.io.FileReader;
 import java.io.IOException;
@@ -37,6 +23,7 @@ import java.io.Reader;
 import java.io.StringReader;
 import java.io.StringWriter;
 import java.util.ArrayList;
+import java.util.Formatter;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -50,11 +37,73 @@ import javax.json.JsonReader;
 import javax.json.JsonValue;
 import javax.json.stream.JsonGenerator;
 
+import org.apache.maven.model.Dependency;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.shared.utils.io.DirectoryScanner;
+import org.apache.sling.feature.Artifact;
+import org.apache.sling.feature.ArtifactId;
+import org.apache.sling.feature.Extension;
+import org.apache.sling.feature.ExtensionType;
+import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.builder.BuilderContext;
+import org.apache.sling.feature.builder.FeatureBuilder;
+import org.apache.sling.feature.builder.FeatureProvider;
+import org.apache.sling.feature.io.json.FeatureJSONReader;
+import org.codehaus.plexus.logging.Logger;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.fge.jsonschema.core.exceptions.ProcessingException;
+import com.github.fge.jsonschema.core.report.LogLevel;
+import com.github.fge.jsonschema.core.report.ProcessingMessage;
+import com.github.fge.jsonschema.core.report.ProcessingReport;
+import com.github.fge.jsonschema.main.JsonSchema;
+import com.github.fge.jsonschema.main.JsonSchemaFactory;
+
 /**
  * The processor processes all feature projects.
  */
 public class Preprocessor {
 
+    private final JsonSchema schema;
+
+    private final ObjectMapper objectMapper;
+
+    public Preprocessor() {
+       JsonSchemaFactory schemaFactory = JsonSchemaFactory.byDefault();
+       String jsonSchemaUri = getClass().getClassLoader().getResource("META-INF/feature/Feature-1.0.0.schema.json").toExternalForm();
+       try {
+           schema = schemaFactory.getJsonSchema(jsonSchemaUri);
+       } catch (ProcessingException e) {
+           throw new RuntimeException("An error occured when retrieving the JSON Schema from " + jsonSchemaUri, e);
+       }
+        objectMapper = new ObjectMapper();
+   }
+    private void checkFeatureFileValidation(File featureFile) {
+       try {
+           JsonNode instance = objectMapper.readTree(featureFile);
+           ProcessingReport report = schema.validate(instance, true);
+           if (!report.isSuccess()) {
+               Formatter formatter = new Formatter();
+               formatter.format("Feature file %s validation detected one or more errors:%n", featureFile);
+                for (ProcessingMessage message : report) {
+                   if (LogLevel.FATAL == message.getLogLevel()
+                           || LogLevel.ERROR == message.getLogLevel())
+                   formatter.format(" * %s: %s%n",
+                                    message.asJson().get("schema").get("pointer").asText(),
+                                    message.getMessage());
+               }
+                String errorMessage = formatter.toString();
+               formatter.close();
+               throw new RuntimeException(errorMessage);
+           }
+       } catch (IOException e) {
+           throw new RuntimeException("An error occurred while reading " + featureFile + " Feature file:", e);
+       } catch (ProcessingException e) {
+           throw new RuntimeException("An error occurred while validating Feature " + featureFile + ", read the log for details:", e);
+       }
+   }
+
     /**
      * Process the provided projects.
      * @param env The environment with all maven settings and projects
@@ -256,6 +305,8 @@ public class Preprocessor {
                     throw new RuntimeException("Unable to read feature " + file.getAbsolutePath(), io);
                 }
 
+                checkFeatureFileValidation(file);
+
                 final String json = preprocessFeature(logger, info, config, file, sb.toString());
                 try (final Reader reader = new StringReader(json)) {
                     final Feature feature = FeatureJSONReader.read(reader, file.getAbsolutePath());
@@ -404,6 +455,7 @@ public class Preprocessor {
 
 	                    // "external" dependency, we can already resolve it
 	                    final File featureFile = ProjectHelper.getOrResolveArtifact(info.project, env.session, env.artifactHandlerManager, env.resolver, id).getFile();
+	                    checkFeatureFileValidation(featureFile);
 	                    try (final FileReader r = new FileReader(featureFile)) {
 	                        return FeatureJSONReader.read(r, featureFile.getAbsolutePath());
 	                    } catch ( final IOException ioe) {