blob: 49da920c3fc2bfc77832c168b3fd095c2993c320 [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 "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"
26 "github.com/opencord/voltha-lib-go/v7/pkg/log"
27 "google.golang.org/grpc/codes"
28)
29
30//ModGroupTask - Group Modification Task
31type ModGroupTask struct {
32 taskID uint8
33 ctx context.Context
34 group *of.Group
35 device *Device
36 timestamp string
37}
38
39//NewModGroupTask - Initializes new group task
40func NewModGroupTask(ctx context.Context, group *of.Group, device *Device) *ModGroupTask {
41 var grp ModGroupTask
42 grp.device = device
43 grp.group = group
44 grp.ctx = ctx
45 tstamp := (time.Now()).Format(time.RFC3339Nano)
46 grp.timestamp = tstamp
47 return &grp
48}
49
50//Name - Name of task
51func (grp *ModGroupTask) Name() string {
52 return "Group Mod Task"
53}
54
55//TaskID - Task id
56func (grp *ModGroupTask) TaskID() uint8 {
57 return grp.taskID
58}
59
60// Timestamp to return timestamp of the task
61func (grp *ModGroupTask) Timestamp() string {
62 return grp.timestamp
63}
64
65//Stop - task stop
66func (grp *ModGroupTask) Stop() {
67}
68
69//Start - task start
70func (grp *ModGroupTask) Start(ctx context.Context, taskID uint8) error {
71 var err error
72 grp.taskID = taskID
73 grp.ctx = ctx
74 i := 0
75
76 processGroupModResult := func(err error) bool {
77
78 statusCode, statusMsg := infraerror.GetErrorInfo(err)
79
80 if infraerrorcode.ErrorCode(statusCode) != infraerrorcode.ErrOk {
81
82 if grp.group.Command == of.GroupCommandAdd && (codes.Code(statusCode) == codes.AlreadyExists) {
83 logger.Warnw(ctx, "Update Group Table Failed - Ignoring since Group Already exists",
84 log.Fields{"groupId": grp.group.GroupID, "groupOp": grp.group.Command, "Status": statusCode, "errorReason": statusMsg})
85 return true
86 }
87 logger.Errorw(ctx, "Update Group Table Failed",
88 log.Fields{"groupId": grp.group.GroupID, "groupOp": grp.group.Command, "Status": statusCode, "errorReason": statusMsg})
89 return false
90 }
91 logger.Infow(ctx, "Group Mod Result", log.Fields{"groupID": grp.group.GroupID, "Error Code": statusCode})
92 return true
93
94 }
95
96 if grp.group.Command != of.GroupCommandDel {
97 grp.group.State = of.GroupOperPending
98 grp.device.UpdateGroupEntry(grp.group)
99 } else {
100 grp.device.DelGroupEntry(grp.group)
101 }
102
103 if !grp.device.isSBOperAllowed(grp.group.ForceAction) {
104 logger.Errorw(ctx, "Skipping Group Table Update", log.Fields{"Reason": "Device State not UP", "State": grp.device.State, "GroupID": grp.group.GroupID, "Operation": grp.group.Command})
105 return nil
106 }
107
108 groupUpdate := of.CreateGroupTableUpdate(grp.group)
109 if vc := grp.device.VolthaClient(); vc != nil {
110
111 //Retry on group mod failure
112 //Retry attempts = 3
113 //Delay between retry = 100ms. Total Possible Delay = 200ms
114 for {
115 logger.Infow(ctx, "Group Mod Triggered", log.Fields{"GroupId": grp.group.GroupID, "Attempt": i})
116 _, err = vc.UpdateLogicalDeviceFlowGroupTable(grp.ctx, groupUpdate)
117 if isSuccess := processGroupModResult(err); isSuccess {
118 break
119 }
120 i++
121 if i < 3 {
122 time.Sleep(100 * time.Millisecond)
123 continue
124 }
125 logger.Errorw(ctx, "Update Group Table Failed on all 3 attempts. Dropping request", log.Fields{"GroupId": grp.group.GroupID, "Bucket": grp.group.Buckets})
126 break
127
128 }
129 return err
130 }
131 logger.Error(ctx, "Update Group Flow Table Failed: Voltha Client Unavailable")
132 return nil
133}