Skip to content

Commit ea6c83f

Browse files
authored
Merge branch 'OpenAPITools:master' into master
2 parents b615edf + 5cef080 commit ea6c83f

File tree

77 files changed

+2291
-800
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+2291
-800
lines changed

modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/Validate.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@
2222

2323
import io.swagger.parser.OpenAPIParser;
2424
import io.swagger.v3.oas.models.OpenAPI;
25+
import io.swagger.v3.parser.core.models.AuthorizationValue;
2526
import io.swagger.v3.parser.core.models.ParseOptions;
2627
import io.swagger.v3.parser.core.models.SwaggerParseResult;
2728
import org.apache.commons.text.WordUtils;
29+
import org.openapitools.codegen.auth.AuthParser;
2830
import org.openapitools.codegen.validation.ValidationResult;
2931
import org.openapitools.codegen.validations.oas.OpenApiEvaluator;
3032
import org.openapitools.codegen.validations.oas.RuleConfiguration;
@@ -44,12 +46,20 @@ public class Validate extends OpenApiGeneratorCommand {
4446
@Option(name = { "--recommend"}, title = "recommend spec improvements")
4547
private Boolean recommend;
4648

49+
@Option(
50+
name = {"-a", "--auth"},
51+
title = "authorization",
52+
description = "adds authorization headers when fetching the OpenAPI definitions remotely. "
53+
+ "Pass in a URL-encoded string of name:header with a comma separating multiple values")
54+
private String auth;
55+
4756
@Override
4857
public void execute() {
4958
System.out.println("Validating spec (" + spec + ")");
5059
ParseOptions options = new ParseOptions();
5160
options.setResolve(true);
52-
SwaggerParseResult result = new OpenAPIParser().readLocation(spec, null, options);
61+
final List<AuthorizationValue> authorizationValues = AuthParser.parse(this.auth);
62+
SwaggerParseResult result = new OpenAPIParser().readLocation(spec, authorizationValues, options);
5363
List<String> messageList = result.getMessages();
5464
Set<String> errors = new HashSet<>(messageList);
5565
Set<String> warnings = new HashSet<>();

modules/openapi-generator-maven-plugin/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@
2020
</properties>
2121
<dependencies>
2222
<dependency>
23-
<groupId>org.sonatype.plexus</groupId>
23+
<groupId>org.codehaus.plexus</groupId>
2424
<artifactId>plexus-build-api</artifactId>
25-
<version>0.0.7</version>
25+
<version>1.2.0</version>
2626
</dependency>
2727
<dependency>
2828
<groupId>org.apache.maven</groupId>

modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import io.swagger.v3.core.util.Yaml;
2525
import io.swagger.v3.parser.OpenAPIResolver;
2626
import io.swagger.v3.parser.OpenAPIV3Parser;
27+
import io.swagger.v3.parser.core.models.AuthorizationValue;
2728
import io.swagger.v3.parser.core.models.ParseOptions;
2829
import lombok.Setter;
2930
import org.apache.commons.io.FileUtils;
@@ -37,6 +38,7 @@
3738
import org.apache.maven.project.MavenProject;
3839
import org.apache.maven.project.MavenProjectHelper;
3940
import org.openapitools.codegen.*;
41+
import org.openapitools.codegen.auth.AuthParser;
4042
import org.openapitools.codegen.config.CodegenConfigurator;
4143
import org.openapitools.codegen.config.GlobalSettings;
4244
import org.openapitools.codegen.config.MergedSpecBuilder;
@@ -1002,8 +1004,10 @@ private String calculateInputSpecHash(String inputSpec) {
10021004
parseOptions.setResolve(true);
10031005

10041006
final URL remoteUrl = inputSpecRemoteUrl();
1007+
final List<AuthorizationValue> authorizationValues = AuthParser.parse(this.auth);
1008+
10051009
return Hashing.sha256().hashBytes(
1006-
new OpenAPIParser().readLocation(remoteUrl == null ? inputSpec : remoteUrl.toString(), null, parseOptions)
1010+
new OpenAPIParser().readLocation(remoteUrl == null ? inputSpec : remoteUrl.toString(), authorizationValues, parseOptions)
10071011
.getOpenAPI().toString().getBytes(StandardCharsets.UTF_8)
10081012
).toString();
10091013
}
@@ -1089,7 +1093,9 @@ private Path createCollapsedSpec() throws MojoExecutionException {
10891093
// Merge the OpenAPI spec file.
10901094
final var parseOptions = new ParseOptions();
10911095
parseOptions.setResolve(true);
1092-
final var openApiMerged = new OpenAPIResolver(new OpenAPIV3Parser().readLocation(inputSpec, null, parseOptions).getOpenAPI()).resolve();
1096+
final List<AuthorizationValue> authorizationValues = AuthParser.parse(this.auth);
1097+
1098+
final var openApiMerged = new OpenAPIResolver(new OpenAPIV3Parser().readLocation(inputSpec, authorizationValues, parseOptions).getOpenAPI()).resolve();
10931099

10941100
// Switch based on JSON or YAML.
10951101
final var extension = inputSpec.toLowerCase(Locale.ROOT).endsWith(".json") ? ".json" : ".yaml";

modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7196,7 +7196,7 @@ public List<CodegenParameter> fromRequestBodyToFormParameters(RequestBody body,
71967196
Schema original = null;
71977197
// check if it's allOf (only 1 sub schema) with or without default/nullable/etc set in the top level
71987198
if (ModelUtils.isAllOf(schema) && schema.getAllOf().size() == 1 &&
7199-
ModelUtils.getType(schema) == null) {
7199+
(ModelUtils.getType(schema) == null || "object".equals(ModelUtils.getType(schema)))) {
72007200
if (schema.getAllOf().get(0) instanceof Schema) {
72017201
original = schema;
72027202
schema = (Schema) schema.getAllOf().get(0);
@@ -7849,7 +7849,7 @@ public CodegenParameter fromRequestBody(RequestBody body, Set<String> imports, S
78497849
Schema original = null;
78507850
// check if it's allOf (only 1 sub schema) with or without default/nullable/etc set in the top level
78517851
if (ModelUtils.isAllOf(schema) && schema.getAllOf().size() == 1 &&
7852-
ModelUtils.getType(schema) == null) {
7852+
(ModelUtils.getType(schema) == null || "object".equals(ModelUtils.getType(schema)))) {
78537853
if (schema.getAllOf().get(0) instanceof Schema) {
78547854
original = schema;
78557855
schema = (Schema) schema.getAllOf().get(0);

modules/openapi-generator/src/main/resources/Java/Configuration.mustache

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,51 @@
22

33
package {{invokerPackage}};
44

5+
import java.util.Objects;
6+
import java.util.concurrent.atomic.AtomicReference;
7+
import java.util.function.Supplier;
8+
59
{{>generatedAnnotation}}
610
public class Configuration {
7-
public static final String VERSION = "{{{artifactVersion}}}";
8-
9-
private static volatile ApiClient defaultApiClient = new ApiClient();
10-
11-
/**
12-
* Get the default API client, which would be used when creating API
13-
* instances without providing an API client.
14-
*
15-
* @return Default API client
16-
*/
17-
public static ApiClient getDefaultApiClient() {
18-
return defaultApiClient;
19-
}
11+
public static final String VERSION = "{{{artifactVersion}}}";
12+
13+
private static final AtomicReference<ApiClient> defaultApiClient = new AtomicReference<>();
14+
private static volatile Supplier<ApiClient> apiClientFactory = ApiClient::new;
2015
21-
/**
22-
* Set the default API client, which would be used when creating API
23-
* instances without providing an API client.
24-
*
25-
* @param apiClient API client
26-
*/
27-
public static void setDefaultApiClient(ApiClient apiClient) {
28-
defaultApiClient = apiClient;
16+
/**
17+
* Get the default API client, which would be used when creating API instances without providing an API client.
18+
*
19+
* @return Default API client
20+
*/
21+
public static ApiClient getDefaultApiClient() {
22+
ApiClient client = defaultApiClient.get();
23+
if (client == null) {
24+
client = defaultApiClient.updateAndGet(val -> {
25+
if (val != null) { // changed by another thread
26+
return val;
27+
}
28+
return apiClientFactory.get();
29+
});
2930
}
30-
}
31+
return client;
32+
}
33+
34+
/**
35+
* Set the default API client, which would be used when creating API instances without providing an API client.
36+
*
37+
* @param apiClient API client
38+
*/
39+
public static void setDefaultApiClient(ApiClient apiClient) {
40+
defaultApiClient.set(apiClient);
41+
}
42+
43+
/**
44+
* set the callback used to create new ApiClient objects
45+
*/
46+
public static void setApiClientFactory(Supplier<ApiClient> factory) {
47+
apiClientFactory = Objects.requireNonNull(factory);
48+
}
49+
50+
private Configuration() {
51+
}
52+
}

modules/openapi-generator/src/main/resources/Java/libraries/apache-httpclient/ApiClient.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
466466
* @param value The header's value
467467
* @return API client
468468
*/
469-
public ApiClient addDefaultHeader(String key, String value) {
469+
public final ApiClient addDefaultHeader(String key, String value) {
470470
defaultHeaderMap.put(key, value);
471471
return this;
472472
}

modules/openapi-generator/src/main/resources/nim-client/api.mustache

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,19 @@ proc {{{operationId}}}*(httpClient: HttpClient{{#allParams}}, {{{paramName}}}: {
3737
httpClient.headers["Content-Type"] = "application/x-www-form-urlencoded"{{/isMultipart}}{{#isMultipart}}
3838
httpClient.headers["Content-Type"] = "multipart/form-data"{{/isMultipart}}{{/hasFormParams}}{{#hasHeaderParams}}{{#headerParams}}
3939
httpClient.headers["{{{baseName}}}"] = {{{paramName}}}{{#isArray}}.join(","){{/isArray}}{{/headerParams}}{{#description}} ## {{{.}}}{{/description}}{{/hasHeaderParams}}{{#hasQueryParams}}
40-
let query_for_api_call = encodeQuery([{{#queryParams}}
40+
let url_encoded_query_params = encodeQuery([{{#queryParams}}
4141
("{{{baseName}}}", ${{{paramName}}}{{#isArray}}.join(","){{/isArray}}), # {{{description}}}{{/queryParams}}
4242
]){{/hasQueryParams}}{{#hasFormParams}}{{^isMultipart}}
43-
let query_for_api_call = encodeQuery([{{#formParams}}
43+
let form_data = encodeQuery([{{#formParams}}
4444
("{{{baseName}}}", ${{{paramName}}}{{#isArray}}.join(","){{/isArray}}), # {{{description}}}{{/formParams}}
4545
]){{/isMultipart}}{{#isMultipart}}
46-
let query_for_api_call = newMultipartData({
46+
let multipart_data = newMultipartData({
4747
{{#formParams}} "{{{baseName}}}": ${{{paramName}}}{{#isArray}}.join(","){{/isArray}}, # {{{description}}}
4848
{{/formParams}}
4949
}){{/isMultipart}}{{/hasFormParams}}{{#returnType}}
5050

51-
let response = httpClient.{{{httpMethod}}}(basepath & {{^pathParams}}"{{{path}}}"{{/pathParams}}{{#hasPathParams}}fmt"{{{path}}}"{{/hasPathParams}}{{#hasQueryParams}} & "?" & query_for_api_call{{/hasQueryParams}}{{#hasBodyParam}}{{#bodyParams}}, $(%{{{paramName}}}){{/bodyParams}}{{/hasBodyParam}}{{#hasFormParams}}, {{^isMultipart}}$query_for_api_call{{/isMultipart}}{{#isMultipart}}multipart=query_for_api_call{{/isMultipart}}{{/hasFormParams}})
51+
let response = httpClient.{{{httpMethod}}}(basepath & {{^pathParams}}"{{{path}}}"{{/pathParams}}{{#hasPathParams}}fmt"{{{path}}}"{{/hasPathParams}}{{#hasQueryParams}} & "?" & url_encoded_query_params{{/hasQueryParams}}{{#hasBodyParam}}{{#bodyParams}}, $(%{{{paramName}}}){{/bodyParams}}{{/hasBodyParam}}{{#hasFormParams}}, {{^isMultipart}}$form_data{{/isMultipart}}{{#isMultipart}}multipart=multipart_data{{/isMultipart}}{{/hasFormParams}})
5252
constructResult[{{{returnType}}}](response){{/returnType}}{{^returnType}}
53-
httpClient.{{{httpMethod}}}(basepath & {{^pathParams}}"{{{path}}}"{{/pathParams}}{{#hasPathParams}}fmt"{{{path}}}"{{/hasPathParams}}{{#hasQueryParams}} & "?" & query_for_api_call{{/hasQueryParams}}{{#hasBodyParam}}{{#bodyParams}}, $(%{{{paramName}}}){{/bodyParams}}{{/hasBodyParam}}{{#hasFormParams}}, {{^isMultipart}}$query_for_api_call{{/isMultipart}}{{#isMultipart}}multipart=query_for_api_call{{/isMultipart}}{{/hasFormParams}}){{/returnType}}
53+
httpClient.{{{httpMethod}}}(basepath & {{^pathParams}}"{{{path}}}"{{/pathParams}}{{#hasPathParams}}fmt"{{{path}}}"{{/hasPathParams}}{{#hasQueryParams}} & "?" & url_encoded_query_params{{/hasQueryParams}}{{#hasBodyParam}}{{#bodyParams}}, $(%{{{paramName}}}){{/bodyParams}}{{/hasBodyParam}}{{#hasFormParams}}, {{^isMultipart}}$form_data{{/isMultipart}}{{#isMultipart}}multipart=multipart_data{{/isMultipart}}{{/hasFormParams}}){{/returnType}}
5454

5555
{{/operation}}{{/operations}}

modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3990,11 +3990,6 @@ public void testComposedRequestBodyTypes() {
39903990
CodegenOperation co;
39913991
CodegenParameter cp;
39923992

3993-
path = "/ComposedObject";
3994-
co = codegen.fromOperation(path, "GET", openAPI.getPaths().get(path).getGet(), null);
3995-
cp = co.bodyParam;
3996-
assertTrue(cp.getIsMap());
3997-
39983993
path = "/ComposedNumber";
39993994
co = codegen.fromOperation(path, "GET", openAPI.getPaths().get(path).getGet(), null);
40003995
cp = co.bodyParam;

modules/openapi-generator/src/test/resources/3_0/rust/petstore.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,26 @@ paths:
676676
student: '#/components/schemas/Person'
677677
teacher: '#/components/schemas/Person'
678678
car: '#/components/schemas/Vehicle'
679+
'/tests/allOfWithOneModel':
680+
get:
681+
tags:
682+
- testing
683+
summary: 'Test for allOf with a single option. (One of the issues in #20500)'
684+
requestBody:
685+
required: true
686+
content:
687+
application/json:
688+
schema:
689+
type: object
690+
allOf:
691+
- $ref: '#/components/schemas/Person'
692+
responses:
693+
'200':
694+
description: successful operation
695+
content:
696+
application/json:
697+
schema:
698+
type: string
679699
externalDocs:
680700
description: Find out more about Swagger
681701
url: 'http://swagger.io'

samples/client/echo_api/java/apache-httpclient/src/main/java/org/openapitools/client/ApiClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ public ApiClient setTempFolderPath(String tempFolderPath) {
384384
* @param value The header's value
385385
* @return API client
386386
*/
387-
public ApiClient addDefaultHeader(String key, String value) {
387+
public final ApiClient addDefaultHeader(String key, String value) {
388388
defaultHeaderMap.put(key, value);
389389
return this;
390390
}

samples/client/echo_api/java/apache-httpclient/src/main/java/org/openapitools/client/Configuration.java

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,29 +13,51 @@
1313

1414
package org.openapitools.client;
1515

16+
import java.util.Objects;
17+
import java.util.concurrent.atomic.AtomicReference;
18+
import java.util.function.Supplier;
19+
1620
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.13.0-SNAPSHOT")
1721
public class Configuration {
18-
public static final String VERSION = "0.1.0";
19-
20-
private static volatile ApiClient defaultApiClient = new ApiClient();
21-
22-
/**
23-
* Get the default API client, which would be used when creating API
24-
* instances without providing an API client.
25-
*
26-
* @return Default API client
27-
*/
28-
public static ApiClient getDefaultApiClient() {
29-
return defaultApiClient;
30-
}
22+
public static final String VERSION = "0.1.0";
23+
24+
private static final AtomicReference<ApiClient> defaultApiClient = new AtomicReference<>();
25+
private static volatile Supplier<ApiClient> apiClientFactory = ApiClient::new;
3126

32-
/**
33-
* Set the default API client, which would be used when creating API
34-
* instances without providing an API client.
35-
*
36-
* @param apiClient API client
37-
*/
38-
public static void setDefaultApiClient(ApiClient apiClient) {
39-
defaultApiClient = apiClient;
27+
/**
28+
* Get the default API client, which would be used when creating API instances without providing an API client.
29+
*
30+
* @return Default API client
31+
*/
32+
public static ApiClient getDefaultApiClient() {
33+
ApiClient client = defaultApiClient.get();
34+
if (client == null) {
35+
client = defaultApiClient.updateAndGet(val -> {
36+
if (val != null) { // changed by another thread
37+
return val;
38+
}
39+
return apiClientFactory.get();
40+
});
4041
}
41-
}
42+
return client;
43+
}
44+
45+
/**
46+
* Set the default API client, which would be used when creating API instances without providing an API client.
47+
*
48+
* @param apiClient API client
49+
*/
50+
public static void setDefaultApiClient(ApiClient apiClient) {
51+
defaultApiClient.set(apiClient);
52+
}
53+
54+
/**
55+
* set the callback used to create new ApiClient objects
56+
*/
57+
public static void setApiClientFactory(Supplier<ApiClient> factory) {
58+
apiClientFactory = Objects.requireNonNull(factory);
59+
}
60+
61+
private Configuration() {
62+
}
63+
}

0 commit comments

Comments
 (0)