blob: 71c7b1ffe36958a65eb67dca261703c289d6358f [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
// This file implements the ArouterPoxy struct and its
// functions. The ArouterProxy is the top level object
// for the affinity router.
import (
"github.com/opencord/voltha-go/common/log"
)
type nbi int
const (
GRPC_NBI nbi = 1
GRPC_STREAMING_NBI nbi = 2
GRPC_CONTROL_NBI nbi = 3
)
// String names for display in error messages.
var arpxyNames = [...]string{"grpc_nbi", "grpc_streaming_nbi", "grpc_control_nbi"}
var arProxy *ArouterProxy = nil
type ArouterProxy struct {
servers map[string]*server // Defined in handler.go
api *ArouterApi
}
// Create the routing proxy
func NewArouterProxy(conf *Configuration) (*ArouterProxy, error) {
arProxy = &ArouterProxy{servers: make(map[string]*server)}
// Create all the servers listed in the configuration
for _, s := range conf.Servers {
if ns, err := newServer(&s); err != nil {
log.Error("Configuration failed")
return nil, err
} else {
arProxy.servers[ns.Name()] = ns
}
}
// TODO: The API is not mandatory, check if it's even in the config before
// trying to create it. If it isn't then don't bother but log a warning.
if api, err := newApi(&conf.Api, arProxy); err != nil {
return nil, err
} else {
arProxy.api = api
}
return arProxy, nil
}
// Start serving
func (ap *ArouterProxy) ListenAndServe() error {
for _, srvr := range ap.servers {
ap.serve(srvr)
}
ap.api.serve()
// Just wait until we're done which only happens
// on a signal or an error.
err := <-doneChan
return err
}
func (ap *ArouterProxy) serve(srvr *server) {
// Start a serving thread
go func() {
srvr.running = true
if err := srvr.proxyServer.Serve(srvr.proxyListener); err != nil {
srvr.running = false
log.Error(err)
errChan <- err
}
}()
}