Skip to content

Commit

Permalink
fix(protoc-gen-grpc-gateway): error if identical annotations are prov…
Browse files Browse the repository at this point in the history
…ided (#2246)

* Add failing test to check for errors with duplicate annotions

* Add map to descriptor.Registry & check for duplicate annotations

* Fix broken tests

* Update annotationMap to use struct{}

* Rename breaking annotations in examples
  • Loading branch information
danedavid authored Aug 1, 2021
1 parent 4cdcd10 commit c4dfa54
Show file tree
Hide file tree
Showing 14 changed files with 612 additions and 114 deletions.
45 changes: 42 additions & 3 deletions examples/internal/clients/abe/api/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2457,15 +2457,15 @@ paths:
get:
tags:
- "ABitOfEverythingService"
operationId: "ABitOfEverythingService_CheckExternalNestedPathEnum"
operationId: "ABitOfEverythingService_CheckExternalPathEnum"
parameters:
- name: "value"
in: "path"
required: true
type: "string"
enum:
- "GHI"
- "JKL"
- "ABC"
- "DEF"
x-exportParamName: "Value"
responses:
200:
Expand Down Expand Up @@ -2534,6 +2534,45 @@ paths:
description: "An unexpected error response."
schema:
$ref: "#/definitions/rpcStatus"
/v3/{value}:check:
get:
tags:
- "ABitOfEverythingService"
operationId: "ABitOfEverythingService_CheckExternalNestedPathEnum"
parameters:
- name: "value"
in: "path"
required: true
type: "string"
enum:
- "GHI"
- "JKL"
x-exportParamName: "Value"
responses:
200:
description: "A successful response."
schema: {}
403:
description: "Returned when the user does not have permission to access\
\ the resource."
schema: {}
404:
description: "Returned when the resource does not exist."
schema:
type: "string"
format: "string"
418:
description: "I'm a teapot."
schema:
$ref: "#/definitions/examplepbNumericEnum"
500:
description: "Server error"
schema:
$ref: "#/definitions/examplepbErrorResponse"
default:
description: "An unexpected error response."
schema:
$ref: "#/definitions/rpcStatus"
securityDefinitions:
ApiKeyAuth:
type: "apiKey"
Expand Down
156 changes: 156 additions & 0 deletions examples/internal/clients/abe/api_a_bit_of_everything_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,162 @@ func (a *ABitOfEverythingServiceApiService) ABitOfEverythingServiceCheckExternal
localVarReturnValue interface{}
)

// create path and map variables
localVarPath := a.client.cfg.BasePath + "/v3/{value}:check"
localVarPath = strings.Replace(localVarPath, "{"+"value"+"}", fmt.Sprintf("%v", value), -1)

localVarHeaderParams := make(map[string]string)
localVarQueryParams := url.Values{}
localVarFormParams := url.Values{}

// to determine the Content-Type header
localVarHttpContentTypes := []string{"application/json", "application/x-foo-mime"}

// set Content-Type header
localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
if localVarHttpContentType != "" {
localVarHeaderParams["Content-Type"] = localVarHttpContentType
}

// to determine the Accept header
localVarHttpHeaderAccepts := []string{"application/json", "application/x-foo-mime"}

// set Accept header
localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
if localVarHttpHeaderAccept != "" {
localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
}
if ctx != nil {
// API Key Authentication
if auth, ok := ctx.Value(ContextAPIKey).(APIKey); ok {
var key string
if auth.Prefix != "" {
key = auth.Prefix + " " + auth.Key
} else {
key = auth.Key
}
localVarHeaderParams["X-API-Key"] = key

}
}
r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
if err != nil {
return localVarReturnValue, nil, err
}

localVarHttpResponse, err := a.client.callAPI(r)
if err != nil || localVarHttpResponse == nil {
return localVarReturnValue, localVarHttpResponse, err
}

localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
localVarHttpResponse.Body.Close()
if err != nil {
return localVarReturnValue, localVarHttpResponse, err
}

if localVarHttpResponse.StatusCode < 300 {
// If we succeed, return the data, otherwise pass on to decode error.
err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"));
if err == nil {
return localVarReturnValue, localVarHttpResponse, err
}
}

if localVarHttpResponse.StatusCode >= 300 {
newErr := GenericSwaggerError{
body: localVarBody,
error: localVarHttpResponse.Status,
}

if localVarHttpResponse.StatusCode == 200 {
var v interface{}
err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"));
if err != nil {
newErr.error = err.Error()
return localVarReturnValue, localVarHttpResponse, newErr
}
newErr.model = v
return localVarReturnValue, localVarHttpResponse, newErr
}

if localVarHttpResponse.StatusCode == 403 {
var v interface{}
err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"));
if err != nil {
newErr.error = err.Error()
return localVarReturnValue, localVarHttpResponse, newErr
}
newErr.model = v
return localVarReturnValue, localVarHttpResponse, newErr
}

if localVarHttpResponse.StatusCode == 404 {
var v string
err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"));
if err != nil {
newErr.error = err.Error()
return localVarReturnValue, localVarHttpResponse, newErr
}
newErr.model = v
return localVarReturnValue, localVarHttpResponse, newErr
}

if localVarHttpResponse.StatusCode == 418 {
var v ExamplepbNumericEnum
err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"));
if err != nil {
newErr.error = err.Error()
return localVarReturnValue, localVarHttpResponse, newErr
}
newErr.model = v
return localVarReturnValue, localVarHttpResponse, newErr
}

if localVarHttpResponse.StatusCode == 500 {
var v ExamplepbErrorResponse
err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"));
if err != nil {
newErr.error = err.Error()
return localVarReturnValue, localVarHttpResponse, newErr
}
newErr.model = v
return localVarReturnValue, localVarHttpResponse, newErr
}

if localVarHttpResponse.StatusCode == 0 {
var v RpcStatus
err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"));
if err != nil {
newErr.error = err.Error()
return localVarReturnValue, localVarHttpResponse, newErr
}
newErr.model = v
return localVarReturnValue, localVarHttpResponse, newErr
}

return localVarReturnValue, localVarHttpResponse, newErr
}

return localVarReturnValue, localVarHttpResponse, nil
}

/*
ABitOfEverythingServiceApiService
* @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
* @param value
@return interface{}
*/
func (a *ABitOfEverythingServiceApiService) ABitOfEverythingServiceCheckExternalPathEnum(ctx context.Context, value string) (interface{}, *http.Response, error) {
var (
localVarHttpMethod = strings.ToUpper("Get")
localVarPostBody interface{}
localVarFileName string
localVarFileBytes []byte
localVarReturnValue interface{}
)

// create path and map variables
localVarPath := a.client.cfg.BasePath + "/v2/{value}:check"
localVarPath = strings.Replace(localVarPath, "{"+"value"+"}", fmt.Sprintf("%v", value), -1)
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,7 @@ service ABitOfEverythingService {
}
rpc CheckExternalNestedPathEnum(pathenum.MessageWithNestedPathEnum) returns (google.protobuf.Empty) {
option (google.api.http) = {
get: "/v2/{value}:check"
get: "/v3/{value}:check"
};
}

Expand Down
63 changes: 60 additions & 3 deletions examples/internal/proto/examplepb/a_bit_of_everything.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -3186,7 +3186,7 @@
},
"/v2/{value}:check": {
"get": {
"operationId": "ABitOfEverythingService_CheckExternalNestedPathEnum",
"operationId": "ABitOfEverythingService_CheckExternalPathEnum",
"responses": {
"200": {
"description": "A successful response.",
Expand Down Expand Up @@ -3231,8 +3231,8 @@
"required": true,
"type": "string",
"enum": [
"GHI",
"JKL"
"ABC",
"DEF"
]
}
],
Expand Down Expand Up @@ -3301,6 +3301,63 @@
"ABitOfEverythingService"
]
}
},
"/v3/{value}:check": {
"get": {
"operationId": "ABitOfEverythingService_CheckExternalNestedPathEnum",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"properties": {}
}
},
"403": {
"description": "Returned when the user does not have permission to access the resource.",
"schema": {}
},
"404": {
"description": "Returned when the resource does not exist.",
"schema": {
"type": "string",
"format": "string"
}
},
"418": {
"description": "I'm a teapot.",
"schema": {
"$ref": "#/definitions/examplepbNumericEnum"
}
},
"500": {
"description": "Server error",
"schema": {
"$ref": "#/definitions/examplepbErrorResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "value",
"in": "path",
"required": true,
"type": "string",
"enum": [
"GHI",
"JKL"
]
}
],
"tags": [
"ABitOfEverythingService"
]
}
}
},
"definitions": {
Expand Down
Loading

0 comments on commit c4dfa54

Please sign in to comment.