blob: 71c7b1ffe36958a65eb67dca261703c289d6358f [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
sslobodr392ebd52019-01-18 12:41:49 -050028type nbi int
29
30const (
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040031 GRPC_NBI nbi = 1
sslobodr392ebd52019-01-18 12:41:49 -050032 GRPC_STREAMING_NBI nbi = 2
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040033 GRPC_CONTROL_NBI nbi = 3
sslobodr392ebd52019-01-18 12:41:49 -050034)
35
36// String names for display in error messages.
37var arpxyNames = [...]string{"grpc_nbi", "grpc_streaming_nbi", "grpc_control_nbi"}
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040038var arProxy *ArouterProxy = nil
sslobodr392ebd52019-01-18 12:41:49 -050039
40type ArouterProxy struct {
41 servers map[string]*server // Defined in handler.go
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040042 api *ArouterApi
sslobodr392ebd52019-01-18 12:41:49 -050043}
44
sslobodr392ebd52019-01-18 12:41:49 -050045// Create the routing proxy
46func NewArouterProxy(conf *Configuration) (*ArouterProxy, error) {
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040047 arProxy = &ArouterProxy{servers: make(map[string]*server)}
sslobodr392ebd52019-01-18 12:41:49 -050048 // Create all the servers listed in the configuration
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040049 for _, s := range conf.Servers {
50 if ns, err := newServer(&s); err != nil {
51 log.Error("Configuration failed")
52 return nil, err
53 } else {
sslobodr392ebd52019-01-18 12:41:49 -050054 arProxy.servers[ns.Name()] = ns
55 }
56 }
57
58 // TODO: The API is not mandatory, check if it's even in the config before
59 // trying to create it. If it isn't then don't bother but log a warning.
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040060 if api, err := newApi(&conf.Api, arProxy); err != nil {
sslobodr392ebd52019-01-18 12:41:49 -050061 return nil, err
62 } else {
63 arProxy.api = api
64 }
65
66 return arProxy, nil
67}
68
69// Start serving
70func (ap *ArouterProxy) ListenAndServe() error {
71
72 for _, srvr := range ap.servers {
73 ap.serve(srvr)
74 }
75 ap.api.serve()
76
77 // Just wait until we're done which only happens
78 // on a signal or an error.
79 err := <-doneChan
80
81 return err
82}
83
84func (ap *ArouterProxy) serve(srvr *server) {
85
86 // Start a serving thread
87 go func() {
88 srvr.running = true
89 if err := srvr.proxyServer.Serve(srvr.proxyListener); err != nil {
90 srvr.running = false
91 log.Error(err)
92 errChan <- err
93 }
94 }()
95}