mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2025-06-28 19:50:49 +00:00
Autoset constants (Required fields having single valid enum value) (#16761)
* Autoset constants (Required fields having single valid enum value) Python Implementation of #16547 * Fixing ``PythonClientCodegenTest.testHandleConstantParams`` for Windows platform.
This commit is contained in:
parent
8bb473316e
commit
2f214ee6c6
@ -43,6 +43,8 @@ public class CodegenConstants {
|
||||
public static final String API_SUFFIX = "apiSuffix";
|
||||
public static final String API_SUFFIX_DESC = "suffix for api classes";
|
||||
|
||||
public static final String AUTOSET_CONSTANTS = "autosetConstants";
|
||||
|
||||
public static final String MODEL_PACKAGE = "modelPackage";
|
||||
public static final String MODEL_PACKAGE_DESC = "package for generated models";
|
||||
|
||||
|
@ -304,6 +304,9 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
|
||||
protected boolean addSuffixToDuplicateOperationNicknames = true;
|
||||
|
||||
// Whether to automatically hardcode params that are considered Constants by OpenAPI Spec
|
||||
protected boolean autosetConstants = false;
|
||||
|
||||
public boolean getAddSuffixToDuplicateOperationNicknames() {
|
||||
return addSuffixToDuplicateOperationNicknames;
|
||||
}
|
||||
@ -427,6 +430,10 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
this.setEnumUnknownDefaultCase(Boolean.parseBoolean(additionalProperties
|
||||
.get(CodegenConstants.ENUM_UNKNOWN_DEFAULT_CASE).toString()));
|
||||
}
|
||||
if (additionalProperties.containsKey(CodegenConstants.AUTOSET_CONSTANTS)) {
|
||||
this.setAutosetConstants(
|
||||
Boolean.parseBoolean(additionalProperties.get(CodegenConstants.AUTOSET_CONSTANTS).toString()));
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
@ -8282,4 +8289,47 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
throw new IllegalArgumentException("Invalid schema type; type must be Boolean or Schema");
|
||||
}
|
||||
}
|
||||
|
||||
public void setAutosetConstants(boolean autosetConstants) {
|
||||
this.autosetConstants = autosetConstants;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method removes all constant Query, Header and Cookie Params from allParams and sets them as constantParams in the CodegenOperation.
|
||||
* The definition of constant is single valued required enum params.
|
||||
* The constantParams in the the generated code should be hardcoded to the constantValue if autosetConstants feature is enabled.
|
||||
*
|
||||
* @param operation - operation to be processed
|
||||
*/
|
||||
protected void handleConstantParams(CodegenOperation operation) {
|
||||
if (!autosetConstants || operation.allParams.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
final ArrayList<CodegenParameter> copy = new ArrayList<>(operation.allParams);
|
||||
// Remove all params from Params, Non constant params will be added back later.
|
||||
operation.allParams.clear();
|
||||
|
||||
// Finds all constant params, removes them from allParams and adds them to constant params.
|
||||
// Also, adds back non constant params to allParams.
|
||||
for (CodegenParameter p : copy) {
|
||||
if (p.isEnum && p.required && p._enum != null && p._enum.size() == 1) {
|
||||
// Add to constantParams for use in the code generation templates.
|
||||
operation.constantParams.add(p);
|
||||
if(p.isQueryParam) {
|
||||
operation.queryParams.removeIf(param -> param.baseName.equals(p.baseName));
|
||||
}
|
||||
if(p.isHeaderParam) {
|
||||
operation.headerParams.removeIf(param -> param.baseName.equals(p.baseName));
|
||||
}
|
||||
if(p.isCookieParam) {
|
||||
operation.cookieParams.removeIf(param -> param.baseName.equals(p.baseName));
|
||||
}
|
||||
LOGGER.info("Update operation [{}]. Remove parameter [{}] because it can only have a fixed value of [{}]", operation.operationId, p.baseName, p._enum.get(0));
|
||||
} else {
|
||||
// Add back to allParams as the param is not a constant.
|
||||
operation.allParams.add(p);
|
||||
}
|
||||
}
|
||||
operation.hasParams = !operation.allParams.isEmpty();
|
||||
}
|
||||
}
|
||||
|
@ -82,7 +82,6 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
|
||||
public static final String TEST_OUTPUT = "testOutput";
|
||||
public static final String IMPLICIT_HEADERS = "implicitHeaders";
|
||||
public static final String IMPLICIT_HEADERS_REGEX = "implicitHeadersRegex";
|
||||
public static final String AUTOSET_CONSTANTS = "autosetConstants";
|
||||
public static final String JAVAX_PACKAGE = "javaxPackage";
|
||||
public static final String USE_JAKARTA_EE = "useJakartaEe";
|
||||
public static final String CONTAINER_DEFAULT_TO_NULL = "containerDefaultToNull";
|
||||
@ -136,7 +135,6 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
|
||||
protected AnnotationLibrary annotationLibrary;
|
||||
protected boolean implicitHeaders = false;
|
||||
protected String implicitHeadersRegex = null;
|
||||
protected boolean autosetConstants = false;
|
||||
protected boolean camelCaseDollarSign = false;
|
||||
protected boolean useJakartaEe = false;
|
||||
protected boolean containerDefaultToNull = false;
|
||||
@ -558,10 +556,6 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
|
||||
this.setImplicitHeadersRegex(additionalProperties.get(IMPLICIT_HEADERS_REGEX).toString());
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(AUTOSET_CONSTANTS)) {
|
||||
this.setAutosetConstants(Boolean.parseBoolean(additionalProperties.get(AUTOSET_CONSTANTS).toString()));
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(CAMEL_CASE_DOLLAR_SIGN)) {
|
||||
this.setCamelCaseDollarSign(Boolean.parseBoolean(additionalProperties.get(CAMEL_CASE_DOLLAR_SIGN).toString()));
|
||||
}
|
||||
@ -2052,10 +2046,6 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
|
||||
this.implicitHeadersRegex = implicitHeadersRegex;
|
||||
}
|
||||
|
||||
public void setAutosetConstants(boolean autosetConstants) {
|
||||
this.autosetConstants = autosetConstants;
|
||||
}
|
||||
|
||||
public void setCamelCaseDollarSign(boolean camelCaseDollarSign) {
|
||||
this.camelCaseDollarSign = camelCaseDollarSign;
|
||||
}
|
||||
@ -2293,46 +2283,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
|
||||
}
|
||||
operation.hasParams = !operation.allParams.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method removes all constant Query, Header and Cookie Params from allParams and sets them as constantParams in the CodegenOperation.
|
||||
* The definition of constant is single valued required enum params.
|
||||
* The constantParams in the the generated code should be hardcoded to the constantValue if autosetConstants feature is enabled.
|
||||
*
|
||||
* @param operation - operation to be processed
|
||||
*/
|
||||
protected void handleConstantParams(CodegenOperation operation) {
|
||||
if (!autosetConstants || operation.allParams.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
final ArrayList<CodegenParameter> copy = new ArrayList<>(operation.allParams);
|
||||
// Remove all params from Params, Non constant params will be added back later.
|
||||
operation.allParams.clear();
|
||||
|
||||
// Finds all constant params, removes them from allParams and adds them to constant params.
|
||||
// Also, adds back non constant params to allParams.
|
||||
for (CodegenParameter p : copy) {
|
||||
if (p.isEnum && p.required && p._enum != null && p._enum.size() == 1) {
|
||||
// Add to constantParams for use in the code generation templates.
|
||||
operation.constantParams.add(p);
|
||||
if(p.isQueryParam) {
|
||||
operation.queryParams.removeIf(param -> param.baseName.equals(p.baseName));
|
||||
}
|
||||
if(p.isHeaderParam) {
|
||||
operation.headerParams.removeIf(param -> param.baseName.equals(p.baseName));
|
||||
}
|
||||
if(p.isCookieParam) {
|
||||
operation.cookieParams.removeIf(param -> param.baseName.equals(p.baseName));
|
||||
}
|
||||
LOGGER.info("Update operation [{}]. Remove parameter [{}] because it can only have a fixed value of [{}]", operation.operationId, p.baseName, p._enum.get(0));
|
||||
} else {
|
||||
// Add back to allParams as the param is not a constant.
|
||||
operation.allParams.add(p);
|
||||
}
|
||||
}
|
||||
operation.hasParams = !operation.allParams.isEmpty();
|
||||
}
|
||||
|
||||
|
||||
private boolean shouldBeImplicitHeader(CodegenParameter parameter) {
|
||||
return StringUtils.isNotBlank(implicitHeadersRegex) && parameter.baseName.matches(implicitHeadersRegex);
|
||||
}
|
||||
|
@ -1281,6 +1281,9 @@ public abstract class AbstractPythonCodegen extends DefaultCodegen implements Co
|
||||
}
|
||||
operation.vendorExtensions.put("x-py-example-import", imports);
|
||||
}
|
||||
|
||||
// Remove constant params from allParams list and add to constantParams
|
||||
handleConstantParams(operation);
|
||||
}
|
||||
|
||||
List<Map<String, String>> newImports = new ArrayList<>();
|
||||
|
@ -227,6 +227,13 @@ class {{classname}}:
|
||||
{{/isArray}}
|
||||
|
||||
{{/queryParams}}
|
||||
{{#constantParams}}
|
||||
{{#isQueryParam}}
|
||||
# Set client side default value of Query Param "{{baseName}}".
|
||||
_query_params['{{baseName}}'] = {{#_enum}}'{{{.}}}'{{/_enum}}
|
||||
|
||||
{{/isQueryParam}}
|
||||
{{/constantParams}}
|
||||
# process the header parameters
|
||||
_header_params = dict(_params.get('_headers', {}))
|
||||
{{#headerParams}}
|
||||
@ -237,6 +244,13 @@ class {{classname}}:
|
||||
{{/isArray}}
|
||||
|
||||
{{/headerParams}}
|
||||
{{#constantParams}}
|
||||
{{#isHeaderParam}}
|
||||
# Set client side default value of Header Param "{{baseName}}".
|
||||
_header_params['{{baseName}}'] = {{#_enum}}'{{{.}}}'{{/_enum}}
|
||||
|
||||
{{/isHeaderParam}}
|
||||
{{/constantParams}}
|
||||
# process the form parameters
|
||||
_form_params: List[Tuple[str, str]] = []
|
||||
_files: Dict[str, str] = {}
|
||||
|
@ -2673,6 +2673,7 @@ public class JavaClientCodegenTest {
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleConstantParams() throws IOException {
|
||||
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
|
||||
output.deleteOnExit();
|
||||
@ -2682,7 +2683,7 @@ public class JavaClientCodegenTest {
|
||||
clientOptInput.openAPI(openAPI);
|
||||
JavaClientCodegen javaClientCodegen = new JavaClientCodegen();
|
||||
javaClientCodegen.setOutputDir(output.getAbsolutePath());
|
||||
javaClientCodegen.additionalProperties().put(JavaClientCodegen.AUTOSET_CONSTANTS, "true");
|
||||
javaClientCodegen.additionalProperties().put(CodegenConstants.AUTOSET_CONSTANTS, "true");
|
||||
javaClientCodegen.setAutosetConstants(true);
|
||||
clientOptInput.config(javaClientCodegen);
|
||||
defaultGenerator.opts(clientOptInput);
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
package org.openapitools.codegen.python;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import com.google.common.collect.Sets;
|
||||
import io.swagger.parser.OpenAPIParser;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
@ -30,6 +31,7 @@ import org.openapitools.codegen.languages.features.CXFServerFeatures;
|
||||
import static org.openapitools.codegen.TestUtils.assertFileContains;
|
||||
import static org.openapitools.codegen.TestUtils.assertFileExists;
|
||||
import org.openapitools.codegen.TestUtils;
|
||||
import org.openapitools.codegen.java.assertions.JavaFileAssert;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
import java.io.File;
|
||||
@ -40,6 +42,9 @@ import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class PythonClientCodegenTest {
|
||||
|
||||
@ -501,4 +506,28 @@ public class PythonClientCodegenTest {
|
||||
CodegenProperty property = vars.get(0);
|
||||
Assert.assertEquals(property.name, "dollar_value");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleConstantParams() throws IOException {
|
||||
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
|
||||
output.deleteOnExit();
|
||||
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/java/autoset_constant.yaml");
|
||||
final DefaultGenerator defaultGenerator = new DefaultGenerator();
|
||||
final ClientOptInput clientOptInput = new ClientOptInput();
|
||||
clientOptInput.openAPI(openAPI);
|
||||
PythonClientCodegen pythonClientCodegen = new PythonClientCodegen();
|
||||
pythonClientCodegen.setOutputDir(output.getAbsolutePath());
|
||||
pythonClientCodegen.additionalProperties().put(CodegenConstants.AUTOSET_CONSTANTS, "true");
|
||||
pythonClientCodegen.setAutosetConstants(true);
|
||||
clientOptInput.config(pythonClientCodegen);
|
||||
defaultGenerator.opts(clientOptInput);
|
||||
|
||||
Map<String, File> files = defaultGenerator.generate().stream()
|
||||
.collect(Collectors.toMap(File::getPath, Function.identity()));
|
||||
|
||||
File apiFile = files
|
||||
.get(Paths.get(output.getAbsolutePath(), "openapi_client", "api", "hello_example_api.py").toString());
|
||||
assertNotNull(apiFile);
|
||||
assertFileContains(apiFile.toPath(), "_header_params['X-CUSTOM_CONSTANT_HEADER'] = 'CONSTANT_VALUE'");
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user