You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ni...@apache.org on 2019/11/07 11:02:37 UTC
[servicecomb-toolkit] 02/07: SCB-1555 Integrate oas-validator
compability check to cli Add subcommands checkcompatibility and cs to cli
This is an automated email from the ASF dual-hosted git repository.
ningjiang pushed a commit to branch import-oas-validator
in repository https://gitbox.apache.org/repos/asf/servicecomb-toolkit.git
commit 37da70ba772f66f4d5f0d1ce8c55a3fecb91517b
Author: Daniel Qian <ch...@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));
+ }
+}