diff --git a/modules/openapi-generator-online/README.md b/modules/openapi-generator-online/README.md index 6d731ceffa9c..6a9cf516c729 100644 --- a/modules/openapi-generator-online/README.md +++ b/modules/openapi-generator-online/README.md @@ -10,7 +10,7 @@ By using the [OpenAPI-Spec](https://openapis.org), you can easily generate a ser This is an example of building a OpenAPI-enabled server in Java using the SpringBoot framework. -The underlying library integrating OpenAPI to SpringBoot is [springfox](https://github.com/springfox/springfox) +The underlying library integrating OpenAPI to SpringBoot is [springdoc](https://github.com/springdoc/springdoc-openapi) ## Building @@ -28,13 +28,6 @@ java -jar ./target/openapi-generator-online.jar This exposes the API on local port 8080. -Springfox supports configuration of the "host" value in the output OpenAPI document by setting the `Host` HTTP header in the request. -To set this explicitly, pass the system property `springfox.documentation.swagger.v2.host` with the desired host. For example: - -``` -java -Dspringfox.documentation.swagger.v2.host=example.com:8888 -jar ./target/openapi-generator-online.jar -``` - ### Via Docker After building from source, change to this module directory (`cd modules/openapi-generator-online`) and build the docker image: diff --git a/modules/openapi-generator-online/pom.xml b/modules/openapi-generator-online/pom.xml index 08b7d222b7a6..362381122ef3 100644 --- a/modules/openapi-generator-online/pom.xml +++ b/modules/openapi-generator-online/pom.xml @@ -12,8 +12,10 @@ jar openapi-generator-online - 2.5.14 - 3.0.0 + 17 + 17 + 3.5.7 + 2.8.14 **/org/openapitools/codegen/online/**/* @@ -46,6 +48,13 @@ + + org.apache.maven.plugins + maven-compiler-plugin + + true + + org.apache.maven.plugins maven-checkstyle-plugin @@ -53,6 +62,13 @@ ${project.parent.basedir}${file.separator}google_checkstyle.xml + + org.apache.maven.plugins + maven-surefire-plugin + + org.junit.jupiter:junit-jupiter + + org.springframework.boot spring-boot-maven-plugin @@ -101,25 +117,11 @@ org.springframework.boot spring-boot-starter-web - + - io.springfox - springfox-swagger2 - ${springfox-version} - - - io.swagger - swagger-annotations - - - io.swagger - swagger-models - - - com.google.guava - guava - - + org.springdoc + springdoc-openapi-starter-webmvc-ui + ${springdoc-version} @@ -133,12 +135,6 @@ ${project.parent.version} - - org.junit.jupiter - junit-jupiter-api - ${junit.version} - test - org.springframework.boot spring-boot-starter-test diff --git a/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/OpenAPI2SpringBoot.java b/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/OpenAPI2SpringBoot.java index 6297bcb2ed6e..08d2b7868ea0 100644 --- a/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/OpenAPI2SpringBoot.java +++ b/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/OpenAPI2SpringBoot.java @@ -57,7 +57,9 @@ public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { - registry.addMapping("/**").allowedOrigins("*").allowedHeaders("Content-Type"); + registry.addMapping("/**") + .allowedOriginPatterns("*") + .allowedHeaders("Content-Type"); } }; } diff --git a/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/api/ApiOriginFilter.java b/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/api/ApiOriginFilter.java index a3594aae1430..9d8ec2786274 100644 --- a/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/api/ApiOriginFilter.java +++ b/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/api/ApiOriginFilter.java @@ -17,12 +17,12 @@ package org.openapitools.codegen.online.api; -import javax.servlet.*; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.*; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; -public class ApiOriginFilter implements javax.servlet.Filter { +public class ApiOriginFilter implements jakarta.servlet.Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { diff --git a/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/api/ApiUtil.java b/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/api/ApiUtil.java index f6b510480a27..f9fdd623538f 100644 --- a/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/api/ApiUtil.java +++ b/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/api/ApiUtil.java @@ -19,7 +19,7 @@ import org.springframework.web.context.request.NativeWebRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; public class ApiUtil { diff --git a/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/api/GenApi.java b/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/api/GenApi.java index 70e077cacec0..dcd6a959156d 100644 --- a/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/api/GenApi.java +++ b/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/api/GenApi.java @@ -22,94 +22,125 @@ */ package org.openapitools.codegen.online.api; -import io.swagger.annotations.*; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.parameters.RequestBody; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import org.openapitools.codegen.CliOption; import org.openapitools.codegen.online.model.GeneratorInput; import org.openapitools.codegen.online.model.ResponseCode; import org.springframework.core.io.Resource; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.bind.annotation.PostMapping; -import javax.validation.Valid; +import jakarta.validation.Valid; import java.util.List; import java.util.Map; -@Api(value = "gen", description = "the gen API") +@Tag(name = "clients", description = "Client generation APIs") +@Tag(name = "servers", description = "Server generation APIs") public interface GenApi { GenApiDelegate getDelegate(); - @ApiOperation(value = "Gets languages supported by the client generator", nickname = "clientOptions", notes = "", response = String.class, responseContainer = "List", tags = {"clients",}) + @Operation(summary = "Gets languages supported by the client generator", operationId = "clientOptions", tags = {"clients"}) @ApiResponses(value = { - @ApiResponse(code = 200, message = "successful operation", response = String.class, responseContainer = "List")}) - @RequestMapping(value = "/gen/clients", - method = RequestMethod.GET) + @ApiResponse(responseCode = "200", description = "successful operation")}) + @GetMapping("/gen/clients") default ResponseEntity> clientOptions() { return getDelegate().clientOptions(); } - @ApiOperation(value = "Downloads a pre-generated file", nickname = "downloadFile", notes = "A valid `fileId` is generated by the `/clients/{language}` or `/servers/{language}` POST operations. The fileId code can be used just once, after which a new `fileId` will need to be requested.", response = MultipartFile.class, tags = {"clients", "servers",}) + @Operation(summary = "Downloads a pre-generated file", operationId = "downloadFile", description = "A valid `fileId` is generated by the `/clients/{language}` or `/servers/{language}` POST operations. The fileId code can be used just once, after which a new `fileId` will need to be requested.", tags = {"clients", "servers"}) @ApiResponses(value = { - @ApiResponse(code = 200, message = "successful operation", response = MultipartFile.class)}) - @RequestMapping(value = "/gen/download/{fileId}", - produces = {"application/octet-stream"}, - method = RequestMethod.GET) - default ResponseEntity downloadFile(@ApiParam(value = "", required = true) @PathVariable("fileId") String fileId) { + @ApiResponse(responseCode = "200", description = "successful operation")}) + @GetMapping(value = "/gen/download/{fileId}", + produces = {"application/octet-stream"}) + default ResponseEntity downloadFile(@Parameter(description = "", required = true) @PathVariable String fileId) { return getDelegate().downloadFile(fileId); } - @ApiOperation(value = "Generates a client library", nickname = "generateClient", notes = "Accepts a `GeneratorInput` options map for spec location and generation options", response = ResponseCode.class, tags = {"clients",}) + @Operation(summary = "Generates a client library", operationId = "generateClient", description = "Accepts a `GeneratorInput` options map for spec location and generation options", tags = {"clients"}) @ApiResponses(value = { - @ApiResponse(code = 200, message = "successful operation", response = ResponseCode.class)}) - @RequestMapping(value = "/gen/clients/{language}", - method = RequestMethod.POST) - default ResponseEntity generateClient(@ApiParam(value = "The target language for the client library", required = true) @PathVariable("language") String language, @ApiParam(value = "Configuration for building the client library", required = true) @Valid @RequestBody GeneratorInput generatorInput) { + @ApiResponse(responseCode = "200", description = "successful operation")}) + @PostMapping(value = "/gen/clients/{language}", consumes = "application/json", produces = "application/json") + default ResponseEntity generateClient( + @Parameter(description = "The target language for the client library", required = true, example = "java") + @PathVariable String language, + @RequestBody(description = "Configuration for building the client library", required = true, + content = @Content(mediaType = "application/json", + schema = @Schema(implementation = GeneratorInput.class), + examples = { + @ExampleObject(name = "Basic Example", + summary = "Basic client generation with OpenAPI URL", + value = "{\"openAPIUrl\": \"https://raw.githubusercontent.com/OpenAPITools/openapi-generator/master/modules/openapi-generator/src/test/resources/3_0/petstore.yaml\", \"options\": {\"packageName\": \"com.example.client\", \"clientPackage\": \"com.example.client\"}}"), + @ExampleObject(name = "With Options", + summary = "Client generation with additional options", + value = "{\"openAPIUrl\": \"https://raw.githubusercontent.com/OpenAPITools/openapi-generator/master/modules/openapi-generator/src/test/resources/3_0/petstore.yaml\", \"options\": {\"packageName\": \"com.example.petstore\", \"clientPackage\": \"com.example.petstore.client\", \"groupId\": \"com.example\", \"artifactId\": \"petstore-client\", \"artifactVersion\": \"1.0.0\"}}") + })) + @Valid + @org.springframework.web.bind.annotation.RequestBody GeneratorInput generatorInput) { return getDelegate().generateClient(language, generatorInput); } - @ApiOperation(value = "Generates a server library", nickname = "generateServerForLanguage", notes = "Accepts a `GeneratorInput` options map for spec location and generation options.", response = ResponseCode.class, tags = {"servers",}) + @Operation(summary = "Generates a server library", operationId = "generateServerForLanguage", description = "Accepts a `GeneratorInput` options map for spec location and generation options.", tags = {"servers"}) @ApiResponses(value = { - @ApiResponse(code = 200, message = "successful operation", response = ResponseCode.class)}) - @RequestMapping(value = "/gen/servers/{framework}", - method = RequestMethod.POST) - default ResponseEntity generateServerForLanguage(@ApiParam(value = "framework", required = true) @PathVariable("framework") String framework, @ApiParam(value = "parameters", required = true) @Valid @RequestBody GeneratorInput generatorInput) { + @ApiResponse(responseCode = "200", description = "successful operation")}) + @PostMapping(value = "/gen/servers/{framework}", consumes = "application/json", produces = "application/json") + default ResponseEntity generateServerForLanguage( + @Parameter(description = "The target server framework", required = true, example = "spring") + @PathVariable String framework, + @RequestBody(description = "Configuration for building the server library", required = true, + content = @Content(mediaType = "application/json", + schema = @Schema(implementation = GeneratorInput.class), + examples = { + @ExampleObject(name = "Basic Example", + summary = "Basic server generation with OpenAPI URL", + value = "{\"openAPIUrl\": \"https://raw.githubusercontent.com/OpenAPITools/openapi-generator/master/modules/openapi-generator/src/test/resources/3_0/petstore.yaml\", \"options\": {\"packageName\": \"com.example.server\", \"basePackage\": \"com.example.server\"}}"), + @ExampleObject(name = "Spring Boot Server", + summary = "Spring Boot server generation with options", + value = "{\"openAPIUrl\": \"https://raw.githubusercontent.com/OpenAPITools/openapi-generator/master/modules/openapi-generator/src/test/resources/3_0/petstore.yaml\", \"options\": {\"packageName\": \"com.example.petstore.server\", \"basePackage\": \"com.example.petstore\", \"groupId\": \"com.example\", \"artifactId\": \"petstore-server\", \"artifactVersion\": \"1.0.0\"}}") + })) + @Valid + @org.springframework.web.bind.annotation.RequestBody + GeneratorInput generatorInput) { return getDelegate().generateServerForLanguage(framework, generatorInput); } - @ApiOperation(value = "Returns options for a client library", nickname = "getClientOptions", notes = "", tags = {"clients",}) + @Operation(summary = "Returns options for a client library", operationId = "getClientOptions", tags = {"clients"}) @ApiResponses(value = { - @ApiResponse(code = 200, message = "successful operation")}) - @RequestMapping(value = "/gen/clients/{language}", - produces = {"application/json"}, - method = RequestMethod.GET) - default ResponseEntity> getClientOptions(@ApiParam(value = "The target language for the client library", required = true) @PathVariable("language") String language) { + @ApiResponse(responseCode = "200", description = "successful operation")}) + @GetMapping(value = "/gen/clients/{language}", + produces = {"application/json"}) + default ResponseEntity> getClientOptions(@Parameter(description = "The target language for the client library", required = true) @PathVariable String language) { return getDelegate().getClientOptions(language); } - @ApiOperation(value = "Returns options for a server framework", nickname = "getServerOptions", notes = "", tags = {"servers",}) + @Operation(summary = "Returns options for a server framework", operationId = "getServerOptions", tags = {"servers"}) @ApiResponses(value = { - @ApiResponse(code = 200, message = "successful operation")}) - @RequestMapping(value = "/gen/servers/{framework}", - produces = {"application/json"}, - method = RequestMethod.GET) - default ResponseEntity> getServerOptions(@ApiParam(value = "The target language for the server framework", required = true) @PathVariable("framework") String framework) { + @ApiResponse(responseCode = "200", description = "successful operation")}) + @GetMapping(value = "/gen/servers/{framework}", + produces = {"application/json"}) + default ResponseEntity> getServerOptions(@Parameter(description = "The target language for the server framework", required = true) @PathVariable String framework) { return getDelegate().getServerOptions(framework); } - @ApiOperation(value = "Gets languages supported by the server generator", nickname = "serverOptions", notes = "", response = String.class, responseContainer = "List", tags = {"servers",}) + @Operation(summary = "Gets languages supported by the server generator", operationId = "serverOptions", tags = {"servers"}) @ApiResponses(value = { - @ApiResponse(code = 200, message = "successful operation", response = String.class, responseContainer = "List")}) - @RequestMapping(value = "/gen/servers", - method = RequestMethod.GET) + @ApiResponse(responseCode = "200", description = "successful operation")}) + @GetMapping("/gen/servers") default ResponseEntity> serverOptions() { return getDelegate().serverOptions(); } diff --git a/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/api/GenApiController.java b/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/api/GenApiController.java index 190cc107ed2d..6465a59f7347 100644 --- a/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/api/GenApiController.java +++ b/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/api/GenApiController.java @@ -17,7 +17,6 @@ package org.openapitools.codegen.online.api; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @@ -27,7 +26,6 @@ public class GenApiController implements GenApi { private final GenApiDelegate delegate; - @Autowired public GenApiController(GenApiDelegate delegate) { this.delegate = delegate; } diff --git a/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/configuration/OpenAPIDocumentationConfig.java b/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/configuration/OpenAPIDocumentationConfig.java index 26e9b34856d6..8e0271457768 100644 --- a/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/configuration/OpenAPIDocumentationConfig.java +++ b/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/configuration/OpenAPIDocumentationConfig.java @@ -17,36 +17,24 @@ package org.openapitools.codegen.online.configuration; -import com.fasterxml.jackson.databind.JsonNode; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Contact; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.info.License; +import io.swagger.v3.oas.models.servers.Server; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.core.io.Resource; -import springfox.documentation.builders.ApiInfoBuilder; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.service.ApiInfo; -import springfox.documentation.service.Contact; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.swagger2.annotations.EnableSwagger2; import java.io.IOException; import java.io.InputStream; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.HashSet; +import java.util.List; import java.util.Properties; -import java.util.Set; - @Configuration -@EnableSwagger2 public class OpenAPIDocumentationConfig { - private final Logger LOGGER = LoggerFactory.getLogger(OpenAPIDocumentationConfig.class); - ApiInfo apiInfo() { + @Bean + public OpenAPI customOpenAPI() { final Properties properties = new Properties(); try (InputStream stream = this.getClass().getResourceAsStream("/version.properties")) { if (stream != null) { @@ -58,53 +46,16 @@ ApiInfo apiInfo() { String version = properties.getProperty("version", "unknown"); - return new ApiInfoBuilder() - .title("OpenAPI Generator Online") - .description("This is an online openapi generator server. You can find out more at https://github.com/OpenAPITools/openapi-generator.") - .license("Apache 2.0") - .licenseUrl("https://www.apache.org/licenses/LICENSE-2.0.html") - .termsOfServiceUrl("") - .version(version) - .contact(new Contact("", "", "")) - .build(); - } - - @Bean - public Docket customImplementation() { - Docket docket = new Docket(DocumentationType.SWAGGER_2) - .select() - .apis(RequestHandlerSelectors.basePackage("org.openapitools.codegen.online.api")) - .build() - .forCodeGeneration(true) - .directModelSubstitute(java.time.LocalDate.class, java.sql.Date.class) - .directModelSubstitute(java.time.OffsetDateTime.class, java.util.Date.class) - .directModelSubstitute(JsonNode.class, java.lang.Object.class) - .ignoredParameterTypes(Resource.class) - .ignoredParameterTypes(InputStream.class) - .apiInfo(apiInfo()); - - String hostString = System.getenv("GENERATOR_HOST"); - if (!StringUtils.isBlank(hostString)) { - try { - URI hostURI = new URI(hostString); - String scheme = hostURI.getScheme(); - if (scheme != null) { - Set protocols = new HashSet(); - protocols.add(scheme); - docket.protocols(protocols); - } - String authority = hostURI.getAuthority(); - if (authority != null) { - // In OpenAPI `host` refers to host _and_ port, a.k.a. the URI authority - docket.host(authority); - } - docket.pathMapping(hostURI.getPath()); - } catch (URISyntaxException e) { - LOGGER.warn("Could not parse configured GENERATOR_HOST '" + hostString + "': " + e.getMessage()); - } - } - - return docket; + return new OpenAPI() + .info(new Info() + .title("OpenAPI Generator Online") + .description("This is an online OpenAPI generator server. You can generate client libraries, server stubs, and API documentation from OpenAPI specifications. Find out more at https://github.com/OpenAPITools/openapi-generator.") + .version(version) + .license(new License() + .name("Apache 2.0") + .url("https://www.apache.org/licenses/LICENSE-2.0.html")) + .contact(new Contact() + .name("OpenAPI Generator Team") + .url("https://github.com/OpenAPITools/openapi-generator"))); } - -} +} \ No newline at end of file diff --git a/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/configuration/ParameterAllowableValuesPlugin.java b/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/configuration/ParameterAllowableValuesPlugin.java deleted file mode 100644 index 00014f5ab9b5..000000000000 --- a/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/configuration/ParameterAllowableValuesPlugin.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.openapitools.codegen.online.configuration; - -import org.openapitools.codegen.CodegenConfig; -import org.openapitools.codegen.CodegenConfigLoader; -import org.openapitools.codegen.CodegenType; -import org.springframework.stereotype.Component; -import springfox.documentation.service.AllowableListValues; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spi.service.ParameterBuilderPlugin; -import springfox.documentation.spi.service.contexts.ParameterContext; - -import java.util.ArrayList; -import java.util.List; - -@Component -public class ParameterAllowableValuesPlugin implements ParameterBuilderPlugin { - - private static List clients = new ArrayList<>(); - private static List servers = new ArrayList<>(); - - static { - List extensions = CodegenConfigLoader.getAll(); - for (CodegenConfig config : extensions) { - if (config.getTag().equals(CodegenType.CLIENT) - || config.getTag().equals(CodegenType.DOCUMENTATION)) { - clients.add(config.getName()); - } else if (config.getTag().equals(CodegenType.SERVER)) { - servers.add(config.getName()); - } - } - - clients.sort(String.CASE_INSENSITIVE_ORDER); - servers.sort(String.CASE_INSENSITIVE_ORDER); - } - - @Override - public void apply(ParameterContext parameterContext) { - String name = parameterContext.getOperationContext().getName(); - switch (name) { - case "getClientOptions": - case "generateClient": - parameterContext.parameterBuilder().allowableValues(new AllowableListValues(clients, "string")); - break; - case "getServerOptions": - case "generateServerForLanguage": - parameterContext.parameterBuilder().allowableValues(new AllowableListValues(servers, "string")); - } - } - - @Override - public boolean supports(DocumentationType documentationType) { - return true; - } -} diff --git a/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/model/ApiResponse.java b/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/model/ApiResponse.java index 9bbc4457bd42..5fee3e173f6e 100644 --- a/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/model/ApiResponse.java +++ b/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/model/ApiResponse.java @@ -17,13 +17,15 @@ package org.openapitools.codegen.online.model; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; import lombok.Setter; -import javax.xml.bind.annotation.XmlTransient; +import jakarta.xml.bind.annotation.XmlTransient; @Setter -@javax.xml.bind.annotation.XmlRootElement +@jakarta.xml.bind.annotation.XmlRootElement +@Schema(description = "API response object") public class ApiResponse { public static final int ERROR = 1; public static final int WARNING = 2; @@ -31,9 +33,16 @@ public class ApiResponse { public static final int OK = 4; public static final int TOO_BUSY = 5; + @Schema(description = "Response code", example = "4") int code; - @Getter String type; - @Getter String message; + + @Getter + @Schema(description = "Response type", example = "ok") + String type; + + @Getter + @Schema(description = "Response message", example = "Operation completed successfully") + String message; public ApiResponse() { } diff --git a/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/model/GeneratorInput.java b/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/model/GeneratorInput.java index be8f8c55f370..1d4832cdcd97 100644 --- a/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/model/GeneratorInput.java +++ b/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/model/GeneratorInput.java @@ -17,8 +17,9 @@ package org.openapitools.codegen.online.model; +import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.parser.core.models.AuthorizationValue; import lombok.Getter; import lombok.Setter; @@ -26,17 +27,24 @@ import java.util.List; import java.util.Map; +@Getter @Setter +@Schema(description = "Configuration for building the client library") public class GeneratorInput { - @Getter private JsonNode spec; - @Getter private Map options; + + @Schema(description = "OpenAPI specification as JSON object", example = "{\"openapi\": \"3.0.0\", \"info\": {\"title\": \"Sample API\", \"version\": \"1.0.0\"}}") + private JsonNode spec; + + @Schema(description = "Generator-specific options", example = "{\"packageName\": \"com.example.client\", \"clientPackage\": \"com.example.client\"}") + private Map options; + + @Schema(description = "URL to the OpenAPI specification", example = "https://raw.githubusercontent.com/OpenAPITools/openapi-generator/master/modules/openapi-generator/src/test/resources/2_0/petstore.yaml", required = false) + @JsonProperty("openAPIUrl") private String openAPIUrl; - @Getter private AuthorizationValue authorizationValue; - //FILTER=operationId:updatePet - @Getter private List openapiNormalizer; - - @ApiModelProperty(example = "https://raw.githubusercontent.com/OpenAPITools/openapi-generator/master/modules/openapi-generator/src/test/resources/2_0/petstore.yaml") - public String getOpenAPIUrl() { - return openAPIUrl; - } + + @Schema(description = "Authorization value for accessing the OpenAPI specification") + private AuthorizationValue authorizationValue; + + @Schema(description = "OpenAPI normalizer rules", example = "[\"FILTER=operationId:updatePet\"]") + private List openapiNormalizer; } diff --git a/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/model/ResponseCode.java b/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/model/ResponseCode.java index a343f647e910..abaa66f3e98d 100644 --- a/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/model/ResponseCode.java +++ b/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/model/ResponseCode.java @@ -17,7 +17,7 @@ package org.openapitools.codegen.online.model; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; import lombok.Setter; @@ -29,14 +29,14 @@ public class ResponseCode { private String code; private String link; - @ApiModelProperty(value = "File download code", + @Schema(description = "File download code", example = "d40029be-eda6-4d62-b1ef-d05e2e91a72a") public String getCode() { return code; } - @ApiModelProperty( - value = "URL for fetching the generated client", + @Schema( + description = "URL for fetching the generated client", example = "http://localhost:8080/api/gen/download/d40029be-eda6-4d62-b1ef-d05e2e91a72a") public String getLink() { return link; diff --git a/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/service/GenApiService.java b/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/service/GenApiService.java index f10599b59376..6e2e015c5d94 100644 --- a/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/service/GenApiService.java +++ b/modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/service/GenApiService.java @@ -44,7 +44,6 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.*; @Service @@ -84,7 +83,7 @@ public ResponseEntity downloadFile(String fileId) { System.out.println("got filename " + g.getFilename()); File file = new File(g.getFilename()); - Path path = Paths.get(file.getAbsolutePath()); + Path path = Path.of(file.getAbsolutePath()); ByteArrayResource resource; try { resource = new ByteArrayResource(Files.readAllBytes(path)); diff --git a/modules/openapi-generator-online/src/main/resources/application.properties b/modules/openapi-generator-online/src/main/resources/application.properties index 98e895618562..27a8701697dc 100644 --- a/modules/openapi-generator-online/src/main/resources/application.properties +++ b/modules/openapi-generator-online/src/main/resources/application.properties @@ -1,5 +1,9 @@ -springfox.documentation.swagger.v2.path=/api-docs server.port=8080 spring.jackson.date-format=org.openapitools.codegen.online.RFC3339DateFormat spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false -spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/ +spring.web.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/ +springdoc.api-docs.path=/api-docs +springdoc.swagger-ui.path=/swagger-ui.html +springdoc.swagger-ui.try-it-out-enabled=true +springdoc.swagger-ui.operations-sorter=alpha +springdoc.swagger-ui.tags-sorter=alpha \ No newline at end of file diff --git a/modules/openapi-generator-online/src/test/java/org/openapitools/codegen/online/api/GenApiControllerTest.java b/modules/openapi-generator-online/src/test/java/org/openapitools/codegen/online/api/GenApiControllerTest.java index 81dfe3425774..9847d36a81e5 100644 --- a/modules/openapi-generator-online/src/test/java/org/openapitools/codegen/online/api/GenApiControllerTest.java +++ b/modules/openapi-generator-online/src/test/java/org/openapitools/codegen/online/api/GenApiControllerTest.java @@ -10,11 +10,10 @@ import org.springframework.http.MediaType; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.MockMvc; -import org.springframework.util.Assert; -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.text.MatchesPattern.matchesPattern; +import static org.hamcrest.Matchers.*; +import static org.junit.jupiter.api.Assertions.assertTrue; + import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @@ -93,7 +92,7 @@ private void generateAndDownload(String type, String name) throws Exception { .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andExpect(jsonPath("$.code").value(matchesPattern(UUID_REGEX))) - .andExpect(jsonPath("$.link").value(matchesPattern("http\\:\\/\\/test.com\\:1234\\/api\\/gen\\/download\\/" + UUID_REGEX))) + .andExpect(jsonPath("$.link").value(matchesPattern("http://test.com:1234/api/gen/download/" + UUID_REGEX))) .andReturn().getResponse().getContentAsString(); String code = new ObjectMapper().readValue(result, ResponseCode.class).getCode(); @@ -115,7 +114,7 @@ public void generateWIthForwardedHeaders() throws Exception { .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andExpect(jsonPath("$.code").value(matchesPattern(UUID_REGEX))) - .andExpect(jsonPath("$.link").value(matchesPattern("https\\:\\/\\/forwarded.com\\:5678\\/api\\/gen\\/download\\/" + UUID_REGEX))) + .andExpect(jsonPath("$.link").value(matchesPattern("https://forwarded.com:5678/api/gen/download/" + UUID_REGEX))) .andReturn().getResponse().getContentAsString(); String code = new ObjectMapper().readValue(result, ResponseCode.class).getCode(); @@ -159,7 +158,7 @@ public void generateWithOpenAPINormalizer() throws Exception { .andExpect(content().contentType("application/zip")) .andExpect(status().isOk()).andReturn().getResponse().getHeader("Content-Length")); - Assert.isTrue(lengthOfNormalized <= lengthOfNotNormalized, "Using the normalizer should result in a smaller or equal file size"); + assertTrue(lengthOfNormalized <= lengthOfNotNormalized, "Using the normalizer should result in a smaller or equal file size"); } }