From fa95a672df7e38eab72551c5775cbc99ce6ebe36 Mon Sep 17 00:00:00 2001 From: gracekarina Date: Tue, 29 May 2018 03:15:34 -0500 Subject: [PATCH 1/5] fixing relative references --- .../v3/parser/util/OpenAPIDeserializer.java | 20 +++++- .../io/swagger/v3/parser/util/PathUtils.java | 31 ++++++--- .../io/swagger/v3/parser/util/RefUtils.java | 23 +++++-- .../v3/parser/test/OpenAPIV3ParserTest.java | 24 +++++-- .../swagger/v3/parser/util/RefUtilsTest.java | 12 +++- .../Paths/Address.yaml | 66 +++++++++++++++++++ .../Schemas/schema.yaml | 24 +++++++ .../relative-upper-directory/swagger.yaml | 11 ++++ .../resources/sample/SwaggerPetstore.yaml | 63 ++++++++++++++++++ .../src/test/resources/sample/pets.yaml | 62 +++++++++++++++++ .../src/test/resources/sample/schema.yaml | 31 +++++++++ 11 files changed, 343 insertions(+), 24 deletions(-) create mode 100644 modules/swagger-parser-v3/src/test/resources/relative-upper-directory/Paths/Address.yaml create mode 100644 modules/swagger-parser-v3/src/test/resources/relative-upper-directory/Schemas/schema.yaml create mode 100644 modules/swagger-parser-v3/src/test/resources/relative-upper-directory/swagger.yaml create mode 100755 modules/swagger-parser-v3/src/test/resources/sample/SwaggerPetstore.yaml create mode 100755 modules/swagger-parser-v3/src/test/resources/sample/pets.yaml create mode 100755 modules/swagger-parser-v3/src/test/resources/sample/schema.yaml diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/OpenAPIDeserializer.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/OpenAPIDeserializer.java index 3bdeb8f115..976fd1c48c 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/OpenAPIDeserializer.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/OpenAPIDeserializer.java @@ -194,6 +194,17 @@ public OpenAPI parseRoot(JsonNode node, ParseResult result) { return openAPI; } + public String mungedRef(String refString) { + // Ref: IETF RFC 3966, Section 5.2.2 + if (!refString.contains(":") && // No scheme + !refString.startsWith("#") && // Path is not empty + !refString.startsWith("/") && // Path is not absolute + refString.indexOf(".") > 0) { // Path does not start with dot but contains "." (file extension) + return "./" + refString; + } + return null; + } + public Map getExtensions(ObjectNode node){ Map extensions = new LinkedHashMap<>(); @@ -490,8 +501,13 @@ public PathItem getPathItem(ObjectNode obj, String location, ParseResult result) JsonNode ref = obj.get("$ref"); if (ref.getNodeType().equals(JsonNodeType.STRING)) { - pathItem.set$ref(ref.asText()); - return pathItem.$ref((ref.asText())); + String mungedRef = mungedRef(ref.textValue()); + if (mungedRef != null) { + pathItem.set$ref(mungedRef); + }else{ + pathItem.set$ref(ref.textValue()); + } + return pathItem; } else if (ref.getNodeType().equals(JsonNodeType.OBJECT)) { ObjectNode node = (ObjectNode) ref; diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/PathUtils.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/PathUtils.java index 5eb3f582b8..72ac186b19 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/PathUtils.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/PathUtils.java @@ -1,21 +1,36 @@ package io.swagger.v3.parser.util; import java.net.URI; +import java.net.URL; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; public class PathUtils { - public static Path getParentDirectoryOfFile(String fileStr) { - final String fileScheme = "file:"; - Path file; - fileStr = fileStr.replaceAll("\\\\","/"); - if (fileStr.toLowerCase().startsWith(fileScheme)) { - file = Paths.get(URI.create(fileStr)).toAbsolutePath(); - } else { - file = Paths.get(fileStr).toAbsolutePath(); + public static Path getParentDirectoryOfFile(String location) { + Path file = null; + try { + location = location.replaceAll("\\\\","/"); + final String fileScheme = "file:"; + if (location.toLowerCase().startsWith(fileScheme)) { + file = Paths.get(URI.create(location)).toAbsolutePath(); + } else { + file = Paths.get(location).toAbsolutePath(); + } + if (!Files.exists(file)) { + URL url = PathUtils.class.getClassLoader().getResource(location); + file = Paths.get((URI.create(url.toExternalForm()))); + return file.getParent(); + } + + + + } catch (Exception e) { + e.getMessage(); } + return file.toAbsolutePath().getParent(); } } \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/RefUtils.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/RefUtils.java index 7b628153a6..d72d09da05 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/RefUtils.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/RefUtils.java @@ -49,7 +49,7 @@ public static boolean isAnExternalRefFormat(RefFormat refFormat) { public static RefFormat computeRefFormat(String ref) { RefFormat result = RefFormat.INTERNAL; - if(ref.startsWith("http")) { + if(ref.startsWith("http")||ref.startsWith("https")) { result = RefFormat.URL; } else if(ref.startsWith("#/")) { result = RefFormat.INTERNAL; @@ -136,13 +136,11 @@ public static String readExternalRef(String file, RefFormat refFormat, List Date: Mon, 4 Jun 2018 06:29:37 -0500 Subject: [PATCH 2/5] fixing relative ref after deserializing issue #727 --- .../swagger/v3/parser/util/OpenAPIDeserializer.java | 9 +++++++-- .../java/io/swagger/v3/parser/util/RefUtils.java | 13 +++++++++++++ .../models/purebred_pet.json | 6 +++--- .../allOf-properties-ext-ref/models/swagger.json | 2 +- .../resources/allOf-properties-ext-ref/swagger.json | 2 +- .../resources/relative-upper-directory/swagger.yaml | 2 +- 6 files changed, 26 insertions(+), 8 deletions(-) diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/OpenAPIDeserializer.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/OpenAPIDeserializer.java index 976fd1c48c..837221a979 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/OpenAPIDeserializer.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/OpenAPIDeserializer.java @@ -1867,8 +1867,13 @@ public Schema getSchema(ObjectNode node, String location, ParseResult result){ JsonNode ref = node.get("$ref"); if (ref != null) { if (ref.getNodeType().equals(JsonNodeType.STRING)) { - schema.set$ref(ref.asText()); - return schema.$ref(ref.asText()); + String mungedRef = mungedRef(ref.textValue()); + if (mungedRef != null) { + schema.set$ref(mungedRef); + }else{ + schema.set$ref(ref.asText()); + } + return schema; } else { result.invalidType(location, "$ref", "string", node); return null; diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/RefUtils.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/RefUtils.java index d72d09da05..bae801d075 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/RefUtils.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/RefUtils.java @@ -49,6 +49,7 @@ public static boolean isAnExternalRefFormat(RefFormat refFormat) { public static RefFormat computeRefFormat(String ref) { RefFormat result = RefFormat.INTERNAL; + ref = mungedRef(ref); if(ref.startsWith("http")||ref.startsWith("https")) { result = RefFormat.URL; } else if(ref.startsWith("#/")) { @@ -60,6 +61,18 @@ public static RefFormat computeRefFormat(String ref) { return result; } + public static String mungedRef(String refString) { + // Ref: IETF RFC 3966, Section 5.2.2 + if (!refString.contains(":") && // No scheme + !refString.startsWith("#") && // Path is not empty + !refString.startsWith("/") && // Path is not absolute + !refString.contains("$") && + refString.indexOf(".") > 0) { // Path does not start with dot but contains "." (file extension) + return "./" + refString; + } + return refString; + } + public static String readExternalUrlRef(String file, RefFormat refFormat, List auths, String rootPath) { diff --git a/modules/swagger-parser-v3/src/test/resources/allOf-properties-ext-ref/models/purebred_pet.json b/modules/swagger-parser-v3/src/test/resources/allOf-properties-ext-ref/models/purebred_pet.json index c1f9b469b0..d85c4e569e 100644 --- a/modules/swagger-parser-v3/src/test/resources/allOf-properties-ext-ref/models/purebred_pet.json +++ b/modules/swagger-parser-v3/src/test/resources/allOf-properties-ext-ref/models/purebred_pet.json @@ -1,7 +1,7 @@ { "allOf": [ { - "$ref": "./pet.json" + "$ref": "pet.json" }, { "type": "object", @@ -11,12 +11,12 @@ "sample": "Labrador" }, "mother": { - "$ref": "./pet.json" + "$ref": "pet.json" }, "siblings": { "type": "array", "items": { - "$ref": "./pet.json" + "$ref": "pet.json" } } } diff --git a/modules/swagger-parser-v3/src/test/resources/allOf-properties-ext-ref/models/swagger.json b/modules/swagger-parser-v3/src/test/resources/allOf-properties-ext-ref/models/swagger.json index d5c2210829..dfbbdc6169 100644 --- a/modules/swagger-parser-v3/src/test/resources/allOf-properties-ext-ref/models/swagger.json +++ b/modules/swagger-parser-v3/src/test/resources/allOf-properties-ext-ref/models/swagger.json @@ -7,7 +7,7 @@ "components": { "schemas": { "record": { - "$ref": "./purebred_pet.json" + "$ref": "purebred_pet.json" } } } diff --git a/modules/swagger-parser-v3/src/test/resources/allOf-properties-ext-ref/swagger.json b/modules/swagger-parser-v3/src/test/resources/allOf-properties-ext-ref/swagger.json index a5bc7e96ba..295e41d30f 100644 --- a/modules/swagger-parser-v3/src/test/resources/allOf-properties-ext-ref/swagger.json +++ b/modules/swagger-parser-v3/src/test/resources/allOf-properties-ext-ref/swagger.json @@ -7,7 +7,7 @@ "components": { "schemas": { "record": { - "$ref": "./models/purebred_pet.json" + "$ref": "models/purebred_pet.json" } } } diff --git a/modules/swagger-parser-v3/src/test/resources/relative-upper-directory/swagger.yaml b/modules/swagger-parser-v3/src/test/resources/relative-upper-directory/swagger.yaml index 336c234b9c..91e0edbc09 100644 --- a/modules/swagger-parser-v3/src/test/resources/relative-upper-directory/swagger.yaml +++ b/modules/swagger-parser-v3/src/test/resources/relative-upper-directory/swagger.yaml @@ -8,4 +8,4 @@ info: description: Service for Swagger and JSON schema testing paths: /api/Address: - $ref: "./Paths/Address.yaml" \ No newline at end of file + $ref: "Paths/Address.yaml" \ No newline at end of file From fafb4b6ac2e6a5be17984189e6ebe3d85ae66e32 Mon Sep 17 00:00:00 2001 From: gracekarina Date: Tue, 5 Jun 2018 16:38:24 -0500 Subject: [PATCH 3/5] more validations where there is a - refs - issue #727 --- .../v3/parser/util/OpenAPIDeserializer.java | 72 +++++++++++++++---- 1 file changed, 57 insertions(+), 15 deletions(-) diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/OpenAPIDeserializer.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/OpenAPIDeserializer.java index 837221a979..953ee3fc7d 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/OpenAPIDeserializer.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/OpenAPIDeserializer.java @@ -980,8 +980,14 @@ public Link getLink(ObjectNode linkNode, String location, ParseResult result) { JsonNode ref = linkNode.get("$ref"); if (ref != null) { if (ref.getNodeType().equals(JsonNodeType.STRING)) { - link.set$ref(ref.asText()); - return link.$ref(ref.asText()); + String mungedRef = mungedRef(ref.textValue()); + if (mungedRef != null) { + link.set$ref(mungedRef); + }else{ + link.set$ref(ref.textValue()); + } + + return link; } else { result.invalidType(location, "$ref", "string", linkNode); return null; @@ -1076,7 +1082,13 @@ public Callback getCallback(ObjectNode node,String location, ParseResult result) if (ref != null) { if (ref.getNodeType().equals(JsonNodeType.STRING)) { PathItem pathItem = new PathItem(); - return callback.addPathItem(name,pathItem.$ref(ref.asText())); + String mungedRef = mungedRef(ref.textValue()); + if (mungedRef != null) { + pathItem.set$ref(mungedRef); + }else{ + pathItem.set$ref(ref.textValue()); + } + return callback.addPathItem(name,pathItem); } else { result.invalidType(location, "$ref", "string", node); return null; @@ -1270,8 +1282,13 @@ public Parameter getParameter(ObjectNode obj, String location, ParseResult resul if (ref != null) { if (ref.getNodeType().equals(JsonNodeType.STRING)) { parameter = new Parameter(); - parameter.set$ref(ref.asText()); - return parameter.$ref(ref.asText()); + String mungedRef = mungedRef(ref.textValue()); + if (mungedRef != null) { + parameter.set$ref(mungedRef); + }else{ + parameter.set$ref(ref.textValue()); + } + return parameter; } else { result.invalidType(location, "$ref", "string", obj); return null; @@ -1426,8 +1443,13 @@ public Header getHeader(ObjectNode headerNode, String location, ParseResult resu JsonNode ref = headerNode.get("$ref"); if (ref != null) { if (ref.getNodeType().equals(JsonNodeType.STRING)) { - header.set$ref(ref.asText()); - return header.$ref(ref.asText()); + String mungedRef = mungedRef(ref.textValue()); + if (mungedRef != null) { + header.set$ref(mungedRef); + }else{ + header.set$ref(ref.textValue()); + } + return header; } else { result.invalidType(location, "$ref", "string", headerNode); return null; @@ -1561,8 +1583,13 @@ public SecurityScheme getSecurityScheme(ObjectNode node, String location, ParseR JsonNode ref = node.get("$ref"); if (ref != null) { if (ref.getNodeType().equals(JsonNodeType.STRING)) { - securityScheme.set$ref(ref.asText()); - return securityScheme.$ref(ref.asText()); + String mungedRef = mungedRef(ref.textValue()); + if (mungedRef != null) { + securityScheme.set$ref(mungedRef); + }else{ + securityScheme.set$ref(ref.textValue()); + } + return securityScheme; } else { result.invalidType(location, "$ref", "string", node); return null; @@ -2172,8 +2199,13 @@ public Example getExample(ObjectNode node, String location, ParseResult result) JsonNode ref = node.get("$ref"); if (ref != null) { if (ref.getNodeType().equals(JsonNodeType.STRING)) { - example.set$ref(ref.asText()); - return example.$ref((ref.asText())); + String mungedRef = mungedRef(ref.textValue()); + if (mungedRef != null) { + example.set$ref(mungedRef); + }else{ + example.set$ref(ref.textValue()); + } + return example; } else { result.invalidType(location, "$ref", "string", node); return null; @@ -2276,8 +2308,13 @@ public ApiResponse getResponse(ObjectNode node, String location, ParseResult res JsonNode ref = node.get("$ref"); if (ref != null) { if (ref.getNodeType().equals(JsonNodeType.STRING)) { - apiResponse.set$ref(ref.asText()); - return apiResponse.$ref((ref.asText())); + String mungedRef = mungedRef(ref.textValue()); + if (mungedRef != null) { + apiResponse.set$ref(mungedRef); + }else{ + apiResponse.set$ref(ref.textValue()); + } + return apiResponse; } else { result.invalidType(location, "$ref", "string", node); return null; @@ -2501,8 +2538,13 @@ protected RequestBody getRequestBody(ObjectNode node, String location, ParseResu JsonNode ref = node.get("$ref"); if (ref != null) { if (ref.getNodeType().equals(JsonNodeType.STRING)) { - body.set$ref(ref.asText()); - return body.$ref(ref.asText()); + String mungedRef = mungedRef(ref.textValue()); + if (mungedRef != null) { + body.set$ref(mungedRef); + }else{ + body.set$ref(ref.textValue()); + } + return body; } else { result.invalidType(location, "$ref", "string", node); return null; From 4a8e21846720edce0b7246ebc08182669998e242 Mon Sep 17 00:00:00 2001 From: Ben Mordue Date: Fri, 6 Jul 2018 14:39:33 +0100 Subject: [PATCH 4/5] Do not read info block if it does not exist --- .../java/io/swagger/v3/parser/converter/SwaggerConverter.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/swagger-parser-v2-converter/src/main/java/io/swagger/v3/parser/converter/SwaggerConverter.java b/modules/swagger-parser-v2-converter/src/main/java/io/swagger/v3/parser/converter/SwaggerConverter.java index b4250e446c..1b6d490b7d 100644 --- a/modules/swagger-parser-v2-converter/src/main/java/io/swagger/v3/parser/converter/SwaggerConverter.java +++ b/modules/swagger-parser-v2-converter/src/main/java/io/swagger/v3/parser/converter/SwaggerConverter.java @@ -141,7 +141,9 @@ public SwaggerParseResult convert(SwaggerDeserializationResult parse) { openAPI.setExternalDocs(convert(swagger.getExternalDocs())); } - openAPI.setInfo(convert(swagger.getInfo())); + if (swagger.getInfo() != null) { + openAPI.setInfo(convert(swagger.getInfo())); + } openAPI.setServers(convert(swagger.getSchemes(), swagger.getHost(), swagger.getBasePath())); From 9d0094a99c2a4a11e9fb4b6d8c40872e03fe36cc Mon Sep 17 00:00:00 2001 From: Jeremie Bresson Date: Fri, 6 Jul 2018 16:38:56 +0200 Subject: [PATCH 5/5] Add a test case for issue #755 --- .../io/swagger/parser/test/V2ConverterTest.java | 7 +++++++ .../src/test/resources/issue-755.yaml | 14 ++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 modules/swagger-parser-v2-converter/src/test/resources/issue-755.yaml diff --git a/modules/swagger-parser-v2-converter/src/test/java/io/swagger/parser/test/V2ConverterTest.java b/modules/swagger-parser-v2-converter/src/test/java/io/swagger/parser/test/V2ConverterTest.java index 4d56529095..4e2c95343a 100644 --- a/modules/swagger-parser-v2-converter/src/test/java/io/swagger/parser/test/V2ConverterTest.java +++ b/modules/swagger-parser-v2-converter/src/test/java/io/swagger/parser/test/V2ConverterTest.java @@ -77,6 +77,7 @@ public class V2ConverterTest { private static final String ISSUE_673_YAML = "issue-673.yaml"; private static final String ISSUE_676_JSON = "issue-676.json"; private static final String ISSUE_708_YAML = "issue-708.yaml"; + private static final String ISSUE_755_YAML = "issue-755.yaml"; private static final String API_BATCH_PATH = "/api/batch/"; private static final String PETS_PATH = "/pets"; @@ -650,6 +651,12 @@ public void testSwaggerParseResultHasMessage() throws Exception { assertNotNull(result.getMessages()); } + @Test(description = "OpenAPI v2 converter - Conversion of a spec without a info section") + public void testIssue755() throws Exception { + final OpenAPI oas = getConvertedOpenAPIFromJsonFile(ISSUE_755_YAML); + assertNotNull(oas); + } + private OpenAPI getConvertedOpenAPIFromJsonFile(String file) throws IOException, URISyntaxException { SwaggerConverter converter = new SwaggerConverter(); String swaggerAsString = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource(file).toURI()))); diff --git a/modules/swagger-parser-v2-converter/src/test/resources/issue-755.yaml b/modules/swagger-parser-v2-converter/src/test/resources/issue-755.yaml new file mode 100644 index 0000000000..083ba6ee8e --- /dev/null +++ b/modules/swagger-parser-v2-converter/src/test/resources/issue-755.yaml @@ -0,0 +1,14 @@ +swagger: '2.0' +host: petstore.swagger.io +basePath: /v2 +schemes: + - http +paths: + /ping: + post: + summary: test + description: 'test it' + operationId: pingOp + responses: + '200': + description: OK \ No newline at end of file