From 94729a9d8f0e179ee8de27130957da81d25a384c Mon Sep 17 00:00:00 2001 From: Michael Edgar Date: Tue, 2 Aug 2022 18:09:46 -0400 Subject: [PATCH] Parse `@Schema`'s defaultValue and enum entries for non-string schemas Fixes #1174 Signed-off-by: Michael Edgar --- .../runtime/io/schema/SchemaFactory.java | 47 +++++++++++++------ .../MethodTargetParametersResource.java | 9 +++- .../javax/MethodTargetParametersResource.java | 9 +++- .../scanner/params.method-target-nojaxrs.json | 42 ++++++++++++----- 4 files changed, 76 insertions(+), 31 deletions(-) diff --git a/core/src/main/java/io/smallrye/openapi/runtime/io/schema/SchemaFactory.java b/core/src/main/java/io/smallrye/openapi/runtime/io/schema/SchemaFactory.java index 66a927779..4b3f4ae23 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/io/schema/SchemaFactory.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/io/schema/SchemaFactory.java @@ -181,7 +181,8 @@ public static Schema readSchema(final AnnotationScannerContext context, schema.setDeprecated(readAttr(annotation, SchemaConstant.PROP_DEPRECATED, defaults)); schema.setType(readSchemaType(annotation, schema, defaults)); schema.setExample(parseSchemaAttr(context, annotation, SchemaConstant.PROP_EXAMPLE, defaults, schema.getType())); - schema.setDefaultValue(readAttr(annotation, SchemaConstant.PROP_DEFAULT_VALUE, defaults)); + schema.setDefaultValue( + parseSchemaAttr(context, annotation, SchemaConstant.PROP_DEFAULT_VALUE, defaults, schema.getType())); schema.setDiscriminator( readDiscriminator(context, JandexUtil.value(annotation, SchemaConstant.PROP_DISCRIMINATOR_PROPERTY), @@ -218,7 +219,22 @@ public static Schema readSchema(final AnnotationScannerContext context, } } - List enumeration = readAttr(annotation, SchemaConstant.PROP_ENUMERATION, defaults); + final Schema.SchemaType type = schema.getType(); + + List enumeration = readAttr(annotation, SchemaConstant.PROP_ENUMERATION, (Object[] values) -> { + List parsed = new ArrayList<>(values.length); + + if (type == Schema.SchemaType.STRING) { + parsed.addAll(Arrays.asList(values)); + } else { + Arrays.stream(values) + .map(String.class::cast) + .map(v -> parseValue(context, v, type)) + .forEach(parsed::add); + } + + return parsed; + }, defaults); if (enumeration != null && !enumeration.isEmpty()) { schema.setEnumeration(enumeration); @@ -323,21 +339,24 @@ static T readAttr(AnnotationInstance annotation, String propertyName, T defa static Object parseSchemaAttr(AnnotationScannerContext context, AnnotationInstance annotation, String propertyName, Map defaults, SchemaType schemaType) { return readAttr(annotation, propertyName, value -> { - if (!(value instanceof String)) { - return value; + if (value instanceof String) { + return parseValue(context, (String) value, schemaType); } - String stringValue = ((String) value); - if (schemaType != SchemaType.STRING) { - Object parsedValue; - for (AnnotationScannerExtension e : context.getExtensions()) { - parsedValue = e.parseValue(stringValue); - if (parsedValue != null) { - return parsedValue; - } + return value; + }, defaults); + } + + static Object parseValue(AnnotationScannerContext context, String stringValue, SchemaType schemaType) { + if (schemaType != SchemaType.STRING) { + Object parsedValue; + for (AnnotationScannerExtension e : context.getExtensions()) { + parsedValue = e.parseValue(stringValue); + if (parsedValue != null) { + return parsedValue; } } - return stringValue; - }, defaults); + } + return stringValue; } /** diff --git a/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/jakarta/MethodTargetParametersResource.java b/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/jakarta/MethodTargetParametersResource.java index 42a78e8ca..7beb31005 100644 --- a/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/jakarta/MethodTargetParametersResource.java +++ b/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/jakarta/MethodTargetParametersResource.java @@ -53,8 +53,13 @@ public static class PagedResponse { @Parameter(name = "filter:op[description]", in = ParameterIn.QUERY, description = "Operations used with the filter", schema = @Schema(type = SchemaType.STRING, enumeration = { "equal", "like", "ilike", "not_equal" }, defaultValue = "equal")), @Parameter(name = "filter[is_enabled]", in = ParameterIn.QUERY, description = "Filtering policies by the is_enabled field." - + "Defaults to true if no operand is given.", schema = @Schema(type = SchemaType.STRING, defaultValue = "true", enumeration = { - "true", "false" })) }) + + "Defaults to true if no operand is given.", schema = @Schema(type = SchemaType.BOOLEAN, defaultValue = "true", enumeration = { + "true", "false" })), + @Parameter(name = "X-Session-Info", in = ParameterIn.COOKIE, description = "Data about the session", schema = @Schema(type = SchemaType.OBJECT, enumeration = { + "{ \"status\": \"active\" }", + "{ \"status\": \"expired\" }" + })), + }) @APIResponse(responseCode = "400", description = "Bad parameter for sorting was passed") @APIResponse(responseCode = "404", description = "No policies found for customer") @APIResponse(responseCode = "403", description = "Individual permissions missing to complete action") diff --git a/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/javax/MethodTargetParametersResource.java b/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/javax/MethodTargetParametersResource.java index af2928332..27d5dee47 100644 --- a/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/javax/MethodTargetParametersResource.java +++ b/extension-jaxrs/src/test/java/test/io/smallrye/openapi/runtime/scanner/javax/MethodTargetParametersResource.java @@ -53,8 +53,13 @@ public static class PagedResponse { @Parameter(name = "filter:op[description]", in = ParameterIn.QUERY, description = "Operations used with the filter", schema = @Schema(type = SchemaType.STRING, enumeration = { "equal", "like", "ilike", "not_equal" }, defaultValue = "equal")), @Parameter(name = "filter[is_enabled]", in = ParameterIn.QUERY, description = "Filtering policies by the is_enabled field." - + "Defaults to true if no operand is given.", schema = @Schema(type = SchemaType.STRING, defaultValue = "true", enumeration = { - "true", "false" })) }) + + "Defaults to true if no operand is given.", schema = @Schema(type = SchemaType.BOOLEAN, defaultValue = "true", enumeration = { + "true", "false" })), + @Parameter(name = "X-Session-Info", in = ParameterIn.COOKIE, description = "Data about the session", schema = @Schema(type = SchemaType.OBJECT, enumeration = { + "{ \"status\": \"active\" }", + "{ \"status\": \"expired\" }" + })), + }) @APIResponse(responseCode = "400", description = "Bad parameter for sorting was passed") @APIResponse(responseCode = "404", description = "No policies found for customer") @APIResponse(responseCode = "403", description = "Individual permissions missing to complete action") diff --git a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.method-target-nojaxrs.json b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.method-target-nojaxrs.json index 37d90fcd6..5fcfcc4ee 100644 --- a/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.method-target-nojaxrs.json +++ b/extension-jaxrs/src/test/resources/io/smallrye/openapi/runtime/scanner/params.method-target-nojaxrs.json @@ -48,12 +48,12 @@ "in": "query", "description": "Filtering policies by the is_enabled field.Defaults to true if no operand is given.", "schema": { - "default": "true", + "default": true, "enum": [ - "true", - "false" + true, + false ], - "type": "string" + "type": "boolean" } }, { @@ -105,6 +105,22 @@ ], "type": "string" } + }, + { + "name": "X-Session-Info", + "in": "cookie", + "description": "Data about the session", + "schema": { + "enum": [ + { + "status": "active" + }, + { + "status": "expired" + } + ], + "type": "object" + } } ], "responses": { @@ -145,10 +161,11 @@ "PagedResponse": { "type": "object", "properties": { - "data": { - "type": "array", - "items": { - "type": "object" + "meta": { + "type": "object", + "additionalProperties": { + "format": "int64", + "type": "integer" } }, "links": { @@ -157,11 +174,10 @@ "type": "string" } }, - "meta": { - "type": "object", - "additionalProperties": { - "format": "int64", - "type": "integer" + "data": { + "type": "array", + "items": { + "type": "object" } } }