Skip to content

Commit

Permalink
fix: ExampleGenerator correctly generates allOf composed schemas
Browse files Browse the repository at this point in the history
Changes the previous behavior of generating `null` examples for allOf composed schemas.

Fixes #17497
  • Loading branch information
acouvreur committed Jan 5, 2024
1 parent a5d3fb4 commit 4c1fb82
Show file tree
Hide file tree
Showing 26 changed files with 164 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -351,9 +351,21 @@ private Object resolveModelToExample(String name, String mediaType, Schema schem
return schema.getExample();
} else if (schema.getProperties() != null) {
LOGGER.debug("Creating example from model values");
for (Object propertyName : schema.getProperties().keySet()) {
Schema property = (Schema) schema.getProperties().get(propertyName.toString());
values.put(propertyName.toString(), resolvePropertyToExample(propertyName.toString(), mediaType, property, processedModels));
traverseSchemaProperties(mediaType, schema, processedModels, values);
schema.setExample(values);
return schema.getExample();
} else if (ModelUtils.isAllOf(schema) || ModelUtils.isAllOfWithProperties(schema)) {
LOGGER.debug("Resolving allOf model '{}' to example", name);
List<Schema> interfaces = schema.getAllOf();
for (Schema composed : interfaces) {
traverseSchemaProperties(mediaType, composed, processedModels, values);
if (composed.get$ref() != null) {
String ref = ModelUtils.getSimpleRef(composed.get$ref());
Schema resolved = ModelUtils.getSchema(openAPI, ref);
if (resolved != null) {
traverseSchemaProperties(mediaType, resolved, processedModels, values);
}
}
}
schema.setExample(values);
return schema.getExample();
Expand All @@ -362,4 +374,13 @@ private Object resolveModelToExample(String name, String mediaType, Schema schem
return null;
}
}

private void traverseSchemaProperties(String mediaType, Schema schema, Set<String> processedModels, Map<String, Object> values) {
if (schema.getProperties() != null) {
for (Object propertyName : schema.getProperties().keySet()) {
Schema property = (Schema) schema.getProperties().get(propertyName.toString());
values.put(propertyName.toString(), resolvePropertyToExample(propertyName.toString(), mediaType, property, processedModels));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -151,4 +151,33 @@ public void generateFromResponseSchemaWithModel() {
assertEquals(String.format(Locale.ROOT, "{%n \"example_schema_property\" : \"example schema property value\"%n}"), examples.get(0).get("example"));
assertEquals("200", examples.get(0).get("statusCode"));
}

@Test
public void generateFromResponseSchemaWithAllOfComposedModel() {
OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/example_generator_test.yaml");

new InlineModelResolver().flatten(openAPI);

ExampleGenerator exampleGenerator = new ExampleGenerator(openAPI.getComponents().getSchemas(), openAPI);
Set<String> mediaTypeKeys = new TreeSet<>();
mediaTypeKeys.add("application/json");
List<Map<String, String>> examples = exampleGenerator.generateFromResponseSchema(
"200",
openAPI
.getPaths()
.get("/generate_from_response_schema_with_allOf_composed_model")
.getGet()
.getResponses()
.get("200")
.getContent()
.get("application/json")
.getSchema(),
mediaTypeKeys
);

assertEquals(1, examples.size());
assertEquals("application/json", examples.get(0).get("contentType"));
assertEquals(String.format(Locale.ROOT, "{%n \"example_schema_property_composed\" : \"example schema property value composed\",%n \"example_schema_property\" : \"example schema property value\"%n}"), examples.get(0).get("example"));
assertEquals("200", examples.get(0).get("statusCode"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,24 @@ paths:
example: primitive types example value
/generate_from_response_schema_with_model:
get:
operationId: generateFromResponseSchemaWithArrayOfPrimitiveTypes
operationId: generateFromResponseSchemaWithModel
responses:
'200':
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/ExampleSchema'
/generate_from_response_schema_with_allOf_composed_model:
get:
operationId: generateFromResponseSchemaWithComposedModel
responses:
'200':
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/ExampleComposedSchema'
components:
schemas:
StringSchema:
Expand All @@ -72,3 +82,12 @@ components:
example_schema_property:
type: string
example: example schema property value
ExampleComposedSchema:
type: object
allOf:
- $ref: '#/components/schemas/ExampleSchema'
- type: object
properties:
example_schema_property_composed:
type: string
example: example schema property value composed
Original file line number Diff line number Diff line change
Expand Up @@ -1919,6 +1919,10 @@ components:
otherProperty:
type: string
type: object
example:
otherProperty: otherProperty
nullableProperty: nullableProperty
type: ChildWithNullable
StringBooleanMap:
additionalProperties:
type: boolean
Expand Down
4 changes: 4 additions & 0 deletions samples/client/petstore/java/feign/api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1919,6 +1919,10 @@ components:
otherProperty:
type: string
type: object
example:
otherProperty: otherProperty
nullableProperty: nullableProperty
type: ChildWithNullable
StringBooleanMap:
additionalProperties:
type: boolean
Expand Down
4 changes: 4 additions & 0 deletions samples/client/petstore/java/resteasy/api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1919,6 +1919,10 @@ components:
otherProperty:
type: string
type: object
example:
otherProperty: otherProperty
nullableProperty: nullableProperty
type: ChildWithNullable
StringBooleanMap:
additionalProperties:
type: boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1919,6 +1919,10 @@ components:
otherProperty:
type: string
type: object
example:
otherProperty: otherProperty
nullableProperty: nullableProperty
type: ChildWithNullable
StringBooleanMap:
additionalProperties:
type: boolean
Expand Down
4 changes: 4 additions & 0 deletions samples/client/petstore/java/resttemplate/api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1919,6 +1919,10 @@ components:
otherProperty:
type: string
type: object
example:
otherProperty: otherProperty
nullableProperty: nullableProperty
type: ChildWithNullable
StringBooleanMap:
additionalProperties:
type: boolean
Expand Down
4 changes: 4 additions & 0 deletions samples/client/petstore/java/vertx/api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1919,6 +1919,10 @@ components:
otherProperty:
type: string
type: object
example:
otherProperty: otherProperty
nullableProperty: nullableProperty
type: ChildWithNullable
StringBooleanMap:
additionalProperties:
type: boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1919,6 +1919,10 @@ components:
otherProperty:
type: string
type: object
example:
otherProperty: otherProperty
nullableProperty: nullableProperty
type: ChildWithNullable
StringBooleanMap:
additionalProperties:
type: boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1919,6 +1919,10 @@ components:
otherProperty:
type: string
type: object
example:
otherProperty: otherProperty
nullableProperty: nullableProperty
type: ChildWithNullable
StringBooleanMap:
additionalProperties:
type: boolean
Expand Down
4 changes: 4 additions & 0 deletions samples/client/petstore/java/webclient/api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1919,6 +1919,10 @@ components:
otherProperty:
type: string
type: object
example:
otherProperty: otherProperty
nullableProperty: nullableProperty
type: ChildWithNullable
StringBooleanMap:
additionalProperties:
type: boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,7 @@ components:
\ characters. The sanitization rules should make it possible to generate a\
\ language-specific classname with allowed characters in that programming\
\ language."
example:
prop2: prop2
objectType: objectType

Original file line number Diff line number Diff line change
Expand Up @@ -1902,6 +1902,10 @@ components:
otherProperty:
type: string
type: object
example:
otherProperty: otherProperty
nullableProperty: nullableProperty
type: ChildWithNullable
StringBooleanMap:
additionalProperties:
type: boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1902,6 +1902,10 @@ components:
otherProperty:
type: string
type: object
example:
otherProperty: otherProperty
nullableProperty: nullableProperty
type: ChildWithNullable
StringBooleanMap:
additionalProperties:
type: boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1919,6 +1919,10 @@ components:
otherProperty:
type: string
type: object
example:
otherProperty: otherProperty
nullableProperty: nullableProperty
type: ChildWithNullable
StringBooleanMap:
additionalProperties:
type: boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1919,6 +1919,10 @@ components:
otherProperty:
type: string
type: object
example:
otherProperty: otherProperty
nullableProperty: nullableProperty
type: ChildWithNullable
StringBooleanMap:
additionalProperties:
type: boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1902,6 +1902,10 @@ components:
otherProperty:
type: string
type: object
example:
otherProperty: otherProperty
nullableProperty: nullableProperty
type: ChildWithNullable
StringBooleanMap:
additionalProperties:
type: boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1902,6 +1902,10 @@ components:
otherProperty:
type: string
type: object
example:
otherProperty: otherProperty
nullableProperty: nullableProperty
type: ChildWithNullable
StringBooleanMap:
additionalProperties:
type: boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1902,6 +1902,10 @@ components:
otherProperty:
type: string
type: object
example:
otherProperty: otherProperty
nullableProperty: nullableProperty
type: ChildWithNullable
StringBooleanMap:
additionalProperties:
type: boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1902,6 +1902,10 @@ components:
otherProperty:
type: string
type: object
example:
otherProperty: otherProperty
nullableProperty: nullableProperty
type: ChildWithNullable
StringBooleanMap:
additionalProperties:
type: boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1902,6 +1902,10 @@ components:
otherProperty:
type: string
type: object
example:
otherProperty: otherProperty
nullableProperty: nullableProperty
type: ChildWithNullable
StringBooleanMap:
additionalProperties:
type: boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1902,6 +1902,10 @@ components:
otherProperty:
type: string
type: object
example:
otherProperty: otherProperty
nullableProperty: nullableProperty
type: ChildWithNullable
StringBooleanMap:
additionalProperties:
type: boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1902,6 +1902,10 @@ components:
otherProperty:
type: string
type: object
example:
otherProperty: otherProperty
nullableProperty: nullableProperty
type: ChildWithNullable
StringBooleanMap:
additionalProperties:
type: boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1902,6 +1902,10 @@ components:
otherProperty:
type: string
type: object
example:
otherProperty: otherProperty
nullableProperty: nullableProperty
type: ChildWithNullable
StringBooleanMap:
additionalProperties:
type: boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1902,6 +1902,10 @@ components:
otherProperty:
type: string
type: object
example:
otherProperty: otherProperty
nullableProperty: nullableProperty
type: ChildWithNullable
StringBooleanMap:
additionalProperties:
type: boolean
Expand Down

0 comments on commit 4c1fb82

Please sign in to comment.