diff --git a/docs/customization.md b/docs/customization.md index 8cc1b4c57637..ffff0188e96d 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -644,6 +644,13 @@ Example: java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i modules/openapi-generator/src/test/resources/3_0/required-properties.yaml -o /tmp/java-okhttp/ --openapi-normalizer NORMALIZER_CLASS=org.openapitools.codegen.OpenAPINormalizerTest$RemoveRequiredNormalizer ``` +- `REMOVE_PROPERTIES_FROM_TYPE_OTHER_THAN_OBJECT`: When set to true, remove the "properties" of a schema with type other than "object". + +Example: +``` +java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i modules/openapi-generator/src/test/resources/3_0/required-properties.yaml -o /tmp/java-okhttp/ --openapi-normalizer REMOVE_PROPERTIES_FROM_TYPE_OTHER_THAN_OBJECT=true +``` + - `FILTER` The `FILTER` parameter allows selective inclusion of API operations based on specific criteria. It applies the `x-internal: true` property to operations that do **not** match the specified values, preventing them from being generated. Multiple filters can be separated by a semicolon. 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 42af855e3992..64ed0b624d11 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 @@ -124,6 +124,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"; @@ -206,6 +209,7 @@ public OpenAPINormalizer(OpenAPI openAPI, Map inputRules) { ruleNames.add(SET_CONTAINER_TO_NULLABLE); ruleNames.add(SET_PRIMITIVE_TYPES_TO_NULLABLE); ruleNames.add(SIMPLIFY_ONEOF_ANYOF_ENUM); + ruleNames.add(REMOVE_PROPERTIES_FROM_TYPE_OTHER_THAN_OBJECT); // rules that are default to true rules.put(SIMPLIFY_ONEOF_ANYOF, true); @@ -702,6 +706,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); @@ -1961,6 +1967,23 @@ private boolean hasOperationId(Operation operation) { private boolean hasMethod(String method) { return methodFilters.contains(method); } + } + /** + * 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 a2567b78606c..118001f798c4 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 @@ -26,6 +26,7 @@ import org.openapitools.codegen.utils.ModelUtils; import org.testng.annotations.Test; +import java.lang.reflect.Array; import java.util.*; import static org.testng.Assert.*; @@ -36,6 +37,26 @@ public class OpenAPINormalizerTest { private static final String X_PARENT = "x-parent"; private static final String X_INTERNAL = "x-internal"; + @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