Skip to content

Commit 4d0b9fc

Browse files
authored
Merge pull request #9765 from swagger-api/ticket-9725
refs #9725 - fix response schema flattening for arrays and maps
2 parents dbb5603 + 8876fa4 commit 4d0b9fc

File tree

5 files changed

+163
-13
lines changed

5 files changed

+163
-13
lines changed

modules/swagger-codegen/src/main/java/io/swagger/codegen/InlineModelResolver.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import io.swagger.models.parameters.BodyParameter;
55
import io.swagger.models.parameters.Parameter;
66
import io.swagger.models.properties.*;
7+
import io.swagger.models.utils.PropertyModelConverter;
78
import io.swagger.util.Json;
89
import org.slf4j.Logger;
910
import org.slf4j.LoggerFactory;
@@ -100,11 +101,11 @@ public void flatten(Swagger swagger) {
100101
if (existing != null) {
101102
Property refProperty = this.makeRefProperty(existing, property);
102103
refProperty.setRequired(op.getRequired());
103-
response.setSchema(refProperty);
104+
response.setResponseSchema(new PropertyModelConverter().propertyToModel(refProperty));
104105
} else {
105106
Property refProperty = this.makeRefProperty(modelName, property);
106107
refProperty.setRequired(op.getRequired());
107-
response.setSchema(refProperty);
108+
response.setResponseSchema(new PropertyModelConverter().propertyToModel(refProperty));
108109
addGenerated(modelName, model);
109110
swagger.addDefinition(modelName, model);
110111
}
@@ -125,10 +126,12 @@ public void flatten(Swagger swagger) {
125126
Property refProperty = this.makeRefProperty(existing, op);
126127
refProperty.setRequired(op.getRequired());
127128
ap.setItems(refProperty);
129+
response.setResponseSchema(new PropertyModelConverter().propertyToModel(ap));
128130
} else {
129131
Property refProperty = this.makeRefProperty(modelName, op);
130132
refProperty.setRequired(op.getRequired());
131133
ap.setItems(refProperty);
134+
response.setResponseSchema(new PropertyModelConverter().propertyToModel(ap));
132135
addGenerated(modelName, innerModel);
133136
swagger.addDefinition(modelName, innerModel);
134137
}
@@ -150,10 +153,12 @@ public void flatten(Swagger swagger) {
150153
RefProperty refProperty = new RefProperty(existing);
151154
refProperty.setRequired(op.getRequired());
152155
mp.setAdditionalProperties(refProperty);
156+
response.setResponseSchema(new PropertyModelConverter().propertyToModel(mp));
153157
} else {
154158
RefProperty refProperty = new RefProperty(modelName);
155159
refProperty.setRequired(op.getRequired());
156160
mp.setAdditionalProperties(refProperty);
161+
response.setResponseSchema(new PropertyModelConverter().propertyToModel(mp));
157162
addGenerated(modelName, innerModel);
158163
swagger.addDefinition(modelName, innerModel);
159164
}
@@ -379,6 +384,12 @@ public Model modelFromProperty(ArrayProperty object, @SuppressWarnings("unused")
379384
model.setDescription(description);
380385
model.setExample(example);
381386
model.setItems(object.getItems());
387+
if (object.getVendorExtensions() != null) {
388+
for (String key : object.getVendorExtensions().keySet()) {
389+
model.setVendorExtension(key, object.getVendorExtensions().get(key));
390+
}
391+
}
392+
382393
return model;
383394
}
384395

@@ -398,10 +409,16 @@ public Model modelFromProperty(ObjectProperty object, String path) {
398409
Map<String, Property> properties = object.getProperties();
399410

400411
ModelImpl model = new ModelImpl();
412+
model.type(object.getType());
401413
model.setDescription(description);
402414
model.setExample(example);
403415
model.setName(name);
404416
model.setXml(xml);
417+
if (object.getVendorExtensions() != null) {
418+
for (String key : object.getVendorExtensions().keySet()) {
419+
model.setVendorExtension(key, object.getVendorExtensions().get(key));
420+
}
421+
}
405422

406423
if (properties != null) {
407424
flattenProperties(properties, path);
@@ -425,6 +442,11 @@ public Model modelFromProperty(MapProperty object, @SuppressWarnings("unused") S
425442
model.setDescription(description);
426443
model.setExample(example);
427444
model.setItems(object.getAdditionalProperties());
445+
if (object.getVendorExtensions() != null) {
446+
for (String key : object.getVendorExtensions().keySet()) {
447+
model.setVendorExtension(key, object.getVendorExtensions().get(key));
448+
}
449+
}
428450

429451
return model;
430452
}

modules/swagger-codegen/src/test/java/io/swagger/codegen/DefaultGeneratorTest.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import io.swagger.codegen.config.CodegenConfigurator;
44
import io.swagger.codegen.languages.JavaClientCodegen;
5+
import io.swagger.codegen.languages.SpringCodegen;
56
import io.swagger.models.ExternalDocs;
67
import io.swagger.models.Swagger;
78
import io.swagger.models.Tag;
@@ -226,6 +227,42 @@ public void testIssue9132() throws Exception {
226227

227228
}
228229

230+
@Test
231+
public void testIssue9725() throws Exception {
232+
final File output = folder.getRoot();
233+
234+
Swagger swagger = new SwaggerParser().read("src/test/resources/2_0/ticket-9725.json");
235+
CodegenConfig codegenConfig = new SpringCodegen();
236+
codegenConfig.setLibrary("spring-cloud");
237+
codegenConfig.setOutputDir(output.getAbsolutePath());
238+
239+
ClientOptInput clientOptInput = new ClientOptInput().opts(new ClientOpts()).swagger(swagger).config(codegenConfig);
240+
241+
//generate
242+
new DefaultGenerator().opts(clientOptInput).generate();
243+
final File defaultApi = new File(output, "src/main/java/io/swagger/api/DefaultApi.java");
244+
assertTrue(defaultApi.exists());
245+
assertTrue(containsSearchStrings(defaultApi,"ResponseEntity<List<GetMarketsRegionIdOrders200Ok>>"));
246+
}
247+
248+
@Test
249+
public void testIssue9725Map() throws Exception {
250+
final File output = folder.getRoot();
251+
252+
Swagger swagger = new SwaggerParser().read("src/test/resources/2_0/ticket-9725-map.json");
253+
CodegenConfig codegenConfig = new SpringCodegen();
254+
codegenConfig.setLibrary("spring-cloud");
255+
codegenConfig.setOutputDir(output.getAbsolutePath());
256+
257+
ClientOptInput clientOptInput = new ClientOptInput().opts(new ClientOpts()).swagger(swagger).config(codegenConfig);
258+
259+
//generate
260+
new DefaultGenerator().opts(clientOptInput).generate();
261+
final File defaultApi = new File(output, "src/main/java/io/swagger/api/DefaultApi.java");
262+
assertTrue(defaultApi.exists());
263+
assertTrue(containsSearchStrings(defaultApi,"ResponseEntity<Map<String, GetMarketsRegionIdOrders200Ok>>"));
264+
}
265+
229266
@Test
230267
public void testRelativeRefs() throws IOException {
231268
final File output = folder.getRoot();

modules/swagger-codegen/src/test/java/io/swagger/codegen/InlineModelResolverTest.java

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -187,19 +187,27 @@ public void resolveInlineModel2DifferentInnerModelsWIthSameTitle() throws Except
187187
public void testInlineResponseModel() throws Exception {
188188
Swagger swagger = new Swagger();
189189

190+
ModelImpl responseSchema = new ModelImpl().type("object").property("name", new StringProperty());
191+
responseSchema.setVendorExtension("x-ext", "ext-prop");
192+
ModelImpl responseSchemaBaz = new ModelImpl().type("object").property("name", new StringProperty());
193+
responseSchemaBaz.setVendorExtension("x-ext", "ext-prop");
190194
swagger.path("/foo/bar", new Path()
191195
.get(new Operation()
192196
.response(200, new Response()
193197
.description("it works!")
194-
.schema(new ObjectProperty()
195-
.property("name", new StringProperty()).vendorExtension("x-ext", "ext-prop")))))
198+
.responseSchema(responseSchema)
199+
)
200+
)
201+
)
196202
.path("/foo/baz", new Path()
197203
.get(new Operation()
198204
.response(200, new Response()
199205
.vendorExtension("x-foo", "bar")
200206
.description("it works!")
201-
.schema(new ObjectProperty()
202-
.property("name", new StringProperty()).vendorExtension("x-ext", "ext-prop")))));
207+
.responseSchema(responseSchemaBaz)
208+
)
209+
)
210+
);
203211
new InlineModelResolver().flatten(swagger);
204212

205213
Map<String, Response> responses = swagger.getPaths().get("/foo/bar").getGet().getResponses();
@@ -208,34 +216,37 @@ public void testInlineResponseModel() throws Exception {
208216
assertNotNull(response);
209217
Property schema = response.getSchema();
210218
assertTrue(schema instanceof RefProperty);
211-
assertEquals(1, schema.getVendorExtensions().size());
212-
assertEquals("ext-prop", schema.getVendorExtensions().get("x-ext"));
213219

214220
ModelImpl model = (ModelImpl)swagger.getDefinitions().get("inline_response_200");
215221
assertTrue(model.getProperties().size() == 1);
216222
assertNotNull(model.getProperties().get("name"));
217223
assertTrue(model.getProperties().get("name") instanceof StringProperty);
224+
assertEquals(1, model.getVendorExtensions().size());
225+
assertEquals("ext-prop", model.getVendorExtensions().get("x-ext"));
218226
}
219227

220228

221229
@Test
222230
public void testInlineResponseModelWithTitle() throws Exception {
223231
Swagger swagger = new Swagger();
224232

233+
225234
String responseTitle = "GetBarResponse";
226-
swagger.path("/foo/bar", new Path()
235+
ModelImpl responseSchema = new ModelImpl().type("object").property("name", new StringProperty());
236+
responseSchema.setTitle(responseTitle);
237+
ModelImpl responseSchemaBaz = new ModelImpl().type("object").property("name", new StringProperty());
238+
239+
swagger.path("/foo/bar", new Path()
227240
.get(new Operation()
228241
.response(200, new Response()
229242
.description("it works!")
230-
.schema(new ObjectProperty().title(responseTitle)
231-
.property("name", new StringProperty())))))
243+
.responseSchema(responseSchema))))
232244
.path("/foo/baz", new Path()
233245
.get(new Operation()
234246
.response(200, new Response()
235247
.vendorExtension("x-foo", "bar")
236248
.description("it works!")
237-
.schema(new ObjectProperty()
238-
.property("name", new StringProperty())))));
249+
.responseSchema(responseSchemaBaz))));
239250
new InlineModelResolver().flatten(swagger);
240251

241252
Map<String, Response> responses = swagger.getPaths().get("/foo/bar").getGet().getResponses();
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"swagger": "2.0",
3+
"info": {
4+
"version": "1.0.0",
5+
"title": "Swagger Petstore"
6+
},
7+
"host": "petstore.swagger.io",
8+
"basePath": "/v2",
9+
"paths": {
10+
"/pet": {
11+
"post": {
12+
"operationId": "addPet",
13+
"produces": [
14+
"application/json"
15+
],
16+
"responses": {
17+
"200": {
18+
"schema": {
19+
"additionalProperties": {
20+
"properties": {
21+
"duration": {
22+
"description": "duration integer",
23+
"format": "int32",
24+
"title": "get_markets_region_id_orders_duration",
25+
"type": "integer"
26+
}
27+
},
28+
"title": "get_markets_region_id_orders_200_ok",
29+
"type": "object"
30+
},
31+
"maxItems": 1000,
32+
"title": "get_markets_region_id_orders_ok",
33+
"type": "object"
34+
}
35+
}
36+
}
37+
}
38+
}
39+
}
40+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"swagger": "2.0",
3+
"info": {
4+
"version": "1.0.0",
5+
"title": "Swagger Petstore"
6+
},
7+
"host": "petstore.swagger.io",
8+
"basePath": "/v2",
9+
"paths": {
10+
"/pet": {
11+
"post": {
12+
"operationId": "addPet",
13+
"produces": [
14+
"application/json"
15+
],
16+
"responses": {
17+
"200": {
18+
"schema": {
19+
"items": {
20+
"properties": {
21+
"duration": {
22+
"description": "duration integer",
23+
"format": "int32",
24+
"title": "get_markets_region_id_orders_duration",
25+
"type": "integer"
26+
}
27+
},
28+
"title": "get_markets_region_id_orders_200_ok",
29+
"type": "object"
30+
},
31+
"maxItems": 1000,
32+
"title": "get_markets_region_id_orders_ok",
33+
"type": "array"
34+
}
35+
}
36+
}
37+
}
38+
}
39+
}
40+
}

0 commit comments

Comments
 (0)