blob: ad6c11157de017fd420963af8d872683900951f6 [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)
Scott Baker2c1c4822019-10-16 11:02:41 -0700161 }
162 return nil, errors.New("unsupported-kv-store")
163}
164
Matteo Scandolo29ff79c2020-11-06 13:03:17 -0800165func SetKVClient(ctx context.Context, Technology string, Backend string, Addr string, configClient bool, basePathKvStore string) *db.Backend {
Scott Baker2c1c4822019-10-16 11:02:41 -0700166 // TODO : Make sure direct call to NewBackend is working fine with backend , currently there is some
167 // issue between kv store and backend , core is not calling NewBackend directly
Neha Sharma94f16a92020-06-26 04:17:55 +0000168 kvClient, err := newKVClient(ctx, Backend, Addr, KVSTORE_RETRY_TIMEOUT)
Scott Baker2c1c4822019-10-16 11:02:41 -0700169 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000170 logger.Fatalw(ctx, "Failed to init KV client\n", log.Fields{"err": err})
Scott Baker2c1c4822019-10-16 11:02:41 -0700171 return nil
172 }
Esin Karaman5351fc52020-02-14 07:45:49 +0000173
174 var pathPrefix string
175 if configClient {
Matteo Scandolo29ff79c2020-11-06 13:03:17 -0800176 pathPrefix = fmt.Sprintf(PATH_PREFIX_FOR_CONFIG, basePathKvStore)
Esin Karaman5351fc52020-02-14 07:45:49 +0000177 } else {
Matteo Scandolo29ff79c2020-11-06 13:03:17 -0800178 pathPrefix = fmt.Sprintf(PATH_PREFIX, basePathKvStore, Technology)
Esin Karaman5351fc52020-02-14 07:45:49 +0000179 }
180
sbarbari1e3e29c2019-11-05 10:06:50 -0500181 kvbackend := &db.Backend{
Scott Baker2c1c4822019-10-16 11:02:41 -0700182 Client: kvClient,
183 StoreType: Backend,
Neha Sharmadd9af392020-04-28 09:03:57 +0000184 Address: Addr,
Scott Baker2c1c4822019-10-16 11:02:41 -0700185 Timeout: KVSTORE_RETRY_TIMEOUT,
Esin Karaman5351fc52020-02-14 07:45:49 +0000186 PathPrefix: pathPrefix}
Scott Baker2c1c4822019-10-16 11:02:41 -0700187
188 return kvbackend
189}
190
191// NewPONResourceManager creates a new PON resource manager.
Matteo Scandolo29ff79c2020-11-06 13:03:17 -0800192func 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 -0700193 var PONMgr PONResourceManager
194 PONMgr.Technology = Technology
195 PONMgr.DeviceType = DeviceType
196 PONMgr.DeviceID = DeviceID
197 PONMgr.Backend = Backend
Neha Sharmadd9af392020-04-28 09:03:57 +0000198 PONMgr.Address = Address
Matteo Scandolo29ff79c2020-11-06 13:03:17 -0800199 PONMgr.KVStore = SetKVClient(ctx, Technology, Backend, Address, false, basePathKvStore)
Scott Baker2c1c4822019-10-16 11:02:41 -0700200 if PONMgr.KVStore == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000201 logger.Error(ctx, "KV Client initilization failed")
Scott Baker2c1c4822019-10-16 11:02:41 -0700202 return nil, errors.New("Failed to init KV client")
203 }
Esin Karaman5351fc52020-02-14 07:45:49 +0000204 // init kv client to read from the config path
Matteo Scandolo29ff79c2020-11-06 13:03:17 -0800205 PONMgr.KVStoreForConfig = SetKVClient(ctx, Technology, Backend, Address, true, basePathKvStore)
Esin Karaman5351fc52020-02-14 07:45:49 +0000206 if PONMgr.KVStoreForConfig == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000207 logger.Error(ctx, "KV Config Client initilization failed")
Esin Karaman5351fc52020-02-14 07:45:49 +0000208 return nil, errors.New("Failed to init KV Config client")
209 }
Girish Gowdrad72fef42021-07-22 16:30:58 -0700210
Scott Baker2c1c4822019-10-16 11:02:41 -0700211 PONMgr.PonResourceRanges = make(map[string]interface{})
212 PONMgr.SharedResourceMgrs = make(map[string]*PONResourceManager)
213 PONMgr.SharedIdxByType = make(map[string]string)
214 PONMgr.SharedIdxByType[ONU_ID] = ONU_ID_SHARED_IDX
215 PONMgr.SharedIdxByType[ALLOC_ID] = ALLOC_ID_SHARED_IDX
216 PONMgr.SharedIdxByType[GEMPORT_ID] = GEMPORT_ID_SHARED_IDX
217 PONMgr.SharedIdxByType[FLOW_ID] = FLOW_ID_SHARED_IDX
218 PONMgr.IntfIDs = make([]uint32, NUM_OF_PON_INTF)
219 PONMgr.OLTModel = DeviceType
220 return &PONMgr, nil
221}
222
223/*
224 Initialize PON resource ranges with config fetched from kv store.
225 return boolean: True if PON resource ranges initialized else false
226 Try to initialize the PON Resource Ranges from KV store based on the
227 OLT model key, if available
228*/
229
npujar5bf737f2020-01-16 19:35:25 +0530230func (PONRMgr *PONResourceManager) InitResourceRangesFromKVStore(ctx context.Context) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -0700231 //Initialize PON resource ranges with config fetched from kv store.
232 //:return boolean: True if PON resource ranges initialized else false
233 // Try to initialize the PON Resource Ranges from KV store based on the
234 // OLT model key, if available
235 if PONRMgr.OLTModel == "" {
Neha Sharma94f16a92020-06-26 04:17:55 +0000236 logger.Error(ctx, "Failed to get OLT model")
Scott Baker2c1c4822019-10-16 11:02:41 -0700237 return false
238 }
239 Path := fmt.Sprintf(PON_RESOURCE_RANGE_CONFIG_PATH, PONRMgr.OLTModel)
240 //get resource from kv store
npujar5bf737f2020-01-16 19:35:25 +0530241 Result, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700242 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000243 logger.Debugf(ctx, "Error in fetching resource %s from KV strore", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700244 return false
245 }
246 if Result == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000247 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 -0700248 return false
249 }
250 //update internal ranges from kv ranges. If there are missing
251 // values in the KV profile, continue to use the defaults
252 Value, err := ToByte(Result.Value)
253 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000254 logger.Error(ctx, "Failed to convert kvpair to byte string")
Scott Baker2c1c4822019-10-16 11:02:41 -0700255 return false
256 }
257 if err := json.Unmarshal(Value, &PONRMgr.PonResourceRanges); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000258 logger.Error(ctx, "Failed to Unmarshal json byte")
Scott Baker2c1c4822019-10-16 11:02:41 -0700259 return false
260 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000261 logger.Debug(ctx, "Init resource ranges from kvstore success")
Scott Baker2c1c4822019-10-16 11:02:41 -0700262 return true
263}
264
Neha Sharma94f16a92020-06-26 04:17:55 +0000265func (PONRMgr *PONResourceManager) UpdateRanges(ctx context.Context, StartIDx string, StartID uint32, EndIDx string, EndID uint32,
Scott Baker2c1c4822019-10-16 11:02:41 -0700266 SharedIDx string, SharedPoolID uint32, RMgr *PONResourceManager) {
267 /*
268 Update the ranges for all reosurce type in the intermnal maps
269 param: resource type start index
270 param: start ID
271 param: resource type end index
272 param: end ID
273 param: resource type shared index
274 param: shared pool id
275 param: global resource manager
276 */
Neha Sharma94f16a92020-06-26 04:17:55 +0000277 logger.Debugf(ctx, "update ranges for %s, %d", StartIDx, StartID)
Scott Baker2c1c4822019-10-16 11:02:41 -0700278
279 if StartID != 0 {
280 if (PONRMgr.PonResourceRanges[StartIDx] == nil) || (PONRMgr.PonResourceRanges[StartIDx].(uint32) < StartID) {
281 PONRMgr.PonResourceRanges[StartIDx] = StartID
282 }
283 }
284 if EndID != 0 {
285 if (PONRMgr.PonResourceRanges[EndIDx] == nil) || (PONRMgr.PonResourceRanges[EndIDx].(uint32) > EndID) {
286 PONRMgr.PonResourceRanges[EndIDx] = EndID
287 }
288 }
289 //if SharedPoolID != 0 {
290 PONRMgr.PonResourceRanges[SharedIDx] = SharedPoolID
291 //}
292 if RMgr != nil {
293 PONRMgr.SharedResourceMgrs[SharedIDx] = RMgr
294 }
295}
296
Neha Sharma94f16a92020-06-26 04:17:55 +0000297func (PONRMgr *PONResourceManager) InitDefaultPONResourceRanges(ctx context.Context,
298 ONUIDStart uint32,
Scott Baker2c1c4822019-10-16 11:02:41 -0700299 ONUIDEnd uint32,
300 ONUIDSharedPoolID uint32,
301 AllocIDStart uint32,
302 AllocIDEnd uint32,
303 AllocIDSharedPoolID uint32,
304 GEMPortIDStart uint32,
305 GEMPortIDEnd uint32,
306 GEMPortIDSharedPoolID uint32,
307 FlowIDStart uint32,
308 FlowIDEnd uint32,
309 FlowIDSharedPoolID uint32,
310 UNIIDStart uint32,
311 UNIIDEnd uint32,
312 NoOfPONPorts uint32,
313 IntfIDs []uint32) bool {
314
315 /*Initialize default PON resource ranges
316
317 :param onu_id_start_idx: onu id start index
318 :param onu_id_end_idx: onu id end index
319 :param onu_id_shared_pool_id: pool idx for id shared by all intfs or None for no sharing
320 :param alloc_id_start_idx: alloc id start index
321 :param alloc_id_end_idx: alloc id end index
322 :param alloc_id_shared_pool_id: pool idx for alloc id shared by all intfs or None for no sharing
323 :param gemport_id_start_idx: gemport id start index
324 :param gemport_id_end_idx: gemport id end index
325 :param gemport_id_shared_pool_id: pool idx for gemport id shared by all intfs or None for no sharing
326 :param flow_id_start_idx: flow id start index
327 :param flow_id_end_idx: flow id end index
328 :param flow_id_shared_pool_id: pool idx for flow id shared by all intfs or None for no sharing
329 :param num_of_pon_ports: number of PON ports
330 :param intf_ids: interfaces serviced by this manager
331 */
Neha Sharma94f16a92020-06-26 04:17:55 +0000332 PONRMgr.UpdateRanges(ctx, ONU_ID_START_IDX, ONUIDStart, ONU_ID_END_IDX, ONUIDEnd, ONU_ID_SHARED_IDX, ONUIDSharedPoolID, nil)
333 PONRMgr.UpdateRanges(ctx, ALLOC_ID_START_IDX, AllocIDStart, ALLOC_ID_END_IDX, AllocIDEnd, ALLOC_ID_SHARED_IDX, AllocIDSharedPoolID, nil)
334 PONRMgr.UpdateRanges(ctx, GEMPORT_ID_START_IDX, GEMPortIDStart, GEMPORT_ID_END_IDX, GEMPortIDEnd, GEMPORT_ID_SHARED_IDX, GEMPortIDSharedPoolID, nil)
335 PONRMgr.UpdateRanges(ctx, FLOW_ID_START_IDX, FlowIDStart, FLOW_ID_END_IDX, FlowIDEnd, FLOW_ID_SHARED_IDX, FlowIDSharedPoolID, nil)
336 PONRMgr.UpdateRanges(ctx, UNI_ID_START_IDX, UNIIDStart, UNI_ID_END_IDX, UNIIDEnd, "", 0, nil)
337 logger.Debug(ctx, "Initialize default range values")
Scott Baker2c1c4822019-10-16 11:02:41 -0700338 var i uint32
339 if IntfIDs == nil {
340 for i = 0; i < NoOfPONPorts; i++ {
341 PONRMgr.IntfIDs = append(PONRMgr.IntfIDs, i)
342 }
343 } else {
344 PONRMgr.IntfIDs = IntfIDs
345 }
346 return true
347}
348
npujar5bf737f2020-01-16 19:35:25 +0530349func (PONRMgr *PONResourceManager) InitDeviceResourcePool(ctx context.Context) error {
Scott Baker2c1c4822019-10-16 11:02:41 -0700350
351 //Initialize resource pool for all PON ports.
352
Neha Sharma94f16a92020-06-26 04:17:55 +0000353 logger.Debug(ctx, "Init resource ranges")
Scott Baker2c1c4822019-10-16 11:02:41 -0700354
355 var err error
356 for _, Intf := range PONRMgr.IntfIDs {
357 SharedPoolID := PONRMgr.PonResourceRanges[ONU_ID_SHARED_IDX].(uint32)
358 if SharedPoolID != 0 {
359 Intf = SharedPoolID
360 }
npujar5bf737f2020-01-16 19:35:25 +0530361 if err = PONRMgr.InitResourceIDPool(ctx, Intf, ONU_ID,
Scott Baker2c1c4822019-10-16 11:02:41 -0700362 PONRMgr.PonResourceRanges[ONU_ID_START_IDX].(uint32),
363 PONRMgr.PonResourceRanges[ONU_ID_END_IDX].(uint32)); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000364 logger.Error(ctx, "Failed to init ONU ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700365 return err
366 }
367 if SharedPoolID != 0 {
368 break
369 }
370 }
371
372 for _, Intf := range PONRMgr.IntfIDs {
373 SharedPoolID := PONRMgr.PonResourceRanges[ALLOC_ID_SHARED_IDX].(uint32)
374 if SharedPoolID != 0 {
375 Intf = SharedPoolID
376 }
npujar5bf737f2020-01-16 19:35:25 +0530377 if err = PONRMgr.InitResourceIDPool(ctx, Intf, ALLOC_ID,
Scott Baker2c1c4822019-10-16 11:02:41 -0700378 PONRMgr.PonResourceRanges[ALLOC_ID_START_IDX].(uint32),
379 PONRMgr.PonResourceRanges[ALLOC_ID_END_IDX].(uint32)); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000380 logger.Error(ctx, "Failed to init ALLOC ID resource pool ")
Scott Baker2c1c4822019-10-16 11:02:41 -0700381 return err
382 }
383 if SharedPoolID != 0 {
384 break
385 }
386 }
387 for _, Intf := range PONRMgr.IntfIDs {
388 SharedPoolID := PONRMgr.PonResourceRanges[GEMPORT_ID_SHARED_IDX].(uint32)
389 if SharedPoolID != 0 {
390 Intf = SharedPoolID
391 }
npujar5bf737f2020-01-16 19:35:25 +0530392 if err = PONRMgr.InitResourceIDPool(ctx, Intf, GEMPORT_ID,
Scott Baker2c1c4822019-10-16 11:02:41 -0700393 PONRMgr.PonResourceRanges[GEMPORT_ID_START_IDX].(uint32),
394 PONRMgr.PonResourceRanges[GEMPORT_ID_END_IDX].(uint32)); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000395 logger.Error(ctx, "Failed to init GEMPORT ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700396 return err
397 }
398 if SharedPoolID != 0 {
399 break
400 }
401 }
402
403 for _, Intf := range PONRMgr.IntfIDs {
404 SharedPoolID := PONRMgr.PonResourceRanges[FLOW_ID_SHARED_IDX].(uint32)
405 if SharedPoolID != 0 {
406 Intf = SharedPoolID
407 }
npujar5bf737f2020-01-16 19:35:25 +0530408 if err = PONRMgr.InitResourceIDPool(ctx, Intf, FLOW_ID,
Scott Baker2c1c4822019-10-16 11:02:41 -0700409 PONRMgr.PonResourceRanges[FLOW_ID_START_IDX].(uint32),
410 PONRMgr.PonResourceRanges[FLOW_ID_END_IDX].(uint32)); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000411 logger.Error(ctx, "Failed to init FLOW ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700412 return err
413 }
414 if SharedPoolID != 0 {
415 break
416 }
417 }
418 return err
419}
420
Girish Gowdra248971a2021-06-01 15:14:15 -0700421func (PONRMgr *PONResourceManager) InitDeviceResourcePoolForIntf(ctx context.Context, intfID uint32) error {
422
423 logger.Debug(ctx, "Init resource ranges for intf %d", intfID)
424
425 var err error
426
427 if err = PONRMgr.InitResourceIDPool(ctx, intfID, ONU_ID,
428 PONRMgr.PonResourceRanges[ONU_ID_START_IDX].(uint32),
429 PONRMgr.PonResourceRanges[ONU_ID_END_IDX].(uint32)); err != nil {
430 logger.Error(ctx, "Failed to init ONU ID resource pool")
431 return err
432 }
433
434 if err = PONRMgr.InitResourceIDPool(ctx, intfID, ALLOC_ID,
435 PONRMgr.PonResourceRanges[ALLOC_ID_START_IDX].(uint32),
436 PONRMgr.PonResourceRanges[ALLOC_ID_END_IDX].(uint32)); err != nil {
437 logger.Error(ctx, "Failed to init ALLOC ID resource pool ")
438 return err
439 }
440
441 if err = PONRMgr.InitResourceIDPool(ctx, intfID, GEMPORT_ID,
442 PONRMgr.PonResourceRanges[GEMPORT_ID_START_IDX].(uint32),
443 PONRMgr.PonResourceRanges[GEMPORT_ID_END_IDX].(uint32)); err != nil {
444 logger.Error(ctx, "Failed to init GEMPORT ID resource pool")
445 return err
446 }
447
448 if err = PONRMgr.InitResourceIDPool(ctx, intfID, FLOW_ID,
449 PONRMgr.PonResourceRanges[FLOW_ID_START_IDX].(uint32),
450 PONRMgr.PonResourceRanges[FLOW_ID_END_IDX].(uint32)); err != nil {
451 logger.Error(ctx, "Failed to init FLOW ID resource pool")
452 return err
453 }
454
455 return nil
456}
457
npujar5bf737f2020-01-16 19:35:25 +0530458func (PONRMgr *PONResourceManager) ClearDeviceResourcePool(ctx context.Context) error {
Scott Baker2c1c4822019-10-16 11:02:41 -0700459
460 //Clear resource pool for all PON ports.
461
Neha Sharma94f16a92020-06-26 04:17:55 +0000462 logger.Debug(ctx, "Clear resource ranges")
Scott Baker2c1c4822019-10-16 11:02:41 -0700463
464 for _, Intf := range PONRMgr.IntfIDs {
465 SharedPoolID := PONRMgr.PonResourceRanges[ONU_ID_SHARED_IDX].(uint32)
466 if SharedPoolID != 0 {
467 Intf = SharedPoolID
468 }
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800469 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, ONU_ID); !status {
Neha Sharma94f16a92020-06-26 04:17:55 +0000470 logger.Error(ctx, "Failed to clear ONU ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700471 return errors.New("Failed to clear ONU ID resource pool")
472 }
473 if SharedPoolID != 0 {
474 break
475 }
476 }
477
478 for _, Intf := range PONRMgr.IntfIDs {
479 SharedPoolID := PONRMgr.PonResourceRanges[ALLOC_ID_SHARED_IDX].(uint32)
480 if SharedPoolID != 0 {
481 Intf = SharedPoolID
482 }
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800483 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, ALLOC_ID); !status {
Neha Sharma94f16a92020-06-26 04:17:55 +0000484 logger.Error(ctx, "Failed to clear ALLOC ID resource pool ")
Scott Baker2c1c4822019-10-16 11:02:41 -0700485 return errors.New("Failed to clear ALLOC ID resource pool")
486 }
487 if SharedPoolID != 0 {
488 break
489 }
490 }
491 for _, Intf := range PONRMgr.IntfIDs {
492 SharedPoolID := PONRMgr.PonResourceRanges[GEMPORT_ID_SHARED_IDX].(uint32)
493 if SharedPoolID != 0 {
494 Intf = SharedPoolID
495 }
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800496 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, GEMPORT_ID); !status {
Neha Sharma94f16a92020-06-26 04:17:55 +0000497 logger.Error(ctx, "Failed to clear GEMPORT ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700498 return errors.New("Failed to clear GEMPORT ID resource pool")
499 }
500 if SharedPoolID != 0 {
501 break
502 }
503 }
504
505 for _, Intf := range PONRMgr.IntfIDs {
506 SharedPoolID := PONRMgr.PonResourceRanges[FLOW_ID_SHARED_IDX].(uint32)
507 if SharedPoolID != 0 {
508 Intf = SharedPoolID
509 }
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800510 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, FLOW_ID); !status {
Neha Sharma94f16a92020-06-26 04:17:55 +0000511 logger.Error(ctx, "Failed to clear FLOW ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700512 return errors.New("Failed to clear FLOW ID resource pool")
513 }
514 if SharedPoolID != 0 {
515 break
516 }
517 }
518 return nil
519}
520
Girish Gowdra248971a2021-06-01 15:14:15 -0700521func (PONRMgr *PONResourceManager) ClearDeviceResourcePoolForIntf(ctx context.Context, intfID uint32) error {
522
523 logger.Debugf(ctx, "Clear resource ranges for intf %d", intfID)
524
525 if status := PONRMgr.ClearResourceIDPool(ctx, intfID, ONU_ID); !status {
526 logger.Error(ctx, "Failed to clear ONU ID resource pool")
527 return errors.New("Failed to clear ONU ID resource pool")
528 }
529
530 if status := PONRMgr.ClearResourceIDPool(ctx, intfID, ALLOC_ID); !status {
531 logger.Error(ctx, "Failed to clear ALLOC ID resource pool ")
532 return errors.New("Failed to clear ALLOC ID resource pool")
533 }
534
535 if status := PONRMgr.ClearResourceIDPool(ctx, intfID, GEMPORT_ID); !status {
536 logger.Error(ctx, "Failed to clear GEMPORT ID resource pool")
537 return errors.New("Failed to clear GEMPORT ID resource pool")
538 }
539
540 if status := PONRMgr.ClearResourceIDPool(ctx, intfID, FLOW_ID); !status {
541 logger.Error(ctx, "Failed to clear FLOW ID resource pool")
542 return errors.New("Failed to clear FLOW ID resource pool")
543 }
544
545 return nil
546}
547
npujar5bf737f2020-01-16 19:35:25 +0530548func (PONRMgr *PONResourceManager) InitResourceIDPool(ctx context.Context, Intf uint32, ResourceType string, StartID uint32, EndID uint32) error {
Scott Baker2c1c4822019-10-16 11:02:41 -0700549
550 /*Initialize Resource ID pool for a given Resource Type on a given PON Port
551
552 :param pon_intf_id: OLT PON interface id
553 :param resource_type: String to identify type of resource
554 :param start_idx: start index for onu id pool
555 :param end_idx: end index for onu id pool
556 :return boolean: True if resource id pool initialized else false
557 */
558
559 // delegate to the master instance if sharing enabled across instances
560 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
561 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujar5bf737f2020-01-16 19:35:25 +0530562 return SharedResourceMgr.InitResourceIDPool(ctx, Intf, ResourceType, StartID, EndID)
Scott Baker2c1c4822019-10-16 11:02:41 -0700563 }
564
Neha Sharma94f16a92020-06-26 04:17:55 +0000565 Path := PONRMgr.GetPath(ctx, Intf, ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700566 if Path == "" {
Neha Sharma94f16a92020-06-26 04:17:55 +0000567 logger.Errorf(ctx, "Failed to get path for resource type %s", ResourceType)
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800568 return fmt.Errorf("Failed to get path for resource type %s", ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700569 }
570
571 //In case of adapter reboot and reconciliation resource in kv store
572 //checked for its presence if not kv store update happens
npujar5bf737f2020-01-16 19:35:25 +0530573 Res, err := PONRMgr.GetResource(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700574 if (err == nil) && (Res != nil) {
Neha Sharma94f16a92020-06-26 04:17:55 +0000575 logger.Debugf(ctx, "Resource %s already present in store ", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700576 return nil
577 } else {
Esin Karaman5351fc52020-02-14 07:45:49 +0000578 var excluded []uint32
579 if ResourceType == GEMPORT_ID {
580 //get gem port ids defined in the KV store, if any, and exclude them from the gem port id pool
581 if reservedGemPortIds, defined := PONRMgr.getReservedGemPortIdsFromKVStore(ctx); defined {
582 excluded = reservedGemPortIds
Neha Sharma94f16a92020-06-26 04:17:55 +0000583 logger.Debugw(ctx, "Excluding some ports from GEM port id pool", log.Fields{"excluded gem ports": excluded})
Esin Karaman5351fc52020-02-14 07:45:49 +0000584 }
585 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000586 FormatResult, err := PONRMgr.FormatResource(ctx, Intf, StartID, EndID, excluded)
Scott Baker2c1c4822019-10-16 11:02:41 -0700587 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000588 logger.Errorf(ctx, "Failed to format resource")
Scott Baker2c1c4822019-10-16 11:02:41 -0700589 return err
590 }
591 // Add resource as json in kv store.
npujar5bf737f2020-01-16 19:35:25 +0530592 err = PONRMgr.KVStore.Put(ctx, Path, FormatResult)
Scott Baker2c1c4822019-10-16 11:02:41 -0700593 if err == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000594 logger.Debug(ctx, "Successfuly posted to kv store")
Scott Baker2c1c4822019-10-16 11:02:41 -0700595 return err
596 }
597 }
598
Neha Sharma94f16a92020-06-26 04:17:55 +0000599 logger.Debug(ctx, "Error initializing pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700600
601 return err
602}
603
Esin Karaman5351fc52020-02-14 07:45:49 +0000604func (PONRMgr *PONResourceManager) getReservedGemPortIdsFromKVStore(ctx context.Context) ([]uint32, bool) {
605 var reservedGemPortIds []uint32
606 // read reserved gem ports from the config path
607 KvPair, err := PONRMgr.KVStoreForConfig.Get(ctx, RESERVED_GEMPORT_IDS_PATH)
608 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000609 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 +0000610 return reservedGemPortIds, false
611 }
612 if KvPair == nil || KvPair.Value == nil {
613 //no reserved gem port defined in the store
614 return reservedGemPortIds, false
615 }
616 Val, err := kvstore.ToByte(KvPair.Value)
617 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000618 logger.Errorw(ctx, "Failed to convert reserved gem port ids into byte array", log.Fields{"err": err})
Esin Karaman5351fc52020-02-14 07:45:49 +0000619 return reservedGemPortIds, false
620 }
621 if err = json.Unmarshal(Val, &reservedGemPortIds); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000622 logger.Errorw(ctx, "Failed to unmarshal reservedGemPortIds", log.Fields{"err": err})
Esin Karaman5351fc52020-02-14 07:45:49 +0000623 return reservedGemPortIds, false
624 }
625 return reservedGemPortIds, true
626}
627
Neha Sharma94f16a92020-06-26 04:17:55 +0000628func (PONRMgr *PONResourceManager) FormatResource(ctx context.Context, IntfID uint32, StartIDx uint32, EndIDx uint32,
Esin Karaman5351fc52020-02-14 07:45:49 +0000629 Excluded []uint32) ([]byte, error) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700630 /*
631 Format resource as json.
632 :param pon_intf_id: OLT PON interface id
633 :param start_idx: start index for id pool
634 :param end_idx: end index for id pool
Esin Karaman5351fc52020-02-14 07:45:49 +0000635 :Id values to be Excluded from the pool
Scott Baker2c1c4822019-10-16 11:02:41 -0700636 :return dictionary: resource formatted as map
637 */
638 // Format resource as json to be stored in backend store
639 Resource := make(map[string]interface{})
640 Resource[PON_INTF_ID] = IntfID
641 Resource[START_IDX] = StartIDx
642 Resource[END_IDX] = EndIDx
643 /*
644 Resource pool stored in backend store as binary string.
645 Tracking the resource allocation will be done by setting the bits \
646 in the byte array. The index set will be the resource number allocated.
647 */
648 var TSData *bitmap.Threadsafe
649 if TSData = bitmap.NewTS(int(EndIDx)); TSData == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000650 logger.Error(ctx, "Failed to create a bitmap")
Scott Baker2c1c4822019-10-16 11:02:41 -0700651 return nil, errors.New("Failed to create bitmap")
652 }
Esin Karaman5351fc52020-02-14 07:45:49 +0000653 for _, excludedID := range Excluded {
654 if excludedID < StartIDx || excludedID > EndIDx {
Neha Sharma94f16a92020-06-26 04:17:55 +0000655 logger.Warnf(ctx, "Cannot reserve %d. It must be in the range of [%d, %d]", excludedID,
Esin Karaman5351fc52020-02-14 07:45:49 +0000656 StartIDx, EndIDx)
657 continue
658 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000659 PONRMgr.reserveID(ctx, TSData, StartIDx, excludedID)
Esin Karaman5351fc52020-02-14 07:45:49 +0000660 }
Scott Baker2c1c4822019-10-16 11:02:41 -0700661 Resource[POOL] = TSData.Data(false) //we pass false so as the TSData lib api does not do a copy of the data and return
662
663 Value, err := json.Marshal(Resource)
664 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000665 logger.Errorf(ctx, "Failed to marshall resource")
Scott Baker2c1c4822019-10-16 11:02:41 -0700666 return nil, err
667 }
668 return Value, err
669}
npujar5bf737f2020-01-16 19:35:25 +0530670func (PONRMgr *PONResourceManager) GetResource(ctx context.Context, Path string) (map[string]interface{}, error) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700671 /*
672 Get resource from kv store.
673
674 :param path: path to get resource
675 :return: resource if resource present in kv store else None
676 */
677 //get resource from kv store
678
679 var Value []byte
680 Result := make(map[string]interface{})
681 var Str string
682
npujar5bf737f2020-01-16 19:35:25 +0530683 Resource, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700684 if (err != nil) || (Resource == nil) {
Neha Sharma94f16a92020-06-26 04:17:55 +0000685 logger.Debugf(ctx, "Resource unavailable at %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700686 return nil, err
687 }
688
689 Value, err = ToByte(Resource.Value)
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800690 if err != nil {
691 return nil, err
692 }
Scott Baker2c1c4822019-10-16 11:02:41 -0700693
694 // decode resource fetched from backend store to dictionary
695 err = json.Unmarshal(Value, &Result)
696 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000697 logger.Error(ctx, "Failed to decode resource")
Scott Baker2c1c4822019-10-16 11:02:41 -0700698 return Result, err
699 }
700 /*
701 resource pool in backend store stored as binary string whereas to
702 access the pool to generate/release IDs it need to be converted
703 as BitArray
704 */
705 Str, err = ToString(Result[POOL])
706 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000707 logger.Error(ctx, "Failed to conver to kv pair to string")
Scott Baker2c1c4822019-10-16 11:02:41 -0700708 return Result, err
709 }
710 Decode64, _ := base64.StdEncoding.DecodeString(Str)
711 Result[POOL], err = ToByte(Decode64)
712 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000713 logger.Error(ctx, "Failed to convert resource pool to byte")
Scott Baker2c1c4822019-10-16 11:02:41 -0700714 return Result, err
715 }
716
717 return Result, err
718}
719
Neha Sharma94f16a92020-06-26 04:17:55 +0000720func (PONRMgr *PONResourceManager) GetPath(ctx context.Context, IntfID uint32, ResourceType string) string {
Scott Baker2c1c4822019-10-16 11:02:41 -0700721 /*
722 Get path for given resource type.
723 :param pon_intf_id: OLT PON interface id
724 :param resource_type: String to identify type of resource
725 :return: path for given resource type
726 */
727
728 /*
729 Get the shared pool for the given resource type.
730 all the resource ranges and the shared resource maps are initialized during the init.
731 */
732 SharedPoolID := PONRMgr.PonResourceRanges[PONRMgr.SharedIdxByType[ResourceType]].(uint32)
733 if SharedPoolID != 0 {
734 IntfID = SharedPoolID
735 }
736 var Path string
737 if ResourceType == ONU_ID {
738 Path = fmt.Sprintf(ONU_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
739 } else if ResourceType == ALLOC_ID {
740 Path = fmt.Sprintf(ALLOC_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
741 } else if ResourceType == GEMPORT_ID {
742 Path = fmt.Sprintf(GEMPORT_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
743 } else if ResourceType == FLOW_ID {
744 Path = fmt.Sprintf(FLOW_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
745 } else {
Neha Sharma94f16a92020-06-26 04:17:55 +0000746 logger.Error(ctx, "Invalid resource pool identifier")
Scott Baker2c1c4822019-10-16 11:02:41 -0700747 }
748 return Path
749}
750
npujar5bf737f2020-01-16 19:35:25 +0530751func (PONRMgr *PONResourceManager) GetResourceID(ctx context.Context, IntfID uint32, ResourceType string, NumIDs uint32) ([]uint32, error) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700752 /*
753 Create alloc/gemport/onu/flow id for given OLT PON interface.
754 :param pon_intf_id: OLT PON interface id
755 :param resource_type: String to identify type of resource
756 :param num_of_id: required number of ids
757 :return list/uint32/None: list, uint32 or None if resource type is
758 alloc_id/gemport_id, onu_id or invalid type respectively
759 */
Matteo Scandolob85b2f02021-03-18 14:44:41 -0700760
761 logger.Debugw(ctx, "getting-resource-id", log.Fields{
762 "intf-id": IntfID,
763 "resource-type": ResourceType,
764 "num": NumIDs,
765 })
766
Scott Baker2c1c4822019-10-16 11:02:41 -0700767 if NumIDs < 1 {
Neha Sharma94f16a92020-06-26 04:17:55 +0000768 logger.Error(ctx, "Invalid number of resources requested")
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800769 return nil, fmt.Errorf("Invalid number of resources requested %d", NumIDs)
Scott Baker2c1c4822019-10-16 11:02:41 -0700770 }
771 // delegate to the master instance if sharing enabled across instances
772
773 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
774 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujar5bf737f2020-01-16 19:35:25 +0530775 return SharedResourceMgr.GetResourceID(ctx, IntfID, ResourceType, NumIDs)
Scott Baker2c1c4822019-10-16 11:02:41 -0700776 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000777 logger.Debugf(ctx, "Fetching resource from %s rsrc mgr for resource %s", PONRMgr.Globalorlocal, ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700778
Neha Sharma94f16a92020-06-26 04:17:55 +0000779 Path := PONRMgr.GetPath(ctx, IntfID, ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700780 if Path == "" {
Neha Sharma94f16a92020-06-26 04:17:55 +0000781 logger.Errorf(ctx, "Failed to get path for resource type %s", ResourceType)
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800782 return nil, fmt.Errorf("Failed to get path for resource type %s", ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700783 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000784 logger.Debugf(ctx, "Get resource for type %s on path %s", ResourceType, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700785 var Result []uint32
786 var NextID uint32
npujar5bf737f2020-01-16 19:35:25 +0530787 Resource, err := PONRMgr.GetResource(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700788 if (err == nil) && (ResourceType == ONU_ID) || (ResourceType == FLOW_ID) {
Neha Sharma94f16a92020-06-26 04:17:55 +0000789 if NextID, err = PONRMgr.GenerateNextID(ctx, Resource); err != nil {
790 logger.Error(ctx, "Failed to Generate ID")
Scott Baker2c1c4822019-10-16 11:02:41 -0700791 return Result, err
792 }
793 Result = append(Result, NextID)
794 } else if (err == nil) && ((ResourceType == GEMPORT_ID) || (ResourceType == ALLOC_ID)) {
795 if NumIDs == 1 {
Neha Sharma94f16a92020-06-26 04:17:55 +0000796 if NextID, err = PONRMgr.GenerateNextID(ctx, Resource); err != nil {
797 logger.Error(ctx, "Failed to Generate ID")
Scott Baker2c1c4822019-10-16 11:02:41 -0700798 return Result, err
799 }
800 Result = append(Result, NextID)
801 } else {
802 for NumIDs > 0 {
Neha Sharma94f16a92020-06-26 04:17:55 +0000803 if NextID, err = PONRMgr.GenerateNextID(ctx, Resource); err != nil {
804 logger.Error(ctx, "Failed to Generate ID")
Scott Baker2c1c4822019-10-16 11:02:41 -0700805 return Result, err
806 }
807 Result = append(Result, NextID)
808 NumIDs--
809 }
810 }
811 } else {
Neha Sharma94f16a92020-06-26 04:17:55 +0000812 logger.Error(ctx, "get resource failed")
Scott Baker2c1c4822019-10-16 11:02:41 -0700813 return Result, err
814 }
815
816 //Update resource in kv store
npujar5bf737f2020-01-16 19:35:25 +0530817 if PONRMgr.UpdateResource(ctx, Path, Resource) != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000818 logger.Errorf(ctx, "Failed to update resource %s", Path)
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800819 return nil, fmt.Errorf("Failed to update resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700820 }
821 return Result, nil
822}
823
824func checkValidResourceType(ResourceType string) bool {
825 KnownResourceTypes := []string{ONU_ID, ALLOC_ID, GEMPORT_ID, FLOW_ID}
826
827 for _, v := range KnownResourceTypes {
828 if v == ResourceType {
829 return true
830 }
831 }
832 return false
833}
834
Matteo Scandolob85b2f02021-03-18 14:44:41 -0700835func (PONRMgr *PONResourceManager) FreeResourceID(ctx context.Context, IntfID uint32, ResourceType string, ReleaseContent []uint32) error {
Scott Baker2c1c4822019-10-16 11:02:41 -0700836 /*
Matteo Scandolob85b2f02021-03-18 14:44:41 -0700837 Release alloc/gemport/onu/flow id for given OLT PON interface.
838 :param pon_intf_id: OLT PON interface id
839 :param resource_type: String to identify type of resource
840 :param release_content: required number of ids
841 :return boolean: True if all IDs in given release_content release else False
Scott Baker2c1c4822019-10-16 11:02:41 -0700842 */
Matteo Scandolob85b2f02021-03-18 14:44:41 -0700843
844 logger.Debugw(ctx, "freeing-resource-id", log.Fields{
845 "intf-id": IntfID,
846 "resource-type": ResourceType,
847 "release-content": ReleaseContent,
848 })
849
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800850 if !checkValidResourceType(ResourceType) {
Matteo Scandolob85b2f02021-03-18 14:44:41 -0700851 err := fmt.Errorf("Invalid resource type: %s", ResourceType)
852 logger.Error(ctx, err.Error())
853 return err
Scott Baker2c1c4822019-10-16 11:02:41 -0700854 }
855 if ReleaseContent == nil {
Matteo Scandolob85b2f02021-03-18 14:44:41 -0700856 err := fmt.Errorf("Nothing to release")
857 logger.Debug(ctx, err.Error())
858 return err
Scott Baker2c1c4822019-10-16 11:02:41 -0700859 }
860 // delegate to the master instance if sharing enabled across instances
861 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
862 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujar5bf737f2020-01-16 19:35:25 +0530863 return SharedResourceMgr.FreeResourceID(ctx, IntfID, ResourceType, ReleaseContent)
Scott Baker2c1c4822019-10-16 11:02:41 -0700864 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000865 Path := PONRMgr.GetPath(ctx, IntfID, ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700866 if Path == "" {
Matteo Scandolob85b2f02021-03-18 14:44:41 -0700867 err := fmt.Errorf("Failed to get path for IntfId %d and ResourceType %s", IntfID, ResourceType)
868 logger.Error(ctx, err.Error())
869 return err
Scott Baker2c1c4822019-10-16 11:02:41 -0700870 }
npujar5bf737f2020-01-16 19:35:25 +0530871 Resource, err := PONRMgr.GetResource(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700872 if err != nil {
Matteo Scandolob85b2f02021-03-18 14:44:41 -0700873 logger.Error(ctx, err.Error())
874 return err
Scott Baker2c1c4822019-10-16 11:02:41 -0700875 }
876 for _, Val := range ReleaseContent {
Neha Sharma94f16a92020-06-26 04:17:55 +0000877 PONRMgr.ReleaseID(ctx, Resource, Val)
Scott Baker2c1c4822019-10-16 11:02:41 -0700878 }
npujar5bf737f2020-01-16 19:35:25 +0530879 if PONRMgr.UpdateResource(ctx, Path, Resource) != nil {
Matteo Scandolob85b2f02021-03-18 14:44:41 -0700880 err := fmt.Errorf("Free resource for %s failed", Path)
881 logger.Errorf(ctx, err.Error())
882 return err
Scott Baker2c1c4822019-10-16 11:02:41 -0700883 }
Matteo Scandolob85b2f02021-03-18 14:44:41 -0700884 return nil
Scott Baker2c1c4822019-10-16 11:02:41 -0700885}
886
npujar5bf737f2020-01-16 19:35:25 +0530887func (PONRMgr *PONResourceManager) UpdateResource(ctx context.Context, Path string, Resource map[string]interface{}) error {
Scott Baker2c1c4822019-10-16 11:02:41 -0700888 /*
889 Update resource in resource kv store.
890 :param path: path to update resource
891 :param resource: resource need to be updated
892 :return boolean: True if resource updated in kv store else False
893 */
894 // TODO resource[POOL] = resource[POOL].bin
895 Value, err := json.Marshal(Resource)
896 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000897 logger.Error(ctx, "failed to Marshal")
Scott Baker2c1c4822019-10-16 11:02:41 -0700898 return err
899 }
npujar5bf737f2020-01-16 19:35:25 +0530900 err = PONRMgr.KVStore.Put(ctx, Path, Value)
Scott Baker2c1c4822019-10-16 11:02:41 -0700901 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000902 logger.Error(ctx, "failed to put data to kv store %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700903 return err
904 }
905 return nil
906}
907
npujar5bf737f2020-01-16 19:35:25 +0530908func (PONRMgr *PONResourceManager) ClearResourceIDPool(ctx context.Context, contIntfID uint32, ResourceType string) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -0700909 /*
910 Clear Resource Pool for a given Resource Type on a given PON Port.
911 :return boolean: True if removed else False
912 */
913
914 // delegate to the master instance if sharing enabled across instances
915 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
916 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujar5bf737f2020-01-16 19:35:25 +0530917 return SharedResourceMgr.ClearResourceIDPool(ctx, contIntfID, ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700918 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000919 Path := PONRMgr.GetPath(ctx, contIntfID, ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700920 if Path == "" {
Neha Sharma94f16a92020-06-26 04:17:55 +0000921 logger.Error(ctx, "Failed to get path")
Scott Baker2c1c4822019-10-16 11:02:41 -0700922 return false
923 }
924
npujar5bf737f2020-01-16 19:35:25 +0530925 if err := PONRMgr.KVStore.Delete(ctx, Path); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000926 logger.Errorf(ctx, "Failed to delete resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700927 return false
928 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000929 logger.Debugf(ctx, "Cleared resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700930 return true
931}
932
npujar5bf737f2020-01-16 19:35:25 +0530933func (PONRMgr PONResourceManager) InitResourceMap(ctx context.Context, PONIntfONUID string) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700934 /*
935 Initialize resource map
936 :param pon_intf_onu_id: reference of PON interface id and onu id
937 */
938 // initialize pon_intf_onu_id tuple to alloc_ids map
939 AllocIDPath := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
940 var AllocIDs []byte
npujar5bf737f2020-01-16 19:35:25 +0530941 Result := PONRMgr.KVStore.Put(ctx, AllocIDPath, AllocIDs)
Scott Baker2c1c4822019-10-16 11:02:41 -0700942 if Result != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000943 logger.Error(ctx, "Failed to update the KV store")
Scott Baker2c1c4822019-10-16 11:02:41 -0700944 return
945 }
946 // initialize pon_intf_onu_id tuple to gemport_ids map
947 GEMPortIDPath := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
948 var GEMPortIDs []byte
npujar5bf737f2020-01-16 19:35:25 +0530949 Result = PONRMgr.KVStore.Put(ctx, GEMPortIDPath, GEMPortIDs)
Scott Baker2c1c4822019-10-16 11:02:41 -0700950 if Result != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000951 logger.Error(ctx, "Failed to update the KV store")
Scott Baker2c1c4822019-10-16 11:02:41 -0700952 return
953 }
954}
955
npujar5bf737f2020-01-16 19:35:25 +0530956func (PONRMgr PONResourceManager) RemoveResourceMap(ctx context.Context, PONIntfONUID string) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -0700957 /*
958 Remove resource map
959 :param pon_intf_onu_id: reference of PON interface id and onu id
960 */
961 // remove pon_intf_onu_id tuple to alloc_ids map
962 var err error
963 AllocIDPath := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujar5bf737f2020-01-16 19:35:25 +0530964 if err = PONRMgr.KVStore.Delete(ctx, AllocIDPath); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000965 logger.Errorf(ctx, "Failed to remove resource %s", AllocIDPath)
Scott Baker2c1c4822019-10-16 11:02:41 -0700966 return false
967 }
968 // remove pon_intf_onu_id tuple to gemport_ids map
969 GEMPortIDPath := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujar5bf737f2020-01-16 19:35:25 +0530970 err = PONRMgr.KVStore.Delete(ctx, GEMPortIDPath)
Scott Baker2c1c4822019-10-16 11:02:41 -0700971 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000972 logger.Errorf(ctx, "Failed to remove resource %s", GEMPortIDPath)
Scott Baker2c1c4822019-10-16 11:02:41 -0700973 return false
974 }
975
976 FlowIDPath := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujar5bf737f2020-01-16 19:35:25 +0530977 if FlowIDs, err := PONRMgr.KVStore.List(ctx, FlowIDPath); err != nil {
Scott Baker2c1c4822019-10-16 11:02:41 -0700978 for _, Flow := range FlowIDs {
979 FlowIDInfoPath := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, PONIntfONUID, Flow.Value)
npujar5bf737f2020-01-16 19:35:25 +0530980 if err = PONRMgr.KVStore.Delete(ctx, FlowIDInfoPath); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000981 logger.Errorf(ctx, "Failed to remove resource %s", FlowIDInfoPath)
Scott Baker2c1c4822019-10-16 11:02:41 -0700982 return false
983 }
984 }
985 }
986
npujar5bf737f2020-01-16 19:35:25 +0530987 if err = PONRMgr.KVStore.Delete(ctx, FlowIDPath); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000988 logger.Errorf(ctx, "Failed to remove resource %s", FlowIDPath)
Scott Baker2c1c4822019-10-16 11:02:41 -0700989 return false
990 }
991
992 return true
993}
994
npujar5bf737f2020-01-16 19:35:25 +0530995func (PONRMgr *PONResourceManager) GetCurrentAllocIDForOnu(ctx context.Context, IntfONUID string) []uint32 {
Scott Baker2c1c4822019-10-16 11:02:41 -0700996 /*
997 Get currently configured alloc ids for given pon_intf_onu_id
998 :param pon_intf_onu_id: reference of PON interface id and onu id
999 :return list: List of alloc_ids if available, else None
1000 */
1001 Path := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
1002
1003 var Data []uint32
npujar5bf737f2020-01-16 19:35:25 +05301004 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001005 if err == nil {
1006 if Value != nil {
1007 Val, err := ToByte(Value.Value)
1008 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001009 logger.Errorw(ctx, "Failed to convert into byte array", log.Fields{"error": err})
Scott Baker2c1c4822019-10-16 11:02:41 -07001010 return Data
1011 }
1012 if err = json.Unmarshal(Val, &Data); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001013 logger.Error(ctx, "Failed to unmarshal", log.Fields{"error": err})
Scott Baker2c1c4822019-10-16 11:02:41 -07001014 return Data
1015 }
1016 }
1017 }
1018 return Data
1019}
1020
npujar5bf737f2020-01-16 19:35:25 +05301021func (PONRMgr *PONResourceManager) GetCurrentGEMPortIDsForOnu(ctx context.Context, IntfONUID string) []uint32 {
Scott Baker2c1c4822019-10-16 11:02:41 -07001022 /*
1023 Get currently configured gemport ids for given pon_intf_onu_id
1024 :param pon_intf_onu_id: reference of PON interface id and onu id
1025 :return list: List of gemport IDs if available, else None
1026 */
1027
1028 Path := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Neha Sharma94f16a92020-06-26 04:17:55 +00001029 logger.Debugf(ctx, "Getting current gemports for %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001030 var Data []uint32
npujar5bf737f2020-01-16 19:35:25 +05301031 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001032 if err == nil {
1033 if Value != nil {
1034 Val, _ := ToByte(Value.Value)
1035 if err = json.Unmarshal(Val, &Data); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001036 logger.Errorw(ctx, "Failed to unmarshal", log.Fields{"error": err})
Scott Baker2c1c4822019-10-16 11:02:41 -07001037 return Data
1038 }
1039 }
1040 } else {
Neha Sharma94f16a92020-06-26 04:17:55 +00001041 logger.Errorf(ctx, "Failed to get data from kvstore for %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001042 }
1043 return Data
1044}
1045
npujar5bf737f2020-01-16 19:35:25 +05301046func (PONRMgr *PONResourceManager) GetCurrentFlowIDsForOnu(ctx context.Context, IntfONUID string) []uint32 {
Scott Baker2c1c4822019-10-16 11:02:41 -07001047 /*
1048 Get currently configured flow ids for given pon_intf_onu_id
1049 :param pon_intf_onu_id: reference of PON interface id and onu id
1050 :return list: List of Flow IDs if available, else None
1051 */
1052
1053 Path := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
1054
1055 var Data []uint32
npujar5bf737f2020-01-16 19:35:25 +05301056 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001057 if err == nil {
1058 if Value != nil {
1059 Val, _ := ToByte(Value.Value)
1060 if err = json.Unmarshal(Val, &Data); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001061 logger.Error(ctx, "Failed to unmarshal")
Scott Baker2c1c4822019-10-16 11:02:41 -07001062 return Data
1063 }
1064 }
1065 }
1066 return Data
1067}
1068
npujar5bf737f2020-01-16 19:35:25 +05301069func (PONRMgr *PONResourceManager) GetFlowIDInfo(ctx context.Context, IntfONUID string, FlowID uint32, Data interface{}) error {
Scott Baker2c1c4822019-10-16 11:02:41 -07001070 /*
1071 Get flow details configured for the ONU.
1072 :param pon_intf_onu_id: reference of PON interface id and onu id
1073 :param flow_id: Flow Id reference
1074 :param Data: Result
1075 :return error: nil if no error in getting from KV store
1076 */
1077
1078 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
1079
npujar5bf737f2020-01-16 19:35:25 +05301080 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001081 if err == nil {
1082 if Value != nil {
1083 Val, err := ToByte(Value.Value)
1084 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001085 logger.Errorw(ctx, "Failed to convert flowinfo into byte array", log.Fields{"error": err})
Scott Baker2c1c4822019-10-16 11:02:41 -07001086 return err
1087 }
1088 if err = json.Unmarshal(Val, Data); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001089 logger.Errorw(ctx, "Failed to unmarshal", log.Fields{"error": err})
Scott Baker2c1c4822019-10-16 11:02:41 -07001090 return err
1091 }
1092 }
1093 }
1094 return err
1095}
1096
npujar5bf737f2020-01-16 19:35:25 +05301097func (PONRMgr *PONResourceManager) RemoveFlowIDInfo(ctx context.Context, IntfONUID string, FlowID uint32) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -07001098 /*
1099 Get flow_id details configured for the ONU.
1100 :param pon_intf_onu_id: reference of PON interface id and onu id
1101 :param flow_id: Flow Id reference
1102 */
1103 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
1104
npujar5bf737f2020-01-16 19:35:25 +05301105 if err := PONRMgr.KVStore.Delete(ctx, Path); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001106 logger.Errorf(ctx, "Falied to remove resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001107 return false
1108 }
1109 return true
1110}
1111
Serkant Uluderya198de902020-11-16 20:29:17 +03001112func (PONRMgr *PONResourceManager) RemoveAllFlowIDInfo(ctx context.Context, IntfONUID string) bool {
1113 /*
1114 Remove flow_id_info details configured for the ONU.
1115 :param pon_intf_onu_id: reference of PON interface id and onu id
1116 */
1117 Path := fmt.Sprintf(FLOW_ID_INFO_PATH_INTF_ONU_PREFIX, PONRMgr.DeviceID, IntfONUID)
1118
1119 if err := PONRMgr.KVStore.DeleteWithPrefix(ctx, Path); err != nil {
1120 logger.Errorf(ctx, "Falied to remove resource %s", Path)
1121 return false
1122 }
1123 return true
1124}
1125
npujar5bf737f2020-01-16 19:35:25 +05301126func (PONRMgr *PONResourceManager) UpdateAllocIdsForOnu(ctx context.Context, IntfONUID string, AllocIDs []uint32) error {
Scott Baker2c1c4822019-10-16 11:02:41 -07001127 /*
1128 Update currently configured alloc ids for given pon_intf_onu_id
1129 :param pon_intf_onu_id: reference of PON interface id and onu id
1130 :param alloc_ids: list of alloc ids
1131 */
1132 var Value []byte
1133 var err error
1134 Path := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Girish Gowdra823da1d2021-10-28 11:47:53 -07001135 if AllocIDs == nil {
1136 // No more alloc ids associated with the key. Delete the key entirely
1137 if err = PONRMgr.KVStore.Delete(ctx, Path); err != nil {
1138 logger.Errorf(ctx, "Failed to delete key %s", Path)
1139 return err
1140 }
1141 } else {
1142 Value, err = json.Marshal(AllocIDs)
1143 if err != nil {
1144 logger.Error(ctx, "failed to Marshal")
1145 return err
1146 }
Scott Baker2c1c4822019-10-16 11:02:41 -07001147
Girish Gowdra823da1d2021-10-28 11:47:53 -07001148 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
1149 logger.Errorf(ctx, "Failed to update resource %s", Path)
1150 return err
1151 }
Scott Baker2c1c4822019-10-16 11:02:41 -07001152 }
1153 return err
1154}
1155
npujar5bf737f2020-01-16 19:35:25 +05301156func (PONRMgr *PONResourceManager) UpdateGEMPortIDsForOnu(ctx context.Context, IntfONUID string, GEMPortIDs []uint32) error {
Scott Baker2c1c4822019-10-16 11:02:41 -07001157 /*
1158 Update currently configured gemport ids for given pon_intf_onu_id
1159 :param pon_intf_onu_id: reference of PON interface id and onu id
1160 :param gemport_ids: list of gem port ids
1161 */
1162
1163 var Value []byte
1164 var err error
1165 Path := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Neha Sharma94f16a92020-06-26 04:17:55 +00001166 logger.Debugf(ctx, "Updating gemport ids for %s", Path)
Girish Gowdra823da1d2021-10-28 11:47:53 -07001167 if GEMPortIDs == nil {
1168 // No more gemport ids associated with the key. Delete the key entirely
1169 if err = PONRMgr.KVStore.Delete(ctx, Path); err != nil {
1170 logger.Errorf(ctx, "Failed to delete key %s", Path)
1171 return err
1172 }
1173 } else {
1174 Value, err = json.Marshal(GEMPortIDs)
1175 if err != nil {
1176 logger.Error(ctx, "failed to Marshal")
1177 return err
1178 }
Scott Baker2c1c4822019-10-16 11:02:41 -07001179
Girish Gowdra823da1d2021-10-28 11:47:53 -07001180 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
1181 logger.Errorf(ctx, "Failed to update resource %s", Path)
1182 return err
1183 }
Scott Baker2c1c4822019-10-16 11:02:41 -07001184 }
1185 return err
1186}
1187
1188func checkForFlowIDInList(FlowIDList []uint32, FlowID uint32) (bool, uint32) {
1189 /*
1190 Check for a flow id in a given list of flow IDs.
1191 :param FLowIDList: List of Flow IDs
1192 :param FlowID: Flowd to check in the list
1193 : return true and the index if present false otherwise.
1194 */
1195
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001196 for idx := range FlowIDList {
Scott Baker2c1c4822019-10-16 11:02:41 -07001197 if FlowID == FlowIDList[idx] {
1198 return true, uint32(idx)
1199 }
1200 }
1201 return false, 0
1202}
1203
npujar5bf737f2020-01-16 19:35:25 +05301204func (PONRMgr *PONResourceManager) UpdateFlowIDForOnu(ctx context.Context, IntfONUID string, FlowID uint32, Add bool) error {
Scott Baker2c1c4822019-10-16 11:02:41 -07001205 /*
1206 Update the flow_id list of the ONU (add or remove flow_id from the list)
1207 :param pon_intf_onu_id: reference of PON interface id and onu id
1208 :param flow_id: flow ID
1209 :param add: Boolean flag to indicate whether the flow_id should be
1210 added or removed from the list. Defaults to adding the flow.
1211 */
1212 var Value []byte
1213 var err error
1214 var RetVal bool
1215 var IDx uint32
1216 Path := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
npujar5bf737f2020-01-16 19:35:25 +05301217 FlowIDs := PONRMgr.GetCurrentFlowIDsForOnu(ctx, IntfONUID)
Scott Baker2c1c4822019-10-16 11:02:41 -07001218
1219 if Add {
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001220 if RetVal, _ = checkForFlowIDInList(FlowIDs, FlowID); RetVal {
1221 return nil
Scott Baker2c1c4822019-10-16 11:02:41 -07001222 }
1223 FlowIDs = append(FlowIDs, FlowID)
1224 } else {
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001225 if RetVal, IDx = checkForFlowIDInList(FlowIDs, FlowID); !RetVal {
1226 return nil
Scott Baker2c1c4822019-10-16 11:02:41 -07001227 }
1228 // delete the index and shift
1229 FlowIDs = append(FlowIDs[:IDx], FlowIDs[IDx+1:]...)
1230 }
1231 Value, err = json.Marshal(FlowIDs)
1232 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001233 logger.Error(ctx, "Failed to Marshal")
Scott Baker2c1c4822019-10-16 11:02:41 -07001234 return err
1235 }
1236
npujar5bf737f2020-01-16 19:35:25 +05301237 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001238 logger.Errorf(ctx, "Failed to update resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001239 return err
1240 }
1241 return err
1242}
1243
npujar5bf737f2020-01-16 19:35:25 +05301244func (PONRMgr *PONResourceManager) UpdateFlowIDInfoForOnu(ctx context.Context, IntfONUID string, FlowID uint32, FlowData interface{}) error {
Scott Baker2c1c4822019-10-16 11:02:41 -07001245 /*
1246 Update any metadata associated with the flow_id. The flow_data could be json
1247 or any of other data structure. The resource manager doesnt care
1248 :param pon_intf_onu_id: reference of PON interface id and onu id
1249 :param flow_id: Flow ID
1250 :param flow_data: Flow data blob
1251 */
1252 var Value []byte
1253 var err error
1254 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
1255 Value, err = json.Marshal(FlowData)
1256 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001257 logger.Error(ctx, "failed to Marshal")
Scott Baker2c1c4822019-10-16 11:02:41 -07001258 return err
1259 }
1260
npujar5bf737f2020-01-16 19:35:25 +05301261 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001262 logger.Errorf(ctx, "Failed to update resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001263 return err
1264 }
1265 return err
1266}
1267
Neha Sharma94f16a92020-06-26 04:17:55 +00001268func (PONRMgr *PONResourceManager) GenerateNextID(ctx context.Context, Resource map[string]interface{}) (uint32, error) {
Scott Baker2c1c4822019-10-16 11:02:41 -07001269 /*
1270 Generate unique id having OFFSET as start
1271 :param resource: resource used to generate ID
1272 :return uint32: generated id
1273 */
1274 ByteArray, err := ToByte(Resource[POOL])
1275 if err != nil {
Scott Baker2c1c4822019-10-16 11:02:41 -07001276 return 0, err
1277 }
1278 Data := bitmap.TSFromData(ByteArray, false)
1279 if Data == nil {
Scott Baker2c1c4822019-10-16 11:02:41 -07001280 return 0, errors.New("Failed to get data from byte array")
1281 }
1282
1283 Len := Data.Len()
1284 var Idx int
1285 for Idx = 0; Idx < Len; Idx++ {
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001286 if !Data.Get(Idx) {
Scott Baker2c1c4822019-10-16 11:02:41 -07001287 break
1288 }
1289 }
Esin Karamanefab54e2021-10-13 11:11:43 +00001290 if Idx == Len {
1291 return 0, errors.New("resource-exhausted--no-free-id-in-the-pool")
1292 }
Scott Baker2c1c4822019-10-16 11:02:41 -07001293 Data.Set(Idx, true)
1294 res := uint32(Resource[START_IDX].(float64))
1295 Resource[POOL] = Data.Data(false)
Neha Sharma94f16a92020-06-26 04:17:55 +00001296 logger.Debugf(ctx, "Generated ID for %d", (uint32(Idx) + res))
Scott Baker2c1c4822019-10-16 11:02:41 -07001297 return (uint32(Idx) + res), err
1298}
1299
Neha Sharma94f16a92020-06-26 04:17:55 +00001300func (PONRMgr *PONResourceManager) ReleaseID(ctx context.Context, Resource map[string]interface{}, Id uint32) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -07001301 /*
1302 Release unique id having OFFSET as start index.
1303 :param resource: resource used to release ID
1304 :param unique_id: id need to be released
1305 */
1306 ByteArray, err := ToByte(Resource[POOL])
1307 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001308 logger.Error(ctx, "Failed to convert resource to byte array")
Scott Baker2c1c4822019-10-16 11:02:41 -07001309 return false
1310 }
1311 Data := bitmap.TSFromData(ByteArray, false)
1312 if Data == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001313 logger.Error(ctx, "Failed to get resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -07001314 return false
1315 }
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001316 Idx := Id - uint32(Resource[START_IDX].(float64))
Esin Karamanefab54e2021-10-13 11:11:43 +00001317 if Idx >= uint32(Data.Len()) {
1318 logger.Errorf(ctx, "ID %d is out of the boundaries of the pool", Id)
1319 return false
1320 }
Scott Baker2c1c4822019-10-16 11:02:41 -07001321 Data.Set(int(Idx), false)
1322 Resource[POOL] = Data.Data(false)
1323
1324 return true
1325}
1326
Esin Karaman5351fc52020-02-14 07:45:49 +00001327/* Reserves a unique id in the specified resource pool.
1328:param Resource: resource used to reserve ID
1329:param Id: ID to be reserved
1330*/
Neha Sharma94f16a92020-06-26 04:17:55 +00001331func (PONRMgr *PONResourceManager) reserveID(ctx context.Context, TSData *bitmap.Threadsafe, StartIndex uint32, Id uint32) bool {
Esin Karaman5351fc52020-02-14 07:45:49 +00001332 Data := bitmap.TSFromData(TSData.Data(false), false)
1333 if Data == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001334 logger.Error(ctx, "Failed to get resource pool")
Esin Karaman5351fc52020-02-14 07:45:49 +00001335 return false
1336 }
1337 Idx := Id - StartIndex
Esin Karamanefab54e2021-10-13 11:11:43 +00001338 if Idx >= uint32(Data.Len()) {
1339 logger.Errorf(ctx, "Reservation failed. ID %d is out of the boundaries of the pool", Id)
1340 return false
1341 }
Esin Karaman5351fc52020-02-14 07:45:49 +00001342 Data.Set(int(Idx), true)
1343 return true
1344}
1345
Scott Baker2c1c4822019-10-16 11:02:41 -07001346func (PONRMgr *PONResourceManager) GetTechnology() string {
1347 return PONRMgr.Technology
1348}
1349
1350func (PONRMgr *PONResourceManager) GetResourceTypeAllocID() string {
1351 return ALLOC_ID
1352}
1353
1354func (PONRMgr *PONResourceManager) GetResourceTypeGemPortID() string {
1355 return GEMPORT_ID
1356}
1357
Matteo Scandolob85b2f02021-03-18 14:44:41 -07001358func (PONRMgr *PONResourceManager) GetResourceTypeOnuID() string {
1359 return ONU_ID
1360}
1361
Scott Baker2c1c4822019-10-16 11:02:41 -07001362// ToByte converts an interface value to a []byte. The interface should either be of
1363// a string type or []byte. Otherwise, an error is returned.
1364func ToByte(value interface{}) ([]byte, error) {
1365 switch t := value.(type) {
1366 case []byte:
1367 return value.([]byte), nil
1368 case string:
1369 return []byte(value.(string)), nil
1370 default:
1371 return nil, fmt.Errorf("unexpected-type-%T", t)
1372 }
1373}
1374
1375// ToString converts an interface value to a string. The interface should either be of
1376// a string type or []byte. Otherwise, an error is returned.
1377func ToString(value interface{}) (string, error) {
1378 switch t := value.(type) {
1379 case []byte:
1380 return string(value.([]byte)), nil
1381 case string:
1382 return value.(string), nil
1383 default:
1384 return "", fmt.Errorf("unexpected-type-%T", t)
1385 }
1386}