blob: d809fbbedc7923d2bf74b2e947e26444adb71bd6 [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
20// This file implements the ArouterPoxy struct and its
21// functions. The ArouterProxy is the top level object
22// for the affinity router.
23
24import (
25 "github.com/opencord/voltha-go/common/log"
26)
27
28
29type nbi int
30
31const (
32 GRPC_NBI nbi = 1
33 GRPC_STREAMING_NBI nbi = 2
34 GRPC_CONTROL_NBI nbi = 3
35)
36
37// String names for display in error messages.
38var arpxyNames = [...]string{"grpc_nbi", "grpc_streaming_nbi", "grpc_control_nbi"}
39var arProxy *ArouterProxy= nil
40
41type ArouterProxy struct {
42 servers map[string]*server // Defined in handler.go
43 api *ArouterApi
44}
45
46
47// Create the routing proxy
48func NewArouterProxy(conf *Configuration) (*ArouterProxy, error) {
49 arProxy = &ArouterProxy{servers:make(map[string]*server)}
50 // Create all the servers listed in the configuration
sslobodr5f0b5a32019-01-24 07:45:19 -050051 for _,s := range conf.Servers {
sslobodrcd37bc52019-01-24 11:47:16 -050052 if ns, err := newServer(&s); err != nil {
sslobodr392ebd52019-01-18 12:41:49 -050053 log.Error("Configuration failed")
54 return nil, err
55 } else {
56 arProxy.servers[ns.Name()] = ns
57 }
58 }
59
60 // TODO: The API is not mandatory, check if it's even in the config before
61 // trying to create it. If it isn't then don't bother but log a warning.
sslobodrcd37bc52019-01-24 11:47:16 -050062 if api,err := newApi(&conf.Api, arProxy); err != nil {
sslobodr392ebd52019-01-18 12:41:49 -050063 return nil, err
64 } else {
65 arProxy.api = api
66 }
67
68 return arProxy, nil
69}
70
71// Start serving
72func (ap *ArouterProxy) ListenAndServe() error {
73
74 for _, srvr := range ap.servers {
75 ap.serve(srvr)
76 }
77 ap.api.serve()
78
79 // Just wait until we're done which only happens
80 // on a signal or an error.
81 err := <-doneChan
82
83 return err
84}
85
86func (ap *ArouterProxy) serve(srvr *server) {
87
88 // Start a serving thread
89 go func() {
90 srvr.running = true
91 if err := srvr.proxyServer.Serve(srvr.proxyListener); err != nil {
92 srvr.running = false
93 log.Error(err)
94 errChan <- err
95 }
96 }()
97}