diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/InlineModelResolver.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/InlineModelResolver.java index aa32789d1b25..777fed9b2cb4 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/InlineModelResolver.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/InlineModelResolver.java @@ -356,7 +356,9 @@ private void gatherInlineModels(Schema schema, String modelPrefix) { } else if (schema.getProperties() != null) { // If non-object type is specified but also properties LOGGER.error("Illegal schema found with non-object type combined with properties," + - " no properties should be defined:\n " + schema.toString()); + " no properties should be defined:" + + " consider using --openapi-normalizer REMOVE_PROPERTIES_FROM_TYPE_OTHER_THAN_OBJECT=true\n " + + schema.toString()); return; } else if (schema.getAdditionalProperties() != null) { // If non-object type is specified but also additionalProperties diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java index 7a95434248a5..f7b9a96fd492 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java @@ -119,6 +119,9 @@ public class OpenAPINormalizer { // the allOf contains a new schema containing the properties in the top level final String REFACTOR_ALLOF_WITH_PROPERTIES_ONLY = "REFACTOR_ALLOF_WITH_PROPERTIES_ONLY"; + // when set to true, remove the "properties" of a schema with type other than "object" + final String REMOVE_PROPERTIES_FROM_TYPE_OTHER_THAN_OBJECT = "REMOVE_PROPERTIES_FROM_TYPE_OTHER_THAN_OBJECT"; + // when set to true, normalize OpenAPI 3.1 spec to make it work with the generator final String NORMALIZE_31SPEC = "NORMALIZE_31SPEC"; @@ -205,6 +208,7 @@ public OpenAPINormalizer(OpenAPI openAPI, Map inputRules) { ruleNames.add(FILTER); ruleNames.add(SET_CONTAINER_TO_NULLABLE); ruleNames.add(SET_PRIMITIVE_TYPES_TO_NULLABLE); + ruleNames.add(REMOVE_PROPERTIES_FROM_TYPE_OTHER_THAN_OBJECT); // rules that are default to true @@ -721,6 +725,8 @@ public Schema normalizeSchema(Schema schema, Set visitedSchemas) { } markSchemaAsVisited(schema, visitedSchemas); + processNormalizeOtherThanObjectWithProperties(schema); + if (ModelUtils.isArraySchema(schema)) { // array Schema result = normalizeArraySchema(schema); normalizeSchema(result.getItems(), visitedSchemas); @@ -1644,5 +1650,21 @@ protected Schema processNormalize31Spec(Schema schema, Set visitedSchema return schema; } - // ===================== end of rules ===================== + /** + * When set to true, remove "properties" attribute on schema other than "object" + * since it should be ignored and may result in odd generated code + * + * @param schema Schema + * @return Schema + */ + protected void processNormalizeOtherThanObjectWithProperties(Schema schema) { + if (getRule(REMOVE_PROPERTIES_FROM_TYPE_OTHER_THAN_OBJECT)) { + // Check object models / any type models / composed models for properties, + // if the schema has a type defined that is not "object" it should not define + // any properties + if (schema.getType() != null && !"object".equals(schema.getType())) { + schema.setProperties(null); + } + } + } } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java index 1d41104f8dc0..e281539b86c7 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java @@ -24,11 +24,33 @@ import org.openapitools.codegen.utils.ModelUtils; import org.testng.annotations.Test; +import java.lang.reflect.Array; import java.util.*; import static org.testng.Assert.*; public class OpenAPINormalizerTest { + + @Test + public void testOpenAPINormalizerOtherThanObjectWithProperties() + { + // to test the rule REF_AS_PARENT_IN_ALLOF + OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/issue_21680_array_with_properties.yaml"); + + Schema schema = openAPI.getComponents().getSchemas().get("errors"); + assertNotNull(schema); + assertNotNull(schema.getProperties()); + + Map options = new HashMap<>(); + options.put("REMOVE_PROPERTIES_FROM_TYPE_OTHER_THAN_OBJECT", "true"); + OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options); + openAPINormalizer.normalize(); + + Schema schema2 = openAPI.getComponents().getSchemas().get("errors"); + assertNotNull(schema2); + assertNull(schema2.getProperties()); + } + @Test public void testOpenAPINormalizerRefAsParentInAllOf() { // to test the rule REF_AS_PARENT_IN_ALLOF diff --git a/modules/openapi-generator/src/test/resources/3_0/issue_21680_array_with_properties.yaml b/modules/openapi-generator/src/test/resources/3_0/issue_21680_array_with_properties.yaml new file mode 100644 index 000000000000..829fabd44713 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/issue_21680_array_with_properties.yaml @@ -0,0 +1,48 @@ +--- +# Corresponds to bug report 21680: https://github.com/openapitools/openapi-generator/issues/21680 +openapi: 3.0.1 +info: + title: API that has problem with OpenAPI Generator + version: 1.0.0 +paths: + "/forbiddenaccesscsrf": + get: + summary: Forbidden access CSRF + operationId: forbiddenAccessCsrfGet + responses: + '403': + description: Expected response + content: + application/json: + schema: + "$ref": "#/components/schemas/errors" +components: + schemas: + error: + required: + - code + - horodatage + - message + type: object + properties: + code: + type: string + description: Short error description + message: + type: string + description: Complete human readable description + error_uri: + type: string + description: Detailed error description URI + format: uri + horodatage: + type: string + description: Date time of occurence + format: date-time + errors: + type: array + properties: + empty: + type: boolean + items: + "$ref": "#/components/schemas/error" \ No newline at end of file