From 7a29793babb9ffd9aebfa24012d08838a6311d6a Mon Sep 17 00:00:00 2001 From: Joel Jonsson Date: Mon, 13 Nov 2017 11:21:05 +0100 Subject: [PATCH 1/2] Fix NPE when referring spec does not contain components tag. --- .../v3/parser/processors/ExternalRefProcessor.java | 4 ++++ .../swagger/v3/parser/test/OpenAPIResolverTest.java | 11 +++++++++++ .../src/test/resources/ref-without-component/a.yaml | 13 +++++++++++++ .../src/test/resources/ref-without-component/b.yaml | 6 ++++++ 4 files changed, 34 insertions(+) create mode 100644 modules/swagger-parser-v3/src/test/resources/ref-without-component/a.yaml create mode 100644 modules/swagger-parser-v3/src/test/resources/ref-without-component/b.yaml diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ExternalRefProcessor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ExternalRefProcessor.java index b30f168487..3abb15ed72 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ExternalRefProcessor.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ExternalRefProcessor.java @@ -1,6 +1,7 @@ package io.swagger.v3.parser.processors; +import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.callbacks.Callback; import io.swagger.v3.oas.models.examples.Example; @@ -46,6 +47,9 @@ public String processRefToExternalSchema(String $ref, RefFormat refFormat) { } String newRef; + if (openAPI.getComponents() == null) { + openAPI.setComponents(new Components()); + } Map schemas = openAPI.getComponents().getSchemas(); if (schemas == null) { diff --git a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIResolverTest.java b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIResolverTest.java index 159d56c49c..b039dc5e19 100644 --- a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIResolverTest.java +++ b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIResolverTest.java @@ -603,6 +603,17 @@ public void resolveComposedSchema(@Injectable final List aut } + @Test + public void referringSpecWithoutComponentsTag() throws Exception { + ParseOptions resolve = new ParseOptions(); + resolve.setResolveFully(true); + final OpenAPI openAPI = new OpenAPIV3Parser().read("src/test/resources/ref-without-component/a.yaml", null, resolve); + + Map schemas = openAPI.getComponents().getSchemas(); + Assert.assertEquals("Example value", schemas.get("CustomerType").getExample()); + } + + private static int getDynamicPort() { return new Random().ints(50000, 60000).findFirst().getAsInt(); } diff --git a/modules/swagger-parser-v3/src/test/resources/ref-without-component/a.yaml b/modules/swagger-parser-v3/src/test/resources/ref-without-component/a.yaml new file mode 100644 index 0000000000..efec250888 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/ref-without-component/a.yaml @@ -0,0 +1,13 @@ +openapi: 3.0.0 +paths: + "/newPerson": + post: + summary: Create new person + description: Create new person + responses: + '200': + description: OK + content: + "*/*": + schema: + "$ref": "./src/test/resources/ref-without-component/b.yaml#/components/schemas/CustomerType" diff --git a/modules/swagger-parser-v3/src/test/resources/ref-without-component/b.yaml b/modules/swagger-parser-v3/src/test/resources/ref-without-component/b.yaml new file mode 100644 index 0000000000..4ca2604e6c --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/ref-without-component/b.yaml @@ -0,0 +1,6 @@ +openapi: 3.0.0 +components: + schemas: + CustomerType: + type: string + example: Example value From 8351812bfc98fbde1d476baaa334a717fc994c36 Mon Sep 17 00:00:00 2001 From: Joel Jonsson Date: Wed, 22 Nov 2017 14:39:34 +0100 Subject: [PATCH 2/2] Add null check for all places accessing components and make it not required. --- .../io/swagger/v3/parser/ResolverCache.java | 58 +++++++++---------- .../processors/ExternalRefProcessor.java | 24 ++++++++ .../v3/parser/util/OpenAPIDeserializer.java | 2 +- .../parser/util/OpenAPIDeserializerTest.java | 1 - 4 files changed, 54 insertions(+), 31 deletions(-) diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/ResolverCache.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/ResolverCache.java index f109157fa5..e24d849975 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/ResolverCache.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/ResolverCache.java @@ -154,38 +154,38 @@ else if(rootPath != null) { private Object loadInternalRef(String ref) { Object result = null; - if(ref.startsWith("#/components/schemas")) { - result = getFromMap(ref, openApi.getComponents().getSchemas(), SCHEMAS_PATTERN); - } - else if(ref.startsWith("#/components/requestBodies")) { - result = getFromMap(ref, openApi.getComponents().getRequestBodies(), REQUEST_BODIES_PATTERN); - } - else if(ref.startsWith("#/components/examples")) { - result = getFromMap(ref, openApi.getComponents().getExamples(), EXAMPLES_PATTERN); - } - else if(ref.startsWith("#/components/responses")) { - result = getFromMap(ref, openApi.getComponents().getResponses(), RESPONSES_PATTERN); - } - else if(ref.startsWith("#/components/parameters")) { - result = getFromMap(ref, openApi.getComponents().getParameters(), PARAMETERS_PATTERN); - } - else if(ref.startsWith("#/components/links")) { - result = getFromMap(ref, openApi.getComponents().getLinks(), LINKS_PATTERN); - } - else if(ref.startsWith("#/components/headers")) { - result = getFromMap(ref, openApi.getComponents().getHeaders(), HEADERS_PATTERN); - } - else if(ref.startsWith("#/components/callbacks")) { - result = getFromMap(ref, openApi.getComponents().getCallbacks(), CALLBACKS_PATTERN); - } - else if(ref.startsWith("#/components/securitySchemes")) { - result = getFromMap(ref, openApi.getComponents().getSecuritySchemes(), SECURITY_SCHEMES); - } - else if(ref.startsWith("#/paths")) { + if (ref.startsWith("#/paths")) { result = getFromMap(ref, openApi.getPaths(), PATHS_PATTERN); + } else if (openApi.getComponents() != null){ + if(ref.startsWith("#/components/schemas")) { + result = getFromMap(ref, openApi.getComponents().getSchemas(), SCHEMAS_PATTERN); + } + else if(ref.startsWith("#/components/requestBodies")) { + result = getFromMap(ref, openApi.getComponents().getRequestBodies(), REQUEST_BODIES_PATTERN); + } + else if(ref.startsWith("#/components/examples")) { + result = getFromMap(ref, openApi.getComponents().getExamples(), EXAMPLES_PATTERN); + } + else if(ref.startsWith("#/components/responses")) { + result = getFromMap(ref, openApi.getComponents().getResponses(), RESPONSES_PATTERN); + } + else if(ref.startsWith("#/components/parameters")) { + result = getFromMap(ref, openApi.getComponents().getParameters(), PARAMETERS_PATTERN); + } + else if(ref.startsWith("#/components/links")) { + result = getFromMap(ref, openApi.getComponents().getLinks(), LINKS_PATTERN); + } + else if(ref.startsWith("#/components/headers")) { + result = getFromMap(ref, openApi.getComponents().getHeaders(), HEADERS_PATTERN); + } + else if(ref.startsWith("#/components/callbacks")) { + result = getFromMap(ref, openApi.getComponents().getCallbacks(), CALLBACKS_PATTERN); + } + else if(ref.startsWith("#/components/securitySchemes")) { + result = getFromMap(ref, openApi.getComponents().getSecuritySchemes(), SECURITY_SCHEMES); + } } - return result; } diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ExternalRefProcessor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ExternalRefProcessor.java index 3abb15ed72..8928399c70 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ExternalRefProcessor.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ExternalRefProcessor.java @@ -125,6 +125,9 @@ public String processRefToExternalResponse(String $ref, RefFormat refFormat) { } String newRef; + if (openAPI.getComponents() == null) { + openAPI.setComponents(new Components()); + } Map responses = openAPI.getComponents().getResponses(); if (responses == null) { @@ -175,6 +178,9 @@ public String processRefToExternalRequestBody(String $ref, RefFormat refFormat) } String newRef; + if (openAPI.getComponents() == null) { + openAPI.setComponents(new Components()); + } Map bodies = openAPI.getComponents().getRequestBodies(); if (bodies == null) { @@ -225,6 +231,9 @@ public String processRefToExternalHeader(String $ref, RefFormat refFormat) { } String newRef; + if (openAPI.getComponents() == null) { + openAPI.setComponents(new Components()); + } Map headers = openAPI.getComponents().getHeaders(); if (headers == null) { @@ -275,6 +284,9 @@ public String processRefToExternalSecurityScheme(String $ref, RefFormat refForma } String newRef; + if (openAPI.getComponents() == null) { + openAPI.setComponents(new Components()); + } Map securitySchemeMap = openAPI.getComponents().getSecuritySchemes(); if (securitySchemeMap == null) { @@ -325,6 +337,9 @@ public String processRefToExternalLink(String $ref, RefFormat refFormat) { } String newRef; + if (openAPI.getComponents() == null) { + openAPI.setComponents(new Components()); + } Map links = openAPI.getComponents().getLinks(); if (links == null) { @@ -375,6 +390,9 @@ public String processRefToExternalExample(String $ref, RefFormat refFormat) { } String newRef; + if (openAPI.getComponents() == null) { + openAPI.setComponents(new Components()); + } Map examples = openAPI.getComponents().getExamples(); if (examples == null) { @@ -425,6 +443,9 @@ public String processRefToExternalParameter(String $ref, RefFormat refFormat) { } String newRef; + if (openAPI.getComponents() == null) { + openAPI.setComponents(new Components()); + } Map parameters = openAPI.getComponents().getParameters(); if (parameters == null) { @@ -475,6 +496,9 @@ public String processRefToExternalCallback(String $ref, RefFormat refFormat) { } String newRef; + if (openAPI.getComponents() == null) { + openAPI.setComponents(new Components()); + } Map callbacks = openAPI.getComponents().getCallbacks(); if (callbacks == null) { 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 de430f1988..b86e22adcd 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 @@ -136,7 +136,7 @@ public OpenAPI parseRoot(JsonNode node, ParseResult result) { openAPI.setPaths(paths); } - obj = getObject("components", rootNode, true, location, result); + obj = getObject("components", rootNode, false, location, result); if (obj != null) { Components components = getComponents(obj, "components", result); openAPI.setComponents(components); diff --git a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/util/OpenAPIDeserializerTest.java b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/util/OpenAPIDeserializerTest.java index d57fd136d7..aae9f2db8f 100644 --- a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/util/OpenAPIDeserializerTest.java +++ b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/util/OpenAPIDeserializerTest.java @@ -542,7 +542,6 @@ public void testAlmostEmpty(@Injectable List auths) { assertTrue(messages.contains("attribute info is missing")); assertTrue(messages.contains("attribute paths is missing")); - assertTrue(messages.contains("attribute components is missing")); assertTrue(messages.contains("attribute new is unexpected")); }