blob: 82269d2b84610acf9d73c37a0a23820d91a3d716 [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"
22 "github.com/opencord/voltha-go/common/log"
sslobodr392ebd52019-01-18 12:41:49 -050023 "google.golang.org/grpc"
24 "google.golang.org/grpc/codes"
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040025 "net"
Kent Hagerman03b58992019-08-29 17:21:03 -040026 "net/url"
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040027 "strconv"
sslobodr392ebd52019-01-18 12:41:49 -050028)
29
30var (
31 clientStreamDescForProxying = &grpc.StreamDesc{
32 ServerStreams: true,
33 ClientStreams: true,
34 }
35)
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040036
sslobodr392ebd52019-01-18 12:41:49 -050037type server struct {
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040038 running bool
39 name string
sslobodr392ebd52019-01-18 12:41:49 -050040 proxyListener net.Listener
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040041 routers map[string]map[string]Router
42 proxyServer *grpc.Server
sslobodr392ebd52019-01-18 12:41:49 -050043}
44
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040045func newServer(config *ServerConfig) (*server, error) {
sslobodr392ebd52019-01-18 12:41:49 -050046 var err error = nil
Kent Hagerman1e9061e2019-05-21 16:01:21 -040047 var rtrn_err = false
48 var s *server
sslobodr392ebd52019-01-18 12:41:49 -050049 // Change over to the new configuration format
50 // Validate the configuration
51 // There should be a name
52 if config.Name == "" {
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040053 log.Error("A server has been defined with no name")
sslobodr392ebd52019-01-18 12:41:49 -050054 rtrn_err = true
55 }
56 // Validate that there's a port specified
57 if config.Port == 0 {
58 log.Errorf("Server %s does not have a valid port assigned", config.Name)
59 rtrn_err = true
60 }
61 // Validate the ip address if one is provided
Kent Hagerman03b58992019-08-29 17:21:03 -040062 if _, err := url.Parse(config.Addr); err != nil {
sslobodr392ebd52019-01-18 12:41:49 -050063 log.Errorf("Invalid address '%s' provided for server '%s'", config.Addr, config.Name)
64 rtrn_err = true
65 }
66 if config.Type != "grpc" && config.Type != "streaming_grpc" {
67 if config.Type == "" {
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040068 log.Errorf("A server 'type' must be defined for server %s", config.Name)
sslobodr392ebd52019-01-18 12:41:49 -050069 } else {
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040070 log.Errorf("The server type must be either 'grpc' or 'streaming_grpc' "+
71 "but '%s' was found for server '%s'", config.Type, config.Name)
sslobodr392ebd52019-01-18 12:41:49 -050072 }
73 rtrn_err = true
74 }
75 if len(config.Routers) == 0 {
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040076 log.Errorf("At least one router must be specified for server '%s'", config.Name)
sslobodr392ebd52019-01-18 12:41:49 -050077 rtrn_err = true
78 }
79
Kent Hagerman1e9061e2019-05-21 16:01:21 -040080 if rtrn_err {
sslobodr392ebd52019-01-18 12:41:49 -050081 return nil, errors.New("Server configuration failed")
82 } else {
83 // The configuration is valid, create a server and configure it.
Kent Hagerman1e9061e2019-05-21 16:01:21 -040084 s = &server{name: config.Name, routers: make(map[string]map[string]Router)}
sslobodr392ebd52019-01-18 12:41:49 -050085 // The listener
Kent Hagerman1e9061e2019-05-21 16:01:21 -040086 if s.proxyListener, err =
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040087 net.Listen("tcp", config.Addr+":"+
88 strconv.Itoa(int(config.Port))); err != nil {
sslobodr392ebd52019-01-18 12:41:49 -050089 log.Error(err)
90 return nil, err
91 }
92 // Create the routers
Kent Hagerman1e9061e2019-05-21 16:01:21 -040093 log.Debugf("Configuring the routers for server %s", s.name)
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040094 for p, r := range config.routers {
95 log.Debugf("Processing router %s for package %s", r.Name, p)
96 if dr, err := newRouter(r); err != nil {
97 log.Error(err)
98 return nil, err
99 } else {
sslobodr392ebd52019-01-18 12:41:49 -0500100 log.Debugf("Adding router %s to the server %s for package %s and service %s",
Kent Hagerman1e9061e2019-05-21 16:01:21 -0400101 dr.Name(), s.name, p, dr.Service())
102 if _, ok := s.routers[p]; ok {
103 s.routers[p][dr.Service()] = dr
sslobodr392ebd52019-01-18 12:41:49 -0500104 } else {
Kent Hagerman1e9061e2019-05-21 16:01:21 -0400105 s.routers[p] = make(map[string]Router)
106 s.routers[p][dr.Service()] = dr
sslobodr392ebd52019-01-18 12:41:49 -0500107 }
108 }
109 }
110 // Configure the grpc handler
Kent Hagerman1e9061e2019-05-21 16:01:21 -0400111 s.proxyServer = grpc.NewServer(
sslobodr392ebd52019-01-18 12:41:49 -0500112 grpc.CustomCodec(Codec()),
Kent Hagerman1e9061e2019-05-21 16:01:21 -0400113 grpc.UnknownServiceHandler(s.TransparentHandler()),
sslobodr392ebd52019-01-18 12:41:49 -0500114 )
115
116 }
Kent Hagerman1e9061e2019-05-21 16:01:21 -0400117 return s, nil
sslobodr392ebd52019-01-18 12:41:49 -0500118}
119
Kent Hagerman0ab4cb22019-04-24 13:13:35 -0400120func (s *server) Name() string {
sslobodr392ebd52019-01-18 12:41:49 -0500121 return s.name
122}
123
124func (s *server) TransparentHandler() grpc.StreamHandler {
125 return s.handler
126}
127
Kent Hagerman1e9061e2019-05-21 16:01:21 -0400128func (s *server) getRouter(pkg string, service string) (Router, bool) {
129 if fn, ok := s.routers[pkg][service]; ok { // Both specified
sslobodr392ebd52019-01-18 12:41:49 -0500130 return fn, ok
Kent Hagerman1e9061e2019-05-21 16:01:21 -0400131 } else if fn, ok = s.routers["*"][service]; ok { // Package wild card
sslobodr392ebd52019-01-18 12:41:49 -0500132 return fn, ok
Kent Hagerman1e9061e2019-05-21 16:01:21 -0400133 } else if fn, ok = s.routers[pkg]["*"]; ok { // Service wild card
sslobodr392ebd52019-01-18 12:41:49 -0500134 return fn, ok
135 } else if fn, ok = s.routers["*"]["*"]; ok { // Both Wildcarded
136 return fn, ok
137 } else {
Kent Hagerman0ab4cb22019-04-24 13:13:35 -0400138 return nil, false
sslobodr392ebd52019-01-18 12:41:49 -0500139 }
140}
141
sslobodr392ebd52019-01-18 12:41:49 -0500142func (s *server) handler(srv interface{}, serverStream grpc.ServerStream) error {
143 // Determine what router is intended to handle this request
144 fullMethodName, ok := grpc.MethodFromServerStream(serverStream)
145 if !ok {
146 return grpc.Errorf(codes.Internal, "lowLevelServerStream doesn't exist in context")
147 }
Kent Hagerman03b58992019-08-29 17:21:03 -0400148 log.Debugf("\n\nProcessing grpc request %s on server %s", fullMethodName, s.name)
Kent Hagerman1e9061e2019-05-21 16:01:21 -0400149 methodInfo := newMethodDetails(fullMethodName)
150 r, ok := s.getRouter(methodInfo.pkg, methodInfo.service)
151 //fn, ok := s.routers[methodInfo.pkg][methodInfo.service]
sslobodr392ebd52019-01-18 12:41:49 -0500152 if !ok {
153 // TODO: Should this be punted to a default transparent router??
154 // Probably not, if one is defined yes otherwise just crap out.
155
Kent Hagerman1e9061e2019-05-21 16:01:21 -0400156 err := fmt.Errorf("Unable to dispatch! Service '%s' for package '%s' not found.", methodInfo.service, methodInfo.pkg)
sslobodr392ebd52019-01-18 12:41:49 -0500157 log.Error(err)
158 return err
159 }
Kent Hagerman03b58992019-08-29 17:21:03 -0400160 log.Debugf("Selected router %s", r.Name())
sslobodr392ebd52019-01-18 12:41:49 -0500161
Kent Hagerman0ab4cb22019-04-24 13:13:35 -0400162 mk, mv, err := r.GetMetaKeyVal(serverStream)
sslobodr392ebd52019-01-18 12:41:49 -0500163 if err != nil {
164 log.Error(err)
165 return err
166 }
167
Kent Hagerman1e9061e2019-05-21 16:01:21 -0400168 //nbR := &nbRequest(srv:srv,serverStream:serverStream,r:r,methodInfo:methodInfo,metaKey:mk,metaVal:mv)
sslobodr392ebd52019-01-18 12:41:49 -0500169
170 // Extract the cluster from the selected router and use it to manage the transfer
Kent Hagerman1e9061e2019-05-21 16:01:21 -0400171 if cluster, err := r.BackendCluster(methodInfo.method, mk); err != nil {
sslobodr392ebd52019-01-18 12:41:49 -0500172 return err
173 } else {
Kent Hagerman1e9061e2019-05-21 16:01:21 -0400174 //return beCluster.handler(nbR)
175 return cluster.handler(srv, serverStream, r, methodInfo, mk, mv)
sslobodr392ebd52019-01-18 12:41:49 -0500176 }
sslobodr392ebd52019-01-18 12:41:49 -0500177}