blob: 39707111e6f5a2c95c6b8b9d4142311bd9f3ba1b [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"
Girish Gowdra4c60c672021-07-26 13:30:57 -070028 "github.com/opencord/voltha-lib-go/v6/pkg/db"
29 "github.com/opencord/voltha-lib-go/v6/pkg/db/kvstore"
30 "github.com/opencord/voltha-lib-go/v6/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
41 //Constants for passing command line arugments
42 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)
1135 Value, err = json.Marshal(AllocIDs)
1136 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001137 logger.Error(ctx, "failed to Marshal")
Scott Baker2c1c4822019-10-16 11:02:41 -07001138 return err
1139 }
1140
npujar5bf737f2020-01-16 19:35:25 +05301141 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001142 logger.Errorf(ctx, "Failed to update resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001143 return err
1144 }
1145 return err
1146}
1147
npujar5bf737f2020-01-16 19:35:25 +05301148func (PONRMgr *PONResourceManager) UpdateGEMPortIDsForOnu(ctx context.Context, IntfONUID string, GEMPortIDs []uint32) error {
Scott Baker2c1c4822019-10-16 11:02:41 -07001149 /*
1150 Update currently configured gemport ids for given pon_intf_onu_id
1151 :param pon_intf_onu_id: reference of PON interface id and onu id
1152 :param gemport_ids: list of gem port ids
1153 */
1154
1155 var Value []byte
1156 var err error
1157 Path := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Neha Sharma94f16a92020-06-26 04:17:55 +00001158 logger.Debugf(ctx, "Updating gemport ids for %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001159 Value, err = json.Marshal(GEMPortIDs)
1160 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001161 logger.Error(ctx, "failed to Marshal")
Scott Baker2c1c4822019-10-16 11:02:41 -07001162 return err
1163 }
1164
npujar5bf737f2020-01-16 19:35:25 +05301165 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001166 logger.Errorf(ctx, "Failed to update resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001167 return err
1168 }
1169 return err
1170}
1171
1172func checkForFlowIDInList(FlowIDList []uint32, FlowID uint32) (bool, uint32) {
1173 /*
1174 Check for a flow id in a given list of flow IDs.
1175 :param FLowIDList: List of Flow IDs
1176 :param FlowID: Flowd to check in the list
1177 : return true and the index if present false otherwise.
1178 */
1179
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001180 for idx := range FlowIDList {
Scott Baker2c1c4822019-10-16 11:02:41 -07001181 if FlowID == FlowIDList[idx] {
1182 return true, uint32(idx)
1183 }
1184 }
1185 return false, 0
1186}
1187
npujar5bf737f2020-01-16 19:35:25 +05301188func (PONRMgr *PONResourceManager) UpdateFlowIDForOnu(ctx context.Context, IntfONUID string, FlowID uint32, Add bool) error {
Scott Baker2c1c4822019-10-16 11:02:41 -07001189 /*
1190 Update the flow_id list of the ONU (add or remove flow_id from the list)
1191 :param pon_intf_onu_id: reference of PON interface id and onu id
1192 :param flow_id: flow ID
1193 :param add: Boolean flag to indicate whether the flow_id should be
1194 added or removed from the list. Defaults to adding the flow.
1195 */
1196 var Value []byte
1197 var err error
1198 var RetVal bool
1199 var IDx uint32
1200 Path := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
npujar5bf737f2020-01-16 19:35:25 +05301201 FlowIDs := PONRMgr.GetCurrentFlowIDsForOnu(ctx, IntfONUID)
Scott Baker2c1c4822019-10-16 11:02:41 -07001202
1203 if Add {
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001204 if RetVal, _ = checkForFlowIDInList(FlowIDs, FlowID); RetVal {
1205 return nil
Scott Baker2c1c4822019-10-16 11:02:41 -07001206 }
1207 FlowIDs = append(FlowIDs, FlowID)
1208 } else {
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001209 if RetVal, IDx = checkForFlowIDInList(FlowIDs, FlowID); !RetVal {
1210 return nil
Scott Baker2c1c4822019-10-16 11:02:41 -07001211 }
1212 // delete the index and shift
1213 FlowIDs = append(FlowIDs[:IDx], FlowIDs[IDx+1:]...)
1214 }
1215 Value, err = json.Marshal(FlowIDs)
1216 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001217 logger.Error(ctx, "Failed to Marshal")
Scott Baker2c1c4822019-10-16 11:02:41 -07001218 return err
1219 }
1220
npujar5bf737f2020-01-16 19:35:25 +05301221 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001222 logger.Errorf(ctx, "Failed to update resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001223 return err
1224 }
1225 return err
1226}
1227
npujar5bf737f2020-01-16 19:35:25 +05301228func (PONRMgr *PONResourceManager) UpdateFlowIDInfoForOnu(ctx context.Context, IntfONUID string, FlowID uint32, FlowData interface{}) error {
Scott Baker2c1c4822019-10-16 11:02:41 -07001229 /*
1230 Update any metadata associated with the flow_id. The flow_data could be json
1231 or any of other data structure. The resource manager doesnt care
1232 :param pon_intf_onu_id: reference of PON interface id and onu id
1233 :param flow_id: Flow ID
1234 :param flow_data: Flow data blob
1235 */
1236 var Value []byte
1237 var err error
1238 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
1239 Value, err = json.Marshal(FlowData)
1240 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001241 logger.Error(ctx, "failed to Marshal")
Scott Baker2c1c4822019-10-16 11:02:41 -07001242 return err
1243 }
1244
npujar5bf737f2020-01-16 19:35:25 +05301245 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001246 logger.Errorf(ctx, "Failed to update resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001247 return err
1248 }
1249 return err
1250}
1251
Neha Sharma94f16a92020-06-26 04:17:55 +00001252func (PONRMgr *PONResourceManager) GenerateNextID(ctx context.Context, Resource map[string]interface{}) (uint32, error) {
Scott Baker2c1c4822019-10-16 11:02:41 -07001253 /*
1254 Generate unique id having OFFSET as start
1255 :param resource: resource used to generate ID
1256 :return uint32: generated id
1257 */
1258 ByteArray, err := ToByte(Resource[POOL])
1259 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001260 logger.Error(ctx, "Failed to convert resource to byte array")
Scott Baker2c1c4822019-10-16 11:02:41 -07001261 return 0, err
1262 }
1263 Data := bitmap.TSFromData(ByteArray, false)
1264 if Data == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001265 logger.Error(ctx, "Failed to get data from byte array")
Scott Baker2c1c4822019-10-16 11:02:41 -07001266 return 0, errors.New("Failed to get data from byte array")
1267 }
1268
1269 Len := Data.Len()
1270 var Idx int
1271 for Idx = 0; Idx < Len; Idx++ {
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001272 if !Data.Get(Idx) {
Scott Baker2c1c4822019-10-16 11:02:41 -07001273 break
1274 }
1275 }
1276 Data.Set(Idx, true)
1277 res := uint32(Resource[START_IDX].(float64))
1278 Resource[POOL] = Data.Data(false)
Neha Sharma94f16a92020-06-26 04:17:55 +00001279 logger.Debugf(ctx, "Generated ID for %d", (uint32(Idx) + res))
Scott Baker2c1c4822019-10-16 11:02:41 -07001280 return (uint32(Idx) + res), err
1281}
1282
Neha Sharma94f16a92020-06-26 04:17:55 +00001283func (PONRMgr *PONResourceManager) ReleaseID(ctx context.Context, Resource map[string]interface{}, Id uint32) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -07001284 /*
1285 Release unique id having OFFSET as start index.
1286 :param resource: resource used to release ID
1287 :param unique_id: id need to be released
1288 */
1289 ByteArray, err := ToByte(Resource[POOL])
1290 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001291 logger.Error(ctx, "Failed to convert resource to byte array")
Scott Baker2c1c4822019-10-16 11:02:41 -07001292 return false
1293 }
1294 Data := bitmap.TSFromData(ByteArray, false)
1295 if Data == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001296 logger.Error(ctx, "Failed to get resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -07001297 return false
1298 }
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001299 Idx := Id - uint32(Resource[START_IDX].(float64))
Scott Baker2c1c4822019-10-16 11:02:41 -07001300 Data.Set(int(Idx), false)
1301 Resource[POOL] = Data.Data(false)
1302
1303 return true
1304}
1305
Esin Karaman5351fc52020-02-14 07:45:49 +00001306/* Reserves a unique id in the specified resource pool.
1307:param Resource: resource used to reserve ID
1308:param Id: ID to be reserved
1309*/
Neha Sharma94f16a92020-06-26 04:17:55 +00001310func (PONRMgr *PONResourceManager) reserveID(ctx context.Context, TSData *bitmap.Threadsafe, StartIndex uint32, Id uint32) bool {
Esin Karaman5351fc52020-02-14 07:45:49 +00001311 Data := bitmap.TSFromData(TSData.Data(false), false)
1312 if Data == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001313 logger.Error(ctx, "Failed to get resource pool")
Esin Karaman5351fc52020-02-14 07:45:49 +00001314 return false
1315 }
1316 Idx := Id - StartIndex
1317 Data.Set(int(Idx), true)
1318 return true
1319}
1320
Scott Baker2c1c4822019-10-16 11:02:41 -07001321func (PONRMgr *PONResourceManager) GetTechnology() string {
1322 return PONRMgr.Technology
1323}
1324
1325func (PONRMgr *PONResourceManager) GetResourceTypeAllocID() string {
1326 return ALLOC_ID
1327}
1328
1329func (PONRMgr *PONResourceManager) GetResourceTypeGemPortID() string {
1330 return GEMPORT_ID
1331}
1332
Matteo Scandolob85b2f02021-03-18 14:44:41 -07001333func (PONRMgr *PONResourceManager) GetResourceTypeOnuID() string {
1334 return ONU_ID
1335}
1336
Scott Baker2c1c4822019-10-16 11:02:41 -07001337// ToByte converts an interface value to a []byte. The interface should either be of
1338// a string type or []byte. Otherwise, an error is returned.
1339func ToByte(value interface{}) ([]byte, error) {
1340 switch t := value.(type) {
1341 case []byte:
1342 return value.([]byte), nil
1343 case string:
1344 return []byte(value.(string)), nil
1345 default:
1346 return nil, fmt.Errorf("unexpected-type-%T", t)
1347 }
1348}
1349
1350// ToString converts an interface value to a string. The interface should either be of
1351// a string type or []byte. Otherwise, an error is returned.
1352func ToString(value interface{}) (string, error) {
1353 switch t := value.(type) {
1354 case []byte:
1355 return string(value.([]byte)), nil
1356 case string:
1357 return value.(string), nil
1358 default:
1359 return "", fmt.Errorf("unexpected-type-%T", t)
1360 }
1361}