blob: 3ed1c044834c38f8459b7a9607919cccf49a7e3f [file] [log] [blame]
Naveen Sampath04696f72022-06-13 15:19:14 +05301/*
2* Copyright 2022-present Open Networking Foundation
3* Licensed under the Apache License, Version 2.0 (the "License");
4* you may not use this file except in compliance with the License.
5* You may obtain a copy of the License at
6*
7* http://www.apache.org/licenses/LICENSE-2.0
8*
9* Unless required by applicable law or agreed to in writing, software
10* distributed under the License is distributed on an "AS IS" BASIS,
11* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12* See the License for the specific language governing permissions and
13* limitations under the License.
14 */
15
16package controller
17
18import (
19 "context"
20 "errors"
21 "sync"
22 "time"
23
24 "encoding/hex"
25
26 "voltha-go-controller/database"
27 errorCodes "voltha-go-controller/internal/pkg/errorcodes"
28 "voltha-go-controller/internal/pkg/intf"
29 "voltha-go-controller/internal/pkg/of"
30 "voltha-go-controller/internal/pkg/tasks"
31 "voltha-go-controller/internal/pkg/util"
32 "voltha-go-controller/internal/pkg/vpagent"
33
Tinoj Joseph1d108322022-07-13 10:07:39 +053034 "voltha-go-controller/log"
Naveen Sampath04696f72022-06-13 15:19:14 +053035)
36
37var logger log.CLogger
38var ctx = context.TODO()
39
40func init() {
41 // Setup this package so that it's log level can be modified at run time
42 var err error
Tinoj Joseph1d108322022-07-13 10:07:39 +053043 logger, err = log.AddPackageWithDefaultParam()
Naveen Sampath04696f72022-06-13 15:19:14 +053044 if err != nil {
45 panic(err)
46 }
47}
48
49var db database.DBIntf
50
Naveen Sampath04696f72022-06-13 15:19:14 +053051// VoltController structure
52type VoltController struct {
53 rebootLock sync.Mutex
54 rebootInProgressDevices map[string]string
55 devices map[string]*Device
56 deviceLock sync.RWMutex
57 vagent map[string]*vpagent.VPAgent
58 ctx context.Context
59 app intf.App
60 RebootFlow bool
61 BlockedDeviceList *util.ConcurrentMap
62 deviceTaskQueue *util.ConcurrentMap
Tinoj Josephaf37ce82022-12-28 11:59:43 +053063 deviceTableSyncDuration time.Duration
Naveen Sampath04696f72022-06-13 15:19:14 +053064}
65
66var vcontroller *VoltController
67
68// NewController is the constructor for VoltController
69func NewController(ctx context.Context, app intf.App) intf.IVPClientAgent {
70 var controller VoltController
71
72 controller.rebootInProgressDevices = make(map[string]string)
73 controller.devices = make(map[string]*Device)
74 controller.deviceLock = sync.RWMutex{}
75 controller.ctx = ctx
76 controller.app = app
77 controller.BlockedDeviceList = util.NewConcurrentMap()
78 controller.deviceTaskQueue = util.NewConcurrentMap()
79 db = database.GetDatabase()
80 vcontroller = &controller
81 return &controller
82}
83
Tinoj Josephaf37ce82022-12-28 11:59:43 +053084//SetDeviceTableSyncDuration - sets interval between device table sync up activity
85// duration - in minutes
86func (v *VoltController) SetDeviceTableSyncDuration(duration int) {
87 v.deviceTableSyncDuration = time.Duration(duration) * time.Second
88}
89
90//GetDeviceTableSyncDuration - returns configured device table sync duration
91func (v *VoltController) GetDeviceTableSyncDuration() time.Duration {
92 return v.deviceTableSyncDuration
93}
94
Naveen Sampath04696f72022-06-13 15:19:14 +053095// AddDevice to add device
Tinoj Joseph07cc5372022-07-18 22:53:51 +053096func (v *VoltController) AddDevice(cntx context.Context, config *intf.VPClientCfg) intf.IVPClient {
Naveen Sampath04696f72022-06-13 15:19:14 +053097
Tinoj Joseph429b9d92022-11-16 18:51:05 +053098 d := NewDevice(cntx, config.DeviceID, config.SerialNum, config.VolthaClient, config.SouthBoundID, config.MfrDesc, config.HwDesc, config.SwDesc)
Naveen Sampath04696f72022-06-13 15:19:14 +053099 v.devices[config.DeviceID] = d
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530100 v.app.AddDevice(cntx, d.ID, d.SerialNum, config.SouthBoundID)
Naveen Sampath04696f72022-06-13 15:19:14 +0530101
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530102 d.RestoreMetersFromDb(cntx)
103 d.RestoreGroupsFromDb(cntx)
104 d.RestoreFlowsFromDb(cntx)
105 d.RestorePortsFromDb(cntx)
Naveen Sampath04696f72022-06-13 15:19:14 +0530106 d.ConnectInd(context.TODO(), intf.DeviceDisc)
107 d.packetOutChannel = config.PacketOutChannel
108
109 logger.Warnw(ctx, "Added device", log.Fields{"Device": config.DeviceID, "SerialNo": d.SerialNum, "State": d.State})
110
111 return d
112}
113
114// DelDevice to delete device
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530115func (v *VoltController) DelDevice(cntx context.Context, id string) {
Naveen Sampath04696f72022-06-13 15:19:14 +0530116 d, ok := v.devices[id]
117 if ok {
118 delete(v.devices, id)
119 d.Delete()
120 }
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530121 v.app.DelDevice(cntx, id)
Naveen Sampath04696f72022-06-13 15:19:14 +0530122 d.cancel() // To stop the device tables sync routine
123 logger.Warnw(ctx, "Deleted device", log.Fields{"Device": id})
124}
125
126//AddControllerTask - add task to controller queue
127func (v *VoltController) AddControllerTask(device string, task tasks.Task) {
128 var taskQueueIntf interface{}
129 var taskQueue *tasks.Tasks
130 var found bool
131 if taskQueueIntf, found = v.deviceTaskQueue.Get(device); !found {
132 taskQueue = tasks.NewTasks(context.TODO())
133 v.deviceTaskQueue.Set(device, taskQueue)
134 } else {
135 taskQueue = taskQueueIntf.(*tasks.Tasks)
136 }
137 taskQueue.AddTask(task)
138 logger.Warnw(ctx, "Task Added to Controller Task List", log.Fields{"Len": taskQueue.NumPendingTasks(), "Total": taskQueue.TotalTasks()})
139}
140
141//AddNewDevice - called when new device is discovered. This will be
142//processed as part of controller queue
143func (v *VoltController) AddNewDevice(config *intf.VPClientCfg) {
144 adt := NewAddDeviceTask(config)
145 v.AddControllerTask(config.DeviceID, adt)
146}
147
148// GetDevice to get device info
149func (v *VoltController) GetDevice(id string) (*Device, error) {
150 d, ok := v.devices[id]
151 if ok {
152 return d, nil
153 }
154 return nil, errorCodes.ErrDeviceNotFound
155}
156
157// IsRebootInProgressForDevice to check if reboot is in progress for the device
158func (v *VoltController) IsRebootInProgressForDevice(device string) bool {
159 v.rebootLock.Lock()
160 defer v.rebootLock.Unlock()
161 _, ok := v.rebootInProgressDevices[device]
162 return ok
163}
164
165// SetRebootInProgressForDevice to set reboot in progress for the device
166func (v *VoltController) SetRebootInProgressForDevice(device string) bool {
167 v.rebootLock.Lock()
168 defer v.rebootLock.Unlock()
169 _, ok := v.rebootInProgressDevices[device]
170 if ok {
171 return true
172 }
173 v.rebootInProgressDevices[device] = device
174 logger.Warnw(ctx, "Setted Reboot-In-Progress flag", log.Fields{"Device": device})
175
176 d, err := v.GetDevice(device)
177 if err == nil {
178 d.ResetCache()
179 } else {
180 logger.Errorw(ctx, "Failed to get device", log.Fields{"Device": device, "Error": err})
181 }
182
183 return true
184}
185
186// ReSetRebootInProgressForDevice to reset reboot in progress for the device
187func (v *VoltController) ReSetRebootInProgressForDevice(device string) bool {
188 v.rebootLock.Lock()
189 defer v.rebootLock.Unlock()
190 _, ok := v.rebootInProgressDevices[device]
191 if !ok {
192 return true
193 }
194 delete(v.rebootInProgressDevices, device)
195 logger.Warnw(ctx, "Resetted Reboot-In-Progress flag", log.Fields{"Device": device})
196 return true
197}
198
199// DeviceRebootInd is device reboot indication
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530200func (v *VoltController) DeviceRebootInd(cntx context.Context, dID string, srNo string, sbID string) {
201 v.app.DeviceRebootInd(cntx, dID, srNo, sbID)
202 _ = db.DelAllRoutesForDevice(cntx, dID)
203 _ = db.DelAllGroup(cntx, dID)
204 _ = db.DelAllMeter(cntx, dID)
205 _ = db.DelAllPONCounters(cntx, dID)
Naveen Sampath04696f72022-06-13 15:19:14 +0530206}
207
208// DeviceDisableInd is device deactivation indication
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530209func (v *VoltController) DeviceDisableInd(cntx context.Context, dID string) {
210 v.app.DeviceDisableInd(cntx, dID)
Naveen Sampath04696f72022-06-13 15:19:14 +0530211}
212
213//TriggerPendingProfileDeleteReq - trigger pending profile delete requests
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530214func (v *VoltController) TriggerPendingProfileDeleteReq(cntx context.Context, device string) {
215 v.app.TriggerPendingProfileDeleteReq(cntx, device)
Naveen Sampath04696f72022-06-13 15:19:14 +0530216}
217
218//TriggerPendingMigrateServicesReq - trigger pending services migration requests
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530219func (v *VoltController) TriggerPendingMigrateServicesReq(cntx context.Context, device string) {
220 v.app.TriggerPendingMigrateServicesReq(cntx, device)
Naveen Sampath04696f72022-06-13 15:19:14 +0530221}
222
223// SetAuditFlags to set the audit flags
224func (v *VoltController) SetAuditFlags(device *Device) {
225 v.app.SetRebootFlag(true)
226 device.auditInProgress = true
227}
228
229// ResetAuditFlags to reset the audit flags
230func (v *VoltController) ResetAuditFlags(device *Device) {
231 v.app.SetRebootFlag(false)
232 device.auditInProgress = false
233}
234
235//ProcessFlowModResultIndication - send flow mod result notification
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530236func (v *VoltController) ProcessFlowModResultIndication(cntx context.Context, flowStatus intf.FlowStatus) {
237 v.app.ProcessFlowModResultIndication(cntx, flowStatus)
Naveen Sampath04696f72022-06-13 15:19:14 +0530238}
239
240// AddVPAgent to add the vpagent
241func (v *VoltController) AddVPAgent(vep string, vpa *vpagent.VPAgent) {
242 v.vagent[vep] = vpa
243}
244
245// VPAgent to get vpagent info
246func (v *VoltController) VPAgent(vep string) (*vpagent.VPAgent, error) {
247 vpa, ok := v.vagent[vep]
248 if ok {
249 return vpa, nil
250 }
251 return nil, errors.New("VPA Not Registered")
252}
253
254// PacketOutReq for packet out request
255func (v *VoltController) PacketOutReq(device string, inport string, outport string, pkt []byte, isCustomPkt bool) error {
256 logger.Debugw(ctx, "Packet Out Req", log.Fields{"Device": device, "OutPort": outport})
257 d, err := v.GetDevice(device)
258 if err != nil {
259 return err
260 }
261 logger.Debugw(ctx, "Packet Out Pkt", log.Fields{"Pkt": hex.EncodeToString(pkt)})
262 return d.PacketOutReq(inport, outport, pkt, isCustomPkt)
263}
264
265// AddFlows to add flows
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530266func (v *VoltController) AddFlows(cntx context.Context, port string, device string, flow *of.VoltFlow) error {
Naveen Sampath04696f72022-06-13 15:19:14 +0530267 d, err := v.GetDevice(device)
268 if err != nil {
269 logger.Errorw(ctx, "Device Not Found", log.Fields{"Device": device})
270 return err
271 }
272 devPort := d.GetPortByName(port)
273 if devPort == nil {
274 logger.Errorw(ctx, "Port Not Found", log.Fields{"Device": device})
275 return errorCodes.ErrPortNotFound
276 }
277 if d.ctx == nil {
278 //FIXME: Application should know the context before it could submit task. Handle at application level
279 logger.Errorw(ctx, "Context is missing. AddFlow Operation Not added to Task", log.Fields{"Device": device})
280 return errorCodes.ErrInvalidParamInRequest
281 }
282
283 var isMigrationRequired bool
284 if flow.MigrateCookie {
285 // flow migration to new cookie must be done only during the audit. Migration for all subflows must be done if
286 // atlease one subflow with old cookie found in the device.
287 for _, subFlow := range flow.SubFlows {
288 if isMigrationRequired = d.IsFlowPresentWithOldCookie(subFlow); isMigrationRequired {
289 break
290 }
291 }
292 }
293
294 if isMigrationRequired {
295 // In this case, the flow is updated in local cache and db here.
296 // Actual flow deletion and addition at voltha will happen during flow tables audit.
297 for _, subFlow := range flow.SubFlows {
298 logger.Debugw(ctx, "Cookie Migration Required", log.Fields{"OldCookie": subFlow.OldCookie, "NewCookie": subFlow.Cookie})
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530299 if err := d.DelFlowWithOldCookie(cntx, subFlow); err != nil {
Naveen Sampath04696f72022-06-13 15:19:14 +0530300 logger.Errorw(ctx, "Delete flow with old cookie failed", log.Fields{"Error": err, "OldCookie": subFlow.OldCookie})
301 }
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530302 if err := d.AddFlow(cntx, subFlow); err != nil {
Naveen Sampath04696f72022-06-13 15:19:14 +0530303 logger.Errorw(ctx, "Flow Add Failed", log.Fields{"Error": err, "Cookie": subFlow.Cookie})
304 }
305 }
306 } else {
307 flow.Command = of.CommandAdd
308 d.UpdateFlows(flow, devPort)
309 for cookie := range flow.SubFlows {
310 logger.Debugw(ctx, "Flow Add added to queue", log.Fields{"Cookie": cookie, "Device": device, "Port": port})
311 }
312 }
313 return nil
314}
315
316// DelFlows to delete flows
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530317func (v *VoltController) DelFlows(cntx context.Context, port string, device string, flow *of.VoltFlow) error {
Naveen Sampath04696f72022-06-13 15:19:14 +0530318 d, err := v.GetDevice(device)
319 if err != nil {
320 logger.Errorw(ctx, "Device Not Found", log.Fields{"Device": device})
321 return err
322 }
323 devPort := d.GetPortByName(port)
324 if devPort == nil {
325 logger.Errorw(ctx, "Port Not Found", log.Fields{"Device": device})
326 return errorCodes.ErrPortNotFound
327 }
328 if d.ctx == nil {
329 //FIXME: Application should know the context before it could submit task. Handle at application level
330 logger.Errorw(ctx, "Context is missing. DelFlow Operation Not added to Task", log.Fields{"Device": device})
331 return errorCodes.ErrInvalidParamInRequest
332 }
333
334 var isMigrationRequired bool
335 if flow.MigrateCookie {
336 // flow migration to new cookie must be done only during the audit. Migration for all subflows must be done if
337 // atlease one subflow with old cookie found in the device.
338 for _, subFlow := range flow.SubFlows {
339 if isMigrationRequired = d.IsFlowPresentWithOldCookie(subFlow); isMigrationRequired {
340 break
341 }
342 }
343 }
344
345 if isMigrationRequired {
346 // In this case, the flow is deleted from local cache and db here.
347 // Actual flow deletion at voltha will happen during flow tables audit.
348 for _, subFlow := range flow.SubFlows {
349 logger.Debugw(ctx, "Old Cookie delete Required", log.Fields{"OldCookie": subFlow.OldCookie})
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530350 if err := d.DelFlowWithOldCookie(cntx, subFlow); err != nil {
Naveen Sampath04696f72022-06-13 15:19:14 +0530351 logger.Errorw(ctx, "DelFlowWithOldCookie failed", log.Fields{"OldCookie": subFlow.OldCookie, "Error": err})
352 }
353 }
354 } else {
355 flow.Command = of.CommandDel
356 d.UpdateFlows(flow, devPort)
357 for cookie := range flow.SubFlows {
358 logger.Debugw(ctx, "Flow Del added to queue", log.Fields{"Cookie": cookie, "Device": device, "Port": port})
359 }
360 }
361 return nil
362}
363
364// GroupUpdate for group update
365func (v *VoltController) GroupUpdate(port string, device string, group *of.Group) error {
366 d, err := v.GetDevice(device)
367 if err != nil {
368 logger.Errorw(ctx, "Device Not Found", log.Fields{"Device": device})
369 return err
370 }
371
372 devPort := d.GetPortByName(port)
373 if devPort == nil {
374 logger.Errorw(ctx, "Port Not Found", log.Fields{"Device": device})
375 return errorCodes.ErrPortNotFound
376 }
377
378 if d.ctx == nil {
379 //FIXME: Application should know the context before it could submit task. Handle at application level
380 logger.Errorw(ctx, "Context is missing. GroupMod Operation Not added to task", log.Fields{"Device": device})
381 return errorCodes.ErrInvalidParamInRequest
382 }
383
384 d.UpdateGroup(group, devPort)
385 return nil
386}
387
388// ModMeter to get mod meter info
389func (v *VoltController) ModMeter(port string, device string, command of.MeterCommand, meter *of.Meter) error {
390 d, err := v.GetDevice(device)
391 if err != nil {
392 logger.Errorw(ctx, "Device Not Found", log.Fields{"Device": device})
393 return err
394 }
395
396 devPort := d.GetPortByName(port)
397 if devPort == nil {
398 logger.Errorw(ctx, "Port Not Found", log.Fields{"Device": device})
399 return errorCodes.ErrPortNotFound
400 }
401
402 d.ModMeter(command, meter, devPort)
403 return nil
404}
405
406// PortAddInd for port add indication
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530407func (v *VoltController) PortAddInd(cntx context.Context, device string, id uint32, name string) {
408 v.app.PortAddInd(cntx, device, id, name)
Naveen Sampath04696f72022-06-13 15:19:14 +0530409}
410
411// PortDelInd for port delete indication
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530412func (v *VoltController) PortDelInd(cntx context.Context, device string, port string) {
413 v.app.PortDelInd(cntx, device, port)
Naveen Sampath04696f72022-06-13 15:19:14 +0530414}
415
416// PortUpdateInd for port update indication
417func (v *VoltController) PortUpdateInd(device string, name string, id uint32) {
418 v.app.PortUpdateInd(device, name, id)
419}
420
421// PortUpInd for port up indication
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530422func (v *VoltController) PortUpInd(cntx context.Context, device string, port string) {
423 v.app.PortUpInd(cntx, device, port)
Naveen Sampath04696f72022-06-13 15:19:14 +0530424}
425
426// PortDownInd for port down indication
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530427func (v *VoltController) PortDownInd(cntx context.Context, device string, port string) {
428 v.app.PortDownInd(cntx, device, port)
Naveen Sampath04696f72022-06-13 15:19:14 +0530429}
430
431// DeviceUpInd for device up indication
432func (v *VoltController) DeviceUpInd(device string) {
433 v.app.DeviceUpInd(device)
434}
435
436// DeviceDownInd for device down indication
437func (v *VoltController) DeviceDownInd(device string) {
438 v.app.DeviceDownInd(device)
439}
440
441// PacketInInd for packet in indication
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530442func (v *VoltController) PacketInInd(cntx context.Context, device string, port string, data []byte) {
443 v.app.PacketInInd(cntx, device, port, data)
Naveen Sampath04696f72022-06-13 15:19:14 +0530444}
445
446// GetPortState to get port status
447func (v *VoltController) GetPortState(device string, name string) (PortState, error) {
448 d, err := v.GetDevice(device)
449 if err != nil {
450 logger.Errorw(ctx, "Device Not Found", log.Fields{"Device": device})
451 return PortStateDown, err
452 }
453 return d.GetPortState(name)
454}
455
456// UpdateMvlanProfiles for update mvlan profiles
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530457func (v *VoltController) UpdateMvlanProfiles(cntx context.Context, device string) {
458 v.app.UpdateMvlanProfilesForDevice(cntx, device)
Naveen Sampath04696f72022-06-13 15:19:14 +0530459}
460
461// GetController to get controller
462func GetController() *VoltController {
463 return vcontroller
464}
465
466/*
467// PostIndication to post indication
468func (v *VoltController) PostIndication(device string, task interface{}) error {
469 var srvTask AddServiceIndTask
470 var portTask AddPortIndTask
471 var taskCommon tasks.Task
472 var isSvcTask bool
473
474 switch data := task.(type) {
475 case *AddServiceIndTask:
476 srvTask = *data
477 taskCommon = data
478 isSvcTask = true
479 case *AddPortIndTask:
480 portTask = *data
481 taskCommon = data
482 }
483
484 d, err := v.GetDevice(device)
485 if err != nil {
486 logger.Errorw(ctx, "Device Not Found", log.Fields{"Device": device})
487 //It means device itself it not present so just post the indication directly
488 if isSvcTask {
489 msgbus.PostAccessConfigInd(srvTask.result, d.SerialNum, srvTask.indicationType, srvTask.serviceName, 0, srvTask.reason, srvTask.trigger, srvTask.portState)
490 } else {
491 msgbus.ProcessPortInd(portTask.indicationType, d.SerialNum, portTask.portName, portTask.accessConfig, portTask.serviceList)
492 }
493 return err
494 }
495 if taskCommon != nil {
496 d.AddTask(taskCommon)
497 }
498 return nil
499}
500*/
501
502// GetTaskList to get the task list
503func (v *VoltController) GetTaskList(device string) []tasks.Task {
504 d, err := v.GetDevice(device)
505 if err != nil || d.ctx == nil {
506 logger.Errorw(ctx, "Device Not Connected/Found", log.Fields{"Device": device, "Dev Obj": d})
507 return []tasks.Task{}
508 }
509 return d.GetTaskList()
510
511}
512
513// AddBlockedDevices to add devices to blocked devices list
514func (v *VoltController) AddBlockedDevices(deviceSerialNumber string) {
515 v.BlockedDeviceList.Set(deviceSerialNumber, deviceSerialNumber)
516}
517
518// DelBlockedDevices to remove device from blocked device list
519func (v *VoltController) DelBlockedDevices(deviceSerialNumber string) {
520 v.BlockedDeviceList.Remove(deviceSerialNumber)
521}
522
523// IsBlockedDevice to check if device is blocked
524func (v *VoltController) IsBlockedDevice(deviceSerialNumber string) bool {
525 _, ifPresent := v.BlockedDeviceList.Get(deviceSerialNumber)
526 return ifPresent
527}
Tinoj Josephec742f62022-09-29 19:11:10 +0530528
529// GetFlows returns flow specific to device and flowID
530func (v *VoltController) GetFlow(deviceID string, cookie uint64) (*of.VoltSubFlow, error) {
531 d, err := v.GetDevice(deviceID)
532 if err != nil {
533 logger.Errorw(ctx, "Device Not Found", log.Fields{"Device": deviceID, "Error": err})
534 return nil, err
535 }
536 if flow, ok := d.GetFlow(cookie); ok {
537 return flow, nil
538 }
539 return nil, nil
540}
541
542// GetFlows returns list of flows for a particular device
543func (v *VoltController) GetFlows(deviceID string) ([]*of.VoltSubFlow, error) {
544 d, err := v.GetDevice(deviceID)
545 if err != nil {
546 logger.Errorw(ctx, "Device Not Found", log.Fields{"Device": deviceID, "Error": err})
547 return nil, err
548 }
549 return d.GetAllFlows(), nil
550}
551
552// GetAllFlows returns list of all flows
553func (v *VoltController) GetAllFlows() ([]*of.VoltSubFlow, error) {
554 var flows []*of.VoltSubFlow
555 for _, d := range v.devices {
556 flows = append(flows, d.GetAllFlows()...)
557 }
558 return flows, nil
559}
560
561// GetAllPendingFlows returns list of all flows
562func (v *VoltController) GetAllPendingFlows() ([]*of.VoltSubFlow, error) {
563 var flows []*of.VoltSubFlow
564 for _, d := range v.devices {
565 flows = append(flows, d.GetAllPendingFlows()...)
566 }
567 return flows, nil
568}
Akash Sonib3abf522022-12-19 13:20:02 +0530569func (v *VoltController) GetAllMeterInfo() (map[string][]*of.Meter, error) {
570 logger.Info(ctx, "Entering into GetAllMeterInfo method")
571 meters := map[string][]*of.Meter{}
572 for _, device := range v.devices {
573 logger.Infow(ctx, "Inside GetAllMeterInfo method", log.Fields{"deviceId": device.ID})
574 for _, meter := range device.meters {
575 meters[device.ID] = append(meters[device.ID], meter)
576 }
577 logger.Infow(ctx, "Inside GetAllMeterInfo method", log.Fields{"meters": meters})
578 }
579 return meters, nil
580}
581
582func (v *VoltController) GetMeterInfo(cntx context.Context, id uint32) (map[string]*of.Meter, error) {
583 logger.Info(ctx, "Entering into GetMeterInfo method")
584 meters := map[string]*of.Meter{}
585 for _, device := range v.devices {
586 logger.Infow(ctx, "Inside GetMeterInfo method", log.Fields{"deviceId": device.ID})
587 meter, err := device.GetMeter(id)
588 if err != nil {
589 logger.Errorw(ctx, "Failed to fetch the meter", log.Fields{"Reason": err.Error()})
590 return nil, err
591 }
592 meters[device.ID] = meter
593 logger.Infow(ctx, "Inside GetAllMeterInfo method", log.Fields{"Meter": meters})
594 }
595 return meters, nil
596}
597
598func (v *VoltController) GetGroupList() ([]*of.Group, error) {
599 logger.Info(ctx, "Entering into GetGroupList method")
600 groups := []*of.Group{}
601 for _, device := range v.devices {
602 device.groups.Range(func(key, value interface{}) bool {
603 groupID := key.(uint32)
604 logger.Infow(ctx, "Inside GetGroupList method", log.Fields{"groupID": groupID})
605 //Obtain all groups associated with the device
606 grps, ok := device.groups.Load(groupID)
607 if !ok {
608 return true
609 }
610 grp := grps.(*of.Group)
611 groups = append(groups, grp)
612 return true
613 })
614 }
615 logger.Debugw(ctx, "Groups", log.Fields{"groups": groups})
616 return groups, nil
617}
618
619func (v *VoltController) GetGroups(cntx context.Context, id uint32) (*of.Group, error) {
620
621 logger.Info(ctx, "Entering into GetGroupList method")
622 var groups *of.Group
623 for _, device := range v.devices {
624 logger.Infow(ctx, "Inside GetGroupList method", log.Fields{"groupID": id})
625 grps, ok := device.groups.Load(id)
626 if !ok {
627 return nil, errors.New("Group not found")
628 }
629 groups = grps.(*of.Group)
630 logger.Debugw(ctx, "Groups", log.Fields{"groups": groups})
631 }
632 return groups, nil
633}