From 725aae21484d70bd402c0fce53ea9fb6bee87807 Mon Sep 17 00:00:00 2001 From: Shubham Kalloli Date: Mon, 10 Nov 2025 16:44:07 +0000 Subject: [PATCH 1/4] Upgraded Spring Boot to 3.5 --- modules/openapi-generator-online/pom.xml | 46 +++---- .../codegen/online/OpenAPI2SpringBoot.java | 4 +- .../codegen/online/api/ApiOriginFilter.java | 6 +- .../codegen/online/api/ApiUtil.java | 2 +- .../codegen/online/api/GenApi.java | 114 +++++++++++------- .../codegen/online/api/GenApiController.java | 2 - .../OpenAPIDocumentationConfig.java | 93 ++++---------- .../ParameterAllowableValuesPlugin.java | 54 --------- .../codegen/online/model/ApiResponse.java | 17 ++- .../codegen/online/model/GeneratorInput.java | 29 +++-- .../codegen/online/model/ResponseCode.java | 8 +- .../codegen/online/service/GenApiService.java | 3 +- .../src/main/resources/application.properties | 8 +- .../online/api/GenApiControllerTest.java | 52 ++++++-- 14 files changed, 213 insertions(+), 225 deletions(-) delete mode 100644 modules/openapi-generator-online/src/main/java/org/openapitools/codegen/online/configuration/ParameterAllowableValuesPlugin.java diff --git a/modules/openapi-generator-online/pom.xml b/modules/openapi-generator-online/pom.xml index 08b7d222b7a6..b86889dbabd0 100644 --- a/modules/openapi-generator-online/pom.xml +++ b/modules/openapi-generator-online/pom.xml @@ -12,8 +12,8 @@ jar openapi-generator-online - 2.5.14 - 3.0.0 + 3.5.7 + 2.8.14 **/org/openapitools/codegen/online/**/* @@ -46,6 +46,13 @@ + + org.apache.maven.plugins + maven-compiler-plugin + + true + + org.apache.maven.plugins maven-checkstyle-plugin @@ -53,6 +60,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 +115,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 +133,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..a43c21b08583 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,122 @@ */ 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 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 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..df68fb653348 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,20 @@ 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"))) + .servers(List.of( + new Server().url("http://localhost:8081").description("Local development server"), + new Server().url("https://api.openapi-generator.tech").description("Production server") + )); } - -} +} \ 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..b65e78766007 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; @@ -27,15 +28,29 @@ import java.util.Map; @Setter +@Schema(description = "Configuration for building the client library") public class GeneratorInput { - @Getter private JsonNode spec; - @Getter private Map options; + + @Getter + @Schema(description = "OpenAPI specification as JSON object", example = "{\"openapi\": \"3.0.0\", \"info\": {\"title\": \"Sample API\", \"version\": \"1.0.0\"}}") + private JsonNode spec; + + @Getter + @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; + + @Getter + @Schema(description = "Authorization value for accessing the OpenAPI specification") + private AuthorizationValue authorizationValue; + + @Getter + @Schema(description = "OpenAPI normalizer rules", example = "[\"FILTER=operationId:updatePet\"]") + 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; } 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..f5364c19285c 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 @@ -3,18 +3,27 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.openapitools.codegen.CliOption; import org.openapitools.codegen.online.model.ResponseCode; +import org.springframework.core.io.ByteArrayResource; +import org.springframework.http.ResponseEntity; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.MockMvc; -import org.springframework.util.Assert; +import static org.junit.jupiter.api.Assertions.assertTrue; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.not; -import static org.hamcrest.text.MatchesPattern.matchesPattern; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.when; 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.*; @@ -29,13 +38,18 @@ public class GenApiControllerTest { @Autowired private MockMvc mockMvc; + @MockitoBean + private GenApiDelegate genApiDelegate; + @Test public void clientLanguages() throws Exception { + when(genApiDelegate.clientOptions()).thenReturn(ResponseEntity.ok(Arrays.asList("java", "python", "javascript"))); getLanguages("clients", "java"); } @Test public void serverFrameworks() throws Exception { + when(genApiDelegate.serverOptions()).thenReturn(ResponseEntity.ok(Arrays.asList("spring", "nodejs", "flask"))); getLanguages("servers", "spring"); } @@ -49,22 +63,32 @@ public void getLanguages(String type, String expected) throws Exception { @Test public void clientOptions() throws Exception { + Map options = new HashMap<>(); + CliOption option = new CliOption("sortParamsByRequiredFlag", "Sort parameters by required flag"); + options.put("sortParamsByRequiredFlag", option); + when(genApiDelegate.getClientOptions("java")).thenReturn(ResponseEntity.ok(options)); getOptions("clients", "java"); } @Test public void clientOptionsUnknown() throws Exception { + when(genApiDelegate.getClientOptions("unknown")).thenReturn(ResponseEntity.notFound().build()); mockMvc.perform(get("/api/gen/clients/unknown")) .andExpect(status().isNotFound()); } @Test public void serverOptions() throws Exception { + Map options = new HashMap<>(); + CliOption option = new CliOption("sortParamsByRequiredFlag", "Sort parameters by required flag"); + options.put("sortParamsByRequiredFlag", option); + when(genApiDelegate.getServerOptions("spring")).thenReturn(ResponseEntity.ok(options)); getOptions("servers", "spring"); } @Test public void serverOptionsUnknown() throws Exception { + when(genApiDelegate.getServerOptions("unknown")).thenReturn(ResponseEntity.notFound().build()); mockMvc.perform(get("/api/gen/servers/unknown")) .andExpect(status().isNotFound()); } @@ -78,11 +102,15 @@ private void getOptions(String type, String name) throws Exception { @Test public void generateClient() throws Exception { + when(genApiDelegate.generateClient(anyString(), any())).thenReturn(ResponseEntity.ok(new ResponseCode("test-code", "http://test.com:1234/api/gen/download/test-code"))); + when(genApiDelegate.downloadFile("test-code")).thenReturn(ResponseEntity.ok().contentType(org.springframework.http.MediaType.valueOf("application/zip")).header("Content-Length", "1024").body(new ByteArrayResource(new byte[1024]))); generateAndDownload("clients", "java"); } @Test public void generateServer() throws Exception { + when(genApiDelegate.generateServerForLanguage(anyString(), any())).thenReturn(ResponseEntity.ok(new ResponseCode("test-code", "http://test.com:1234/api/gen/download/test-code"))); + when(genApiDelegate.downloadFile("test-code")).thenReturn(ResponseEntity.ok().contentType(org.springframework.http.MediaType.valueOf("application/zip")).header("Content-Length", "1024").body(new ByteArrayResource(new byte[1024]))); generateAndDownload("servers", "spring"); } @@ -92,8 +120,8 @@ private void generateAndDownload(String type, String name) throws Exception { .content("{\"openAPIUrl\": \"" + OPENAPI_URL + "\"}")) .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("$.code").value("test-code")) + .andExpect(jsonPath("$.link").value("http://test.com:1234/api/gen/download/test-code")) .andReturn().getResponse().getContentAsString(); String code = new ObjectMapper().readValue(result, ResponseCode.class).getCode(); @@ -106,6 +134,9 @@ private void generateAndDownload(String type, String name) throws Exception { @Test public void generateWIthForwardedHeaders() throws Exception { + when(genApiDelegate.generateClient(anyString(), any())).thenReturn(ResponseEntity.ok(new ResponseCode("test-code", "https://forwarded.com:5678/api/gen/download/test-code"))); + when(genApiDelegate.downloadFile("test-code")).thenReturn(ResponseEntity.ok().contentType(org.springframework.http.MediaType.valueOf("application/zip")).header("Content-Length", "1024").body(new ByteArrayResource(new byte[1024]))); + String result = mockMvc.perform(post("http://test.com:1234/api/gen/clients/java") .contentType(MediaType.APPLICATION_JSON) .header("X-Forwarded-Proto", "https") @@ -114,8 +145,8 @@ public void generateWIthForwardedHeaders() throws Exception { .content("{\"openAPIUrl\": \"" + OPENAPI_URL + "\"}")) .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("$.code").value("test-code")) + .andExpect(jsonPath("$.link").value("https://forwarded.com:5678/api/gen/download/test-code")) .andReturn().getResponse().getContentAsString(); String code = new ObjectMapper().readValue(result, ResponseCode.class).getCode(); @@ -128,6 +159,7 @@ public void generateWIthForwardedHeaders() throws Exception { @Test public void generateClientWithInvalidOpenAPIUrl() throws Exception { + when(genApiDelegate.generateClient(anyString(), any())).thenReturn(ResponseEntity.badRequest().build()); final String invalidOpenAPIUrl = "https://[::1]/invalid_openapi.json"; mockMvc.perform(post("http://test.com:1234/api/gen/clients/java") .contentType(MediaType.APPLICATION_JSON) @@ -137,6 +169,12 @@ public void generateClientWithInvalidOpenAPIUrl() throws Exception { @Test public void generateWithOpenAPINormalizer() throws Exception { + when(genApiDelegate.generateClient(anyString(), any())) + .thenReturn(ResponseEntity.ok(new ResponseCode("test-code-1", "http://test.com:1234/api/gen/download/test-code-1"))) + .thenReturn(ResponseEntity.ok(new ResponseCode("test-code-2", "http://test.com:1234/api/gen/download/test-code-2"))); + when(genApiDelegate.downloadFile("test-code-1")).thenReturn(ResponseEntity.ok().contentType(org.springframework.http.MediaType.valueOf("application/zip")).header("Content-Length", "512").body(new ByteArrayResource(new byte[512]))); + when(genApiDelegate.downloadFile("test-code-2")).thenReturn(ResponseEntity.ok().contentType(org.springframework.http.MediaType.valueOf("application/zip")).header("Content-Length", "1024").body(new ByteArrayResource(new byte[1024]))); + String withOpenAPINormalizer = "{\"openAPIUrl\":\"https://raw.githubusercontent.com/OpenAPITools/openapi-generator/master/modules/openapi-generator/src/test/resources/2_0/petstore.yaml\",\"openapiNormalizer\":[\"FILTER=operationId:updatePet\"],\"options\":{},\"spec\":{}}"; String withoutOpenAPINormalizer = "{\"openAPIUrl\":\"https://raw.githubusercontent.com/OpenAPITools/openapi-generator/master/modules/openapi-generator/src/test/resources/2_0/petstore.yaml\",\"options\":{},\"spec\":{}}"; @@ -159,7 +197,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"); } } From 62caf3c9bfac6f5eb7be051761bdf4d5d3592e4e Mon Sep 17 00:00:00 2001 From: Shubham Kalloli Date: Mon, 17 Nov 2025 10:19:57 +0000 Subject: [PATCH 2/4] Fix for Request Body Signed-off-by: Shubham Kalloli --- .../codegen/online/api/GenApi.java | 7 ++- .../codegen/online/model/GeneratorInput.java | 9 +-- .../online/api/GenApiControllerTest.java | 55 +++---------------- 3 files changed, 15 insertions(+), 56 deletions(-) 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 a43c21b08583..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 @@ -86,7 +86,8 @@ default ResponseEntity generateClient( 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 GeneratorInput generatorInput) { + @Valid + @org.springframework.web.bind.annotation.RequestBody GeneratorInput generatorInput) { return getDelegate().generateClient(language, generatorInput); } @@ -109,7 +110,9 @@ default ResponseEntity generateServerForLanguage( 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 GeneratorInput generatorInput) { + @Valid + @org.springframework.web.bind.annotation.RequestBody + GeneratorInput generatorInput) { return getDelegate().generateServerForLanguage(framework, generatorInput); } 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 b65e78766007..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 @@ -27,15 +27,14 @@ import java.util.List; import java.util.Map; +@Getter @Setter @Schema(description = "Configuration for building the client library") public class GeneratorInput { - @Getter @Schema(description = "OpenAPI specification as JSON object", example = "{\"openapi\": \"3.0.0\", \"info\": {\"title\": \"Sample API\", \"version\": \"1.0.0\"}}") private JsonNode spec; - @Getter @Schema(description = "Generator-specific options", example = "{\"packageName\": \"com.example.client\", \"clientPackage\": \"com.example.client\"}") private Map options; @@ -43,15 +42,9 @@ public class GeneratorInput { @JsonProperty("openAPIUrl") private String openAPIUrl; - @Getter @Schema(description = "Authorization value for accessing the OpenAPI specification") private AuthorizationValue authorizationValue; - @Getter @Schema(description = "OpenAPI normalizer rules", example = "[\"FILTER=operationId:updatePet\"]") private List openapiNormalizer; - - public String getOpenAPIUrl() { - return openAPIUrl; - } } 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 f5364c19285c..dc68a9f3ceaa 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 @@ -3,29 +3,20 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.openapitools.codegen.CliOption; import org.openapitools.codegen.online.model.ResponseCode; -import org.springframework.core.io.ByteArrayResource; -import org.springframework.http.ResponseEntity; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; -import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.MockMvc; + +import static org.hamcrest.Matchers.*; import static org.junit.jupiter.api.Assertions.assertTrue; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.not; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.when; + 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.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @ExtendWith(SpringExtension.class) @@ -38,18 +29,13 @@ public class GenApiControllerTest { @Autowired private MockMvc mockMvc; - @MockitoBean - private GenApiDelegate genApiDelegate; - @Test public void clientLanguages() throws Exception { - when(genApiDelegate.clientOptions()).thenReturn(ResponseEntity.ok(Arrays.asList("java", "python", "javascript"))); getLanguages("clients", "java"); } @Test public void serverFrameworks() throws Exception { - when(genApiDelegate.serverOptions()).thenReturn(ResponseEntity.ok(Arrays.asList("spring", "nodejs", "flask"))); getLanguages("servers", "spring"); } @@ -63,32 +49,22 @@ public void getLanguages(String type, String expected) throws Exception { @Test public void clientOptions() throws Exception { - Map options = new HashMap<>(); - CliOption option = new CliOption("sortParamsByRequiredFlag", "Sort parameters by required flag"); - options.put("sortParamsByRequiredFlag", option); - when(genApiDelegate.getClientOptions("java")).thenReturn(ResponseEntity.ok(options)); getOptions("clients", "java"); } @Test public void clientOptionsUnknown() throws Exception { - when(genApiDelegate.getClientOptions("unknown")).thenReturn(ResponseEntity.notFound().build()); mockMvc.perform(get("/api/gen/clients/unknown")) .andExpect(status().isNotFound()); } @Test public void serverOptions() throws Exception { - Map options = new HashMap<>(); - CliOption option = new CliOption("sortParamsByRequiredFlag", "Sort parameters by required flag"); - options.put("sortParamsByRequiredFlag", option); - when(genApiDelegate.getServerOptions("spring")).thenReturn(ResponseEntity.ok(options)); getOptions("servers", "spring"); } @Test public void serverOptionsUnknown() throws Exception { - when(genApiDelegate.getServerOptions("unknown")).thenReturn(ResponseEntity.notFound().build()); mockMvc.perform(get("/api/gen/servers/unknown")) .andExpect(status().isNotFound()); } @@ -102,15 +78,11 @@ private void getOptions(String type, String name) throws Exception { @Test public void generateClient() throws Exception { - when(genApiDelegate.generateClient(anyString(), any())).thenReturn(ResponseEntity.ok(new ResponseCode("test-code", "http://test.com:1234/api/gen/download/test-code"))); - when(genApiDelegate.downloadFile("test-code")).thenReturn(ResponseEntity.ok().contentType(org.springframework.http.MediaType.valueOf("application/zip")).header("Content-Length", "1024").body(new ByteArrayResource(new byte[1024]))); generateAndDownload("clients", "java"); } @Test public void generateServer() throws Exception { - when(genApiDelegate.generateServerForLanguage(anyString(), any())).thenReturn(ResponseEntity.ok(new ResponseCode("test-code", "http://test.com:1234/api/gen/download/test-code"))); - when(genApiDelegate.downloadFile("test-code")).thenReturn(ResponseEntity.ok().contentType(org.springframework.http.MediaType.valueOf("application/zip")).header("Content-Length", "1024").body(new ByteArrayResource(new byte[1024]))); generateAndDownload("servers", "spring"); } @@ -118,10 +90,11 @@ private void generateAndDownload(String type, String name) throws Exception { String result = mockMvc.perform(post("http://test.com:1234/api/gen/" + type + "/" + name) .contentType(MediaType.APPLICATION_JSON) .content("{\"openAPIUrl\": \"" + OPENAPI_URL + "\"}")) + .andDo(print()) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(jsonPath("$.code").value("test-code")) - .andExpect(jsonPath("$.link").value("http://test.com:1234/api/gen/download/test-code")) + .andExpect(jsonPath("$.code").value(matchesPattern(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(); @@ -134,9 +107,6 @@ private void generateAndDownload(String type, String name) throws Exception { @Test public void generateWIthForwardedHeaders() throws Exception { - when(genApiDelegate.generateClient(anyString(), any())).thenReturn(ResponseEntity.ok(new ResponseCode("test-code", "https://forwarded.com:5678/api/gen/download/test-code"))); - when(genApiDelegate.downloadFile("test-code")).thenReturn(ResponseEntity.ok().contentType(org.springframework.http.MediaType.valueOf("application/zip")).header("Content-Length", "1024").body(new ByteArrayResource(new byte[1024]))); - String result = mockMvc.perform(post("http://test.com:1234/api/gen/clients/java") .contentType(MediaType.APPLICATION_JSON) .header("X-Forwarded-Proto", "https") @@ -145,8 +115,8 @@ public void generateWIthForwardedHeaders() throws Exception { .content("{\"openAPIUrl\": \"" + OPENAPI_URL + "\"}")) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(jsonPath("$.code").value("test-code")) - .andExpect(jsonPath("$.link").value("https://forwarded.com:5678/api/gen/download/test-code")) + .andExpect(jsonPath("$.code").value(matchesPattern(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 +129,6 @@ public void generateWIthForwardedHeaders() throws Exception { @Test public void generateClientWithInvalidOpenAPIUrl() throws Exception { - when(genApiDelegate.generateClient(anyString(), any())).thenReturn(ResponseEntity.badRequest().build()); final String invalidOpenAPIUrl = "https://[::1]/invalid_openapi.json"; mockMvc.perform(post("http://test.com:1234/api/gen/clients/java") .contentType(MediaType.APPLICATION_JSON) @@ -169,12 +138,6 @@ public void generateClientWithInvalidOpenAPIUrl() throws Exception { @Test public void generateWithOpenAPINormalizer() throws Exception { - when(genApiDelegate.generateClient(anyString(), any())) - .thenReturn(ResponseEntity.ok(new ResponseCode("test-code-1", "http://test.com:1234/api/gen/download/test-code-1"))) - .thenReturn(ResponseEntity.ok(new ResponseCode("test-code-2", "http://test.com:1234/api/gen/download/test-code-2"))); - when(genApiDelegate.downloadFile("test-code-1")).thenReturn(ResponseEntity.ok().contentType(org.springframework.http.MediaType.valueOf("application/zip")).header("Content-Length", "512").body(new ByteArrayResource(new byte[512]))); - when(genApiDelegate.downloadFile("test-code-2")).thenReturn(ResponseEntity.ok().contentType(org.springframework.http.MediaType.valueOf("application/zip")).header("Content-Length", "1024").body(new ByteArrayResource(new byte[1024]))); - String withOpenAPINormalizer = "{\"openAPIUrl\":\"https://raw.githubusercontent.com/OpenAPITools/openapi-generator/master/modules/openapi-generator/src/test/resources/2_0/petstore.yaml\",\"openapiNormalizer\":[\"FILTER=operationId:updatePet\"],\"options\":{},\"spec\":{}}"; String withoutOpenAPINormalizer = "{\"openAPIUrl\":\"https://raw.githubusercontent.com/OpenAPITools/openapi-generator/master/modules/openapi-generator/src/test/resources/2_0/petstore.yaml\",\"options\":{},\"spec\":{}}"; From d119d21672385f7a5765bc1fe999bb5e2cd1a8a2 Mon Sep 17 00:00:00 2001 From: Shubham Kalloli Date: Mon, 17 Nov 2025 14:20:29 +0000 Subject: [PATCH 3/4] Added Java 17 compatibility in Online Module Signed-off-by: Shubham Kalloli --- modules/openapi-generator-online/README.md | 9 +-------- modules/openapi-generator-online/pom.xml | 2 ++ .../online/configuration/OpenAPIDocumentationConfig.java | 6 +----- 3 files changed, 4 insertions(+), 13 deletions(-) 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 b86889dbabd0..362381122ef3 100644 --- a/modules/openapi-generator-online/pom.xml +++ b/modules/openapi-generator-online/pom.xml @@ -12,6 +12,8 @@ jar openapi-generator-online + 17 + 17 3.5.7 2.8.14 **/org/openapitools/codegen/online/**/* 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 df68fb653348..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 @@ -56,10 +56,6 @@ public OpenAPI customOpenAPI() { .url("https://www.apache.org/licenses/LICENSE-2.0.html")) .contact(new Contact() .name("OpenAPI Generator Team") - .url("https://github.com/OpenAPITools/openapi-generator"))) - .servers(List.of( - new Server().url("http://localhost:8081").description("Local development server"), - new Server().url("https://api.openapi-generator.tech").description("Production server") - )); + .url("https://github.com/OpenAPITools/openapi-generator"))); } } \ No newline at end of file From 86f89b4435a85ce8d75a50c7b08f6133e036d219 Mon Sep 17 00:00:00 2001 From: Shubham Kalloli Date: Mon, 17 Nov 2025 15:27:48 +0000 Subject: [PATCH 4/4] Cleaned up test Signed-off-by: Shubham Kalloli --- .../openapitools/codegen/online/api/GenApiControllerTest.java | 2 -- 1 file changed, 2 deletions(-) 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 dc68a9f3ceaa..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 @@ -16,7 +16,6 @@ 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.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @ExtendWith(SpringExtension.class) @@ -90,7 +89,6 @@ private void generateAndDownload(String type, String name) throws Exception { String result = mockMvc.perform(post("http://test.com:1234/api/gen/" + type + "/" + name) .contentType(MediaType.APPLICATION_JSON) .content("{\"openAPIUrl\": \"" + OPENAPI_URL + "\"}")) - .andDo(print()) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andExpect(jsonPath("$.code").value(matchesPattern(UUID_REGEX)))