1/* 2 * 3 * Copyright 2019 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package edsbalancer 19 20import ( 21 "encoding/json" 22 "fmt" 23 24 "google.golang.org/grpc/balancer" 25 "google.golang.org/grpc/serviceconfig" 26) 27 28// EDSConfig represents the loadBalancingConfig section of the service config 29// for EDS balancers. 30type EDSConfig struct { 31 serviceconfig.LoadBalancingConfig 32 // BalancerName represents the load balancer to use. 33 BalancerName string 34 // ChildPolicy represents the load balancing config for the child 35 // policy. 36 ChildPolicy *loadBalancingConfig 37 // FallBackPolicy represents the load balancing config for the 38 // fallback. 39 FallBackPolicy *loadBalancingConfig 40 // Name to use in EDS query. If not present, defaults to the server 41 // name from the target URI. 42 EDSServiceName string 43 // LRS server to send load reports to. If not present, load reporting 44 // will be disabled. If set to the empty string, load reporting will 45 // be sent to the same server that we obtained CDS data from. 46 LrsLoadReportingServerName *string 47} 48 49// edsConfigJSON is the intermediate unmarshal result of EDSConfig. ChildPolicy 50// and Fallbackspolicy are post-processed, and for each, the first installed 51// policy is kept. 52type edsConfigJSON struct { 53 BalancerName string 54 ChildPolicy []*loadBalancingConfig 55 FallbackPolicy []*loadBalancingConfig 56 EDSServiceName string 57 LRSLoadReportingServerName *string 58} 59 60// UnmarshalJSON parses the JSON-encoded byte slice in data and stores it in l. 61// When unmarshalling, we iterate through the childPolicy/fallbackPolicy lists 62// and select the first LB policy which has been registered. 63func (l *EDSConfig) UnmarshalJSON(data []byte) error { 64 var configJSON edsConfigJSON 65 if err := json.Unmarshal(data, &configJSON); err != nil { 66 return err 67 } 68 69 l.BalancerName = configJSON.BalancerName 70 l.EDSServiceName = configJSON.EDSServiceName 71 l.LrsLoadReportingServerName = configJSON.LRSLoadReportingServerName 72 73 for _, lbcfg := range configJSON.ChildPolicy { 74 if balancer.Get(lbcfg.Name) != nil { 75 l.ChildPolicy = lbcfg 76 break 77 } 78 } 79 80 for _, lbcfg := range configJSON.FallbackPolicy { 81 if balancer.Get(lbcfg.Name) != nil { 82 l.FallBackPolicy = lbcfg 83 break 84 } 85 } 86 return nil 87} 88 89// MarshalJSON returns a JSON encoding of l. 90func (l *EDSConfig) MarshalJSON() ([]byte, error) { 91 return nil, fmt.Errorf("EDSConfig.MarshalJSON() is unimplemented") 92} 93 94// loadBalancingConfig represents a single load balancing config, 95// stored in JSON format. 96type loadBalancingConfig struct { 97 Name string 98 Config json.RawMessage 99} 100 101// MarshalJSON returns a JSON encoding of l. 102func (l *loadBalancingConfig) MarshalJSON() ([]byte, error) { 103 return nil, fmt.Errorf("loadBalancingConfig.MarshalJSON() is unimplemented") 104} 105 106// UnmarshalJSON parses the JSON-encoded byte slice in data and stores it in l. 107func (l *loadBalancingConfig) UnmarshalJSON(data []byte) error { 108 var cfg map[string]json.RawMessage 109 if err := json.Unmarshal(data, &cfg); err != nil { 110 return err 111 } 112 for name, config := range cfg { 113 l.Name = name 114 l.Config = config 115 } 116 return nil 117} 118