Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flatten ComposedSchemas at Array items in responses, parameters, requestBodies #1384

Merged
merged 1 commit into from
Jun 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,13 @@ public void flatten(OpenAPI openAPI) {
addGenerated(modelName, model);
openAPI.getComponents().addSchemas(modelName, model);
} else if (model instanceof ComposedSchema) {
String modelName = resolveModelName(model.getTitle(), "body");
mediaType.setSchema(new Schema().$ref(modelName));
addGenerated(modelName, model);
openAPI.getComponents().addSchemas(modelName, model);
flattenComposedSchema(model, pathname);
if (model.get$ref() == null) {
String modelName = resolveModelName(model.getTitle(), "body");
mediaType.setSchema(this.makeRefProperty(modelName, model));
addGenerated(modelName, model);
openAPI.getComponents().addSchemas(modelName, model);
}
} else if (model instanceof ArraySchema) {
ArraySchema am = (ArraySchema) model;
Schema inner = am.getItems();
Expand All @@ -106,6 +109,14 @@ public void flatten(OpenAPI openAPI) {
addGenerated(modelName, inner);
openAPI.getComponents().addSchemas(modelName, inner);
}
}else if (inner instanceof ComposedSchema && this.flattenComposedSchemas){
flattenComposedSchema(inner,key);
if (inner.get$ref() == null) {
String modelName = resolveModelName(inner.getTitle(), "inline_body_items_" + key + "_" + pathname);
am.setItems(this.makeRefProperty(modelName, inner));
addGenerated(modelName, inner);
openAPI.getComponents().addSchemas(modelName, inner);
}
}
}
}
Expand Down Expand Up @@ -149,6 +160,14 @@ public void flatten(OpenAPI openAPI) {
addGenerated(modelName, am);
openAPI.getComponents().addSchemas(modelName, am);
}
}else if (inner instanceof ComposedSchema && this.flattenComposedSchemas){
flattenComposedSchema(inner, parameter.getName());
if (inner.get$ref() == null) {
String modelName = resolveModelName(inner.getTitle(), "inline_parameter_items_" + parameter.getName());
am.setItems(this.makeRefProperty(modelName, inner));
addGenerated(modelName, inner);
openAPI.getComponents().addSchemas(modelName, inner);
}
}
}
}
Expand Down Expand Up @@ -177,16 +196,16 @@ public void flatten(OpenAPI openAPI) {
addGenerated(modelName, mediaSchema);
openAPI.getComponents().addSchemas(modelName, mediaSchema);
}
}
} else if (mediaSchema instanceof ComposedSchema ){
String modelName = resolveModelName(mediaSchema.getTitle(), "inline_response_" + key);
String existing = matchGenerated(mediaSchema);
if (existing != null) {
media.setSchema(this.makeRefProperty(existing, mediaSchema));
} else {
media.setSchema(this.makeRefProperty(modelName, mediaSchema));
addGenerated(modelName, mediaSchema);
openAPI.getComponents().addSchemas(modelName, mediaSchema);
}else if (mediaSchema instanceof ComposedSchema) {
String modelName = resolveModelName(mediaSchema.getTitle(), "inline_response_" + key);
String existing = matchGenerated(mediaSchema);
if (existing != null) {
media.setSchema(this.makeRefProperty(existing, mediaSchema));
} else {
media.setSchema(this.makeRefProperty(modelName, mediaSchema));
addGenerated(modelName, mediaSchema);
openAPI.getComponents().addSchemas(modelName, mediaSchema);
}
}

}else if (mediaSchema instanceof ArraySchema) {
Expand All @@ -206,8 +225,17 @@ public void flatten(OpenAPI openAPI) {
addGenerated(modelName, inner);
openAPI.getComponents().addSchemas(modelName, inner);
}
}else if (inner instanceof ComposedSchema && this.flattenComposedSchemas){
flattenComposedSchema(inner,key);
if (inner.get$ref() == null) {
String modelName = resolveModelName(inner.getTitle(), "inline_response_items" + key);
ap.setItems(this.makeRefProperty(modelName, inner));
addGenerated(modelName, inner);
openAPI.getComponents().addSchemas(modelName, inner);
}
}
}

} else if (mediaSchema.getAdditionalProperties() != null && mediaSchema.getAdditionalProperties() instanceof Schema) {

Schema innerProperty = (Schema) mediaSchema.getAdditionalProperties();
Expand Down Expand Up @@ -260,6 +288,14 @@ public void flatten(OpenAPI openAPI) {
} else {
m.setItems(new Schema().$ref(existing));
}
}else if (inner instanceof ComposedSchema && this.flattenComposedSchemas){
flattenComposedSchema(inner,modelName);
if (inner.get$ref() == null) {
modelName = resolveModelName(inner.getTitle(), "inline_array_items_" + modelName);
m.setItems(this.makeRefProperty(modelName, inner));
addGenerated(modelName, inner);
openAPI.getComponents().addSchemas(modelName, inner);
}
}
}
} else if (model instanceof ComposedSchema) {
Expand Down Expand Up @@ -473,6 +509,40 @@ public void flattenProperties(Map<String, Schema> properties, String path) {
}
}

private void flattenComposedSchema(Schema inner, String key) {

ComposedSchema composedSchema = (ComposedSchema) inner;
String inlineModelName = "";

List<Schema> list = null;
if (composedSchema.getAllOf() != null) {
list = composedSchema.getAllOf();
inlineModelName = "AllOf";
}else if (composedSchema.getAnyOf() != null) {
list = composedSchema.getAnyOf();
inlineModelName = "AnyOf";
}else if (composedSchema.getOneOf() != null) {
list = composedSchema.getOneOf();
inlineModelName = "OneOf";
}

for(int i= 0; i<list.size();i++){
if (list.get(i).get$ref() == null){
Schema inline = list.get(i);
if (inline.getProperties()!= null){
flattenProperties(inline.getProperties(), key);
}
if (this.flattenComposedSchemas) {
int position = i+1;
inlineModelName = resolveModelName(inline.getTitle(), key + inlineModelName + "_" + position);
list.set(i,new Schema().$ref(inlineModelName));
addGenerated(inlineModelName, inline);
openAPI.getComponents().addSchemas(inlineModelName, inline);
}
}
}
}

@SuppressWarnings("static-method")
public Schema modelFromProperty(ArraySchema object, @SuppressWarnings("unused") String path) {
String description = object.getDescription();
Expand Down Expand Up @@ -593,7 +663,8 @@ public void copyVendorExtensions(Schema source, Schema target) {
private boolean isObjectSchema(Schema schema) {
return schema instanceof ObjectSchema
|| "object".equalsIgnoreCase(schema.getType())
|| (schema.getType() == null && schema.getProperties() != null && !schema.getProperties().isEmpty());
|| (schema.getType() == null && schema.getProperties() != null && !schema.getProperties().isEmpty()
|| schema instanceof ComposedSchema);
}

public boolean isSkipMatches() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,68 @@ public class OpenAPIV3ParserTest {
protected int serverPort = getDynamicPort();
protected WireMockServer wireMockServer;

@Test
public void testIssueFlattenArraySchemaItemsInlineModelFalse() {
OpenAPIV3Parser openApiParser = new OpenAPIV3Parser();
ParseOptions options = new ParseOptions();
options.setResolve(true);
options.setFlatten(true);
options.setFlattenComposedSchemas(false);
options.setCamelCaseFlattenNaming(false);
SwaggerParseResult parseResult = openApiParser.readLocation("flattenArrayItems.yaml", null, options);
OpenAPI openAPI = parseResult.getOpenAPI();

//responses
assertNull(openAPI.getComponents().getSchemas().get("Inline_response_items200"));
assertNull(openAPI.getComponents().getSchemas().get("Inline_response_400"));

//parameters
assertNull(openAPI.getComponents().getSchemas().get("Inline_parameter_items_bodylimit"));
assertNull(openAPI.getComponents().getSchemas().get("Pagelimit"));

//requestBodies
assertNull(openAPI.getComponents().getSchemas().get("Body"));
assertNull(openAPI.getComponents().getSchemas().get("Inline_response_items200"));

//components
assertNull(openAPI.getComponents().getSchemas().get("Inline_array_items_ArrayTest"));

}

@Test
public void testIssueFlattenArraySchemaItemsInlineModelTrue() {
OpenAPIV3Parser openApiParser = new OpenAPIV3Parser();
ParseOptions options = new ParseOptions();
options.setResolve(true);
options.setFlatten(true);
options.setFlattenComposedSchemas(true);
options.setCamelCaseFlattenNaming(true);
SwaggerParseResult parseResult = openApiParser.readLocation("flattenArrayItems.yaml", null, options);
OpenAPI openAPI = parseResult.getOpenAPI();

//responses
assertNotNull(openAPI.getComponents().getSchemas().get("Inline_response_items200"));
assertEquals(((ComposedSchema)openAPI.getComponents().getSchemas().get("Inline_response_items200")).getAnyOf().get(0).get$ref(),"#/components/schemas/Macaw");
assertNotNull(openAPI.getComponents().getSchemas().get("Inline_response_400"));
assertEquals(((ComposedSchema)openAPI.getComponents().getSchemas().get("Inline_response_400")).getAnyOf().get(0).get$ref(),"#/components/schemas/Macaw3");

//parameters
assertNotNull(openAPI.getComponents().getSchemas().get("Inline_parameter_items_bodylimit"));
assertEquals(((ComposedSchema)openAPI.getComponents().getSchemas().get("Inline_parameter_items_bodylimit")).getAnyOf().get(0).get$ref(),"#/components/schemas/Macaw1");
assertNotNull(openAPI.getComponents().getSchemas().get("Pagelimit"));
assertEquals(((ComposedSchema)openAPI.getComponents().getSchemas().get("Pagelimit")).getOneOf().get(0).get$ref(),"#/components/schemas/Macaw2");

//requestBodies
assertNotNull(openAPI.getComponents().getSchemas().get("Body"));
assertEquals(((ComposedSchema)openAPI.getComponents().getSchemas().get("Body")).getAllOf().get(1).get$ref(),"#/components/schemas/requestBodiesAllOf_2");
assertNotNull(openAPI.getComponents().getSchemas().get("Inline_response_items200"));
assertEquals(((ComposedSchema)openAPI.getComponents().getSchemas().get("Inline_body_items_applicationxml_requestBodies")).getAllOf().get(1).get$ref(),"#/components/schemas/ApplicationxmlAllOf_2");

//components
assertNotNull(openAPI.getComponents().getSchemas().get("Inline_array_items_ArrayTest"));
assertEquals(((ComposedSchema)openAPI.getComponents().getSchemas().get("Inline_array_items_ArrayTest")).getOneOf().get(1).get$ref(),"#/components/schemas/ArrayTestOneOf_2");
}


@Test
public void testCamelCaseFlattenNamingFalse() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -938,13 +938,10 @@ public void testInlineMapResponseWithObjectSchema() throws Exception {

ApiResponses apiResponses = new ApiResponses().addApiResponse("200",apiResponse);



openAPI.path("/foo/baz", new PathItem()
.get(new Operation()
.responses(apiResponses)));


new InlineModelResolver().flatten(openAPI);

ApiResponse response = openAPI.getPaths().get("/foo/baz").getGet().getResponses().get("200");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
openapi: 3.0.2
info:
title: test - OAS3
version: 1.0.0
paths:
"/parameters":
get:
description: ...
parameters:
- name: bodylimit
in: query
schema:
type: array
items:
anyOf:
- "$ref": "#/components/schemas/Macaw1"
- "$ref": "#/components/schemas/Parakeet1"
- name: pagelimit
in: query
schema:
oneOf:
- "$ref": "#/components/schemas/Macaw2"
- "$ref": "#/components/schemas/Parakeet2"
/responses:
get:
responses:
'200':
description: successful operation
content:
application/json:
schema:
type: array
items:
anyOf:
- "$ref": "#/components/schemas/Macaw"
- "$ref": "#/components/schemas/Parakeet"
'400':
description: successful operation
content:
application/json:
schema:
anyOf:
- "$ref": "#/components/schemas/Macaw3"
- "$ref": "#/components/schemas/Parakeet3"
/requestBodies:
post:
requestBody:
content:
"application/json":
schema:
type: object
allOf:
- $ref: '#/components/schemas/Address'
- type: object
required:
- gps
properties:
gps:
type: string
"application/xml":
schema:
type: array
items:
allOf:
- $ref: '#/components/schemas/Address2'
- type: object
required:
- gps2
properties:
gps2:
type: string
components:
schemas:
ArrayTest:
type: array
items:
oneOf:
- $ref: "#/components/schemas/Foo"
- type: object
properties:
foo:
type: string