Skip to content

Commit 7d9098f

Browse files
authored
Merge pull request #630 from swagger-api/fix/allOfResolving
fixing allOf external resolving refs #628
2 parents 7b972b8 + d2cc416 commit 7d9098f

File tree

4 files changed

+150
-15
lines changed

4 files changed

+150
-15
lines changed

modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ExternalRefProcessor.java

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import io.swagger.v3.oas.models.headers.Header;
99
import io.swagger.v3.oas.models.links.Link;
1010
import io.swagger.v3.oas.models.media.ArraySchema;
11+
import io.swagger.v3.oas.models.media.ComposedSchema;
1112
import io.swagger.v3.oas.models.media.Schema;
1213
import io.swagger.v3.oas.models.parameters.Parameter;
1314
import io.swagger.v3.oas.models.parameters.RequestBody;
@@ -83,64 +84,88 @@ public String processRefToExternalSchema(String $ref, RefFormat refFormat) {
8384

8485
String file = $ref.split("#/")[0];
8586
if (schema.get$ref() != null) {
86-
RefFormat format = computeRefFormat(schema.get$ref());
87-
if (isAnExternalRefFormat(format)) {
88-
schema.set$ref(processRefToExternalSchema(schema.get$ref(), format));
89-
} else {
90-
processRefToExternalSchema(file + schema.get$ref(), RefFormat.RELATIVE);
87+
processRefSchema(schema,file);
88+
}
89+
90+
if(schema instanceof ComposedSchema){
91+
ComposedSchema composedSchema = (ComposedSchema) schema;
92+
if (composedSchema.getAllOf() != null){
93+
for(Schema item : composedSchema.getAllOf()){
94+
if (item.get$ref() != null){
95+
processRefSchema(item,file);
96+
}
97+
}
98+
99+
}else if (composedSchema.getOneOf() != null){
100+
for(Schema item : composedSchema.getOneOf()){
101+
if (item.get$ref() != null){
102+
if (item.get$ref() != null){
103+
processRefSchema(item,file);
104+
}
105+
}
106+
}
107+
}else if (composedSchema.getAnyOf() != null){
108+
for(Schema item : composedSchema.getAnyOf()){
109+
if (item.get$ref() != null){
110+
if (item.get$ref() != null){
111+
processRefSchema(item,file);
112+
}
113+
}
114+
}
115+
91116
}
92117
}
93118
//Loop the properties and recursively call this method;
94119
Map<String, Schema> subProps = schema.getProperties();
95120
if (subProps != null) {
96121
for (Map.Entry<String, Schema> prop : subProps.entrySet()) {
97122
if (prop.getValue().get$ref() != null) {
98-
processRefProperty(prop.getValue(), file);
123+
processRefSchema(prop.getValue(), file);
99124
} else if (prop.getValue() instanceof ArraySchema) {
100125
ArraySchema arrayProp = (ArraySchema) prop.getValue();
101126
if (arrayProp.getItems() != null && arrayProp.getItems().get$ref() != null &&
102127
StringUtils.isNotBlank(arrayProp.get$ref())) {
103-
processRefProperty(arrayProp.getItems(), file);
128+
processRefSchema(arrayProp.getItems(), file);
104129
}
105130
} else if (prop.getValue().getAdditionalProperties() != null && prop.getValue().getAdditionalProperties() instanceof Schema) {
106131
Schema mapProp = (Schema) prop.getValue().getAdditionalProperties();
107132
if (mapProp.get$ref() != null) {
108-
processRefProperty(mapProp, file);
133+
processRefSchema(mapProp, file);
109134
} else if (mapProp.getAdditionalProperties() instanceof ArraySchema &&
110135
((ArraySchema) mapProp).getItems()!= null &&
111136
((ArraySchema) mapProp).getItems().get$ref() != null
112137
&& StringUtils.isNotBlank(((ArraySchema) mapProp).getItems().get$ref())) {
113-
processRefProperty(((ArraySchema) mapProp.getAdditionalProperties()).getItems(), file);
138+
processRefSchema(((ArraySchema) mapProp.getAdditionalProperties()).getItems(), file);
114139
}
115140
}
116141
}
117142
}
118143
if(schema.getAdditionalProperties() != null && schema.getAdditionalProperties() instanceof Schema){
119144
Schema additionalProperty = (Schema) schema.getAdditionalProperties();
120145
if (additionalProperty.get$ref() != null) {
121-
processRefProperty(additionalProperty, file);
146+
processRefSchema(additionalProperty, file);
122147
} else if (additionalProperty instanceof ArraySchema) {
123148
ArraySchema arrayProp = (ArraySchema) additionalProperty;
124149
if (arrayProp.getItems() != null && arrayProp.getItems().get$ref() != null &&
125150
StringUtils.isNotBlank(arrayProp.get$ref())) {
126-
processRefProperty(arrayProp.getItems(), file);
151+
processRefSchema(arrayProp.getItems(), file);
127152
}
128153
} else if (additionalProperty.getAdditionalProperties() != null && additionalProperty.getAdditionalProperties() instanceof Schema) {
129154
Schema mapProp = (Schema) additionalProperty.getAdditionalProperties();
130155
if (mapProp.get$ref() != null) {
131-
processRefProperty(mapProp, file);
156+
processRefSchema(mapProp, file);
132157
} else if (mapProp.getAdditionalProperties() instanceof ArraySchema &&
133158
((ArraySchema) mapProp).getItems() != null &&
134159
((ArraySchema) mapProp).getItems().get$ref() != null
135160
&& StringUtils.isNotBlank(((ArraySchema) mapProp).getItems().get$ref())) {
136-
processRefProperty(((ArraySchema) mapProp).getItems(), file);
161+
processRefSchema(((ArraySchema) mapProp).getItems(), file);
137162
}
138163
}
139164

140165
}
141166
if (schema instanceof ArraySchema && ((ArraySchema) schema).getItems() != null && ((ArraySchema) schema).getItems().get$ref() != null
142167
&& StringUtils.isNotBlank(((ArraySchema) schema).getItems().get$ref())) {
143-
processRefProperty(((ArraySchema) schema).getItems(), file);
168+
processRefSchema(((ArraySchema) schema).getItems(), file);
144169
}
145170
}
146171

@@ -614,7 +639,7 @@ public String processRefToExternalCallback(String $ref, RefFormat refFormat) {
614639
}
615640

616641

617-
private void processRefProperty(Schema subRef, String externalFile) {
642+
private void processRefSchema(Schema subRef, String externalFile) {
618643
RefFormat format = computeRefFormat(subRef.get$ref());
619644
if (isAnExternalRefFormat(format)) {
620645
String $ref = constructRef(subRef, externalFile);

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.github.tomakehurst.wiremock.WireMockServer;
55
import com.github.tomakehurst.wiremock.client.WireMock;
66
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
7+
import io.swagger.v3.core.util.Yaml;
78
import io.swagger.v3.oas.models.Components;
89
import io.swagger.v3.oas.models.OpenAPI;
910
import io.swagger.v3.oas.models.media.Schema;
@@ -324,6 +325,23 @@ public void testRefAndInlineAllOf(@Injectable final List<AuthorizationValue> aut
324325
Assert.assertTrue(openAPI.getPaths().get("/refToAllOf").getGet().getResponses().get("200").getContent().get("application/json").getSchema().getProperties().size() == 2);
325326
}
326327

328+
@Test
329+
public void testComposedRefResolvingIssue628(@Injectable final List<AuthorizationValue> auths) throws Exception {
330+
ParseOptions options = new ParseOptions();
331+
options.setResolve(true);
332+
OpenAPI openAPI = new OpenAPIV3Parser().read("src/test/resources/composedSchemaRef.yaml", auths, options);
333+
334+
Assert.assertNotNull(openAPI);
335+
336+
Assert.assertTrue(openAPI.getComponents().getSchemas().size() == 5);
337+
Assert.assertNotNull(openAPI.getComponents().getSchemas().get("Cat"));
338+
Assert.assertNotNull(openAPI.getComponents().getSchemas().get("Dog"));
339+
Assert.assertNotNull(openAPI.getComponents().getSchemas().get("Pet"));
340+
Assert.assertNotNull(openAPI.getComponents().getSchemas().get("Lion"));
341+
Assert.assertNotNull(openAPI.getComponents().getSchemas().get("Bear"));
342+
343+
}
344+
327345
@Test
328346
public void testOneOfExternalRefConflictName() throws Exception {
329347
OpenAPI openAPI = new OpenAPIV3Parser().read("src/test/resources/oneof_name_conflict/oneOf-external-ref-name-conflict.yaml");
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
openapi: 3.0.0
2+
info:
3+
version: 0.0.0
4+
title: oneOf and anyOf
5+
6+
paths:
7+
/oneOf:
8+
get:
9+
responses:
10+
'200':
11+
description: One of Cat or Dog
12+
content:
13+
application/json:
14+
schema:
15+
oneOf:
16+
- $ref: './refComponents.yaml#/components/schemas/Cat'
17+
- $ref: './refComponents.yaml#/components/schemas/Dog'
18+
- $ref: './refComponents.yaml#/components/schemas/Lion'
19+
/anyOf:
20+
get:
21+
responses:
22+
'200':
23+
description: Any of Cat or Dog
24+
content:
25+
application/json:
26+
schema:
27+
anyOf:
28+
- $ref: './refComponents.yaml#/components/schemas/Cat'
29+
- $ref: './refComponents.yaml#/components/schemas/Dog'
30+
- $ref: './refComponents.yaml#/components/schemas/Bear'
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
openapi: 3.0.0
2+
info:
3+
version: 0.0.0
4+
title: apa
5+
6+
components:
7+
schemas:
8+
Pet:
9+
required:
10+
- name
11+
- petType
12+
properties:
13+
name:
14+
type: string
15+
petType:
16+
type: string
17+
Cat:
18+
allOf:
19+
- $ref: '#/components/schemas/Pet'
20+
- type: object
21+
properties:
22+
huntingSkill:
23+
type: string
24+
default: lazy
25+
enum:
26+
- lazy
27+
- aggressive
28+
required:
29+
- huntingSkill
30+
Dog:
31+
allOf:
32+
- $ref: '#/components/schemas/Pet'
33+
- type: object
34+
properties:
35+
packSize:
36+
description: The size of the pack the dog is from
37+
type: integer
38+
required:
39+
- packSize
40+
Lion:
41+
oneOf:
42+
- $ref: '#/components/schemas/Pet'
43+
- type: object
44+
properties:
45+
huntingSkill:
46+
type: string
47+
default: lazy
48+
enum:
49+
- lazy
50+
- aggressive
51+
required:
52+
- huntingSkill
53+
Bear:
54+
anyOf:
55+
- $ref: '#/components/schemas/Pet'
56+
- type: object
57+
properties:
58+
packSize:
59+
description: The size of the pack the dog is from
60+
type: integer
61+
required:
62+
- packSize

0 commit comments

Comments
 (0)