Skip to content

Commit

Permalink
Import open api core
Browse files Browse the repository at this point in the history
  • Loading branch information
KavinduZoysa committed Sep 26, 2024
1 parent 02d98cb commit e4540f5
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ dependencies {
transitive = false
}

implementation files('libs/openapi-core-2.1.1-SNAPSHOT.jar')
implementation "io.ballerina.openapi:core:2.1.1-20240926-171100-1f88ade"
implementation ("io.swagger.parser.v3:swagger-parser:${swaggerParserVersion}") {
exclude group: "io.swagger", module: "swagger-compat-spec-parser"
exclude group: "org.slf4j", module: "slf4j-ext"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
import io.ballerina.projects.Document;
import io.ballerina.tools.diagnostics.Diagnostic;
import io.ballerina.tools.diagnostics.DiagnosticSeverity;
import io.ballerina.tools.text.LinePosition;
import io.ballerina.tools.text.LineRange;
import org.ballerinalang.formatter.core.Formatter;
import org.ballerinalang.formatter.core.FormatterException;
import io.swagger.v3.oas.models.OpenAPI;
Expand All @@ -65,7 +67,7 @@
import static io.ballerina.openapi.core.generators.common.GeneratorConstants.DEFAULT_FILE_HEADER;

/**
* Generates service from the open api contract.
* Generates service from the OpenAPI contract.
*
* @since 1.4.0
*/
Expand All @@ -81,6 +83,8 @@ public class OpenApiServiceGenerator {
public static final String CLOSE_BRACE = "}";
public static final String IMPORT = "import ballerina/http;";
public static final String SERVICE_DECLARATION = "service OASServiceType on new http:Listener(%s) {";
public static final String SERVICE_OBJ_FILE = "service_contract.bal";
public static final String SERVICE_IMPL_FILE = "service_implementation.bal";

public OpenApiServiceGenerator(Path oAContractPath, Path projectPath, int port, WorkspaceManager workspaceManager) {
this.oAContractPath = oAContractPath;
Expand All @@ -89,14 +93,14 @@ public OpenApiServiceGenerator(Path oAContractPath, Path projectPath, int port,
this.port = port;
}

public void generateService() throws IOException, BallerinaOpenApiException, FormatterException,
public LineRange generateService() throws IOException, BallerinaOpenApiException, FormatterException,
WorkspaceDocumentException, EventSyncException {
Filter filter = new Filter(new ArrayList<>(), new ArrayList<>());

List<Diagnostic> diagnostics = new ArrayList<>();
List<GenSrcFile> genFiles = generateBallerinaService(oAContractPath, filter, diagnostics);
if (genFiles.isEmpty()) {
return;
throw new BallerinaOpenApiException("Cannot generate service from the given OpenAPI contract.");
}

List<String> errorMessages = new ArrayList<>();
Expand All @@ -117,8 +121,17 @@ public void generateService() throws IOException, BallerinaOpenApiException, For

writeGeneratedSources(genFiles, projectPath);

genServiceDeclaration(projectPath.resolve("service_contract.bal"), projectPath.resolve(
"service_implementation.bal"));
Path serviceImplPath = projectPath.resolve(SERVICE_IMPL_FILE);
genServiceDeclaration(projectPath.resolve(SERVICE_OBJ_FILE), serviceImplPath);

this.workspaceManager.loadProject(serviceImplPath);
Optional<Document> document = this.workspaceManager.document(serviceImplPath);
if (document.isEmpty()) {
throw new BallerinaOpenApiException("Invalid service implementation is generated.");
}

return LineRange.from(SERVICE_IMPL_FILE, LinePosition.from(1,
0), document.get().syntaxTree().rootNode().lineRange().endLine());
}

public List<GenSrcFile> generateBallerinaService(Path openAPI, Filter filter, List<Diagnostic> diagnostics)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ dependencies {
balTools("org.ballerinalang:jballerina-tools:${ballerinaLangVersion}") {
transitive = false
}
implementation files('libs/openapi-core-2.1.1-SNAPSHOT.jar')
implementation "io.ballerina.openapi:core:2.1.1-20240926-171100-1f88ade"
}

def balDistribution = file("$project.buildDir/extracted-distribution/jballerina-tools-${ballerinaLangVersion}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -398,8 +398,7 @@ public CompletableFuture<OpenApiServiceGenerationResponse> generateServiceFromOp
Path projectPath = Path.of(request.projectPath());
OpenApiServiceGenerator openApiServiceGenerator = new OpenApiServiceGenerator(openApiContractPath,
projectPath, request.port(), workspaceManager);
openApiServiceGenerator.generateService();
response.setSuccess(true);
response.setService(openApiServiceGenerator.generateService());
} catch (Throwable e) {
//TODO: Handle errors generated by the flow model generator service.
response.setError(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
package io.ballerina.flowmodelgenerator.extension.request;

/**
* Represents a request to generate the service from open api contract.
* Represents a request to generate the service from OpenAPI contract.
*
* @param openApiContractPath Location for open api contract
* @param openApiContractPath Location for OpenAPI contract
* @param projectPath Location for the generated services
* @param port port
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,22 @@

package io.ballerina.flowmodelgenerator.extension.response;

import io.ballerina.tools.text.LineRange;

/**
* Represents the response for open api service generation API.
* Represents the response for OpenAPI service generation API.
*
* @since 1.4.0
*/
public class OpenApiServiceGenerationResponse extends AbstractFlowModelResponse {

private boolean success;
private LineRange service;

public void setSuccess(boolean success) {
this.success = success;
public LineRange getService() {
return service;
}

public boolean isSuccess() {
return success;
public void setService(LineRange service) {
this.service = service;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

package io.ballerina.flowmodelgenerator.extension;

import com.google.gson.JsonObject;
import io.ballerina.flowmodelgenerator.extension.request.OpenAPIServiceGenerationRequest;
import org.ballerinalang.langserver.BallerinaLanguageServer;
import org.ballerinalang.langserver.util.TestUtil;
Expand All @@ -28,10 +29,11 @@

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

/**
* Test cases for the open api service generation.
* Test cases for the OpenAPI service generation.
*
* @since 1.4.0
*/
Expand All @@ -41,24 +43,30 @@ public class ServiceGeneratorTest extends AbstractLSTest {
@Override
protected Object[] getConfigsList() {
return new Object[][]{
{Path.of("petstore.yaml")}
{Path.of("config1.json")}
};
}

@Override
@Test(dataProvider = "data-provider")
public void test(Path contract) throws IOException {
public void test(Path config) throws IOException {
Endpoint endpoint = TestUtil.newLanguageServer().withLanguageServer(new BallerinaLanguageServer()).build();
Path contractPath = resDir.resolve("contracts").resolve(contract);
Path configJsonPath = configDir.resolve(config);
TestConfig testConfig = gson.fromJson(Files.newBufferedReader(configJsonPath), TestConfig.class);
Path contractPath = resDir.resolve("contracts").resolve(testConfig.contractFile());

Path project = resDir.resolve("project");
String projectPath = project.toAbsolutePath().toString();
OpenAPIServiceGenerationRequest request =
new OpenAPIServiceGenerationRequest(contractPath.toAbsolutePath().toString(), projectPath, 9090);
String success = getResponse(endpoint, request).get("success").getAsString();
Assert.assertEquals(success, "true");
TestUtil.shutdownLanguageServer(endpoint);
JsonObject resp = getResponse(endpoint, request);
deleteFolder(project.toFile());
if (!resp.getAsJsonObject("service").equals(testConfig.lineRange())) {
TestConfig updatedConfig = new TestConfig(testConfig.contractFile(), resp.get("service").getAsJsonObject());
updateConfig(configJsonPath, updatedConfig);
Assert.fail(String.format("Failed test: '%s'", configJsonPath));
}
TestUtil.shutdownLanguageServer(endpoint);
}

@Override
Expand All @@ -78,14 +86,25 @@ protected String getApiName() {

private void deleteFolder(File folder) {
File[] files = folder.listFiles();
if(files!=null) {
for(File f: files) {
if(f.isDirectory()) {
if (files != null) {
for (File f : files) {
if (f.isDirectory()) {
deleteFolder(f);
} else {
f.delete();
}
}
}
}

/**
* Represents the test configuration for the service generation.
*
* @param contractFile OpenAPI contract file
* @param lineRange line range of service declaration
* @since 1.4.0
*/
private record TestConfig(String contractFile, JsonObject lineRange) {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"contractFile": "petstore.yaml",
"lineRange": {
"fileName": "service_implementation.bal",
"startLine": {
"line": 1,
"offset": 0
},
"endLine": {
"line": 14,
"offset": 1
}
}
}

0 comments on commit e4540f5

Please sign in to comment.