blob: d88d68bea5ccf32ac6231c6ac26a58426d9574ba [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"
David K. Bainbridgee05cf0c2021-08-19 03:16:50 +000025 "github.com/opencord/voltha-lib-go/v7/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 }
David K. Bainbridgee05cf0c2021-08-19 03:16:50 +000055 vc := ofa.volthaClient.Get()
56 if vc == nil {
57 logger.Error(ctx, "No client found to query device list from voltha")
58 ofa.events <- ofaEventVolthaDisconnected
59 return
60 }
61 deviceList, err := vc.ListLogicalDevices(log.WithSpanFromContext(context.Background(), ctx), &empty.Empty{})
David K. Bainbridge157bdab2020-01-16 14:38:05 -080062 if err != nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +000063 logger.Errorw(ctx, "ofagent failed to query device list from voltha",
David K. Bainbridge157bdab2020-01-16 14:38:05 -080064 log.Fields{"error": err})
David K. Bainbridge9cb404e2020-01-28 14:32:29 -080065 ofa.events <- ofaEventVolthaDisconnected
David K. Bainbridge157bdab2020-01-16 14:38:05 -080066 return
67 }
68 devices := deviceList.GetItems()
69
70 var toAdd []string
71 var toDel []string
72 var deviceIDMap = make(map[string]string)
73 for i := 0; i < len(devices); i++ {
74 deviceID := devices[i].GetId()
75 deviceIDMap[deviceID] = deviceID
76 if ofa.clientMap[deviceID] == nil {
77 toAdd = append(toAdd, deviceID)
78 }
79 }
80 for key := range ofa.clientMap {
81 if deviceIDMap[key] == "" {
82 toDel = append(toDel, key)
83 }
84 }
Rohan Agrawalc32d9932020-06-15 11:01:47 +000085 logger.Debugw(ctx, "GrpcClient refreshDeviceList", log.Fields{"ToAdd": toAdd, "ToDel": toDel})
David K. Bainbridge157bdab2020-01-16 14:38:05 -080086 for i := 0; i < len(toAdd); i++ {
Rohan Agrawalc32d9932020-06-15 11:01:47 +000087 ofa.addOFClient(ctx, toAdd[i]) // client is started in addOFClient
David K. Bainbridge157bdab2020-01-16 14:38:05 -080088 }
89 for i := 0; i < len(toDel); i++ {
90 ofa.clientMap[toDel[i]].Stop()
91 ofa.mapLock.Lock()
92 delete(ofa.clientMap, toDel[i])
93 ofa.mapLock.Unlock()
94 }
95}
96
Rohan Agrawalc32d9932020-06-15 11:01:47 +000097func (ofa *OFAgent) addOFClient(ctx context.Context, deviceID string) *openflow.OFClient {
98 logger.Debugw(ctx, "GrpcClient addClient called ", log.Fields{"device-id": deviceID})
David K. Bainbridge157bdab2020-01-16 14:38:05 -080099 ofa.mapLock.Lock()
100 ofc := ofa.clientMap[deviceID]
101 if ofc == nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000102 ofc = openflow.NewOFClient(ctx, &openflow.OFClient{
Jonathan Hart4b110f62020-03-13 17:36:19 -0700103 DeviceID: deviceID,
104 OFControllerEndPoints: ofa.OFControllerEndPoints,
105 VolthaClient: ofa.volthaClient,
106 PacketOutChannel: ofa.packetOutChannel,
107 ConnectionMaxRetries: ofa.ConnectionMaxRetries,
108 ConnectionRetryDelay: ofa.ConnectionRetryDelay,
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800109 })
Jonathan Hart4b110f62020-03-13 17:36:19 -0700110 ofc.Run(context.Background())
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800111 ofa.clientMap[deviceID] = ofc
112 }
113 ofa.mapLock.Unlock()
divyadesai9a2c9b02020-08-18 06:40:51 +0000114 logger.Debugw(ctx, "Finished with addClient", log.Fields{"device-id": deviceID})
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800115 return ofc
116}
117
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000118func (ofa *OFAgent) getOFClient(ctx context.Context, deviceID string) *openflow.OFClient {
khenaidoo927391f2021-06-18 17:06:52 -0400119 ofa.mapLock.Lock()
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800120 ofc := ofa.clientMap[deviceID]
khenaidoo927391f2021-06-18 17:06:52 -0400121 ofa.mapLock.Unlock()
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800122 if ofc == nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000123 ofc = ofa.addOFClient(ctx, deviceID)
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800124 }
125 return ofc
126}
khenaidoo927391f2021-06-18 17:06:52 -0400127
128//clearAllOFClient clears all OF connections for all clients
129func (ofa *OFAgent) clearAllOFClient() {
130 logger.Debug(context.Background(), "stopping-all-of-connections...")
131 ofa.mapLock.Lock()
132 for deviceID := range ofa.clientMap {
133 ofa.clientMap[deviceID].Stop()
134 delete(ofa.clientMap, deviceID)
135 }
136 ofa.mapLock.Unlock()
137}