blob: d751723c778bb01525d0e6720732c9ba7345733c [file] [log] [blame]
Scott Baker2c1c4822019-10-16 11:02:41 -07001/*
2 * Copyright 2019-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package ponresourcemanager
18
19import (
npujar5bf737f2020-01-16 19:35:25 +053020 "context"
Scott Baker2c1c4822019-10-16 11:02:41 -070021 "encoding/base64"
22 "encoding/json"
23 "errors"
24 "fmt"
Neha Sharma130ac6d2020-04-08 08:46:32 +000025 "time"
Scott Baker2c1c4822019-10-16 11:02:41 -070026
serkant.uluderyab38671c2019-11-01 09:35:38 -070027 bitmap "github.com/boljen/go-bitmap"
khenaidoo26721882021-08-11 17:42:52 -040028 "github.com/opencord/voltha-lib-go/v7/pkg/db"
29 "github.com/opencord/voltha-lib-go/v7/pkg/db/kvstore"
30 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Scott Baker2c1c4822019-10-16 11:02:41 -070031)
32
33const (
34 //Constants to identify resource pool
35 UNI_ID = "UNI_ID"
36 ONU_ID = "ONU_ID"
37 ALLOC_ID = "ALLOC_ID"
38 GEMPORT_ID = "GEMPORT_ID"
39 FLOW_ID = "FLOW_ID"
40
khenaidoo26721882021-08-11 17:42:52 -040041 //Constants for passing command line arguments
Scott Baker2c1c4822019-10-16 11:02:41 -070042 OLT_MODEL_ARG = "--olt_model"
Matteo Scandolo29ff79c2020-11-06 13:03:17 -080043
44 PATH_PREFIX = "%s/resource_manager/{%s}"
Esin Karaman5351fc52020-02-14 07:45:49 +000045
46 /*The path under which configuration data is stored is defined as technology/device agnostic.
47 That means the path does not include any specific technology/device variable. Using technology/device
48 agnostic path also makes northbound applications, that need to write to this path,
49 technology/device agnostic.
50
51 Default kv client of PonResourceManager reads from/writes to PATH_PREFIX defined above.
52 That is why, an additional kv client (named KVStoreForConfig) is defined to read from the config path.
53 */
Matteo Scandolo29ff79c2020-11-06 13:03:17 -080054
55 PATH_PREFIX_FOR_CONFIG = "%s/resource_manager/config"
Scott Baker2c1c4822019-10-16 11:02:41 -070056 /*The resource ranges for a given device model should be placed
57 at 'resource_manager/<technology>/resource_ranges/<olt_model_type>'
58 path on the KV store.
59 If Resource Range parameters are to be read from the external KV store,
60 they are expected to be stored in the following format.
61 Note: All parameters are MANDATORY for now.
62 constants used as keys to reference the resource range parameters from
63 and external KV store.
64 */
65 UNI_ID_START_IDX = "uni_id_start"
66 UNI_ID_END_IDX = "uni_id_end"
67 ONU_ID_START_IDX = "onu_id_start"
68 ONU_ID_END_IDX = "onu_id_end"
69 ONU_ID_SHARED_IDX = "onu_id_shared"
70 ALLOC_ID_START_IDX = "alloc_id_start"
71 ALLOC_ID_END_IDX = "alloc_id_end"
72 ALLOC_ID_SHARED_IDX = "alloc_id_shared"
73 GEMPORT_ID_START_IDX = "gemport_id_start"
74 GEMPORT_ID_END_IDX = "gemport_id_end"
75 GEMPORT_ID_SHARED_IDX = "gemport_id_shared"
76 FLOW_ID_START_IDX = "flow_id_start"
77 FLOW_ID_END_IDX = "flow_id_end"
78 FLOW_ID_SHARED_IDX = "flow_id_shared"
79 NUM_OF_PON_PORT = "pon_ports"
80
81 /*
82 The KV store backend is initialized with a path prefix and we need to
83 provide only the suffix.
84 */
85 PON_RESOURCE_RANGE_CONFIG_PATH = "resource_ranges/%s"
86
87 //resource path suffix
88 //Path on the KV store for storing alloc id ranges and resource pool for a given interface
89 //Format: <device_id>/alloc_id_pool/<pon_intf_id>
90 ALLOC_ID_POOL_PATH = "{%s}/alloc_id_pool/{%d}"
91 //Path on the KV store for storing gemport id ranges and resource pool for a given interface
92 //Format: <device_id>/gemport_id_pool/<pon_intf_id>
93 GEMPORT_ID_POOL_PATH = "{%s}/gemport_id_pool/{%d}"
94 //Path on the KV store for storing onu id ranges and resource pool for a given interface
95 //Format: <device_id>/onu_id_pool/<pon_intf_id>
96 ONU_ID_POOL_PATH = "{%s}/onu_id_pool/{%d}"
97 //Path on the KV store for storing flow id ranges and resource pool for a given interface
98 //Format: <device_id>/flow_id_pool/<pon_intf_id>
99 FLOW_ID_POOL_PATH = "{%s}/flow_id_pool/{%d}"
100
101 //Path on the KV store for storing list of alloc IDs for a given ONU
102 //Format: <device_id>/<(pon_intf_id, onu_id)>/alloc_ids
103 ALLOC_ID_RESOURCE_MAP_PATH = "{%s}/{%s}/alloc_ids"
104
105 //Path on the KV store for storing list of gemport IDs for a given ONU
106 //Format: <device_id>/<(pon_intf_id, onu_id)>/gemport_ids
107 GEMPORT_ID_RESOURCE_MAP_PATH = "{%s}/{%s}/gemport_ids"
108
109 //Path on the KV store for storing list of Flow IDs for a given ONU
110 //Format: <device_id>/<(pon_intf_id, onu_id)>/flow_ids
111 FLOW_ID_RESOURCE_MAP_PATH = "{%s}/{%s}/flow_ids"
112
113 //Flow Id info: Use to store more metadata associated with the flow_id
Serkant Uluderya198de902020-11-16 20:29:17 +0300114 FLOW_ID_INFO_PATH_PREFIX = "{%s}/flow_id_info"
115 //Format: <device_id>/flow_id_info/<(pon_intf_id, onu_id)>
116 FLOW_ID_INFO_PATH_INTF_ONU_PREFIX = "{%s}/flow_id_info/{%s}"
117 //Format: <device_id>/flow_id_info/<(pon_intf_id, onu_id)><flow_id>
118 FLOW_ID_INFO_PATH = FLOW_ID_INFO_PATH_PREFIX + "/{%s}/{%d}"
Scott Baker2c1c4822019-10-16 11:02:41 -0700119
120 //Constants for internal usage.
121 PON_INTF_ID = "pon_intf_id"
122 START_IDX = "start_idx"
123 END_IDX = "end_idx"
124 POOL = "pool"
125 NUM_OF_PON_INTF = 16
126
Neha Sharma130ac6d2020-04-08 08:46:32 +0000127 KVSTORE_RETRY_TIMEOUT = 5 * time.Second
Esin Karaman5351fc52020-02-14 07:45:49 +0000128 //Path on the KV store for storing reserved gem ports
129 //Format: reserved_gemport_ids
130 RESERVED_GEMPORT_IDS_PATH = "reserved_gemport_ids"
Scott Baker2c1c4822019-10-16 11:02:41 -0700131)
132
133//type ResourceTypeIndex string
134//type ResourceType string
135
136type PONResourceManager struct {
137 //Implements APIs to initialize/allocate/release alloc/gemport/onu IDs.
Esin Karaman5351fc52020-02-14 07:45:49 +0000138 Technology string
139 DeviceType string
140 DeviceID string
serkant.uluderya2f2855e2021-01-30 12:43:40 +0300141 Backend string // ETCD only currently
Neha Sharmadd9af392020-04-28 09:03:57 +0000142 Address string // address of the KV store
Esin Karaman5351fc52020-02-14 07:45:49 +0000143 OLTModel string
144 KVStore *db.Backend
145 KVStoreForConfig *db.Backend
Scott Baker2c1c4822019-10-16 11:02:41 -0700146
147 // Below attribute, pon_resource_ranges, should be initialized
148 // by reading from KV store.
149 PonResourceRanges map[string]interface{}
150 SharedResourceMgrs map[string]*PONResourceManager
151 SharedIdxByType map[string]string
152 IntfIDs []uint32 // list of pon interface IDs
153 Globalorlocal string
154}
155
Neha Sharma94f16a92020-06-26 04:17:55 +0000156func newKVClient(ctx context.Context, storeType string, address string, timeout time.Duration) (kvstore.Client, error) {
157 logger.Infow(ctx, "kv-store-type", log.Fields{"store": storeType})
Scott Baker2c1c4822019-10-16 11:02:41 -0700158 switch storeType {
Scott Baker2c1c4822019-10-16 11:02:41 -0700159 case "etcd":
Neha Sharma94f16a92020-06-26 04:17:55 +0000160 return kvstore.NewEtcdClient(ctx, address, timeout, log.WarnLevel)
serkant.uluderyae5afeff2021-02-23 18:00:23 +0300161 case "redis":
162 return kvstore.NewRedisClient(address, timeout, false)
163 case "redis-sentinel":
164 return kvstore.NewRedisClient(address, timeout, true)
Scott Baker2c1c4822019-10-16 11:02:41 -0700165 }
166 return nil, errors.New("unsupported-kv-store")
167}
168
Matteo Scandolo29ff79c2020-11-06 13:03:17 -0800169func SetKVClient(ctx context.Context, Technology string, Backend string, Addr string, configClient bool, basePathKvStore string) *db.Backend {
Scott Baker2c1c4822019-10-16 11:02:41 -0700170 // TODO : Make sure direct call to NewBackend is working fine with backend , currently there is some
171 // issue between kv store and backend , core is not calling NewBackend directly
Neha Sharma94f16a92020-06-26 04:17:55 +0000172 kvClient, err := newKVClient(ctx, Backend, Addr, KVSTORE_RETRY_TIMEOUT)
Scott Baker2c1c4822019-10-16 11:02:41 -0700173 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000174 logger.Fatalw(ctx, "Failed to init KV client\n", log.Fields{"err": err})
Scott Baker2c1c4822019-10-16 11:02:41 -0700175 return nil
176 }
Esin Karaman5351fc52020-02-14 07:45:49 +0000177
178 var pathPrefix string
179 if configClient {
Matteo Scandolo29ff79c2020-11-06 13:03:17 -0800180 pathPrefix = fmt.Sprintf(PATH_PREFIX_FOR_CONFIG, basePathKvStore)
Esin Karaman5351fc52020-02-14 07:45:49 +0000181 } else {
Matteo Scandolo29ff79c2020-11-06 13:03:17 -0800182 pathPrefix = fmt.Sprintf(PATH_PREFIX, basePathKvStore, Technology)
Esin Karaman5351fc52020-02-14 07:45:49 +0000183 }
184
sbarbari1e3e29c2019-11-05 10:06:50 -0500185 kvbackend := &db.Backend{
Scott Baker2c1c4822019-10-16 11:02:41 -0700186 Client: kvClient,
187 StoreType: Backend,
Neha Sharmadd9af392020-04-28 09:03:57 +0000188 Address: Addr,
Scott Baker2c1c4822019-10-16 11:02:41 -0700189 Timeout: KVSTORE_RETRY_TIMEOUT,
Esin Karaman5351fc52020-02-14 07:45:49 +0000190 PathPrefix: pathPrefix}
Scott Baker2c1c4822019-10-16 11:02:41 -0700191
192 return kvbackend
193}
194
195// NewPONResourceManager creates a new PON resource manager.
Matteo Scandolo29ff79c2020-11-06 13:03:17 -0800196func NewPONResourceManager(ctx context.Context, Technology string, DeviceType string, DeviceID string, Backend string, Address string, basePathKvStore string) (*PONResourceManager, error) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700197 var PONMgr PONResourceManager
198 PONMgr.Technology = Technology
199 PONMgr.DeviceType = DeviceType
200 PONMgr.DeviceID = DeviceID
201 PONMgr.Backend = Backend
Neha Sharmadd9af392020-04-28 09:03:57 +0000202 PONMgr.Address = Address
Matteo Scandolo29ff79c2020-11-06 13:03:17 -0800203 PONMgr.KVStore = SetKVClient(ctx, Technology, Backend, Address, false, basePathKvStore)
Scott Baker2c1c4822019-10-16 11:02:41 -0700204 if PONMgr.KVStore == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000205 logger.Error(ctx, "KV Client initilization failed")
Scott Baker2c1c4822019-10-16 11:02:41 -0700206 return nil, errors.New("Failed to init KV client")
207 }
Esin Karaman5351fc52020-02-14 07:45:49 +0000208 // init kv client to read from the config path
Matteo Scandolo29ff79c2020-11-06 13:03:17 -0800209 PONMgr.KVStoreForConfig = SetKVClient(ctx, Technology, Backend, Address, true, basePathKvStore)
Esin Karaman5351fc52020-02-14 07:45:49 +0000210 if PONMgr.KVStoreForConfig == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000211 logger.Error(ctx, "KV Config Client initilization failed")
Esin Karaman5351fc52020-02-14 07:45:49 +0000212 return nil, errors.New("Failed to init KV Config client")
213 }
Girish Gowdrad72fef42021-07-22 16:30:58 -0700214
Scott Baker2c1c4822019-10-16 11:02:41 -0700215 PONMgr.PonResourceRanges = make(map[string]interface{})
216 PONMgr.SharedResourceMgrs = make(map[string]*PONResourceManager)
217 PONMgr.SharedIdxByType = make(map[string]string)
218 PONMgr.SharedIdxByType[ONU_ID] = ONU_ID_SHARED_IDX
219 PONMgr.SharedIdxByType[ALLOC_ID] = ALLOC_ID_SHARED_IDX
220 PONMgr.SharedIdxByType[GEMPORT_ID] = GEMPORT_ID_SHARED_IDX
221 PONMgr.SharedIdxByType[FLOW_ID] = FLOW_ID_SHARED_IDX
222 PONMgr.IntfIDs = make([]uint32, NUM_OF_PON_INTF)
223 PONMgr.OLTModel = DeviceType
224 return &PONMgr, nil
225}
226
227/*
228 Initialize PON resource ranges with config fetched from kv store.
229 return boolean: True if PON resource ranges initialized else false
230 Try to initialize the PON Resource Ranges from KV store based on the
231 OLT model key, if available
232*/
233
npujar5bf737f2020-01-16 19:35:25 +0530234func (PONRMgr *PONResourceManager) InitResourceRangesFromKVStore(ctx context.Context) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -0700235 //Initialize PON resource ranges with config fetched from kv store.
236 //:return boolean: True if PON resource ranges initialized else false
237 // Try to initialize the PON Resource Ranges from KV store based on the
238 // OLT model key, if available
239 if PONRMgr.OLTModel == "" {
Neha Sharma94f16a92020-06-26 04:17:55 +0000240 logger.Error(ctx, "Failed to get OLT model")
Scott Baker2c1c4822019-10-16 11:02:41 -0700241 return false
242 }
243 Path := fmt.Sprintf(PON_RESOURCE_RANGE_CONFIG_PATH, PONRMgr.OLTModel)
244 //get resource from kv store
npujar5bf737f2020-01-16 19:35:25 +0530245 Result, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700246 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000247 logger.Debugf(ctx, "Error in fetching resource %s from KV strore", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700248 return false
249 }
250 if Result == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000251 logger.Debug(ctx, "There may be no resources in the KV store in case of fresh bootup, return true")
Scott Baker2c1c4822019-10-16 11:02:41 -0700252 return false
253 }
254 //update internal ranges from kv ranges. If there are missing
255 // values in the KV profile, continue to use the defaults
256 Value, err := ToByte(Result.Value)
257 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000258 logger.Error(ctx, "Failed to convert kvpair to byte string")
Scott Baker2c1c4822019-10-16 11:02:41 -0700259 return false
260 }
261 if err := json.Unmarshal(Value, &PONRMgr.PonResourceRanges); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000262 logger.Error(ctx, "Failed to Unmarshal json byte")
Scott Baker2c1c4822019-10-16 11:02:41 -0700263 return false
264 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000265 logger.Debug(ctx, "Init resource ranges from kvstore success")
Scott Baker2c1c4822019-10-16 11:02:41 -0700266 return true
267}
268
Neha Sharma94f16a92020-06-26 04:17:55 +0000269func (PONRMgr *PONResourceManager) UpdateRanges(ctx context.Context, StartIDx string, StartID uint32, EndIDx string, EndID uint32,
Scott Baker2c1c4822019-10-16 11:02:41 -0700270 SharedIDx string, SharedPoolID uint32, RMgr *PONResourceManager) {
271 /*
272 Update the ranges for all reosurce type in the intermnal maps
273 param: resource type start index
274 param: start ID
275 param: resource type end index
276 param: end ID
277 param: resource type shared index
278 param: shared pool id
279 param: global resource manager
280 */
Neha Sharma94f16a92020-06-26 04:17:55 +0000281 logger.Debugf(ctx, "update ranges for %s, %d", StartIDx, StartID)
Scott Baker2c1c4822019-10-16 11:02:41 -0700282
283 if StartID != 0 {
284 if (PONRMgr.PonResourceRanges[StartIDx] == nil) || (PONRMgr.PonResourceRanges[StartIDx].(uint32) < StartID) {
285 PONRMgr.PonResourceRanges[StartIDx] = StartID
286 }
287 }
288 if EndID != 0 {
289 if (PONRMgr.PonResourceRanges[EndIDx] == nil) || (PONRMgr.PonResourceRanges[EndIDx].(uint32) > EndID) {
290 PONRMgr.PonResourceRanges[EndIDx] = EndID
291 }
292 }
293 //if SharedPoolID != 0 {
294 PONRMgr.PonResourceRanges[SharedIDx] = SharedPoolID
295 //}
296 if RMgr != nil {
297 PONRMgr.SharedResourceMgrs[SharedIDx] = RMgr
298 }
299}
300
Neha Sharma94f16a92020-06-26 04:17:55 +0000301func (PONRMgr *PONResourceManager) InitDefaultPONResourceRanges(ctx context.Context,
302 ONUIDStart uint32,
Scott Baker2c1c4822019-10-16 11:02:41 -0700303 ONUIDEnd uint32,
304 ONUIDSharedPoolID uint32,
305 AllocIDStart uint32,
306 AllocIDEnd uint32,
307 AllocIDSharedPoolID uint32,
308 GEMPortIDStart uint32,
309 GEMPortIDEnd uint32,
310 GEMPortIDSharedPoolID uint32,
311 FlowIDStart uint32,
312 FlowIDEnd uint32,
313 FlowIDSharedPoolID uint32,
314 UNIIDStart uint32,
315 UNIIDEnd uint32,
316 NoOfPONPorts uint32,
317 IntfIDs []uint32) bool {
318
319 /*Initialize default PON resource ranges
320
321 :param onu_id_start_idx: onu id start index
322 :param onu_id_end_idx: onu id end index
323 :param onu_id_shared_pool_id: pool idx for id shared by all intfs or None for no sharing
324 :param alloc_id_start_idx: alloc id start index
325 :param alloc_id_end_idx: alloc id end index
326 :param alloc_id_shared_pool_id: pool idx for alloc id shared by all intfs or None for no sharing
327 :param gemport_id_start_idx: gemport id start index
328 :param gemport_id_end_idx: gemport id end index
329 :param gemport_id_shared_pool_id: pool idx for gemport id shared by all intfs or None for no sharing
330 :param flow_id_start_idx: flow id start index
331 :param flow_id_end_idx: flow id end index
332 :param flow_id_shared_pool_id: pool idx for flow id shared by all intfs or None for no sharing
333 :param num_of_pon_ports: number of PON ports
334 :param intf_ids: interfaces serviced by this manager
335 */
Neha Sharma94f16a92020-06-26 04:17:55 +0000336 PONRMgr.UpdateRanges(ctx, ONU_ID_START_IDX, ONUIDStart, ONU_ID_END_IDX, ONUIDEnd, ONU_ID_SHARED_IDX, ONUIDSharedPoolID, nil)
337 PONRMgr.UpdateRanges(ctx, ALLOC_ID_START_IDX, AllocIDStart, ALLOC_ID_END_IDX, AllocIDEnd, ALLOC_ID_SHARED_IDX, AllocIDSharedPoolID, nil)
338 PONRMgr.UpdateRanges(ctx, GEMPORT_ID_START_IDX, GEMPortIDStart, GEMPORT_ID_END_IDX, GEMPortIDEnd, GEMPORT_ID_SHARED_IDX, GEMPortIDSharedPoolID, nil)
339 PONRMgr.UpdateRanges(ctx, FLOW_ID_START_IDX, FlowIDStart, FLOW_ID_END_IDX, FlowIDEnd, FLOW_ID_SHARED_IDX, FlowIDSharedPoolID, nil)
340 PONRMgr.UpdateRanges(ctx, UNI_ID_START_IDX, UNIIDStart, UNI_ID_END_IDX, UNIIDEnd, "", 0, nil)
341 logger.Debug(ctx, "Initialize default range values")
Scott Baker2c1c4822019-10-16 11:02:41 -0700342 var i uint32
343 if IntfIDs == nil {
344 for i = 0; i < NoOfPONPorts; i++ {
345 PONRMgr.IntfIDs = append(PONRMgr.IntfIDs, i)
346 }
347 } else {
348 PONRMgr.IntfIDs = IntfIDs
349 }
350 return true
351}
352
npujar5bf737f2020-01-16 19:35:25 +0530353func (PONRMgr *PONResourceManager) InitDeviceResourcePool(ctx context.Context) error {
Scott Baker2c1c4822019-10-16 11:02:41 -0700354
355 //Initialize resource pool for all PON ports.
356
Neha Sharma94f16a92020-06-26 04:17:55 +0000357 logger.Debug(ctx, "Init resource ranges")
Scott Baker2c1c4822019-10-16 11:02:41 -0700358
359 var err error
360 for _, Intf := range PONRMgr.IntfIDs {
361 SharedPoolID := PONRMgr.PonResourceRanges[ONU_ID_SHARED_IDX].(uint32)
362 if SharedPoolID != 0 {
363 Intf = SharedPoolID
364 }
npujar5bf737f2020-01-16 19:35:25 +0530365 if err = PONRMgr.InitResourceIDPool(ctx, Intf, ONU_ID,
Scott Baker2c1c4822019-10-16 11:02:41 -0700366 PONRMgr.PonResourceRanges[ONU_ID_START_IDX].(uint32),
367 PONRMgr.PonResourceRanges[ONU_ID_END_IDX].(uint32)); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000368 logger.Error(ctx, "Failed to init ONU ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700369 return err
370 }
371 if SharedPoolID != 0 {
372 break
373 }
374 }
375
376 for _, Intf := range PONRMgr.IntfIDs {
377 SharedPoolID := PONRMgr.PonResourceRanges[ALLOC_ID_SHARED_IDX].(uint32)
378 if SharedPoolID != 0 {
379 Intf = SharedPoolID
380 }
npujar5bf737f2020-01-16 19:35:25 +0530381 if err = PONRMgr.InitResourceIDPool(ctx, Intf, ALLOC_ID,
Scott Baker2c1c4822019-10-16 11:02:41 -0700382 PONRMgr.PonResourceRanges[ALLOC_ID_START_IDX].(uint32),
383 PONRMgr.PonResourceRanges[ALLOC_ID_END_IDX].(uint32)); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000384 logger.Error(ctx, "Failed to init ALLOC ID resource pool ")
Scott Baker2c1c4822019-10-16 11:02:41 -0700385 return err
386 }
387 if SharedPoolID != 0 {
388 break
389 }
390 }
391 for _, Intf := range PONRMgr.IntfIDs {
392 SharedPoolID := PONRMgr.PonResourceRanges[GEMPORT_ID_SHARED_IDX].(uint32)
393 if SharedPoolID != 0 {
394 Intf = SharedPoolID
395 }
npujar5bf737f2020-01-16 19:35:25 +0530396 if err = PONRMgr.InitResourceIDPool(ctx, Intf, GEMPORT_ID,
Scott Baker2c1c4822019-10-16 11:02:41 -0700397 PONRMgr.PonResourceRanges[GEMPORT_ID_START_IDX].(uint32),
398 PONRMgr.PonResourceRanges[GEMPORT_ID_END_IDX].(uint32)); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000399 logger.Error(ctx, "Failed to init GEMPORT ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700400 return err
401 }
402 if SharedPoolID != 0 {
403 break
404 }
405 }
406
407 for _, Intf := range PONRMgr.IntfIDs {
408 SharedPoolID := PONRMgr.PonResourceRanges[FLOW_ID_SHARED_IDX].(uint32)
409 if SharedPoolID != 0 {
410 Intf = SharedPoolID
411 }
npujar5bf737f2020-01-16 19:35:25 +0530412 if err = PONRMgr.InitResourceIDPool(ctx, Intf, FLOW_ID,
Scott Baker2c1c4822019-10-16 11:02:41 -0700413 PONRMgr.PonResourceRanges[FLOW_ID_START_IDX].(uint32),
414 PONRMgr.PonResourceRanges[FLOW_ID_END_IDX].(uint32)); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000415 logger.Error(ctx, "Failed to init FLOW ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700416 return err
417 }
418 if SharedPoolID != 0 {
419 break
420 }
421 }
422 return err
423}
424
Girish Gowdra248971a2021-06-01 15:14:15 -0700425func (PONRMgr *PONResourceManager) InitDeviceResourcePoolForIntf(ctx context.Context, intfID uint32) error {
426
427 logger.Debug(ctx, "Init resource ranges for intf %d", intfID)
428
429 var err error
430
431 if err = PONRMgr.InitResourceIDPool(ctx, intfID, ONU_ID,
432 PONRMgr.PonResourceRanges[ONU_ID_START_IDX].(uint32),
433 PONRMgr.PonResourceRanges[ONU_ID_END_IDX].(uint32)); err != nil {
434 logger.Error(ctx, "Failed to init ONU ID resource pool")
435 return err
436 }
437
438 if err = PONRMgr.InitResourceIDPool(ctx, intfID, ALLOC_ID,
439 PONRMgr.PonResourceRanges[ALLOC_ID_START_IDX].(uint32),
440 PONRMgr.PonResourceRanges[ALLOC_ID_END_IDX].(uint32)); err != nil {
441 logger.Error(ctx, "Failed to init ALLOC ID resource pool ")
442 return err
443 }
444
445 if err = PONRMgr.InitResourceIDPool(ctx, intfID, GEMPORT_ID,
446 PONRMgr.PonResourceRanges[GEMPORT_ID_START_IDX].(uint32),
447 PONRMgr.PonResourceRanges[GEMPORT_ID_END_IDX].(uint32)); err != nil {
448 logger.Error(ctx, "Failed to init GEMPORT ID resource pool")
449 return err
450 }
451
452 if err = PONRMgr.InitResourceIDPool(ctx, intfID, FLOW_ID,
453 PONRMgr.PonResourceRanges[FLOW_ID_START_IDX].(uint32),
454 PONRMgr.PonResourceRanges[FLOW_ID_END_IDX].(uint32)); err != nil {
455 logger.Error(ctx, "Failed to init FLOW ID resource pool")
456 return err
457 }
458
459 return nil
460}
461
npujar5bf737f2020-01-16 19:35:25 +0530462func (PONRMgr *PONResourceManager) ClearDeviceResourcePool(ctx context.Context) error {
Scott Baker2c1c4822019-10-16 11:02:41 -0700463
464 //Clear resource pool for all PON ports.
465
Neha Sharma94f16a92020-06-26 04:17:55 +0000466 logger.Debug(ctx, "Clear resource ranges")
Scott Baker2c1c4822019-10-16 11:02:41 -0700467
468 for _, Intf := range PONRMgr.IntfIDs {
469 SharedPoolID := PONRMgr.PonResourceRanges[ONU_ID_SHARED_IDX].(uint32)
470 if SharedPoolID != 0 {
471 Intf = SharedPoolID
472 }
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800473 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, ONU_ID); !status {
Neha Sharma94f16a92020-06-26 04:17:55 +0000474 logger.Error(ctx, "Failed to clear ONU ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700475 return errors.New("Failed to clear ONU ID resource pool")
476 }
477 if SharedPoolID != 0 {
478 break
479 }
480 }
481
482 for _, Intf := range PONRMgr.IntfIDs {
483 SharedPoolID := PONRMgr.PonResourceRanges[ALLOC_ID_SHARED_IDX].(uint32)
484 if SharedPoolID != 0 {
485 Intf = SharedPoolID
486 }
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800487 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, ALLOC_ID); !status {
Neha Sharma94f16a92020-06-26 04:17:55 +0000488 logger.Error(ctx, "Failed to clear ALLOC ID resource pool ")
Scott Baker2c1c4822019-10-16 11:02:41 -0700489 return errors.New("Failed to clear ALLOC ID resource pool")
490 }
491 if SharedPoolID != 0 {
492 break
493 }
494 }
495 for _, Intf := range PONRMgr.IntfIDs {
496 SharedPoolID := PONRMgr.PonResourceRanges[GEMPORT_ID_SHARED_IDX].(uint32)
497 if SharedPoolID != 0 {
498 Intf = SharedPoolID
499 }
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800500 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, GEMPORT_ID); !status {
Neha Sharma94f16a92020-06-26 04:17:55 +0000501 logger.Error(ctx, "Failed to clear GEMPORT ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700502 return errors.New("Failed to clear GEMPORT ID resource pool")
503 }
504 if SharedPoolID != 0 {
505 break
506 }
507 }
508
509 for _, Intf := range PONRMgr.IntfIDs {
510 SharedPoolID := PONRMgr.PonResourceRanges[FLOW_ID_SHARED_IDX].(uint32)
511 if SharedPoolID != 0 {
512 Intf = SharedPoolID
513 }
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800514 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, FLOW_ID); !status {
Neha Sharma94f16a92020-06-26 04:17:55 +0000515 logger.Error(ctx, "Failed to clear FLOW ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700516 return errors.New("Failed to clear FLOW ID resource pool")
517 }
518 if SharedPoolID != 0 {
519 break
520 }
521 }
522 return nil
523}
524
Girish Gowdra248971a2021-06-01 15:14:15 -0700525func (PONRMgr *PONResourceManager) ClearDeviceResourcePoolForIntf(ctx context.Context, intfID uint32) error {
526
527 logger.Debugf(ctx, "Clear resource ranges for intf %d", intfID)
528
529 if status := PONRMgr.ClearResourceIDPool(ctx, intfID, ONU_ID); !status {
530 logger.Error(ctx, "Failed to clear ONU ID resource pool")
531 return errors.New("Failed to clear ONU ID resource pool")
532 }
533
534 if status := PONRMgr.ClearResourceIDPool(ctx, intfID, ALLOC_ID); !status {
535 logger.Error(ctx, "Failed to clear ALLOC ID resource pool ")
536 return errors.New("Failed to clear ALLOC ID resource pool")
537 }
538
539 if status := PONRMgr.ClearResourceIDPool(ctx, intfID, GEMPORT_ID); !status {
540 logger.Error(ctx, "Failed to clear GEMPORT ID resource pool")
541 return errors.New("Failed to clear GEMPORT ID resource pool")
542 }
543
544 if status := PONRMgr.ClearResourceIDPool(ctx, intfID, FLOW_ID); !status {
545 logger.Error(ctx, "Failed to clear FLOW ID resource pool")
546 return errors.New("Failed to clear FLOW ID resource pool")
547 }
548
549 return nil
550}
551
npujar5bf737f2020-01-16 19:35:25 +0530552func (PONRMgr *PONResourceManager) InitResourceIDPool(ctx context.Context, Intf uint32, ResourceType string, StartID uint32, EndID uint32) error {
Scott Baker2c1c4822019-10-16 11:02:41 -0700553
554 /*Initialize Resource ID pool for a given Resource Type on a given PON Port
555
556 :param pon_intf_id: OLT PON interface id
557 :param resource_type: String to identify type of resource
558 :param start_idx: start index for onu id pool
559 :param end_idx: end index for onu id pool
560 :return boolean: True if resource id pool initialized else false
561 */
562
563 // delegate to the master instance if sharing enabled across instances
564 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
565 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujar5bf737f2020-01-16 19:35:25 +0530566 return SharedResourceMgr.InitResourceIDPool(ctx, Intf, ResourceType, StartID, EndID)
Scott Baker2c1c4822019-10-16 11:02:41 -0700567 }
568
Neha Sharma94f16a92020-06-26 04:17:55 +0000569 Path := PONRMgr.GetPath(ctx, Intf, ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700570 if Path == "" {
Neha Sharma94f16a92020-06-26 04:17:55 +0000571 logger.Errorf(ctx, "Failed to get path for resource type %s", ResourceType)
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800572 return fmt.Errorf("Failed to get path for resource type %s", ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700573 }
574
575 //In case of adapter reboot and reconciliation resource in kv store
576 //checked for its presence if not kv store update happens
npujar5bf737f2020-01-16 19:35:25 +0530577 Res, err := PONRMgr.GetResource(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700578 if (err == nil) && (Res != nil) {
Neha Sharma94f16a92020-06-26 04:17:55 +0000579 logger.Debugf(ctx, "Resource %s already present in store ", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700580 return nil
581 } else {
Esin Karaman5351fc52020-02-14 07:45:49 +0000582 var excluded []uint32
583 if ResourceType == GEMPORT_ID {
584 //get gem port ids defined in the KV store, if any, and exclude them from the gem port id pool
585 if reservedGemPortIds, defined := PONRMgr.getReservedGemPortIdsFromKVStore(ctx); defined {
586 excluded = reservedGemPortIds
Neha Sharma94f16a92020-06-26 04:17:55 +0000587 logger.Debugw(ctx, "Excluding some ports from GEM port id pool", log.Fields{"excluded gem ports": excluded})
Esin Karaman5351fc52020-02-14 07:45:49 +0000588 }
589 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000590 FormatResult, err := PONRMgr.FormatResource(ctx, Intf, StartID, EndID, excluded)
Scott Baker2c1c4822019-10-16 11:02:41 -0700591 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000592 logger.Errorf(ctx, "Failed to format resource")
Scott Baker2c1c4822019-10-16 11:02:41 -0700593 return err
594 }
595 // Add resource as json in kv store.
npujar5bf737f2020-01-16 19:35:25 +0530596 err = PONRMgr.KVStore.Put(ctx, Path, FormatResult)
Scott Baker2c1c4822019-10-16 11:02:41 -0700597 if err == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000598 logger.Debug(ctx, "Successfuly posted to kv store")
Scott Baker2c1c4822019-10-16 11:02:41 -0700599 return err
600 }
601 }
602
Neha Sharma94f16a92020-06-26 04:17:55 +0000603 logger.Debug(ctx, "Error initializing pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700604
605 return err
606}
607
Esin Karaman5351fc52020-02-14 07:45:49 +0000608func (PONRMgr *PONResourceManager) getReservedGemPortIdsFromKVStore(ctx context.Context) ([]uint32, bool) {
609 var reservedGemPortIds []uint32
610 // read reserved gem ports from the config path
611 KvPair, err := PONRMgr.KVStoreForConfig.Get(ctx, RESERVED_GEMPORT_IDS_PATH)
612 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000613 logger.Errorw(ctx, "Unable to get reserved GEM port ids from the kv store", log.Fields{"err": err})
Esin Karaman5351fc52020-02-14 07:45:49 +0000614 return reservedGemPortIds, false
615 }
616 if KvPair == nil || KvPair.Value == nil {
617 //no reserved gem port defined in the store
618 return reservedGemPortIds, false
619 }
620 Val, err := kvstore.ToByte(KvPair.Value)
621 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000622 logger.Errorw(ctx, "Failed to convert reserved gem port ids into byte array", log.Fields{"err": err})
Esin Karaman5351fc52020-02-14 07:45:49 +0000623 return reservedGemPortIds, false
624 }
625 if err = json.Unmarshal(Val, &reservedGemPortIds); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000626 logger.Errorw(ctx, "Failed to unmarshal reservedGemPortIds", log.Fields{"err": err})
Esin Karaman5351fc52020-02-14 07:45:49 +0000627 return reservedGemPortIds, false
628 }
629 return reservedGemPortIds, true
630}
631
Neha Sharma94f16a92020-06-26 04:17:55 +0000632func (PONRMgr *PONResourceManager) FormatResource(ctx context.Context, IntfID uint32, StartIDx uint32, EndIDx uint32,
Esin Karaman5351fc52020-02-14 07:45:49 +0000633 Excluded []uint32) ([]byte, error) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700634 /*
635 Format resource as json.
636 :param pon_intf_id: OLT PON interface id
637 :param start_idx: start index for id pool
638 :param end_idx: end index for id pool
Esin Karaman5351fc52020-02-14 07:45:49 +0000639 :Id values to be Excluded from the pool
Scott Baker2c1c4822019-10-16 11:02:41 -0700640 :return dictionary: resource formatted as map
641 */
642 // Format resource as json to be stored in backend store
643 Resource := make(map[string]interface{})
644 Resource[PON_INTF_ID] = IntfID
645 Resource[START_IDX] = StartIDx
646 Resource[END_IDX] = EndIDx
647 /*
648 Resource pool stored in backend store as binary string.
649 Tracking the resource allocation will be done by setting the bits \
650 in the byte array. The index set will be the resource number allocated.
651 */
652 var TSData *bitmap.Threadsafe
653 if TSData = bitmap.NewTS(int(EndIDx)); TSData == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000654 logger.Error(ctx, "Failed to create a bitmap")
Scott Baker2c1c4822019-10-16 11:02:41 -0700655 return nil, errors.New("Failed to create bitmap")
656 }
Esin Karaman5351fc52020-02-14 07:45:49 +0000657 for _, excludedID := range Excluded {
658 if excludedID < StartIDx || excludedID > EndIDx {
Neha Sharma94f16a92020-06-26 04:17:55 +0000659 logger.Warnf(ctx, "Cannot reserve %d. It must be in the range of [%d, %d]", excludedID,
Esin Karaman5351fc52020-02-14 07:45:49 +0000660 StartIDx, EndIDx)
661 continue
662 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000663 PONRMgr.reserveID(ctx, TSData, StartIDx, excludedID)
Esin Karaman5351fc52020-02-14 07:45:49 +0000664 }
Scott Baker2c1c4822019-10-16 11:02:41 -0700665 Resource[POOL] = TSData.Data(false) //we pass false so as the TSData lib api does not do a copy of the data and return
666
667 Value, err := json.Marshal(Resource)
668 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000669 logger.Errorf(ctx, "Failed to marshall resource")
Scott Baker2c1c4822019-10-16 11:02:41 -0700670 return nil, err
671 }
672 return Value, err
673}
npujar5bf737f2020-01-16 19:35:25 +0530674func (PONRMgr *PONResourceManager) GetResource(ctx context.Context, Path string) (map[string]interface{}, error) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700675 /*
676 Get resource from kv store.
677
678 :param path: path to get resource
679 :return: resource if resource present in kv store else None
680 */
681 //get resource from kv store
682
683 var Value []byte
684 Result := make(map[string]interface{})
685 var Str string
686
npujar5bf737f2020-01-16 19:35:25 +0530687 Resource, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700688 if (err != nil) || (Resource == nil) {
Neha Sharma94f16a92020-06-26 04:17:55 +0000689 logger.Debugf(ctx, "Resource unavailable at %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700690 return nil, err
691 }
692
693 Value, err = ToByte(Resource.Value)
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800694 if err != nil {
695 return nil, err
696 }
Scott Baker2c1c4822019-10-16 11:02:41 -0700697
698 // decode resource fetched from backend store to dictionary
699 err = json.Unmarshal(Value, &Result)
700 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000701 logger.Error(ctx, "Failed to decode resource")
Scott Baker2c1c4822019-10-16 11:02:41 -0700702 return Result, err
703 }
704 /*
705 resource pool in backend store stored as binary string whereas to
706 access the pool to generate/release IDs it need to be converted
707 as BitArray
708 */
709 Str, err = ToString(Result[POOL])
710 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000711 logger.Error(ctx, "Failed to conver to kv pair to string")
Scott Baker2c1c4822019-10-16 11:02:41 -0700712 return Result, err
713 }
714 Decode64, _ := base64.StdEncoding.DecodeString(Str)
715 Result[POOL], err = ToByte(Decode64)
716 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000717 logger.Error(ctx, "Failed to convert resource pool to byte")
Scott Baker2c1c4822019-10-16 11:02:41 -0700718 return Result, err
719 }
720
721 return Result, err
722}
723
Neha Sharma94f16a92020-06-26 04:17:55 +0000724func (PONRMgr *PONResourceManager) GetPath(ctx context.Context, IntfID uint32, ResourceType string) string {
Scott Baker2c1c4822019-10-16 11:02:41 -0700725 /*
726 Get path for given resource type.
727 :param pon_intf_id: OLT PON interface id
728 :param resource_type: String to identify type of resource
729 :return: path for given resource type
730 */
731
732 /*
733 Get the shared pool for the given resource type.
734 all the resource ranges and the shared resource maps are initialized during the init.
735 */
736 SharedPoolID := PONRMgr.PonResourceRanges[PONRMgr.SharedIdxByType[ResourceType]].(uint32)
737 if SharedPoolID != 0 {
738 IntfID = SharedPoolID
739 }
740 var Path string
741 if ResourceType == ONU_ID {
742 Path = fmt.Sprintf(ONU_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
743 } else if ResourceType == ALLOC_ID {
744 Path = fmt.Sprintf(ALLOC_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
745 } else if ResourceType == GEMPORT_ID {
746 Path = fmt.Sprintf(GEMPORT_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
747 } else if ResourceType == FLOW_ID {
748 Path = fmt.Sprintf(FLOW_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
749 } else {
Neha Sharma94f16a92020-06-26 04:17:55 +0000750 logger.Error(ctx, "Invalid resource pool identifier")
Scott Baker2c1c4822019-10-16 11:02:41 -0700751 }
752 return Path
753}
754
npujar5bf737f2020-01-16 19:35:25 +0530755func (PONRMgr *PONResourceManager) GetResourceID(ctx context.Context, IntfID uint32, ResourceType string, NumIDs uint32) ([]uint32, error) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700756 /*
757 Create alloc/gemport/onu/flow id for given OLT PON interface.
758 :param pon_intf_id: OLT PON interface id
759 :param resource_type: String to identify type of resource
760 :param num_of_id: required number of ids
761 :return list/uint32/None: list, uint32 or None if resource type is
762 alloc_id/gemport_id, onu_id or invalid type respectively
763 */
Matteo Scandolob85b2f02021-03-18 14:44:41 -0700764
765 logger.Debugw(ctx, "getting-resource-id", log.Fields{
766 "intf-id": IntfID,
767 "resource-type": ResourceType,
768 "num": NumIDs,
769 })
770
Scott Baker2c1c4822019-10-16 11:02:41 -0700771 if NumIDs < 1 {
Neha Sharma94f16a92020-06-26 04:17:55 +0000772 logger.Error(ctx, "Invalid number of resources requested")
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800773 return nil, fmt.Errorf("Invalid number of resources requested %d", NumIDs)
Scott Baker2c1c4822019-10-16 11:02:41 -0700774 }
775 // delegate to the master instance if sharing enabled across instances
776
777 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
778 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujar5bf737f2020-01-16 19:35:25 +0530779 return SharedResourceMgr.GetResourceID(ctx, IntfID, ResourceType, NumIDs)
Scott Baker2c1c4822019-10-16 11:02:41 -0700780 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000781 logger.Debugf(ctx, "Fetching resource from %s rsrc mgr for resource %s", PONRMgr.Globalorlocal, ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700782
Neha Sharma94f16a92020-06-26 04:17:55 +0000783 Path := PONRMgr.GetPath(ctx, IntfID, ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700784 if Path == "" {
Neha Sharma94f16a92020-06-26 04:17:55 +0000785 logger.Errorf(ctx, "Failed to get path for resource type %s", ResourceType)
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800786 return nil, fmt.Errorf("Failed to get path for resource type %s", ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700787 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000788 logger.Debugf(ctx, "Get resource for type %s on path %s", ResourceType, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700789 var Result []uint32
790 var NextID uint32
npujar5bf737f2020-01-16 19:35:25 +0530791 Resource, err := PONRMgr.GetResource(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700792 if (err == nil) && (ResourceType == ONU_ID) || (ResourceType == FLOW_ID) {
Neha Sharma94f16a92020-06-26 04:17:55 +0000793 if NextID, err = PONRMgr.GenerateNextID(ctx, Resource); err != nil {
794 logger.Error(ctx, "Failed to Generate ID")
Scott Baker2c1c4822019-10-16 11:02:41 -0700795 return Result, err
796 }
797 Result = append(Result, NextID)
798 } else if (err == nil) && ((ResourceType == GEMPORT_ID) || (ResourceType == ALLOC_ID)) {
799 if NumIDs == 1 {
Neha Sharma94f16a92020-06-26 04:17:55 +0000800 if NextID, err = PONRMgr.GenerateNextID(ctx, Resource); err != nil {
801 logger.Error(ctx, "Failed to Generate ID")
Scott Baker2c1c4822019-10-16 11:02:41 -0700802 return Result, err
803 }
804 Result = append(Result, NextID)
805 } else {
806 for NumIDs > 0 {
Neha Sharma94f16a92020-06-26 04:17:55 +0000807 if NextID, err = PONRMgr.GenerateNextID(ctx, Resource); err != nil {
808 logger.Error(ctx, "Failed to Generate ID")
Scott Baker2c1c4822019-10-16 11:02:41 -0700809 return Result, err
810 }
811 Result = append(Result, NextID)
812 NumIDs--
813 }
814 }
815 } else {
Neha Sharma94f16a92020-06-26 04:17:55 +0000816 logger.Error(ctx, "get resource failed")
Scott Baker2c1c4822019-10-16 11:02:41 -0700817 return Result, err
818 }
819
820 //Update resource in kv store
npujar5bf737f2020-01-16 19:35:25 +0530821 if PONRMgr.UpdateResource(ctx, Path, Resource) != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000822 logger.Errorf(ctx, "Failed to update resource %s", Path)
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800823 return nil, fmt.Errorf("Failed to update resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700824 }
825 return Result, nil
826}
827
828func checkValidResourceType(ResourceType string) bool {
829 KnownResourceTypes := []string{ONU_ID, ALLOC_ID, GEMPORT_ID, FLOW_ID}
830
831 for _, v := range KnownResourceTypes {
832 if v == ResourceType {
833 return true
834 }
835 }
836 return false
837}
838
Matteo Scandolob85b2f02021-03-18 14:44:41 -0700839func (PONRMgr *PONResourceManager) FreeResourceID(ctx context.Context, IntfID uint32, ResourceType string, ReleaseContent []uint32) error {
Scott Baker2c1c4822019-10-16 11:02:41 -0700840 /*
Matteo Scandolob85b2f02021-03-18 14:44:41 -0700841 Release alloc/gemport/onu/flow id for given OLT PON interface.
842 :param pon_intf_id: OLT PON interface id
843 :param resource_type: String to identify type of resource
844 :param release_content: required number of ids
845 :return boolean: True if all IDs in given release_content release else False
Scott Baker2c1c4822019-10-16 11:02:41 -0700846 */
Matteo Scandolob85b2f02021-03-18 14:44:41 -0700847
848 logger.Debugw(ctx, "freeing-resource-id", log.Fields{
849 "intf-id": IntfID,
850 "resource-type": ResourceType,
851 "release-content": ReleaseContent,
852 })
853
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800854 if !checkValidResourceType(ResourceType) {
Matteo Scandolob85b2f02021-03-18 14:44:41 -0700855 err := fmt.Errorf("Invalid resource type: %s", ResourceType)
856 logger.Error(ctx, err.Error())
857 return err
Scott Baker2c1c4822019-10-16 11:02:41 -0700858 }
859 if ReleaseContent == nil {
Matteo Scandolob85b2f02021-03-18 14:44:41 -0700860 err := fmt.Errorf("Nothing to release")
861 logger.Debug(ctx, err.Error())
862 return err
Scott Baker2c1c4822019-10-16 11:02:41 -0700863 }
864 // delegate to the master instance if sharing enabled across instances
865 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
866 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujar5bf737f2020-01-16 19:35:25 +0530867 return SharedResourceMgr.FreeResourceID(ctx, IntfID, ResourceType, ReleaseContent)
Scott Baker2c1c4822019-10-16 11:02:41 -0700868 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000869 Path := PONRMgr.GetPath(ctx, IntfID, ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700870 if Path == "" {
Matteo Scandolob85b2f02021-03-18 14:44:41 -0700871 err := fmt.Errorf("Failed to get path for IntfId %d and ResourceType %s", IntfID, ResourceType)
872 logger.Error(ctx, err.Error())
873 return err
Scott Baker2c1c4822019-10-16 11:02:41 -0700874 }
npujar5bf737f2020-01-16 19:35:25 +0530875 Resource, err := PONRMgr.GetResource(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700876 if err != nil {
Matteo Scandolob85b2f02021-03-18 14:44:41 -0700877 logger.Error(ctx, err.Error())
878 return err
Scott Baker2c1c4822019-10-16 11:02:41 -0700879 }
880 for _, Val := range ReleaseContent {
Neha Sharma94f16a92020-06-26 04:17:55 +0000881 PONRMgr.ReleaseID(ctx, Resource, Val)
Scott Baker2c1c4822019-10-16 11:02:41 -0700882 }
npujar5bf737f2020-01-16 19:35:25 +0530883 if PONRMgr.UpdateResource(ctx, Path, Resource) != nil {
Matteo Scandolob85b2f02021-03-18 14:44:41 -0700884 err := fmt.Errorf("Free resource for %s failed", Path)
885 logger.Errorf(ctx, err.Error())
886 return err
Scott Baker2c1c4822019-10-16 11:02:41 -0700887 }
Matteo Scandolob85b2f02021-03-18 14:44:41 -0700888 return nil
Scott Baker2c1c4822019-10-16 11:02:41 -0700889}
890
npujar5bf737f2020-01-16 19:35:25 +0530891func (PONRMgr *PONResourceManager) UpdateResource(ctx context.Context, Path string, Resource map[string]interface{}) error {
Scott Baker2c1c4822019-10-16 11:02:41 -0700892 /*
893 Update resource in resource kv store.
894 :param path: path to update resource
895 :param resource: resource need to be updated
896 :return boolean: True if resource updated in kv store else False
897 */
898 // TODO resource[POOL] = resource[POOL].bin
899 Value, err := json.Marshal(Resource)
900 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000901 logger.Error(ctx, "failed to Marshal")
Scott Baker2c1c4822019-10-16 11:02:41 -0700902 return err
903 }
npujar5bf737f2020-01-16 19:35:25 +0530904 err = PONRMgr.KVStore.Put(ctx, Path, Value)
Scott Baker2c1c4822019-10-16 11:02:41 -0700905 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000906 logger.Error(ctx, "failed to put data to kv store %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700907 return err
908 }
909 return nil
910}
911
npujar5bf737f2020-01-16 19:35:25 +0530912func (PONRMgr *PONResourceManager) ClearResourceIDPool(ctx context.Context, contIntfID uint32, ResourceType string) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -0700913 /*
914 Clear Resource Pool for a given Resource Type on a given PON Port.
915 :return boolean: True if removed else False
916 */
917
918 // delegate to the master instance if sharing enabled across instances
919 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
920 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujar5bf737f2020-01-16 19:35:25 +0530921 return SharedResourceMgr.ClearResourceIDPool(ctx, contIntfID, ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700922 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000923 Path := PONRMgr.GetPath(ctx, contIntfID, ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700924 if Path == "" {
Neha Sharma94f16a92020-06-26 04:17:55 +0000925 logger.Error(ctx, "Failed to get path")
Scott Baker2c1c4822019-10-16 11:02:41 -0700926 return false
927 }
928
npujar5bf737f2020-01-16 19:35:25 +0530929 if err := PONRMgr.KVStore.Delete(ctx, Path); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000930 logger.Errorf(ctx, "Failed to delete resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700931 return false
932 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000933 logger.Debugf(ctx, "Cleared resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700934 return true
935}
936
npujar5bf737f2020-01-16 19:35:25 +0530937func (PONRMgr PONResourceManager) InitResourceMap(ctx context.Context, PONIntfONUID string) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700938 /*
939 Initialize resource map
940 :param pon_intf_onu_id: reference of PON interface id and onu id
941 */
942 // initialize pon_intf_onu_id tuple to alloc_ids map
943 AllocIDPath := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
944 var AllocIDs []byte
npujar5bf737f2020-01-16 19:35:25 +0530945 Result := PONRMgr.KVStore.Put(ctx, AllocIDPath, AllocIDs)
Scott Baker2c1c4822019-10-16 11:02:41 -0700946 if Result != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000947 logger.Error(ctx, "Failed to update the KV store")
Scott Baker2c1c4822019-10-16 11:02:41 -0700948 return
949 }
950 // initialize pon_intf_onu_id tuple to gemport_ids map
951 GEMPortIDPath := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
952 var GEMPortIDs []byte
npujar5bf737f2020-01-16 19:35:25 +0530953 Result = PONRMgr.KVStore.Put(ctx, GEMPortIDPath, GEMPortIDs)
Scott Baker2c1c4822019-10-16 11:02:41 -0700954 if Result != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000955 logger.Error(ctx, "Failed to update the KV store")
Scott Baker2c1c4822019-10-16 11:02:41 -0700956 return
957 }
958}
959
npujar5bf737f2020-01-16 19:35:25 +0530960func (PONRMgr PONResourceManager) RemoveResourceMap(ctx context.Context, PONIntfONUID string) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -0700961 /*
962 Remove resource map
963 :param pon_intf_onu_id: reference of PON interface id and onu id
964 */
965 // remove pon_intf_onu_id tuple to alloc_ids map
966 var err error
967 AllocIDPath := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujar5bf737f2020-01-16 19:35:25 +0530968 if err = PONRMgr.KVStore.Delete(ctx, AllocIDPath); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000969 logger.Errorf(ctx, "Failed to remove resource %s", AllocIDPath)
Scott Baker2c1c4822019-10-16 11:02:41 -0700970 return false
971 }
972 // remove pon_intf_onu_id tuple to gemport_ids map
973 GEMPortIDPath := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujar5bf737f2020-01-16 19:35:25 +0530974 err = PONRMgr.KVStore.Delete(ctx, GEMPortIDPath)
Scott Baker2c1c4822019-10-16 11:02:41 -0700975 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000976 logger.Errorf(ctx, "Failed to remove resource %s", GEMPortIDPath)
Scott Baker2c1c4822019-10-16 11:02:41 -0700977 return false
978 }
979
980 FlowIDPath := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujar5bf737f2020-01-16 19:35:25 +0530981 if FlowIDs, err := PONRMgr.KVStore.List(ctx, FlowIDPath); err != nil {
Scott Baker2c1c4822019-10-16 11:02:41 -0700982 for _, Flow := range FlowIDs {
983 FlowIDInfoPath := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, PONIntfONUID, Flow.Value)
npujar5bf737f2020-01-16 19:35:25 +0530984 if err = PONRMgr.KVStore.Delete(ctx, FlowIDInfoPath); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000985 logger.Errorf(ctx, "Failed to remove resource %s", FlowIDInfoPath)
Scott Baker2c1c4822019-10-16 11:02:41 -0700986 return false
987 }
988 }
989 }
990
npujar5bf737f2020-01-16 19:35:25 +0530991 if err = PONRMgr.KVStore.Delete(ctx, FlowIDPath); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000992 logger.Errorf(ctx, "Failed to remove resource %s", FlowIDPath)
Scott Baker2c1c4822019-10-16 11:02:41 -0700993 return false
994 }
995
996 return true
997}
998
npujar5bf737f2020-01-16 19:35:25 +0530999func (PONRMgr *PONResourceManager) GetCurrentAllocIDForOnu(ctx context.Context, IntfONUID string) []uint32 {
Scott Baker2c1c4822019-10-16 11:02:41 -07001000 /*
1001 Get currently configured alloc ids for given pon_intf_onu_id
1002 :param pon_intf_onu_id: reference of PON interface id and onu id
1003 :return list: List of alloc_ids if available, else None
1004 */
1005 Path := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
1006
1007 var Data []uint32
npujar5bf737f2020-01-16 19:35:25 +05301008 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001009 if err == nil {
1010 if Value != nil {
1011 Val, err := ToByte(Value.Value)
1012 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001013 logger.Errorw(ctx, "Failed to convert into byte array", log.Fields{"error": err})
Scott Baker2c1c4822019-10-16 11:02:41 -07001014 return Data
1015 }
1016 if err = json.Unmarshal(Val, &Data); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001017 logger.Error(ctx, "Failed to unmarshal", log.Fields{"error": err})
Scott Baker2c1c4822019-10-16 11:02:41 -07001018 return Data
1019 }
1020 }
1021 }
1022 return Data
1023}
1024
npujar5bf737f2020-01-16 19:35:25 +05301025func (PONRMgr *PONResourceManager) GetCurrentGEMPortIDsForOnu(ctx context.Context, IntfONUID string) []uint32 {
Scott Baker2c1c4822019-10-16 11:02:41 -07001026 /*
1027 Get currently configured gemport ids for given pon_intf_onu_id
1028 :param pon_intf_onu_id: reference of PON interface id and onu id
1029 :return list: List of gemport IDs if available, else None
1030 */
1031
1032 Path := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Neha Sharma94f16a92020-06-26 04:17:55 +00001033 logger.Debugf(ctx, "Getting current gemports for %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001034 var Data []uint32
npujar5bf737f2020-01-16 19:35:25 +05301035 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001036 if err == nil {
1037 if Value != nil {
1038 Val, _ := ToByte(Value.Value)
1039 if err = json.Unmarshal(Val, &Data); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001040 logger.Errorw(ctx, "Failed to unmarshal", log.Fields{"error": err})
Scott Baker2c1c4822019-10-16 11:02:41 -07001041 return Data
1042 }
1043 }
1044 } else {
Neha Sharma94f16a92020-06-26 04:17:55 +00001045 logger.Errorf(ctx, "Failed to get data from kvstore for %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001046 }
1047 return Data
1048}
1049
npujar5bf737f2020-01-16 19:35:25 +05301050func (PONRMgr *PONResourceManager) GetCurrentFlowIDsForOnu(ctx context.Context, IntfONUID string) []uint32 {
Scott Baker2c1c4822019-10-16 11:02:41 -07001051 /*
1052 Get currently configured flow ids for given pon_intf_onu_id
1053 :param pon_intf_onu_id: reference of PON interface id and onu id
1054 :return list: List of Flow IDs if available, else None
1055 */
1056
1057 Path := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
1058
1059 var Data []uint32
npujar5bf737f2020-01-16 19:35:25 +05301060 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001061 if err == nil {
1062 if Value != nil {
1063 Val, _ := ToByte(Value.Value)
1064 if err = json.Unmarshal(Val, &Data); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001065 logger.Error(ctx, "Failed to unmarshal")
Scott Baker2c1c4822019-10-16 11:02:41 -07001066 return Data
1067 }
1068 }
1069 }
1070 return Data
1071}
1072
npujar5bf737f2020-01-16 19:35:25 +05301073func (PONRMgr *PONResourceManager) GetFlowIDInfo(ctx context.Context, IntfONUID string, FlowID uint32, Data interface{}) error {
Scott Baker2c1c4822019-10-16 11:02:41 -07001074 /*
1075 Get flow details configured for the ONU.
1076 :param pon_intf_onu_id: reference of PON interface id and onu id
1077 :param flow_id: Flow Id reference
1078 :param Data: Result
1079 :return error: nil if no error in getting from KV store
1080 */
1081
1082 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
1083
npujar5bf737f2020-01-16 19:35:25 +05301084 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001085 if err == nil {
1086 if Value != nil {
1087 Val, err := ToByte(Value.Value)
1088 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001089 logger.Errorw(ctx, "Failed to convert flowinfo into byte array", log.Fields{"error": err})
Scott Baker2c1c4822019-10-16 11:02:41 -07001090 return err
1091 }
1092 if err = json.Unmarshal(Val, Data); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001093 logger.Errorw(ctx, "Failed to unmarshal", log.Fields{"error": err})
Scott Baker2c1c4822019-10-16 11:02:41 -07001094 return err
1095 }
1096 }
1097 }
1098 return err
1099}
1100
npujar5bf737f2020-01-16 19:35:25 +05301101func (PONRMgr *PONResourceManager) RemoveFlowIDInfo(ctx context.Context, IntfONUID string, FlowID uint32) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -07001102 /*
1103 Get flow_id details configured for the ONU.
1104 :param pon_intf_onu_id: reference of PON interface id and onu id
1105 :param flow_id: Flow Id reference
1106 */
1107 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
1108
npujar5bf737f2020-01-16 19:35:25 +05301109 if err := PONRMgr.KVStore.Delete(ctx, Path); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001110 logger.Errorf(ctx, "Falied to remove resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001111 return false
1112 }
1113 return true
1114}
1115
Serkant Uluderya198de902020-11-16 20:29:17 +03001116func (PONRMgr *PONResourceManager) RemoveAllFlowIDInfo(ctx context.Context, IntfONUID string) bool {
1117 /*
1118 Remove flow_id_info details configured for the ONU.
1119 :param pon_intf_onu_id: reference of PON interface id and onu id
1120 */
1121 Path := fmt.Sprintf(FLOW_ID_INFO_PATH_INTF_ONU_PREFIX, PONRMgr.DeviceID, IntfONUID)
1122
1123 if err := PONRMgr.KVStore.DeleteWithPrefix(ctx, Path); err != nil {
1124 logger.Errorf(ctx, "Falied to remove resource %s", Path)
1125 return false
1126 }
1127 return true
1128}
1129
npujar5bf737f2020-01-16 19:35:25 +05301130func (PONRMgr *PONResourceManager) UpdateAllocIdsForOnu(ctx context.Context, IntfONUID string, AllocIDs []uint32) error {
Scott Baker2c1c4822019-10-16 11:02:41 -07001131 /*
1132 Update currently configured alloc ids for given pon_intf_onu_id
1133 :param pon_intf_onu_id: reference of PON interface id and onu id
1134 :param alloc_ids: list of alloc ids
1135 */
1136 var Value []byte
1137 var err error
1138 Path := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Girish Gowdra823da1d2021-10-28 11:47:53 -07001139 if AllocIDs == nil {
1140 // No more alloc ids associated with the key. Delete the key entirely
1141 if err = PONRMgr.KVStore.Delete(ctx, Path); err != nil {
1142 logger.Errorf(ctx, "Failed to delete key %s", Path)
1143 return err
1144 }
1145 } else {
1146 Value, err = json.Marshal(AllocIDs)
1147 if err != nil {
1148 logger.Error(ctx, "failed to Marshal")
1149 return err
1150 }
Scott Baker2c1c4822019-10-16 11:02:41 -07001151
Girish Gowdra823da1d2021-10-28 11:47:53 -07001152 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
1153 logger.Errorf(ctx, "Failed to update resource %s", Path)
1154 return err
1155 }
Scott Baker2c1c4822019-10-16 11:02:41 -07001156 }
1157 return err
1158}
1159
npujar5bf737f2020-01-16 19:35:25 +05301160func (PONRMgr *PONResourceManager) UpdateGEMPortIDsForOnu(ctx context.Context, IntfONUID string, GEMPortIDs []uint32) error {
Scott Baker2c1c4822019-10-16 11:02:41 -07001161 /*
1162 Update currently configured gemport ids for given pon_intf_onu_id
1163 :param pon_intf_onu_id: reference of PON interface id and onu id
1164 :param gemport_ids: list of gem port ids
1165 */
1166
1167 var Value []byte
1168 var err error
1169 Path := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Neha Sharma94f16a92020-06-26 04:17:55 +00001170 logger.Debugf(ctx, "Updating gemport ids for %s", Path)
Girish Gowdra823da1d2021-10-28 11:47:53 -07001171 if GEMPortIDs == nil {
1172 // No more gemport ids associated with the key. Delete the key entirely
1173 if err = PONRMgr.KVStore.Delete(ctx, Path); err != nil {
1174 logger.Errorf(ctx, "Failed to delete key %s", Path)
1175 return err
1176 }
1177 } else {
1178 Value, err = json.Marshal(GEMPortIDs)
1179 if err != nil {
1180 logger.Error(ctx, "failed to Marshal")
1181 return err
1182 }
Scott Baker2c1c4822019-10-16 11:02:41 -07001183
Girish Gowdra823da1d2021-10-28 11:47:53 -07001184 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
1185 logger.Errorf(ctx, "Failed to update resource %s", Path)
1186 return err
1187 }
Scott Baker2c1c4822019-10-16 11:02:41 -07001188 }
1189 return err
1190}
1191
1192func checkForFlowIDInList(FlowIDList []uint32, FlowID uint32) (bool, uint32) {
1193 /*
1194 Check for a flow id in a given list of flow IDs.
1195 :param FLowIDList: List of Flow IDs
1196 :param FlowID: Flowd to check in the list
1197 : return true and the index if present false otherwise.
1198 */
1199
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001200 for idx := range FlowIDList {
Scott Baker2c1c4822019-10-16 11:02:41 -07001201 if FlowID == FlowIDList[idx] {
1202 return true, uint32(idx)
1203 }
1204 }
1205 return false, 0
1206}
1207
npujar5bf737f2020-01-16 19:35:25 +05301208func (PONRMgr *PONResourceManager) UpdateFlowIDForOnu(ctx context.Context, IntfONUID string, FlowID uint32, Add bool) error {
Scott Baker2c1c4822019-10-16 11:02:41 -07001209 /*
1210 Update the flow_id list of the ONU (add or remove flow_id from the list)
1211 :param pon_intf_onu_id: reference of PON interface id and onu id
1212 :param flow_id: flow ID
1213 :param add: Boolean flag to indicate whether the flow_id should be
1214 added or removed from the list. Defaults to adding the flow.
1215 */
1216 var Value []byte
1217 var err error
1218 var RetVal bool
1219 var IDx uint32
1220 Path := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
npujar5bf737f2020-01-16 19:35:25 +05301221 FlowIDs := PONRMgr.GetCurrentFlowIDsForOnu(ctx, IntfONUID)
Scott Baker2c1c4822019-10-16 11:02:41 -07001222
1223 if Add {
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001224 if RetVal, _ = checkForFlowIDInList(FlowIDs, FlowID); RetVal {
1225 return nil
Scott Baker2c1c4822019-10-16 11:02:41 -07001226 }
1227 FlowIDs = append(FlowIDs, FlowID)
1228 } else {
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001229 if RetVal, IDx = checkForFlowIDInList(FlowIDs, FlowID); !RetVal {
1230 return nil
Scott Baker2c1c4822019-10-16 11:02:41 -07001231 }
1232 // delete the index and shift
1233 FlowIDs = append(FlowIDs[:IDx], FlowIDs[IDx+1:]...)
1234 }
1235 Value, err = json.Marshal(FlowIDs)
1236 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001237 logger.Error(ctx, "Failed to Marshal")
Scott Baker2c1c4822019-10-16 11:02:41 -07001238 return err
1239 }
1240
npujar5bf737f2020-01-16 19:35:25 +05301241 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001242 logger.Errorf(ctx, "Failed to update resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001243 return err
1244 }
1245 return err
1246}
1247
npujar5bf737f2020-01-16 19:35:25 +05301248func (PONRMgr *PONResourceManager) UpdateFlowIDInfoForOnu(ctx context.Context, IntfONUID string, FlowID uint32, FlowData interface{}) error {
Scott Baker2c1c4822019-10-16 11:02:41 -07001249 /*
1250 Update any metadata associated with the flow_id. The flow_data could be json
1251 or any of other data structure. The resource manager doesnt care
1252 :param pon_intf_onu_id: reference of PON interface id and onu id
1253 :param flow_id: Flow ID
1254 :param flow_data: Flow data blob
1255 */
1256 var Value []byte
1257 var err error
1258 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
1259 Value, err = json.Marshal(FlowData)
1260 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001261 logger.Error(ctx, "failed to Marshal")
Scott Baker2c1c4822019-10-16 11:02:41 -07001262 return err
1263 }
1264
npujar5bf737f2020-01-16 19:35:25 +05301265 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001266 logger.Errorf(ctx, "Failed to update resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001267 return err
1268 }
1269 return err
1270}
1271
Neha Sharma94f16a92020-06-26 04:17:55 +00001272func (PONRMgr *PONResourceManager) GenerateNextID(ctx context.Context, Resource map[string]interface{}) (uint32, error) {
Scott Baker2c1c4822019-10-16 11:02:41 -07001273 /*
1274 Generate unique id having OFFSET as start
1275 :param resource: resource used to generate ID
1276 :return uint32: generated id
1277 */
1278 ByteArray, err := ToByte(Resource[POOL])
1279 if err != nil {
Scott Baker2c1c4822019-10-16 11:02:41 -07001280 return 0, err
1281 }
1282 Data := bitmap.TSFromData(ByteArray, false)
1283 if Data == nil {
Scott Baker2c1c4822019-10-16 11:02:41 -07001284 return 0, errors.New("Failed to get data from byte array")
1285 }
1286
1287 Len := Data.Len()
1288 var Idx int
1289 for Idx = 0; Idx < Len; Idx++ {
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001290 if !Data.Get(Idx) {
Scott Baker2c1c4822019-10-16 11:02:41 -07001291 break
1292 }
1293 }
Esin Karamanefab54e2021-10-13 11:11:43 +00001294 if Idx == Len {
1295 return 0, errors.New("resource-exhausted--no-free-id-in-the-pool")
1296 }
Scott Baker2c1c4822019-10-16 11:02:41 -07001297 Data.Set(Idx, true)
1298 res := uint32(Resource[START_IDX].(float64))
1299 Resource[POOL] = Data.Data(false)
Neha Sharma94f16a92020-06-26 04:17:55 +00001300 logger.Debugf(ctx, "Generated ID for %d", (uint32(Idx) + res))
Scott Baker2c1c4822019-10-16 11:02:41 -07001301 return (uint32(Idx) + res), err
1302}
1303
Neha Sharma94f16a92020-06-26 04:17:55 +00001304func (PONRMgr *PONResourceManager) ReleaseID(ctx context.Context, Resource map[string]interface{}, Id uint32) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -07001305 /*
1306 Release unique id having OFFSET as start index.
1307 :param resource: resource used to release ID
1308 :param unique_id: id need to be released
1309 */
1310 ByteArray, err := ToByte(Resource[POOL])
1311 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001312 logger.Error(ctx, "Failed to convert resource to byte array")
Scott Baker2c1c4822019-10-16 11:02:41 -07001313 return false
1314 }
1315 Data := bitmap.TSFromData(ByteArray, false)
1316 if Data == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001317 logger.Error(ctx, "Failed to get resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -07001318 return false
1319 }
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001320 Idx := Id - uint32(Resource[START_IDX].(float64))
Esin Karamanefab54e2021-10-13 11:11:43 +00001321 if Idx >= uint32(Data.Len()) {
1322 logger.Errorf(ctx, "ID %d is out of the boundaries of the pool", Id)
1323 return false
1324 }
Scott Baker2c1c4822019-10-16 11:02:41 -07001325 Data.Set(int(Idx), false)
1326 Resource[POOL] = Data.Data(false)
1327
1328 return true
1329}
1330
Esin Karaman5351fc52020-02-14 07:45:49 +00001331/* Reserves a unique id in the specified resource pool.
1332:param Resource: resource used to reserve ID
1333:param Id: ID to be reserved
1334*/
Neha Sharma94f16a92020-06-26 04:17:55 +00001335func (PONRMgr *PONResourceManager) reserveID(ctx context.Context, TSData *bitmap.Threadsafe, StartIndex uint32, Id uint32) bool {
Esin Karaman5351fc52020-02-14 07:45:49 +00001336 Data := bitmap.TSFromData(TSData.Data(false), false)
1337 if Data == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001338 logger.Error(ctx, "Failed to get resource pool")
Esin Karaman5351fc52020-02-14 07:45:49 +00001339 return false
1340 }
1341 Idx := Id - StartIndex
Esin Karamanefab54e2021-10-13 11:11:43 +00001342 if Idx >= uint32(Data.Len()) {
1343 logger.Errorf(ctx, "Reservation failed. ID %d is out of the boundaries of the pool", Id)
1344 return false
1345 }
Esin Karaman5351fc52020-02-14 07:45:49 +00001346 Data.Set(int(Idx), true)
1347 return true
1348}
1349
Scott Baker2c1c4822019-10-16 11:02:41 -07001350func (PONRMgr *PONResourceManager) GetTechnology() string {
1351 return PONRMgr.Technology
1352}
1353
1354func (PONRMgr *PONResourceManager) GetResourceTypeAllocID() string {
1355 return ALLOC_ID
1356}
1357
1358func (PONRMgr *PONResourceManager) GetResourceTypeGemPortID() string {
1359 return GEMPORT_ID
1360}
1361
Matteo Scandolob85b2f02021-03-18 14:44:41 -07001362func (PONRMgr *PONResourceManager) GetResourceTypeOnuID() string {
1363 return ONU_ID
1364}
1365
Scott Baker2c1c4822019-10-16 11:02:41 -07001366// ToByte converts an interface value to a []byte. The interface should either be of
1367// a string type or []byte. Otherwise, an error is returned.
1368func ToByte(value interface{}) ([]byte, error) {
1369 switch t := value.(type) {
1370 case []byte:
1371 return value.([]byte), nil
1372 case string:
1373 return []byte(value.(string)), nil
1374 default:
1375 return nil, fmt.Errorf("unexpected-type-%T", t)
1376 }
1377}
1378
1379// ToString converts an interface value to a string. The interface should either be of
1380// a string type or []byte. Otherwise, an error is returned.
1381func ToString(value interface{}) (string, error) {
1382 switch t := value.(type) {
1383 case []byte:
1384 return string(value.([]byte)), nil
1385 case string:
1386 return value.(string), nil
1387 default:
1388 return "", fmt.Errorf("unexpected-type-%T", t)
1389 }
1390}