-
Notifications
You must be signed in to change notification settings - Fork 531
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Action to validate a definition using parser cli #1774
Changes from 13 commits
767b620
cdb4bc9
be358d5
63064ee
c70c219
33b586f
9b7f23a
642047f
467dc95
510eda5
c3467ef
a385a99
263ab9b
9cb5477
bbe9510
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
name: 'Swagger Parser CLI' | ||
description: 'Uses swagger parser CLI to allow validation of a definition' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. change to "Parses, validates, dereferences an OpenAPI definition" |
||
inputs: | ||
inputSpec: | ||
description: 'file of the openapi definition' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. path to OpenAPI definition file |
||
required: true | ||
options: | ||
description: 'parser options' | ||
required: false | ||
logsPath: | ||
description: 'file of the logs messages or errors' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. path to validation result file |
||
required: true | ||
parserSpecPath: | ||
description: 'path where a file can be found with parsed definition' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. output path of the serialized parsed definition |
||
required: false | ||
runs: | ||
using: "composite" | ||
steps: | ||
- id: java-version | ||
run: java -version 2>&1 | fgrep -i version | cut -d'"' -f2 | sed -e 's/^1\./1\%/' -e 's/\..*//' -e 's/%/./' | ||
shell: bash | ||
- name: Build Java | ||
if: steps.java-version == null || steps.java-version < 1.8 | ||
uses: actions/setup-java@v3 | ||
with: | ||
distribution: 'zulu' | ||
java-version: '11' | ||
- name: Download JAR | ||
run: curl -L "https://repository.sonatype.org/service/local/artifact/maven/content?r=central-proxy&g=io.swagger.parser.v3&a=swagger-parser-cli&e=jar&v=LATEST" -o swagger-parser-cli.jar | ||
shell: bash | ||
- id: execute | ||
name: Execute Jar | ||
run: java -jar swagger-parser-cli.jar -i ${{ inputs.inputSpec }} ${{ inputs.options }} -o ${{ inputs.parserSpecPath }} -l ${{ inputs.logsPath }} | ||
shell: bash |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
name: SwaggerParserCLI Test | ||
|
||
on: [push] | ||
|
||
jobs: | ||
validate_job: | ||
runs-on: ubuntu-latest | ||
name: A job to validate a definition | ||
steps: | ||
- uses: actions/checkout@v3 | ||
with: | ||
ref: action | ||
- uses: ./.github/actions/ | ||
with: | ||
inputSpec: '/home/runner/work/swagger-parser/swagger-parser/modules/swagger-parser-cli/src/test/resources/fileWithNoErrorMessages.yaml' | ||
options: '-resolve -resolveFully' | ||
logsPath: '/home/runner/work/swagger-parser/swagger-parser/modules/swagger-parser-cli/target/test-classes/parserLogs.yaml' | ||
parserSpecPath: '/home/runner/work/swagger-parser/swagger-parser/modules/swagger-parser-cli/target/test-classes/specParsed.yaml' | ||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,144 @@ | ||
package io.swagger.v3.parser; | ||
|
||
import io.swagger.v3.core.util.Json; | ||
import io.swagger.v3.core.util.Yaml; | ||
|
||
import io.swagger.v3.parser.core.models.ParseOptions; | ||
import io.swagger.v3.parser.core.models.SwaggerParseResult; | ||
import net.sourceforge.argparse4j.ArgumentParsers; | ||
import net.sourceforge.argparse4j.impl.Arguments; | ||
import net.sourceforge.argparse4j.inf.ArgumentParser; | ||
import net.sourceforge.argparse4j.inf.ArgumentParserException; | ||
import net.sourceforge.argparse4j.inf.Namespace; | ||
|
||
|
||
import java.io.OutputStream; | ||
import java.nio.file.Files; | ||
import java.nio.file.Paths; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
|
||
public class SwaggerParser { | ||
|
||
public static final String RESOLVE = "resolve"; | ||
public static final String RESOLVEFULLY = "resolvefully"; | ||
public static final String FLATTEN = "flatten"; | ||
|
||
public static void main(String[] args) { | ||
if (args.length > 0){ | ||
List<String> messages = readFromLocation(args[0]); | ||
if ( messages.size() > 0){ | ||
messages.forEach(System.out::println); | ||
ArgumentParser parser = ArgumentParsers.newFor("swagger-parser").build() | ||
.defaultHelp(true); | ||
parser.addArgument("-i") | ||
.dest("i") | ||
.required(true) | ||
.type(String.class) | ||
.help("input file to be parsed"); | ||
parser.addArgument("-resolve") | ||
.dest(RESOLVE) | ||
.type(Boolean.class) | ||
.action(Arguments.storeTrue()) | ||
.setDefault(false) | ||
.help("resolve remote or local references"); | ||
parser.addArgument("-resolveFully") | ||
.dest(RESOLVEFULLY) | ||
.type(Boolean.class) | ||
.action(Arguments.storeTrue()) | ||
.setDefault(false) | ||
.help(""); | ||
parser.addArgument("-flatten") | ||
.dest(FLATTEN) | ||
.type(Boolean.class) | ||
.action(Arguments.storeTrue()) | ||
.setDefault(false) | ||
.help(""); | ||
parser.addArgument("-o") | ||
.dest("o") | ||
.type(String.class) | ||
.help("output file parsed"); | ||
parser.addArgument("-l") | ||
.dest("l") | ||
.type(String.class) | ||
.help("output error logs"); | ||
parser.addArgument("-json") | ||
.dest("json") | ||
.type(String.class) | ||
.help("generate file as JSON"); | ||
parser.addArgument("-yaml") | ||
.dest("yaml") | ||
.type(String.class) | ||
.help("generate file as YAML"); | ||
try{ | ||
readFromLocation(parser.parseArgs(args)); | ||
}catch (ArgumentParserException e) { | ||
parser.handleError(e); | ||
System.exit(1); | ||
} | ||
} | ||
} | ||
|
||
public static List<String> readFromLocation(String location) { | ||
private static void generateMessagesFile(List<String> messages, Namespace arguments) { | ||
if ( messages != null && !messages.isEmpty() && arguments != null && arguments.getString("l") != null){ | ||
if(arguments.getString("l") != null) { | ||
generateParsedFile(arguments, "l", messages.toString()); | ||
} | ||
} | ||
} | ||
|
||
public static List<String> readFromLocation(Namespace args) { | ||
List<String> messages = new ArrayList<>(); | ||
ParseOptions options; | ||
try { | ||
final SwaggerParseResult result = new OpenAPIV3Parser().readLocation(location, null, null); | ||
options = setOptions(args); | ||
final SwaggerParseResult result = new OpenAPIV3Parser().readLocation(args.get("i"), null, options); | ||
if(args.getString("o") != null) { | ||
if (result.getOpenAPI() != null){ | ||
String output; | ||
if(args.getString("json") != null){ | ||
output = Json.pretty(result.getOpenAPI()); | ||
}else if(args.getString("yaml") != null){ | ||
output = Yaml.pretty(result.getOpenAPI()); | ||
}else{ | ||
output= Yaml.pretty(result.getOpenAPI()); | ||
} | ||
generateParsedFile(args, "o", output ); | ||
} | ||
} | ||
if(result.getOpenAPI() == null || !result.getMessages().isEmpty()){ | ||
messages = result.getMessages(); | ||
generateMessagesFile(messages, args); | ||
} | ||
}catch (Exception e){ | ||
e.printStackTrace(); | ||
System.exit(1); | ||
} | ||
return messages; | ||
} | ||
|
||
private static void generateParsedFile(Namespace args, String o, String result) { | ||
try { | ||
if(result != null) { | ||
OutputStream out = Files.newOutputStream(Paths.get(args.getString(o))); | ||
byte[] specBytes = result.getBytes(); | ||
out.write(specBytes); | ||
out.close(); | ||
} | ||
}catch (Exception e){ | ||
e.printStackTrace(); | ||
} | ||
} | ||
|
||
private static ParseOptions setOptions(Namespace parseOptions) { | ||
ParseOptions options = new ParseOptions(); | ||
|
||
if (parseOptions.getString(RESOLVE) !=null && parseOptions.getString(RESOLVE).equals("true")) { | ||
options.setResolve(true); | ||
} | ||
if (parseOptions.getString(RESOLVEFULLY) != null && parseOptions.getString(RESOLVEFULLY).equals("true")) { | ||
options.setResolveFully(true); | ||
} | ||
if (parseOptions.getString(FLATTEN) != null && parseOptions.getString(FLATTEN).equals("true")) { | ||
options.setFlatten(true); | ||
} | ||
return options; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,120 @@ | ||
import io.swagger.v3.parser.SwaggerParser; | ||
import net.sourceforge.argparse4j.inf.ArgumentParserException; | ||
import net.sourceforge.argparse4j.inf.Namespace; | ||
import org.testng.Assert; | ||
import org.testng.annotations.Test; | ||
|
||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.Paths; | ||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
public class SwaggerParserCLITest { | ||
@Test | ||
public void validateOKFromLocationTest(){ | ||
String []args = new String[1]; | ||
args[0] = "src/test/resources/fileWithNoErrorMessages.yaml"; | ||
Assert.assertTrue(SwaggerParser.readFromLocation(args[0]).size() == 0); | ||
Map<String,Object> args = new HashMap(); | ||
args.put("i","src/test/resources/fileWithNoErrorMessages.yaml"); | ||
Namespace namespace = new Namespace(args); | ||
Assert.assertTrue(SwaggerParser.readFromLocation(namespace).size() == 0); | ||
} | ||
|
||
@Test | ||
public void validateErrorFromLocationTest(){ | ||
String []args = new String[1]; | ||
args[0] = "src/test/resources/fileWithValidationErrorMessages.yaml"; | ||
Assert.assertEquals(SwaggerParser.readFromLocation(args[0]).get(0), "attribute info.version is missing"); | ||
Assert.assertEquals(SwaggerParser.readFromLocation(args[0]).get(1), "attribute paths.'/cu'(post).responses.200.description is missing"); | ||
Map<String,Object> args = new HashMap(); | ||
args.put("i","src/test/resources/fileWithValidationErrorMessages.yaml"); | ||
Namespace namespace = new Namespace(args); | ||
Assert.assertEquals(SwaggerParser.readFromLocation(namespace).toString(), "[attribute info.version is missing, attribute paths.'/cu'(post).responses.200.description is missing]"); | ||
} | ||
|
||
@Test | ||
public void validateErrorTest(){ | ||
Map<String,Object> args = new HashMap(); | ||
args.put("i","src/test/resources/fileWithValidationErrorMessages.yaml"); | ||
args.put("resolve", "true"); | ||
args.put("resolvefully", "true"); | ||
args.put("o", "target/test-classes/parsedSpec.yaml"); | ||
args.put("l", "target/test-classes/errorLogs.yaml"); | ||
Namespace namespace = new Namespace(args); | ||
Assert.assertEquals(SwaggerParser.readFromLocation(namespace).toString(), "[attribute info.version is missing, attribute paths.'/cu'(post).responses.200.description is missing]"); | ||
} | ||
|
||
@Test | ||
public void validateFileNotFoundInLocationTest(){ | ||
String []args = new String[1]; | ||
args[0] = "src/test/resources/WrongLocation.yaml"; | ||
Assert.assertTrue(SwaggerParser.readFromLocation(args[0]).size() == 1); | ||
Assert.assertEquals(SwaggerParser.readFromLocation(args[0]).get(0), "Unable to read location `src/test/resources/WrongLocation.yaml`"); | ||
Map<String,Object> args = new HashMap(); | ||
args.put("i","src/test/resources/WrongLocation.yaml"); | ||
args.put("l", "target/test-classes/errorLogs.yaml"); | ||
Namespace namespace = new Namespace(args); | ||
List<String> messages = new ArrayList<>(); | ||
try { | ||
messages = SwaggerParser.readFromLocation(namespace); | ||
}catch (Exception e){ | ||
Assert.fail("error"); | ||
} | ||
Assert.assertTrue( messages.size() == 1); | ||
Assert.assertEquals(messages.toString(), "[Unable to read location `src/test/resources/WrongLocation.yaml`]"); | ||
} | ||
|
||
@Test | ||
public void validateOKFromLocationWithResolveOptionTest(){ | ||
Map<String,Object> args = new HashMap(); | ||
args.put("i","src/test/resources/internal-references-in-external-files/main.yaml"); | ||
args.put("resolve", "true"); | ||
Namespace namespace = new Namespace(args); | ||
Assert.assertTrue(SwaggerParser.readFromLocation(namespace).size() == 0); | ||
} | ||
|
||
@Test | ||
public void validateOKFromLocationWithResolveFullyOptionTestYaml(){ | ||
Map<String,Object> args = new HashMap(); | ||
args.put("i","src/test/resources/internal-references-in-external-files/main.yaml"); | ||
args.put("resolve", "true"); | ||
args.put("resolvefully", "true"); | ||
args.put("yaml", "true"); | ||
args.put("o", "target/test-classes/parsedSpec.yaml"); | ||
Namespace namespace = new Namespace(args); | ||
Path path = Paths.get("target/test-classes/parsedSpec.yaml"); | ||
|
||
Assert.assertTrue(SwaggerParser.readFromLocation(namespace).size() == 0); | ||
Assert.assertTrue(Files.exists(path)); | ||
} | ||
|
||
@Test | ||
public void validateOKFromLocationWithResolveFullyOptionTestJson(){ | ||
Map<String,Object> args = new HashMap(); | ||
args.put("i","src/test/resources/internal-references-in-external-files/main.yaml"); | ||
args.put("resolve", "true"); | ||
args.put("resolvefully", "true"); | ||
args.put("json", "true"); | ||
args.put("o", "target/test-classes/parsedSpec.json"); | ||
Namespace namespace = new Namespace(args); | ||
Path path = Paths.get("target/test-classes/parsedSpec.json"); | ||
|
||
Assert.assertTrue(SwaggerParser.readFromLocation(namespace).size() == 0); | ||
Assert.assertTrue(Files.exists(path)); | ||
} | ||
|
||
@Test | ||
public void validateOKFromLocationWithOnlyResolveFullyOptionTest(){ | ||
Map<String,Object> args = new HashMap(); | ||
args.put("i","src/test/resources/internal-references-in-external-files/main.yaml"); | ||
args.put("resolvefully","true"); | ||
Namespace namespace = new Namespace(args); | ||
Assert.assertTrue(SwaggerParser.readFromLocation(namespace).size() == 0); | ||
} | ||
|
||
@Test | ||
public void validateOKFromLocationWithFlattenOptionTest() throws ArgumentParserException { | ||
Map<String,Object> args = new HashMap(); | ||
args.put("i","src/test/resources/internal-references-in-external-files/main.yaml"); | ||
args.put("resolve", "true"); | ||
args.put("resolvefully", "true"); | ||
args.put("flatten", "true"); | ||
args.put("o", "target/test-classes/parsedSpec.yaml"); | ||
args.put("l", "target/test-classes/errorLogs.yaml"); | ||
Namespace namespace = new Namespace(args); | ||
Assert.assertTrue(SwaggerParser.readFromLocation(namespace).size() == 0); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
common: | ||
allOf: | ||
- $ref: "#/core" | ||
- type: object | ||
properties: | ||
attribute: | ||
type: string | ||
direct: | ||
$ref: "#/core" | ||
referenced: | ||
type: array | ||
items: | ||
$ref: "#/core" | ||
|
||
core: | ||
type: object | ||
properties: | ||
coreAttribute: | ||
type: string | ||
inner: | ||
$ref: "#/innerCore" | ||
|
||
innerCore: | ||
type: object | ||
properties: | ||
innerCoreAttribute: | ||
type: string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
change to "Swagger Parser"