blob: 69ab0aa841797978efb3637dcceee55327f77d4f [file] [log] [blame]
David K. Bainbridge157bdab2020-01-16 14:38:05 -08001/*
2 Copyright 2020 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 ofagent
18
19import (
20 "context"
David Bainbridgef8ce7d22020-04-08 12:49:41 -070021 "time"
22
David K. Bainbridge157bdab2020-01-16 14:38:05 -080023 "github.com/golang/protobuf/ptypes/empty"
24 "github.com/opencord/ofagent-go/internal/pkg/openflow"
Andrea Campanella18448bc2021-07-08 18:47:22 +020025 "github.com/opencord/voltha-lib-go/v5/pkg/log"
David K. Bainbridge157bdab2020-01-16 14:38:05 -080026)
27
28func (ofa *OFAgent) synchronizeDeviceList(ctx context.Context) {
29 // Refresh once to get everything started
Rohan Agrawalc32d9932020-06-15 11:01:47 +000030 ofa.refreshDeviceList(ctx)
David K. Bainbridge157bdab2020-01-16 14:38:05 -080031
32 tick := time.NewTicker(ofa.DeviceListRefreshInterval)
33loop:
34 for {
35 select {
36 case <-ctx.Done():
37 break loop
38 case <-tick.C:
Rohan Agrawalc32d9932020-06-15 11:01:47 +000039 ofa.refreshDeviceList(ctx)
David K. Bainbridge157bdab2020-01-16 14:38:05 -080040 }
41 }
42 tick.Stop()
43}
44
Rohan Agrawalc32d9932020-06-15 11:01:47 +000045func (ofa *OFAgent) refreshDeviceList(ctx context.Context) {
Girish Kumar01e0c632020-08-10 16:48:56 +000046 span, ctx := log.CreateChildSpan(ctx, "refresh-device-list")
47 defer span.Finish()
48
David K. Bainbridge9cb404e2020-01-28 14:32:29 -080049 // If we exit, assume disconnected
50 if ofa.volthaClient == nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +000051 logger.Error(ctx, "no-voltha-connection")
David K. Bainbridge9cb404e2020-01-28 14:32:29 -080052 ofa.events <- ofaEventVolthaDisconnected
53 return
54 }
Girish Kumar01e0c632020-08-10 16:48:56 +000055 deviceList, err := ofa.volthaClient.Get().ListLogicalDevices(log.WithSpanFromContext(context.Background(), ctx), &empty.Empty{})
David K. Bainbridge157bdab2020-01-16 14:38:05 -080056 if err != nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +000057 logger.Errorw(ctx, "ofagent failed to query device list from voltha",
David K. Bainbridge157bdab2020-01-16 14:38:05 -080058 log.Fields{"error": err})
David K. Bainbridge9cb404e2020-01-28 14:32:29 -080059 ofa.events <- ofaEventVolthaDisconnected
David K. Bainbridge157bdab2020-01-16 14:38:05 -080060 return
61 }
62 devices := deviceList.GetItems()
63
64 var toAdd []string
65 var toDel []string
66 var deviceIDMap = make(map[string]string)
67 for i := 0; i < len(devices); i++ {
68 deviceID := devices[i].GetId()
69 deviceIDMap[deviceID] = deviceID
70 if ofa.clientMap[deviceID] == nil {
71 toAdd = append(toAdd, deviceID)
72 }
73 }
74 for key := range ofa.clientMap {
75 if deviceIDMap[key] == "" {
76 toDel = append(toDel, key)
77 }
78 }
Rohan Agrawalc32d9932020-06-15 11:01:47 +000079 logger.Debugw(ctx, "GrpcClient refreshDeviceList", log.Fields{"ToAdd": toAdd, "ToDel": toDel})
David K. Bainbridge157bdab2020-01-16 14:38:05 -080080 for i := 0; i < len(toAdd); i++ {
Rohan Agrawalc32d9932020-06-15 11:01:47 +000081 ofa.addOFClient(ctx, toAdd[i]) // client is started in addOFClient
David K. Bainbridge157bdab2020-01-16 14:38:05 -080082 }
83 for i := 0; i < len(toDel); i++ {
84 ofa.clientMap[toDel[i]].Stop()
85 ofa.mapLock.Lock()
86 delete(ofa.clientMap, toDel[i])
87 ofa.mapLock.Unlock()
88 }
89}
90
Rohan Agrawalc32d9932020-06-15 11:01:47 +000091func (ofa *OFAgent) addOFClient(ctx context.Context, deviceID string) *openflow.OFClient {
92 logger.Debugw(ctx, "GrpcClient addClient called ", log.Fields{"device-id": deviceID})
David K. Bainbridge157bdab2020-01-16 14:38:05 -080093 ofa.mapLock.Lock()
94 ofc := ofa.clientMap[deviceID]
95 if ofc == nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +000096 ofc = openflow.NewOFClient(ctx, &openflow.OFClient{
Jonathan Hart4b110f62020-03-13 17:36:19 -070097 DeviceID: deviceID,
98 OFControllerEndPoints: ofa.OFControllerEndPoints,
99 VolthaClient: ofa.volthaClient,
100 PacketOutChannel: ofa.packetOutChannel,
101 ConnectionMaxRetries: ofa.ConnectionMaxRetries,
102 ConnectionRetryDelay: ofa.ConnectionRetryDelay,
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800103 })
Jonathan Hart4b110f62020-03-13 17:36:19 -0700104 ofc.Run(context.Background())
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800105 ofa.clientMap[deviceID] = ofc
106 }
107 ofa.mapLock.Unlock()
divyadesai9a2c9b02020-08-18 06:40:51 +0000108 logger.Debugw(ctx, "Finished with addClient", log.Fields{"device-id": deviceID})
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800109 return ofc
110}
111
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000112func (ofa *OFAgent) getOFClient(ctx context.Context, deviceID string) *openflow.OFClient {
khenaidoo927391f2021-06-18 17:06:52 -0400113 ofa.mapLock.Lock()
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800114 ofc := ofa.clientMap[deviceID]
khenaidoo927391f2021-06-18 17:06:52 -0400115 ofa.mapLock.Unlock()
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800116 if ofc == nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000117 ofc = ofa.addOFClient(ctx, deviceID)
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800118 }
119 return ofc
120}
khenaidoo927391f2021-06-18 17:06:52 -0400121
122//clearAllOFClient clears all OF connections for all clients
123func (ofa *OFAgent) clearAllOFClient() {
124 logger.Debug(context.Background(), "stopping-all-of-connections...")
125 ofa.mapLock.Lock()
126 for deviceID := range ofa.clientMap {
127 ofa.clientMap[deviceID].Stop()
128 delete(ofa.clientMap, deviceID)
129 }
130 ofa.mapLock.Unlock()
131}