diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/filter/SpecFilter.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/filter/SpecFilter.java index f930ff9a64..7d2f00a211 100755 --- a/modules/swagger-core/src/main/java/io/swagger/v3/core/filter/SpecFilter.java +++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/filter/SpecFilter.java @@ -12,7 +12,6 @@ import io.swagger.v3.oas.models.callbacks.Callback; import io.swagger.v3.oas.models.headers.Header; import io.swagger.v3.oas.models.media.ArraySchema; -import io.swagger.v3.oas.models.media.ComposedSchema; import io.swagger.v3.oas.models.media.Content; import io.swagger.v3.oas.models.media.MediaType; import io.swagger.v3.oas.models.media.Schema; @@ -310,20 +309,23 @@ private void addSchemaRef(Schema schema, Set referencedDefinitions) { addSchemaRef(((ArraySchema) schema).getItems(), referencedDefinitions); } else if (schema.getTypes() != null && schema.getTypes().contains("array") && schema.getItems() != null) { addSchemaRef(schema.getItems(), referencedDefinitions); - } else if (schema instanceof ComposedSchema) { - ComposedSchema composedSchema = (ComposedSchema) schema; - if (composedSchema.getAllOf() != null) { - for (Schema ref : composedSchema.getAllOf()) { + } else { + List allOf = schema.getAllOf(); + List anyOf = schema.getAnyOf(); + List oneOf = schema.getOneOf(); + + if (allOf != null) { + for (Schema ref : allOf) { addSchemaRef(ref, referencedDefinitions); } } - if (composedSchema.getAnyOf() != null) { - for (Schema ref : composedSchema.getAnyOf()) { + if (anyOf != null) { + for (Schema ref : anyOf) { addSchemaRef(ref, referencedDefinitions); } } - if (composedSchema.getOneOf() != null) { - for (Schema ref : composedSchema.getOneOf()) { + if (oneOf != null) { + for (Schema ref : oneOf) { addSchemaRef(ref, referencedDefinitions); } } diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/filter/SpecFilterTest.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/filter/SpecFilterTest.java index 9ffb7c687e..f04c9b56e7 100644 --- a/modules/swagger-core/src/test/java/io/swagger/v3/core/filter/SpecFilterTest.java +++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/filter/SpecFilterTest.java @@ -47,6 +47,7 @@ public class SpecFilterTest { private static final String RESOURCE_PATH = "specFiles/petstore-3.0-v2.json"; private static final String RESOURCE_PATH_3303 = "specFiles/petstore-3.0-v2-ticket-3303.json"; private static final String RESOURCE_PATH_LIST = "specFiles/3.1.0/list-3.1.json"; + private static final String RESOURCE_PATH_COMPOSED_SCHEMA = "specFiles/3.1.0/composed-schema-3.1.json"; private static final String RESOURCE_REFERRED_SCHEMAS = "specFiles/petstore-3.0-referred-schemas.json"; private static final String RESOURCE_PATH_WITHOUT_MODELS = "specFiles/petstore-3.0-v2_withoutModels.json"; private static final String RESOURCE_DEPRECATED_OPERATIONS = "specFiles/deprecatedoperationmodel.json"; @@ -286,6 +287,18 @@ public void shouldRemoveBrokenNestedRefsKeepArray() throws IOException { assertTrue(filtered.getComponents().getSchemas().containsKey("SomeChildObject"), "Schemas should contains child list"); } + @Test + public void shouldRemoveBrokenNestedRefsKeepComposedSchemas() throws IOException { + final OpenAPI openAPI = getOpenAPI31(RESOURCE_PATH_COMPOSED_SCHEMA); + final RemoveUnreferencedDefinitionsFilter remover = new RemoveUnreferencedDefinitionsFilter(); + final OpenAPI filtered = new SpecFilter().filter(openAPI, remover, null, null, null); + + assertEquals(filtered.getComponents().getSchemas().size(), 4, "Expected to have parent and abstract child with both implementations schemas"); + assertTrue(filtered.getComponents().getSchemas().containsKey("SomeChild1ImplObject"), "Schemas should contains child 1 implementation"); + assertTrue(filtered.getComponents().getSchemas().containsKey("SomeChild2ImplObject"), "Schemas should contains child 2 implementation"); + assertTrue(filtered.getComponents().getSchemas().containsKey("SomeChildObject"), "Schemas should contains child abstract parent"); + } + @Test public void shouldNotRemoveGoodRefs() throws IOException { final OpenAPI openAPI = getOpenAPI(RESOURCE_PATH); diff --git a/modules/swagger-core/src/test/resources/specFiles/3.1.0/composed-schema-3.1.json b/modules/swagger-core/src/test/resources/specFiles/3.1.0/composed-schema-3.1.json new file mode 100644 index 0000000000..3fbe926a7e --- /dev/null +++ b/modules/swagger-core/src/test/resources/specFiles/3.1.0/composed-schema-3.1.json @@ -0,0 +1,85 @@ +{ + "components": { + "schemas": { + "SomeChild1ImplObject": { + "allOf": [ + { + "$ref": "#/components/schemas/SomeChildObject" + } + ] + }, + "SomeChild2ImplObject": { + "allOf": [ + { + "$ref": "#/components/schemas/SomeChildObject" + } + ] + }, + "SomeChildObject": { + "description": "Some child object" + }, + "SomeParentObject": { + "description": "Some parent object", + "properties": { + "id": { + "description": "id", + "format": "int64", + "type": "integer" + }, + "other": { + "description": "other", + "oneOf": [ + { + "$ref": "#/components/schemas/SomeChild1ImplObject" + }, + { + "$ref": "#/components/schemas/SomeChild2ImplObject" + } + ] + } + } + } + } + }, + "info": { + "title": "OpenAPI definition", + "version": "v0" + }, + "openapi": "3.1.0", + "paths": { + "/some/call": { + "get": { + "description": "Some operation description", + "operationId": "getSome", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SomeParentObject" + } + } + }, + "description": "OK" + } + }, + "summary": "Some summary", + "tags": [ + "Some" + ] + } + } + }, + "servers": [ + { + "description": "Generated server url", + "url": "http://localhost:8080" + } + ], + "tags": [ + { + "description": "some actions", + "name": "Some" + } + ] +} \ No newline at end of file