blob: 40c805b088241085a16bf1255dc2a26d8e660b99 [file] [log] [blame]
Don Newton98fd8812019-09-23 15:15:02 -04001/*
2 Copyright 2017 the original author or authors.
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
17package grpc
18
19import (
20 "context"
Don Newtonb437c6f2019-12-18 11:51:57 -050021 "sync"
Don Newton98fd8812019-09-23 15:15:02 -040022 "time"
23
24 "github.com/golang/protobuf/ptypes/empty"
25
26 "github.com/opencord/ofagent-go/openflow"
27
28 "fmt"
Don Newton7577f072020-01-06 12:41:11 -050029
30 "github.com/opencord/ofagent-go/settings"
31 l "github.com/opencord/voltha-lib-go/v2/pkg/log"
Don Newton98fd8812019-09-23 15:15:02 -040032
Don Newtonb437c6f2019-12-18 11:51:57 -050033 pb "github.com/opencord/voltha-protos/v2/go/voltha"
Don Newton98fd8812019-09-23 15:15:02 -040034 "google.golang.org/grpc"
35)
36
Don Newton7577f072020-01-06 12:41:11 -050037var grpcDeviceID = "GRPC_CLIENT"
Don Newton98fd8812019-09-23 15:15:02 -040038var client pb.VolthaServiceClient
39var clientMap map[string]*openflow.Client
40var ofAddress string
41var ofPort uint16
Don Newtonb437c6f2019-12-18 11:51:57 -050042var mapLock sync.Mutex
Don Newton7577f072020-01-06 12:41:11 -050043var logger, _ = l.AddPackage(l.JSON, l.DebugLevel, nil)
Don Newton98fd8812019-09-23 15:15:02 -040044
Don Newton7577f072020-01-06 12:41:11 -050045//StartClient - make the inital connection to voltha and kicks off io streams
Don Newton98fd8812019-09-23 15:15:02 -040046func StartClient(endpointAddress string, endpointPort uint16, openFlowAddress string, openFlowPort uint16) {
Don Newton7577f072020-01-06 12:41:11 -050047
48 if settings.GetDebug(grpcDeviceID) {
49 logger.Debugw("Starting GRPC - VOLTHA client", l.Fields{"EndPointAddr": endpointAddress,
50 "EndPointPort": endpointPort, "OpenFlowAddress": openFlowAddress, "OpenFlowPort": openFlowPort})
51 }
Don Newton98fd8812019-09-23 15:15:02 -040052 ofAddress = openFlowAddress
53 ofPort = openFlowPort
54 clientMap = make(map[string]*openflow.Client)
55 var opts []grpc.DialOption
56 opts = append(opts, grpc.WithInsecure())
57 endpoint := fmt.Sprintf("%s:%d", endpointAddress, endpointPort)
58 conn, err := grpc.Dial(endpoint, opts...)
59 defer conn.Close()
60 if err != nil {
Don Newton7577f072020-01-06 12:41:11 -050061 l.Fatalw("StartClient failed opening GRPC connecton", l.Fields{"EndPoint": endpoint, "Error": err})
Don Newton98fd8812019-09-23 15:15:02 -040062 }
63 client = pb.NewVolthaServiceClient(conn)
64
65 go receivePacketIn(client)
66 go receiveChangeEvent(client)
67 go streamPacketOut(client)
68
69 openflow.SetGrpcClient(&client)
70 for {
Don Newton7577f072020-01-06 12:41:11 -050071 if settings.GetDebug(grpcDeviceID) {
72 logger.Debugln("GrpcClient entering device refresh pull")
73 }
Don Newton98fd8812019-09-23 15:15:02 -040074 deviceList, err := client.ListLogicalDevices(context.Background(), &empty.Empty{})
75 if err != nil {
Don Newton7577f072020-01-06 12:41:11 -050076 logger.Errorw("GrpcClient getDeviceList failed", l.Fields{"Error": err})
Don Newton98fd8812019-09-23 15:15:02 -040077 }
78 devices := deviceList.GetItems()
79 refreshDeviceList(devices)
80 time.Sleep(time.Minute)
Don Newton98fd8812019-09-23 15:15:02 -040081 }
82}
83func refreshDeviceList(devices []*pb.LogicalDevice) {
84 //first find the new ones
Don Newtonb437c6f2019-12-18 11:51:57 -050085
Don Newton98fd8812019-09-23 15:15:02 -040086 var toAdd []string
87 var toDel []string
Don Newton7577f072020-01-06 12:41:11 -050088 var deviceIDMap = make(map[string]string)
Don Newton98fd8812019-09-23 15:15:02 -040089 for i := 0; i < len(devices); i++ {
Don Newton7577f072020-01-06 12:41:11 -050090 deviceID := devices[i].GetId()
91 deviceIDMap[deviceID] = deviceID
92 if clientMap[deviceID] == nil {
93 toAdd = append(toAdd, deviceID)
Don Newton98fd8812019-09-23 15:15:02 -040094 }
95 }
Don Newton7577f072020-01-06 12:41:11 -050096 for key := range clientMap {
97 if deviceIDMap[key] == "" {
Don Newton98fd8812019-09-23 15:15:02 -040098 toDel = append(toDel, key)
99 }
100 }
Don Newton7577f072020-01-06 12:41:11 -0500101 if settings.GetDebug(grpcDeviceID) {
102 logger.Debugw("GrpcClient refreshDeviceList", l.Fields{"ToAdd": toAdd, "ToDel": toDel})
103 }
Don Newton98fd8812019-09-23 15:15:02 -0400104 for i := 0; i < len(toAdd); i++ {
105 var client = addClient(toAdd[i])
106 go client.Start()
107 }
108 for i := 0; i < len(toDel); i++ {
109 clientMap[toDel[i]].End()
Don Newtonb437c6f2019-12-18 11:51:57 -0500110 mapLock.Lock()
Don Newton98fd8812019-09-23 15:15:02 -0400111 delete(clientMap, toDel[i])
Don Newtonb437c6f2019-12-18 11:51:57 -0500112 mapLock.Unlock()
Don Newton98fd8812019-09-23 15:15:02 -0400113 }
114}
Don Newton7577f072020-01-06 12:41:11 -0500115func addClient(deviceID string) *openflow.Client {
116 if settings.GetDebug(grpcDeviceID) {
117 logger.Debugw("GrpcClient addClient called ", l.Fields{"DeviceID": deviceID})
118 }
Don Newtonb437c6f2019-12-18 11:51:57 -0500119 mapLock.Lock()
120 var client *openflow.Client
Don Newton7577f072020-01-06 12:41:11 -0500121 client = clientMap[deviceID]
Don Newtonb437c6f2019-12-18 11:51:57 -0500122 if client == nil {
Don Newton7577f072020-01-06 12:41:11 -0500123 client = openflow.NewClient(ofAddress, ofPort, deviceID, true)
124 go client.Start()
125 clientMap[deviceID] = client
Don Newtonb437c6f2019-12-18 11:51:57 -0500126 }
127 mapLock.Unlock()
Don Newton7577f072020-01-06 12:41:11 -0500128 logger.Debugw("Finished with addClient", l.Fields{"deviceID": deviceID})
Don Newton98fd8812019-09-23 15:15:02 -0400129 return client
130}
Don Newton7577f072020-01-06 12:41:11 -0500131
132//GetClient Returns a pointer to the OpenFlow client
133func GetClient(deviceID string) *openflow.Client {
134 client := clientMap[deviceID]
135 if client == nil {
136 client = addClient(deviceID)
137 }
138 return client
Don Newtone0d34a82019-11-14 10:58:06 -0500139}