Skip to content

Commit 231ef37

Browse files
authored
Merge pull request ballerina-platform#1831 from ballerina-platform/align-improv
OpenAPI tool enhancements and fixes for connector regeneration
2 parents 1482984 + de1dbe2 commit 231ef37

161 files changed

Lines changed: 8122 additions & 8290 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
[package]
22
org= "ballerina"
33
name= "openapi"
4-
version= "@toml.version@"
4+
version= "2.3.1"

module-ballerina-openapi/CompilerPlugin.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ id = "openapi-tools"
33
class = "io.ballerina.openapi.validator.OpenAPIValidatorPlugin"
44

55
[[dependency]]
6-
path = "../openapi-validator/build/libs/openapi-validator-@project.version@.jar"
6+
path = "../openapi-validator/build/libs/openapi-validator-2.3.1-SNAPSHOT.jar"
77
groupId = "ballerina"
88
artifactId = "openapi"
9-
version = "@project.version@."
9+
version = "2.3.1-SNAPSHOT"

openapi-cli/src/main/java/io/ballerina/openapi/cmd/Align.java

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@
2323
import picocli.CommandLine;
2424

2525
import java.io.PrintStream;
26+
import java.util.ArrayList;
27+
import java.util.Arrays;
28+
import java.util.Collections;
29+
import java.util.List;
30+
import java.util.Objects;
2631
import java.util.Optional;
2732

2833
/**
@@ -38,7 +43,22 @@
3843
)
3944
public class Align extends SubCmdBase {
4045

46+
public static final String INVALID_ALIGNMENT_OPTIONS = "ERROR: Invalid alignment type '%s' provided. " +
47+
"The available options are: %s";
4148
private static final String INFO_MSG_PREFIX = "Aligned";
49+
public static final String NAME = "name";
50+
public static final String DOC = "doc";
51+
public static final String BASEPATH = "basepath";
52+
public static final List<String> DEFAULT_ALIGNMENT_TYPES = List.of(NAME, DOC, BASEPATH);
53+
private List<String> alignmentTypes = Arrays.asList(NAME, DOC, BASEPATH);
54+
55+
@CommandLine.Option(names = {"--include"}, description = "Alignment types to be included. " +
56+
"The available options are: name, doc, basepath.")
57+
public String includedAlignments;
58+
59+
@CommandLine.Option(names = {"--exclude"}, description = "Alignment types to be excluded. " +
60+
"The available options are: name, doc, basepath.")
61+
public String excludedAlignments;
4262

4363
public Align() {
4464
super(CommandType.ALIGN, INFO_MSG_PREFIX);
@@ -48,21 +68,52 @@ public Align(PrintStream errorStream, boolean exitWhenFinish) {
4868
super(CommandType.ALIGN, INFO_MSG_PREFIX, errorStream, exitWhenFinish);
4969
}
5070

71+
@Override
72+
public void execute() {
73+
setAlignmentTypes();
74+
super.execute();
75+
}
76+
77+
private void setAlignmentTypes() {
78+
List<String> validatedIncludedAlignments = getValidatedAlignmentTypes(includedAlignments);
79+
List<String> validatedExcludedAlignments = getValidatedAlignmentTypes(excludedAlignments);
80+
if (!validatedIncludedAlignments.isEmpty()) {
81+
alignmentTypes = validatedIncludedAlignments;
82+
} else if (!validatedExcludedAlignments.isEmpty()) {
83+
alignmentTypes.removeAll(validatedExcludedAlignments);
84+
}
85+
}
86+
87+
private List<String> getValidatedAlignmentTypes(String alignmentTypes) {
88+
if (Objects.isNull(alignmentTypes) || alignmentTypes.isEmpty()) {
89+
return Collections.emptyList();
90+
}
91+
String[] alignmentTypesList = alignmentTypes.split(COMMA);
92+
List<String> validatedAlignmentTypes = new ArrayList<>();
93+
for (String alignmentType : alignmentTypesList) {
94+
if (DEFAULT_ALIGNMENT_TYPES.contains(alignmentType)) {
95+
validatedAlignmentTypes.add(alignmentType);
96+
} else {
97+
printError(INVALID_ALIGNMENT_OPTIONS.formatted(alignmentType, DEFAULT_ALIGNMENT_TYPES));
98+
}
99+
}
100+
return validatedAlignmentTypes;
101+
}
102+
51103
@Override
52104
public String getDefaultFileName() {
53105
return "aligned_ballerina_openapi";
54106
}
55107

56108
@Override
57109
public Optional<OpenAPI> generate(String openAPIFileContent) {
58-
Optional<OpenAPI> filteredOpenAPI = getFilteredOpenAPI(openAPIFileContent, true);
110+
Optional<OpenAPI> filteredOpenAPI = getFilteredOpenAPI(openAPIFileContent);
59111
return filteredOpenAPI.flatMap(this::alignOpenAPI);
60112
}
61113

62114
private Optional<OpenAPI> alignOpenAPI(OpenAPI openAPI) {
63-
OASModifier oasAligner = new OASModifier();
64115
try {
65-
return Optional.of(oasAligner.modifyWithBallerinaConventions(openAPI));
116+
return Optional.of(new OASModifier().modify(openAPI, alignmentTypes));
66117
} catch (BallerinaOpenApiException exp) {
67118
printError("ERROR: %s".formatted(exp.getMessage()));
68119
return Optional.empty();

openapi-cli/src/main/java/io/ballerina/openapi/cmd/Flatten.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public String getDefaultFileName() {
6868

6969
@Override
7070
public Optional<OpenAPI> generate(String openAPIFileContent) {
71-
Optional<OpenAPI> filteredOpenAPI = getFilteredOpenAPI(openAPIFileContent, false);
71+
Optional<OpenAPI> filteredOpenAPI = getFilteredOpenAPI(openAPIFileContent);
7272
if (filteredOpenAPI.isEmpty()) {
7373
return Optional.empty();
7474
}

openapi-cli/src/main/java/io/ballerina/openapi/cmd/SubCmdBase.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package io.ballerina.openapi.cmd;
1919

2020
import io.ballerina.cli.BLauncherCmd;
21+
import io.ballerina.openapi.core.generators.common.InlineModelResolver;
2122
import io.ballerina.openapi.core.generators.common.model.Filter;
2223
import io.ballerina.openapi.service.mapper.utils.CodegenUtils;
2324
import io.swagger.parser.OpenAPIParser;
@@ -26,7 +27,6 @@
2627
import io.swagger.v3.oas.models.OpenAPI;
2728
import io.swagger.v3.parser.core.models.ParseOptions;
2829
import io.swagger.v3.parser.core.models.SwaggerParseResult;
29-
import io.swagger.v3.parser.util.InlineModelResolver;
3030
import picocli.CommandLine;
3131

3232
import java.io.IOException;
@@ -75,7 +75,7 @@ public String getName() {
7575
}
7676

7777
private static final String COMMAND_IDENTIFIER = "openapi-%s";
78-
private static final String COMMA = ",";
78+
protected static final String COMMA = ",";
7979

8080
private static final String INFO_OUTPUT_WRITTEN_MSG = "INFO: %s OpenAPI definition file was successfully" +
8181
" written to: %s%n";
@@ -195,17 +195,16 @@ private void generateOpenAPI() {
195195
public abstract String getDefaultFileName();
196196

197197
public Optional<OpenAPI> getFlattenOpenAPI(OpenAPI openAPI) {
198-
// Flatten the OpenAPI definition with `flattenComposedSchemas: true` and `camelCaseFlattenNaming: true`
199-
InlineModelResolver inlineModelResolver = new InlineModelResolver(true, true);
198+
// Flatten the OpenAPI definition with `flattenComposedSchemas: true` and `skipMatches: false`
199+
InlineModelResolver inlineModelResolver = new InlineModelResolver(true, false);
200200
inlineModelResolver.flatten(openAPI);
201201
return Optional.of(openAPI);
202202
}
203203

204-
public Optional<OpenAPI> getFilteredOpenAPI(String openAPIFileContent, boolean enableResolver) {
204+
public Optional<OpenAPI> getFilteredOpenAPI(String openAPIFileContent) {
205205
// Read the contents of the file with default parser options
206206
// Flattening will be done after filtering the operations
207207
ParseOptions parseOptions = new ParseOptions();
208-
parseOptions.setResolve(enableResolver);
209208
SwaggerParseResult parserResult = new OpenAPIParser().readContents(openAPIFileContent, null,
210209
parseOptions);
211210
if (!parserResult.getMessages().isEmpty() &&

openapi-cli/src/main/resources/cli-help/ballerina-openapi-align.help

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,22 @@ SYNOPSIS
99
[-f | --format] [json|yaml]
1010
[-t | --tags] <tag-names>
1111
[--operations] <operation-names>
12+
[--include] <align-type-names>
13+
[--exclude] <align-type-names>
14+
[--help]
1215

1316
DESCRIPTION
14-
Align the OpenAPI contract file according to the best naming
15-
practices of Ballerina. The Ballerina name extensions are added
16-
to the schemas which can not be modified directly.
17+
Align the OpenAPI contract file according to the best practices of Ballerina.
1718

19+
By default, the following alignments are done:
20+
- `name`: Align according to the best naming practices of Ballerina. The Ballerina
21+
name extensions are added to the schemas which can not be modified directly.
22+
- `doc`: Align according to the best documentation practices of Ballerina.
23+
- `basepath`: Extract the common base path from the operations and add it to the
24+
server url.
25+
26+
The alignments can be filtered using the `--include` and `--exclude` options.
27+
The `--include` option has higher priority than the `--exclude` option.
1828

1929
OPTIONS
2030
-i, --input <openapi-contract-file-path>
@@ -43,6 +53,17 @@ OPTIONS
4353
This is an optional input. The aligned OpenAPI contract will only
4454
have the given operations.
4555

56+
--include <align-type-names>
57+
This is an optional input. The aligned OpenAPI contract will only
58+
have the given alignments. The supported alignments are: `name`,
59+
`doc` and `basepath`.
60+
61+
--exclude <align-type-names>
62+
This is an optional input. The aligned OpenAPI contract will not
63+
have the given alignments. The supported alignments are: `name`,
64+
`doc`and `basepath`. The `--include` option has higher priority than
65+
the `--exclude` option.
66+
4667
EXAMPLES
4768
Align the `service.yaml` OpenAPI contract file.
4869
$ bal openapi align -i service.yaml
@@ -54,3 +75,6 @@ EXAMPLES
5475
Align the `service.json` OpenAPI contract file by filtering the
5576
operations with the `service` tag.
5677
$ bal openapi align -i service.json -t service
78+
79+
Align the `service.json` OpenAPI contract with only the `name` alignment.
80+
$ bal openapi align -i service.json --include name

openapi-cli/src/test/java/io/ballerina/openapi/cmd/BallerinaCodeGeneratorLicenseTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,6 @@ public void testServiceGeneration() throws IOException {
118118
Assert.fail("Code generation failed. : " + readOutput(true));
119119
}
120120
}
121-
122121
@Test(description = "Test openapi to ballerina code generation with default file headers")
123122
public void testBothClientServiceGeneration() throws IOException {
124123
Path petstoreYaml = resourceDir.resolve(Paths.get("petstore.yaml"));
@@ -145,6 +144,7 @@ public void testBothClientServiceGeneration() throws IOException {
145144
}
146145
}
147146

147+
148148
@Test(description = "Test openapi to ballerina code generation with user provided license headers")
149149
public void testUserGivenLicenseHeader() throws IOException {
150150
Path petstoreYaml = resourceDir.resolve(Paths.get("petstore.yaml"));

openapi-cli/src/test/java/io/ballerina/openapi/generators/auth/HttpAuthTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818

1919
package io.ballerina.openapi.generators.auth;
2020

21+
import io.ballerina.compiler.syntax.tree.AssignmentStatementNode;
2122
import io.ballerina.compiler.syntax.tree.Node;
2223
import io.ballerina.compiler.syntax.tree.ParameterNode;
23-
import io.ballerina.compiler.syntax.tree.VariableDeclarationNode;
2424
import io.ballerina.openapi.core.generators.client.AuthConfigGeneratorImp;
2525
import io.ballerina.openapi.core.generators.client.exception.ClientException;
2626
import io.ballerina.openapi.core.generators.common.GeneratorUtils;
@@ -84,7 +84,7 @@ public void testGetClientInitializationNode() {
8484
AuthConfigGeneratorImp ballerinaAuthConfigGenerator = new AuthConfigGeneratorImp(
8585
false, true);
8686
String expectedParam = TestConstants.HTTP_CLIENT_DECLARATION;
87-
VariableDeclarationNode generatedInitParamNode = ballerinaAuthConfigGenerator.getClientInitializationNode();
87+
AssignmentStatementNode generatedInitParamNode = ballerinaAuthConfigGenerator.getClientInitializationNode();
8888
expectedParam = (expectedParam.trim()).replaceAll("\\s+", "");
8989
String generatedParamsStr = (generatedInitParamNode.toString().trim()).replaceAll("\\s+", "");
9090
Assert.assertEquals(expectedParam, generatedParamsStr);

openapi-cli/src/test/java/io/ballerina/openapi/generators/auth/OAuth2Tests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@
1818

1919
package io.ballerina.openapi.generators.auth;
2020

21+
import io.ballerina.compiler.syntax.tree.AssignmentStatementNode;
2122
import io.ballerina.compiler.syntax.tree.Node;
2223
import io.ballerina.compiler.syntax.tree.ParameterNode;
2324
import io.ballerina.compiler.syntax.tree.TypeDefinitionNode;
24-
import io.ballerina.compiler.syntax.tree.VariableDeclarationNode;
2525
import io.ballerina.openapi.core.generators.client.AuthConfigGeneratorImp;
2626
import io.ballerina.openapi.core.generators.client.exception.ClientException;
2727
import io.ballerina.openapi.core.generators.common.GeneratorUtils;
@@ -88,7 +88,7 @@ public void testGetClientInitializationNode() {
8888
AuthConfigGeneratorImp ballerinaAuthConfigGenerator = new AuthConfigGeneratorImp(false,
8989
true);
9090
String expectedParam = TestConstants.HTTP_CLIENT_DECLARATION;
91-
VariableDeclarationNode generatedInitParamNode = ballerinaAuthConfigGenerator.getClientInitializationNode();
91+
AssignmentStatementNode generatedInitParamNode = ballerinaAuthConfigGenerator.getClientInitializationNode();
9292
expectedParam = (expectedParam.trim()).replaceAll("\\s+", "");
9393
String generatedParamsStr = (generatedInitParamNode.toString().trim()).replaceAll("\\s+", "");
9494
Assert.assertEquals(expectedParam, generatedParamsStr);

openapi-cli/src/test/java/io/ballerina/openapi/generators/client/AllOfResponsesTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public void getReturnTypeForAllOf() throws IOException, BallerinaOpenApiExceptio
5555
TypeHandler.createInstance(response, false);
5656
Operation post = response.getPaths().get("/users/{userId}/meetings").getPost();
5757
FunctionReturnTypeGeneratorImp functionReturnType = new FunctionReturnTypeGeneratorImp(post, response, "post");
58-
assertEquals(functionReturnType.getReturnType().get().type().toString(), "inline_response_201|error");
58+
assertEquals(functionReturnType.getReturnType().get().type().toString(), "inline_response_201|error?");
5959
}
6060

6161
@Test(description = "Tests for the object response without property")

0 commit comments

Comments
 (0)