blob: f71bd308c930008700cb633270b216a7ddc26be7 [file] [log] [blame]
sslobodr392ebd52019-01-18 12:41:49 -05001/*
2 * Copyright 2018-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16// gRPC affinity router with active/active backends
17
18package afrouter
19
20import (
sslobodr392ebd52019-01-18 12:41:49 -050021 "errors"
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040022 "fmt"
sslobodr392ebd52019-01-18 12:41:49 -050023 "google.golang.org/grpc"
24)
25
26const (
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040027 RT_RPC_AFFINITY_MESSAGE = iota + 1
28 RT_RPC_AFFINITY_HEADER = iota + 1
29 RT_BINDING = iota + 1
30 RT_ROUND_ROBIN = iota + 1
sslobodr392ebd52019-01-18 12:41:49 -050031)
32
33// String names for display in error messages.
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040034var rTypeNames = []string{"", "rpc_affinity_message", "rpc_affinity_header", "binding", "round_robin"}
35var rAssnNames = []string{"", "round_robin"}
sslobodr392ebd52019-01-18 12:41:49 -050036
37var allRouters map[string]Router = make(map[string]Router)
38
39// The router interface
40type Router interface {
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040041 Name() string
sslobodr392ebd52019-01-18 12:41:49 -050042 Route(interface{}) *backend
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040043 Service() string
sslobodr392ebd52019-01-18 12:41:49 -050044 BackendCluster(string, string) (*backendCluster, error)
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040045 FindBackendCluster(string) *backendCluster
sslobodr392ebd52019-01-18 12:41:49 -050046 ReplyHandler(interface{}) error
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040047 GetMetaKeyVal(serverStream grpc.ServerStream) (string, string, error)
sslobodr392ebd52019-01-18 12:41:49 -050048}
49
sslobodrcd37bc52019-01-24 11:47:16 -050050func newRouter(config *RouterConfig) (Router, error) {
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040051 r, err := newMethodRouter(config)
52 if err == nil {
sslobodr392ebd52019-01-18 12:41:49 -050053 allRouters[r.Name()] = r
54 }
55 return r, err
56}
57
sslobodrcd37bc52019-01-24 11:47:16 -050058func newSubRouter(rconf *RouterConfig, config *RouteConfig) (Router, error) {
sslobodr392ebd52019-01-18 12:41:49 -050059 idx := strIndex(rTypeNames, config.Type)
sslobodr5f0b5a32019-01-24 07:45:19 -050060 switch idx {
61 case RT_RPC_AFFINITY_MESSAGE:
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040062 r, err := newAffinityRouter(rconf, config)
sslobodr5f0b5a32019-01-24 07:45:19 -050063 if err == nil {
64 allRouters[rconf.Name+config.Name] = r
65 }
66 return r, err
67 case RT_BINDING:
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040068 r, err := newBindingRouter(rconf, config)
sslobodr5f0b5a32019-01-24 07:45:19 -050069 if err == nil {
70 allRouters[rconf.Name+config.Name] = r
71 }
72 return r, err
73 case RT_ROUND_ROBIN:
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040074 r, err := newRoundRobinRouter(rconf, config)
sslobodr5f0b5a32019-01-24 07:45:19 -050075 if err == nil {
76 allRouters[rconf.Name+config.Name] = r
77 }
78 return r, err
79 default:
80 return nil, errors.New(fmt.Sprintf("Internal error, undefined router type: %s", config.Type))
81 }
sslobodr392ebd52019-01-18 12:41:49 -050082}