From b0c9456addea6c2d7821a5450f2d73624a00c9d0 Mon Sep 17 00:00:00 2001 From: William Cheng Date: Thu, 15 Feb 2024 13:05:31 +0800 Subject: [PATCH] add FILTER to openapi normalizer (#17859) --- docs/customization.md | 7 +++++ .../codegen/OpenAPINormalizer.java | 31 ++++++++++++++++++- .../codegen/OpenAPINormalizerTest.java | 18 +++++++++++ ...nableKeepOnlyFirstTagInOperation_test.yaml | 19 ++++++++++++ 4 files changed, 74 insertions(+), 1 deletion(-) diff --git a/docs/customization.md b/docs/customization.md index 8e85645773..a4cbb12fce 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -584,3 +584,10 @@ Example: ``` java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i modules/openapi-generator/src/test/resources/3_0/enableKeepOnlyFirstTagInOperation_test.yaml -o /tmp/java-okhttp/ --openapi-normalizer REMOVE_X_INTERNAL=true ``` + +- `FILTER`: When set to `operationId:addPet|getPetById` for example, it will add `x-internal:true` to operations with operationId not equal to addPet/getPetById (which will have x-internal set to false) so that these operations marked as internal won't be generated. + +Example: +``` +java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i modules/openapi-generator/src/test/resources/3_0/petstore.yaml -o /tmp/java-okhttp/ --openapi-normalizer FILTER="operationId:addPet|getPetById" +``` diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java index 61ea6c2f73..ffc5235ea1 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java @@ -101,6 +101,10 @@ public class OpenAPINormalizer { final String X_INTERNAL = "x-internal"; boolean removeXInternal; + // when set (e.g. operationId:getPetById, addPet), filter out (or remove) everything else + final String FILTER = "FILTER"; + HashSet operationIdFilters = new HashSet<>(); + // ============= end of rules ============= /** @@ -131,6 +135,7 @@ public class OpenAPINormalizer { ruleNames.add(REFACTOR_ALLOF_WITH_PROPERTIES_ONLY); ruleNames.add(NORMALIZE_31SPEC); ruleNames.add(REMOVE_X_INTERNAL); + ruleNames.add(FILTER); // rules that are default to true rules.put(SIMPLIFY_ONEOF_ANYOF, true); @@ -166,7 +171,7 @@ public class OpenAPINormalizer { for (Map.Entry rule : inputRules.entrySet()) { LOGGER.debug("processing rule {} => {}", rule.getKey(), rule.getValue()); if (!ruleNames.contains(rule.getKey())) { // invalid rule name - LOGGER.warn("Invalid openapi-normalizer rule name: ", rule.getKey()); + LOGGER.warn("Invalid openapi-normalizer rule name: {}", rule.getKey()); } else if (enableAll) { rules.put(rule.getKey(), true); // set rule } else { @@ -179,6 +184,21 @@ public class OpenAPINormalizer { if (setTagsForAllOperations != null) { rules.put(SET_TAGS_FOR_ALL_OPERATIONS, true); } + + if (inputRules.get(FILTER) != null) { + rules.put(FILTER, true); + + String[] filterStrs = inputRules.get(FILTER).split(":"); + if (filterStrs.length != 2) { // only support operationId with : at the moment + LOGGER.error("FILTER rule must be in the form of `operationId:name1|name2|name3`: {}", inputRules.get(FILTER)); + } else { + if ("operationId".equals(filterStrs[0])) { + operationIdFilters = new HashSet<>(Arrays.asList(filterStrs[1].split("[|]"))); + } else { + LOGGER.error("FILTER rule must be in the form of `operationId:name1|name2|name3`: {}", inputRules.get(FILTER)); + } + } + } } /** @@ -230,6 +250,15 @@ public class OpenAPINormalizer { normalizeParameters(path.getParameters()); for (Operation operation : operations) { + if (operationIdFilters.size() > 0) { + if (operationIdFilters.contains(operation.getOperationId())) { + operation.addExtension("x-internal", false); + } else { + LOGGER.info("operation `{}` marked as internal only (x-internal: true) by the FILTER", operation.getOperationId()); + operation.addExtension("x-internal", true); + } + } + normalizeOperation(operation); normalizeRequestBody(operation); normalizeParameters(operation.getParameters()); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java index 2c43e697c6..2694910817 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java @@ -449,4 +449,22 @@ public class OpenAPINormalizerTest { assertEquals(openAPI.getPaths().get("/person/display/{personId}").getDelete().getExtensions().get("x-internal"), null); assertEquals(s2.getExtensions().get("x-internal"), null); } + + @Test + public void testFilter() { + OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/enableKeepOnlyFirstTagInOperation_test.yaml"); + + assertEquals(openAPI.getPaths().get("/person/display/{personId}").getGet().getExtensions(), null); + assertEquals(openAPI.getPaths().get("/person/display/{personId}").getDelete().getExtensions().get("x-internal"), true); + assertEquals(openAPI.getPaths().get("/person/display/{personId}").getPut().getExtensions(), null); + + Map options = new HashMap<>(); + options.put("FILTER", "operationId:delete|list"); + OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options); + openAPINormalizer.normalize(); + + assertEquals(openAPI.getPaths().get("/person/display/{personId}").getGet().getExtensions().get("x-internal"), false); + assertEquals(openAPI.getPaths().get("/person/display/{personId}").getDelete().getExtensions().get("x-internal"), false); + assertEquals(openAPI.getPaths().get("/person/display/{personId}").getPut().getExtensions().get("x-internal"), true); + } } \ No newline at end of file diff --git a/modules/openapi-generator/src/test/resources/3_0/enableKeepOnlyFirstTagInOperation_test.yaml b/modules/openapi-generator/src/test/resources/3_0/enableKeepOnlyFirstTagInOperation_test.yaml index 8b99e18d3b..04abd51fc9 100644 --- a/modules/openapi-generator/src/test/resources/3_0/enableKeepOnlyFirstTagInOperation_test.yaml +++ b/modules/openapi-generator/src/test/resources/3_0/enableKeepOnlyFirstTagInOperation_test.yaml @@ -46,6 +46,25 @@ paths: application/json: schema: $ref: "#/components/schemas/Person" + put: + tags: + - person + parameters: + - name: personId + in: path + required: true + description: The id of the person to retrieve + schema: + type: string + operationId: put + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/Person" + components: schemas: Person: