Skip to content

Commit 19dcc26

Browse files
authored
fix: resolve refs within external schemas (#2338)
1 parent 702586f commit 19dcc26

4 files changed

Lines changed: 93 additions & 0 deletions

File tree

modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/reference/OpenAPI31Traverser.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,9 @@ public Schema traverseSchema(Schema schema, ReferenceVisitor visitor, List<Strin
794794
resolvedURI = ReferenceUtils.toBaseURI(resolvedURI);
795795
}
796796
context.getIdsCache().put(resolvedURI, Json31.pretty(schema));
797+
if (!visitor.reference.getReferenceSet().containsKey(resolvedURI)) {
798+
visitor.reference.getReferenceSet().put(resolvedURI, visitor.reference);
799+
}
797800
} catch (Exception e) {
798801
//
799802
}
@@ -920,6 +923,9 @@ public Schema traverseSchema(Schema schema, ReferenceVisitor visitor, List<Strin
920923
visiting.remove(schema);
921924
return handleRootLocalRefs(schema.get$ref(), resolved, context.getOpenApi().getComponents().getSchemas());
922925
}
926+
if (resolvedNotNull && schema.getProperties() != null && !schema.getProperties().isEmpty()) {
927+
traverseSchemaMap(schema.getProperties(), visitor, inheritedIds);
928+
}
923929
// merge ALL STUFF
924930
mergeSchemas(schema, resolved);
925931
visitedMap.put(schema, deepcopy(resolved, Schema.class));

modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV31ParserSchemaTest.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,14 @@ private void setUpWireMockServer() throws IOException {
153153
.withBody(pathFile
154154
.getBytes(StandardCharsets.UTF_8))));
155155

156+
pathFile = FileUtils.readFileToString(new File("src/test/resources/3.1.0/dereference/schema/external-oas-with-id-defs/oas.yaml"), StandardCharsets.UTF_8);
157+
158+
WireMock.stubFor(get(urlPathMatching("/oai-v3.1-schema.yaml"))
159+
.willReturn(aResponse()
160+
.withStatus(HttpURLConnection.HTTP_OK)
161+
.withHeader("Content-type", "application/yaml")
162+
.withBody(pathFile.getBytes(StandardCharsets.UTF_8))));
163+
156164
}
157165

158166
@AfterClass
@@ -216,6 +224,25 @@ public void testAnchorUnresolve() throws Exception {
216224
compare("$anchor-not-found", swaggerParseResult);
217225
}
218226

227+
@Test
228+
public void testExternalSchemaWithIdAndDefsResolution_issue2271() throws IOException {
229+
String rootYaml = FileUtils.readFileToString(
230+
new File("src/test/resources/3.1.0/dereference/schema/external-oas-with-id-defs/root.yaml"),
231+
StandardCharsets.UTF_8);
232+
rootYaml = rootYaml.replace("${dynamicPort}", String.valueOf(this.serverPort));
233+
234+
ParseOptions options = new ParseOptions();
235+
options.setResolve(true);
236+
SwaggerParseResult result = new OpenAPIV3Parser().readContents(rootYaml, null, options);
237+
238+
org.testng.Assert.assertNotNull(result.getOpenAPI());
239+
org.testng.Assert.assertTrue(
240+
result.getMessages() == null
241+
|| result.getMessages().stream().noneMatch(m -> m.contains("Could not find /$defs")),
242+
"Expected no $defs resolution errors when resolving external schema with $id, but got: "
243+
+ result.getMessages());
244+
}
245+
219246
public void compare(String dir, SwaggerParseResult result) throws Exception {
220247
ObjectMapper mapper = Json31.mapper().copy();
221248
mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
$id: 'https://spec.openapis.org/oas/3.1/schema/2022-10-07'
2+
$schema: 'https://json-schema.org/draft/2020-12/schema'
3+
type: object
4+
properties:
5+
info:
6+
$ref: '#/$defs/info'
7+
servers:
8+
type: array
9+
items:
10+
$ref: '#/$defs/server'
11+
$ref: '#/$defs/extensions'
12+
$defs:
13+
info:
14+
type: object
15+
properties:
16+
title:
17+
type: string
18+
required:
19+
- title
20+
server:
21+
type: object
22+
properties:
23+
url:
24+
type: string
25+
required:
26+
- url
27+
extensions:
28+
patternProperties:
29+
'^x-': true
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
openapi: 3.1.0
2+
info:
3+
title: Test external OAI schema with $id and $defs resolution
4+
version: 1.0.0
5+
paths:
6+
/hello:
7+
get:
8+
operationId: hello
9+
responses:
10+
"200":
11+
description: A successful response
12+
$ref: '#/components/responses/Data'
13+
components:
14+
responses:
15+
Data:
16+
description: Description of the response
17+
content:
18+
application/json:
19+
schema:
20+
type: object
21+
required:
22+
- items
23+
properties:
24+
items:
25+
message:
26+
type: string
27+
schema:
28+
$ref: "#/components/schemas/OpenApiSchema"
29+
schemas:
30+
OpenApiSchema:
31+
$ref: "http://localhost:${dynamicPort}/oai-v3.1-schema.yaml"

0 commit comments

Comments
 (0)