blob: f1e729fe60bdb221bd06249e6aa87ae646149813 [file] [log] [blame]
/*
* Copyright 2018-present Open Networking Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// gRPC affinity router with active/active backends
package afrouter
import (
"fmt"
"errors"
"google.golang.org/grpc"
)
const (
RT_RPC_AFFINITY_MESSAGE = iota+1
RT_RPC_AFFINITY_HEADER = iota+1
RT_BINDING = iota+1
RT_ROUND_ROBIN = iota+1
)
// String names for display in error messages.
var rTypeNames = []string{"","rpc_affinity_message","rpc_affinity_header","binding", "round_robin"}
var rAssnNames = []string{"","round_robin"}
var allRouters map[string]Router = make(map[string]Router)
// The router interface
type Router interface {
Name() (string)
Route(interface{}) *backend
Service() (string)
BackendCluster(string, string) (*backendCluster, error)
FindBackendCluster(string) (*backendCluster)
ReplyHandler(interface{}) error
GetMetaKeyVal(serverStream grpc.ServerStream) (string,string,error)
}
func newRouter(config *RouterConfig) (Router, error) {
r,err := newMethodRouter(config)
if err == nil {
allRouters[r.Name()] = r
}
return r, err
}
func newSubRouter(rconf *RouterConfig, config *RouteConfig) (Router, error) {
idx := strIndex(rTypeNames, config.Type)
switch idx {
case RT_RPC_AFFINITY_MESSAGE:
r,err := newAffinityRouter(rconf, config)
if err == nil {
allRouters[rconf.Name+config.Name] = r
}
return r, err
case RT_BINDING:
r,err := newBindingRouter(rconf, config)
if err == nil {
allRouters[rconf.Name+config.Name] = r
}
return r, err
case RT_ROUND_ROBIN:
r,err := newRoundRobinRouter(rconf, config)
if err == nil {
allRouters[rconf.Name+config.Name] = r
}
return r, err
default:
return nil, errors.New(fmt.Sprintf("Internal error, undefined router type: %s", config.Type))
}
return nil, errors.New(fmt.Sprintf("Unrecognized router type '%s'",config.Type))
}