blob: f5b3f12f39cc8aa663a005739439a5c3f7c4b4a9 [file] [log] [blame]
Abhilash S.L7f17e402019-03-15 17:40:41 +05301/*
Joey Armstrong11f5a572024-01-12 19:11:32 -05002 * Copyright 2019-2024 Open Networking Foundation (ONF) and the ONF Contributors
Abhilash S.L7f17e402019-03-15 17:40:41 +05303
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
Joey Armstrong3f0e2422023-07-05 18:25:41 -040017// 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"
Akash Kankanala041a2122024-10-16 15:49:22 +053046 // MeterIDPathSuffix - <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
Gamze Abakafee36392019-10-03 11:17:24 +000047 MeterIDPathSuffix = "{%d,%d,%d}/{%d}/meter_id/{%s}"
Girish Gowdra950326e2021-11-05 12:43:24 -070048
49 // OnuPacketInPathPrefix - path prefix where ONU packet-in vlanID/PCP is stored
Girish Gowdraa09aeab2020-09-14 16:30:52 -070050 //format: onu_packetin/{<intfid>,<onuid>,<logicalport>}
Girish Gowdra950326e2021-11-05 12:43:24 -070051 OnuPacketInPathPrefix = "onu_packetin/{%d,%d,%d}"
52 // OnuPacketInPath path on the kvstore to store packetin gemport,which will be used for packetin, packetout
Girish Gowdraa09aeab2020-09-14 16:30:52 -070053 //format: onu_packetin/{<intfid>,<onuid>,<logicalport>}/{<vlanId>,<priority>}
Girish Gowdra950326e2021-11-05 12:43:24 -070054 OnuPacketInPath = OnuPacketInPathPrefix + "/{%d,%d}"
55
Akash Kankanala041a2122024-10-16 15:49:22 +053056 // FlowIDsForGemPathPrefix format: flowids_for_gem/<intfid>
Girish Gowdra950326e2021-11-05 12:43:24 -070057 FlowIDsForGemPathPrefix = "flowids_per_gem/{%d}"
Akash Kankanala041a2122024-10-16 15:49:22 +053058 // FlowIDsForGem flowids_for_gem/<intfid>/<gemport-id>
Girish Gowdra950326e2021-11-05 12:43:24 -070059 FlowIDsForGem = FlowIDsForGemPathPrefix + "/{%d}"
60
Akash Kankanala041a2122024-10-16 15:49:22 +053061 // McastQueuesForIntf multicast queues for pon interfaces
Esin Karamanccb714b2019-11-29 15:02:06 +000062 McastQueuesForIntf = "mcast_qs_for_int"
Akash Kankanala041a2122024-10-16 15:49:22 +053063 // FlowGroup flow_groups/<flow_group_id>
Esin Karamanccb714b2019-11-29 15:02:06 +000064 // A group is stored under this path on the KV store after it has been installed to the device.
65 // It should also be deleted after it has been removed from the device accordingly.
66 FlowGroup = "flow_groups/{%d}"
Akash Kankanala041a2122024-10-16 15:49:22 +053067 // FlowGroupCached flow_groups_cached/<flow_group_id>
Esin Karamanccb714b2019-11-29 15:02:06 +000068 // When a group add request received, we create the group without setting any members to it since we cannot
69 // set any members to a group until it is associated with a multicast flow. It is a BAL limitation.
70 // When the related multicast flow has been created we perform set members operation for the group.
71 // That is why we need to keep the members of a group until the multicast flow creation request comes.
72 // We preserve the groups under "FlowGroupsCached" directory in the KV store temporarily. Having set members,
73 // we remove the group from the cached group store.
74 FlowGroupCached = "flow_groups_cached/{%d}"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070075
Akash Kankanala041a2122024-10-16 15:49:22 +053076 // FlowIDPath - Path on the KV store for storing list of Flow IDs for a given subscriber
Girish Gowdraa09aeab2020-09-14 16:30:52 -070077 //Format: BasePathKvStore/<(pon_intf_id, onu_id, uni_id)>/flow_ids
78 FlowIDPath = "{%s}/flow_ids"
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -070079
Akash Kankanala041a2122024-10-16 15:49:22 +053080 // OnuGemInfoPathPathPrefix format: onu_gem_info/<intfid>
Girish Gowdra950326e2021-11-05 12:43:24 -070081 OnuGemInfoPathPathPrefix = "onu_gem_info/{%d}"
Akash Kankanala041a2122024-10-16 15:49:22 +053082 // OnuGemInfoPath is path on the kvstore to store onugem info map
Girish Gowdra950326e2021-11-05 12:43:24 -070083 //format: onu_gem_info/<intfid>/<onu_id>
84 OnuGemInfoPath = OnuGemInfoPathPathPrefix + "/{%d}"
yasin saplid0566272021-12-21 09:10:30 +000085
86 // NNI uint32 version of -1 which represents the NNI port
87 NNI = 4294967295
salmansiddiqui7ac62132019-08-22 03:58:50 +000088)
Abhilash S.L7f17e402019-03-15 17:40:41 +053089
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070090// FlowInfo holds the flow information
Abhilash S.L8ee90712019-04-29 16:24:22 +053091type FlowInfo struct {
Girish Gowdraa09aeab2020-09-14 16:30:52 -070092 Flow *openolt.Flow
93 IsSymmtricFlow bool
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +053094}
95
96// OnuGemInfo holds onu information along with gem port list and uni port list
97type OnuGemInfo struct {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +053098 SerialNumber string
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +053099 GemPorts []uint32
100 UniPorts []uint32
Akash Kankanala041a2122024-10-16 15:49:22 +0530101 OnuID uint32
102 IntfID uint32
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530103}
104
105// PacketInInfoKey is the key for packet in gemport
106type PacketInInfoKey struct {
107 IntfID uint32
108 OnuID uint32
109 LogicalPort uint32
Esin Karaman7fb80c22020-07-16 14:23:33 +0000110 VlanID uint16
111 Priority uint8
Abhilash S.L8ee90712019-04-29 16:24:22 +0530112}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700113
Esin Karamanccb714b2019-11-29 15:02:06 +0000114// GroupInfo holds group information
115type GroupInfo struct {
Esin Karamanccb714b2019-11-29 15:02:06 +0000116 OutPorts []uint32
Akash Kankanala041a2122024-10-16 15:49:22 +0530117 GroupID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +0000118}
119
Girish Gowdraa482f272021-03-24 23:04:19 -0700120// MeterInfo store meter information at path <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
121type MeterInfo struct {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700122 RefCnt uint8 // number of flow references for this meter. When RefCnt is 0, the MeterInfo should be deleted.
123 MeterID uint32
Girish Gowdraa482f272021-03-24 23:04:19 -0700124}
125
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700126// OpenOltResourceMgr holds resource related information as provided below for each field
Abhilash S.L7f17e402019-03-15 17:40:41 +0530127type OpenOltResourceMgr struct {
Akash Kankanala041a2122024-10-16 15:49:22 +0530128 TechprofileRef tp.TechProfileIf
129 KVStore *db.Backend // backend kv store connection handle
130 DevInfo *openolt.DeviceInfo // device information
Girish Gowdru0c588b22019-04-23 23:24:56 -0400131 // array of pon resource managers per interface technology
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700132 PonRsrMgr *ponrmgr.PONResourceManager
Girish Gowdra38d533d2020-03-30 20:38:51 -0700133
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700134 // Local maps used for write-through-cache - start
Akash Kankanala041a2122024-10-16 15:49:22 +0530135 allocIDsForOnu map[string][]uint32
136
137 gemPortIDsForOnu map[string][]uint32
138
139 techProfileIDsForOnu map[string][]uint32
140
141 meterInfoForOnu map[string]*MeterInfo
142
143 onuGemInfo map[string]*OnuGemInfo
144
145 gemPortForPacketInInfo map[string]uint32
146
147 flowIDsForGem map[uint32][]uint64
148
149 mcastQueueForIntf map[uint32][]uint32
150
151 groupInfo map[string]*GroupInfo
152 DeviceID string // OLT device id
153 Address string // Host and port of the kv store to connect to
154 Args string // args
155 DeviceType string
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700156 allocIDsForOnuLock sync.RWMutex
157
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700158 gemPortIDsForOnuLock sync.RWMutex
159
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700160 techProfileIDsForOnuLock sync.RWMutex
161
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700162 meterInfoForOnuLock sync.RWMutex
163
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700164 onuGemInfoLock sync.RWMutex
165
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700166 gemPortForPacketInInfoLock sync.RWMutex
167
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700168 flowIDsForGemLock sync.RWMutex
169
Akash Kankanala041a2122024-10-16 15:49:22 +0530170 mcastQueueForIntfLock sync.RWMutex
171 groupInfoLock sync.RWMutex
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700172 // Local maps used for write-through-cache - end
Girish Gowdra4c3d4602021-07-22 16:33:37 -0700173
Akash Kankanala041a2122024-10-16 15:49:22 +0530174 PonIntfID uint32
175 mcastQueueForIntfLoadedFromKvStore bool
Abhilash S.L7f17e402019-03-15 17:40:41 +0530176}
177
Neha Sharma96b7bf22020-06-15 10:37:32 +0000178func newKVClient(ctx context.Context, storeType string, address string, timeout time.Duration) (kvstore.Client, error) {
179 logger.Infow(ctx, "kv-store-type", log.Fields{"store": storeType})
Girish Gowdru0c588b22019-04-23 23:24:56 -0400180 switch storeType {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400181 case "etcd":
Neha Sharma96b7bf22020-06-15 10:37:32 +0000182 return kvstore.NewEtcdClient(ctx, address, timeout, log.FatalLevel)
Abhay Kumar9bcfeb22024-07-12 09:14:25 +0530183 case "redis":
184 return kvstore.NewRedisClient(address, timeout, false)
185 case "redis-sentinel":
186 return kvstore.NewRedisClient(address, timeout, true)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400187 }
188 return nil, errors.New("unsupported-kv-store")
Abhilash S.L7f17e402019-03-15 17:40:41 +0530189}
190
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700191// SetKVClient sets the KV client and return a kv backend
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800192func SetKVClient(ctx context.Context, backend string, addr string, DeviceID string, basePathKvStore string) *db.Backend {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400193 // TODO : Make sure direct call to NewBackend is working fine with backend , currently there is some
194 // issue between kv store and backend , core is not calling NewBackend directly
Neha Sharma96b7bf22020-06-15 10:37:32 +0000195 kvClient, err := newKVClient(ctx, backend, addr, KvstoreTimeout)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400196 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000197 logger.Fatalw(ctx, "Failed to init KV client\n", log.Fields{"err": err})
Girish Gowdru0c588b22019-04-23 23:24:56 -0400198 return nil
199 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700200 // return db.NewBackend(ctx, backend, addr, KvstoreTimeout, fmt.Sprintf(BasePathKvStore, basePathKvStore, DeviceID))
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700201
sbarbaria8910ba2019-11-05 10:12:23 -0500202 kvbackend := &db.Backend{
Girish Gowdru0c588b22019-04-23 23:24:56 -0400203 Client: kvClient,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700204 StoreType: backend,
Neha Sharma3f221ae2020-04-29 19:02:12 +0000205 Address: addr,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700206 Timeout: KvstoreTimeout,
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800207 PathPrefix: fmt.Sprintf(BasePathKvStore, basePathKvStore, DeviceID)}
Abhilash S.L7f17e402019-03-15 17:40:41 +0530208
Girish Gowdru0c588b22019-04-23 23:24:56 -0400209 return kvbackend
Abhilash S.L7f17e402019-03-15 17:40:41 +0530210}
211
Holger Hildebrandt143b5be2023-02-10 08:28:15 +0000212// CloseKVClient closes open KV clients
213func (rsrcMgr *OpenOltResourceMgr) CloseKVClient(ctx context.Context) {
214 if rsrcMgr.KVStore != nil {
215 rsrcMgr.KVStore.Client.Close(ctx)
216 rsrcMgr.KVStore = nil
217 }
218 if rsrcMgr.PonRsrMgr != nil {
219 rsrcMgr.PonRsrMgr.CloseKVClient(ctx)
220 }
221}
222
Gamze Abakafee36392019-10-03 11:17:24 +0000223// NewResourceMgr init a New resource manager instance which in turn instantiates pon resource manager
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700224// instances according to technology. Initializes the default resource ranges for all
225// the resources.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700226func 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 -0400227 var ResourceMgr OpenOltResourceMgr
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700228 logger.Debugf(ctx, "Init new resource manager , ponIf: %v, address: %s, device-id: %s", PonIntfID, KVStoreAddress, deviceID)
229 ResourceMgr.PonIntfID = PonIntfID
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700230 ResourceMgr.DeviceID = deviceID
Neha Sharma3f221ae2020-04-29 19:02:12 +0000231 ResourceMgr.Address = KVStoreAddress
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700232 ResourceMgr.DeviceType = deviceType
233 ResourceMgr.DevInfo = devInfo
Abhilash S.L7f17e402019-03-15 17:40:41 +0530234
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700235 Backend := kvStoreType
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800236 ResourceMgr.KVStore = SetKVClient(ctx, Backend, ResourceMgr.Address, deviceID, basePathKvStore)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400237 if ResourceMgr.KVStore == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000238 logger.Error(ctx, "Failed to setup KV store")
Girish Gowdru0c588b22019-04-23 23:24:56 -0400239 }
Girish Gowdra38d533d2020-03-30 20:38:51 -0700240
Girish Gowdru0c588b22019-04-23 23:24:56 -0400241 // TODO self.args = registry('main').get_args()
Abhilash S.L7f17e402019-03-15 17:40:41 +0530242
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700243 // Create a separate Resource Manager instance for each range. This assumes that
Girish Gowdru0c588b22019-04-23 23:24:56 -0400244 // each technology is represented by only a single range
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700245 for _, TechRange := range devInfo.Ranges {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700246 for _, intfID := range TechRange.IntfIds {
247 if intfID == PonIntfID {
248 technology := TechRange.Technology
249 logger.Debugf(ctx, "Device info technology %s, intf-id %v", technology, PonIntfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000250
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700251 rsrMgr, err := ponrmgr.NewPONResourceManager(ctx, technology, deviceType, deviceID,
252 Backend, ResourceMgr.Address, basePathKvStore)
253 if err != nil {
254 logger.Errorf(ctx, "Failed to create pon resource manager instance for technology %s", technology)
255 return nil
256 }
257 ResourceMgr.PonRsrMgr = rsrMgr
258 // self.initialize_device_resource_range_and_pool(resource_mgr, global_resource_mgr, arange)
259 InitializeDeviceResourceRangeAndPool(ctx, rsrMgr, TechRange, devInfo)
260 if err := ResourceMgr.PonRsrMgr.InitDeviceResourcePoolForIntf(ctx, intfID); err != nil {
261 logger.Fatal(ctx, "failed-to-initialize-device-resource-pool-intf-id-%v-device-id", ResourceMgr.PonIntfID, ResourceMgr.DeviceID)
262 return nil
263 }
264 }
Girish Gowdru0c588b22019-04-23 23:24:56 -0400265 }
Girish Gowdru0c588b22019-04-23 23:24:56 -0400266 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700267
268 ResourceMgr.InitLocalCache()
yasin saplibddc2d72022-02-08 13:10:17 +0000269 if err := ResourceMgr.LoadLocalCacheFromKVStore(ctx); err != nil {
yasin sapli9e4c5092022-02-01 13:52:33 +0000270 logger.Error(ctx, "failed-to-load-local-cache-from-kvstore")
271 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000272 logger.Info(ctx, "Initialization of resource manager success!")
Girish Gowdru0c588b22019-04-23 23:24:56 -0400273 return &ResourceMgr
Abhilash S.L7f17e402019-03-15 17:40:41 +0530274}
275
Joey Armstrong3f0e2422023-07-05 18:25:41 -0400276// InitLocalCache initializes local maps used for write-through-cache
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700277func (rsrcMgr *OpenOltResourceMgr) InitLocalCache() {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700278 rsrcMgr.allocIDsForOnu = make(map[string][]uint32)
279 rsrcMgr.gemPortIDsForOnu = make(map[string][]uint32)
280 rsrcMgr.techProfileIDsForOnu = make(map[string][]uint32)
281 rsrcMgr.meterInfoForOnu = make(map[string]*MeterInfo)
282 rsrcMgr.onuGemInfo = make(map[string]*OnuGemInfo)
283 rsrcMgr.gemPortForPacketInInfo = make(map[string]uint32)
284 rsrcMgr.flowIDsForGem = make(map[uint32][]uint64)
285 rsrcMgr.mcastQueueForIntf = make(map[uint32][]uint32)
286 rsrcMgr.groupInfo = make(map[string]*GroupInfo)
287}
288
Joey Armstrong3f0e2422023-07-05 18:25:41 -0400289// LoadLocalCacheFromKVStore loads local maps
yasin saplibddc2d72022-02-08 13:10:17 +0000290func (rsrcMgr *OpenOltResourceMgr) LoadLocalCacheFromKVStore(ctx context.Context) error {
Akash Kankanala041a2122024-10-16 15:49:22 +0530291 // List all the keys for OnuGemInfo
yasin saplibddc2d72022-02-08 13:10:17 +0000292 prefixPath := fmt.Sprintf(OnuGemInfoPathPathPrefix, rsrcMgr.PonIntfID)
yasin sapli9e4c5092022-02-01 13:52:33 +0000293 keys, err := rsrcMgr.KVStore.List(ctx, prefixPath)
294 logger.Debug(ctx, "load-local-cache-from-KV-store-started")
295 if err != nil {
296 logger.Errorf(ctx, "failed-to-list-keys-from-path-%s", prefixPath)
297 return err
298 }
299 for path := range keys {
300 var Val []byte
301 var onugem OnuGemInfo
302 // Get rid of the path prefix
303 stringToBeReplaced := rsrcMgr.KVStore.PathPrefix + "/"
304 replacedWith := ""
305 path = strings.Replace(path, stringToBeReplaced, replacedWith, 1)
306
307 value, err := rsrcMgr.KVStore.Get(ctx, path)
308 if err != nil {
309 logger.Errorw(ctx, "failed-to-get-from-kv-store", log.Fields{"path": path})
310 return err
311 } else if value == nil {
312 logger.Debug(ctx, "no-onugeminfo-for-path", log.Fields{"path": path})
313 continue
314 }
315 if Val, err = kvstore.ToByte(value.Value); err != nil {
316 logger.Error(ctx, "failed-to-covert-to-byte-array")
317 return err
318 }
319 if err = json.Unmarshal(Val, &onugem); err != nil {
320 logger.Error(ctx, "failed-to-unmarshall")
321 return err
322 }
323 logger.Debugw(ctx, "found-onugeminfo-from-path", log.Fields{"path": path, "onuGemInfo": onugem})
324
325 rsrcMgr.onuGemInfoLock.Lock()
326 rsrcMgr.onuGemInfo[path] = &onugem
327 rsrcMgr.onuGemInfoLock.Unlock()
yasin sapli9e4c5092022-02-01 13:52:33 +0000328 }
329 logger.Debug(ctx, "load-local-cache-from-KV-store-finished")
330 return nil
331}
332
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700333// InitializeDeviceResourceRangeAndPool initializes the resource range pool according to the sharing type, then apply
334// device specific information. If KV doesn't exist
335// or is broader than the device, the device's information will
336// dictate the range limits
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700337func InitializeDeviceResourceRangeAndPool(ctx context.Context, ponRMgr *ponrmgr.PONResourceManager,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700338 techRange *openolt.DeviceInfo_DeviceResourceRanges, devInfo *openolt.DeviceInfo) {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700339 // var ONUIDShared, AllocIDShared, GEMPortIDShared openolt.DeviceInfo_DeviceResourceRanges_Pool_SharingType
340 var ONUIDStart, ONUIDEnd, AllocIDStart, AllocIDEnd, GEMPortIDStart, GEMPortIDEnd uint32
341 var ONUIDShared, AllocIDShared, GEMPortIDShared, FlowIDShared uint32
342
343 // The below variables are just dummy and needed to pass as arguments to InitDefaultPONResourceRanges function.
344 // The openolt adapter does not need flowIDs to be managed as it is managed on the OLT device
345 // The UNI IDs are dynamically generated by openonu adapter for every discovered UNI.
346 var flowIDDummyStart, flowIDDummyEnd uint32 = 1, 2
347 var uniIDDummyStart, uniIDDummyEnd uint32 = 0, 1
Abhilash S.L7f17e402019-03-15 17:40:41 +0530348
Girish Gowdru0c588b22019-04-23 23:24:56 -0400349 // init the resource range pool according to the sharing type
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700350 logger.Debugw(ctx, "Device info init", log.Fields{"technology": techRange.Technology,
351 "onu_id_start": ONUIDStart, "onu_id_end": ONUIDEnd,
352 "alloc_id_start": AllocIDStart, "alloc_id_end": AllocIDEnd,
353 "gemport_id_start": GEMPortIDStart, "gemport_id_end": GEMPortIDEnd,
354 "intf_ids": techRange.IntfIds,
355 })
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700356 for _, RangePool := range techRange.Pools {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700357 // FIXME: Remove hardcoding
mgouda86543582025-10-29 20:58:16 +0530358 switch RangePool.Type {
359 case openolt.DeviceInfo_DeviceResourceRanges_Pool_ONU_ID:
Girish Gowdru0c588b22019-04-23 23:24:56 -0400360 ONUIDStart = RangePool.Start
361 ONUIDEnd = RangePool.End
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700362 ONUIDShared = uint32(RangePool.Sharing)
mgouda86543582025-10-29 20:58:16 +0530363 case openolt.DeviceInfo_DeviceResourceRanges_Pool_ALLOC_ID:
Girish Gowdru0c588b22019-04-23 23:24:56 -0400364 AllocIDStart = RangePool.Start
365 AllocIDEnd = RangePool.End
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700366 AllocIDShared = uint32(RangePool.Sharing)
mgouda86543582025-10-29 20:58:16 +0530367 case openolt.DeviceInfo_DeviceResourceRanges_Pool_GEMPORT_ID:
Girish Gowdru0c588b22019-04-23 23:24:56 -0400368 GEMPortIDStart = RangePool.Start
369 GEMPortIDEnd = RangePool.End
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700370 GEMPortIDShared = uint32(RangePool.Sharing)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400371 }
372 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530373
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700374 ponRMgr.InitDefaultPONResourceRanges(ctx, ONUIDStart, ONUIDEnd, ONUIDShared,
375 AllocIDStart, AllocIDEnd, AllocIDShared,
376 GEMPortIDStart, GEMPortIDEnd, GEMPortIDShared,
377 flowIDDummyStart, flowIDDummyEnd, FlowIDShared, uniIDDummyStart, uniIDDummyEnd,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700378 devInfo.PonPorts, techRange.IntfIds)
Abhilash S.L7f17e402019-03-15 17:40:41 +0530379}
380
Devmalya Paul495b94a2019-08-27 19:42:00 -0400381// Delete clears used resources for the particular olt device being deleted
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700382func (rsrcMgr *OpenOltResourceMgr) Delete(ctx context.Context, intfID uint32) error {
383 if err := rsrcMgr.PonRsrMgr.ClearDeviceResourcePoolForIntf(ctx, intfID); err != nil {
384 logger.Debug(ctx, "Failed to clear device resource pool")
385 return err
Devmalya Paul495b94a2019-08-27 19:42:00 -0400386 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000387 logger.Debug(ctx, "Cleared device resource pool")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400388 return nil
389}
Abhilash S.L7f17e402019-03-15 17:40:41 +0530390
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700391// GetONUID returns the available onuID for the given pon-port
yasin saplibddc2d72022-02-08 13:10:17 +0000392func (rsrcMgr *OpenOltResourceMgr) GetONUID(ctx context.Context) (uint32, error) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400393 // Get ONU id for a provided pon interface ID.
yasin saplibddc2d72022-02-08 13:10:17 +0000394 onuID, err := rsrcMgr.TechprofileRef.GetResourceID(ctx, rsrcMgr.PonIntfID,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400395 ponrmgr.ONU_ID, 1)
396 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000397 logger.Errorf(ctx, "Failed to get resource for interface %d for type %s",
yasin saplibddc2d72022-02-08 13:10:17 +0000398 rsrcMgr.PonIntfID, ponrmgr.ONU_ID)
cbabuabf02352019-10-15 13:14:56 +0200399 return 0, err
Girish Gowdru0c588b22019-04-23 23:24:56 -0400400 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700401 if len(onuID) > 0 {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700402 return onuID[0], err
Girish Gowdru0c588b22019-04-23 23:24:56 -0400403 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530404
Girish Gowdra950326e2021-11-05 12:43:24 -0700405 return 0, fmt.Errorf("no-onu-id-allocated")
Abhilash S.L8ee90712019-04-29 16:24:22 +0530406}
407
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700408// UpdateAllocIdsForOnu updates alloc ids in kv store for a given pon interface id, onu id and uni id
yasin saplibddc2d72022-02-08 13:10:17 +0000409func (rsrcMgr *OpenOltResourceMgr) UpdateAllocIdsForOnu(ctx context.Context, onuID uint32, uniID uint32, allocIDs []uint32) error {
yasin saplibddc2d72022-02-08 13:10:17 +0000410 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", rsrcMgr.PonIntfID, onuID, uniID)
Gamze Abaka745ccb72021-11-18 11:29:58 +0000411
412 // Note: in case the write to DB fails there could be inconsistent data between cache and db.
413 // Although this is highly unlikely with DB retries in place, this is something we have to deal with in the next release
414 if err := rsrcMgr.PonRsrMgr.UpdateAllocIdsForOnu(ctx, intfOnuIDuniID, allocIDs); err != nil {
415 logger.Errorw(ctx, "Failed to update alloc ids for onu", log.Fields{"err": err})
416 return err
417 }
418
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700419 // update cache
420 rsrcMgr.allocIDsForOnuLock.Lock()
421 rsrcMgr.allocIDsForOnu[intfOnuIDuniID] = allocIDs
422 rsrcMgr.allocIDsForOnuLock.Unlock()
Gamze Abaka745ccb72021-11-18 11:29:58 +0000423 return nil
Abhilash S.L7f17e402019-03-15 17:40:41 +0530424}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700425
426// GetCurrentGEMPortIDsForOnu returns gem ports for given pon interface , onu id and uni id
Akash Kankanala041a2122024-10-16 15:49:22 +0530427func (rsrcMgr *OpenOltResourceMgr) GetCurrentGEMPortIDsForOnu(ctx context.Context, onuID uint32, uniID uint32) []uint32 {
yasin saplibddc2d72022-02-08 13:10:17 +0000428 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", rsrcMgr.PonIntfID, onuID, uniID)
Abhilash S.L7f17e402019-03-15 17:40:41 +0530429
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700430 // fetch from cache
431 rsrcMgr.gemPortIDsForOnuLock.RLock()
432 gemIDs, ok := rsrcMgr.gemPortIDsForOnu[intfOnuIDuniID]
433 rsrcMgr.gemPortIDsForOnuLock.RUnlock()
434 if ok {
435 return gemIDs
436 }
437 /* Get gem ports for given pon interface , onu id and uni id. */
438 gemIDs = rsrcMgr.PonRsrMgr.GetCurrentGEMPortIDsForOnu(ctx, intfOnuIDuniID)
439
440 // update cache
441 rsrcMgr.gemPortIDsForOnuLock.Lock()
442 rsrcMgr.gemPortIDsForOnu[intfOnuIDuniID] = gemIDs
443 rsrcMgr.gemPortIDsForOnuLock.Unlock()
444
445 return gemIDs
Abhilash S.L7f17e402019-03-15 17:40:41 +0530446}
447
Gamze Abakafee36392019-10-03 11:17:24 +0000448// GetCurrentAllocIDsForOnu returns alloc ids for given pon interface and onu id
yasin saplibddc2d72022-02-08 13:10:17 +0000449func (rsrcMgr *OpenOltResourceMgr) GetCurrentAllocIDsForOnu(ctx context.Context, onuID uint32, uniID uint32) []uint32 {
yasin saplibddc2d72022-02-08 13:10:17 +0000450 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", rsrcMgr.PonIntfID, onuID, uniID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700451 // fetch from cache
452 rsrcMgr.allocIDsForOnuLock.RLock()
453 allocIDs, ok := rsrcMgr.allocIDsForOnu[intfOnuIDuniID]
454 rsrcMgr.allocIDsForOnuLock.RUnlock()
455 if ok {
456 return allocIDs
Girish Gowdru0c588b22019-04-23 23:24:56 -0400457 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700458 allocIDs = rsrcMgr.PonRsrMgr.GetCurrentAllocIDForOnu(ctx, intfOnuIDuniID)
459
460 // update cache
461 rsrcMgr.allocIDsForOnuLock.Lock()
462 rsrcMgr.allocIDsForOnu[intfOnuIDuniID] = allocIDs
463 rsrcMgr.allocIDsForOnuLock.Unlock()
464
465 return allocIDs
Gamze Abakafee36392019-10-03 11:17:24 +0000466}
467
468// RemoveAllocIDForOnu removes the alloc id for given pon interface, onu id, uni id and alloc id
yasin saplibddc2d72022-02-08 13:10:17 +0000469func (rsrcMgr *OpenOltResourceMgr) RemoveAllocIDForOnu(ctx context.Context, onuID uint32, uniID uint32, allocID uint32) {
470 allocIDs := rsrcMgr.GetCurrentAllocIDsForOnu(ctx, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000471 for i := 0; i < len(allocIDs); i++ {
472 if allocIDs[i] == allocID {
473 allocIDs = append(allocIDs[:i], allocIDs[i+1:]...)
474 break
475 }
476 }
yasin saplibddc2d72022-02-08 13:10:17 +0000477 err := rsrcMgr.UpdateAllocIdsForOnu(ctx, onuID, uniID, allocIDs)
Gamze Abakafee36392019-10-03 11:17:24 +0000478 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700479 logger.Errorf(ctx, "Failed to Remove Alloc Id For Onu. intfID %d onuID %d uniID %d allocID %d",
yasin saplibddc2d72022-02-08 13:10:17 +0000480 rsrcMgr.PonIntfID, onuID, uniID, allocID)
Gamze Abakafee36392019-10-03 11:17:24 +0000481 }
482}
483
484// RemoveGemPortIDForOnu removes the gem port id for given pon interface, onu id, uni id and gem port id
yasin saplibddc2d72022-02-08 13:10:17 +0000485func (rsrcMgr *OpenOltResourceMgr) RemoveGemPortIDForOnu(ctx context.Context, onuID uint32, uniID uint32, gemPortID uint32) {
486 gemPortIDs := rsrcMgr.GetCurrentGEMPortIDsForOnu(ctx, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000487 for i := 0; i < len(gemPortIDs); i++ {
488 if gemPortIDs[i] == gemPortID {
489 gemPortIDs = append(gemPortIDs[:i], gemPortIDs[i+1:]...)
490 break
491 }
492 }
yasin saplibddc2d72022-02-08 13:10:17 +0000493 err := rsrcMgr.UpdateGEMPortIDsForOnu(ctx, onuID, uniID, gemPortIDs)
Gamze Abakafee36392019-10-03 11:17:24 +0000494 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700495 logger.Errorf(ctx, "Failed to Remove Gem Id For Onu. intfID %d onuID %d uniID %d gemPortId %d",
yasin saplibddc2d72022-02-08 13:10:17 +0000496 rsrcMgr.PonIntfID, onuID, uniID, gemPortID)
Gamze Abakafee36392019-10-03 11:17:24 +0000497 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530498}
499
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700500// UpdateGEMPortIDsForOnu updates gemport ids on to the kv store for a given pon port, onu id and uni id
Akash Kankanala041a2122024-10-16 15:49:22 +0530501func (rsrcMgr *OpenOltResourceMgr) UpdateGEMPortIDsForOnu(ctx context.Context, onuID uint32, uniID uint32, gemIDs []uint32) error {
yasin saplibddc2d72022-02-08 13:10:17 +0000502 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", rsrcMgr.PonIntfID, onuID, uniID)
Gamze Abaka745ccb72021-11-18 11:29:58 +0000503
504 if err := rsrcMgr.PonRsrMgr.UpdateGEMPortIDsForOnu(ctx, intfOnuIDuniID, gemIDs); err != nil {
505 logger.Errorw(ctx, "Failed to update gem port ids for onu", log.Fields{"err": err})
506 return err
507 }
508
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700509 // update cache
510 rsrcMgr.gemPortIDsForOnuLock.Lock()
511 rsrcMgr.gemPortIDsForOnu[intfOnuIDuniID] = gemIDs
512 rsrcMgr.gemPortIDsForOnuLock.Unlock()
Gamze Abaka745ccb72021-11-18 11:29:58 +0000513 return nil
Abhilash S.L7f17e402019-03-15 17:40:41 +0530514}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700515
516// FreeonuID releases(make free) onu id for a particular pon-port
yasin saplibddc2d72022-02-08 13:10:17 +0000517func (rsrcMgr *OpenOltResourceMgr) FreeonuID(ctx context.Context, onuID []uint32) {
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -0700518 if len(onuID) == 0 {
519 logger.Info(ctx, "onu id slice is nil, nothing to free")
520 return
521 }
yasin saplibddc2d72022-02-08 13:10:17 +0000522 if err := rsrcMgr.TechprofileRef.FreeResourceID(ctx, rsrcMgr.PonIntfID, ponrmgr.ONU_ID, onuID); err != nil {
Matteo Scandolo84585372021-03-18 14:21:22 -0700523 logger.Errorw(ctx, "error-while-freeing-onu-id", log.Fields{
yasin saplibddc2d72022-02-08 13:10:17 +0000524 "intf-id": rsrcMgr.PonIntfID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700525 "onu-id": onuID,
526 "err": err.Error(),
527 })
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -0700528 } else {
yasin saplibddc2d72022-02-08 13:10:17 +0000529 logger.Infow(ctx, "freed onu id", log.Fields{"intfID": rsrcMgr.PonIntfID, "onuID": onuID})
Matteo Scandolo84585372021-03-18 14:21:22 -0700530 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530531}
532
Gamze Abakafee36392019-10-03 11:17:24 +0000533// FreeAllocID frees AllocID on the PON resource pool and also frees the allocID association
534// for the given OLT device.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700535// The caller should ensure that this is a blocking call and this operation is serialized for
536// the ONU so as not cause resource corruption since there are no mutexes used here.
Girish Gowdraf3728b12022-02-02 21:46:51 -0800537// Setting freeFromResourcePool to false will not clear it from the resource pool but only
538// clear it for the given pon/onu/uni
Akash Kankanala041a2122024-10-16 15:49:22 +0530539func (rsrcMgr *OpenOltResourceMgr) FreeAllocID(ctx context.Context, onuID uint32, uniID uint32, allocID uint32, freeFromResourcePool bool) {
yasin saplibddc2d72022-02-08 13:10:17 +0000540 rsrcMgr.RemoveAllocIDForOnu(ctx, onuID, uniID, allocID)
Girish Gowdraf3728b12022-02-02 21:46:51 -0800541 if freeFromResourcePool {
542 allocIDs := make([]uint32, 0)
543 allocIDs = append(allocIDs, allocID)
yasin saplibddc2d72022-02-08 13:10:17 +0000544 if err := rsrcMgr.TechprofileRef.FreeResourceID(ctx, rsrcMgr.PonIntfID, ponrmgr.ALLOC_ID, allocIDs); err != nil {
Girish Gowdraf3728b12022-02-02 21:46:51 -0800545 logger.Errorw(ctx, "error-while-freeing-alloc-id", log.Fields{
yasin saplibddc2d72022-02-08 13:10:17 +0000546 "intf-id": rsrcMgr.PonIntfID,
Girish Gowdraf3728b12022-02-02 21:46:51 -0800547 "onu-id": onuID,
548 "err": err.Error(),
549 })
550 }
Matteo Scandolo84585372021-03-18 14:21:22 -0700551 }
Gamze Abakafee36392019-10-03 11:17:24 +0000552}
553
554// FreeGemPortID frees GemPortID on the PON resource pool and also frees the gemPortID association
555// for the given OLT device.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700556// The caller should ensure that this is a blocking call and this operation is serialized for
557// the ONU so as not cause resource corruption since there are no mutexes used here.
yasin saplibddc2d72022-02-08 13:10:17 +0000558func (rsrcMgr *OpenOltResourceMgr) FreeGemPortID(ctx context.Context, onuID uint32,
Gamze Abakafee36392019-10-03 11:17:24 +0000559 uniID uint32, gemPortID uint32) {
yasin saplibddc2d72022-02-08 13:10:17 +0000560 rsrcMgr.RemoveGemPortIDForOnu(ctx, onuID, uniID, gemPortID)
Girish Gowdrab77ded92020-04-08 11:45:05 -0700561
Gamze Abakafee36392019-10-03 11:17:24 +0000562 gemPortIDs := make([]uint32, 0)
563 gemPortIDs = append(gemPortIDs, gemPortID)
yasin saplibddc2d72022-02-08 13:10:17 +0000564 if err := rsrcMgr.TechprofileRef.FreeResourceID(ctx, rsrcMgr.PonIntfID, ponrmgr.GEMPORT_ID, gemPortIDs); err != nil {
Matteo Scandolo84585372021-03-18 14:21:22 -0700565 logger.Errorw(ctx, "error-while-freeing-gem-port-id", log.Fields{
yasin saplibddc2d72022-02-08 13:10:17 +0000566 "intf-id": rsrcMgr.PonIntfID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700567 "onu-id": onuID,
568 "err": err.Error(),
569 })
570 }
Gamze Abakafee36392019-10-03 11:17:24 +0000571}
572
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700573// FreePONResourcesForONU make the pon resources free for a given pon interface and onu id
yasin saplibddc2d72022-02-08 13:10:17 +0000574func (rsrcMgr *OpenOltResourceMgr) FreePONResourcesForONU(ctx context.Context, onuID uint32, uniID uint32) {
yasin saplibddc2d72022-02-08 13:10:17 +0000575 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", rsrcMgr.PonIntfID, onuID, uniID)
Abhilash S.L7f17e402019-03-15 17:40:41 +0530576
Sridhar Ravindra92c9b0d2025-01-16 00:15:54 +0530577 if rsrcMgr.PonRsrMgr == nil || rsrcMgr.TechprofileRef == nil {
578 logger.Warn(ctx, "PonRsrMgr or TechprofileRef is nil")
579 return
580 }
581
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700582 AllocIDs := rsrcMgr.PonRsrMgr.GetCurrentAllocIDForOnu(ctx, intfOnuIDuniID)
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700583
yasin saplibddc2d72022-02-08 13:10:17 +0000584 if err := rsrcMgr.TechprofileRef.FreeResourceID(ctx, rsrcMgr.PonIntfID,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400585 ponrmgr.ALLOC_ID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700586 AllocIDs); err != nil {
587 logger.Errorw(ctx, "error-while-freeing-all-alloc-ids-for-onu", log.Fields{
yasin saplibddc2d72022-02-08 13:10:17 +0000588 "intf-id": rsrcMgr.PonIntfID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700589 "onu-id": onuID,
590 "err": err.Error(),
591 })
592 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530593
Akash Kankanala041a2122024-10-16 15:49:22 +0530594 // update cache
Gamze Abaka745ccb72021-11-18 11:29:58 +0000595 rsrcMgr.allocIDsForOnuLock.Lock()
596 delete(rsrcMgr.allocIDsForOnu, intfOnuIDuniID)
597 rsrcMgr.allocIDsForOnuLock.Unlock()
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700598
Gamze Abaka745ccb72021-11-18 11:29:58 +0000599 GEMPortIDs := rsrcMgr.PonRsrMgr.GetCurrentGEMPortIDsForOnu(ctx, intfOnuIDuniID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700600
yasin saplibddc2d72022-02-08 13:10:17 +0000601 if err := rsrcMgr.TechprofileRef.FreeResourceID(ctx, rsrcMgr.PonIntfID,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400602 ponrmgr.GEMPORT_ID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700603 GEMPortIDs); err != nil {
604 logger.Errorw(ctx, "error-while-freeing-all-gem-port-ids-for-onu", log.Fields{
yasin saplibddc2d72022-02-08 13:10:17 +0000605 "intf-id": rsrcMgr.PonIntfID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700606 "onu-id": onuID,
607 "err": err.Error(),
608 })
609 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530610
Gamze Abaka745ccb72021-11-18 11:29:58 +0000611 // update cache
612 rsrcMgr.gemPortIDsForOnuLock.Lock()
613 delete(rsrcMgr.gemPortIDsForOnu, intfOnuIDuniID)
614 rsrcMgr.gemPortIDsForOnuLock.Unlock()
615
Girish Gowdru0c588b22019-04-23 23:24:56 -0400616 // Clear resource map associated with (pon_intf_id, gemport_id) tuple.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700617 rsrcMgr.PonRsrMgr.RemoveResourceMap(ctx, intfOnuIDuniID)
Abhilash S.L7f17e402019-03-15 17:40:41 +0530618}
619
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700620// IsFlowOnKvStore checks if the given flowID is present on the kv store
621// Returns true if the flowID is found, otherwise it returns false
yasin saplibddc2d72022-02-08 13:10:17 +0000622func (rsrcMgr *OpenOltResourceMgr) IsFlowOnKvStore(ctx context.Context, onuID int32, flowID uint64) (bool, error) {
yasin saplid0566272021-12-21 09:10:30 +0000623 var anyError error
Abhilash S.L7f17e402019-03-15 17:40:41 +0530624
yasin saplid0566272021-12-21 09:10:30 +0000625 // In case of nni trap flow
626 if onuID == -1 {
yasin saplibddc2d72022-02-08 13:10:17 +0000627 nniTrapflowIDs, err := rsrcMgr.GetFlowIDsForGem(ctx, NNI)
yasin saplid0566272021-12-21 09:10:30 +0000628 if err != nil {
629 logger.Warnw(ctx, "failed-to-get-nni-trap-flowIDs", log.Fields{"err": err})
630 return false, err
631 }
632 for _, id := range nniTrapflowIDs {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700633 if flowID == id {
yasin saplid0566272021-12-21 09:10:30 +0000634 return true, nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400635 }
636 }
637 }
yasin saplid0566272021-12-21 09:10:30 +0000638
yasin saplibddc2d72022-02-08 13:10:17 +0000639 path := fmt.Sprintf(OnuGemInfoPath, rsrcMgr.PonIntfID, onuID)
yasin saplid0566272021-12-21 09:10:30 +0000640 rsrcMgr.onuGemInfoLock.RLock()
641 val, ok := rsrcMgr.onuGemInfo[path]
642 rsrcMgr.onuGemInfoLock.RUnlock()
643
644 if ok {
645 for _, gem := range val.GemPorts {
yasin saplibddc2d72022-02-08 13:10:17 +0000646 flowIDs, err := rsrcMgr.GetFlowIDsForGem(ctx, gem)
yasin saplid0566272021-12-21 09:10:30 +0000647 if err != nil {
648 anyError = err
649 logger.Warnw(ctx, "failed-to-get-flowIDs-for-gem", log.Fields{"err": err, "onuID": onuID, "gem": gem})
650 } else {
651 for _, id := range flowIDs {
652 if flowID == id {
653 return true, nil
654 }
655 }
656 }
657 }
658 }
659 return false, anyError
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400660}
Manikkaraj kb1d51442019-07-23 10:41:02 -0400661
salmansiddiqui7ac62132019-08-22 03:58:50 +0000662// GetTechProfileIDForOnu fetches Tech-Profile-ID from the KV-Store for the given onu based on the path
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700663// This path is formed as the following: {intfID, onuID, uniID}/tp_id
yasin saplibddc2d72022-02-08 13:10:17 +0000664func (rsrcMgr *OpenOltResourceMgr) GetTechProfileIDForOnu(ctx context.Context, onuID uint32, uniID uint32) []uint32 {
665 Path := fmt.Sprintf(tpIDPathSuffix, rsrcMgr.PonIntfID, onuID, uniID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700666 // fetch from cache
667 rsrcMgr.techProfileIDsForOnuLock.RLock()
668 tpIDs, ok := rsrcMgr.techProfileIDsForOnu[Path]
669 rsrcMgr.techProfileIDsForOnuLock.RUnlock()
670 if ok {
671 return tpIDs
672 }
673 Value, err := rsrcMgr.KVStore.Get(ctx, Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400674 if err == nil {
675 if Value != nil {
676 Val, err := kvstore.ToByte(Value.Value)
677 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700678 logger.Errorw(ctx, "Failed to convert into byte array", log.Fields{"err": err})
679 return tpIDs
Manikkaraj kb1d51442019-07-23 10:41:02 -0400680 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700681 if err = json.Unmarshal(Val, &tpIDs); err != nil {
682 logger.Error(ctx, "Failed to unmarshal", log.Fields{"err": err})
683 return tpIDs
Manikkaraj kb1d51442019-07-23 10:41:02 -0400684 }
685 }
686 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000687 logger.Errorf(ctx, "Failed to get TP id from kvstore for path %s", Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400688 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700689 logger.Debugf(ctx, "Getting TP id %d from path %s", tpIDs, Path)
690
691 // update cache
692 rsrcMgr.techProfileIDsForOnuLock.Lock()
693 rsrcMgr.techProfileIDsForOnu[Path] = tpIDs
694 rsrcMgr.techProfileIDsForOnuLock.Unlock()
695
696 return tpIDs
Manikkaraj kb1d51442019-07-23 10:41:02 -0400697}
698
Gamze Abakafee36392019-10-03 11:17:24 +0000699// 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 -0700700// This path is formed as the following: {intfID, onuID, uniID}/tp_id
yasin saplibddc2d72022-02-08 13:10:17 +0000701func (rsrcMgr *OpenOltResourceMgr) RemoveTechProfileIDsForOnu(ctx context.Context, onuID uint32, uniID uint32) error {
702 intfOnuUniID := fmt.Sprintf(tpIDPathSuffix, rsrcMgr.PonIntfID, onuID, uniID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700703
704 if err := rsrcMgr.KVStore.Delete(ctx, intfOnuUniID); err != nil {
705 logger.Errorw(ctx, "Failed to delete techprofile id resource in KV store", log.Fields{"path": intfOnuUniID})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400706 return err
707 }
Gamze Abaka745ccb72021-11-18 11:29:58 +0000708
709 // update cache
710 rsrcMgr.techProfileIDsForOnuLock.Lock()
711 delete(rsrcMgr.techProfileIDsForOnu, intfOnuUniID)
712 rsrcMgr.techProfileIDsForOnuLock.Unlock()
Manikkaraj kb1d51442019-07-23 10:41:02 -0400713 return nil
714}
715
Gamze Abakafee36392019-10-03 11:17:24 +0000716// 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 -0700717// This path is formed as the following: {intfID, onuID, uniID}/tp_id
yasin saplibddc2d72022-02-08 13:10:17 +0000718func (rsrcMgr *OpenOltResourceMgr) RemoveTechProfileIDForOnu(ctx context.Context, onuID uint32, uniID uint32, tpID uint32) error {
719 tpIDList := rsrcMgr.GetTechProfileIDForOnu(ctx, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000720 for i, tpIDInList := range tpIDList {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700721 if tpIDInList == tpID {
Gamze Abakafee36392019-10-03 11:17:24 +0000722 tpIDList = append(tpIDList[:i], tpIDList[i+1:]...)
723 }
724 }
yasin saplibddc2d72022-02-08 13:10:17 +0000725 intfOnuUniID := fmt.Sprintf(tpIDPathSuffix, rsrcMgr.PonIntfID, onuID, uniID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700726
Gamze Abakafee36392019-10-03 11:17:24 +0000727 Value, err := json.Marshal(tpIDList)
728 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000729 logger.Error(ctx, "failed to Marshal")
Gamze Abakafee36392019-10-03 11:17:24 +0000730 return err
731 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700732 if err = rsrcMgr.KVStore.Put(ctx, intfOnuUniID, Value); err != nil {
733 logger.Errorf(ctx, "Failed to update resource %s", intfOnuUniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000734 return err
735 }
Gamze Abaka745ccb72021-11-18 11:29:58 +0000736
737 // update cache
738 rsrcMgr.techProfileIDsForOnuLock.Lock()
739 rsrcMgr.techProfileIDsForOnu[intfOnuUniID] = tpIDList
740 rsrcMgr.techProfileIDsForOnuLock.Unlock()
Gamze Abakafee36392019-10-03 11:17:24 +0000741 return err
742}
743
744// UpdateTechProfileIDForOnu updates (put) already present tech-profile-id for the given onu based on the path
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700745// This path is formed as the following: {intfID, onuID, uniID}/tp_id
yasin saplibddc2d72022-02-08 13:10:17 +0000746func (rsrcMgr *OpenOltResourceMgr) UpdateTechProfileIDForOnu(ctx context.Context, onuID uint32,
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700747 uniID uint32, tpID uint32) error {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400748 var Value []byte
749 var err error
750
yasin saplibddc2d72022-02-08 13:10:17 +0000751 intfOnuUniID := fmt.Sprintf(tpIDPathSuffix, rsrcMgr.PonIntfID, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000752
yasin saplibddc2d72022-02-08 13:10:17 +0000753 tpIDList := rsrcMgr.GetTechProfileIDForOnu(ctx, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000754 for _, value := range tpIDList {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700755 if value == tpID {
756 logger.Debugf(ctx, "tpID %d is already in tpIdList for the path %s", tpID, intfOnuUniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000757 return err
758 }
759 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700760 logger.Debugf(ctx, "updating tp id %d on path %s", tpID, intfOnuUniID)
761 tpIDList = append(tpIDList, tpID)
762
Gamze Abakafee36392019-10-03 11:17:24 +0000763 Value, err = json.Marshal(tpIDList)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400764 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000765 logger.Error(ctx, "failed to Marshal")
Manikkaraj kb1d51442019-07-23 10:41:02 -0400766 return err
767 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700768 if err = rsrcMgr.KVStore.Put(ctx, intfOnuUniID, Value); err != nil {
769 logger.Errorf(ctx, "Failed to update resource %s", intfOnuUniID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400770 return err
771 }
Gamze Abaka745ccb72021-11-18 11:29:58 +0000772
773 // update cache
774 rsrcMgr.techProfileIDsForOnuLock.Lock()
775 rsrcMgr.techProfileIDsForOnu[intfOnuUniID] = tpIDList
776 rsrcMgr.techProfileIDsForOnuLock.Unlock()
Manikkaraj kb1d51442019-07-23 10:41:02 -0400777 return err
778}
779
Girish Gowdraa482f272021-03-24 23:04:19 -0700780// StoreMeterInfoForOnu updates the meter id in the KV-Store for the given onu based on the path
Gamze Abakafee36392019-10-03 11:17:24 +0000781// This path is formed as the following: <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
yasin saplibddc2d72022-02-08 13:10:17 +0000782func (rsrcMgr *OpenOltResourceMgr) StoreMeterInfoForOnu(ctx context.Context, Direction string, onuID uint32,
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700783 uniID uint32, tpID uint32, meterInfo *MeterInfo) error {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400784 var Value []byte
785 var err error
yasin saplibddc2d72022-02-08 13:10:17 +0000786 intfOnuUniID := fmt.Sprintf(MeterIDPathSuffix, rsrcMgr.PonIntfID, onuID, uniID, tpID, Direction)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700787
Girish Gowdraa482f272021-03-24 23:04:19 -0700788 Value, err = json.Marshal(*meterInfo)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400789 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000790 logger.Error(ctx, "failed to Marshal meter config")
Manikkaraj kb1d51442019-07-23 10:41:02 -0400791 return err
792 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700793 if err = rsrcMgr.KVStore.Put(ctx, intfOnuUniID, Value); err != nil {
794 logger.Errorf(ctx, "Failed to store meter into KV store %s", intfOnuUniID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400795 return err
796 }
Gamze Abaka745ccb72021-11-18 11:29:58 +0000797
798 // update cache
799 rsrcMgr.meterInfoForOnuLock.Lock()
800 rsrcMgr.meterInfoForOnu[intfOnuUniID] = meterInfo
801 rsrcMgr.meterInfoForOnuLock.Unlock()
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700802 logger.Debugw(ctx, "meter info updated successfully", log.Fields{"path": intfOnuUniID, "meter-info": meterInfo})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400803 return err
804}
805
Girish Gowdraa482f272021-03-24 23:04:19 -0700806// GetMeterInfoForOnu fetches the meter id from the kv store for the given onu based on the path
Gamze Abakafee36392019-10-03 11:17:24 +0000807// This path is formed as the following: <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
yasin saplibddc2d72022-02-08 13:10:17 +0000808func (rsrcMgr *OpenOltResourceMgr) GetMeterInfoForOnu(ctx context.Context, Direction string, onuID uint32,
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700809 uniID uint32, tpID uint32) (*MeterInfo, error) {
yasin saplibddc2d72022-02-08 13:10:17 +0000810 Path := fmt.Sprintf(MeterIDPathSuffix, rsrcMgr.PonIntfID, onuID, uniID, tpID, Direction)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700811
812 // get from cache
813 rsrcMgr.meterInfoForOnuLock.RLock()
814 val, ok := rsrcMgr.meterInfoForOnu[Path]
815 rsrcMgr.meterInfoForOnuLock.RUnlock()
816 if ok {
817 return val, nil
818 }
819
Girish Gowdraa482f272021-03-24 23:04:19 -0700820 var meterInfo MeterInfo
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700821 Value, err := rsrcMgr.KVStore.Get(ctx, Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400822 if err == nil {
823 if Value != nil {
Girish Gowdraa482f272021-03-24 23:04:19 -0700824 logger.Debug(ctx, "Found meter info in KV store", log.Fields{"Direction": Direction})
salmansiddiqui7ac62132019-08-22 03:58:50 +0000825 Val, er := kvstore.ToByte(Value.Value)
826 if er != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700827 logger.Errorw(ctx, "Failed to convert into byte array", log.Fields{"err": er})
salmansiddiqui7ac62132019-08-22 03:58:50 +0000828 return nil, er
Manikkaraj kb1d51442019-07-23 10:41:02 -0400829 }
Girish Gowdraa482f272021-03-24 23:04:19 -0700830 if er = json.Unmarshal(Val, &meterInfo); er != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700831 logger.Error(ctx, "Failed to unmarshal meter info", log.Fields{"err": er})
salmansiddiqui7ac62132019-08-22 03:58:50 +0000832 return nil, er
Manikkaraj kb1d51442019-07-23 10:41:02 -0400833 }
834 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000835 logger.Debug(ctx, "meter-does-not-exists-in-KVStore")
Manikkaraj kb1d51442019-07-23 10:41:02 -0400836 return nil, err
837 }
838 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000839 logger.Errorf(ctx, "Failed to get Meter config from kvstore for path %s", Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400840 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700841 // update cache
842 rsrcMgr.meterInfoForOnuLock.Lock()
843 rsrcMgr.meterInfoForOnu[Path] = &meterInfo
844 rsrcMgr.meterInfoForOnuLock.Unlock()
845
Girish Gowdraa482f272021-03-24 23:04:19 -0700846 return &meterInfo, err
Manikkaraj kb1d51442019-07-23 10:41:02 -0400847}
848
Girish Gowdraa482f272021-03-24 23:04:19 -0700849// HandleMeterInfoRefCntUpdate increments or decrements the reference counter for a given meter.
850// When reference count becomes 0, it clears the meter information from the kv store
balaji.nagarajan29be8bc2026-01-26 16:31:41 +0530851func (rsrcMgr *OpenOltResourceMgr) HandleMeterInfoRefCntUpdate(ctx context.Context, meterInfo *MeterInfo, Direction string,
yasin saplibddc2d72022-02-08 13:10:17 +0000852 onuID uint32, uniID uint32, tpID uint32, increment bool) error {
balaji.nagarajan29be8bc2026-01-26 16:31:41 +0530853 var err error
854 if meterInfo == nil {
855 meterInfo, err = rsrcMgr.GetMeterInfoForOnu(ctx, Direction, onuID, uniID, tpID)
856 }
Girish Gowdra82c80982021-03-26 16:22:02 -0700857 if err != nil {
858 return err
859 } else if meterInfo == nil {
860 // If we are increasing the reference count, we expect the meter information to be present on KV store.
861 // But if decrementing the reference count, the meter is possibly already cleared from KV store. Just log warn but do not return error.
862 if increment {
yasin saplibddc2d72022-02-08 13:10:17 +0000863 logger.Errorf(ctx, "error-fetching-meter-info-for-intf-%d-onu-%d-uni-%d-tp-id-%d-direction-%s", rsrcMgr.PonIntfID, onuID, uniID, tpID, Direction)
864 return fmt.Errorf("error-fetching-meter-info-for-intf-%d-onu-%d-uni-%d-tp-id-%d-direction-%s", rsrcMgr.PonIntfID, onuID, uniID, tpID, Direction)
Girish Gowdra82c80982021-03-26 16:22:02 -0700865 }
866 logger.Warnw(ctx, "meter is already cleared",
yasin saplibddc2d72022-02-08 13:10:17 +0000867 log.Fields{"intfID": rsrcMgr.PonIntfID, "onuID": onuID, "uniID": uniID, "direction": Direction, "increment": increment})
Girish Gowdra82c80982021-03-26 16:22:02 -0700868 return nil
Girish Gowdraa482f272021-03-24 23:04:19 -0700869 }
Girish Gowdra82c80982021-03-26 16:22:02 -0700870
Girish Gowdraa482f272021-03-24 23:04:19 -0700871 if increment {
872 meterInfo.RefCnt++
873 } else {
874 meterInfo.RefCnt--
Girish Gowdraa482f272021-03-24 23:04:19 -0700875 }
yasin saplibddc2d72022-02-08 13:10:17 +0000876 if err := rsrcMgr.StoreMeterInfoForOnu(ctx, Direction, onuID, uniID, tpID, meterInfo); err != nil {
Girish Gowdraa482f272021-03-24 23:04:19 -0700877 return err
878 }
879 return nil
880}
881
882// RemoveMeterInfoForOnu deletes the meter id from the kV-Store for the given onu based on the path
Gamze Abakafee36392019-10-03 11:17:24 +0000883// This path is formed as the following: <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
yasin saplibddc2d72022-02-08 13:10:17 +0000884func (rsrcMgr *OpenOltResourceMgr) RemoveMeterInfoForOnu(ctx context.Context, Direction string, onuID uint32,
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700885 uniID uint32, tpID uint32) error {
yasin saplibddc2d72022-02-08 13:10:17 +0000886 Path := fmt.Sprintf(MeterIDPathSuffix, rsrcMgr.PonIntfID, onuID, uniID, tpID, Direction)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700887
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700888 if err := rsrcMgr.KVStore.Delete(ctx, Path); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000889 logger.Errorf(ctx, "Failed to delete meter id %s from kvstore ", Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400890 return err
891 }
Gamze Abaka745ccb72021-11-18 11:29:58 +0000892
893 // update cache
894 rsrcMgr.meterInfoForOnuLock.Lock()
895 delete(rsrcMgr.meterInfoForOnu, Path)
896 rsrcMgr.meterInfoForOnuLock.Unlock()
Manikkaraj kb1d51442019-07-23 10:41:02 -0400897 return nil
898}
salmansiddiqui7ac62132019-08-22 03:58:50 +0000899
Joey Armstrong3f0e2422023-07-05 18:25:41 -0400900// AddGemToOnuGemInfo adds gemport to onugem info kvstore and also local cache
balaji.nagarajan29be8bc2026-01-26 16:31:41 +0530901func (rsrcMgr *OpenOltResourceMgr) AddGemToOnuGemInfo(ctx context.Context, onuID uint32, gemPorts []uint32) error {
yasin saplibddc2d72022-02-08 13:10:17 +0000902 onugem, err := rsrcMgr.GetOnuGemInfo(ctx, onuID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700903 if err != nil || onugem == nil || onugem.SerialNumber == "" {
yasin saplibddc2d72022-02-08 13:10:17 +0000904 logger.Errorf(ctx, "failed to get onuifo for intfid %d", rsrcMgr.PonIntfID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530905 return err
906 }
balaji.nagarajan29be8bc2026-01-26 16:31:41 +0530907 dbGemPortMap := make(map[uint32]bool)
908 for _, gem := range onugem.GemPorts {
909 dbGemPortMap[gem] = true
910 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700911 if onugem.OnuID == onuID {
balaji.nagarajan29be8bc2026-01-26 16:31:41 +0530912 for _, gemPort := range gemPorts {
913 if _, exists := dbGemPortMap[gemPort]; exists {
914 logger.Debugw(ctx, "Gem already present in onugem info, skpping addition", log.Fields{"gem": gemPort})
915 continue
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700916 }
balaji.nagarajan29be8bc2026-01-26 16:31:41 +0530917 logger.Debugw(ctx, "Added gem to onugem info", log.Fields{"gem": gemPort})
918 onugem.GemPorts = append(onugem.GemPorts, gemPort)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700919 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700920 } else {
yasin saplibddc2d72022-02-08 13:10:17 +0000921 logger.Errorw(ctx, "onu id in OnuGemInfo does not match", log.Fields{"onuID": onuID, "ponIf": rsrcMgr.PonIntfID, "onuGemInfoOnuID": onugem.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700922 return fmt.Errorf("onu-id-in-OnuGemInfo-does-not-match-%v", onuID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530923 }
924
yasin saplibddc2d72022-02-08 13:10:17 +0000925 err = rsrcMgr.AddOnuGemInfo(ctx, onuID, *onugem)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530926 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000927 logger.Error(ctx, "Failed to add onugem to kv store")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530928 return err
929 }
930 return err
931}
932
Joey Armstrong3f0e2422023-07-05 18:25:41 -0400933// RemoveGemFromOnuGemInfo removes gemport from onugem info on kvstore and also local cache
yasin saplibddc2d72022-02-08 13:10:17 +0000934func (rsrcMgr *OpenOltResourceMgr) RemoveGemFromOnuGemInfo(ctx context.Context, onuID uint32, gemPort uint32) error {
935 onugem, err := rsrcMgr.GetOnuGemInfo(ctx, onuID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700936 if err != nil || onugem == nil || onugem.SerialNumber == "" {
yasin saplibddc2d72022-02-08 13:10:17 +0000937 logger.Errorf(ctx, "failed to get onuifo for intfid %d", rsrcMgr.PonIntfID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700938 return err
939 }
940 updated := false
941 if onugem.OnuID == onuID {
942 for i, gem := range onugem.GemPorts {
943 if gem == gemPort {
944 logger.Debugw(ctx, "Gem found, removing from onu gem info", log.Fields{"gem": gem})
945 onugem.GemPorts = append(onugem.GemPorts[:i], onugem.GemPorts[i+1:]...)
946 updated = true
947 break
948 }
949 }
950 } else {
yasin saplibddc2d72022-02-08 13:10:17 +0000951 logger.Errorw(ctx, "onu id in OnuGemInfo does not match", log.Fields{"onuID": onuID, "ponIf": rsrcMgr.PonIntfID, "onuGemInfoOnuID": onugem.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700952 return fmt.Errorf("onu-id-in-OnuGemInfo-does-not-match-%v", onuID)
953 }
954 if updated {
yasin saplibddc2d72022-02-08 13:10:17 +0000955 err = rsrcMgr.AddOnuGemInfo(ctx, onuID, *onugem)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700956 if err != nil {
957 logger.Error(ctx, "Failed to add onugem to kv store")
958 return err
959 }
960 } else {
961 logger.Debugw(ctx, "Gem port not found in onu gem info", log.Fields{"gem": gemPort})
962 }
963 return nil
964}
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530965
Joey Armstrong3f0e2422023-07-05 18:25:41 -0400966// GetOnuGemInfo gets onu gem info from the kvstore per interface
yasin saplibddc2d72022-02-08 13:10:17 +0000967func (rsrcMgr *OpenOltResourceMgr) GetOnuGemInfo(ctx context.Context, onuID uint32) (*OnuGemInfo, error) {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700968 var err error
969 var Val []byte
970 var onugem OnuGemInfo
971
yasin saplibddc2d72022-02-08 13:10:17 +0000972 path := fmt.Sprintf(OnuGemInfoPath, rsrcMgr.PonIntfID, onuID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700973
974 rsrcMgr.onuGemInfoLock.RLock()
975 val, ok := rsrcMgr.onuGemInfo[path]
976 rsrcMgr.onuGemInfoLock.RUnlock()
977 if ok {
978 return val, nil
979 }
980 value, err := rsrcMgr.KVStore.Get(ctx, path)
981 if err != nil {
982 logger.Errorw(ctx, "Failed to get from kv store", log.Fields{"path": path})
983 return nil, err
984 } else if value == nil {
985 logger.Debug(ctx, "No onuinfo for path", log.Fields{"path": path})
986 return nil, nil // returning nil as this could happen if there are no onus for the interface yet
987 }
988 if Val, err = kvstore.ToByte(value.Value); err != nil {
989 logger.Error(ctx, "Failed to convert to byte array")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530990 return nil, err
991 }
992
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700993 if err = json.Unmarshal(Val, &onugem); err != nil {
994 logger.Error(ctx, "Failed to unmarshall")
995 return nil, err
996 }
997 logger.Debugw(ctx, "found onugem info from path", log.Fields{"path": path, "onuGemInfo": onugem})
998 rsrcMgr.onuGemInfoLock.Lock()
999 rsrcMgr.onuGemInfo[path] = &onugem
1000 rsrcMgr.onuGemInfoLock.Unlock()
1001
1002 return &onugem, nil
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301003}
1004
Joey Armstrong3f0e2422023-07-05 18:25:41 -04001005// AddNewOnuGemInfoToCacheAndKvStore function adds a new onu gem info to cache and kvstore
yasin saplibddc2d72022-02-08 13:10:17 +00001006func (rsrcMgr *OpenOltResourceMgr) AddNewOnuGemInfoToCacheAndKvStore(ctx context.Context, onuID uint32, serialNum string) error {
yasin saplibddc2d72022-02-08 13:10:17 +00001007 Path := fmt.Sprintf(OnuGemInfoPath, rsrcMgr.PonIntfID, onuID)
yasin sapli9e4c5092022-02-01 13:52:33 +00001008
1009 rsrcMgr.onuGemInfoLock.Lock()
1010 _, ok := rsrcMgr.onuGemInfo[Path]
1011 rsrcMgr.onuGemInfoLock.Unlock()
1012
1013 // If the ONU already exists in onuGemInfo list, nothing to do
1014 if ok {
1015 logger.Debugw(ctx, "onu-id-already-exists-in-cache", log.Fields{"onuID": onuID, "serialNum": serialNum})
1016 return nil
1017 }
1018
yasin saplibddc2d72022-02-08 13:10:17 +00001019 onuGemInfo := OnuGemInfo{OnuID: onuID, SerialNumber: serialNum, IntfID: rsrcMgr.PonIntfID}
yasin sapli9e4c5092022-02-01 13:52:33 +00001020
yasin saplibddc2d72022-02-08 13:10:17 +00001021 if err := rsrcMgr.AddOnuGemInfo(ctx, onuID, onuGemInfo); err != nil {
yasin sapli9e4c5092022-02-01 13:52:33 +00001022 return err
1023 }
1024 logger.Infow(ctx, "added-onuinfo",
1025 log.Fields{
yasin saplibddc2d72022-02-08 13:10:17 +00001026 "intf-id": rsrcMgr.PonIntfID,
yasin sapli9e4c5092022-02-01 13:52:33 +00001027 "onu-id": onuID,
1028 "serial-num": serialNum,
1029 "onu": onuGemInfo,
1030 "device-id": rsrcMgr.DeviceID})
1031 return nil
1032}
1033
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001034// AddOnuGemInfo adds onu info on to the kvstore per interface
yasin saplibddc2d72022-02-08 13:10:17 +00001035func (rsrcMgr *OpenOltResourceMgr) AddOnuGemInfo(ctx context.Context, onuID uint32, onuGem OnuGemInfo) error {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001036 var Value []byte
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301037 var err error
yasin saplibddc2d72022-02-08 13:10:17 +00001038 Path := fmt.Sprintf(OnuGemInfoPath, rsrcMgr.PonIntfID, onuID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301039
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001040 Value, err = json.Marshal(onuGem)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301041 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001042 logger.Error(ctx, "failed to Marshal")
1043 return err
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301044 }
1045
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001046 if err = rsrcMgr.KVStore.Put(ctx, Path, Value); err != nil {
1047 logger.Errorf(ctx, "Failed to update resource %s", Path)
1048 return err
1049 }
yasin sapli9e4c5092022-02-01 13:52:33 +00001050 logger.Debugw(ctx, "added onu gem info to store", log.Fields{"onuGemInfo": onuGem, "Path": Path})
Gamze Abaka745ccb72021-11-18 11:29:58 +00001051
Akash Kankanala041a2122024-10-16 15:49:22 +05301052 // update cache
Gamze Abaka745ccb72021-11-18 11:29:58 +00001053 rsrcMgr.onuGemInfoLock.Lock()
1054 rsrcMgr.onuGemInfo[Path] = &onuGem
1055 rsrcMgr.onuGemInfoLock.Unlock()
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001056 return err
1057}
1058
1059// DelOnuGemInfo deletes the onugem info from kvstore per ONU
yasin saplibddc2d72022-02-08 13:10:17 +00001060func (rsrcMgr *OpenOltResourceMgr) DelOnuGemInfo(ctx context.Context, onuID uint32) error {
1061 path := fmt.Sprintf(OnuGemInfoPath, rsrcMgr.PonIntfID, onuID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001062
1063 if err := rsrcMgr.KVStore.Delete(ctx, path); err != nil {
1064 logger.Errorf(ctx, "failed to remove resource %s", path)
1065 return err
1066 }
Gamze Abaka745ccb72021-11-18 11:29:58 +00001067
Akash Kankanala041a2122024-10-16 15:49:22 +05301068 // update cache
Gamze Abaka745ccb72021-11-18 11:29:58 +00001069 rsrcMgr.onuGemInfoLock.Lock()
1070 logger.Debugw(ctx, "removing onu gem info", log.Fields{"onuGemInfo": rsrcMgr.onuGemInfo[path]})
1071 delete(rsrcMgr.onuGemInfo, path)
1072 rsrcMgr.onuGemInfoLock.Unlock()
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001073 return nil
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301074}
1075
Joey Armstrong3f0e2422023-07-05 18:25:41 -04001076// DeleteAllOnuGemInfoForIntf deletes all the all onu gem info on the given pon interface
yasin saplibddc2d72022-02-08 13:10:17 +00001077func (rsrcMgr *OpenOltResourceMgr) DeleteAllOnuGemInfoForIntf(ctx context.Context) error {
yasin saplibddc2d72022-02-08 13:10:17 +00001078 path := fmt.Sprintf(OnuGemInfoPathPathPrefix, rsrcMgr.PonIntfID)
Girish Gowdra950326e2021-11-05 12:43:24 -07001079
yasin saplibddc2d72022-02-08 13:10:17 +00001080 logger.Debugw(ctx, "delete-all-onu-gem-info-for-pon-intf", log.Fields{"intfID": rsrcMgr.PonIntfID})
Girish Gowdra950326e2021-11-05 12:43:24 -07001081 if err := rsrcMgr.KVStore.DeleteWithPrefix(ctx, path); err != nil {
1082 logger.Errorf(ctx, "failed-to-remove-resource-%s", path)
1083 return err
1084 }
1085
1086 // Reset cache. Normally not necessary as the entire device is getting deleted when this API is invoked.
1087 rsrcMgr.onuGemInfoLock.Lock()
1088 rsrcMgr.onuGemInfo = make(map[string]*OnuGemInfo)
1089 rsrcMgr.onuGemInfoLock.Unlock()
1090 return nil
1091}
1092
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301093// AddUniPortToOnuInfo adds uni port to the onuinfo kvstore. check if the uni is already present if not update the kv store.
yasin saplibddc2d72022-02-08 13:10:17 +00001094func (rsrcMgr *OpenOltResourceMgr) AddUniPortToOnuInfo(ctx context.Context, onuID uint32, portNo uint32) {
yasin saplibddc2d72022-02-08 13:10:17 +00001095 onugem, err := rsrcMgr.GetOnuGemInfo(ctx, onuID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001096 if err != nil || onugem == nil || onugem.SerialNumber == "" {
yasin saplibddc2d72022-02-08 13:10:17 +00001097 logger.Warnf(ctx, "failed to get onuifo for intfid %d", rsrcMgr.PonIntfID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301098 return
1099 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001100
1101 if onugem.OnuID == onuID {
1102 for _, uni := range onugem.UniPorts {
1103 if uni == portNo {
1104 logger.Debugw(ctx, "uni already present in onugem info", log.Fields{"uni": portNo})
1105 return
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301106 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301107 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001108 onugem.UniPorts = append(onugem.UniPorts, portNo)
1109 } else {
yasin saplibddc2d72022-02-08 13:10:17 +00001110 logger.Warnw(ctx, "onu id mismatch in onu gem info", log.Fields{"intfID": rsrcMgr.PonIntfID, "onuID": onuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001111 return
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301112 }
yasin saplibddc2d72022-02-08 13:10:17 +00001113 err = rsrcMgr.AddOnuGemInfo(ctx, onuID, *onugem)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301114 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001115 logger.Errorw(ctx, "Failed to add uni port in onugem to kv store", log.Fields{"uni": portNo})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301116 return
1117 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301118}
1119
Joey Armstrong3f0e2422023-07-05 18:25:41 -04001120// 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 -07001121func (rsrcMgr *OpenOltResourceMgr) UpdateGemPortForPktIn(ctx context.Context, pktIn PacketInInfoKey, gemPort uint32) {
Girish Gowdra950326e2021-11-05 12:43:24 -07001122 path := fmt.Sprintf(OnuPacketInPath, pktIn.IntfID, pktIn.OnuID, pktIn.LogicalPort, pktIn.VlanID, pktIn.Priority)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001123
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301124 Value, err := json.Marshal(gemPort)
1125 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001126 logger.Error(ctx, "Failed to marshal data")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301127 return
1128 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001129 if err = rsrcMgr.KVStore.Put(ctx, path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001130 logger.Errorw(ctx, "Failed to put to kvstore", log.Fields{"path": path, "value": gemPort})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301131 return
1132 }
Gamze Abaka745ccb72021-11-18 11:29:58 +00001133
1134 // update cache
1135 rsrcMgr.gemPortForPacketInInfoLock.Lock()
1136 rsrcMgr.gemPortForPacketInInfo[path] = gemPort
1137 rsrcMgr.gemPortForPacketInInfoLock.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +00001138 logger.Debugw(ctx, "added gem packet in successfully", log.Fields{"path": path, "gem": gemPort})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301139}
1140
Esin Karaman7fb80c22020-07-16 14:23:33 +00001141// 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 -07001142func (rsrcMgr *OpenOltResourceMgr) GetGemPortFromOnuPktIn(ctx context.Context, packetInInfoKey PacketInInfoKey) (uint32, error) {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301143 var Val []byte
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301144
Girish Gowdra950326e2021-11-05 12:43:24 -07001145 path := fmt.Sprintf(OnuPacketInPath, packetInInfoKey.IntfID, packetInInfoKey.OnuID, packetInInfoKey.LogicalPort,
Esin Karaman7fb80c22020-07-16 14:23:33 +00001146 packetInInfoKey.VlanID, packetInInfoKey.Priority)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001147 // get from cache
1148 rsrcMgr.gemPortForPacketInInfoLock.RLock()
1149 gemPort, ok := rsrcMgr.gemPortForPacketInInfo[path]
1150 rsrcMgr.gemPortForPacketInInfoLock.RUnlock()
1151 if ok {
1152 logger.Debugw(ctx, "found packein gemport from path", log.Fields{"path": path, "gem": gemPort})
1153 return gemPort, nil
1154 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301155
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001156 value, err := rsrcMgr.KVStore.Get(ctx, path)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301157 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001158 logger.Errorw(ctx, "Failed to get from kv store", log.Fields{"path": path})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301159 return uint32(0), err
1160 } else if value == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001161 logger.Debugw(ctx, "No pkt in gem found", log.Fields{"path": path})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301162 return uint32(0), nil
1163 }
1164
1165 if Val, err = kvstore.ToByte(value.Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001166 logger.Error(ctx, "Failed to convert to byte array")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301167 return uint32(0), err
1168 }
1169 if err = json.Unmarshal(Val, &gemPort); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001170 logger.Error(ctx, "Failed to unmarshall")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301171 return uint32(0), err
1172 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001173 logger.Debugw(ctx, "found packein gemport from path", log.Fields{"path": path, "gem": gemPort})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001174 // update cache
1175 rsrcMgr.gemPortForPacketInInfoLock.Lock()
1176 rsrcMgr.gemPortForPacketInInfo[path] = gemPort
1177 rsrcMgr.gemPortForPacketInInfoLock.Unlock()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301178
1179 return gemPort, nil
1180}
1181
Joey Armstrong3f0e2422023-07-05 18:25:41 -04001182// DeletePacketInGemPortForOnu deletes the packet-in gemport for ONU
yasin saplibddc2d72022-02-08 13:10:17 +00001183func (rsrcMgr *OpenOltResourceMgr) DeletePacketInGemPortForOnu(ctx context.Context, onuID uint32, logicalPort uint32) error {
1184 path := fmt.Sprintf(OnuPacketInPathPrefix, rsrcMgr.PonIntfID, onuID, logicalPort)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001185 value, err := rsrcMgr.KVStore.List(ctx, path)
Esin Karaman7fb80c22020-07-16 14:23:33 +00001186 if err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001187 logger.Errorf(ctx, "failed-to-read-value-from-path-%s", path)
1188 return errors.New("failed-to-read-value-from-path-" + path)
Esin Karaman7fb80c22020-07-16 14:23:33 +00001189 }
Esin Karaman7fb80c22020-07-16 14:23:33 +00001190
Gamze Abaka745ccb72021-11-18 11:29:58 +00001191 logger.Debugw(ctx, "delete-packetin-gem-port", log.Fields{"realPath": path})
1192 if err := rsrcMgr.KVStore.DeleteWithPrefix(ctx, path); err != nil {
1193 logger.Errorf(ctx, "failed-to-remove-resource-%s", path)
1194 return err
1195 }
1196
Akash Kankanala041a2122024-10-16 15:49:22 +05301197 // remove them one by one
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001198 for key := range value {
serkant.uluderya4f5ed592020-12-17 20:57:59 +03001199 // Remove the PathPrefix from the path on KV key.
Girish Gowdra950326e2021-11-05 12:43:24 -07001200 // gemPortForPacketInInfo cache uses OnuPacketInPath as the key
serkant.uluderya4f5ed592020-12-17 20:57:59 +03001201 stringToBeReplaced := rsrcMgr.KVStore.PathPrefix + "/"
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001202 replacedWith := ""
1203 key = strings.Replace(key, stringToBeReplaced, replacedWith, 1)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001204 // update cache
1205 rsrcMgr.gemPortForPacketInInfoLock.Lock()
1206 delete(rsrcMgr.gemPortForPacketInInfo, key)
1207 rsrcMgr.gemPortForPacketInInfoLock.Unlock()
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001208
serkant.uluderya4f5ed592020-12-17 20:57:59 +03001209 logger.Debugw(ctx, "removed-key-from-packetin-gem-port-cache", log.Fields{"key": key, "cache-len": len(rsrcMgr.gemPortForPacketInInfo)})
1210 }
1211
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301212 return nil
1213}
1214
Joey Armstrong3f0e2422023-07-05 18:25:41 -04001215// GetFlowIDsForGem gets the list of FlowIDs for the given gemport
yasin saplibddc2d72022-02-08 13:10:17 +00001216func (rsrcMgr *OpenOltResourceMgr) GetFlowIDsForGem(ctx context.Context, gem uint32) ([]uint64, error) {
1217 path := fmt.Sprintf(FlowIDsForGem, rsrcMgr.PonIntfID, gem)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001218
1219 // get from cache
1220 rsrcMgr.flowIDsForGemLock.RLock()
1221 flowIDs, ok := rsrcMgr.flowIDsForGem[gem]
1222 rsrcMgr.flowIDsForGemLock.RUnlock()
1223 if ok {
1224 return flowIDs, nil
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301225 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301226
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001227 value, err := rsrcMgr.KVStore.Get(ctx, path)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301228 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001229 logger.Errorw(ctx, "Failed to get from kv store", log.Fields{"path": path})
1230 return nil, err
yasin saplid0566272021-12-21 09:10:30 +00001231 } else if value == nil || value.Value == nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001232 logger.Debug(ctx, "no flow-ids found", log.Fields{"path": path})
1233 return nil, nil
1234 }
1235 Val, err := kvstore.ToByte(value.Value)
1236 if err != nil {
1237 logger.Error(ctx, "Failed to convert to byte array")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301238 return nil, err
1239 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301240
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001241 if err = json.Unmarshal(Val, &flowIDs); err != nil {
1242 logger.Error(ctx, "Failed to unmarshall")
1243 return nil, err
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301244 }
1245
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001246 // update cache
1247 rsrcMgr.flowIDsForGemLock.Lock()
1248 rsrcMgr.flowIDsForGem[gem] = flowIDs
1249 rsrcMgr.flowIDsForGemLock.Unlock()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301250
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001251 return flowIDs, nil
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301252}
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301253
yasin sapli9e4c5092022-02-01 13:52:33 +00001254// IsGemPortUsedByAnotherFlow returns true if given gem is used by another flow
Girish Gowdrab4c33302022-03-18 15:07:38 -07001255func (rsrcMgr *OpenOltResourceMgr) IsGemPortUsedByAnotherFlow(ctx context.Context, gemPortID uint32, flowID uint64) (bool, error) {
1256 flowIDList, err := rsrcMgr.GetFlowIDsForGem(ctx, gemPortID)
1257 if err != nil {
1258 return false, err
1259 }
yasin sapli9e4c5092022-02-01 13:52:33 +00001260 for _, id := range flowIDList {
1261 if flowID != id {
Girish Gowdrab4c33302022-03-18 15:07:38 -07001262 return true, nil
yasin sapli9e4c5092022-02-01 13:52:33 +00001263 }
1264 }
Girish Gowdrab4c33302022-03-18 15:07:38 -07001265 return false, nil
yasin sapli9e4c5092022-02-01 13:52:33 +00001266}
1267
1268// RegisterFlowIDForGem updates both cache and KV store for flowIDsForGem map
yasin saplibddc2d72022-02-08 13:10:17 +00001269func (rsrcMgr *OpenOltResourceMgr) RegisterFlowIDForGem(ctx context.Context, gemPortID uint32, flowFromCore *ofp.OfpFlowStats) error {
Girish Gowdrab4c33302022-03-18 15:07:38 -07001270 flowIDs, err := rsrcMgr.GetFlowIDsForGem(ctx, gemPortID)
1271 if err != nil {
1272 return err
yasin sapli9e4c5092022-02-01 13:52:33 +00001273 }
Girish Gowdrab4c33302022-03-18 15:07:38 -07001274
1275 flowIDs = appendUnique64bit(flowIDs, flowFromCore.Id)
yasin sapli9e4c5092022-02-01 13:52:33 +00001276 // update the flowids for a gem to the KVstore
yasin saplibddc2d72022-02-08 13:10:17 +00001277 return rsrcMgr.UpdateFlowIDsForGem(ctx, gemPortID, flowIDs)
yasin sapli9e4c5092022-02-01 13:52:33 +00001278}
1279
Joey Armstrong3f0e2422023-07-05 18:25:41 -04001280// UpdateFlowIDsForGem updates flow id per gemport
yasin saplibddc2d72022-02-08 13:10:17 +00001281func (rsrcMgr *OpenOltResourceMgr) UpdateFlowIDsForGem(ctx context.Context, gem uint32, flowIDs []uint64) error {
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301282 var val []byte
yasin saplibddc2d72022-02-08 13:10:17 +00001283 path := fmt.Sprintf(FlowIDsForGem, rsrcMgr.PonIntfID, gem)
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301284
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001285 if flowIDs == nil {
Girish Gowdra950326e2021-11-05 12:43:24 -07001286 if err := rsrcMgr.KVStore.Delete(ctx, path); err != nil {
1287 logger.Errorw(ctx, "Failed to delete from kvstore", log.Fields{"err": err, "path": path})
1288 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001289 return nil
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301290 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001291 val, err := json.Marshal(flowIDs)
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301292 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001293 logger.Error(ctx, "Failed to marshal data", log.Fields{"err": err})
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301294 return err
1295 }
Girish Gowdrab77ded92020-04-08 11:45:05 -07001296
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001297 if err = rsrcMgr.KVStore.Put(ctx, path, val); err != nil {
1298 logger.Errorw(ctx, "Failed to put to kvstore", log.Fields{"err": err, "path": path, "value": val})
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301299 return err
1300 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001301 logger.Debugw(ctx, "added flowid list for gem to kv successfully", log.Fields{"path": path, "flowidlist": flowIDs})
Gamze Abaka745ccb72021-11-18 11:29:58 +00001302
1303 // update cache
1304 rsrcMgr.flowIDsForGemLock.Lock()
1305 rsrcMgr.flowIDsForGem[gem] = flowIDs
1306 rsrcMgr.flowIDsForGemLock.Unlock()
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301307 return nil
1308}
1309
Joey Armstrong3f0e2422023-07-05 18:25:41 -04001310// DeleteFlowIDsForGem deletes the flowID list entry per gem from kvstore.
yasin saplibddc2d72022-02-08 13:10:17 +00001311func (rsrcMgr *OpenOltResourceMgr) DeleteFlowIDsForGem(ctx context.Context, gem uint32) error {
1312 path := fmt.Sprintf(FlowIDsForGem, rsrcMgr.PonIntfID, gem)
Gamze Abaka745ccb72021-11-18 11:29:58 +00001313 if err := rsrcMgr.KVStore.Delete(ctx, path); err != nil {
1314 logger.Errorw(ctx, "Failed to delete from kvstore", log.Fields{"err": err, "path": path})
1315 return err
1316 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001317 // update cache
1318 rsrcMgr.flowIDsForGemLock.Lock()
1319 delete(rsrcMgr.flowIDsForGem, gem)
1320 rsrcMgr.flowIDsForGemLock.Unlock()
Gamze Abaka745ccb72021-11-18 11:29:58 +00001321 return nil
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301322}
Esin Karamanccb714b2019-11-29 15:02:06 +00001323
Joey Armstrong3f0e2422023-07-05 18:25:41 -04001324// DeleteAllFlowIDsForGemForIntf deletes all the flow ids associated for all the gems on the given pon interface
yasin saplibddc2d72022-02-08 13:10:17 +00001325func (rsrcMgr *OpenOltResourceMgr) DeleteAllFlowIDsForGemForIntf(ctx context.Context) error {
1326 path := fmt.Sprintf(FlowIDsForGemPathPrefix, rsrcMgr.PonIntfID)
Girish Gowdra950326e2021-11-05 12:43:24 -07001327
yasin saplibddc2d72022-02-08 13:10:17 +00001328 logger.Debugw(ctx, "delete-flow-ids-for-gem-for-pon-intf", log.Fields{"intfID": rsrcMgr.PonIntfID})
Girish Gowdra950326e2021-11-05 12:43:24 -07001329 if err := rsrcMgr.KVStore.DeleteWithPrefix(ctx, path); err != nil {
1330 logger.Errorf(ctx, "failed-to-remove-resource-%s", path)
1331 return err
1332 }
1333
1334 // Reset cache. Normally not necessary as the entire device is getting deleted when this API is invoked.
1335 rsrcMgr.flowIDsForGemLock.Lock()
1336 rsrcMgr.flowIDsForGem = make(map[uint32][]uint64)
1337 rsrcMgr.flowIDsForGemLock.Unlock()
1338 return nil
1339}
1340
Joey Armstrong3f0e2422023-07-05 18:25:41 -04001341// GetMcastQueuePerInterfaceMap gets multicast queue info per pon interface
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001342func (rsrcMgr *OpenOltResourceMgr) GetMcastQueuePerInterfaceMap(ctx context.Context) (map[uint32][]uint32, error) {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001343 path := McastQueuesForIntf
Esin Karamanccb714b2019-11-29 15:02:06 +00001344 var val []byte
1345
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001346 rsrcMgr.mcastQueueForIntfLock.RLock()
1347 if rsrcMgr.mcastQueueForIntfLoadedFromKvStore {
1348 rsrcMgr.mcastQueueForIntfLock.RUnlock()
1349 return rsrcMgr.mcastQueueForIntf, nil
1350 }
1351 rsrcMgr.mcastQueueForIntfLock.RUnlock()
1352
1353 kvPair, err := rsrcMgr.KVStore.Get(ctx, path)
Esin Karamanccb714b2019-11-29 15:02:06 +00001354 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001355 logger.Error(ctx, "failed to get data from kv store")
Esin Karamanccb714b2019-11-29 15:02:06 +00001356 return nil, err
1357 }
1358 if kvPair != nil && kvPair.Value != nil {
1359 if val, err = kvstore.ToByte(kvPair.Value); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001360 logger.Error(ctx, "Failed to convert to byte array ", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001361 return nil, err
1362 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001363 rsrcMgr.mcastQueueForIntfLock.Lock()
1364 defer rsrcMgr.mcastQueueForIntfLock.Unlock()
1365 if err = json.Unmarshal(val, &rsrcMgr.mcastQueueForIntf); err != nil {
1366 logger.Error(ctx, "Failed to unmarshall ", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001367 return nil, err
1368 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001369 rsrcMgr.mcastQueueForIntfLoadedFromKvStore = true
Esin Karamanccb714b2019-11-29 15:02:06 +00001370 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001371 return rsrcMgr.mcastQueueForIntf, nil
Esin Karamanccb714b2019-11-29 15:02:06 +00001372}
1373
Joey Armstrong3f0e2422023-07-05 18:25:41 -04001374// AddMcastQueueForIntf adds multicast queue for pon interface
yasin saplibddc2d72022-02-08 13:10:17 +00001375func (rsrcMgr *OpenOltResourceMgr) AddMcastQueueForIntf(ctx context.Context, gem uint32, servicePriority uint32) error {
Esin Karamanccb714b2019-11-29 15:02:06 +00001376 var val []byte
Kent Hagermane6ff1012020-07-14 15:07:53 -04001377 path := McastQueuesForIntf
Esin Karamanccb714b2019-11-29 15:02:06 +00001378
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001379 // Load local cache from kv store the first time
1380 rsrcMgr.mcastQueueForIntfLock.RLock()
1381 if !rsrcMgr.mcastQueueForIntfLoadedFromKvStore {
1382 rsrcMgr.mcastQueueForIntfLock.RUnlock()
1383 _, err := rsrcMgr.GetMcastQueuePerInterfaceMap(ctx)
1384 if err != nil {
yasin saplibddc2d72022-02-08 13:10:17 +00001385 logger.Errorw(ctx, "Failed to get multicast queue info for interface", log.Fields{"err": err, "intf": rsrcMgr.PonIntfID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001386 return err
1387 }
1388 } else {
1389 rsrcMgr.mcastQueueForIntfLock.RUnlock()
1390 }
1391
1392 // Update KV store
1393 rsrcMgr.mcastQueueForIntfLock.Lock()
yasin saplibddc2d72022-02-08 13:10:17 +00001394 rsrcMgr.mcastQueueForIntf[rsrcMgr.PonIntfID] = []uint32{gem, servicePriority}
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001395 val, err := json.Marshal(rsrcMgr.mcastQueueForIntf)
Esin Karamanccb714b2019-11-29 15:02:06 +00001396 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001397 rsrcMgr.mcastQueueForIntfLock.Unlock()
1398 logger.Errorw(ctx, "Failed to marshal data", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001399 return err
1400 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001401 rsrcMgr.mcastQueueForIntfLock.Unlock()
1402
1403 if err = rsrcMgr.KVStore.Put(ctx, path, val); err != nil {
1404 logger.Errorw(ctx, "Failed to put to kvstore", log.Fields{"err": err, "path": path, "value": val})
Esin Karamanccb714b2019-11-29 15:02:06 +00001405 return err
1406 }
yasin saplibddc2d72022-02-08 13:10:17 +00001407 logger.Debugw(ctx, "added multicast queue info to KV store successfully", log.Fields{"path": path, "interfaceId": rsrcMgr.PonIntfID, "gem": gem, "svcPrior": servicePriority})
Esin Karamanccb714b2019-11-29 15:02:06 +00001408 return nil
1409}
1410
Joey Armstrong3f0e2422023-07-05 18:25:41 -04001411// DeleteMcastQueueForIntf deletes multicast queue info for the current pon interface from kvstore
Gustavo Silva41af9122022-10-11 11:05:13 -03001412func (rsrcMgr *OpenOltResourceMgr) DeleteMcastQueueForIntf(ctx context.Context) error {
Girish Gowdraf3728b12022-02-02 21:46:51 -08001413 path := McastQueuesForIntf
1414
1415 if err := rsrcMgr.KVStore.Delete(ctx, path); err != nil {
1416 logger.Errorw(ctx, "Failed to delete multicast queue info from kvstore", log.Fields{"err": err, "interfaceId": rsrcMgr.PonIntfID})
Gustavo Silva41af9122022-10-11 11:05:13 -03001417 return err
Girish Gowdraf3728b12022-02-02 21:46:51 -08001418 }
1419 logger.Debugw(ctx, "deleted multicast queue info from KV store successfully", log.Fields{"interfaceId": rsrcMgr.PonIntfID})
Gustavo Silva41af9122022-10-11 11:05:13 -03001420 return nil
Girish Gowdraf3728b12022-02-02 21:46:51 -08001421}
1422
Joey Armstrong3f0e2422023-07-05 18:25:41 -04001423// AddFlowGroupToKVStore adds flow group into KV store
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001424func (rsrcMgr *OpenOltResourceMgr) AddFlowGroupToKVStore(ctx context.Context, groupEntry *ofp.OfpGroupEntry, cached bool) error {
Esin Karamanccb714b2019-11-29 15:02:06 +00001425 var Value []byte
1426 var err error
1427 var path string
1428 if cached {
1429 path = fmt.Sprintf(FlowGroupCached, groupEntry.Desc.GroupId)
1430 } else {
1431 path = fmt.Sprintf(FlowGroup, groupEntry.Desc.GroupId)
1432 }
Akash Kankanala041a2122024-10-16 15:49:22 +05301433 // build group info object
Esin Karamanccb714b2019-11-29 15:02:06 +00001434 var outPorts []uint32
1435 for _, ofBucket := range groupEntry.Desc.Buckets {
1436 for _, ofAction := range ofBucket.Actions {
1437 if ofAction.Type == ofp.OfpActionType_OFPAT_OUTPUT {
1438 outPorts = append(outPorts, ofAction.GetOutput().Port)
1439 }
1440 }
1441 }
1442 groupInfo := GroupInfo{
1443 GroupID: groupEntry.Desc.GroupId,
1444 OutPorts: outPorts,
1445 }
1446
1447 Value, err = json.Marshal(groupInfo)
1448
1449 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001450 logger.Error(ctx, "failed to Marshal flow group object")
Esin Karamanccb714b2019-11-29 15:02:06 +00001451 return err
1452 }
1453
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001454 if err = rsrcMgr.KVStore.Put(ctx, path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001455 logger.Errorf(ctx, "Failed to update resource %s", path)
Esin Karamanccb714b2019-11-29 15:02:06 +00001456 return err
1457 }
Gamze Abaka745ccb72021-11-18 11:29:58 +00001458
1459 // update cache
1460 rsrcMgr.groupInfoLock.Lock()
1461 rsrcMgr.groupInfo[path] = &groupInfo
1462 rsrcMgr.groupInfoLock.Unlock()
Esin Karamanccb714b2019-11-29 15:02:06 +00001463 return nil
1464}
1465
Joey Armstrong3f0e2422023-07-05 18:25:41 -04001466// RemoveFlowGroupFromKVStore removes flow group from KV store
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001467func (rsrcMgr *OpenOltResourceMgr) RemoveFlowGroupFromKVStore(ctx context.Context, groupID uint32, cached bool) error {
Esin Karamanccb714b2019-11-29 15:02:06 +00001468 var path string
1469 if cached {
1470 path = fmt.Sprintf(FlowGroupCached, groupID)
1471 } else {
1472 path = fmt.Sprintf(FlowGroup, groupID)
1473 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001474
1475 if err := rsrcMgr.KVStore.Delete(ctx, path); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001476 logger.Errorf(ctx, "Failed to remove resource %s due to %s", path, err)
Esin Karamand519bbf2020-07-01 11:16:03 +00001477 return err
Esin Karamanccb714b2019-11-29 15:02:06 +00001478 }
Gamze Abaka745ccb72021-11-18 11:29:58 +00001479
1480 // update cache
1481 rsrcMgr.groupInfoLock.Lock()
1482 delete(rsrcMgr.groupInfo, path)
1483 rsrcMgr.groupInfoLock.Unlock()
Esin Karamand519bbf2020-07-01 11:16:03 +00001484 return nil
Esin Karamanccb714b2019-11-29 15:02:06 +00001485}
1486
Joey Armstrong3f0e2422023-07-05 18:25:41 -04001487// GetFlowGroupFromKVStore fetches flow group from the KV store. Returns (false, {} error) if any problem occurs during
1488// fetching the data. Returns (true, groupInfo, nil) if the group is fetched successfully.
Esin Karamanccb714b2019-11-29 15:02:06 +00001489// Returns (false, {}, nil) if the group does not exists in the KV store.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001490func (rsrcMgr *OpenOltResourceMgr) GetFlowGroupFromKVStore(ctx context.Context, groupID uint32, cached bool) (bool, GroupInfo, error) {
Esin Karamanccb714b2019-11-29 15:02:06 +00001491 var groupInfo GroupInfo
1492 var path string
1493 if cached {
1494 path = fmt.Sprintf(FlowGroupCached, groupID)
1495 } else {
1496 path = fmt.Sprintf(FlowGroup, groupID)
1497 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001498
1499 // read from cache
1500 rsrcMgr.groupInfoLock.RLock()
1501 gi, ok := rsrcMgr.groupInfo[path]
1502 rsrcMgr.groupInfoLock.RUnlock()
1503 if ok {
1504 return true, *gi, nil
1505 }
1506
1507 kvPair, err := rsrcMgr.KVStore.Get(ctx, path)
Esin Karamanccb714b2019-11-29 15:02:06 +00001508 if err != nil {
1509 return false, groupInfo, err
1510 }
1511 if kvPair != nil && kvPair.Value != nil {
1512 Val, err := kvstore.ToByte(kvPair.Value)
1513 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001514 logger.Errorw(ctx, "Failed to convert flow group into byte array", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001515 return false, groupInfo, err
1516 }
1517 if err = json.Unmarshal(Val, &groupInfo); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001518 logger.Errorw(ctx, "Failed to unmarshal", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001519 return false, groupInfo, err
1520 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001521 // update cache
1522 rsrcMgr.groupInfoLock.Lock()
1523 rsrcMgr.groupInfo[path] = &groupInfo
1524 rsrcMgr.groupInfoLock.Unlock()
1525
Esin Karamanccb714b2019-11-29 15:02:06 +00001526 return true, groupInfo, nil
1527 }
1528 return false, groupInfo, nil
1529}
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001530
yasin sapli9e4c5092022-02-01 13:52:33 +00001531// GetOnuGemInfoList returns all gems in the onuGemInfo map
1532func (rsrcMgr *OpenOltResourceMgr) GetOnuGemInfoList(ctx context.Context) []OnuGemInfo {
1533 var onuGemInfoLst []OnuGemInfo
1534 rsrcMgr.onuGemInfoLock.RLock()
1535 defer rsrcMgr.onuGemInfoLock.RUnlock()
1536 for _, v := range rsrcMgr.onuGemInfo {
1537 onuGemInfoLst = append(onuGemInfoLst, *v)
1538 }
1539 return onuGemInfoLst
1540}
1541
yasin sapli9e4c5092022-02-01 13:52:33 +00001542func appendUnique64bit(slice []uint64, item uint64) []uint64 {
1543 for _, sliceElement := range slice {
1544 if sliceElement == item {
1545 return slice
1546 }
1547 }
1548 return append(slice, item)
1549}