blob: 7ea6ef21c0430fe08360542ba914a1c9e0f5f8d4 [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 (
20 "fmt"
sslobodr392ebd52019-01-18 12:41:49 -050021 "github.com/golang/protobuf/proto"
22 "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
26func Codec() grpc.Codec {
27 return CodecWithParent(&protoCodec{})
28}
29
sslobodrcd37bc52019-01-24 11:47:16 -050030func CodecWithParent(parent grpc.Codec) grpc.Codec {
31 return &transparentRoutingCodec{parent}
sslobodr392ebd52019-01-18 12:41:49 -050032}
33
sslobodrcd37bc52019-01-24 11:47:16 -050034type transparentRoutingCodec struct {
sslobodr392ebd52019-01-18 12:41:49 -050035 parentCodec grpc.Codec
36}
37
Kent Hagerman03b58992019-08-29 17:21:03 -040038// responseFrame is a frame being "returned" to whomever established the connection
39type responseFrame struct {
sslobodr392ebd52019-01-18 12:41:49 -050040 payload []byte
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040041 router Router
42 method string
Kent Hagerman1e9061e2019-05-21 16:01:21 -040043 backend *backend
sslobodr392ebd52019-01-18 12:41:49 -050044 metaKey string
45 metaVal string
46}
47
Kent Hagerman03b58992019-08-29 17:21:03 -040048// requestFrame is a frame coming in from whomever established the connection
49type requestFrame struct {
Kent Hagerman1e9061e2019-05-21 16:01:21 -040050 payload []byte
51 router Router
52 backend *backend
53 err error
54 methodInfo methodDetails
55 serialNo uint64
56 metaKey string
57 metaVal string
sslobodr392ebd52019-01-18 12:41:49 -050058}
59
sslobodrcd37bc52019-01-24 11:47:16 -050060func (cdc *transparentRoutingCodec) Marshal(v interface{}) ([]byte, error) {
sslobodr392ebd52019-01-18 12:41:49 -050061 switch t := v.(type) {
Kent Hagerman03b58992019-08-29 17:21:03 -040062 case *responseFrame:
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040063 return t.payload, nil
Kent Hagerman03b58992019-08-29 17:21:03 -040064 case *requestFrame:
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040065 return t.payload, nil
66 default:
67 return cdc.parentCodec.Marshal(v)
sslobodr392ebd52019-01-18 12:41:49 -050068 }
sslobodr392ebd52019-01-18 12:41:49 -050069}
70
sslobodrcd37bc52019-01-24 11:47:16 -050071func (cdc *transparentRoutingCodec) Unmarshal(data []byte, v interface{}) error {
sslobodr392ebd52019-01-18 12:41:49 -050072 switch t := v.(type) {
Kent Hagerman03b58992019-08-29 17:21:03 -040073 case *responseFrame:
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040074 t.payload = data
75 // This is where the affinity is established on a northbound response
76 t.router.ReplyHandler(v)
77 return nil
Kent Hagerman03b58992019-08-29 17:21:03 -040078 case *requestFrame:
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040079 t.payload = data
80 // This is were the afinity value is pulled from the payload
81 // and the backend selected.
Kent Hagerman1e9061e2019-05-21 16:01:21 -040082 t.backend = t.router.Route(v)
Kent Hagerman03b58992019-08-29 17:21:03 -040083 name := "<nil>"
84 if t.backend != nil {
85 name = t.backend.name
86 }
87 log.Debugf("Routing returned %s for method %s", name, t.methodInfo.method)
Kent Hagerman0ab4cb22019-04-24 13:13:35 -040088 return nil
89 default:
90 return cdc.parentCodec.Unmarshal(data, v)
sslobodr392ebd52019-01-18 12:41:49 -050091 }
92}
93
sslobodrcd37bc52019-01-24 11:47:16 -050094func (cdc *transparentRoutingCodec) String() string {
95 return fmt.Sprintf("%s", cdc.parentCodec.String())
sslobodr392ebd52019-01-18 12:41:49 -050096}
97
sslobodrcd37bc52019-01-24 11:47:16 -050098// protoCodec is a Codec implementation with protobuf. It is the default Codec for gRPC.
sslobodr392ebd52019-01-18 12:41:49 -050099type protoCodec struct{}
100
101func (protoCodec) Marshal(v interface{}) ([]byte, error) {
102 return proto.Marshal(v.(proto.Message))
103}
104
105func (protoCodec) Unmarshal(data []byte, v interface{}) error {
106 return proto.Unmarshal(data, v.(proto.Message))
107}
108
109func (protoCodec) String() string {
sslobodrcd37bc52019-01-24 11:47:16 -0500110 return "protoCodec"
sslobodr392ebd52019-01-18 12:41:49 -0500111}