blob: ca68ed74db194e93f4e858d1bcdef913bceb4946 [file] [log] [blame]
package descriptor
import (
"bytes"
"fmt"
"io/ioutil"
"strings"
"github.com/ghodss/yaml"
"github.com/golang/protobuf/jsonpb"
)
func loadGrpcAPIServiceFromYAML(yamlFileContents []byte, yamlSourceLogName string) (*GrpcAPIService, error) {
jsonContents, err := yaml.YAMLToJSON(yamlFileContents)
if err != nil {
return nil, fmt.Errorf("Failed to convert gRPC API Configuration from YAML in '%v' to JSON: %v", yamlSourceLogName, err)
}
// As our GrpcAPIService is incomplete accept unkown fields.
unmarshaler := jsonpb.Unmarshaler{
AllowUnknownFields: true,
}
serviceConfiguration := GrpcAPIService{}
if err := unmarshaler.Unmarshal(bytes.NewReader(jsonContents), &serviceConfiguration); err != nil {
return nil, fmt.Errorf("Failed to parse gRPC API Configuration from YAML in '%v': %v", yamlSourceLogName, err)
}
return &serviceConfiguration, nil
}
func registerHTTPRulesFromGrpcAPIService(registry *Registry, service *GrpcAPIService, sourceLogName string) error {
if service.HTTP == nil {
// Nothing to do
return nil
}
for _, rule := range service.HTTP.GetRules() {
selector := "." + strings.Trim(rule.GetSelector(), " ")
if strings.ContainsAny(selector, "*, ") {
return fmt.Errorf("Selector '%v' in %v must specify a single service method without wildcards", rule.GetSelector(), sourceLogName)
}
registry.AddExternalHTTPRule(selector, rule)
}
return nil
}
// LoadGrpcAPIServiceFromYAML loads a gRPC API Configuration from the given YAML file
// and registers the HttpRule descriptions contained in it as externalHTTPRules in
// the given registry. This must be done before loading the proto file.
//
// You can learn more about gRPC API Service descriptions from google's documentation
// at https://cloud.google.com/endpoints/docs/grpc/grpc-service-config
//
// Note that for the purposes of the gateway generator we only consider a subset of all
// available features google supports in their service descriptions.
func (r *Registry) LoadGrpcAPIServiceFromYAML(yamlFile string) error {
yamlFileContents, err := ioutil.ReadFile(yamlFile)
if err != nil {
return fmt.Errorf("Failed to read gRPC API Configuration description from '%v': %v", yamlFile, err)
}
service, err := loadGrpcAPIServiceFromYAML(yamlFileContents, yamlFile)
if err != nil {
return err
}
return registerHTTPRulesFromGrpcAPIService(r, service, yamlFile)
}