blob: aca644062d8cdfc0e84c9f14e02d00bd30eaf257 [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.
vinokuma926cb3e2023-03-29 11:41:06 +053014 */
Naveen Sampath04696f72022-06-13 15:19:14 +053015
16package controller
17
18import (
19 "context"
20 "time"
21
22 infraerror "voltha-go-controller/internal/pkg/errorcodes"
23 infraerrorcode "voltha-go-controller/internal/pkg/errorcodes/service"
24
25 "voltha-go-controller/internal/pkg/of"
Tinoj Joseph1d108322022-07-13 10:07:39 +053026 "voltha-go-controller/log"
vinokuma926cb3e2023-03-29 11:41:06 +053027
Naveen Sampath04696f72022-06-13 15:19:14 +053028 "google.golang.org/grpc/codes"
29)
30
vinokuma926cb3e2023-03-29 11:41:06 +053031// ModGroupTask - Group Modification Task
Naveen Sampath04696f72022-06-13 15:19:14 +053032type ModGroupTask struct {
Naveen Sampath04696f72022-06-13 15:19:14 +053033 ctx context.Context
34 group *of.Group
35 device *Device
36 timestamp string
vinokuma926cb3e2023-03-29 11:41:06 +053037 taskID uint8
Naveen Sampath04696f72022-06-13 15:19:14 +053038}
39
vinokuma926cb3e2023-03-29 11:41:06 +053040// NewModGroupTask - Initializes new group task
Naveen Sampath04696f72022-06-13 15:19:14 +053041func NewModGroupTask(ctx context.Context, group *of.Group, device *Device) *ModGroupTask {
42 var grp ModGroupTask
43 grp.device = device
44 grp.group = group
45 grp.ctx = ctx
46 tstamp := (time.Now()).Format(time.RFC3339Nano)
47 grp.timestamp = tstamp
48 return &grp
49}
50
vinokuma926cb3e2023-03-29 11:41:06 +053051// Name - Name of task
Naveen Sampath04696f72022-06-13 15:19:14 +053052func (grp *ModGroupTask) Name() string {
53 return "Group Mod Task"
54}
55
vinokuma926cb3e2023-03-29 11:41:06 +053056// TaskID - Task id
Naveen Sampath04696f72022-06-13 15:19:14 +053057func (grp *ModGroupTask) TaskID() uint8 {
58 return grp.taskID
59}
60
61// Timestamp to return timestamp of the task
62func (grp *ModGroupTask) Timestamp() string {
63 return grp.timestamp
64}
65
vinokuma926cb3e2023-03-29 11:41:06 +053066// Stop - task stop
Naveen Sampath04696f72022-06-13 15:19:14 +053067func (grp *ModGroupTask) Stop() {
68}
69
vinokuma926cb3e2023-03-29 11:41:06 +053070// Start - task start
Naveen Sampath04696f72022-06-13 15:19:14 +053071func (grp *ModGroupTask) Start(ctx context.Context, taskID uint8) error {
72 var err error
73 grp.taskID = taskID
74 grp.ctx = ctx
75 i := 0
76
77 processGroupModResult := func(err error) bool {
Naveen Sampath04696f72022-06-13 15:19:14 +053078 statusCode, statusMsg := infraerror.GetErrorInfo(err)
79
80 if infraerrorcode.ErrorCode(statusCode) != infraerrorcode.ErrOk {
Naveen Sampath04696f72022-06-13 15:19:14 +053081 if grp.group.Command == of.GroupCommandAdd && (codes.Code(statusCode) == codes.AlreadyExists) {
82 logger.Warnw(ctx, "Update Group Table Failed - Ignoring since Group Already exists",
83 log.Fields{"groupId": grp.group.GroupID, "groupOp": grp.group.Command, "Status": statusCode, "errorReason": statusMsg})
84 return true
85 }
86 logger.Errorw(ctx, "Update Group Table Failed",
87 log.Fields{"groupId": grp.group.GroupID, "groupOp": grp.group.Command, "Status": statusCode, "errorReason": statusMsg})
88 return false
89 }
Akash Soni6168f312023-05-18 20:57:33 +053090 logger.Debugw(ctx, "Group Mod Result", log.Fields{"groupID": grp.group.GroupID, "Error Code": statusCode})
Naveen Sampath04696f72022-06-13 15:19:14 +053091 return true
Naveen Sampath04696f72022-06-13 15:19:14 +053092 }
93
94 if grp.group.Command != of.GroupCommandDel {
95 grp.group.State = of.GroupOperPending
Tinoj Joseph07cc5372022-07-18 22:53:51 +053096 grp.device.UpdateGroupEntry(ctx, grp.group)
Naveen Sampath04696f72022-06-13 15:19:14 +053097 } else {
Tinoj Joseph07cc5372022-07-18 22:53:51 +053098 grp.device.DelGroupEntry(ctx, grp.group)
Naveen Sampath04696f72022-06-13 15:19:14 +053099 }
100
101 if !grp.device.isSBOperAllowed(grp.group.ForceAction) {
Akash Soni6168f312023-05-18 20:57:33 +0530102 logger.Warnw(ctx, "Skipping Group Table Update", log.Fields{"Reason": "Device State not UP", "State": grp.device.State, "GroupID": grp.group.GroupID, "Operation": grp.group.Command})
Naveen Sampath04696f72022-06-13 15:19:14 +0530103 return nil
104 }
105
106 groupUpdate := of.CreateGroupTableUpdate(grp.group)
107 if vc := grp.device.VolthaClient(); vc != nil {
vinokuma926cb3e2023-03-29 11:41:06 +0530108 // Retry on group mod failure
109 // Retry attempts = 3
110 // Delay between retry = 100ms. Total Possible Delay = 200ms
Naveen Sampath04696f72022-06-13 15:19:14 +0530111 for {
112 logger.Infow(ctx, "Group Mod Triggered", log.Fields{"GroupId": grp.group.GroupID, "Attempt": i})
113 _, err = vc.UpdateLogicalDeviceFlowGroupTable(grp.ctx, groupUpdate)
114 if isSuccess := processGroupModResult(err); isSuccess {
115 break
116 }
117 i++
118 if i < 3 {
119 time.Sleep(100 * time.Millisecond)
120 continue
121 }
122 logger.Errorw(ctx, "Update Group Table Failed on all 3 attempts. Dropping request", log.Fields{"GroupId": grp.group.GroupID, "Bucket": grp.group.Buckets})
123 break
Naveen Sampath04696f72022-06-13 15:19:14 +0530124 }
125 return err
126 }
127 logger.Error(ctx, "Update Group Flow Table Failed: Voltha Client Unavailable")
128 return nil
129}