forked from loafle/openapi-generator-original
Fix anyOf/oneOf normalization for 3.1 spec (#19758)
* fix anyOf/oneOf normalization for 3.1 spec * update samples
This commit is contained in:
parent
fad33dfebf
commit
2111713117
@ -516,7 +516,7 @@ public class OpenAPINormalizer {
|
|||||||
return schema;
|
return schema;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((visitedSchemas.contains(schema))) {
|
if (visitedSchemas.contains(schema)) {
|
||||||
return schema; // skip due to circular reference
|
return schema; // skip due to circular reference
|
||||||
} else {
|
} else {
|
||||||
visitedSchemas.add(schema);
|
visitedSchemas.add(schema);
|
||||||
@ -535,7 +535,6 @@ public class OpenAPINormalizer {
|
|||||||
return normalizeAnyOf(schema, visitedSchemas);
|
return normalizeAnyOf(schema, visitedSchemas);
|
||||||
} else if (ModelUtils.isAllOfWithProperties(schema)) { // allOf with properties
|
} else if (ModelUtils.isAllOfWithProperties(schema)) { // allOf with properties
|
||||||
schema = normalizeAllOfWithProperties(schema, visitedSchemas);
|
schema = normalizeAllOfWithProperties(schema, visitedSchemas);
|
||||||
normalizeSchema(schema, visitedSchemas);
|
|
||||||
} else if (ModelUtils.isAllOf(schema)) { // allOf
|
} else if (ModelUtils.isAllOf(schema)) { // allOf
|
||||||
return normalizeAllOf(schema, visitedSchemas);
|
return normalizeAllOf(schema, visitedSchemas);
|
||||||
} else if (ModelUtils.isComposedSchema(schema)) { // composed schema
|
} else if (ModelUtils.isComposedSchema(schema)) { // composed schema
|
||||||
@ -643,15 +642,19 @@ public class OpenAPINormalizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Schema normalizeOneOf(Schema schema, Set<Schema> visitedSchemas) {
|
private Schema normalizeOneOf(Schema schema, Set<Schema> visitedSchemas) {
|
||||||
for (Object item : schema.getOneOf()) {
|
for (int i = 0; i < schema.getOneOf().size(); i++) {
|
||||||
|
// normalize oneOf sub schemas one by one
|
||||||
|
Object item = schema.getOneOf().get(i);
|
||||||
|
|
||||||
if (item == null) {
|
if (item == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!(item instanceof Schema)) {
|
if (!(item instanceof Schema)) {
|
||||||
throw new RuntimeException("Error! oneOf schema is not of the type Schema: " + item);
|
throw new RuntimeException("Error! oneOf schema is not of the type Schema: " + item);
|
||||||
}
|
}
|
||||||
// normalize oenOf sub schemas one by one
|
|
||||||
normalizeSchema((Schema) item, visitedSchemas);
|
// update sub-schema with the updated schema
|
||||||
|
schema.getOneOf().set(i, normalizeSchema((Schema) item, visitedSchemas));
|
||||||
}
|
}
|
||||||
// process rules here
|
// process rules here
|
||||||
schema = processSimplifyOneOf(schema);
|
schema = processSimplifyOneOf(schema);
|
||||||
@ -660,7 +663,10 @@ public class OpenAPINormalizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Schema normalizeAnyOf(Schema schema, Set<Schema> visitedSchemas) {
|
private Schema normalizeAnyOf(Schema schema, Set<Schema> visitedSchemas) {
|
||||||
for (Object item : schema.getAnyOf()) {
|
for (int i = 0; i < schema.getAnyOf().size(); i++) {
|
||||||
|
// normalize anyOf sub schemas one by one
|
||||||
|
Object item = schema.getAnyOf().get(i);
|
||||||
|
|
||||||
if (item == null) {
|
if (item == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -668,8 +674,9 @@ public class OpenAPINormalizer {
|
|||||||
if (!(item instanceof Schema)) {
|
if (!(item instanceof Schema)) {
|
||||||
throw new RuntimeException("Error! anyOf schema is not of the type Schema: " + item);
|
throw new RuntimeException("Error! anyOf schema is not of the type Schema: " + item);
|
||||||
}
|
}
|
||||||
// normalize anyOf sub schemas one by one
|
|
||||||
normalizeSchema((Schema) item, visitedSchemas);
|
// update sub-schema with the updated schema
|
||||||
|
schema.getAnyOf().set(i, normalizeSchema((Schema) item, visitedSchemas));
|
||||||
}
|
}
|
||||||
|
|
||||||
// process rules here
|
// process rules here
|
||||||
|
@ -600,7 +600,9 @@ public class ModelUtils {
|
|||||||
Schema<?> items = schema.getItems();
|
Schema<?> items = schema.getItems();
|
||||||
if (items == null) {
|
if (items == null) {
|
||||||
if (schema instanceof JsonSchema) { // 3.1 spec
|
if (schema instanceof JsonSchema) { // 3.1 spec
|
||||||
// do nothing as the schema may contain prefixItems only
|
// set the items to a new schema (any type)
|
||||||
|
items = new Schema<>();
|
||||||
|
schema.setItems(items);
|
||||||
} else { // 3.0 spec, default to string
|
} else { // 3.0 spec, default to string
|
||||||
LOGGER.error("Undefined array inner type for `{}`. Default to String.", schema.getName());
|
LOGGER.error("Undefined array inner type for `{}`. Default to String.", schema.getName());
|
||||||
items = new StringSchema().description("TODO default missing array inner type to string");
|
items = new StringSchema().description("TODO default missing array inner type to string");
|
||||||
|
@ -605,6 +605,16 @@ public class OpenAPINormalizerTest {
|
|||||||
assertNotEquals(((Schema) schema7.getProperties().get("with_prefixitems")).getPrefixItems(), null);
|
assertNotEquals(((Schema) schema7.getProperties().get("with_prefixitems")).getPrefixItems(), null);
|
||||||
assertEquals(((Schema) schema7.getProperties().get("without_items")).getItems(), null);
|
assertEquals(((Schema) schema7.getProperties().get("without_items")).getItems(), null);
|
||||||
|
|
||||||
|
Schema schema9 = openAPI.getComponents().getSchemas().get("AnyOfArrayWithPrefixItems");
|
||||||
|
assertEquals(((Schema) schema9.getAnyOf().get(0)).getItems(), null);
|
||||||
|
assertNotEquals(((Schema) schema9.getAnyOf().get(0)).getPrefixItems(), null);
|
||||||
|
assertEquals(((Schema) schema9.getAnyOf().get(1)).getItems(), null);
|
||||||
|
|
||||||
|
Schema schema11 = openAPI.getComponents().getSchemas().get("OneOfArrayWithPrefixItems");
|
||||||
|
assertEquals(((Schema) schema11.getOneOf().get(0)).getItems(), null);
|
||||||
|
assertNotEquals(((Schema) schema11.getOneOf().get(0)).getPrefixItems(), null);
|
||||||
|
assertEquals(((Schema) schema11.getOneOf().get(1)).getItems(), null);
|
||||||
|
|
||||||
Map<String, String> inputRules = Map.of("NORMALIZE_31SPEC", "true");
|
Map<String, String> inputRules = Map.of("NORMALIZE_31SPEC", "true");
|
||||||
OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, inputRules);
|
OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, inputRules);
|
||||||
openAPINormalizer.normalize();
|
openAPINormalizer.normalize();
|
||||||
@ -632,6 +642,16 @@ public class OpenAPINormalizerTest {
|
|||||||
assertNotEquals(((Schema) schema8.getProperties().get("with_prefixitems")).getItems(), null);
|
assertNotEquals(((Schema) schema8.getProperties().get("with_prefixitems")).getItems(), null);
|
||||||
assertEquals(((Schema) schema8.getProperties().get("with_prefixitems")).getPrefixItems(), null);
|
assertEquals(((Schema) schema8.getProperties().get("with_prefixitems")).getPrefixItems(), null);
|
||||||
assertNotEquals(((Schema) schema8.getProperties().get("without_items")).getItems(), null);
|
assertNotEquals(((Schema) schema8.getProperties().get("without_items")).getItems(), null);
|
||||||
|
|
||||||
|
Schema schema10 = openAPI.getComponents().getSchemas().get("AnyOfArrayWithPrefixItems");
|
||||||
|
assertNotEquals(((Schema) schema10.getAnyOf().get(0)).getItems(), null);
|
||||||
|
assertEquals(((Schema) schema10.getAnyOf().get(0)).getPrefixItems(), null);
|
||||||
|
assertNotEquals(((Schema) schema10.getAnyOf().get(1)).getItems(), null);
|
||||||
|
|
||||||
|
Schema schema12 = openAPI.getComponents().getSchemas().get("OneOfArrayWithPrefixItems");
|
||||||
|
assertNotEquals(((Schema) schema12.getOneOf().get(0)).getItems(), null);
|
||||||
|
assertEquals(((Schema) schema12.getOneOf().get(0)).getPrefixItems(), null);
|
||||||
|
assertNotEquals(((Schema) schema12.getOneOf().get(1)).getItems(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -461,4 +461,12 @@ public class ModelUtilsTest {
|
|||||||
Assert.assertEquals(deepCopy, schema);
|
Assert.assertEquals(deepCopy, schema);
|
||||||
Assert.assertNotSame(deepCopy, schema);
|
Assert.assertNotSame(deepCopy, schema);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetSchemaItemsWith31Spec() {
|
||||||
|
OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_1/issue_18291.yaml");
|
||||||
|
Schema arrayWithPrefixItems = ModelUtils.getSchema(openAPI, "ArrayWithPrefixItems");
|
||||||
|
Assert.assertNotNull(ModelUtils.getSchemaItems((Schema) arrayWithPrefixItems.getProperties().get("with_prefixitems")));
|
||||||
|
Assert.assertNotNull(ModelUtils.getSchemaItems((Schema) arrayWithPrefixItems.getProperties().get("without_items")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,3 +47,23 @@ components:
|
|||||||
minItems: 2
|
minItems: 2
|
||||||
without_items:
|
without_items:
|
||||||
type: array
|
type: array
|
||||||
|
AnyOfArrayWithPrefixItems:
|
||||||
|
anyOf:
|
||||||
|
- type: array
|
||||||
|
prefixItems:
|
||||||
|
- type: number
|
||||||
|
title: Longitude
|
||||||
|
- type: number
|
||||||
|
title: Latitude
|
||||||
|
maxItems: 2
|
||||||
|
minItems: 2
|
||||||
|
- type: array
|
||||||
|
OneOfArrayWithPrefixItems:
|
||||||
|
oneOf:
|
||||||
|
- type: array
|
||||||
|
prefixItems:
|
||||||
|
- type: integer
|
||||||
|
- type: integer
|
||||||
|
maxItems: 3
|
||||||
|
minItems: 3
|
||||||
|
- type: array
|
@ -815,6 +815,7 @@ paths:
|
|||||||
items:
|
items:
|
||||||
$ref: '#/components/schemas/myObject'
|
$ref: '#/components/schemas/myObject'
|
||||||
nullable: true
|
nullable: true
|
||||||
|
type: array
|
||||||
description: ""
|
description: ""
|
||||||
tags:
|
tags:
|
||||||
- fake
|
- fake
|
||||||
@ -1185,6 +1186,7 @@ components:
|
|||||||
- type: string
|
- type: string
|
||||||
- items:
|
- items:
|
||||||
type: string
|
type: string
|
||||||
|
type: array
|
||||||
securitySchemes:
|
securitySchemes:
|
||||||
petstore_auth:
|
petstore_auth:
|
||||||
flows:
|
flows:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user