|
@@ -2,19 +2,29 @@ package internal
|
|
|
|
|
|
import (
|
|
import (
|
|
"fmt"
|
|
"fmt"
|
|
|
|
+ "net/http"
|
|
|
|
+ "strings"
|
|
|
|
|
|
"github.com/fullstorydev/grpcurl"
|
|
"github.com/fullstorydev/grpcurl"
|
|
"github.com/jhump/protoreflect/desc"
|
|
"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.
|
|
// 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()
|
|
svcs, err := source.ListServices()
|
|
if err != nil {
|
|
if err != nil {
|
|
return nil, err
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
|
|
- var methods []string
|
|
|
|
|
|
+ var methods []Method
|
|
for _, svc := range svcs {
|
|
for _, svc := range svcs {
|
|
d, err := source.FindSymbol(svc)
|
|
d, err := source.FindSymbol(svc)
|
|
if err != nil {
|
|
if err != nil {
|
|
@@ -25,10 +35,68 @@ func GetMethods(source grpcurl.DescriptorSource) ([]string, error) {
|
|
case *desc.ServiceDescriptor:
|
|
case *desc.ServiceDescriptor:
|
|
svcMethods := val.GetMethods()
|
|
svcMethods := val.GetMethods()
|
|
for _, method := range svcMethods {
|
|
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
|
|
return methods, nil
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+func adjustHttpPath(path string) string {
|
|
|
|
+ path = strings.ReplaceAll(path, "{", ":")
|
|
|
|
+ path = strings.ReplaceAll(path, "}", "")
|
|
|
|
+ return path
|
|
|
|
+}
|