feat: support google.api.http in gateway (#2161)
This commit is contained in:
@@ -2,19 +2,29 @@ package internal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/fullstorydev/grpcurl"
|
||||
"github.com/jhump/protoreflect/desc"
|
||||
"google.golang.org/genproto/googleapis/api/annotations"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
type Method struct {
|
||||
HttpMethod string
|
||||
HttpPath string
|
||||
RpcPath string
|
||||
}
|
||||
|
||||
// GetMethods returns all methods of the given grpcurl.DescriptorSource.
|
||||
func GetMethods(source grpcurl.DescriptorSource) ([]string, error) {
|
||||
func GetMethods(source grpcurl.DescriptorSource) ([]Method, error) {
|
||||
svcs, err := source.ListServices()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var methods []string
|
||||
var methods []Method
|
||||
for _, svc := range svcs {
|
||||
d, err := source.FindSymbol(svc)
|
||||
if err != nil {
|
||||
@@ -25,10 +35,68 @@ func GetMethods(source grpcurl.DescriptorSource) ([]string, error) {
|
||||
case *desc.ServiceDescriptor:
|
||||
svcMethods := val.GetMethods()
|
||||
for _, method := range svcMethods {
|
||||
methods = append(methods, fmt.Sprintf("%s/%s", svc, method.GetName()))
|
||||
rpcPath := fmt.Sprintf("%s/%s", svc, method.GetName())
|
||||
ext := proto.GetExtension(method.GetMethodOptions(), annotations.E_Http)
|
||||
if ext == nil {
|
||||
methods = append(methods, Method{
|
||||
RpcPath: rpcPath,
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
httpExt, ok := ext.(*annotations.HttpRule)
|
||||
if !ok {
|
||||
methods = append(methods, Method{
|
||||
RpcPath: rpcPath,
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
switch rule := httpExt.GetPattern().(type) {
|
||||
case *annotations.HttpRule_Get:
|
||||
methods = append(methods, Method{
|
||||
HttpMethod: http.MethodGet,
|
||||
HttpPath: adjustHttpPath(rule.Get),
|
||||
RpcPath: rpcPath,
|
||||
})
|
||||
case *annotations.HttpRule_Post:
|
||||
methods = append(methods, Method{
|
||||
HttpMethod: http.MethodPost,
|
||||
HttpPath: adjustHttpPath(rule.Post),
|
||||
RpcPath: rpcPath,
|
||||
})
|
||||
case *annotations.HttpRule_Put:
|
||||
methods = append(methods, Method{
|
||||
HttpMethod: http.MethodPut,
|
||||
HttpPath: adjustHttpPath(rule.Put),
|
||||
RpcPath: rpcPath,
|
||||
})
|
||||
case *annotations.HttpRule_Delete:
|
||||
methods = append(methods, Method{
|
||||
HttpMethod: http.MethodDelete,
|
||||
HttpPath: adjustHttpPath(rule.Delete),
|
||||
RpcPath: rpcPath,
|
||||
})
|
||||
case *annotations.HttpRule_Patch:
|
||||
methods = append(methods, Method{
|
||||
HttpMethod: http.MethodPatch,
|
||||
HttpPath: adjustHttpPath(rule.Patch),
|
||||
RpcPath: rpcPath,
|
||||
})
|
||||
default:
|
||||
methods = append(methods, Method{
|
||||
RpcPath: rpcPath,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return methods, nil
|
||||
}
|
||||
|
||||
func adjustHttpPath(path string) string {
|
||||
path = strings.ReplaceAll(path, "{", ":")
|
||||
path = strings.ReplaceAll(path, "}", "")
|
||||
return path
|
||||
}
|
||||
|
||||
@@ -25,5 +25,9 @@ func TestGetMethods(t *testing.T) {
|
||||
assert.Nil(t, err)
|
||||
methods, err := GetMethods(source)
|
||||
assert.Nil(t, err)
|
||||
assert.EqualValues(t, []string{"hello.Hello/Ping"}, methods)
|
||||
assert.EqualValues(t, []Method{
|
||||
{
|
||||
RpcPath: "hello.Hello/Ping",
|
||||
},
|
||||
}, methods)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user