blob: 70f164a2f0019b5876109a38bde1d6d6fa5b17a3 [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 Hagerman1e9061e2019-05-21 16:01:21 -040083func (rr RoundRobinRouter) BackendCluster(s string, mk string) (*cluster, error) {
84 return rr.cluster, nil
sslobodr392ebd52019-01-18 12:41:49 -050085}
86
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040087func (rr RoundRobinRouter) Name() string {
sslobodr392ebd52019-01-18 12:41:49 -050088 return rr.name
89}
90
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040091func (rr RoundRobinRouter) Route(sel interface{}) *backend {
sslobodr392ebd52019-01-18 12:41:49 -050092 var err error
93 switch sl := sel.(type) {
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040094 case *nbFrame:
95 // Since this is a round robin router just get the next backend
Kent Hagerman1e9061e2019-05-21 16:01:21 -040096 if *rr.currentBackend, err = rr.cluster.nextBackend(*rr.currentBackend, BackendSequenceRoundRobin); err == nil {
97 return *rr.currentBackend
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040098 } else {
99 sl.err = err
sslobodr392ebd52019-01-18 12:41:49 -0500100 return nil
Kent Hagerman0ab4cb22019-04-24 13:13:35 -0400101 }
102 default:
103 log.Errorf("Internal: invalid data type in Route call %v", sel)
104 return nil
sslobodr392ebd52019-01-18 12:41:49 -0500105 }
sslobodr392ebd52019-01-18 12:41:49 -0500106}
107
Kent Hagerman0ab4cb22019-04-24 13:13:35 -0400108func (rr RoundRobinRouter) Service() string {
sslobodr392ebd52019-01-18 12:41:49 -0500109 return rr.grpcService
110}
111
Kent Hagerman1e9061e2019-05-21 16:01:21 -0400112func (rr RoundRobinRouter) FindBackendCluster(becName string) *cluster {
113 if becName == rr.cluster.name {
114 return rr.cluster
sslobodr360c8d72019-02-05 12:47:56 -0500115 }
116 return nil
sslobodr392ebd52019-01-18 12:41:49 -0500117}
118
119func (rr RoundRobinRouter) ReplyHandler(sel interface{}) error { // This is a no-op
120 return nil
121}