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