[GO Gin Server] Webhooks support: add missing webhook handlers (#17411)

* Implement postProcessWebhooksWithModels

* Implement postProcessWebhooksWithModels

* Add missing webhook handlers

* Test webhook handler

* Generate samples
This commit is contained in:
Beppe Catanese 2023-12-21 09:10:09 +01:00 committed by GitHub
parent b20c8db281
commit a34eeaed77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 260 additions and 72 deletions

View File

@ -22,10 +22,7 @@ import io.swagger.v3.oas.models.media.Schema;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.*;
import org.openapitools.codegen.model.ModelMap;
import org.openapitools.codegen.model.ModelsMap;
import org.openapitools.codegen.model.OperationMap;
import org.openapitools.codegen.model.OperationsMap;
import org.openapitools.codegen.model.*;
import org.openapitools.codegen.utils.ModelUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -586,6 +583,105 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
return objs;
}
@Override
public WebhooksMap postProcessWebhooksWithModels(WebhooksMap objs, List<ModelMap> allModels) {
OperationMap objectMap = objs.getWebhooks();
List<CodegenOperation> operations = objectMap.getOperation();
for (CodegenOperation operation : operations) {
// http method verb conversion (e.g. PUT => Put)
operation.httpMethod = camelize(operation.httpMethod.toLowerCase(Locale.ROOT));
}
// remove model imports to avoid error
List<Map<String, String>> imports = objs.getImports();
if (imports == null)
return objs;
Iterator<Map<String, String>> iterator = imports.iterator();
while (iterator.hasNext()) {
String _import = iterator.next().get("import");
if (_import.startsWith(apiPackage()))
iterator.remove();
}
// this will only import "fmt" and "strings" if there are items in pathParams
for (CodegenOperation operation : operations) {
if (operation.pathParams != null && operation.pathParams.size() > 0) {
imports.add(createMapping("import", "strings"));
break; //just need to import once
}
}
boolean addedTimeImport = false;
boolean addedOSImport = false;
boolean addedReflectImport = false;
for (CodegenOperation operation : operations) {
// import "os" if the operation uses files
if (!addedOSImport && "*os.File".equals(operation.returnType)) {
imports.add(createMapping("import", "os"));
addedOSImport = true;
}
for (CodegenParameter param : operation.allParams) {
// import "os" if the operation uses files
if (!addedOSImport && "*os.File".equals(param.dataType)) {
imports.add(createMapping("import", "os"));
addedOSImport = true;
}
// import "time" if the operation has a time parameter.
if (!addedTimeImport && "time.Time".equals(param.dataType)) {
imports.add(createMapping("import", "time"));
addedTimeImport = true;
}
// import "reflect" package if the parameter is collectionFormat=multi
if (!addedReflectImport && param.isCollectionFormatMulti) {
imports.add(createMapping("import", "reflect"));
addedReflectImport = true;
}
// set x-exportParamName
char nameFirstChar = param.paramName.charAt(0);
if (Character.isUpperCase(nameFirstChar)) {
// First char is already uppercase, just use paramName.
param.vendorExtensions.put("x-export-param-name", param.paramName);
} else {
// It's a lowercase first char, let's convert it to uppercase
StringBuilder sb = new StringBuilder(param.paramName);
sb.setCharAt(0, Character.toUpperCase(nameFirstChar));
param.vendorExtensions.put("x-export-param-name", sb.toString());
}
}
setExportParameterName(operation.queryParams);
setExportParameterName(operation.formParams);
setExportParameterName(operation.headerParams);
setExportParameterName(operation.bodyParams);
setExportParameterName(operation.cookieParams);
setExportParameterName(operation.optionalParams);
setExportParameterName(operation.requiredParams);
}
// recursively add import for mapping one type to multiple imports
List<Map<String, String>> recursiveImports = objs.getImports();
if (recursiveImports == null)
return objs;
ListIterator<Map<String, String>> listIterator = imports.listIterator();
while (listIterator.hasNext()) {
String _import = listIterator.next().get("import");
// if the import package happens to be found in the importMapping (key)
// add the corresponding import package to the list
if (importMapping.containsKey(_import)) {
listIterator.add(createMapping("import", importMapping.get(_import)));
}
}
return objs;
}
private void setExportParameterName(List<CodegenParameter> codegenParameters) {
for (CodegenParameter param : codegenParameters) {
char nameFirstChar = param.paramName.charAt(0);

View File

@ -7,12 +7,18 @@ import (
)
type {{classname}} struct {
}
{{#operation}}
// {{httpMethod}} {{{basePathWithoutHost}}}{{{path}}}
// {{{summary}}}
// {{httpMethod}} {{{basePathWithoutHost}}}{{{path}}}{{#summary}}
// {{{.}}} {{/summary}}
{{#isDeprecated}}
// Deprecated
// Deprecated
{{/isDeprecated}}
{{nickname}} gin.HandlerFunc
func (api *{{classname}}) {{nickname}}(c *gin.Context) {
// Your handler implementation
c.JSON(200, gin.H{"status": "OK"})
}
{{/operation}}
}{{/operations}}
{{/operations}}

View File

@ -51,7 +51,8 @@ func DefaultHandleFunc(c *gin.Context) {
type ApiHandleFunctions struct {
{{#apiInfo}}{{#apis}}{{#operations}}
// Routes for the {{classname}} part of the API
{{classname}} {{classname}}{{/operations}}{{/apis}}{{/apiInfo}}
{{classname}} {{classname}}{{/operations}}{{/apis}}{{/apiInfo}}{{#webhooks}}{{#operations}}
{{classname}} {{classname}}{{/operations}}{{/webhooks}}
}
func getRoutes(handleFunctions ApiHandleFunctions) []Route {

View File

@ -74,10 +74,12 @@ public class GoGinServerCodegenTest {
DefaultGenerator generator = new DefaultGenerator();
List<File> files = generator.opts(configurator.toClientOptInput()).generate();
files.forEach(File::deleteOnExit);
//files.forEach(File::deleteOnExit);
TestUtils.assertFileContains(Paths.get(output + "/go/routers.go"),
"NewPetPost");
TestUtils.assertFileContains(Paths.get(output + "/go/api_default.go"),
" c.JSON(200, gin.H{\"status\": \"OK\"})");
}
}

View File

@ -14,29 +14,62 @@ import (
)
type PetAPI struct {
// Post /v2/pet
// Add a new pet to the store
AddPet gin.HandlerFunc
// Delete /v2/pet/:petId
// Deletes a pet
DeletePet gin.HandlerFunc
// Get /v2/pet/findByStatus
// Finds Pets by status
FindPetsByStatus gin.HandlerFunc
// Get /v2/pet/findByTags
// Finds Pets by tags
// Deprecated
FindPetsByTags gin.HandlerFunc
// Get /v2/pet/:petId
// Find pet by ID
GetPetById gin.HandlerFunc
// Put /v2/pet
// Update an existing pet
UpdatePet gin.HandlerFunc
// Post /v2/pet/:petId
// Updates a pet in the store with form data
UpdatePetWithForm gin.HandlerFunc
// Post /v2/pet/:petId/uploadImage
// uploads an image
UploadFile gin.HandlerFunc
}
// Post /v2/pet
// Add a new pet to the store
func (api *PetAPI) AddPet(c *gin.Context) {
// Your handler implementation
c.JSON(200, gin.H{"status": "OK"})
}
// Delete /v2/pet/:petId
// Deletes a pet
func (api *PetAPI) DeletePet(c *gin.Context) {
// Your handler implementation
c.JSON(200, gin.H{"status": "OK"})
}
// Get /v2/pet/findByStatus
// Finds Pets by status
func (api *PetAPI) FindPetsByStatus(c *gin.Context) {
// Your handler implementation
c.JSON(200, gin.H{"status": "OK"})
}
// Get /v2/pet/findByTags
// Finds Pets by tags
// Deprecated
func (api *PetAPI) FindPetsByTags(c *gin.Context) {
// Your handler implementation
c.JSON(200, gin.H{"status": "OK"})
}
// Get /v2/pet/:petId
// Find pet by ID
func (api *PetAPI) GetPetById(c *gin.Context) {
// Your handler implementation
c.JSON(200, gin.H{"status": "OK"})
}
// Put /v2/pet
// Update an existing pet
func (api *PetAPI) UpdatePet(c *gin.Context) {
// Your handler implementation
c.JSON(200, gin.H{"status": "OK"})
}
// Post /v2/pet/:petId
// Updates a pet in the store with form data
func (api *PetAPI) UpdatePetWithForm(c *gin.Context) {
// Your handler implementation
c.JSON(200, gin.H{"status": "OK"})
}
// Post /v2/pet/:petId/uploadImage
// uploads an image
func (api *PetAPI) UploadFile(c *gin.Context) {
// Your handler implementation
c.JSON(200, gin.H{"status": "OK"})
}

View File

@ -14,16 +14,33 @@ import (
)
type StoreAPI struct {
// Delete /v2/store/order/:orderId
// Delete purchase order by ID
DeleteOrder gin.HandlerFunc
// Get /v2/store/inventory
// Returns pet inventories by status
GetInventory gin.HandlerFunc
// Get /v2/store/order/:orderId
// Find purchase order by ID
GetOrderById gin.HandlerFunc
// Post /v2/store/order
// Place an order for a pet
PlaceOrder gin.HandlerFunc
}
// Delete /v2/store/order/:orderId
// Delete purchase order by ID
func (api *StoreAPI) DeleteOrder(c *gin.Context) {
// Your handler implementation
c.JSON(200, gin.H{"status": "OK"})
}
// Get /v2/store/inventory
// Returns pet inventories by status
func (api *StoreAPI) GetInventory(c *gin.Context) {
// Your handler implementation
c.JSON(200, gin.H{"status": "OK"})
}
// Get /v2/store/order/:orderId
// Find purchase order by ID
func (api *StoreAPI) GetOrderById(c *gin.Context) {
// Your handler implementation
c.JSON(200, gin.H{"status": "OK"})
}
// Post /v2/store/order
// Place an order for a pet
func (api *StoreAPI) PlaceOrder(c *gin.Context) {
// Your handler implementation
c.JSON(200, gin.H{"status": "OK"})
}

View File

@ -14,28 +14,61 @@ import (
)
type UserAPI struct {
// Post /v2/user
// Create user
CreateUser gin.HandlerFunc
// Post /v2/user/createWithArray
// Creates list of users with given input array
CreateUsersWithArrayInput gin.HandlerFunc
// Post /v2/user/createWithList
// Creates list of users with given input array
CreateUsersWithListInput gin.HandlerFunc
// Delete /v2/user/:username
// Delete user
DeleteUser gin.HandlerFunc
// Get /v2/user/:username
// Get user by user name
GetUserByName gin.HandlerFunc
// Get /v2/user/login
// Logs user into the system
LoginUser gin.HandlerFunc
// Get /v2/user/logout
// Logs out current logged in user session
LogoutUser gin.HandlerFunc
// Put /v2/user/:username
// Updated user
UpdateUser gin.HandlerFunc
}
// Post /v2/user
// Create user
func (api *UserAPI) CreateUser(c *gin.Context) {
// Your handler implementation
c.JSON(200, gin.H{"status": "OK"})
}
// Post /v2/user/createWithArray
// Creates list of users with given input array
func (api *UserAPI) CreateUsersWithArrayInput(c *gin.Context) {
// Your handler implementation
c.JSON(200, gin.H{"status": "OK"})
}
// Post /v2/user/createWithList
// Creates list of users with given input array
func (api *UserAPI) CreateUsersWithListInput(c *gin.Context) {
// Your handler implementation
c.JSON(200, gin.H{"status": "OK"})
}
// Delete /v2/user/:username
// Delete user
func (api *UserAPI) DeleteUser(c *gin.Context) {
// Your handler implementation
c.JSON(200, gin.H{"status": "OK"})
}
// Get /v2/user/:username
// Get user by user name
func (api *UserAPI) GetUserByName(c *gin.Context) {
// Your handler implementation
c.JSON(200, gin.H{"status": "OK"})
}
// Get /v2/user/login
// Logs user into the system
func (api *UserAPI) LoginUser(c *gin.Context) {
// Your handler implementation
c.JSON(200, gin.H{"status": "OK"})
}
// Get /v2/user/logout
// Logs out current logged in user session
func (api *UserAPI) LogoutUser(c *gin.Context) {
// Your handler implementation
c.JSON(200, gin.H{"status": "OK"})
}
// Put /v2/user/:username
// Updated user
func (api *UserAPI) UpdateUser(c *gin.Context) {
// Your handler implementation
c.JSON(200, gin.H{"status": "OK"})
}