grpc_api_configuration.go 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. package descriptor
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "strings"
  6. "git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/internal/descriptor/apiconfig"
  7. "github.com/ghodss/yaml"
  8. "google.golang.org/protobuf/encoding/protojson"
  9. )
  10. func loadGrpcAPIServiceFromYAML(yamlFileContents []byte, yamlSourceLogName string) (*apiconfig.GrpcAPIService, error) {
  11. jsonContents, err := yaml.YAMLToJSON(yamlFileContents)
  12. if err != nil {
  13. return nil, fmt.Errorf("failed to convert gRPC API Configuration from YAML in '%v' to JSON: %v", yamlSourceLogName, err)
  14. }
  15. // As our GrpcAPIService is incomplete, accept unknown fields.
  16. unmarshaler := protojson.UnmarshalOptions{
  17. DiscardUnknown: true,
  18. }
  19. serviceConfiguration := apiconfig.GrpcAPIService{}
  20. if err := unmarshaler.Unmarshal(jsonContents, &serviceConfiguration); err != nil {
  21. return nil, fmt.Errorf("failed to parse gRPC API Configuration from YAML in '%v': %v", yamlSourceLogName, err)
  22. }
  23. return &serviceConfiguration, nil
  24. }
  25. func registerHTTPRulesFromGrpcAPIService(registry *Registry, service *apiconfig.GrpcAPIService, sourceLogName string) error {
  26. if service.Http == nil {
  27. // Nothing to do
  28. return nil
  29. }
  30. for _, rule := range service.Http.GetRules() {
  31. selector := "." + strings.Trim(rule.GetSelector(), " ")
  32. if strings.ContainsAny(selector, "*, ") {
  33. return fmt.Errorf("selector '%v' in %v must specify a single service method without wildcards", rule.GetSelector(), sourceLogName)
  34. }
  35. registry.AddExternalHTTPRule(selector, rule)
  36. }
  37. return nil
  38. }
  39. // LoadGrpcAPIServiceFromYAML loads a gRPC API Configuration from the given YAML file
  40. // and registers the HttpRule descriptions contained in it as externalHTTPRules in
  41. // the given registry. This must be done before loading the proto file.
  42. //
  43. // You can learn more about gRPC API Service descriptions from google's documentation
  44. // at https://cloud.google.com/endpoints/docs/grpc/grpc-service-config
  45. //
  46. // Note that for the purposes of the gateway generator we only consider a subset of all
  47. // available features google supports in their service descriptions.
  48. func (r *Registry) LoadGrpcAPIServiceFromYAML(yamlFile string) error {
  49. yamlFileContents, err := ioutil.ReadFile(yamlFile)
  50. if err != nil {
  51. return fmt.Errorf("failed to read gRPC API Configuration description from '%v': %v", yamlFile, err)
  52. }
  53. service, err := loadGrpcAPIServiceFromYAML(yamlFileContents, yamlFile)
  54. if err != nil {
  55. return err
  56. }
  57. return registerHTTPRulesFromGrpcAPIService(r, service, yamlFile)
  58. }