Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Vert.x Web template to Vert.x 4 #7364

Merged
merged 5 commits into from
Sep 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
generatorName: java-vertx-web
outputDir: samples/server/petstore/java-vertx-web/rx
outputDir: samples/server/petstore/java-vertx-web
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/JavaVertXWebServer
additionalProperties:
hideGenerationTimestamp: "true"
artifactId: java-vertx-web-rx-server
artifactId: java-vertx-web-server
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,14 @@
package org.openapitools.codegen.languages;

import io.swagger.v3.oas.models.media.Schema;
import org.openapitools.codegen.CodegenConstants;
import org.openapitools.codegen.CodegenModel;
import org.openapitools.codegen.CodegenOperation;
import org.openapitools.codegen.CodegenProperty;
import org.openapitools.codegen.CodegenType;
import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.GeneratorMetadata;
import org.openapitools.codegen.meta.Stability;
import org.openapitools.codegen.SupportingFile;

import java.io.File;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class JavaVertXWebServerCodegen extends AbstractJavaCodegen {

Expand Down Expand Up @@ -69,7 +64,7 @@ public JavaVertXWebServerCodegen() {
updateOption(CodegenConstants.API_PACKAGE, apiPackage);
updateOption(CodegenConstants.MODEL_PACKAGE, modelPackage);
updateOption(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
updateOption(this.DATE_LIBRARY, this.getDateLibrary());
updateOption(DATE_LIBRARY, this.getDateLibrary());

// Override type mapping
typeMapping.put("file", "FileUpload");
Expand Down Expand Up @@ -99,6 +94,7 @@ public void processOpts() {
importMapping.put("JsonProperty", "com.fasterxml.jackson.annotation.JsonProperty");
importMapping.put("JsonValue", "com.fasterxml.jackson.annotation.JsonValue");
importMapping.put("FileUpload", "io.vertx.ext.web.FileUpload");
importMapping.put("JsonObject", "io.vertx.core.json.JsonObject");

modelDocTemplateFiles.clear();
apiDocTemplateFiles.clear();
Expand All @@ -107,10 +103,7 @@ public void processOpts() {
supportingFiles.clear();
supportingFiles.add(new SupportingFile("supportFiles/openapi.mustache", resourceFolder, "openapi.yaml"));
supportingFiles.add(new SupportingFile("supportFiles/HttpServerVerticle.mustache", sourcePackageFolder, "HttpServerVerticle.java"));
supportingFiles.add(new SupportingFile("supportFiles/MainVerticle.mustache", sourcePackageFolder, "MainVerticle.java"));
supportingFiles.add(new SupportingFile("supportFiles/ApiResponse.mustache", sourcePackageFolder, "ApiResponse.java"));
supportingFiles.add(new SupportingFile("supportFiles/ApiException.mustache", sourcePackageFolder, "ApiException.java"));
supportingFiles.add(new SupportingFile("supportFiles/ParameterCast.mustache", sourcePackageFolder, "ParameterCast.java"));
supportingFiles.add(new SupportingFile("supportFiles/pom.mustache", "", "pom.xml"));

supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")
Expand All @@ -129,6 +122,7 @@ public void postProcessModelProperty(CodegenModel model, CodegenProperty propert
}
}

@SuppressWarnings("unchecked")
@Override
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) {
Map<String, Object> newObjs = super.postProcessOperationsWithModels(objs, allModels);
Expand All @@ -141,11 +135,39 @@ public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> o
if (operation.returnType == null) {
operation.returnType = "Void";
}
if (operation.allParams.stream().anyMatch(p -> p.isFormParam && p.isFile)) {
// If there is a file upload, exclude other form params since it's not clear how the user should access to these
operation.allParams = operation
.allParams
.stream()
.filter(p -> !p.isFormParam || p.isFile)
.collect(Collectors.toList());
} else if (operation.allParams.stream().anyMatch(p -> p.isFormParam)) {
// In Vert.x 4 Web OpenAPI the forms are handled as single json object
// We create a dummy param here and remove the other ones
CodegenParameter dummyParam = new CodegenParameter();
dummyParam.isFormParam = true;
dummyParam.isFile = false;
dummyParam.dataType = "JsonObject";
dummyParam.paramName = "formBody";
operation.allParams = Stream.concat(
operation.allParams.stream().filter(p -> !p.isFormParam),
Stream.of(dummyParam)
).collect(Collectors.toList());
}
}
}
return newObjs;
}

@Override
public void postProcessParameter(CodegenParameter parameter) {
super.postProcessParameter(parameter);
if (parameter.isUuid || parameter.isDate || parameter.isDateTime) {
parameter.dataType = "String";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@slinkydeveloper what about updating typeMapping instead to map these types (e.g. UUID) with "String"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WDYM? Vert.x doesn't have any "strong" mapping for uuid/date/datetime

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll submit a separate PR to show you how I would have done it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've filed #7457. Please take a look when you've time.

}
}

@Override
public Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
generateYAMLSpecFile(objs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,15 @@ Project generated on : {{generatedDate}}
This document assumes you have maven available.

To build the project using maven, run:

```bash
mvn package
```

To run the project, run the jar or use maven exec plugin:

```bash
mvn package && java -jar target/target/java-vertx-web-rx-server-{{artifactVersion}}-fat.jar
mvn exec:java
```

If all builds successfully, the server should run on [http://localhost:8080/](http://localhost:8080/)
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ package {{package}};

import {{invokerPackage}}.ApiResponse;

import io.reactivex.Single;
import io.vertx.core.Future;
import io.vertx.core.json.JsonObject;

import java.util.List;
import java.util.Map;

public interface {{classname}} {
{{#operations}}
{{#operation}}
Single<ApiResponse<{{{returnType}}}>> {{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}},{{/hasMore}}{{/allParams}});
Future<ApiResponse<{{{returnType}}}>> {{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
{{/operation}}
{{/operations}}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,66 +3,61 @@ package {{package}};
{{#imports}}import {{import}};
{{/imports}}

import {{invokerPackage}}.ParameterCast;
import {{invokerPackage}}.ApiException;

import com.fasterxml.jackson.core.type.TypeReference;
import io.vertx.core.json.Json;
import io.vertx.core.Handler;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.core.json.jackson.DatabindCodec;
import io.vertx.ext.web.openapi.RouterFactory;
import io.vertx.ext.web.validation.RequestParameters;
import io.vertx.ext.web.validation.RequestParameter;
import io.vertx.ext.web.validation.ValidationHandler;
import io.vertx.ext.web.RoutingContext;
import io.vertx.core.json.JsonObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.reactivex.Single;

import java.util.List;
import java.util.Map;

public class {{classname}}Handler {

private static final Logger logger = LoggerFactory.getLogger({{classname}}Handler.class);
private {{classname}} apiImpl = new {{classname}}Impl();

public {{classname}}Handler(Map<String, Handler<RoutingContext>> operationHandlers) {
private final {{classname}} apiImpl;

public {{classname}}Handler() {
this.apiImpl = new {{classname}}Impl();
}

public void mount(RouterFactory factory) {
{{#operations}}
{{#operation}}
operationHandlers.put("{{operationId}}", this::{{operationId}});
factory.operation("{{operationId}}").handler(this::{{operationId}});
{{/operation}}
{{/operations}}
}

{{#operations}}
{{#operation}}

private void {{operationId}}(RoutingContext routingContext) {
logger.info("{{operationId}}()");
HttpServerResponse response = routingContext.response();

{{#returnType}}Single{{/returnType}}{{^returnType}}Completable{{/returnType}}.defer( () -> {
{{#allParams}}{{^isBodyParam}}{{>headerParams}}{{>pathParams}}{{>queryParams}}{{>formParams}}{{/isBodyParam}}{{/allParams}}
{{#allParams}}
{{#isBodyParam}}
String jsonString = routingContext.getBodyAsString();
{{{dataType}}} {{paramName}} = jsonString == null ? null : Json.decodeValue(jsonString, new TypeReference<{{{dataType}}}>(){});
{{/isBodyParam}}
{{/allParams}}
// Param extraction
RequestParameters requestParameters = routingContext.get(ValidationHandler.REQUEST_CONTEXT_KEY);

{{#allParams}}{{>headerParams}}{{>pathParams}}{{>queryParams}}{{>formParams}}{{>bodyParams}}{{/allParams}}
{{#allParams}}
logger.info("Parameter {{paramName}} is {}", {{paramName}});
logger.debug("Parameter {{paramName}} is {}", {{paramName}});
{{/allParams}}
return apiImpl.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
})
.subscribe(
apiResponse -> {
response.setStatusCode(apiResponse.getStatusCode())
.end(Json.encodePrettily(apiResponse.getData()));
}, error -> {
if (error instanceof ApiException) {
ApiException apiException = (ApiException) error;
response.setStatusCode(apiException.getStatusCode()).end(apiException.getMessage());

apiImpl.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
.onSuccess(apiResponse -> {
routingContext.response().setStatusCode(apiResponse.getStatusCode());
if (apiResponse.hasData()) {
routingContext.json(apiResponse.getData());
} else {
response.setStatusCode(500).end(error.getMessage());
routingContext.response().end();
}
}).dispose();
})
.onFailure(routingContext::fail);
}

{{/operation}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ package {{package}};
{{/imports}}

import {{invokerPackage}}.ApiResponse;
import {{invokerPackage}}.ApiException;

import io.reactivex.Single;
import io.vertx.core.Future;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.handler.impl.HttpStatusException;

import java.util.List;
import java.util.Map;
Expand All @@ -16,8 +17,8 @@ import java.util.Map;
public class {{classname}}Impl implements {{classname}} {
{{#operations}}
{{#operation}}
public Single<ApiResponse<{{{returnType}}}>> {{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}},{{/hasMore}}{{/allParams}}) {
return Single.error(new ApiException("Not Implemented").setStatusCode(501));
public Future<ApiResponse<{{{returnType}}}>> {{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) {
return Future.failedFuture(new HttpStatusException(501));
}

{{/operation}}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{{#isBodyParam}}
RequestParameter body = requestParameters.body();
{{{dataType}}} {{paramName}} = body != null ? DatabindCodec.mapper().convertValue(body.get(), new TypeReference<{{{dataType}}}>(){}) : null;
{{/isBodyParam}}
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
{{#isFormParam}}
{{^isListContainer}}
{{^isFile}}
{{#isModel}}
{{{dataType}}} {{paramName}} = ParameterCast.toObject(routingContext.request().getFormAttribute("{{baseName}}"), {{dataType}}.class);
{{/isModel}}
{{^isModel}}
{{{dataType}}} {{paramName}} = ParameterCast.to{{dataType}}(routingContext.request().getFormAttribute("{{baseName}}"));
{{/isModel}}
RequestParameter body = requestParameters.body();
JsonObject {{paramName}} = body != null ? body.getJsonObject() : null;
{{/isFile}}
{{#isFile}}
{{{dataType}}} {{paramName}} = routingContext.fileUploads().iterator().next();
{{{dataType}}} {{paramName}} = routingContext.fileUploads().iterator().next();
{{/isFile}}
{{/isListContainer}}
{{#isListContainer}}
{{{dataType}}} {{paramName}} = routingContext.request().params().getAll("{{baseName}}");
{{/isListContainer}}
{{/isFormParam}}
{{/isFormParam}}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{{#isHeaderParam}}
{{^isListContainer}}
{{#isModel}}
{{{dataType}}} {{paramName}} = ParameterCast.toObject(routingContext.request().getHeader("{{baseName}}"), {{dataType}}.class);
{{{dataType}}} {{paramName}} = requestParameters.headerParameter("{{baseName}}") != null ? DatabindCodec.mapper().convertValue(requestParameters.headerParameter("{{baseName}}").get(), new TypeReference<{{{dataType}}}>(){}) : null;
{{/isModel}}
{{^isModel}}
{{{dataType}}} {{paramName}} = ParameterCast.to{{dataType}}(routingContext.request().getHeader("{{baseName}}"));
{{{dataType}}} {{paramName}} = requestParameters.headerParameter("{{baseName}}") != null ? requestParameters.headerParameter("{{baseName}}").get{{dataType}}() : null;
{{/isModel}}
{{/isListContainer}}
{{#isListContainer}}
{{{dataType}}} {{paramName}} = routingContext.request().params().getAll("{{baseName}}");
{{{dataType}}} {{paramName}} = requestParameters.headerParameter("{{baseName}}") != null ? DatabindCodec.mapper().convertValue(requestParameters.headerParameter("{{baseName}}").get(), new TypeReference<{{{dataType}}}>(){}) : null;
{{/isListContainer}}
{{/isHeaderParam}}
{{/isHeaderParam}}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{{#isPathParam}}
{{^isListContainer}}
{{#isModel}}
{{{dataType}}} {{paramName}} = ParameterCast.toObject(routingContext.pathParams().get("{{baseName}}"), {{dataType}}.class);
{{{dataType}}} {{paramName}} = requestParameters.pathParameter("{{baseName}}") != null ? DatabindCodec.mapper().convertValue(requestParameters.pathParameter("{{baseName}}").get(), new TypeReference<{{{dataType}}}>(){}) : null;
{{/isModel}}
{{^isModel}}
{{{dataType}}} {{paramName}} = ParameterCast.to{{dataType}}(routingContext.pathParams().get("{{baseName}}"));
{{{dataType}}} {{paramName}} = requestParameters.pathParameter("{{baseName}}") != null ? requestParameters.pathParameter("{{baseName}}").get{{dataType}}() : null;
{{/isModel}}
{{/isListContainer}}
{{#isListContainer}}
{{{dataType}}} {{paramName}} = routingContext.request().params().getAll("{{baseName}}");
{{{dataType}}} {{paramName}} = requestParameters.pathParameter("{{baseName}}") != null ? DatabindCodec.mapper().convertValue(requestParameters.pathParameter("{{baseName}}").get(), new TypeReference<{{{dataType}}}>(){}) : null;
{{/isListContainer}}
{{/isPathParam}}
{{/isPathParam}}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{{#isQueryParam}}
{{^isListContainer}}
{{#isModel}}
{{{dataType}}} {{paramName}} = ParameterCast.toObject(routingContext.queryParams().get("{{baseName}}"), {{dataType}}.class);
{{{dataType}}} {{paramName}} = requestParameters.queryParameter("{{baseName}}") != null ? DatabindCodec.mapper().convertValue(requestParameters.queryParameter("{{baseName}}").get(), new TypeReference<{{{dataType}}}>(){}) : null;
{{/isModel}}
{{^isModel}}
{{{dataType}}} {{paramName}} = ParameterCast.to{{dataType}}(routingContext.queryParams().get("{{baseName}}"));
{{{dataType}}} {{paramName}} = requestParameters.queryParameter("{{baseName}}") != null ? requestParameters.queryParameter("{{baseName}}").get{{dataType}}() : null;
{{/isModel}}
{{/isListContainer}}
{{#isListContainer}}
{{{dataType}}} {{paramName}} = routingContext.request().params().getAll("{{baseName}}");
{{{dataType}}} {{paramName}} = requestParameters.queryParameter("{{baseName}}") != null ? DatabindCodec.mapper().convertValue(requestParameters.queryParameter("{{baseName}}").get(), new TypeReference<{{{dataType}}}>(){}) : null;
{{/isListContainer}}
{{/isQueryParam}}
{{/isQueryParam}}

This file was deleted.

Loading