From 9a05890ae7f7f18f8a2ad3486f9e074bbf676ba5 Mon Sep 17 00:00:00 2001 From: Shubham Date: Thu, 4 Apr 2024 17:38:52 +0530 Subject: [PATCH] fix: fixes for go json ingress (#571) # Fixes # Changes for Go json ingress. The impact can be seen [here](https://github.com/twilio/twilio-go/pull/242). ### Checklist - [x] I acknowledge that all my contributions will be made under the project's license - [x] Run `make test-docker` - [x] Verify affected language: - [x] Generate [twilio-go](https://github.com/twilio/twilio-go) from our [OpenAPI specification](https://github.com/twilio/twilio-oai) using the [build_twilio_go.py](./examples/build_twilio_go.py) using `python examples/build_twilio_go.py path/to/twilio-oai/spec/yaml path/to/twilio-go` and inspect the diff - [x] Run `make test` in `twilio-go` - [x] Create a pull request in `twilio-go` - [x] Provide a link below to the pull request - [x] I have made a material change to the repo (functionality, testing, spelling, grammar) - [x] I have read the [Contribution Guidelines](https://github.com/twilio/twilio-oai-generator/blob/main/CONTRIBUTING.md) and my PR follows them - [x] I have titled the PR appropriately - [x] I have updated my branch with the main branch - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] I have added the necessary documentation about the functionality in the appropriate .md file - [ ] I have added inline documentation to the code I modified If you have questions, please create a GitHub Issue in this repository. --- .../go-client/helper/rest/flex/v1/README.md | 2 +- ...ponse.go => model_update_call_response.go} | 4 +- .../go/go-client/helper/rest/flex/v1/voice.go | 4 +- .../com/twilio/oai/TwilioGoGenerator.java | 71 ++++++++++++++++++- .../resources/twilio-go/api_service.mustache | 2 +- 5 files changed, 74 insertions(+), 9 deletions(-) rename examples/go/go-client/helper/rest/flex/v1/{model_update_call_200_response.go => model_update_call_response.go} (86%) diff --git a/examples/go/go-client/helper/rest/flex/v1/README.md b/examples/go/go-client/helper/rest/flex/v1/README.md index bbb9ac9d1..0e3536d92 100644 --- a/examples/go/go-client/helper/rest/flex/v1/README.md +++ b/examples/go/go-client/helper/rest/flex/v1/README.md @@ -43,7 +43,7 @@ Class | Method | HTTP request | Description ## Documentation For Models - [ListCredentialAwsResponse](docs/ListCredentialAwsResponse.md) - - [UpdateCall200Response](docs/UpdateCall200Response.md) + - [UpdateCallResponse](docs/UpdateCallResponse.md) - [TestResponseObject](docs/TestResponseObject.md) - [ListCredentialAwsResponseMeta](docs/ListCredentialAwsResponseMeta.md) diff --git a/examples/go/go-client/helper/rest/flex/v1/model_update_call_200_response.go b/examples/go/go-client/helper/rest/flex/v1/model_update_call_response.go similarity index 86% rename from examples/go/go-client/helper/rest/flex/v1/model_update_call_200_response.go rename to examples/go/go-client/helper/rest/flex/v1/model_update_call_response.go index f0548e961..293492b39 100644 --- a/examples/go/go-client/helper/rest/flex/v1/model_update_call_200_response.go +++ b/examples/go/go-client/helper/rest/flex/v1/model_update_call_response.go @@ -14,8 +14,8 @@ package openapi -// UpdateCall200Response struct for UpdateCall200Response -type UpdateCall200Response struct { +// UpdateCallResponse struct for UpdateCallResponse +type UpdateCallResponse struct { // Non-string path parameter in the response. Sid *int `json:"sid,omitempty"` } diff --git a/examples/go/go-client/helper/rest/flex/v1/voice.go b/examples/go/go-client/helper/rest/flex/v1/voice.go index 88f989e29..c5285610d 100644 --- a/examples/go/go-client/helper/rest/flex/v1/voice.go +++ b/examples/go/go-client/helper/rest/flex/v1/voice.go @@ -20,7 +20,7 @@ import ( "strings" ) -func (c *ApiService) UpdateCall(Sid string) (*UpdateCall200Response, error) { +func (c *ApiService) UpdateCall(Sid string) (*UpdateCallResponse, error) { path := "/v1/Voice/{Sid}" path = strings.Replace(path, "{"+"Sid"+"}", Sid, -1) @@ -34,7 +34,7 @@ func (c *ApiService) UpdateCall(Sid string) (*UpdateCall200Response, error) { defer resp.Body.Close() - ps := &UpdateCall200Response{} + ps := &UpdateCallResponse{} if err := json.NewDecoder(resp.Body).Decode(ps); err != nil { return nil, err } diff --git a/src/main/java/com/twilio/oai/TwilioGoGenerator.java b/src/main/java/com/twilio/oai/TwilioGoGenerator.java index cb5a2f23c..d599c84d5 100644 --- a/src/main/java/com/twilio/oai/TwilioGoGenerator.java +++ b/src/main/java/com/twilio/oai/TwilioGoGenerator.java @@ -2,10 +2,9 @@ import com.twilio.oai.common.Utility; -import java.util.List; -import java.util.Map; -import java.util.Optional; +import java.util.*; import java.util.function.Function; +import java.util.regex.Pattern; import java.util.stream.Collector; import java.util.stream.Collectors; @@ -21,6 +20,7 @@ import org.openapitools.codegen.model.ModelsMap; import org.openapitools.codegen.model.OperationMap; import org.openapitools.codegen.model.OperationsMap; +import org.openapitools.codegen.utils.StringUtils; import static com.twilio.oai.common.ApplicationConstants.STRING; @@ -68,6 +68,68 @@ public ModelsMap postProcessModels(final ModelsMap objs) { return results; } + boolean containsAllOf(String modelName) { + return modelName.contains("allOf"); + } + + boolean containsStatusCode(String modelName) { + return Pattern.compile("_\\d{3}_").matcher(modelName).find(); + } + + String removeStatusCode(String modelName) { + if(modelName == null || modelName.isEmpty()) + return modelName; + return modelName.replaceFirst("_\\d{3}", ""); + } + + String removeDigits(String modelName) { + if(modelName == null || modelName.isEmpty()) + return modelName; + return modelName.replaceFirst("\\d{3}", ""); + } + + String modelNameWithoutStatusCode(String modelName) { + if(modelName == null || modelName.isEmpty()) + return modelName; + String newModelName = removeStatusCode(modelName); + if(Objects.equals(newModelName, modelName)) + newModelName = removeDigits(newModelName); + return StringUtils.camelize(newModelName); + } + + @Override + public Map updateAllModels(Map objs) { + objs = super.updateAllModels(objs); + + Set modelNames = objs.keySet() + .stream() + .filter(key -> (containsStatusCode(key) || containsAllOf(key))) + .map(this::modelNameWithoutStatusCode) + .collect(Collectors.toSet()); + + objs.entrySet().removeIf(entry -> containsAllOf(entry.getKey()) || modelNames.contains(entry.getKey())); + Map updatedObjs = new HashMap<>(); + + objs.forEach((key, value) -> { + if (containsStatusCode(key)) { + ModelMap modelMap = value.getModels().get(0); + String importPath = (String) modelMap.get("importPath"); + CodegenModel model = modelMap.getModel(); + key = modelNameWithoutStatusCode(key); + model.setName(modelNameWithoutStatusCode(model.name)); + model.setClassname(modelNameWithoutStatusCode(model.classname)); + model.setClassVarName(modelNameWithoutStatusCode(model.classVarName)); + model.setClassFilename(removeStatusCode(model.classFilename)); + modelMap.setModel(model); + modelMap.put("importPath", removeDigits(importPath)); + value.put("classname", removeDigits((String) value.get("classname"))); + } + updatedObjs.put(key, value); + }); + + return updatedObjs; + } + @Override public void postProcessModelProperty(CodegenModel model, CodegenProperty property) { super.postProcessModelProperty(model, property); @@ -122,6 +184,7 @@ public OperationsMap postProcessOperationsWithModels(final OperationsMap objs, L for (final CodegenOperation co : opList) { Utility.populateCrudOperations(co); Utility.resolveContentType(co); + co.returnType = modelNameWithoutStatusCode(co.returnType); if (co.nickname.startsWith("List")) { // make sure the format matches the other methods @@ -205,6 +268,8 @@ public void processOpenAPI(final OpenAPI openAPI) { .forEach((name, path) -> path .readOperations() .forEach(operation -> { + if(Objects.equals(openAPI.getServers().get(0).getUrl(), "/")) + openAPI.servers(path.getServers()); // Group operations together by tag. This gives us one file/post-process per resource. operation.addTagsItem(PathUtils.cleanPathAndRemoveFirstElement(name)); // Add a parameter called limit for list and stream operations diff --git a/src/main/resources/twilio-go/api_service.mustache b/src/main/resources/twilio-go/api_service.mustache index bc9e96477..423f2c683 100644 --- a/src/main/resources/twilio-go/api_service.mustache +++ b/src/main/resources/twilio-go/api_service.mustache @@ -13,7 +13,7 @@ type ApiService struct { func NewApiService(requestHandler *twilio.RequestHandler) *ApiService { return &ApiService { requestHandler: requestHandler, - baseURL: "{{#apiInfo}}{{#apis}}{{#operations}}{{#-first}}{{#operation}}{{#-first}}{{#servers}}{{url}}{{/servers}}{{/-first}}{{/operation}}{{/-first}}{{/operations}}{{/apis}}{{/apiInfo}}", + baseURL: "{{#hasServers}}{{#servers}}{{url}}{{/servers}}{{/hasServers}}", } }