Skip to content

Commit

Permalink
Fix set schema example null value
Browse files Browse the repository at this point in the history
  • Loading branch information
altro3 committed Sep 4, 2024
1 parent a011b63 commit 3c086ad
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public interface OpenApiModelProp {
String PROP_REF_DOLLAR = "$ref";
String PROP_HIDDEN = "hidden";
String PROP_EXAMPLE = "example";
String PROP_EXAMPLE_SET_FLAG = "exampleSetFlag";
String PROP_EXAMPLES = "examples";
String PROP_NOT = "not";
String PROP_ALL_OF = "allOf";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@
import io.swagger.v3.oas.models.PathItem;
import io.swagger.v3.oas.models.Paths;
import io.swagger.v3.oas.models.examples.Example;
import io.swagger.v3.oas.models.headers.Header;
import io.swagger.v3.oas.models.media.Content;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.media.StringSchema;
import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.oas.models.responses.ApiResponse;

Expand All @@ -43,6 +45,7 @@
import static io.micronaut.openapi.visitor.SchemaUtils.EMPTY_SIMPLE_SCHEMA;
import static io.micronaut.openapi.visitor.SchemaUtils.TYPE_OBJECT;
import static io.micronaut.openapi.visitor.SchemaUtils.TYPE_STRING;
import static io.micronaut.openapi.visitor.SchemaUtils.setSpecVersion;

/**
* Normalization methods for openAPI objects.
Expand Down Expand Up @@ -134,10 +137,37 @@ public static void normalizeOperation(Operation operation, VisitorContext contex
if (CollectionUtils.isNotEmpty(operation.getResponses())) {
for (ApiResponse apiResponse : operation.getResponses().values()) {
normalizeContent(apiResponse.getContent(), context);
normalizeHeaders(apiResponse.getHeaders(), context);
}
}
}

public static void normalizeHeaders(Map<String, Header> headers, VisitorContext context) {
if (CollectionUtils.isEmpty(headers)) {
return;
}

for (var header : headers.values()) {
Schema<?> headerSchema = header.getSchema();
if (headerSchema == null) {
headerSchema = setSpecVersion(new StringSchema());
header.setSchema(headerSchema);
}
Schema<?> normalizedSchema = normalizeSchema(headerSchema, context);
if (normalizedSchema != null) {
header.setSchema(normalizedSchema);
} else if (headerSchema.equals(EMPTY_SIMPLE_SCHEMA)) {
headerSchema.setType(TYPE_OBJECT);
}
if (header.getExample() != null
&& header.getExample() instanceof String exampleStr) {
header.setExample(ConvertUtils.parseByTypeAndFormat(exampleStr, header.getSchema().getType(), header.getSchema().getFormat(), context, false));
}
normalizeExamples(header.getExamples());
normalizeContent(header.getContent(), context);
}
}

public static void normalizeContent(Content content, VisitorContext context) {
if (CollectionUtils.isEmpty(content)) {
return;
Expand Down Expand Up @@ -233,9 +263,7 @@ public static Schema<?> normalizeSchema(Schema<?> schema, VisitorContext context
schema.setType(type);
schema.setAllOf(allOf);
schema.setDefault(defaultValue);
if (schema.getExample() == null) {
schema.setExampleSetFlag(false);
} else if (TYPE_STRING.equals(schema.getType()) && schema.getExample() instanceof String exampleStr) {
if (!TYPE_STRING.equals(schema.getType()) && schema.getExample() instanceof String exampleStr) {
schema.setExample(ConvertUtils.parseByTypeAndFormat(exampleStr, type, schema.getFormat(), context, false));
}
normalizeSchemaProperties(schema, context);
Expand Down Expand Up @@ -303,9 +331,7 @@ private static void normalizeSchemaProperties(Schema<?> schema, VisitorContext c

String type = schema.getType();

if (schema.getExample() == null) {
schema.setExampleSetFlag(false);
} else if (!TYPE_STRING.equals(type) && schema.getExample() instanceof String exampleStr) {
if (!TYPE_STRING.equals(type) && schema.getExample() instanceof String exampleStr) {
schema.setExample(ConvertUtils.parseByTypeAndFormat(exampleStr, type, schema.getFormat(), context, false));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@
import static io.micronaut.openapi.visitor.OpenApiModelProp.PROP_ENUM;
import static io.micronaut.openapi.visitor.OpenApiModelProp.PROP_EXAMPLE;
import static io.micronaut.openapi.visitor.OpenApiModelProp.PROP_EXAMPLES;
import static io.micronaut.openapi.visitor.OpenApiModelProp.PROP_EXAMPLE_SET_FLAG;
import static io.micronaut.openapi.visitor.OpenApiModelProp.PROP_EXPRESSION;
import static io.micronaut.openapi.visitor.OpenApiModelProp.PROP_EXTENSIONS;
import static io.micronaut.openapi.visitor.OpenApiModelProp.PROP_EXTERNAL_DOCS;
Expand Down Expand Up @@ -1327,6 +1328,9 @@ public static Map<CharSequence, Object> toValueMap(Map<CharSequence, Object> val
newValues.remove(PROP_WRITE_ONLY);
}
} else {
if (key.equals(PROP_EXAMPLE)) {
newValues.put(PROP_EXAMPLE_SET_FLAG, true);
}
var parsedJsonValue = parseJsonString(value);
newValues.put(key, parsedJsonValue != null ? parsedJsonValue : value);
}
Expand Down Expand Up @@ -2460,6 +2464,12 @@ private static Schema<?> doBindSchemaAnnotationValue(VisitorContext context, Typ
} catch (IOException e) {
warn("Error reading Swagger Schema for element [" + element + "]: " + e.getMessage(), context, element);
}
// fix for example = "null"
if (schemaToBind.getExample() == null
&& !schemaToBind.getExampleSetFlag()
&& schemaJson.get(PROP_EXAMPLE_SET_FLAG) != null) {
schemaToBind.setExampleSetFlag(true);
}

String defaultValue = null;
String[] allowableValues = null;
Expand Down Expand Up @@ -2572,7 +2582,7 @@ private static void schemaToValueMap(Map<CharSequence, Object> valueMap, Schema<
if (entry.getKey().equals("specVersion")) {
continue;
}
if (entry.getKey().equals("exampleSetFlag") && StringUtils.FALSE.equals(value.toString())) {
if (entry.getKey().equals(PROP_EXAMPLE_SET_FLAG) && StringUtils.FALSE.equals(value.toString())) {
continue;
}
valueMap.put(entry.getKey(), value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1189,4 +1189,49 @@ class MyBean {}
schemas.Car.properties.resourceType
schemas.Car.properties.selected
}

void "test example set null"() {

when:
buildBeanDefinition('test.MyBean', '''
package test;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Put;import io.swagger.v3.oas.annotations.media.Schema;import jakarta.validation.constraints.Pattern;
import java.util.List;
@Controller
class HelloController {
@Put("/sendModelWithDiscriminator")
Parent sendModelWithDiscriminator() {
return null;
}
}
class Parent {
@Schema(nullable = true, example = "null")
public Integer id;
}
@jakarta.inject.Singleton
class MyBean {}
''')
then: "the state is correct"
Utils.testReference != null

when: "The OpenAPI is retrieved"
def openApi = Utils.testReference
def schemas = openApi.components.schemas

then: "the components are valid"
schemas.Parent
schemas.Parent.properties.id
schemas.Parent.properties.id.type == 'integer'
schemas.Parent.properties.id.format == 'int32'
schemas.Parent.properties.id.nullable
schemas.Parent.properties.id.exampleSetFlag
schemas.Parent.properties.id.example == null
}
}

0 comments on commit 3c086ad

Please sign in to comment.