diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/reference/DereferencerContext.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/reference/DereferencerContext.java index bcb5eb1073..46019780cf 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/reference/DereferencerContext.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/reference/DereferencerContext.java @@ -20,6 +20,7 @@ public class DereferencerContext { protected SwaggerParseResult swaggerParseResult; protected boolean addParametersToEachOperation = true; protected String currentUri; + protected Map idsCache = new LinkedHashMap<>(); private Map referenceSet = new LinkedHashMap<>(); @@ -115,6 +116,19 @@ public DereferencerContext referenceSet(Map referenceSet) { return this; } + public Map getIdsCache() { + return idsCache; + } + + public void setIdsCache(Map idsCache) { + this.idsCache = idsCache; + } + + public DereferencerContext idsCache(Map idsCache) { + this.idsCache = idsCache; + return this; + } + public DereferencerContext rootUri(String rootUri) { this.rootUri = rootUri; return this; diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/reference/IdsTraverser.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/reference/IdsTraverser.java new file mode 100644 index 0000000000..3b1e2a4797 --- /dev/null +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/reference/IdsTraverser.java @@ -0,0 +1,675 @@ +package io.swagger.v3.parser.reference; + +import com.fasterxml.jackson.core.JsonProcessingException; +import io.swagger.v3.core.util.Json31; +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.Operation; +import io.swagger.v3.oas.models.PathItem; +import io.swagger.v3.oas.models.Paths; +import io.swagger.v3.oas.models.callbacks.Callback; +import io.swagger.v3.oas.models.examples.Example; +import io.swagger.v3.oas.models.headers.Header; +import io.swagger.v3.oas.models.links.Link; +import io.swagger.v3.oas.models.media.Encoding; +import io.swagger.v3.oas.models.media.MediaType; +import io.swagger.v3.oas.models.media.Schema; +import io.swagger.v3.oas.models.parameters.Parameter; +import io.swagger.v3.oas.models.parameters.RequestBody; +import io.swagger.v3.oas.models.responses.ApiResponse; +import io.swagger.v3.oas.models.responses.ApiResponses; +import io.swagger.v3.oas.models.security.SecurityScheme; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.BiFunction; + +public class IdsTraverser implements Traverser { + + private DereferencerContext context; + + public IdsTraverser(DereferencerContext context) { + this.context = context; + } + + public DereferencerContext getContext() { + return context; + } + + public void setContext(DereferencerContext context) { + this.context = context; + } + + public IdsTraverser context(DereferencerContext context) { + this.context = context; + return this; + } + + public Set visiting = new HashSet<>(); + protected HashMap visitedMap = new HashMap<>(); + + public OpenAPI traverse(OpenAPI openAPI, Visitor visitor) throws Exception { + return traverseOpenApi(openAPI, visitor); + } + + public OpenAPI traverseOpenApi(OpenAPI openAPI, Visitor visitor) { + if (openAPI == null) { + return null; + } + if (visiting.contains(openAPI)) { + return openAPI; + } + if (visitedMap.containsKey(openAPI)) { + return (OpenAPI)visitedMap.get(openAPI); + } + visiting.add(openAPI); + + OpenAPI resolved = openAPI; + + Paths paths = traversePaths(resolved.getPaths(), visitor); + if (paths != null) { + resolved.paths(paths); + } + Components components = traverseComponents(resolved.getComponents(), visitor); + if (components != null) { + resolved.components(components); + } + + traverseMap(resolved.getWebhooks(), visitor, this::traversePathItem); + + visitedMap.put(openAPI, resolved); + visiting.remove(openAPI); + return resolved; + } + + public Components traverseComponents(Components components, Visitor visitor) { + if (components == null) { + return null; + } + if (visiting.contains(components)) { + return components; + } + + if (visitedMap.containsKey(components)) { + return (Components)visitedMap.get(components); + } + visiting.add(components); + Components resolved = components; + traverseMap(resolved.getPathItems(), visitor, this::traversePathItem); + traverseMap(resolved.getParameters(), visitor, this::traverseParameter); + traverseMap(resolved.getCallbacks(), visitor, this::traverseCallback); + traverseMap(resolved.getRequestBodies(), visitor, this::traverseRequestBody); + traverseMap(resolved.getSecuritySchemes(), visitor, this::traverseSecurityScheme); + traverseSchemaMap(resolved.getSchemas(), visitor, new ArrayList<>()); + traverseMap(resolved.getHeaders(), visitor, this::traverseHeader); + traverseMap(resolved.getLinks(), visitor, this::traverseLink); + traverseMap(resolved.getResponses(), visitor, this::traverseResponse); + + traverseMap(resolved.getExamples(), visitor, this::traverseExample); + visitedMap.put(components, resolved); + visiting.remove(components); + return resolved; + } + + public Paths traversePaths(Paths paths, Visitor visitor) { + if (paths == null) { + return null; + } + if (visiting.contains(paths)) { + return paths; + } + + if (visitedMap.containsKey(paths)) { + return (Paths)visitedMap.get(paths); + } + visiting.add(paths); + Paths resolved = paths; + traverseMap(resolved, visitor, this::traversePathItem); + visitedMap.put(paths, resolved); + visiting.remove(paths); + return resolved; + } + + public Operation traverseOperation(Operation operation, Visitor visitor) { + if (operation == null) { + return null; + } + if (visiting.contains(operation)) { + return operation; + } + + if (visitedMap.containsKey(operation)) { + return (Operation)visitedMap.get(operation); + } + visiting.add(operation); + Operation resolved = operation; + + if (resolved.getParameters() != null) { + for (int i = 0; i < resolved.getParameters().size(); i++) { + Parameter resolvedParameter = traverseParameter(resolved.getParameters().get(i), visitor); + if (resolvedParameter != null) { + resolved.getParameters().set(i, resolvedParameter); + } + } + } + if (resolved.getRequestBody() != null) { + RequestBody resolvedRequestBody = traverseRequestBody(resolved.getRequestBody(), visitor); + if (resolvedRequestBody != null) { + resolved.setRequestBody(resolvedRequestBody); + } + + } + + if (resolved.getResponses() != null) { + ApiResponses resolvedResponses = traverseResponses(resolved.getResponses(), visitor); + if (resolvedResponses != null) { + resolved.setResponses(resolvedResponses); + } + } + + traverseMap(resolved.getCallbacks(), visitor, this::traverseCallback); + + visitedMap.put(operation, resolved); + visiting.remove(operation); + return resolved; + } + + public ApiResponses traverseResponses(ApiResponses responses, Visitor visitor) { + if (responses == null) { + return null; + } + if (visiting.contains(responses)) { + return responses; + } + + if (visitedMap.containsKey(responses)) { + return (ApiResponses)visitedMap.get(responses); + } + visiting.add(responses); + ApiResponses resolved = responses; + traverseMap(resolved, visitor, this::traverseResponse); + visitedMap.put(responses, resolved); + visiting.remove(responses); + return resolved; + } + + + public ApiResponse traverseResponse(ApiResponse response, Visitor visitor) { + if (response == null) { + return null; + } + if (visiting.contains(response)) { + return response; + } + + if (visitedMap.containsKey(response)) { + return (ApiResponse)visitedMap.get(response); + } + visiting.add(response); + ApiResponse resolved = response; + + traverseMap(resolved.getContent(), visitor, this::traverseMediaType); + + traverseMap(resolved.getHeaders(), visitor, this::traverseHeader); + + traverseMap(resolved.getLinks(), visitor, this::traverseLink); + + // TODO ignored as no dereference for servers atm + // resolved.getServers() + + visitedMap.put(response, deepcopy(resolved, ApiResponse.class)); + visiting.remove(response); + return resolved; + } + + public RequestBody traverseRequestBody(RequestBody requestBody, Visitor visitor) { + if (requestBody == null) { + return null; + } + if (visiting.contains(requestBody)) { + return requestBody; + } + + if (visitedMap.containsKey(requestBody)) { + return (RequestBody)visitedMap.get(requestBody); + } + visiting.add(requestBody); + RequestBody resolved = requestBody; + + traverseMap(resolved.getContent(), visitor, this::traverseMediaType); + + visitedMap.put(requestBody, deepcopy(resolved, RequestBody.class)); + visiting.remove(requestBody); + return resolved; + } + + /* + * + * constructs accepting $ref + * + */ + + public PathItem traversePathItem(PathItem pathItem, Visitor visitor) { + if (pathItem == null) { + return null; + } + if (visiting.contains(pathItem)) { + return pathItem; + } + + if (visitedMap.containsKey(pathItem)) { + return (PathItem) visitedMap.get(pathItem); + } + visiting.add(pathItem); + PathItem resolved = pathItem; + Operation getOp = resolved.getGet(); + Operation resolvedOperation = traverseOperation(getOp, visitor); + if (resolvedOperation != null) { + resolved.setGet(resolvedOperation); + } + Operation putOp = resolved.getPut(); + resolvedOperation = traverseOperation(putOp, visitor); + if (resolvedOperation != null) { + resolved.setPut(resolvedOperation); + } + Operation deleteOp = resolved.getDelete(); + resolvedOperation = traverseOperation(deleteOp, visitor); + if (resolvedOperation != null) { + resolved.setDelete(resolvedOperation); + } + Operation patchOp = resolved.getPatch(); + resolvedOperation = traverseOperation(patchOp, visitor); + if (resolvedOperation != null) { + resolved.setPatch(resolvedOperation); + } + Operation optionsOp = resolved.getOptions(); + resolvedOperation = traverseOperation(optionsOp, visitor); + if (resolvedOperation != null) { + resolved.setOptions(resolvedOperation); + } + Operation headOp = resolved.getHead(); + resolvedOperation = traverseOperation(headOp, visitor); + if (resolvedOperation != null) { + resolved.setHead(resolvedOperation); + } + Operation postOp = resolved.getPost(); + resolvedOperation = traverseOperation(postOp, visitor); + if (resolvedOperation != null) { + resolved.setPost(resolvedOperation); + } + Operation traceOp = resolved.getTrace(); + resolvedOperation = traverseOperation(traceOp, visitor); + if (resolvedOperation != null) { + resolved.setTrace(resolvedOperation); + } + + if (resolved.getParameters() != null) { + for (int i = 0; i < resolved.getParameters().size(); i++) { + Parameter resolvedParameter = traverseParameter(resolved.getParameters().get(i), visitor); + if (resolvedParameter != null) { + resolved.getParameters().set(i, resolvedParameter); + } + } + } + + visitedMap.put(pathItem, deepcopy(resolved, PathItem.class)); + visiting.remove(pathItem); + return resolved; + } + + public Parameter traverseParameter(Parameter parameter, Visitor visitor) { + if (parameter == null) { + return null; + } + if (visiting.contains(parameter)) { + return parameter; + } + + if (visitedMap.containsKey(parameter)) { + return (Parameter)visitedMap.get(parameter); + } + visiting.add(parameter); + Parameter resolved = parameter; + + traverseMap(resolved.getContent(), visitor, this::traverseMediaType); + if (resolved.getSchema() != null) { + Schema schema = traverseSchema(resolved.getSchema(), visitor, new ArrayList<>()); + if (schema != null) { + resolved.setSchema(schema); + } + } + + traverseMap(resolved.getExamples(), visitor, this::traverseExample); + + visitedMap.put(parameter, deepcopy(resolved, Parameter.class)); + visiting.remove(parameter); + return resolved; + + } + + public Example traverseExample(Example example, Visitor visitor) { + if (example == null) { + return null; + } + if (visiting.contains(example)) { + return example; + } + + if (visitedMap.containsKey(example)) { + return (Example)visitedMap.get(example); + } + visiting.add(example); + Example resolved = example; + + visitedMap.put(example, deepcopy(resolved, Example.class)); + visiting.remove(example); + return resolved; + + } + + public Callback traverseCallback(Callback callback, Visitor visitor) { + + if (callback == null) { + return null; + } + if (visiting.contains(callback)) { + return callback; + } + + if (visitedMap.containsKey(callback)) { + return (Callback)visitedMap.get(callback); + } + visiting.add(callback); + traverseMap(callback, visitor, this::traversePathItem); + visitedMap.put(callback, callback); + visiting.remove(callback); + return callback; + } + + public MediaType traverseMediaType(MediaType mediaType, Visitor visitor) { + if (mediaType == null) { + return null; + } + if (visiting.contains(mediaType)) { + return mediaType; + } + + if (visitedMap.containsKey(mediaType)) { + return (MediaType)visitedMap.get(mediaType); + } + visiting.add(mediaType); + MediaType resolved = mediaType; + + if (resolved.getSchema() != null) { + traverseSchema(resolved.getSchema(), visitor, new ArrayList<>()); + } + traverseMap(resolved.getEncoding(), visitor, this::traverseEncoding); + traverseMap(resolved.getExamples(), visitor, this::traverseExample); + visitedMap.put(mediaType, resolved); + visiting.remove(mediaType); + return resolved; + } + + public Encoding traverseEncoding(Encoding encoding, Visitor visitor) { + if (encoding == null) { + return null; + } + if (visiting.contains(encoding)) { + return encoding; + } + + if (visitedMap.containsKey(encoding)) { + return (Encoding)visitedMap.get(encoding); + } + visiting.add(encoding); + Encoding resolved = encoding; + + traverseMap(resolved.getHeaders(), visitor, this::traverseHeader); + visitedMap.put(encoding, resolved); + visiting.remove(encoding); + return resolved; + + } + + public Header traverseHeader(Header header, Visitor visitor) { + if (header == null) { + return null; + } + if (visiting.contains(header)) { + return header; + } + + if (visitedMap.containsKey(header)) { + return (Header)visitedMap.get(header); + } + visiting.add(header); + Header resolved = header; + + traverseMap(resolved.getContent(), visitor, this::traverseMediaType); + if (resolved.getSchema() != null) { + traverseSchema(resolved.getSchema(), visitor, new ArrayList<>()); + } + + visitedMap.put(header, deepcopy(resolved, Header.class)); + visiting.remove(header); + return resolved; + } + + public SecurityScheme traverseSecurityScheme(SecurityScheme securityScheme, Visitor visitor) { + if (securityScheme == null) { + return null; + } + if (visiting.contains(securityScheme)) { + return securityScheme; + } + + if (visitedMap.containsKey(securityScheme)) { + return (SecurityScheme)visitedMap.get(securityScheme); + } + visiting.add(securityScheme); + SecurityScheme resolved = securityScheme; + visitedMap.put(securityScheme, deepcopy(resolved, SecurityScheme.class)); + visiting.remove(securityScheme); + return resolved; + } + + public Link traverseLink(Link link, Visitor visitor) { + if (link == null) { + return null; + } + if (visiting.contains(link)) { + return link; + } + + if (visitedMap.containsKey(link)) { + return (Link)visitedMap.get(link); + } + visiting.add(link); + Link resolved = link; + + traverseMap(resolved.getHeaders(), visitor, this::traverseHeader); + visitedMap.put(link, deepcopy(resolved, Link.class)); + visiting.remove(link); + return resolved; + } + + public Schema traverseSchema(Schema schema, Visitor visitor, List inheritedIds) { + if (schema == null) { + return null; + } + if (visiting.contains(schema)) { + return schema; + } + if (visitedMap.containsKey(schema)) { + return (Schema)visitedMap.get(schema); + } + visiting.add(schema); + + if (StringUtils.isNotBlank(schema.get$id())) { + inheritedIds.add(schema.get$id()); + try { + String resolvedURI = context.currentUri; + for (String id : inheritedIds) { + String urlWithoutHash = ReferenceUtils.toBaseURI(id); + resolvedURI = ReferenceUtils.resolve(urlWithoutHash, resolvedURI); + resolvedURI = ReferenceUtils.toBaseURI(resolvedURI); + } + context.getIdsCache().put(resolvedURI, Json31.pretty(schema)); + } catch (Exception e) { + // + } + } + Schema resolved = schema; + + traverseSchemaMap(resolved.getProperties(), visitor, inheritedIds); + + if (resolved.getAdditionalItems() != null) { + Schema traversedSchema = traverseSchema(resolved.getAdditionalItems(), visitor, inheritedIds); + if (traversedSchema != null) { + resolved.setAdditionalItems(traversedSchema); + } + } + if (resolved.getAdditionalProperties() != null && resolved.getAdditionalProperties() instanceof Schema) { + Schema traversedSchema = traverseSchema((Schema)resolved.getAdditionalProperties(), visitor, inheritedIds); + if (traversedSchema != null) { + resolved.setAdditionalProperties(traversedSchema); + } + } + if (resolved.getAllOf() != null) { + for (int i = 0; i < resolved.getAllOf().size(); i++) { + Schema resolvedSchema = traverseSchema((Schema)resolved.getAllOf().get(i), visitor, inheritedIds); + if (resolvedSchema != null) { + resolved.getAllOf().set(i, resolvedSchema); + } + } + } + if (resolved.getAnyOf() != null) { + for (int i = 0; i < resolved.getAnyOf().size(); i++) { + Schema resolvedSchema = traverseSchema((Schema)resolved.getAnyOf().get(i), visitor, inheritedIds); + if (resolvedSchema != null) { + resolved.getAnyOf().set(i, resolvedSchema); + } + } + } + if (resolved.getContains() != null) { + Schema traversedSchema = traverseSchema(resolved.getContains(), visitor, inheritedIds); + if (traversedSchema != null) { + resolved.setContains(traversedSchema); + } + } + if (resolved.getContentSchema() != null) { + Schema traversedSchema = traverseSchema(resolved.getContentSchema(), visitor, inheritedIds); + if (traversedSchema != null) { + resolved.setContentSchema(traversedSchema); + } + } + traverseSchemaMap(resolved.getDependentSchemas(), visitor, inheritedIds); + if (resolved.getElse() != null) { + Schema traversedSchema = traverseSchema(resolved.getElse(), visitor, inheritedIds); + if (traversedSchema != null) { + resolved.setElse(traversedSchema); + } + } + if (resolved.getIf() != null) { + Schema traversedSchema = traverseSchema(resolved.getIf(), visitor, inheritedIds); + if (traversedSchema != null) { + resolved.setIf(traversedSchema); + } + } + if (resolved.getItems() != null) { + Schema traversedSchema = traverseSchema(resolved.getItems(), visitor, inheritedIds); + if (traversedSchema != null) { + resolved.setItems(traversedSchema); + } + } + if (resolved.getNot() != null) { + Schema traversedSchema = traverseSchema(resolved.getNot(), visitor, inheritedIds); + if (traversedSchema != null) { + resolved.setNot(traversedSchema); + } + } + if (resolved.getOneOf() != null) { + for (int i = 0; i < resolved.getOneOf().size(); i++) { + Schema resolvedSchema = traverseSchema((Schema)resolved.getOneOf().get(i), visitor, inheritedIds); + if (resolvedSchema != null) { + resolved.getOneOf().set(i, resolvedSchema); + } + } + } + traverseSchemaMap(resolved.getPatternProperties(), visitor, inheritedIds); + if (resolved.getPrefixItems() != null) { + for (int i = 0; i < resolved.getPrefixItems().size(); i++) { + Schema resolvedSchema = traverseSchema((Schema)resolved.getPrefixItems().get(i), visitor, inheritedIds); + if (resolvedSchema != null) { + resolved.getPrefixItems().set(i, resolvedSchema); + } + } + } + if (resolved.getThen() != null) { + Schema traversedSchema = traverseSchema(resolved.getThen(), visitor, inheritedIds); + if (traversedSchema != null) { + resolved.setThen(traversedSchema); + } + } + if (resolved.getUnevaluatedItems() != null) { + Schema traversedSchema = traverseSchema(resolved.getUnevaluatedItems(), visitor, inheritedIds); + if (traversedSchema != null) { + resolved.setUnevaluatedItems(traversedSchema); + } + } + if (resolved.getAdditionalProperties() != null && resolved.getUnevaluatedProperties() instanceof Schema) { + Schema traversedSchema = traverseSchema((Schema)resolved.getUnevaluatedProperties(), visitor, inheritedIds); + if (traversedSchema != null) { + resolved.setUnevaluatedProperties(traversedSchema); + } + } + + if (StringUtils.isNotBlank(schema.get$id())) { + inheritedIds.remove(schema.get$id()); + } + visitedMap.put(schema, deepcopy(resolved, Schema.class)); + visiting.remove(schema); + return resolved; + + } + + public T deepcopy(T entity, Class clazz) { + try { + return (T)Json31.mapper().readValue(Json31.mapper().writeValueAsString(entity), clazz); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + + public void traverseMap(Map map, Visitor visitor, BiFunction traverser) { + if (map != null) { + Map copy = new LinkedHashMap<>(map); + for (String key : copy.keySet()) { + T entity = copy.get(key); + T resolved = traverser.apply(entity, visitor); + if (resolved != null) { + map.put(key, resolved); + } + } + } + } + + public void traverseSchemaMap(Map map, Visitor visitor, List inheritedIds) { + if (map != null) { + Map copy = new LinkedHashMap<>(map); + for (String key : copy.keySet()) { + Schema entity = copy.get(key); + Schema resolved = traverseSchema(entity, visitor, inheritedIds); + if (resolved != null) { + map.put(key, resolved); + } + } + } + } +} diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/reference/OpenAPI31Traverser.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/reference/OpenAPI31Traverser.java index 7611687f87..ca61dac25b 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/reference/OpenAPI31Traverser.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/reference/OpenAPI31Traverser.java @@ -786,6 +786,17 @@ public Schema traverseSchema(Schema schema, ReferenceVisitor visitor, List auths) throws Exception { + // check if the URL is defined as $id in current document + if (context.getIdsCache().containsKey(absoluteUri)) { + return deserializeIntoTree(context.getIdsCache().get(absoluteUri)); + } else { + Traverser idsTraverser = new IdsTraverser(context); + idsTraverser.traverse(context.getOpenApi(), null); + if (context.getIdsCache().containsKey(absoluteUri)) { + return deserializeIntoTree(context.getIdsCache().get(absoluteUri)); + } + } + return deserializeIntoTree(readURI(absoluteUri, auths)); } diff --git a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV31ParserSchemaTest.java b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV31ParserSchemaTest.java index 0768c1aaf2..0a01edcdf9 100644 --- a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV31ParserSchemaTest.java +++ b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV31ParserSchemaTest.java @@ -8,6 +8,9 @@ import com.github.tomakehurst.wiremock.client.WireMock; import com.github.tomakehurst.wiremock.core.WireMockConfiguration; import io.swagger.v3.core.util.Json31; +import io.swagger.v3.core.util.Yaml31; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.parser.OpenAPIV3Parser; import io.swagger.v3.parser.core.models.ParseOptions; import io.swagger.v3.parser.core.models.SwaggerParseResult; @@ -20,13 +23,12 @@ import java.io.IOException; import java.net.HttpURLConnection; import java.nio.charset.StandardCharsets; +import java.util.Map; import java.util.Random; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.get; import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching; -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertTrue; public class OpenAPIV31ParserSchemaTest { protected int serverPort = getDynamicPort(); @@ -218,6 +220,31 @@ public void testAnchorUnresolve() throws Exception { compare("$anchor-not-found", swaggerParseResult); } + @Test (enabled = false) + public void testa() throws Exception { + ParseOptions parseOptions = new ParseOptions(); + parseOptions.setResolve(true); + //parseOptions.setResolveFully(true); + // + SwaggerParseResult result = new OpenAPIV3Parser().readLocation("http://localhost:8002/api/v31/openapi.json", null, parseOptions); + // SwaggerParseResult result = new OpenAPIV3Parser().readLocation("https://petstore31.swagger.io/api/v31/openapi.json", null, parseOptions); + OpenAPI openAPI = result.getOpenAPI(); + + if (result.getMessages() != null) { + result.getMessages() + .forEach(System.err::println); // validation errors and warnings + } + + if (openAPI != null) { + final Map schemas = openAPI.getComponents() + .getSchemas(); +/* schemas.entrySet() + .stream() + .forEach(this::printSchema);*/ + } + Yaml31.prettyPrint(openAPI); + } + public void compare(String dir, SwaggerParseResult result) throws Exception { ObjectMapper mapper = Json31.mapper().copy();