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

ningjiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-toolkit.git

commit 653b4b2cfc1316b1cc1847dee57bdddd1faf9103
Author: Daniel Qian <chanjars...@gmail.com>
AuthorDate: Thu Nov 7 14:25:47 2019 +0800

    SCB-1555 Integrate oas-validator compability check to cli
    Add subcommands checkcompatibility and cs to cli
---
 cli/pom.xml                                        |   5 +
 .../toolkit/cli/CheckCompatibility.java            |  26 +++++
 .../toolkit/cli/CheckCompatibilityAbbr.java        |  26 +++++
 .../toolkit/cli/CheckCompatibilityBase.java        | 129 +++++++++++++++++++++
 .../servicecomb/toolkit/cli/CheckStyleBase.java    |  14 +--
 .../servicecomb/toolkit/cli/ToolkitMain.java       |   7 +-
 .../apache/servicecomb/toolkit/cli/CliTest.java    |  25 +++-
 .../{parser-test.yaml => compatibility-left.yaml}  |   6 +-
 .../{parser-test.yaml => compatibility-right.yaml} |   8 +-
 .../resources/oas/{parser-test.yaml => style.yaml} |   0
 ...dingAllowedReservedChangeDiffValidatorTest.java |   1 -
 .../oasv/common/OasObjectPropertyLocation.java     |  14 +++
 .../oasv/common/OasObjectPropertyLocationTest.java |  16 +++
 13 files changed, 259 insertions(+), 18 deletions(-)

diff --git a/cli/pom.xml b/cli/pom.xml
index 6a222d7..4499804 100644
--- a/cli/pom.xml
+++ b/cli/pom.xml
@@ -85,6 +85,11 @@
       <groupId>org.apache.servicecomb.toolkit</groupId>
       <artifactId>oas-validator-compliance</artifactId>
     </dependency>
+
+    <dependency>
+      <groupId>org.apache.servicecomb.toolkit</groupId>
+      <artifactId>oas-validator-compatibility</artifactId>
+    </dependency>
   </dependencies>
 
   <build>
diff --git 
a/cli/src/main/java/org/apache/servicecomb/toolkit/cli/CheckCompatibility.java 
b/cli/src/main/java/org/apache/servicecomb/toolkit/cli/CheckCompatibility.java
new file mode 100644
index 0000000..c12439d
--- /dev/null
+++ 
b/cli/src/main/java/org/apache/servicecomb/toolkit/cli/CheckCompatibility.java
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+package org.apache.servicecomb.toolkit.cli;
+
+import io.airlift.airline.Command;
+
+@Command(name = "checkcompatibility",
+    description = "Check compatibility for two OpenAPI v3 spec yamls, right 
one should be semantically compatible with left one")
+public class CheckCompatibility extends CheckCompatibilityBase {
+
+}
diff --git 
a/cli/src/main/java/org/apache/servicecomb/toolkit/cli/CheckCompatibilityAbbr.java
 
b/cli/src/main/java/org/apache/servicecomb/toolkit/cli/CheckCompatibilityAbbr.java
new file mode 100644
index 0000000..2f14b2b
--- /dev/null
+++ 
b/cli/src/main/java/org/apache/servicecomb/toolkit/cli/CheckCompatibilityAbbr.java
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+package org.apache.servicecomb.toolkit.cli;
+
+import io.airlift.airline.Command;
+
+@Command(name = "cc",
+    description = "Check compatibility for two OpenAPI v3 spec yamls, right 
one should be semantically compatible with left one")
+public class CheckCompatibilityAbbr extends CheckCompatibilityBase {
+
+}
diff --git 
a/cli/src/main/java/org/apache/servicecomb/toolkit/cli/CheckCompatibilityBase.java
 
b/cli/src/main/java/org/apache/servicecomb/toolkit/cli/CheckCompatibilityBase.java
new file mode 100644
index 0000000..298132f
--- /dev/null
+++ 
b/cli/src/main/java/org/apache/servicecomb/toolkit/cli/CheckCompatibilityBase.java
@@ -0,0 +1,129 @@
+/*
+ * 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.
+ */
+
+package org.apache.servicecomb.toolkit.cli;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.StringJoiner;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.io.FileUtils;
+import org.apache.servicecomb.toolkit.oasv.common.OasObjectPropertyLocation;
+import 
org.apache.servicecomb.toolkit.oasv.compatibility.CompatibilityCheckParser;
+import 
org.apache.servicecomb.toolkit.oasv.compatibility.factory.DefaultOasSpecDiffValidatorFactory;
+import 
org.apache.servicecomb.toolkit.oasv.diffvalidation.api.OasDiffValidationContext;
+import org.apache.servicecomb.toolkit.oasv.diffvalidation.api.OasDiffViolation;
+import 
org.apache.servicecomb.toolkit.oasv.diffvalidation.api.OasSpecDiffValidator;
+import 
org.apache.servicecomb.toolkit.oasv.diffvalidation.factory.OasSpecDiffValidatorFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import 
org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+import io.airlift.airline.Arguments;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.parser.core.models.SwaggerParseResult;
+
+public class CheckCompatibilityBase implements Runnable {
+
+  private final Logger LOGGER = LoggerFactory.getLogger(this.getClass());
+
+  @Arguments(
+      title = "files", required = true,
+      description = "Two OpenAPI v3 spec yamls"
+  )
+  private List<String> filePaths;
+
+  @Override
+  public void run() {
+
+    if (filePaths.size() != 2) {
+      LOGGER.error("Require 2 files");
+      return;
+    }
+
+    OpenAPI oldOas = null;
+    OpenAPI newOas = null;
+    try {
+      oldOas = loadOpenApi(filePaths.get(0));
+      newOas = loadOpenApi(filePaths.get(1));
+    } catch (Exception e) {
+      LOGGER.error(e.getMessage());
+      return;
+    }
+
+    OasSpecDiffValidator diffValidator = createOasSpecDiffValidator();
+
+    List<OasDiffViolation> violations = 
diffValidator.validate(createContext(oldOas, newOas), oldOas, newOas);
+
+    if (CollectionUtils.isNotEmpty(violations)) {
+      for (OasDiffViolation violation : violations) {
+        LOGGER.info("left  : {}\nright : {}\nerror : {}\n------",
+            
OasObjectPropertyLocation.toPathString(violation.getLeftLocation()),
+            
OasObjectPropertyLocation.toPathString(violation.getRightLocation()),
+            violation.getError()
+        );
+      }
+      return;
+    }
+    LOGGER.info("Everything is good");
+  }
+
+  private OpenAPI loadOpenApi(String filePath) throws IOException {
+    String yaml = loadFileContent(filePath);
+    SwaggerParseResult oldParseResult = 
CompatibilityCheckParser.parseYaml(yaml);
+    OpenAPI openAPI = oldParseResult.getOpenAPI();
+    if (openAPI == null) {
+      StringJoiner errors = new StringJoiner("\n", "Parse errors:", "");
+      if (CollectionUtils.isNotEmpty(oldParseResult.getMessages())) {
+        for (String message : oldParseResult.getMessages()) {
+          errors.add(message);
+        }
+      }
+      throw new RuntimeException(errors.toString());
+    }
+
+    return openAPI;
+  }
+
+
+  private OasSpecDiffValidator createOasSpecDiffValidator() {
+    AnnotationConfigApplicationContext ctx = new 
AnnotationConfigApplicationContext(
+        DefaultOasSpecDiffValidatorFactory.class.getPackage().getName());
+    try {
+      OasSpecDiffValidatorFactory diffValidatorFactory = 
ctx.getBean(OasSpecDiffValidatorFactory.class);
+      return diffValidatorFactory.create();
+    } finally {
+      ctx.close();
+    }
+  }
+
+
+  private String loadFileContent(String filePath) throws IOException {
+    Path specPath = Paths.get(filePath);
+    specPath.toAbsolutePath().toString();
+    return FileUtils.readFileToString(specPath.toFile());
+  }
+
+  private OasDiffValidationContext createContext(OpenAPI leftOpenAPI, OpenAPI 
rightOpenAPI) {
+
+    OasDiffValidationContext context = new 
OasDiffValidationContext(leftOpenAPI, rightOpenAPI);
+    return context;
+  }
+}
diff --git 
a/cli/src/main/java/org/apache/servicecomb/toolkit/cli/CheckStyleBase.java 
b/cli/src/main/java/org/apache/servicecomb/toolkit/cli/CheckStyleBase.java
index e021d9f..393d97d 100644
--- a/cli/src/main/java/org/apache/servicecomb/toolkit/cli/CheckStyleBase.java
+++ b/cli/src/main/java/org/apache/servicecomb/toolkit/cli/CheckStyleBase.java
@@ -24,7 +24,6 @@ import java.util.List;
 
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.io.FileUtils;
-import org.apache.servicecomb.toolkit.oasv.common.OasObjectProperty;
 import org.apache.servicecomb.toolkit.oasv.common.OasObjectPropertyLocation;
 import org.apache.servicecomb.toolkit.oasv.compliance.ComplianceCheckParser;
 import 
org.apache.servicecomb.toolkit.oasv.compliance.factory.DefaultOasSpecValidatorFactory;
@@ -37,7 +36,6 @@ import org.slf4j.LoggerFactory;
 import 
org.springframework.context.annotation.AnnotationConfigApplicationContext;
 
 import io.airlift.airline.Arguments;
-import io.airlift.airline.Command;
 import io.swagger.v3.oas.models.OpenAPI;
 import io.swagger.v3.parser.core.models.SwaggerParseResult;
 
@@ -79,22 +77,14 @@ public class CheckStyleBase implements Runnable {
     List<OasViolation> violations = 
oasSpecValidator.validate(createContext(openAPI), openAPI);
     if (CollectionUtils.isNotEmpty(violations)) {
       for (OasViolation violation : violations) {
-        LOGGER.info("{}: {}", toPathString(violation.getLocation()), 
violation.getError());
+        LOGGER.info("path  : {}\nerror : {}\n------",
+            OasObjectPropertyLocation.toPathString(violation.getLocation()), 
violation.getError());
       }
       return;
     }
     LOGGER.info("Everything is good");
   }
 
-  private String toPathString(OasObjectPropertyLocation location) {
-    StringBuilder sb = new StringBuilder();
-    List<OasObjectProperty> path = location.getPath();
-    for (OasObjectProperty property : path) {
-      sb.append(property.getName()).append('.');
-    }
-    sb.deleteCharAt(sb.length() - 1);
-    return sb.toString();
-  }
 
   private OasSpecValidator createOasSpecValidator() {
     AnnotationConfigApplicationContext ctx = new 
AnnotationConfigApplicationContext(
diff --git 
a/cli/src/main/java/org/apache/servicecomb/toolkit/cli/ToolkitMain.java 
b/cli/src/main/java/org/apache/servicecomb/toolkit/cli/ToolkitMain.java
index 39b2477..5a75e86 100755
--- a/cli/src/main/java/org/apache/servicecomb/toolkit/cli/ToolkitMain.java
+++ b/cli/src/main/java/org/apache/servicecomb/toolkit/cli/ToolkitMain.java
@@ -37,7 +37,12 @@ public class ToolkitMain {
     builder.withDescription("Microservice development toolkit(version " + 
projectVersion
         + "). ");
     builder.withDefaultCommand(Help.class);
-    builder.withCommands(CodeGenerate.class, DocGenerate.class, 
CheckStyle.class, CheckStyleAbbr.class, Help.class);
+    builder.withCommands(
+        CodeGenerate.class, DocGenerate.class,
+        CheckStyle.class, CheckStyleAbbr.class,
+        CheckCompatibility.class, CheckCompatibilityAbbr.class,
+        Help.class
+    );
     Runnable cmd = builder.build().parse(args);
 
     cmd.run();
diff --git a/cli/src/test/java/org/apache/servicecomb/toolkit/cli/CliTest.java 
b/cli/src/test/java/org/apache/servicecomb/toolkit/cli/CliTest.java
index 2068ddb..5990a0b 100755
--- a/cli/src/test/java/org/apache/servicecomb/toolkit/cli/CliTest.java
+++ b/cli/src/test/java/org/apache/servicecomb/toolkit/cli/CliTest.java
@@ -95,7 +95,7 @@ public class CliTest {
   public void testCheckStyle() throws IOException {
     String[] args = new String[] {
         "checkstyle",
-        
Paths.get("./src/test/resources/oas/parser-test.yaml").toFile().getCanonicalPath()
+        
Paths.get("./src/test/resources/oas/style.yaml").toFile().getCanonicalPath()
     };
     ToolkitMain.main(args);
   }
@@ -104,9 +104,30 @@ public class CliTest {
   public void testCheckStyleAbbr() throws IOException {
     String[] args = new String[] {
         "cs",
-        
Paths.get("./src/test/resources/oas/parser-test.yaml").toFile().getCanonicalPath()
+        
Paths.get("./src/test/resources/oas/style.yaml").toFile().getCanonicalPath()
     };
     ToolkitMain.main(args);
   }
 
+  @Test
+  public void testCheckCompatibility() throws IOException {
+    String[] args = new String[] {
+        "checkcompatibility",
+        
Paths.get("./src/test/resources/oas/compatibility-left.yaml").toFile().getCanonicalPath(),
+        
Paths.get("./src/test/resources/oas/compatibility-right.yaml").toFile().getCanonicalPath()
+    };
+    ToolkitMain.main(args);
+  }
+
+  @Test
+  public void testCheckCompatibilityAbbr() throws IOException {
+    String[] args = new String[] {
+        "cc",
+        
Paths.get("./src/test/resources/oas/compatibility-left.yaml").toFile().getCanonicalPath(),
+        
Paths.get("./src/test/resources/oas/compatibility-right.yaml").toFile().getCanonicalPath()
+    };
+    ToolkitMain.main(args);
+  }
+
+
 }
diff --git a/cli/src/test/resources/oas/parser-test.yaml 
b/cli/src/test/resources/oas/compatibility-left.yaml
old mode 100644
new mode 100755
similarity index 94%
copy from cli/src/test/resources/oas/parser-test.yaml
copy to cli/src/test/resources/oas/compatibility-left.yaml
index f7b88b5..ea3e0e8
--- a/cli/src/test/resources/oas/parser-test.yaml
+++ b/cli/src/test/resources/oas/compatibility-left.yaml
@@ -17,7 +17,11 @@
 openapi: "3.0.0"
 info:
   version: 1.0.0
-  title: Pet petstore
+  title: Swagger petstore
+  license:
+    name: MIT
+servers:
+  - url: http://petstore.swagger.io/v1
 paths:
   /pets:
     get:
diff --git a/cli/src/test/resources/oas/parser-test.yaml 
b/cli/src/test/resources/oas/compatibility-right.yaml
old mode 100644
new mode 100755
similarity index 90%
copy from cli/src/test/resources/oas/parser-test.yaml
copy to cli/src/test/resources/oas/compatibility-right.yaml
index f7b88b5..5854b12
--- a/cli/src/test/resources/oas/parser-test.yaml
+++ b/cli/src/test/resources/oas/compatibility-right.yaml
@@ -17,7 +17,11 @@
 openapi: "3.0.0"
 info:
   version: 1.0.0
-  title: Pet petstore
+  title: Swagger petstore
+  license:
+    name: MIT
+servers:
+  - url: http://petstore.swagger.io/v1
 paths:
   /pets:
     get:
@@ -43,6 +47,8 @@ paths:
             encoding:
               foo:
                 contentType: 'application/octet-stream'
+              bar:
+                contentType: 'application/octet-stream'
       responses:
         '200':
           description: A paged array of pets
diff --git a/cli/src/test/resources/oas/parser-test.yaml 
b/cli/src/test/resources/oas/style.yaml
similarity index 100%
rename from cli/src/test/resources/oas/parser-test.yaml
rename to cli/src/test/resources/oas/style.yaml
diff --git 
a/oas-validator/oas-validator-compatibility/src/test/java/org/apache/servicecomb/toolkit/oasv/compatibility/validators/encoding/EncodingAllowedReservedChangeDiffValidatorTest.java
 
b/oas-validator/oas-validator-compatibility/src/test/java/org/apache/servicecomb/toolkit/oasv/compatibility/validators/encoding/EncodingAllowedReservedChangeDiffValidatorTest.java
index d9d640f..e0e7e51 100755
--- 
a/oas-validator/oas-validator-compatibility/src/test/java/org/apache/servicecomb/toolkit/oasv/compatibility/validators/encoding/EncodingAllowedReservedChangeDiffValidatorTest.java
+++ 
b/oas-validator/oas-validator-compatibility/src/test/java/org/apache/servicecomb/toolkit/oasv/compatibility/validators/encoding/EncodingAllowedReservedChangeDiffValidatorTest.java
@@ -40,7 +40,6 @@ public class EncodingAllowedReservedChangeDiffValidatorTest 
extends OasCompatibi
   @Test
   public void validate() {
     OpenAPI leftOpenAPI = 
loadRelative("petstore-encoding-allow-reserved-a.yaml");
-    System.out.println(leftOpenAPI.toString());
     OpenAPI rightOpenAPI = 
loadRelative("petstore-encoding-allow-reserved-b.yaml");
     List<OasDiffViolation> violations = oasSpecDiffValidator
       .validate(createContext(leftOpenAPI, rightOpenAPI), leftOpenAPI, 
rightOpenAPI);
diff --git 
a/oas-validator/oas-validator-core/src/main/java/org/apache/servicecomb/toolkit/oasv/common/OasObjectPropertyLocation.java
 
b/oas-validator/oas-validator-core/src/main/java/org/apache/servicecomb/toolkit/oasv/common/OasObjectPropertyLocation.java
index 346e667..a97ef0f 100755
--- 
a/oas-validator/oas-validator-core/src/main/java/org/apache/servicecomb/toolkit/oasv/common/OasObjectPropertyLocation.java
+++ 
b/oas-validator/oas-validator-core/src/main/java/org/apache/servicecomb/toolkit/oasv/common/OasObjectPropertyLocation.java
@@ -117,4 +117,18 @@ public class OasObjectPropertyLocation {
       .add("path=" + path)
       .toString();
   }
+
+  public static String toPathString(OasObjectPropertyLocation location) {
+    if (location == null) {
+      return "";
+    }
+
+    StringBuilder sb = new StringBuilder();
+    List<OasObjectProperty> path = location.getPath();
+    for (OasObjectProperty property : path) {
+      sb.append(property.getName()).append('.');
+    }
+    sb.deleteCharAt(sb.length() - 1);
+    return sb.toString();
+  }
 }
diff --git 
a/oas-validator/oas-validator-core/src/test/java/org/apache/servicecomb/toolkit/oasv/common/OasObjectPropertyLocationTest.java
 
b/oas-validator/oas-validator-core/src/test/java/org/apache/servicecomb/toolkit/oasv/common/OasObjectPropertyLocationTest.java
new file mode 100644
index 0000000..ac5bcd5
--- /dev/null
+++ 
b/oas-validator/oas-validator-core/src/test/java/org/apache/servicecomb/toolkit/oasv/common/OasObjectPropertyLocationTest.java
@@ -0,0 +1,16 @@
+package org.apache.servicecomb.toolkit.oasv.common;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+public class OasObjectPropertyLocationTest {
+
+  @Test
+  public void toPathString() {
+    assertEquals("$.foo.bar",
+        
OasObjectPropertyLocation.toPathString(OasObjectPropertyLocation.root().property("foo").property("bar")));
+
+    assertEquals("", OasObjectPropertyLocation.toPathString(null));
+  }
+}

Reply via email to