descriptorsource.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. package internal
  2. import (
  3. "fmt"
  4. "net/http"
  5. "strings"
  6. "github.com/fullstorydev/grpcurl"
  7. "github.com/jhump/protoreflect/desc"
  8. "google.golang.org/genproto/googleapis/api/annotations"
  9. "google.golang.org/protobuf/proto"
  10. )
  11. type Method struct {
  12. HttpMethod string
  13. HttpPath string
  14. RpcPath string
  15. }
  16. // GetMethods returns all methods of the given grpcurl.DescriptorSource.
  17. func GetMethods(source grpcurl.DescriptorSource) ([]Method, error) {
  18. svcs, err := source.ListServices()
  19. if err != nil {
  20. return nil, err
  21. }
  22. var methods []Method
  23. for _, svc := range svcs {
  24. d, err := source.FindSymbol(svc)
  25. if err != nil {
  26. return nil, err
  27. }
  28. switch val := d.(type) {
  29. case *desc.ServiceDescriptor:
  30. svcMethods := val.GetMethods()
  31. for _, method := range svcMethods {
  32. rpcPath := fmt.Sprintf("%s/%s", svc, method.GetName())
  33. ext := proto.GetExtension(method.GetMethodOptions(), annotations.E_Http)
  34. switch rule := ext.(type) {
  35. case *annotations.HttpRule:
  36. if rule == nil {
  37. methods = append(methods, Method{
  38. RpcPath: rpcPath,
  39. })
  40. continue
  41. }
  42. switch httpRule := rule.GetPattern().(type) {
  43. case *annotations.HttpRule_Get:
  44. methods = append(methods, Method{
  45. HttpMethod: http.MethodGet,
  46. HttpPath: adjustHttpPath(httpRule.Get),
  47. RpcPath: rpcPath,
  48. })
  49. case *annotations.HttpRule_Post:
  50. methods = append(methods, Method{
  51. HttpMethod: http.MethodPost,
  52. HttpPath: adjustHttpPath(httpRule.Post),
  53. RpcPath: rpcPath,
  54. })
  55. case *annotations.HttpRule_Put:
  56. methods = append(methods, Method{
  57. HttpMethod: http.MethodPut,
  58. HttpPath: adjustHttpPath(httpRule.Put),
  59. RpcPath: rpcPath,
  60. })
  61. case *annotations.HttpRule_Delete:
  62. methods = append(methods, Method{
  63. HttpMethod: http.MethodDelete,
  64. HttpPath: adjustHttpPath(httpRule.Delete),
  65. RpcPath: rpcPath,
  66. })
  67. case *annotations.HttpRule_Patch:
  68. methods = append(methods, Method{
  69. HttpMethod: http.MethodPatch,
  70. HttpPath: adjustHttpPath(httpRule.Patch),
  71. RpcPath: rpcPath,
  72. })
  73. default:
  74. methods = append(methods, Method{
  75. RpcPath: rpcPath,
  76. })
  77. }
  78. default:
  79. methods = append(methods, Method{
  80. RpcPath: rpcPath,
  81. })
  82. }
  83. }
  84. }
  85. }
  86. return methods, nil
  87. }
  88. func adjustHttpPath(path string) string {
  89. path = strings.ReplaceAll(path, "{", ":")
  90. path = strings.ReplaceAll(path, "}", "")
  91. return path
  92. }