Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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()));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,15 @@ 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";
private static final String ISSUE_762_JSON = "issue-762.json";
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";
Expand Down Expand Up @@ -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())));
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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<String,Object> getExtensions(ObjectNode node){

Map<String,Object> extensions = new LinkedHashMap<>();
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<AuthorizationValue> auths,
String rootPath) {
Expand Down Expand Up @@ -136,27 +149,38 @@ public static String readExternalRef(String file, RefFormat refFormat, List<Auth
throw new RuntimeException("Ref is not external");
}

String result;
String result = null;

try {
if (refFormat == RefFormat.URL) {

result = RemoteUrl.urlToString(file, auths);

} else {
//its assumed to be a relative file ref
final Path pathToUse = parentDirectory.resolve(file).normalize();
Copy link
Contributor

@JehandadK JehandadK Aug 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this parentDirectory be the directory of where the file containing $ref exists or the directory of the main file which is read first by the Parser?

I am asking this because this seems to be the behavior of swagger-ui. And to make my swagger spec work with both I had to use links.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is the directory where the file is


if(Files.exists(pathToUse)) {
result = IOUtils.toString(new FileInputStream(pathToUse.toFile()), "UTF-8");
} else {
String url = file;
if(url.contains("..")) {
url = parentDirectory + url.substring(url.indexOf(".") + 2);
}else{
url = parentDirectory + url.substring(url.indexOf(".") + 1);
}
final Path pathToUse2 = parentDirectory.resolve(url).normalize();

if(Files.exists(pathToUse2)) {
result = IOUtils.toString(new FileInputStream(pathToUse2.toFile()), "UTF-8");
}
}
if (result == null){
result = ClasspathHelper.loadFileFromClasspath(file);
}


}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Unable to load " + refFormat + " ref: " + file, e);
throw new RuntimeException("Unable to load " + refFormat + " ref: " + file + " path: "+parentDirectory, e);
}

return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,25 @@ public void issue682() throws Exception {
OpenAPIV3Parser parser = new OpenAPIV3Parser();
ParseOptions options = new ParseOptions();
options.setResolve(true);
options.setResolveCombinators(false);
options.setResolveFully(true);

String location = getClass().getResource("/odin.yaml").toString();
Assert.assertNotNull(location);
final SwaggerParseResult result = parser.readLocation(location, null, options);
final SwaggerParseResult result = parser.readLocation("src/test/resources/sample/SwaggerPetstore.yaml", null, options);
Assert.assertNotNull(result.getOpenAPI());
Assert.assertTrue(result.getMessages().isEmpty());
Assert.assertTrue(result.getOpenAPI().getPaths().get("/JTasker/startRun").getPost().getRequestBody().getContent().get("application/json").getSchema().getProperties().size() == 2);
Assert.assertNotNull(result.getOpenAPI().getPaths().get("/pets").getGet());
}

@Test
public void issueRelativeRefs2() throws Exception {
OpenAPIV3Parser parser = new OpenAPIV3Parser();
ParseOptions options = new ParseOptions();
options.setResolve(true);

final SwaggerParseResult result = parser.readLocation("src/test/resources/relative-upper-directory/swagger.yaml", null, options);
Assert.assertNotNull(result.getOpenAPI());
OpenAPI openAPI = result.getOpenAPI();
assertNotNull(openAPI.getPaths().get("/api/Address").getGet());
assertTrue(openAPI.getComponents().getSchemas().size() == 1);
assertNotNull(openAPI.getComponents().getSchemas().get("AddressEx"));
}

@Test
Expand Down
Loading