descriptorsource.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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. if ext == nil {
  35. methods = append(methods, Method{
  36. RpcPath: rpcPath,
  37. })
  38. continue
  39. }
  40. httpExt, ok := ext.(*annotations.HttpRule)
  41. if !ok {
  42. methods = append(methods, Method{
  43. RpcPath: rpcPath,
  44. })
  45. continue
  46. }
  47. switch rule := httpExt.GetPattern().(type) {
  48. case *annotations.HttpRule_Get:
  49. methods = append(methods, Method{
  50. HttpMethod: http.MethodGet,
  51. HttpPath: adjustHttpPath(rule.Get),
  52. RpcPath: rpcPath,
  53. })
  54. case *annotations.HttpRule_Post:
  55. methods = append(methods, Method{
  56. HttpMethod: http.MethodPost,
  57. HttpPath: adjustHttpPath(rule.Post),
  58. RpcPath: rpcPath,
  59. })
  60. case *annotations.HttpRule_Put:
  61. methods = append(methods, Method{
  62. HttpMethod: http.MethodPut,
  63. HttpPath: adjustHttpPath(rule.Put),
  64. RpcPath: rpcPath,
  65. })
  66. case *annotations.HttpRule_Delete:
  67. methods = append(methods, Method{
  68. HttpMethod: http.MethodDelete,
  69. HttpPath: adjustHttpPath(rule.Delete),
  70. RpcPath: rpcPath,
  71. })
  72. case *annotations.HttpRule_Patch:
  73. methods = append(methods, Method{
  74. HttpMethod: http.MethodPatch,
  75. HttpPath: adjustHttpPath(rule.Patch),
  76. RpcPath: rpcPath,
  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. }