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 5e312ec274..26c0b5b4f8 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 @@ -143,7 +143,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())); 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 99381a728b..f6cfc58f4b 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 @@ -79,6 +79,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 ISSUE_740_YAML = "issue-740.yaml"; private static final String ISSUE_756_JSON = "issue-756.json"; private static final String ISSUE_758_JSON = "issue-758.json"; @@ -86,6 +87,7 @@ public class V2ConverterTest { private static final String ISSUE_765_YAML = "issue-765.yaml"; private static final String ISSUE_768_JSON = "issue-786.json"; + private static final String API_BATCH_PATH = "/api/batch/"; private static final String PETS_PATH = "/pets"; private static final String PET_FIND_BY_STATUS_PATH = "/pet/findByStatus"; @@ -704,12 +706,20 @@ public void testSwaggerParseResultHasMessage() throws Exception { assertNotNull(result.getMessages()); } + @Test(description = "OpenAPI v2 converter - Migrate minLength, maxLength and pattern of String property") public void testIssue786() throws Exception { final OpenAPI oas = getConvertedOpenAPIFromJsonFile(ISSUE_768_JSON); assertNotNull(oas); } + + @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 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 0e6c331299..a7dcca31f1 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 @@ -203,6 +203,17 @@ public OpenAPI parseRoot(JsonNode node, ParseResult result, String path) { 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<>(); @@ -531,8 +542,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; @@ -1005,8 +1021,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; @@ -1101,7 +1123,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; @@ -1295,8 +1323,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; @@ -1451,8 +1484,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; @@ -1586,8 +1624,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; @@ -1892,8 +1935,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; @@ -2192,8 +2240,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; @@ -2303,8 +2356,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; @@ -2528,8 +2586,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; 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 66380ceac8..9c0d8c317d 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,8 @@ public static boolean isAnExternalRefFormat(RefFormat refFormat) { public static RefFormat computeRefFormat(String ref) { RefFormat result = RefFormat.INTERNAL; - if(ref.startsWith("http")) { + ref = mungedRef(ref); + if(ref.startsWith("http")||ref.startsWith("https")) { result = RefFormat.URL; } else if(ref.startsWith("#/")) { result = RefFormat.INTERNAL; @@ -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) { @@ -136,13 +149,11 @@ public static String readExternalRef(String file, RefFormat refFormat, List