add a rule to keep only the first tag (#14465)

This commit is contained in:
William Cheng
2023-01-20 15:50:31 +08:00
committed by GitHub
parent 4ecb9f4186
commit 5e7d31a83b
3 changed files with 113 additions and 1 deletions

View File

@@ -48,6 +48,10 @@ public class OpenAPINormalizer {
final String REF_AS_PARENT_IN_ALLOF = "REF_AS_PARENT_IN_ALLOF";
boolean enableRefAsParentInAllOf;
// when set to true, only keep the first tag in operation if there are more than one tag defined.
final String KEEP_ONLY_FIRST_TAG_IN_OPERATION = "KEEP_ONLY_FIRST_TAG_IN_OPERATION";
boolean enableKeepOnlyFirstTagInOperation;
// when set to true, complex composed schemas (a mix of oneOf/anyOf/anyOf and properties) with
// oneOf/anyOf containing only `required` and no properties (these are properties inter-dependency rules)
// are removed as most generators cannot handle such case at the moment
@@ -91,6 +95,10 @@ public class OpenAPINormalizer {
enableRefAsParentInAllOf = true;
}
if (enableAll || "true".equalsIgnoreCase(rules.get(KEEP_ONLY_FIRST_TAG_IN_OPERATION))) {
enableKeepOnlyFirstTagInOperation = true;
}
if (enableAll || "true".equalsIgnoreCase(rules.get(REMOVE_ANYOF_ONEOF_AND_KEEP_PROPERTIES_ONLY))) {
removeAnyOfOneOfAndKeepPropertiesOnly = true;
}
@@ -146,6 +154,7 @@ public class OpenAPINormalizer {
}
for (Operation operation : operations) {
normalizeOperation(operation);
normalizeRequestBody(operation);
normalizeParameters(operation);
normalizeResponses(operation);
@@ -153,6 +162,15 @@ public class OpenAPINormalizer {
}
}
/**
* Normalizes operation
*
* @param operation Operation
*/
private void normalizeOperation(Operation operation) {
processKeepOnlyFirstTagInOperation(operation);
}
/**
* Normalizes schemas in content
*
@@ -432,6 +450,25 @@ public class OpenAPINormalizer {
}
}
/**
* Keep only first tag in the operation if the operation has more than
* one tag.
*
* @param operation Operation
*/
private void processKeepOnlyFirstTagInOperation(Operation operation) {
if (!enableKeepOnlyFirstTagInOperation) {
return;
}
if (operation.getTags() != null && !operation.getTags().isEmpty() && operation.getTags().size() > 1) {
// has more than 1 tag
String firstTag = operation.getTags().get(0);
operation.setTags(null);
operation.addTagsItem(firstTag);
}
}
/**
* If the schema contains anyOf/oneOf and properties, remove oneOf/anyOf as these serve as rules to
* ensure inter-dependency between properties. It's a workaround as such validation is not supported at the moment.

View File

@@ -4326,6 +4326,23 @@ public class DefaultCodegenTest {
assertEquals(schema5.getExtensions().get("x-parent"), "abstract");
}
@Test
public void testOpenAPINormalizerEnableKeepOnlyFirstTagInOperation() {
OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/enableKeepOnlyFirstTagInOperation_test.yaml");
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getGet().getTags().size(), 2);
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getDelete().getTags().size(), 1);
Map<String, String> options = new HashMap<>();
options.put("KEEP_ONLY_FIRST_TAG_IN_OPERATION", "true");
OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options);
openAPINormalizer.normalize();
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getGet().getTags().size(), 1);
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getDelete().getTags().size(), 1);
assertEquals(openAPI.getPaths().get("/person/display/{personId}").getGet().getTags().get(0), "person");
}
@Test
public void testOpenAPINormalizerRemoveAnyOfOneOfAndKeepPropertiesOnly() {
// to test the rule REMOVE_ANYOF_ONEOF_AND_KEEP_PROPERTIIES_ONLY
@@ -4359,6 +4376,5 @@ public class DefaultCodegenTest {
Schema schema3 = openAPI.getComponents().getSchemas().get("AnyOfTest");
assertNull(schema3.getAnyOf());
assertTrue(schema3 instanceof StringSchema);
}
}

View File

@@ -0,0 +1,59 @@
openapi: 3.0.1
info:
version: 1.0.0
title: Example
license:
name: MIT
servers:
- url: http://api.example.xyz/v1
paths:
/person/display/{personId}:
get:
tags:
- person
- basic
parameters:
- name: personId
in: path
required: true
description: The id of the person to retrieve
schema:
type: string
operationId: list
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/Person"
delete:
tags:
- person
parameters:
- name: personId
in: path
required: true
description: The id of the person to retrieve
schema:
type: string
operationId: delete
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/Person"
components:
schemas:
Person:
description: person
type: object
properties:
$_type:
type: string
lastName:
type: string
firstName:
type: string