blob: 805cffe27be9ae6b73546872bc557fb9a54fdf22 [file] [log] [blame]
Abhilash S.L7f17e402019-03-15 17:40:41 +05301/*
2 * Copyright 2019-present Open Networking Foundation
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
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070017//Package resourcemanager provides the utility for managing resources
manikkaraj kbf256be2019-03-25 00:13:48 +053018package resourcemanager
Abhilash S.L7f17e402019-03-15 17:40:41 +053019
20import (
npujarec5762e2020-01-01 14:08:48 +053021 "context"
Girish Gowdru0c588b22019-04-23 23:24:56 -040022 "encoding/json"
23 "errors"
24 "fmt"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070025 "strings"
Girish Gowdra38d533d2020-03-30 20:38:51 -070026 "sync"
Neha Sharmacc656962020-04-14 14:26:11 +000027 "time"
Abhilash S.L7f17e402019-03-15 17:40:41 +053028
khenaidoo106c61a2021-08-11 18:05:46 -040029 tp "github.com/opencord/voltha-lib-go/v7/pkg/techprofile"
30
31 "github.com/opencord/voltha-lib-go/v7/pkg/db"
32 "github.com/opencord/voltha-lib-go/v7/pkg/db/kvstore"
33 "github.com/opencord/voltha-lib-go/v7/pkg/log"
34 ponrmgr "github.com/opencord/voltha-lib-go/v7/pkg/ponresourcemanager"
35 ofp "github.com/opencord/voltha-protos/v5/go/openflow_13"
36 "github.com/opencord/voltha-protos/v5/go/openolt"
Abhilash S.L7f17e402019-03-15 17:40:41 +053037)
38
salmansiddiqui7ac62132019-08-22 03:58:50 +000039const (
40 // KvstoreTimeout specifies the time out for KV Store Connection
Neha Sharmacc656962020-04-14 14:26:11 +000041 KvstoreTimeout = 5 * time.Second
Matteo Scandolodfa7a972020-11-06 13:03:40 -080042 // BasePathKvStore - <pathPrefix>/openolt/<device_id>
43 BasePathKvStore = "%s/openolt/{%s}"
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -070044 // tpIDPathSuffix - <(pon_id, onu_id, uni_id)>/tp_id
45 tpIDPathSuffix = "{%d,%d,%d}/tp_id"
Gamze Abakafee36392019-10-03 11:17:24 +000046 //MeterIDPathSuffix - <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
47 MeterIDPathSuffix = "{%d,%d,%d}/{%d}/meter_id/{%s}"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070048 // OnuPacketINPathPrefix - path prefix where ONU packet-in vlanID/PCP is stored
49 //format: onu_packetin/{<intfid>,<onuid>,<logicalport>}
50 OnuPacketINPathPrefix = "onu_packetin/{%d,%d,%d}"
51 // OnuPacketINPath path on the kvstore to store packetin gemport,which will be used for packetin, packetout
52 //format: onu_packetin/{<intfid>,<onuid>,<logicalport>}/{<vlanId>,<priority>}
53 OnuPacketINPath = OnuPacketINPathPrefix + "/{%d,%d}"
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -070054 //FlowIDsForGem flowids_per_gem/<intfid>/<gemport-id>
55 FlowIDsForGem = "flowids_per_gem/{%d}/{%d}"
Esin Karamanccb714b2019-11-29 15:02:06 +000056 //McastQueuesForIntf multicast queues for pon interfaces
57 McastQueuesForIntf = "mcast_qs_for_int"
58 //FlowGroup flow_groups/<flow_group_id>
59 // A group is stored under this path on the KV store after it has been installed to the device.
60 // It should also be deleted after it has been removed from the device accordingly.
61 FlowGroup = "flow_groups/{%d}"
62 //FlowGroupCached flow_groups_cached/<flow_group_id>
63 // When a group add request received, we create the group without setting any members to it since we cannot
64 // set any members to a group until it is associated with a multicast flow. It is a BAL limitation.
65 // When the related multicast flow has been created we perform set members operation for the group.
66 // That is why we need to keep the members of a group until the multicast flow creation request comes.
67 // We preserve the groups under "FlowGroupsCached" directory in the KV store temporarily. Having set members,
68 // we remove the group from the cached group store.
69 FlowGroupCached = "flow_groups_cached/{%d}"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070070
71 //FlowIDPath - Path on the KV store for storing list of Flow IDs for a given subscriber
72 //Format: BasePathKvStore/<(pon_intf_id, onu_id, uni_id)>/flow_ids
73 FlowIDPath = "{%s}/flow_ids"
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -070074
75 //OnuGemInfoPath is path on the kvstore to store onugem info map
76 //format: <device-id>/onu_gem_info/<intfid>
77 OnuGemInfoPath = "onu_gem_info/{%d}/{%d}" // onu_gem/<intfid>/<onuID>
salmansiddiqui7ac62132019-08-22 03:58:50 +000078)
Abhilash S.L7f17e402019-03-15 17:40:41 +053079
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070080// FlowInfo holds the flow information
Abhilash S.L8ee90712019-04-29 16:24:22 +053081type FlowInfo struct {
Girish Gowdraa09aeab2020-09-14 16:30:52 -070082 Flow *openolt.Flow
83 IsSymmtricFlow bool
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +053084}
85
86// OnuGemInfo holds onu information along with gem port list and uni port list
87type OnuGemInfo struct {
88 OnuID uint32
89 SerialNumber string
90 IntfID uint32
91 GemPorts []uint32
92 UniPorts []uint32
93}
94
95// PacketInInfoKey is the key for packet in gemport
96type PacketInInfoKey struct {
97 IntfID uint32
98 OnuID uint32
99 LogicalPort uint32
Esin Karaman7fb80c22020-07-16 14:23:33 +0000100 VlanID uint16
101 Priority uint8
Abhilash S.L8ee90712019-04-29 16:24:22 +0530102}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700103
Esin Karamanccb714b2019-11-29 15:02:06 +0000104// GroupInfo holds group information
105type GroupInfo struct {
106 GroupID uint32
107 OutPorts []uint32
108}
109
Girish Gowdraa482f272021-03-24 23:04:19 -0700110// MeterInfo store meter information at path <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
111type MeterInfo struct {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700112 RefCnt uint8 // number of flow references for this meter. When RefCnt is 0, the MeterInfo should be deleted.
113 MeterID uint32
Girish Gowdraa482f272021-03-24 23:04:19 -0700114}
115
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700116// OpenOltResourceMgr holds resource related information as provided below for each field
Abhilash S.L7f17e402019-03-15 17:40:41 +0530117type OpenOltResourceMgr struct {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700118 PonIntfID uint32
Neha Sharma3f221ae2020-04-29 19:02:12 +0000119 DeviceID string // OLT device id
120 Address string // Host and port of the kv store to connect to
121 Args string // args
122 KVStore *db.Backend // backend kv store connection handle
123 DeviceType string
124 DevInfo *openolt.DeviceInfo // device information
Girish Gowdru0c588b22019-04-23 23:24:56 -0400125 // array of pon resource managers per interface technology
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700126 PonRsrMgr *ponrmgr.PONResourceManager
Girish Gowdra38d533d2020-03-30 20:38:51 -0700127
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700128 // Local maps used for write-through-cache - start
129 flowIDsForOnu map[string][]uint64
130 flowIDsForOnuLock sync.RWMutex
131
132 allocIDsForOnu map[string][]uint32
133 allocIDsForOnuLock sync.RWMutex
134
135 gemPortIDsForOnu map[string][]uint32
136 gemPortIDsForOnuLock sync.RWMutex
137
138 techProfileIDsForOnu map[string][]uint32
139 techProfileIDsForOnuLock sync.RWMutex
140
141 meterInfoForOnu map[string]*MeterInfo
142 meterInfoForOnuLock sync.RWMutex
143
144 onuGemInfo map[string]*OnuGemInfo
145 onuGemInfoLock sync.RWMutex
146
147 gemPortForPacketInInfo map[string]uint32
148 gemPortForPacketInInfoLock sync.RWMutex
149
150 flowIDsForGem map[uint32][]uint64
151 flowIDsForGemLock sync.RWMutex
152
153 mcastQueueForIntf map[uint32][]uint32
154 mcastQueueForIntfLock sync.RWMutex
155 mcastQueueForIntfLoadedFromKvStore bool
156
157 groupInfo map[string]*GroupInfo
158 groupInfoLock sync.RWMutex
159 // Local maps used for write-through-cache - end
Girish Gowdra4c3d4602021-07-22 16:33:37 -0700160
Girish Gowdra76a1b092021-07-28 10:07:04 -0700161 TechprofileRef tp.TechProfileIf
Abhilash S.L7f17e402019-03-15 17:40:41 +0530162}
163
Neha Sharma96b7bf22020-06-15 10:37:32 +0000164func newKVClient(ctx context.Context, storeType string, address string, timeout time.Duration) (kvstore.Client, error) {
165 logger.Infow(ctx, "kv-store-type", log.Fields{"store": storeType})
Girish Gowdru0c588b22019-04-23 23:24:56 -0400166 switch storeType {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400167 case "etcd":
Neha Sharma96b7bf22020-06-15 10:37:32 +0000168 return kvstore.NewEtcdClient(ctx, address, timeout, log.FatalLevel)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400169 }
170 return nil, errors.New("unsupported-kv-store")
Abhilash S.L7f17e402019-03-15 17:40:41 +0530171}
172
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700173// SetKVClient sets the KV client and return a kv backend
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800174func SetKVClient(ctx context.Context, backend string, addr string, DeviceID string, basePathKvStore string) *db.Backend {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400175 // TODO : Make sure direct call to NewBackend is working fine with backend , currently there is some
176 // issue between kv store and backend , core is not calling NewBackend directly
Neha Sharma96b7bf22020-06-15 10:37:32 +0000177 kvClient, err := newKVClient(ctx, backend, addr, KvstoreTimeout)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400178 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000179 logger.Fatalw(ctx, "Failed to init KV client\n", log.Fields{"err": err})
Girish Gowdru0c588b22019-04-23 23:24:56 -0400180 return nil
181 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700182 // return db.NewBackend(ctx, backend, addr, KvstoreTimeout, fmt.Sprintf(BasePathKvStore, basePathKvStore, DeviceID))
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700183
sbarbaria8910ba2019-11-05 10:12:23 -0500184 kvbackend := &db.Backend{
Girish Gowdru0c588b22019-04-23 23:24:56 -0400185 Client: kvClient,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700186 StoreType: backend,
Neha Sharma3f221ae2020-04-29 19:02:12 +0000187 Address: addr,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700188 Timeout: KvstoreTimeout,
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800189 PathPrefix: fmt.Sprintf(BasePathKvStore, basePathKvStore, DeviceID)}
Abhilash S.L7f17e402019-03-15 17:40:41 +0530190
Girish Gowdru0c588b22019-04-23 23:24:56 -0400191 return kvbackend
Abhilash S.L7f17e402019-03-15 17:40:41 +0530192}
193
Gamze Abakafee36392019-10-03 11:17:24 +0000194// NewResourceMgr init a New resource manager instance which in turn instantiates pon resource manager
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700195// instances according to technology. Initializes the default resource ranges for all
196// the resources.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700197func NewResourceMgr(ctx context.Context, PonIntfID uint32, deviceID string, KVStoreAddress string, kvStoreType string, deviceType string, devInfo *openolt.DeviceInfo, basePathKvStore string) *OpenOltResourceMgr {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400198 var ResourceMgr OpenOltResourceMgr
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700199 logger.Debugf(ctx, "Init new resource manager , ponIf: %v, address: %s, device-id: %s", PonIntfID, KVStoreAddress, deviceID)
200 ResourceMgr.PonIntfID = PonIntfID
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700201 ResourceMgr.DeviceID = deviceID
Neha Sharma3f221ae2020-04-29 19:02:12 +0000202 ResourceMgr.Address = KVStoreAddress
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700203 ResourceMgr.DeviceType = deviceType
204 ResourceMgr.DevInfo = devInfo
Abhilash S.L7f17e402019-03-15 17:40:41 +0530205
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700206 Backend := kvStoreType
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800207 ResourceMgr.KVStore = SetKVClient(ctx, Backend, ResourceMgr.Address, deviceID, basePathKvStore)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400208 if ResourceMgr.KVStore == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000209 logger.Error(ctx, "Failed to setup KV store")
Girish Gowdru0c588b22019-04-23 23:24:56 -0400210 }
Girish Gowdra38d533d2020-03-30 20:38:51 -0700211
Girish Gowdru0c588b22019-04-23 23:24:56 -0400212 // TODO self.args = registry('main').get_args()
Abhilash S.L7f17e402019-03-15 17:40:41 +0530213
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700214 // Create a separate Resource Manager instance for each range. This assumes that
Girish Gowdru0c588b22019-04-23 23:24:56 -0400215 // each technology is represented by only a single range
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700216 for _, TechRange := range devInfo.Ranges {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700217 for _, intfID := range TechRange.IntfIds {
218 if intfID == PonIntfID {
219 technology := TechRange.Technology
220 logger.Debugf(ctx, "Device info technology %s, intf-id %v", technology, PonIntfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000221
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700222 rsrMgr, err := ponrmgr.NewPONResourceManager(ctx, technology, deviceType, deviceID,
223 Backend, ResourceMgr.Address, basePathKvStore)
224 if err != nil {
225 logger.Errorf(ctx, "Failed to create pon resource manager instance for technology %s", technology)
226 return nil
227 }
228 ResourceMgr.PonRsrMgr = rsrMgr
229 // self.initialize_device_resource_range_and_pool(resource_mgr, global_resource_mgr, arange)
230 InitializeDeviceResourceRangeAndPool(ctx, rsrMgr, TechRange, devInfo)
231 if err := ResourceMgr.PonRsrMgr.InitDeviceResourcePoolForIntf(ctx, intfID); err != nil {
232 logger.Fatal(ctx, "failed-to-initialize-device-resource-pool-intf-id-%v-device-id", ResourceMgr.PonIntfID, ResourceMgr.DeviceID)
233 return nil
234 }
235 }
Girish Gowdru0c588b22019-04-23 23:24:56 -0400236 }
Girish Gowdru0c588b22019-04-23 23:24:56 -0400237 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700238
239 ResourceMgr.InitLocalCache()
240
Neha Sharma96b7bf22020-06-15 10:37:32 +0000241 logger.Info(ctx, "Initialization of resource manager success!")
Girish Gowdru0c588b22019-04-23 23:24:56 -0400242 return &ResourceMgr
Abhilash S.L7f17e402019-03-15 17:40:41 +0530243}
244
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700245//InitLocalCache initializes local maps used for write-through-cache
246func (rsrcMgr *OpenOltResourceMgr) InitLocalCache() {
247 rsrcMgr.flowIDsForOnu = make(map[string][]uint64)
248 rsrcMgr.allocIDsForOnu = make(map[string][]uint32)
249 rsrcMgr.gemPortIDsForOnu = make(map[string][]uint32)
250 rsrcMgr.techProfileIDsForOnu = make(map[string][]uint32)
251 rsrcMgr.meterInfoForOnu = make(map[string]*MeterInfo)
252 rsrcMgr.onuGemInfo = make(map[string]*OnuGemInfo)
253 rsrcMgr.gemPortForPacketInInfo = make(map[string]uint32)
254 rsrcMgr.flowIDsForGem = make(map[uint32][]uint64)
255 rsrcMgr.mcastQueueForIntf = make(map[uint32][]uint32)
256 rsrcMgr.groupInfo = make(map[string]*GroupInfo)
257}
258
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700259// InitializeDeviceResourceRangeAndPool initializes the resource range pool according to the sharing type, then apply
260// device specific information. If KV doesn't exist
261// or is broader than the device, the device's information will
262// dictate the range limits
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700263func InitializeDeviceResourceRangeAndPool(ctx context.Context, ponRMgr *ponrmgr.PONResourceManager,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700264 techRange *openolt.DeviceInfo_DeviceResourceRanges, devInfo *openolt.DeviceInfo) {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700265 // var ONUIDShared, AllocIDShared, GEMPortIDShared openolt.DeviceInfo_DeviceResourceRanges_Pool_SharingType
266 var ONUIDStart, ONUIDEnd, AllocIDStart, AllocIDEnd, GEMPortIDStart, GEMPortIDEnd uint32
267 var ONUIDShared, AllocIDShared, GEMPortIDShared, FlowIDShared uint32
268
269 // The below variables are just dummy and needed to pass as arguments to InitDefaultPONResourceRanges function.
270 // The openolt adapter does not need flowIDs to be managed as it is managed on the OLT device
271 // The UNI IDs are dynamically generated by openonu adapter for every discovered UNI.
272 var flowIDDummyStart, flowIDDummyEnd uint32 = 1, 2
273 var uniIDDummyStart, uniIDDummyEnd uint32 = 0, 1
Abhilash S.L7f17e402019-03-15 17:40:41 +0530274
Girish Gowdru0c588b22019-04-23 23:24:56 -0400275 // init the resource range pool according to the sharing type
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700276 logger.Debugw(ctx, "Device info init", log.Fields{"technology": techRange.Technology,
277 "onu_id_start": ONUIDStart, "onu_id_end": ONUIDEnd,
278 "alloc_id_start": AllocIDStart, "alloc_id_end": AllocIDEnd,
279 "gemport_id_start": GEMPortIDStart, "gemport_id_end": GEMPortIDEnd,
280 "intf_ids": techRange.IntfIds,
281 })
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700282 for _, RangePool := range techRange.Pools {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700283 // FIXME: Remove hardcoding
Girish Gowdru0c588b22019-04-23 23:24:56 -0400284 if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_ONU_ID {
285 ONUIDStart = RangePool.Start
286 ONUIDEnd = RangePool.End
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700287 ONUIDShared = uint32(RangePool.Sharing)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400288 } else if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_ALLOC_ID {
289 AllocIDStart = RangePool.Start
290 AllocIDEnd = RangePool.End
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700291 AllocIDShared = uint32(RangePool.Sharing)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400292 } else if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_GEMPORT_ID {
293 GEMPortIDStart = RangePool.Start
294 GEMPortIDEnd = RangePool.End
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700295 GEMPortIDShared = uint32(RangePool.Sharing)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400296 }
297 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530298
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700299 ponRMgr.InitDefaultPONResourceRanges(ctx, ONUIDStart, ONUIDEnd, ONUIDShared,
300 AllocIDStart, AllocIDEnd, AllocIDShared,
301 GEMPortIDStart, GEMPortIDEnd, GEMPortIDShared,
302 flowIDDummyStart, flowIDDummyEnd, FlowIDShared, uniIDDummyStart, uniIDDummyEnd,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700303 devInfo.PonPorts, techRange.IntfIds)
Abhilash S.L7f17e402019-03-15 17:40:41 +0530304
Abhilash S.L7f17e402019-03-15 17:40:41 +0530305}
306
Devmalya Paul495b94a2019-08-27 19:42:00 -0400307// Delete clears used resources for the particular olt device being deleted
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700308func (rsrcMgr *OpenOltResourceMgr) Delete(ctx context.Context, intfID uint32) error {
309 if err := rsrcMgr.PonRsrMgr.ClearDeviceResourcePoolForIntf(ctx, intfID); err != nil {
310 logger.Debug(ctx, "Failed to clear device resource pool")
311 return err
Devmalya Paul495b94a2019-08-27 19:42:00 -0400312 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000313 logger.Debug(ctx, "Cleared device resource pool")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400314 return nil
315}
Abhilash S.L7f17e402019-03-15 17:40:41 +0530316
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700317// GetONUID returns the available onuID for the given pon-port
318func (rsrcMgr *OpenOltResourceMgr) GetONUID(ctx context.Context, PonIntfID uint32) (uint32, error) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400319 // Get ONU id for a provided pon interface ID.
Girish Gowdra76a1b092021-07-28 10:07:04 -0700320 onuID, err := rsrcMgr.TechprofileRef.GetResourceID(ctx, PonIntfID,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400321 ponrmgr.ONU_ID, 1)
322 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000323 logger.Errorf(ctx, "Failed to get resource for interface %d for type %s",
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700324 PonIntfID, ponrmgr.ONU_ID)
cbabuabf02352019-10-15 13:14:56 +0200325 return 0, err
Girish Gowdru0c588b22019-04-23 23:24:56 -0400326 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700327 if len(onuID) > 0 {
328 rsrcMgr.PonRsrMgr.InitResourceMap(ctx, fmt.Sprintf("%d,%d", PonIntfID, onuID[0]))
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700329 return onuID[0], err
Girish Gowdru0c588b22019-04-23 23:24:56 -0400330 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530331
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700332 return 0, err // return onuID 0 on error
Abhilash S.L8ee90712019-04-29 16:24:22 +0530333}
334
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700335// GetCurrentFlowIDsForOnu fetches flow ID from the resource manager
336// Note: For flows which trap from the NNI and not really associated with any particular
337// ONU (like LLDP), the onu_id and uni_id is set as -1. The intf_id is the NNI intf_id.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700338func (rsrcMgr *OpenOltResourceMgr) GetCurrentFlowIDsForOnu(ctx context.Context, PonIntfID uint32, onuID int32, uniID int32) ([]uint64, error) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700339
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700340 subs := fmt.Sprintf("%d,%d,%d", PonIntfID, onuID, uniID)
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700341 path := fmt.Sprintf(FlowIDPath, subs)
342
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700343 // fetch from cache
344 rsrcMgr.flowIDsForOnuLock.RLock()
345 flowIDsForOnu, ok := rsrcMgr.flowIDsForOnu[path]
346 rsrcMgr.flowIDsForOnuLock.RUnlock()
347
348 if ok {
349 return flowIDsForOnu, nil
350 }
351
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700352 var data []uint64
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700353 value, err := rsrcMgr.KVStore.Get(ctx, path)
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700354 if err == nil {
355 if value != nil {
356 Val, _ := toByte(value.Value)
357 if err = json.Unmarshal(Val, &data); err != nil {
358 logger.Error(ctx, "Failed to unmarshal")
359 return nil, err
360 }
361 }
Serkant Uluderya89ff40c2019-10-17 16:02:25 -0700362 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700363 // update cache
364 rsrcMgr.flowIDsForOnuLock.Lock()
365 rsrcMgr.flowIDsForOnu[path] = data
366 rsrcMgr.flowIDsForOnuLock.Unlock()
367
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700368 return data, nil
Abhilash S.L8ee90712019-04-29 16:24:22 +0530369}
370
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700371// UpdateAllocIdsForOnu updates alloc ids in kv store for a given pon interface id, onu id and uni id
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700372func (rsrcMgr *OpenOltResourceMgr) UpdateAllocIdsForOnu(ctx context.Context, ponPort uint32, onuID uint32, uniID uint32, allocIDs []uint32) error {
Abhilash S.L7f17e402019-03-15 17:40:41 +0530373
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700374 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", ponPort, onuID, uniID)
375 // update cache
376 rsrcMgr.allocIDsForOnuLock.Lock()
377 rsrcMgr.allocIDsForOnu[intfOnuIDuniID] = allocIDs
378 rsrcMgr.allocIDsForOnuLock.Unlock()
379
380 // Note: in case the write to DB fails there could be inconsistent data between cache and db.
381 // Although this is highly unlikely with DB retries in place, this is something we have to deal with in the next release
382 return rsrcMgr.PonRsrMgr.UpdateAllocIdsForOnu(ctx, intfOnuIDuniID,
383 allocIDs)
Abhilash S.L7f17e402019-03-15 17:40:41 +0530384}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700385
386// GetCurrentGEMPortIDsForOnu returns gem ports for given pon interface , onu id and uni id
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700387func (rsrcMgr *OpenOltResourceMgr) GetCurrentGEMPortIDsForOnu(ctx context.Context, intfID uint32, onuID uint32,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700388 uniID uint32) []uint32 {
Abhilash S.L7f17e402019-03-15 17:40:41 +0530389
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700390 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", intfID, onuID, uniID)
Abhilash S.L7f17e402019-03-15 17:40:41 +0530391
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700392 // fetch from cache
393 rsrcMgr.gemPortIDsForOnuLock.RLock()
394 gemIDs, ok := rsrcMgr.gemPortIDsForOnu[intfOnuIDuniID]
395 rsrcMgr.gemPortIDsForOnuLock.RUnlock()
396 if ok {
397 return gemIDs
398 }
399 /* Get gem ports for given pon interface , onu id and uni id. */
400 gemIDs = rsrcMgr.PonRsrMgr.GetCurrentGEMPortIDsForOnu(ctx, intfOnuIDuniID)
401
402 // update cache
403 rsrcMgr.gemPortIDsForOnuLock.Lock()
404 rsrcMgr.gemPortIDsForOnu[intfOnuIDuniID] = gemIDs
405 rsrcMgr.gemPortIDsForOnuLock.Unlock()
406
407 return gemIDs
Abhilash S.L7f17e402019-03-15 17:40:41 +0530408}
409
Gamze Abakafee36392019-10-03 11:17:24 +0000410// GetCurrentAllocIDsForOnu returns alloc ids for given pon interface and onu id
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700411func (rsrcMgr *OpenOltResourceMgr) GetCurrentAllocIDsForOnu(ctx context.Context, intfID uint32, onuID uint32, uniID uint32) []uint32 {
Abhilash S.L7f17e402019-03-15 17:40:41 +0530412
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700413 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", intfID, onuID, uniID)
414 // fetch from cache
415 rsrcMgr.allocIDsForOnuLock.RLock()
416 allocIDs, ok := rsrcMgr.allocIDsForOnu[intfOnuIDuniID]
417 rsrcMgr.allocIDsForOnuLock.RUnlock()
418 if ok {
419 return allocIDs
Girish Gowdru0c588b22019-04-23 23:24:56 -0400420 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700421 allocIDs = rsrcMgr.PonRsrMgr.GetCurrentAllocIDForOnu(ctx, intfOnuIDuniID)
422
423 // update cache
424 rsrcMgr.allocIDsForOnuLock.Lock()
425 rsrcMgr.allocIDsForOnu[intfOnuIDuniID] = allocIDs
426 rsrcMgr.allocIDsForOnuLock.Unlock()
427
428 return allocIDs
Gamze Abakafee36392019-10-03 11:17:24 +0000429}
430
431// RemoveAllocIDForOnu removes the alloc id for given pon interface, onu id, uni id and alloc id
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700432func (rsrcMgr *OpenOltResourceMgr) RemoveAllocIDForOnu(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, allocID uint32) {
433 allocIDs := rsrcMgr.GetCurrentAllocIDsForOnu(ctx, intfID, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000434 for i := 0; i < len(allocIDs); i++ {
435 if allocIDs[i] == allocID {
436 allocIDs = append(allocIDs[:i], allocIDs[i+1:]...)
437 break
438 }
439 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700440 err := rsrcMgr.UpdateAllocIdsForOnu(ctx, intfID, onuID, uniID, allocIDs)
Gamze Abakafee36392019-10-03 11:17:24 +0000441 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700442 logger.Errorf(ctx, "Failed to Remove Alloc Id For Onu. intfID %d onuID %d uniID %d allocID %d",
Gamze Abakafee36392019-10-03 11:17:24 +0000443 intfID, onuID, uniID, allocID)
444 }
445}
446
447// RemoveGemPortIDForOnu removes the gem port id for given pon interface, onu id, uni id and gem port id
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700448func (rsrcMgr *OpenOltResourceMgr) RemoveGemPortIDForOnu(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, gemPortID uint32) {
449 gemPortIDs := rsrcMgr.GetCurrentGEMPortIDsForOnu(ctx, intfID, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000450 for i := 0; i < len(gemPortIDs); i++ {
451 if gemPortIDs[i] == gemPortID {
452 gemPortIDs = append(gemPortIDs[:i], gemPortIDs[i+1:]...)
453 break
454 }
455 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700456 err := rsrcMgr.UpdateGEMPortIDsForOnu(ctx, intfID, onuID, uniID, gemPortIDs)
Gamze Abakafee36392019-10-03 11:17:24 +0000457 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700458 logger.Errorf(ctx, "Failed to Remove Gem Id For Onu. intfID %d onuID %d uniID %d gemPortId %d",
Gamze Abakafee36392019-10-03 11:17:24 +0000459 intfID, onuID, uniID, gemPortID)
460 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530461}
462
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700463// UpdateGEMPortIDsForOnu updates gemport ids on to the kv store for a given pon port, onu id and uni id
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700464func (rsrcMgr *OpenOltResourceMgr) UpdateGEMPortIDsForOnu(ctx context.Context, ponPort uint32, onuID uint32,
465 uniID uint32, gemIDs []uint32) error {
466 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", ponPort, onuID, uniID)
467 // update cache
468 rsrcMgr.gemPortIDsForOnuLock.Lock()
469 rsrcMgr.gemPortIDsForOnu[intfOnuIDuniID] = gemIDs
470 rsrcMgr.gemPortIDsForOnuLock.Unlock()
471
472 // Note: in case the write to DB fails there could be inconsistent data between cache and db.
473 // Although this is highly unlikely with DB retries in place, this is something we have to deal with in the next release
474 return rsrcMgr.PonRsrMgr.UpdateGEMPortIDsForOnu(ctx, intfOnuIDuniID,
475 gemIDs)
Abhilash S.L7f17e402019-03-15 17:40:41 +0530476
477}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700478
479// FreeonuID releases(make free) onu id for a particular pon-port
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700480func (rsrcMgr *OpenOltResourceMgr) FreeonuID(ctx context.Context, intfID uint32, onuID []uint32) {
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -0700481 if len(onuID) == 0 {
482 logger.Info(ctx, "onu id slice is nil, nothing to free")
483 return
484 }
Girish Gowdra76a1b092021-07-28 10:07:04 -0700485 if err := rsrcMgr.TechprofileRef.FreeResourceID(ctx, intfID, ponrmgr.ONU_ID, onuID); err != nil {
Matteo Scandolo84585372021-03-18 14:21:22 -0700486 logger.Errorw(ctx, "error-while-freeing-onu-id", log.Fields{
487 "intf-id": intfID,
488 "onu-id": onuID,
489 "err": err.Error(),
490 })
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -0700491 } else {
492 logger.Infow(ctx, "freed onu id", log.Fields{"intfID": intfID, "onuID": onuID})
Matteo Scandolo84585372021-03-18 14:21:22 -0700493 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530494
Girish Gowdru0c588b22019-04-23 23:24:56 -0400495 /* Free onu id for a particular interface.*/
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700496 var IntfonuID string
497 for _, onu := range onuID {
498 IntfonuID = fmt.Sprintf("%d,%d", intfID, onu)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700499 rsrcMgr.PonRsrMgr.RemoveResourceMap(ctx, IntfonuID)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400500 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530501}
502
Gamze Abakafee36392019-10-03 11:17:24 +0000503// FreeAllocID frees AllocID on the PON resource pool and also frees the allocID association
504// for the given OLT device.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700505// The caller should ensure that this is a blocking call and this operation is serialized for
506// the ONU so as not cause resource corruption since there are no mutexes used here.
507func (rsrcMgr *OpenOltResourceMgr) FreeAllocID(ctx context.Context, intfID uint32, onuID uint32,
Gamze Abakafee36392019-10-03 11:17:24 +0000508 uniID uint32, allocID uint32) {
Girish Gowdrab77ded92020-04-08 11:45:05 -0700509
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700510 rsrcMgr.RemoveAllocIDForOnu(ctx, intfID, onuID, uniID, allocID)
Gamze Abakafee36392019-10-03 11:17:24 +0000511 allocIDs := make([]uint32, 0)
512 allocIDs = append(allocIDs, allocID)
Girish Gowdra76a1b092021-07-28 10:07:04 -0700513 if err := rsrcMgr.TechprofileRef.FreeResourceID(ctx, intfID, ponrmgr.ALLOC_ID, allocIDs); err != nil {
Matteo Scandolo84585372021-03-18 14:21:22 -0700514 logger.Errorw(ctx, "error-while-freeing-alloc-id", log.Fields{
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700515 "intf-id": intfID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700516 "onu-id": onuID,
517 "err": err.Error(),
518 })
519 }
Gamze Abakafee36392019-10-03 11:17:24 +0000520}
521
522// FreeGemPortID frees GemPortID on the PON resource pool and also frees the gemPortID association
523// for the given OLT device.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700524// The caller should ensure that this is a blocking call and this operation is serialized for
525// the ONU so as not cause resource corruption since there are no mutexes used here.
526func (rsrcMgr *OpenOltResourceMgr) FreeGemPortID(ctx context.Context, intfID uint32, onuID uint32,
Gamze Abakafee36392019-10-03 11:17:24 +0000527 uniID uint32, gemPortID uint32) {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700528 rsrcMgr.RemoveGemPortIDForOnu(ctx, intfID, onuID, uniID, gemPortID)
Girish Gowdrab77ded92020-04-08 11:45:05 -0700529
Gamze Abakafee36392019-10-03 11:17:24 +0000530 gemPortIDs := make([]uint32, 0)
531 gemPortIDs = append(gemPortIDs, gemPortID)
Girish Gowdra76a1b092021-07-28 10:07:04 -0700532 if err := rsrcMgr.TechprofileRef.FreeResourceID(ctx, intfID, ponrmgr.GEMPORT_ID, gemPortIDs); err != nil {
Matteo Scandolo84585372021-03-18 14:21:22 -0700533 logger.Errorw(ctx, "error-while-freeing-gem-port-id", log.Fields{
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700534 "intf-id": intfID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700535 "onu-id": onuID,
536 "err": err.Error(),
537 })
538 }
Gamze Abakafee36392019-10-03 11:17:24 +0000539}
540
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700541// FreePONResourcesForONU make the pon resources free for a given pon interface and onu id
542func (rsrcMgr *OpenOltResourceMgr) FreePONResourcesForONU(ctx context.Context, intfID uint32, onuID uint32, uniID uint32) {
Abhilash S.L7f17e402019-03-15 17:40:41 +0530543
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700544 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", intfID, onuID, uniID)
Abhilash S.L7f17e402019-03-15 17:40:41 +0530545
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700546 AllocIDs := rsrcMgr.PonRsrMgr.GetCurrentAllocIDForOnu(ctx, intfOnuIDuniID)
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700547
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700548 rsrcMgr.allocIDsForOnuLock.Lock()
549 delete(rsrcMgr.allocIDsForOnu, intfOnuIDuniID)
550 rsrcMgr.allocIDsForOnuLock.Unlock()
551
Girish Gowdra76a1b092021-07-28 10:07:04 -0700552 if err := rsrcMgr.TechprofileRef.FreeResourceID(ctx, intfID,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400553 ponrmgr.ALLOC_ID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700554 AllocIDs); err != nil {
555 logger.Errorw(ctx, "error-while-freeing-all-alloc-ids-for-onu", log.Fields{
556 "intf-id": intfID,
557 "onu-id": onuID,
558 "err": err.Error(),
559 })
560 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530561
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700562 GEMPortIDs := rsrcMgr.PonRsrMgr.GetCurrentGEMPortIDsForOnu(ctx, intfOnuIDuniID)
563
564 rsrcMgr.gemPortIDsForOnuLock.Lock()
565 delete(rsrcMgr.gemPortIDsForOnu, intfOnuIDuniID)
566 rsrcMgr.gemPortIDsForOnuLock.Unlock()
567
Girish Gowdra76a1b092021-07-28 10:07:04 -0700568 if err := rsrcMgr.TechprofileRef.FreeResourceID(ctx, intfID,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400569 ponrmgr.GEMPORT_ID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700570 GEMPortIDs); err != nil {
571 logger.Errorw(ctx, "error-while-freeing-all-gem-port-ids-for-onu", log.Fields{
572 "intf-id": intfID,
573 "onu-id": onuID,
574 "err": err.Error(),
575 })
576 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530577
Girish Gowdru0c588b22019-04-23 23:24:56 -0400578 // Clear resource map associated with (pon_intf_id, gemport_id) tuple.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700579 rsrcMgr.PonRsrMgr.RemoveResourceMap(ctx, intfOnuIDuniID)
Abhilash S.L7f17e402019-03-15 17:40:41 +0530580}
581
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700582// IsFlowOnKvStore checks if the given flowID is present on the kv store
583// Returns true if the flowID is found, otherwise it returns false
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700584func (rsrcMgr *OpenOltResourceMgr) IsFlowOnKvStore(ctx context.Context, intfID uint32, onuID int32, uniID int32,
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700585 flowID uint64) bool {
Abhilash S.L7f17e402019-03-15 17:40:41 +0530586
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700587 FlowIDs, err := rsrcMgr.GetCurrentFlowIDsForOnu(ctx, intfID, onuID, uniID)
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700588 if err != nil {
589 // error logged in the called function
590 return false
591 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400592 if FlowIDs != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700593 logger.Debugw(ctx, "Found flowId(s) for this ONU", log.Fields{"pon": intfID, "onuID": onuID, "uniID": uniID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700594 for _, id := range FlowIDs {
595 if flowID == id {
596 return true
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400597 }
598 }
599 }
600 return false
601}
Manikkaraj kb1d51442019-07-23 10:41:02 -0400602
salmansiddiqui7ac62132019-08-22 03:58:50 +0000603// GetTechProfileIDForOnu fetches Tech-Profile-ID from the KV-Store for the given onu based on the path
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700604// This path is formed as the following: {intfID, onuID, uniID}/tp_id
605func (rsrcMgr *OpenOltResourceMgr) GetTechProfileIDForOnu(ctx context.Context, intfID uint32, onuID uint32, uniID uint32) []uint32 {
606 Path := fmt.Sprintf(tpIDPathSuffix, intfID, onuID, uniID)
607 // fetch from cache
608 rsrcMgr.techProfileIDsForOnuLock.RLock()
609 tpIDs, ok := rsrcMgr.techProfileIDsForOnu[Path]
610 rsrcMgr.techProfileIDsForOnuLock.RUnlock()
611 if ok {
612 return tpIDs
613 }
614 Value, err := rsrcMgr.KVStore.Get(ctx, Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400615 if err == nil {
616 if Value != nil {
617 Val, err := kvstore.ToByte(Value.Value)
618 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700619 logger.Errorw(ctx, "Failed to convert into byte array", log.Fields{"err": err})
620 return tpIDs
Manikkaraj kb1d51442019-07-23 10:41:02 -0400621 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700622 if err = json.Unmarshal(Val, &tpIDs); err != nil {
623 logger.Error(ctx, "Failed to unmarshal", log.Fields{"err": err})
624 return tpIDs
Manikkaraj kb1d51442019-07-23 10:41:02 -0400625 }
626 }
627 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000628 logger.Errorf(ctx, "Failed to get TP id from kvstore for path %s", Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400629 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700630 logger.Debugf(ctx, "Getting TP id %d from path %s", tpIDs, Path)
631
632 // update cache
633 rsrcMgr.techProfileIDsForOnuLock.Lock()
634 rsrcMgr.techProfileIDsForOnu[Path] = tpIDs
635 rsrcMgr.techProfileIDsForOnuLock.Unlock()
636
637 return tpIDs
Manikkaraj kb1d51442019-07-23 10:41:02 -0400638
639}
640
Gamze Abakafee36392019-10-03 11:17:24 +0000641// RemoveTechProfileIDsForOnu deletes all tech profile ids from the KV-Store for the given onu based on the path
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700642// This path is formed as the following: {intfID, onuID, uniID}/tp_id
643func (rsrcMgr *OpenOltResourceMgr) RemoveTechProfileIDsForOnu(ctx context.Context, intfID uint32, onuID uint32, uniID uint32) error {
644 intfOnuUniID := fmt.Sprintf(tpIDPathSuffix, intfID, onuID, uniID)
645 // update cache
646 rsrcMgr.techProfileIDsForOnuLock.Lock()
647 delete(rsrcMgr.techProfileIDsForOnu, intfOnuUniID)
648 rsrcMgr.techProfileIDsForOnuLock.Unlock()
649
650 if err := rsrcMgr.KVStore.Delete(ctx, intfOnuUniID); err != nil {
651 logger.Errorw(ctx, "Failed to delete techprofile id resource in KV store", log.Fields{"path": intfOnuUniID})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400652 return err
653 }
654 return nil
655}
656
Gamze Abakafee36392019-10-03 11:17:24 +0000657// RemoveTechProfileIDForOnu deletes a specific tech profile id from the KV-Store for the given onu based on the path
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700658// This path is formed as the following: {intfID, onuID, uniID}/tp_id
659func (rsrcMgr *OpenOltResourceMgr) RemoveTechProfileIDForOnu(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, tpID uint32) error {
660 tpIDList := rsrcMgr.GetTechProfileIDForOnu(ctx, intfID, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000661 for i, tpIDInList := range tpIDList {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700662 if tpIDInList == tpID {
Gamze Abakafee36392019-10-03 11:17:24 +0000663 tpIDList = append(tpIDList[:i], tpIDList[i+1:]...)
664 }
665 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700666 intfOnuUniID := fmt.Sprintf(tpIDPathSuffix, intfID, onuID, uniID)
667 // update cache
668 rsrcMgr.techProfileIDsForOnuLock.Lock()
669 rsrcMgr.techProfileIDsForOnu[intfOnuUniID] = tpIDList
670 rsrcMgr.techProfileIDsForOnuLock.Unlock()
671
Gamze Abakafee36392019-10-03 11:17:24 +0000672 Value, err := json.Marshal(tpIDList)
673 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000674 logger.Error(ctx, "failed to Marshal")
Gamze Abakafee36392019-10-03 11:17:24 +0000675 return err
676 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700677 if err = rsrcMgr.KVStore.Put(ctx, intfOnuUniID, Value); err != nil {
678 logger.Errorf(ctx, "Failed to update resource %s", intfOnuUniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000679 return err
680 }
681 return err
682}
683
684// UpdateTechProfileIDForOnu updates (put) already present tech-profile-id for the given onu based on the path
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700685// This path is formed as the following: {intfID, onuID, uniID}/tp_id
686func (rsrcMgr *OpenOltResourceMgr) UpdateTechProfileIDForOnu(ctx context.Context, intfID uint32, onuID uint32,
687 uniID uint32, tpID uint32) error {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400688 var Value []byte
689 var err error
690
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700691 intfOnuUniID := fmt.Sprintf(tpIDPathSuffix, intfID, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000692
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700693 tpIDList := rsrcMgr.GetTechProfileIDForOnu(ctx, intfID, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000694 for _, value := range tpIDList {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700695 if value == tpID {
696 logger.Debugf(ctx, "tpID %d is already in tpIdList for the path %s", tpID, intfOnuUniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000697 return err
698 }
699 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700700 logger.Debugf(ctx, "updating tp id %d on path %s", tpID, intfOnuUniID)
701 tpIDList = append(tpIDList, tpID)
702
703 // update cache
704 rsrcMgr.techProfileIDsForOnuLock.Lock()
705 rsrcMgr.techProfileIDsForOnu[intfOnuUniID] = tpIDList
706 rsrcMgr.techProfileIDsForOnuLock.Unlock()
707
Gamze Abakafee36392019-10-03 11:17:24 +0000708 Value, err = json.Marshal(tpIDList)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400709 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000710 logger.Error(ctx, "failed to Marshal")
Manikkaraj kb1d51442019-07-23 10:41:02 -0400711 return err
712 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700713 if err = rsrcMgr.KVStore.Put(ctx, intfOnuUniID, Value); err != nil {
714 logger.Errorf(ctx, "Failed to update resource %s", intfOnuUniID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400715 return err
716 }
717 return err
718}
719
Girish Gowdraa482f272021-03-24 23:04:19 -0700720// StoreMeterInfoForOnu updates the meter id in the KV-Store for the given onu based on the path
Gamze Abakafee36392019-10-03 11:17:24 +0000721// This path is formed as the following: <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700722func (rsrcMgr *OpenOltResourceMgr) StoreMeterInfoForOnu(ctx context.Context, Direction string, intfID uint32, onuID uint32,
723 uniID uint32, tpID uint32, meterInfo *MeterInfo) error {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400724 var Value []byte
725 var err error
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700726 intfOnuUniID := fmt.Sprintf(MeterIDPathSuffix, intfID, onuID, uniID, tpID, Direction)
727
728 // update cache
729 rsrcMgr.meterInfoForOnuLock.Lock()
730 rsrcMgr.meterInfoForOnu[intfOnuUniID] = meterInfo
731 rsrcMgr.meterInfoForOnuLock.Unlock()
732
Girish Gowdraa482f272021-03-24 23:04:19 -0700733 Value, err = json.Marshal(*meterInfo)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400734 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000735 logger.Error(ctx, "failed to Marshal meter config")
Manikkaraj kb1d51442019-07-23 10:41:02 -0400736 return err
737 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700738 if err = rsrcMgr.KVStore.Put(ctx, intfOnuUniID, Value); err != nil {
739 logger.Errorf(ctx, "Failed to store meter into KV store %s", intfOnuUniID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400740 return err
741 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700742 logger.Debugw(ctx, "meter info updated successfully", log.Fields{"path": intfOnuUniID, "meter-info": meterInfo})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400743 return err
744}
745
Girish Gowdraa482f272021-03-24 23:04:19 -0700746// GetMeterInfoForOnu fetches the meter id from the kv store for the given onu based on the path
Gamze Abakafee36392019-10-03 11:17:24 +0000747// This path is formed as the following: <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700748func (rsrcMgr *OpenOltResourceMgr) GetMeterInfoForOnu(ctx context.Context, Direction string, intfID uint32, onuID uint32,
749 uniID uint32, tpID uint32) (*MeterInfo, error) {
750 Path := fmt.Sprintf(MeterIDPathSuffix, intfID, onuID, uniID, tpID, Direction)
751
752 // get from cache
753 rsrcMgr.meterInfoForOnuLock.RLock()
754 val, ok := rsrcMgr.meterInfoForOnu[Path]
755 rsrcMgr.meterInfoForOnuLock.RUnlock()
756 if ok {
757 return val, nil
758 }
759
Girish Gowdraa482f272021-03-24 23:04:19 -0700760 var meterInfo MeterInfo
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700761 Value, err := rsrcMgr.KVStore.Get(ctx, Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400762 if err == nil {
763 if Value != nil {
Girish Gowdraa482f272021-03-24 23:04:19 -0700764 logger.Debug(ctx, "Found meter info in KV store", log.Fields{"Direction": Direction})
salmansiddiqui7ac62132019-08-22 03:58:50 +0000765 Val, er := kvstore.ToByte(Value.Value)
766 if er != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700767 logger.Errorw(ctx, "Failed to convert into byte array", log.Fields{"err": er})
salmansiddiqui7ac62132019-08-22 03:58:50 +0000768 return nil, er
Manikkaraj kb1d51442019-07-23 10:41:02 -0400769 }
Girish Gowdraa482f272021-03-24 23:04:19 -0700770 if er = json.Unmarshal(Val, &meterInfo); er != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700771 logger.Error(ctx, "Failed to unmarshal meter info", log.Fields{"err": er})
salmansiddiqui7ac62132019-08-22 03:58:50 +0000772 return nil, er
Manikkaraj kb1d51442019-07-23 10:41:02 -0400773 }
774 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000775 logger.Debug(ctx, "meter-does-not-exists-in-KVStore")
Manikkaraj kb1d51442019-07-23 10:41:02 -0400776 return nil, err
777 }
778 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000779 logger.Errorf(ctx, "Failed to get Meter config from kvstore for path %s", Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400780
781 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700782 // update cache
783 rsrcMgr.meterInfoForOnuLock.Lock()
784 rsrcMgr.meterInfoForOnu[Path] = &meterInfo
785 rsrcMgr.meterInfoForOnuLock.Unlock()
786
Girish Gowdraa482f272021-03-24 23:04:19 -0700787 return &meterInfo, err
Manikkaraj kb1d51442019-07-23 10:41:02 -0400788}
789
Girish Gowdraa482f272021-03-24 23:04:19 -0700790// HandleMeterInfoRefCntUpdate increments or decrements the reference counter for a given meter.
791// When reference count becomes 0, it clears the meter information from the kv store
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700792func (rsrcMgr *OpenOltResourceMgr) HandleMeterInfoRefCntUpdate(ctx context.Context, Direction string,
793 intfID uint32, onuID uint32, uniID uint32, tpID uint32, increment bool) error {
794 meterInfo, err := rsrcMgr.GetMeterInfoForOnu(ctx, Direction, intfID, onuID, uniID, tpID)
Girish Gowdra82c80982021-03-26 16:22:02 -0700795 if err != nil {
796 return err
797 } else if meterInfo == nil {
798 // If we are increasing the reference count, we expect the meter information to be present on KV store.
799 // But if decrementing the reference count, the meter is possibly already cleared from KV store. Just log warn but do not return error.
800 if increment {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700801 logger.Errorf(ctx, "error-fetching-meter-info-for-intf-%d-onu-%d-uni-%d-tp-id-%d-direction-%s", intfID, onuID, uniID, tpID, Direction)
802 return fmt.Errorf("error-fetching-meter-info-for-intf-%d-onu-%d-uni-%d-tp-id-%d-direction-%s", intfID, onuID, uniID, tpID, Direction)
Girish Gowdra82c80982021-03-26 16:22:02 -0700803 }
804 logger.Warnw(ctx, "meter is already cleared",
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700805 log.Fields{"intfID": intfID, "onuID": onuID, "uniID": uniID, "direction": Direction, "increment": increment})
Girish Gowdra82c80982021-03-26 16:22:02 -0700806 return nil
Girish Gowdraa482f272021-03-24 23:04:19 -0700807 }
Girish Gowdra82c80982021-03-26 16:22:02 -0700808
Girish Gowdraa482f272021-03-24 23:04:19 -0700809 if increment {
810 meterInfo.RefCnt++
811 } else {
812 meterInfo.RefCnt--
Girish Gowdra82c80982021-03-26 16:22:02 -0700813 // If RefCnt become 0 clear the meter information from the DB.
Girish Gowdraa482f272021-03-24 23:04:19 -0700814 if meterInfo.RefCnt == 0 {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700815 if err := rsrcMgr.RemoveMeterInfoForOnu(ctx, Direction, intfID, onuID, uniID, tpID); err != nil {
Girish Gowdraa482f272021-03-24 23:04:19 -0700816 return err
817 }
818 return nil
819 }
820 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700821 if err := rsrcMgr.StoreMeterInfoForOnu(ctx, Direction, intfID, onuID, uniID, tpID, meterInfo); err != nil {
Girish Gowdraa482f272021-03-24 23:04:19 -0700822 return err
823 }
824 return nil
825}
826
827// RemoveMeterInfoForOnu deletes the meter id from the kV-Store for the given onu based on the path
Gamze Abakafee36392019-10-03 11:17:24 +0000828// This path is formed as the following: <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700829func (rsrcMgr *OpenOltResourceMgr) RemoveMeterInfoForOnu(ctx context.Context, Direction string, intfID uint32, onuID uint32,
830 uniID uint32, tpID uint32) error {
831 Path := fmt.Sprintf(MeterIDPathSuffix, intfID, onuID, uniID, tpID, Direction)
832
833 // update cache
834 rsrcMgr.meterInfoForOnuLock.Lock()
835 delete(rsrcMgr.meterInfoForOnu, Path)
836 rsrcMgr.meterInfoForOnuLock.Unlock()
837
838 if err := rsrcMgr.KVStore.Delete(ctx, Path); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000839 logger.Errorf(ctx, "Failed to delete meter id %s from kvstore ", Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400840 return err
841 }
842 return nil
843}
salmansiddiqui7ac62132019-08-22 03:58:50 +0000844
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700845//AddGemToOnuGemInfo adds gemport to onugem info kvstore and also local cache
846func (rsrcMgr *OpenOltResourceMgr) AddGemToOnuGemInfo(ctx context.Context, intfID uint32, onuID uint32, gemPort uint32) error {
847 onugem, err := rsrcMgr.GetOnuGemInfo(ctx, intfID, onuID)
848 if err != nil || onugem == nil || onugem.SerialNumber == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000849 logger.Errorf(ctx, "failed to get onuifo for intfid %d", intfID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530850 return err
851 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700852 if onugem.OnuID == onuID {
853 for _, gem := range onugem.GemPorts {
854 if gem == gemPort {
855 logger.Debugw(ctx, "Gem already present in onugem info, skpping addition", log.Fields{"gem": gem})
856 return nil
857 }
858 }
859 logger.Debugw(ctx, "Added gem to onugem info", log.Fields{"gem": gemPort})
860 onugem.GemPorts = append(onugem.GemPorts, gemPort)
861 } else {
862 logger.Errorw(ctx, "onu id in OnuGemInfo does not match", log.Fields{"onuID": onuID, "ponIf": intfID, "onuGemInfoOnuID": onugem.OnuID})
863 return fmt.Errorf("onu-id-in-OnuGemInfo-does-not-match-%v", onuID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530864 }
865
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700866 err = rsrcMgr.AddOnuGemInfo(ctx, intfID, onuID, *onugem)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530867 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000868 logger.Error(ctx, "Failed to add onugem to kv store")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530869 return err
870 }
871 return err
872}
873
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700874//RemoveGemFromOnuGemInfo removes gemport from onugem info on kvstore and also local cache
875func (rsrcMgr *OpenOltResourceMgr) RemoveGemFromOnuGemInfo(ctx context.Context, intfID uint32, onuID uint32, gemPort uint32) error {
876 onugem, err := rsrcMgr.GetOnuGemInfo(ctx, intfID, onuID)
877 if err != nil || onugem == nil || onugem.SerialNumber == "" {
878 logger.Errorf(ctx, "failed to get onuifo for intfid %d", intfID)
879 return err
880 }
881 updated := false
882 if onugem.OnuID == onuID {
883 for i, gem := range onugem.GemPorts {
884 if gem == gemPort {
885 logger.Debugw(ctx, "Gem found, removing from onu gem info", log.Fields{"gem": gem})
886 onugem.GemPorts = append(onugem.GemPorts[:i], onugem.GemPorts[i+1:]...)
887 updated = true
888 break
889 }
890 }
891 } else {
892 logger.Errorw(ctx, "onu id in OnuGemInfo does not match", log.Fields{"onuID": onuID, "ponIf": intfID, "onuGemInfoOnuID": onugem.OnuID})
893 return fmt.Errorf("onu-id-in-OnuGemInfo-does-not-match-%v", onuID)
894 }
895 if updated {
896 err = rsrcMgr.AddOnuGemInfo(ctx, intfID, onuID, *onugem)
897 if err != nil {
898 logger.Error(ctx, "Failed to add onugem to kv store")
899 return err
900 }
901 } else {
902 logger.Debugw(ctx, "Gem port not found in onu gem info", log.Fields{"gem": gemPort})
903 }
904 return nil
905}
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530906
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700907//GetOnuGemInfo gets onu gem info from the kvstore per interface
908func (rsrcMgr *OpenOltResourceMgr) GetOnuGemInfo(ctx context.Context, intfID uint32, onuID uint32) (*OnuGemInfo, error) {
909 var err error
910 var Val []byte
911 var onugem OnuGemInfo
912
913 path := fmt.Sprintf(OnuGemInfoPath, intfID, onuID)
914
915 rsrcMgr.onuGemInfoLock.RLock()
916 val, ok := rsrcMgr.onuGemInfo[path]
917 rsrcMgr.onuGemInfoLock.RUnlock()
918 if ok {
919 return val, nil
920 }
921 value, err := rsrcMgr.KVStore.Get(ctx, path)
922 if err != nil {
923 logger.Errorw(ctx, "Failed to get from kv store", log.Fields{"path": path})
924 return nil, err
925 } else if value == nil {
926 logger.Debug(ctx, "No onuinfo for path", log.Fields{"path": path})
927 return nil, nil // returning nil as this could happen if there are no onus for the interface yet
928 }
929 if Val, err = kvstore.ToByte(value.Value); err != nil {
930 logger.Error(ctx, "Failed to convert to byte array")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530931 return nil, err
932 }
933
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700934 if err = json.Unmarshal(Val, &onugem); err != nil {
935 logger.Error(ctx, "Failed to unmarshall")
936 return nil, err
937 }
938 logger.Debugw(ctx, "found onugem info from path", log.Fields{"path": path, "onuGemInfo": onugem})
939 rsrcMgr.onuGemInfoLock.Lock()
940 rsrcMgr.onuGemInfo[path] = &onugem
941 rsrcMgr.onuGemInfoLock.Unlock()
942
943 return &onugem, nil
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530944}
945
Chaitrashree G S1a55b882020-02-04 17:35:35 -0500946// AddOnuGemInfo adds onu info on to the kvstore per interface
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700947func (rsrcMgr *OpenOltResourceMgr) AddOnuGemInfo(ctx context.Context, intfID uint32, onuID uint32, onuGem OnuGemInfo) error {
948
949 var Value []byte
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530950 var err error
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700951 Path := fmt.Sprintf(OnuGemInfoPath, intfID, onuID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530952
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700953 rsrcMgr.onuGemInfoLock.Lock()
954 rsrcMgr.onuGemInfo[Path] = &onuGem
955 rsrcMgr.onuGemInfoLock.Unlock()
956
957 Value, err = json.Marshal(onuGem)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530958 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700959 logger.Error(ctx, "failed to Marshal")
960 return err
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530961 }
962
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700963 if err = rsrcMgr.KVStore.Put(ctx, Path, Value); err != nil {
964 logger.Errorf(ctx, "Failed to update resource %s", Path)
965 return err
966 }
Girish Gowdrabcf98af2021-07-01 08:24:42 -0700967 logger.Debugw(ctx, "added onu gem info to store", log.Fields{"onuGemInfo": onuGem})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700968 return err
969}
970
971// DelOnuGemInfo deletes the onugem info from kvstore per ONU
972func (rsrcMgr *OpenOltResourceMgr) DelOnuGemInfo(ctx context.Context, intfID uint32, onuID uint32) error {
973 path := fmt.Sprintf(OnuGemInfoPath, intfID, onuID)
974 rsrcMgr.onuGemInfoLock.Lock()
975 logger.Debugw(ctx, "removing onu gem info", log.Fields{"onuGemInfo": rsrcMgr.onuGemInfo[path]})
976 delete(rsrcMgr.onuGemInfo, path)
977 rsrcMgr.onuGemInfoLock.Unlock()
978
979 if err := rsrcMgr.KVStore.Delete(ctx, path); err != nil {
980 logger.Errorf(ctx, "failed to remove resource %s", path)
981 return err
982 }
Andrea Campanellab83b39d2020-03-30 11:41:16 +0200983 return nil
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530984}
985
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530986// AddUniPortToOnuInfo adds uni port to the onuinfo kvstore. check if the uni is already present if not update the kv store.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700987func (rsrcMgr *OpenOltResourceMgr) AddUniPortToOnuInfo(ctx context.Context, intfID uint32, onuID uint32, portNo uint32) {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530988
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700989 onugem, err := rsrcMgr.GetOnuGemInfo(ctx, intfID, onuID)
990 if err != nil || onugem == nil || onugem.SerialNumber == "" {
991 logger.Warnf(ctx, "failed to get onuifo for intfid %d", intfID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530992 return
993 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700994
995 if onugem.OnuID == onuID {
996 for _, uni := range onugem.UniPorts {
997 if uni == portNo {
998 logger.Debugw(ctx, "uni already present in onugem info", log.Fields{"uni": portNo})
999 return
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301000 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301001 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001002 onugem.UniPorts = append(onugem.UniPorts, portNo)
1003 } else {
1004 logger.Warnw(ctx, "onu id mismatch in onu gem info", log.Fields{"intfID": intfID, "onuID": onuID})
1005 return
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301006 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001007 err = rsrcMgr.AddOnuGemInfo(ctx, intfID, onuID, *onugem)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301008 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001009 logger.Errorw(ctx, "Failed to add uni port in onugem to kv store", log.Fields{"uni": portNo})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301010 return
1011 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301012}
1013
Esin Karaman7fb80c22020-07-16 14:23:33 +00001014//UpdateGemPortForPktIn updates gemport for pkt in path to kvstore, path being intfid, onuid, portno, vlan id, priority bit
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001015func (rsrcMgr *OpenOltResourceMgr) UpdateGemPortForPktIn(ctx context.Context, pktIn PacketInInfoKey, gemPort uint32) {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301016
Esin Karaman7fb80c22020-07-16 14:23:33 +00001017 path := fmt.Sprintf(OnuPacketINPath, pktIn.IntfID, pktIn.OnuID, pktIn.LogicalPort, pktIn.VlanID, pktIn.Priority)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001018 // update cache
1019 rsrcMgr.gemPortForPacketInInfoLock.Lock()
1020 rsrcMgr.gemPortForPacketInInfo[path] = gemPort
1021 rsrcMgr.gemPortForPacketInInfoLock.Unlock()
1022
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301023 Value, err := json.Marshal(gemPort)
1024 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001025 logger.Error(ctx, "Failed to marshal data")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301026 return
1027 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001028 if err = rsrcMgr.KVStore.Put(ctx, path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001029 logger.Errorw(ctx, "Failed to put to kvstore", log.Fields{"path": path, "value": gemPort})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301030 return
1031 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001032 logger.Debugw(ctx, "added gem packet in successfully", log.Fields{"path": path, "gem": gemPort})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301033}
1034
Esin Karaman7fb80c22020-07-16 14:23:33 +00001035// GetGemPortFromOnuPktIn gets the gem port from onu pkt in path, path being intfid, onuid, portno, vlan id, priority bit
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001036func (rsrcMgr *OpenOltResourceMgr) GetGemPortFromOnuPktIn(ctx context.Context, packetInInfoKey PacketInInfoKey) (uint32, error) {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301037
1038 var Val []byte
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301039
Esin Karaman7fb80c22020-07-16 14:23:33 +00001040 path := fmt.Sprintf(OnuPacketINPath, packetInInfoKey.IntfID, packetInInfoKey.OnuID, packetInInfoKey.LogicalPort,
1041 packetInInfoKey.VlanID, packetInInfoKey.Priority)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001042 // get from cache
1043 rsrcMgr.gemPortForPacketInInfoLock.RLock()
1044 gemPort, ok := rsrcMgr.gemPortForPacketInInfo[path]
1045 rsrcMgr.gemPortForPacketInInfoLock.RUnlock()
1046 if ok {
1047 logger.Debugw(ctx, "found packein gemport from path", log.Fields{"path": path, "gem": gemPort})
1048 return gemPort, nil
1049 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301050
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001051 value, err := rsrcMgr.KVStore.Get(ctx, path)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301052 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001053 logger.Errorw(ctx, "Failed to get from kv store", log.Fields{"path": path})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301054 return uint32(0), err
1055 } else if value == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001056 logger.Debugw(ctx, "No pkt in gem found", log.Fields{"path": path})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301057 return uint32(0), nil
1058 }
1059
1060 if Val, err = kvstore.ToByte(value.Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001061 logger.Error(ctx, "Failed to convert to byte array")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301062 return uint32(0), err
1063 }
1064 if err = json.Unmarshal(Val, &gemPort); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001065 logger.Error(ctx, "Failed to unmarshall")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301066 return uint32(0), err
1067 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001068 logger.Debugw(ctx, "found packein gemport from path", log.Fields{"path": path, "gem": gemPort})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001069 // update cache
1070 rsrcMgr.gemPortForPacketInInfoLock.Lock()
1071 rsrcMgr.gemPortForPacketInInfo[path] = gemPort
1072 rsrcMgr.gemPortForPacketInInfoLock.Unlock()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301073
1074 return gemPort, nil
1075}
1076
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001077//DeletePacketInGemPortForOnu deletes the packet-in gemport for ONU
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001078func (rsrcMgr *OpenOltResourceMgr) DeletePacketInGemPortForOnu(ctx context.Context, intfID uint32, onuID uint32, logicalPort uint32) error {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001079 path := fmt.Sprintf(OnuPacketINPathPrefix, intfID, onuID, logicalPort)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001080 value, err := rsrcMgr.KVStore.List(ctx, path)
Esin Karaman7fb80c22020-07-16 14:23:33 +00001081 if err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001082 logger.Errorf(ctx, "failed-to-read-value-from-path-%s", path)
1083 return errors.New("failed-to-read-value-from-path-" + path)
Esin Karaman7fb80c22020-07-16 14:23:33 +00001084 }
Esin Karaman7fb80c22020-07-16 14:23:33 +00001085
1086 //remove them one by one
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001087 for key := range value {
serkant.uluderya4f5ed592020-12-17 20:57:59 +03001088 // Remove the PathPrefix from the path on KV key.
1089 // gemPortForPacketInInfo cache uses OnuPacketINPath as the key
1090 stringToBeReplaced := rsrcMgr.KVStore.PathPrefix + "/"
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001091 replacedWith := ""
1092 key = strings.Replace(key, stringToBeReplaced, replacedWith, 1)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001093 // update cache
1094 rsrcMgr.gemPortForPacketInInfoLock.Lock()
1095 delete(rsrcMgr.gemPortForPacketInInfo, key)
1096 rsrcMgr.gemPortForPacketInInfoLock.Unlock()
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001097
serkant.uluderya4f5ed592020-12-17 20:57:59 +03001098 logger.Debugw(ctx, "removed-key-from-packetin-gem-port-cache", log.Fields{"key": key, "cache-len": len(rsrcMgr.gemPortForPacketInInfo)})
1099 }
1100
1101 logger.Debugw(ctx, "delete-packetin-gem-port", log.Fields{"realPath": path})
1102 if err := rsrcMgr.KVStore.DeleteWithPrefix(ctx, path); err != nil {
1103 logger.Errorf(ctx, "failed-to-remove-resource-%s", path)
1104 return err
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301105 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001106
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301107 return nil
1108}
1109
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001110//GetFlowIDsForGem gets the list of FlowIDs for the given gemport
1111func (rsrcMgr *OpenOltResourceMgr) GetFlowIDsForGem(ctx context.Context, intf uint32, gem uint32) ([]uint64, error) {
1112 path := fmt.Sprintf(FlowIDsForGem, intf, gem)
1113
1114 // get from cache
1115 rsrcMgr.flowIDsForGemLock.RLock()
1116 flowIDs, ok := rsrcMgr.flowIDsForGem[gem]
1117 rsrcMgr.flowIDsForGemLock.RUnlock()
1118 if ok {
1119 return flowIDs, nil
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301120 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301121
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001122 value, err := rsrcMgr.KVStore.Get(ctx, path)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301123 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001124 logger.Errorw(ctx, "Failed to get from kv store", log.Fields{"path": path})
1125 return nil, err
1126 } else if value == nil {
1127 logger.Debug(ctx, "no flow-ids found", log.Fields{"path": path})
1128 return nil, nil
1129 }
1130 Val, err := kvstore.ToByte(value.Value)
1131 if err != nil {
1132 logger.Error(ctx, "Failed to convert to byte array")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301133 return nil, err
1134 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301135
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001136 if err = json.Unmarshal(Val, &flowIDs); err != nil {
1137 logger.Error(ctx, "Failed to unmarshall")
1138 return nil, err
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301139 }
1140
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001141 // update cache
1142 rsrcMgr.flowIDsForGemLock.Lock()
1143 rsrcMgr.flowIDsForGem[gem] = flowIDs
1144 rsrcMgr.flowIDsForGemLock.Unlock()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301145
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001146 return flowIDs, nil
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301147}
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301148
1149//UpdateFlowIDsForGem updates flow id per gemport
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001150func (rsrcMgr *OpenOltResourceMgr) UpdateFlowIDsForGem(ctx context.Context, intf uint32, gem uint32, flowIDs []uint64) error {
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301151 var val []byte
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001152 path := fmt.Sprintf(FlowIDsForGem, intf, gem)
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301153
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001154 // update cache
1155 rsrcMgr.flowIDsForGemLock.Lock()
1156 rsrcMgr.flowIDsForGem[gem] = flowIDs
1157 rsrcMgr.flowIDsForGemLock.Unlock()
1158
1159 if flowIDs == nil {
1160 return nil
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301161 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001162 val, err := json.Marshal(flowIDs)
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301163 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001164 logger.Error(ctx, "Failed to marshal data", log.Fields{"err": err})
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301165 return err
1166 }
Girish Gowdrab77ded92020-04-08 11:45:05 -07001167
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001168 if err = rsrcMgr.KVStore.Put(ctx, path, val); err != nil {
1169 logger.Errorw(ctx, "Failed to put to kvstore", log.Fields{"err": err, "path": path, "value": val})
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301170 return err
1171 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001172 logger.Debugw(ctx, "added flowid list for gem to kv successfully", log.Fields{"path": path, "flowidlist": flowIDs})
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301173 return nil
1174}
1175
1176//DeleteFlowIDsForGem deletes the flowID list entry per gem from kvstore.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001177func (rsrcMgr *OpenOltResourceMgr) DeleteFlowIDsForGem(ctx context.Context, intf uint32, gem uint32) {
1178 path := fmt.Sprintf(FlowIDsForGem, intf, gem)
1179 // update cache
1180 rsrcMgr.flowIDsForGemLock.Lock()
1181 delete(rsrcMgr.flowIDsForGem, gem)
1182 rsrcMgr.flowIDsForGemLock.Unlock()
1183 if err := rsrcMgr.KVStore.Delete(ctx, path); err != nil {
1184 logger.Errorw(ctx, "Failed to delete from kvstore", log.Fields{"err": err, "path": path})
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301185 }
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301186}
Esin Karamanccb714b2019-11-29 15:02:06 +00001187
1188//GetMcastQueuePerInterfaceMap gets multicast queue info per pon interface
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001189func (rsrcMgr *OpenOltResourceMgr) GetMcastQueuePerInterfaceMap(ctx context.Context) (map[uint32][]uint32, error) {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001190 path := McastQueuesForIntf
Esin Karamanccb714b2019-11-29 15:02:06 +00001191 var val []byte
1192
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001193 rsrcMgr.mcastQueueForIntfLock.RLock()
1194 if rsrcMgr.mcastQueueForIntfLoadedFromKvStore {
1195 rsrcMgr.mcastQueueForIntfLock.RUnlock()
1196 return rsrcMgr.mcastQueueForIntf, nil
1197 }
1198 rsrcMgr.mcastQueueForIntfLock.RUnlock()
1199
1200 kvPair, err := rsrcMgr.KVStore.Get(ctx, path)
Esin Karamanccb714b2019-11-29 15:02:06 +00001201 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001202 logger.Error(ctx, "failed to get data from kv store")
Esin Karamanccb714b2019-11-29 15:02:06 +00001203 return nil, err
1204 }
1205 if kvPair != nil && kvPair.Value != nil {
1206 if val, err = kvstore.ToByte(kvPair.Value); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001207 logger.Error(ctx, "Failed to convert to byte array ", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001208 return nil, err
1209 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001210 rsrcMgr.mcastQueueForIntfLock.Lock()
1211 defer rsrcMgr.mcastQueueForIntfLock.Unlock()
1212 if err = json.Unmarshal(val, &rsrcMgr.mcastQueueForIntf); err != nil {
1213 logger.Error(ctx, "Failed to unmarshall ", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001214 return nil, err
1215 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001216 rsrcMgr.mcastQueueForIntfLoadedFromKvStore = true
Esin Karamanccb714b2019-11-29 15:02:06 +00001217 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001218 return rsrcMgr.mcastQueueForIntf, nil
Esin Karamanccb714b2019-11-29 15:02:06 +00001219}
1220
1221//AddMcastQueueForIntf adds multicast queue for pon interface
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001222func (rsrcMgr *OpenOltResourceMgr) AddMcastQueueForIntf(ctx context.Context, intf uint32, gem uint32, servicePriority uint32) error {
Esin Karamanccb714b2019-11-29 15:02:06 +00001223 var val []byte
Kent Hagermane6ff1012020-07-14 15:07:53 -04001224 path := McastQueuesForIntf
Esin Karamanccb714b2019-11-29 15:02:06 +00001225
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001226 // Load local cache from kv store the first time
1227 rsrcMgr.mcastQueueForIntfLock.RLock()
1228 if !rsrcMgr.mcastQueueForIntfLoadedFromKvStore {
1229 rsrcMgr.mcastQueueForIntfLock.RUnlock()
1230 _, err := rsrcMgr.GetMcastQueuePerInterfaceMap(ctx)
1231 if err != nil {
1232 logger.Errorw(ctx, "Failed to get multicast queue info for interface", log.Fields{"err": err, "intf": intf})
1233 return err
1234 }
1235 } else {
1236 rsrcMgr.mcastQueueForIntfLock.RUnlock()
1237 }
1238
1239 // Update KV store
1240 rsrcMgr.mcastQueueForIntfLock.Lock()
1241 rsrcMgr.mcastQueueForIntf[intf] = []uint32{gem, servicePriority}
1242 val, err := json.Marshal(rsrcMgr.mcastQueueForIntf)
Esin Karamanccb714b2019-11-29 15:02:06 +00001243 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001244 rsrcMgr.mcastQueueForIntfLock.Unlock()
1245 logger.Errorw(ctx, "Failed to marshal data", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001246 return err
1247 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001248 rsrcMgr.mcastQueueForIntfLock.Unlock()
1249
1250 if err = rsrcMgr.KVStore.Put(ctx, path, val); err != nil {
1251 logger.Errorw(ctx, "Failed to put to kvstore", log.Fields{"err": err, "path": path, "value": val})
Esin Karamanccb714b2019-11-29 15:02:06 +00001252 return err
1253 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001254 logger.Debugw(ctx, "added multicast queue info to KV store successfully", log.Fields{"path": path, "interfaceId": intf, "gem": gem, "svcPrior": servicePriority})
Esin Karamanccb714b2019-11-29 15:02:06 +00001255 return nil
1256}
1257
1258//AddFlowGroupToKVStore adds flow group into KV store
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001259func (rsrcMgr *OpenOltResourceMgr) AddFlowGroupToKVStore(ctx context.Context, groupEntry *ofp.OfpGroupEntry, cached bool) error {
Esin Karamanccb714b2019-11-29 15:02:06 +00001260 var Value []byte
1261 var err error
1262 var path string
1263 if cached {
1264 path = fmt.Sprintf(FlowGroupCached, groupEntry.Desc.GroupId)
1265 } else {
1266 path = fmt.Sprintf(FlowGroup, groupEntry.Desc.GroupId)
1267 }
1268 //build group info object
1269 var outPorts []uint32
1270 for _, ofBucket := range groupEntry.Desc.Buckets {
1271 for _, ofAction := range ofBucket.Actions {
1272 if ofAction.Type == ofp.OfpActionType_OFPAT_OUTPUT {
1273 outPorts = append(outPorts, ofAction.GetOutput().Port)
1274 }
1275 }
1276 }
1277 groupInfo := GroupInfo{
1278 GroupID: groupEntry.Desc.GroupId,
1279 OutPorts: outPorts,
1280 }
1281
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001282 rsrcMgr.groupInfoLock.Lock()
1283 rsrcMgr.groupInfo[path] = &groupInfo
1284 rsrcMgr.groupInfoLock.Unlock()
1285
Esin Karamanccb714b2019-11-29 15:02:06 +00001286 Value, err = json.Marshal(groupInfo)
1287
1288 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001289 logger.Error(ctx, "failed to Marshal flow group object")
Esin Karamanccb714b2019-11-29 15:02:06 +00001290 return err
1291 }
1292
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001293 if err = rsrcMgr.KVStore.Put(ctx, path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001294 logger.Errorf(ctx, "Failed to update resource %s", path)
Esin Karamanccb714b2019-11-29 15:02:06 +00001295 return err
1296 }
1297 return nil
1298}
1299
1300//RemoveFlowGroupFromKVStore removes flow group from KV store
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001301func (rsrcMgr *OpenOltResourceMgr) RemoveFlowGroupFromKVStore(ctx context.Context, groupID uint32, cached bool) error {
Esin Karamanccb714b2019-11-29 15:02:06 +00001302 var path string
1303 if cached {
1304 path = fmt.Sprintf(FlowGroupCached, groupID)
1305 } else {
1306 path = fmt.Sprintf(FlowGroup, groupID)
1307 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001308 rsrcMgr.groupInfoLock.Lock()
1309 delete(rsrcMgr.groupInfo, path)
1310 rsrcMgr.groupInfoLock.Unlock()
1311
1312 if err := rsrcMgr.KVStore.Delete(ctx, path); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001313 logger.Errorf(ctx, "Failed to remove resource %s due to %s", path, err)
Esin Karamand519bbf2020-07-01 11:16:03 +00001314 return err
Esin Karamanccb714b2019-11-29 15:02:06 +00001315 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001316 return nil
Esin Karamanccb714b2019-11-29 15:02:06 +00001317}
1318
1319//GetFlowGroupFromKVStore fetches flow group from the KV store. Returns (false, {} error) if any problem occurs during
1320//fetching the data. Returns (true, groupInfo, nil) if the group is fetched successfully.
1321// Returns (false, {}, nil) if the group does not exists in the KV store.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001322func (rsrcMgr *OpenOltResourceMgr) GetFlowGroupFromKVStore(ctx context.Context, groupID uint32, cached bool) (bool, GroupInfo, error) {
Esin Karamanccb714b2019-11-29 15:02:06 +00001323 var groupInfo GroupInfo
1324 var path string
1325 if cached {
1326 path = fmt.Sprintf(FlowGroupCached, groupID)
1327 } else {
1328 path = fmt.Sprintf(FlowGroup, groupID)
1329 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001330
1331 // read from cache
1332 rsrcMgr.groupInfoLock.RLock()
1333 gi, ok := rsrcMgr.groupInfo[path]
1334 rsrcMgr.groupInfoLock.RUnlock()
1335 if ok {
1336 return true, *gi, nil
1337 }
1338
1339 kvPair, err := rsrcMgr.KVStore.Get(ctx, path)
Esin Karamanccb714b2019-11-29 15:02:06 +00001340 if err != nil {
1341 return false, groupInfo, err
1342 }
1343 if kvPair != nil && kvPair.Value != nil {
1344 Val, err := kvstore.ToByte(kvPair.Value)
1345 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001346 logger.Errorw(ctx, "Failed to convert flow group into byte array", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001347 return false, groupInfo, err
1348 }
1349 if err = json.Unmarshal(Val, &groupInfo); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001350 logger.Errorw(ctx, "Failed to unmarshal", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001351 return false, groupInfo, err
1352 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001353 // update cache
1354 rsrcMgr.groupInfoLock.Lock()
1355 rsrcMgr.groupInfo[path] = &groupInfo
1356 rsrcMgr.groupInfoLock.Unlock()
1357
Esin Karamanccb714b2019-11-29 15:02:06 +00001358 return true, groupInfo, nil
1359 }
1360 return false, groupInfo, nil
1361}
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001362
1363// toByte converts an interface value to a []byte. The interface should either be of
1364// a string type or []byte. Otherwise, an error is returned.
1365func toByte(value interface{}) ([]byte, error) {
1366 switch t := value.(type) {
1367 case []byte:
1368 return value.([]byte), nil
1369 case string:
1370 return []byte(value.(string)), nil
1371 default:
1372 return nil, fmt.Errorf("unexpected-type-%T", t)
1373 }
1374}