| /* |
| * Copyright 2022-present Open Networking Foundation |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package controller |
| |
| import ( |
| "context" |
| "time" |
| |
| "voltha-go-controller/internal/pkg/of" |
| "voltha-go-controller/log" |
| ) |
| |
| // ModMeterTask structure |
| type ModMeterTask struct { |
| ctx context.Context |
| meter *of.Meter |
| device *Device |
| timestamp string |
| command of.MeterCommand |
| taskID uint8 |
| } |
| |
| // NewModMeterTask is the constructor for ModMeterTask |
| func NewModMeterTask(ctx context.Context, command of.MeterCommand, meter *of.Meter, device *Device) *ModMeterTask { |
| var mmt ModMeterTask |
| mmt.device = device |
| mmt.meter = meter |
| mmt.ctx = ctx |
| mmt.command = command |
| tstamp := (time.Now()).Format(time.RFC3339Nano) |
| mmt.timestamp = tstamp |
| return &mmt |
| } |
| |
| // Name returns name of the task |
| func (mmt *ModMeterTask) Name() string { |
| return "Add Flows Task" |
| } |
| |
| // TaskID returns task Id of the task |
| func (mmt *ModMeterTask) TaskID() uint8 { |
| return mmt.taskID |
| } |
| |
| // Timestamp returns time stamp for the task |
| func (mmt *ModMeterTask) Timestamp() string { |
| return mmt.timestamp |
| } |
| |
| // Stop to stop the task |
| func (mmt *ModMeterTask) Stop() { |
| } |
| |
| // Start to start the task |
| func (mmt *ModMeterTask) Start(ctx context.Context, taskID uint8) error { |
| mmt.taskID = taskID |
| mmt.ctx = ctx |
| |
| // Temp commenting Sync response handling |
| //triggerMeterNotification := func(err error) { |
| |
| // statusCode, statusMsg := infraerror.GetErrorInfo(err) |
| |
| // if mmt.command == of.MeterCommandAdd && infraerrorcode.ErrorCode(statusCode) != infraerrorcode.ErrOk { |
| // mmt.meter.State = of.MeterOperFailure |
| // mmt.meter.ErrorReason = statusMsg |
| |
| // logger.Errorw(ctx, "Update Meter Table Failed", |
| // log.Fields{"meterId": mmt.meter.ID, "meterOp": mmt.command, "Status": statusCode, "errorReason": statusMsg}) |
| // go mmt.device.AddMeterToDb(mmt.meter) |
| // } else { |
| // logger.Infow("Meter Mod Result", log.Fields{"meterID": mmt.meter.ID, "Error Code": statusCode}) |
| // } |
| // } |
| |
| // First add/delete the flows first locally before passing them to actual device |
| if mmt.command == of.MeterCommandAdd { |
| mmt.meter.State = of.MeterOperPending |
| if err := mmt.device.AddMeter(ctx, mmt.meter); err != nil { |
| // Meter already exists so we dont have to do anything here |
| return nil |
| } |
| logger.Infow(ctx, "Updated meter state to pending", log.Fields{"Meter": mmt.meter.ID}) |
| } else { |
| if !mmt.device.DelMeter(ctx, mmt.meter) { |
| // Meter doesn't exist so we dont have to do anything here |
| return nil |
| } |
| } |
| |
| if mmt.device.State != DeviceStateUP { |
| logger.Errorw(ctx, "Update Meter Table Failed: Device State DOWN", log.Fields{"Reason": "Device State DOWN", "Meter": mmt.meter.ID}) |
| return nil |
| } |
| meterMod, err := of.MeterUpdate(mmt.device.ID, mmt.command, mmt.meter) |
| if err != nil { |
| logger.Errorw(ctx, "Update Meter Table Failed", log.Fields{"Reason": err.Error()}) |
| return err |
| } |
| |
| if vc := mmt.device.VolthaClient(); vc != nil { |
| if _, err = vc.UpdateLogicalDeviceMeterTable(mmt.ctx, meterMod); err != nil { |
| logger.Errorw(ctx, "Update Meter Table Failed", log.Fields{"Reason": err.Error()}) |
| } else { |
| mmt.meter.State = of.MeterOperSuccess |
| if err = mmt.device.UpdateMeter(ctx, mmt.meter); err != nil { |
| // Meter does not exist, update failed |
| logger.Error(ctx, "Update meter to DB failed") |
| } |
| logger.Infow(ctx, "Updated meter state to success", log.Fields{"Meter": mmt.meter.ID}) |
| } |
| //triggerMeterNotification(err) |
| return err |
| } |
| |
| logger.Error(ctx, "Update Meter Table Failed: Voltha Client Unavailable") |
| return nil |
| } |