blob: 60ff4576904f61a3eed79a176bc65538657f15bf [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 */
sslobodr392ebd52019-01-18 12:41:49 -050016
17package afrouter
18
19import (
sslobodr392ebd52019-01-18 12:41:49 -050020 "errors"
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040021 "fmt"
sslobodr392ebd52019-01-18 12:41:49 -050022 "github.com/opencord/voltha-go/common/log"
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040023 "google.golang.org/grpc"
sslobodr392ebd52019-01-18 12:41:49 -050024)
25
26type RoundRobinRouter struct {
Kent Hagerman1e9061e2019-05-21 16:01:21 -040027 name string
28 grpcService string
29 cluster *cluster
30 currentBackend **backend
sslobodr392ebd52019-01-18 12:41:49 -050031}
32
sslobodrcd37bc52019-01-24 11:47:16 -050033func newRoundRobinRouter(rconf *RouterConfig, config *RouteConfig) (Router, error) {
sslobodr392ebd52019-01-18 12:41:49 -050034 var err error = nil
Kent Hagerman1e9061e2019-05-21 16:01:21 -040035 var rtrn_err = false
sslobodr392ebd52019-01-18 12:41:49 -050036 // Validate the configuration
37
38 log.Debug("Creating a new round robin router")
39 // A name must exist
40 if config.Name == "" {
41 log.Error("A router 'name' must be specified")
42 rtrn_err = true
43 }
44
45 if rconf.ProtoPackage == "" {
46 log.Error("A 'package' must be specified")
47 rtrn_err = true
48 }
49
50 if rconf.ProtoService == "" {
51 log.Error("A 'service' must be specified")
52 rtrn_err = true
53 }
54
55 var bptr *backend
56 bptr = nil
57 rr := RoundRobinRouter{
Kent Hagerman1e9061e2019-05-21 16:01:21 -040058 name: config.Name,
59 grpcService: rconf.ProtoService,
60 currentBackend: &bptr,
sslobodr392ebd52019-01-18 12:41:49 -050061 }
62
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040063 // Create the backend cluster or link to an existing one
sslobodr392ebd52019-01-18 12:41:49 -050064 ok := true
Kent Hagerman1e9061e2019-05-21 16:01:21 -040065 if rr.cluster, ok = clusters[config.backendCluster.Name]; !ok {
66 if rr.cluster, err = newBackendCluster(config.backendCluster); err != nil {
sslobodr392ebd52019-01-18 12:41:49 -050067 log.Errorf("Could not create a backend for router %s", config.Name)
68 rtrn_err = true
69 }
70 }
71
72 if rtrn_err {
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040073 return rr, errors.New(fmt.Sprintf("Failed to create a new router '%s'", rr.name))
sslobodr392ebd52019-01-18 12:41:49 -050074 }
75
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040076 return rr, nil
sslobodr392ebd52019-01-18 12:41:49 -050077}
78
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040079func (rr RoundRobinRouter) GetMetaKeyVal(serverStream grpc.ServerStream) (string, string, error) {
80 return "", "", nil
sslobodr392ebd52019-01-18 12:41:49 -050081}
82
Kent Hagerman03b58992019-08-29 17:21:03 -040083func (rr RoundRobinRouter) IsStreaming(_ string) (bool, bool) {
84 panic("not implemented")
85}
86
Kent Hagerman1e9061e2019-05-21 16:01:21 -040087func (rr RoundRobinRouter) BackendCluster(s string, mk string) (*cluster, error) {
88 return rr.cluster, nil
sslobodr392ebd52019-01-18 12:41:49 -050089}
90
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040091func (rr RoundRobinRouter) Name() string {
sslobodr392ebd52019-01-18 12:41:49 -050092 return rr.name
93}
94
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040095func (rr RoundRobinRouter) Route(sel interface{}) *backend {
sslobodr392ebd52019-01-18 12:41:49 -050096 var err error
97 switch sl := sel.(type) {
Kent Hagerman03b58992019-08-29 17:21:03 -040098 case *requestFrame:
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040099 // Since this is a round robin router just get the next backend
Kent Hagerman1e9061e2019-05-21 16:01:21 -0400100 if *rr.currentBackend, err = rr.cluster.nextBackend(*rr.currentBackend, BackendSequenceRoundRobin); err == nil {
101 return *rr.currentBackend
Kent Hagerman0ab4cb22019-04-24 13:13:35 -0400102 } else {
103 sl.err = err
sslobodr392ebd52019-01-18 12:41:49 -0500104 return nil
Kent Hagerman0ab4cb22019-04-24 13:13:35 -0400105 }
106 default:
107 log.Errorf("Internal: invalid data type in Route call %v", sel)
108 return nil
sslobodr392ebd52019-01-18 12:41:49 -0500109 }
sslobodr392ebd52019-01-18 12:41:49 -0500110}
111
Kent Hagerman0ab4cb22019-04-24 13:13:35 -0400112func (rr RoundRobinRouter) Service() string {
sslobodr392ebd52019-01-18 12:41:49 -0500113 return rr.grpcService
114}
115
Kent Hagerman1e9061e2019-05-21 16:01:21 -0400116func (rr RoundRobinRouter) FindBackendCluster(becName string) *cluster {
117 if becName == rr.cluster.name {
118 return rr.cluster
sslobodr360c8d72019-02-05 12:47:56 -0500119 }
120 return nil
sslobodr392ebd52019-01-18 12:41:49 -0500121}
122
123func (rr RoundRobinRouter) ReplyHandler(sel interface{}) error { // This is a no-op
124 return nil
125}