MakeBuilderMap parses the provided RouteLookupConfig proto and returns a map from paths to key builders.
(cfg *rlspb.RouteLookupConfig)
| 35 | // MakeBuilderMap parses the provided RouteLookupConfig proto and returns a map |
| 36 | // from paths to key builders. |
| 37 | func MakeBuilderMap(cfg *rlspb.RouteLookupConfig) (BuilderMap, error) { |
| 38 | kbs := cfg.GetGrpcKeybuilders() |
| 39 | if len(kbs) == 0 { |
| 40 | return nil, errors.New("rls: RouteLookupConfig does not contain any GrpcKeyBuilder") |
| 41 | } |
| 42 | |
| 43 | bm := make(map[string]builder) |
| 44 | for _, kb := range kbs { |
| 45 | // Extract keys from `headers`, `constant_keys` and `extra_keys` fields |
| 46 | // and populate appropriate values in the builder struct. Also ensure |
| 47 | // that keys are not repeated. |
| 48 | var matchers []matcher |
| 49 | seenKeys := make(map[string]bool) |
| 50 | constantKeys := kb.GetConstantKeys() |
| 51 | for k := range kb.GetConstantKeys() { |
| 52 | seenKeys[k] = true |
| 53 | } |
| 54 | for _, h := range kb.GetHeaders() { |
| 55 | if h.GetRequiredMatch() { |
| 56 | return nil, fmt.Errorf("rls: GrpcKeyBuilder in RouteLookupConfig has required_match field set {%+v}", kbs) |
| 57 | } |
| 58 | key := h.GetKey() |
| 59 | if seenKeys[key] { |
| 60 | return nil, fmt.Errorf("rls: GrpcKeyBuilder in RouteLookupConfig contains repeated key %q across headers, constant_keys and extra_keys {%+v}", key, kbs) |
| 61 | } |
| 62 | seenKeys[key] = true |
| 63 | matchers = append(matchers, matcher{key: h.GetKey(), names: h.GetNames()}) |
| 64 | } |
| 65 | if seenKeys[kb.GetExtraKeys().GetHost()] { |
| 66 | return nil, fmt.Errorf("rls: GrpcKeyBuilder in RouteLookupConfig contains repeated key %q in extra_keys from constant_keys or headers {%+v}", kb.GetExtraKeys().GetHost(), kbs) |
| 67 | } |
| 68 | if seenKeys[kb.GetExtraKeys().GetService()] { |
| 69 | return nil, fmt.Errorf("rls: GrpcKeyBuilder in RouteLookupConfig contains repeated key %q in extra_keys from constant_keys or headers {%+v}", kb.GetExtraKeys().GetService(), kbs) |
| 70 | } |
| 71 | if seenKeys[kb.GetExtraKeys().GetMethod()] { |
| 72 | return nil, fmt.Errorf("rls: GrpcKeyBuilder in RouteLookupConfig contains repeated key %q in extra_keys from constant_keys or headers {%+v}", kb.GetExtraKeys().GetMethod(), kbs) |
| 73 | } |
| 74 | b := builder{ |
| 75 | headerKeys: matchers, |
| 76 | constantKeys: constantKeys, |
| 77 | hostKey: kb.GetExtraKeys().GetHost(), |
| 78 | serviceKey: kb.GetExtraKeys().GetService(), |
| 79 | methodKey: kb.GetExtraKeys().GetMethod(), |
| 80 | } |
| 81 | |
| 82 | // Store the builder created above in the BuilderMap based on the value |
| 83 | // of the `Names` field, which wraps incoming request's service and |
| 84 | // method. Also, ensure that there are no repeated `Names` field. |
| 85 | names := kb.GetNames() |
| 86 | if len(names) == 0 { |
| 87 | return nil, fmt.Errorf("rls: GrpcKeyBuilder in RouteLookupConfig does not contain any Name {%+v}", kbs) |
| 88 | } |
| 89 | for _, name := range names { |
| 90 | if name.GetService() == "" { |
| 91 | return nil, fmt.Errorf("rls: GrpcKeyBuilder in RouteLookupConfig contains a Name field with no Service {%+v}", kbs) |
| 92 | } |
| 93 | if strings.Contains(name.GetMethod(), `/`) { |
| 94 | return nil, fmt.Errorf("rls: GrpcKeyBuilder in RouteLookupConfig contains a method with a slash {%+v}", kbs) |