blob: b4c2fec8b69c65ce542923b2d2f3cff7b7a32ac2 [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 Gowdra89c985b2020-10-14 15:02:09 -070028 "github.com/opencord/voltha-lib-go/v4/pkg/db"
29 "github.com/opencord/voltha-lib-go/v4/pkg/db/kvstore"
30 "github.com/opencord/voltha-lib-go/v4/pkg/log"
31 tp "github.com/opencord/voltha-lib-go/v4/pkg/techprofile"
Scott Baker2c1c4822019-10-16 11:02:41 -070032)
33
34const (
35 //Constants to identify resource pool
36 UNI_ID = "UNI_ID"
37 ONU_ID = "ONU_ID"
38 ALLOC_ID = "ALLOC_ID"
39 GEMPORT_ID = "GEMPORT_ID"
40 FLOW_ID = "FLOW_ID"
41
42 //Constants for passing command line arugments
43 OLT_MODEL_ARG = "--olt_model"
Matteo Scandolo29ff79c2020-11-06 13:03:17 -080044
45 PATH_PREFIX = "%s/resource_manager/{%s}"
Esin Karaman5351fc52020-02-14 07:45:49 +000046
47 /*The path under which configuration data is stored is defined as technology/device agnostic.
48 That means the path does not include any specific technology/device variable. Using technology/device
49 agnostic path also makes northbound applications, that need to write to this path,
50 technology/device agnostic.
51
52 Default kv client of PonResourceManager reads from/writes to PATH_PREFIX defined above.
53 That is why, an additional kv client (named KVStoreForConfig) is defined to read from the config path.
54 */
Matteo Scandolo29ff79c2020-11-06 13:03:17 -080055
56 PATH_PREFIX_FOR_CONFIG = "%s/resource_manager/config"
Scott Baker2c1c4822019-10-16 11:02:41 -070057 /*The resource ranges for a given device model should be placed
58 at 'resource_manager/<technology>/resource_ranges/<olt_model_type>'
59 path on the KV store.
60 If Resource Range parameters are to be read from the external KV store,
61 they are expected to be stored in the following format.
62 Note: All parameters are MANDATORY for now.
63 constants used as keys to reference the resource range parameters from
64 and external KV store.
65 */
66 UNI_ID_START_IDX = "uni_id_start"
67 UNI_ID_END_IDX = "uni_id_end"
68 ONU_ID_START_IDX = "onu_id_start"
69 ONU_ID_END_IDX = "onu_id_end"
70 ONU_ID_SHARED_IDX = "onu_id_shared"
71 ALLOC_ID_START_IDX = "alloc_id_start"
72 ALLOC_ID_END_IDX = "alloc_id_end"
73 ALLOC_ID_SHARED_IDX = "alloc_id_shared"
74 GEMPORT_ID_START_IDX = "gemport_id_start"
75 GEMPORT_ID_END_IDX = "gemport_id_end"
76 GEMPORT_ID_SHARED_IDX = "gemport_id_shared"
77 FLOW_ID_START_IDX = "flow_id_start"
78 FLOW_ID_END_IDX = "flow_id_end"
79 FLOW_ID_SHARED_IDX = "flow_id_shared"
80 NUM_OF_PON_PORT = "pon_ports"
81
82 /*
83 The KV store backend is initialized with a path prefix and we need to
84 provide only the suffix.
85 */
86 PON_RESOURCE_RANGE_CONFIG_PATH = "resource_ranges/%s"
87
88 //resource path suffix
89 //Path on the KV store for storing alloc id ranges and resource pool for a given interface
90 //Format: <device_id>/alloc_id_pool/<pon_intf_id>
91 ALLOC_ID_POOL_PATH = "{%s}/alloc_id_pool/{%d}"
92 //Path on the KV store for storing gemport id ranges and resource pool for a given interface
93 //Format: <device_id>/gemport_id_pool/<pon_intf_id>
94 GEMPORT_ID_POOL_PATH = "{%s}/gemport_id_pool/{%d}"
95 //Path on the KV store for storing onu id ranges and resource pool for a given interface
96 //Format: <device_id>/onu_id_pool/<pon_intf_id>
97 ONU_ID_POOL_PATH = "{%s}/onu_id_pool/{%d}"
98 //Path on the KV store for storing flow id ranges and resource pool for a given interface
99 //Format: <device_id>/flow_id_pool/<pon_intf_id>
100 FLOW_ID_POOL_PATH = "{%s}/flow_id_pool/{%d}"
101
102 //Path on the KV store for storing list of alloc IDs for a given ONU
103 //Format: <device_id>/<(pon_intf_id, onu_id)>/alloc_ids
104 ALLOC_ID_RESOURCE_MAP_PATH = "{%s}/{%s}/alloc_ids"
105
106 //Path on the KV store for storing list of gemport IDs for a given ONU
107 //Format: <device_id>/<(pon_intf_id, onu_id)>/gemport_ids
108 GEMPORT_ID_RESOURCE_MAP_PATH = "{%s}/{%s}/gemport_ids"
109
110 //Path on the KV store for storing list of Flow IDs for a given ONU
111 //Format: <device_id>/<(pon_intf_id, onu_id)>/flow_ids
112 FLOW_ID_RESOURCE_MAP_PATH = "{%s}/{%s}/flow_ids"
113
114 //Flow Id info: Use to store more metadata associated with the flow_id
115 //Format: <device_id>/<(pon_intf_id, onu_id)>/flow_id_info/<flow_id>
116 FLOW_ID_INFO_PATH = "{%s}/{%s}/flow_id_info/{%d}"
117
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +0530118 //path on the kvstore to store onugem info map
119 //format: <device-id>/onu_gem_info/<intfid>
120 ONU_GEM_INFO_PATH = "{%s}/onu_gem_info/{%d}" // onu_gem/<(intfid)>
121
Scott Baker2c1c4822019-10-16 11:02:41 -0700122 //Constants for internal usage.
123 PON_INTF_ID = "pon_intf_id"
124 START_IDX = "start_idx"
125 END_IDX = "end_idx"
126 POOL = "pool"
127 NUM_OF_PON_INTF = 16
128
Neha Sharma130ac6d2020-04-08 08:46:32 +0000129 KVSTORE_RETRY_TIMEOUT = 5 * time.Second
Esin Karaman5351fc52020-02-14 07:45:49 +0000130 //Path on the KV store for storing reserved gem ports
131 //Format: reserved_gemport_ids
132 RESERVED_GEMPORT_IDS_PATH = "reserved_gemport_ids"
Scott Baker2c1c4822019-10-16 11:02:41 -0700133)
134
135//type ResourceTypeIndex string
136//type ResourceType string
137
138type PONResourceManager struct {
139 //Implements APIs to initialize/allocate/release alloc/gemport/onu IDs.
Esin Karaman5351fc52020-02-14 07:45:49 +0000140 Technology string
141 DeviceType string
142 DeviceID string
143 Backend string // ETCD, or consul
Neha Sharmadd9af392020-04-28 09:03:57 +0000144 Address string // address of the KV store
Esin Karaman5351fc52020-02-14 07:45:49 +0000145 OLTModel string
146 KVStore *db.Backend
147 KVStoreForConfig *db.Backend
148 TechProfileMgr tp.TechProfileIf // create object of *tp.TechProfileMgr
Scott Baker2c1c4822019-10-16 11:02:41 -0700149
150 // Below attribute, pon_resource_ranges, should be initialized
151 // by reading from KV store.
152 PonResourceRanges map[string]interface{}
153 SharedResourceMgrs map[string]*PONResourceManager
154 SharedIdxByType map[string]string
155 IntfIDs []uint32 // list of pon interface IDs
156 Globalorlocal string
157}
158
Neha Sharma94f16a92020-06-26 04:17:55 +0000159func newKVClient(ctx context.Context, storeType string, address string, timeout time.Duration) (kvstore.Client, error) {
160 logger.Infow(ctx, "kv-store-type", log.Fields{"store": storeType})
Scott Baker2c1c4822019-10-16 11:02:41 -0700161 switch storeType {
162 case "consul":
Neha Sharma94f16a92020-06-26 04:17:55 +0000163 return kvstore.NewConsulClient(ctx, address, timeout)
Scott Baker2c1c4822019-10-16 11:02:41 -0700164 case "etcd":
Neha Sharma94f16a92020-06-26 04:17:55 +0000165 return kvstore.NewEtcdClient(ctx, address, timeout, log.WarnLevel)
Scott Baker2c1c4822019-10-16 11:02:41 -0700166 }
167 return nil, errors.New("unsupported-kv-store")
168}
169
Matteo Scandolo29ff79c2020-11-06 13:03:17 -0800170func SetKVClient(ctx context.Context, Technology string, Backend string, Addr string, configClient bool, basePathKvStore string) *db.Backend {
Scott Baker2c1c4822019-10-16 11:02:41 -0700171 // TODO : Make sure direct call to NewBackend is working fine with backend , currently there is some
172 // issue between kv store and backend , core is not calling NewBackend directly
Neha Sharma94f16a92020-06-26 04:17:55 +0000173 kvClient, err := newKVClient(ctx, Backend, Addr, KVSTORE_RETRY_TIMEOUT)
Scott Baker2c1c4822019-10-16 11:02:41 -0700174 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000175 logger.Fatalw(ctx, "Failed to init KV client\n", log.Fields{"err": err})
Scott Baker2c1c4822019-10-16 11:02:41 -0700176 return nil
177 }
Esin Karaman5351fc52020-02-14 07:45:49 +0000178
179 var pathPrefix string
180 if configClient {
Matteo Scandolo29ff79c2020-11-06 13:03:17 -0800181 pathPrefix = fmt.Sprintf(PATH_PREFIX_FOR_CONFIG, basePathKvStore)
Esin Karaman5351fc52020-02-14 07:45:49 +0000182 } else {
Matteo Scandolo29ff79c2020-11-06 13:03:17 -0800183 pathPrefix = fmt.Sprintf(PATH_PREFIX, basePathKvStore, Technology)
Esin Karaman5351fc52020-02-14 07:45:49 +0000184 }
185
sbarbari1e3e29c2019-11-05 10:06:50 -0500186 kvbackend := &db.Backend{
Scott Baker2c1c4822019-10-16 11:02:41 -0700187 Client: kvClient,
188 StoreType: Backend,
Neha Sharmadd9af392020-04-28 09:03:57 +0000189 Address: Addr,
Scott Baker2c1c4822019-10-16 11:02:41 -0700190 Timeout: KVSTORE_RETRY_TIMEOUT,
Esin Karaman5351fc52020-02-14 07:45:49 +0000191 PathPrefix: pathPrefix}
Scott Baker2c1c4822019-10-16 11:02:41 -0700192
193 return kvbackend
194}
195
196// NewPONResourceManager creates a new PON resource manager.
Matteo Scandolo29ff79c2020-11-06 13:03:17 -0800197func 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 -0700198 var PONMgr PONResourceManager
199 PONMgr.Technology = Technology
200 PONMgr.DeviceType = DeviceType
201 PONMgr.DeviceID = DeviceID
202 PONMgr.Backend = Backend
Neha Sharmadd9af392020-04-28 09:03:57 +0000203 PONMgr.Address = Address
Matteo Scandolo29ff79c2020-11-06 13:03:17 -0800204 PONMgr.KVStore = SetKVClient(ctx, Technology, Backend, Address, false, basePathKvStore)
Scott Baker2c1c4822019-10-16 11:02:41 -0700205 if PONMgr.KVStore == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000206 logger.Error(ctx, "KV Client initilization failed")
Scott Baker2c1c4822019-10-16 11:02:41 -0700207 return nil, errors.New("Failed to init KV client")
208 }
Esin Karaman5351fc52020-02-14 07:45:49 +0000209 // init kv client to read from the config path
Matteo Scandolo29ff79c2020-11-06 13:03:17 -0800210 PONMgr.KVStoreForConfig = SetKVClient(ctx, Technology, Backend, Address, true, basePathKvStore)
Esin Karaman5351fc52020-02-14 07:45:49 +0000211 if PONMgr.KVStoreForConfig == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000212 logger.Error(ctx, "KV Config Client initilization failed")
Esin Karaman5351fc52020-02-14 07:45:49 +0000213 return nil, errors.New("Failed to init KV Config client")
214 }
Scott Baker2c1c4822019-10-16 11:02:41 -0700215 // Initialize techprofile for this technology
Neha Sharma94f16a92020-06-26 04:17:55 +0000216 if PONMgr.TechProfileMgr, _ = tp.NewTechProfile(ctx, &PONMgr, Backend, Address); PONMgr.TechProfileMgr == nil {
217 logger.Error(ctx, "Techprofile initialization failed")
Scott Baker2c1c4822019-10-16 11:02:41 -0700218 return nil, errors.New("Failed to init tech profile")
219 }
220 PONMgr.PonResourceRanges = make(map[string]interface{})
221 PONMgr.SharedResourceMgrs = make(map[string]*PONResourceManager)
222 PONMgr.SharedIdxByType = make(map[string]string)
223 PONMgr.SharedIdxByType[ONU_ID] = ONU_ID_SHARED_IDX
224 PONMgr.SharedIdxByType[ALLOC_ID] = ALLOC_ID_SHARED_IDX
225 PONMgr.SharedIdxByType[GEMPORT_ID] = GEMPORT_ID_SHARED_IDX
226 PONMgr.SharedIdxByType[FLOW_ID] = FLOW_ID_SHARED_IDX
227 PONMgr.IntfIDs = make([]uint32, NUM_OF_PON_INTF)
228 PONMgr.OLTModel = DeviceType
229 return &PONMgr, nil
230}
231
232/*
233 Initialize PON resource ranges with config fetched from kv store.
234 return boolean: True if PON resource ranges initialized else false
235 Try to initialize the PON Resource Ranges from KV store based on the
236 OLT model key, if available
237*/
238
npujar5bf737f2020-01-16 19:35:25 +0530239func (PONRMgr *PONResourceManager) InitResourceRangesFromKVStore(ctx context.Context) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -0700240 //Initialize PON resource ranges with config fetched from kv store.
241 //:return boolean: True if PON resource ranges initialized else false
242 // Try to initialize the PON Resource Ranges from KV store based on the
243 // OLT model key, if available
244 if PONRMgr.OLTModel == "" {
Neha Sharma94f16a92020-06-26 04:17:55 +0000245 logger.Error(ctx, "Failed to get OLT model")
Scott Baker2c1c4822019-10-16 11:02:41 -0700246 return false
247 }
248 Path := fmt.Sprintf(PON_RESOURCE_RANGE_CONFIG_PATH, PONRMgr.OLTModel)
249 //get resource from kv store
npujar5bf737f2020-01-16 19:35:25 +0530250 Result, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700251 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000252 logger.Debugf(ctx, "Error in fetching resource %s from KV strore", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700253 return false
254 }
255 if Result == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000256 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 -0700257 return false
258 }
259 //update internal ranges from kv ranges. If there are missing
260 // values in the KV profile, continue to use the defaults
261 Value, err := ToByte(Result.Value)
262 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000263 logger.Error(ctx, "Failed to convert kvpair to byte string")
Scott Baker2c1c4822019-10-16 11:02:41 -0700264 return false
265 }
266 if err := json.Unmarshal(Value, &PONRMgr.PonResourceRanges); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000267 logger.Error(ctx, "Failed to Unmarshal json byte")
Scott Baker2c1c4822019-10-16 11:02:41 -0700268 return false
269 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000270 logger.Debug(ctx, "Init resource ranges from kvstore success")
Scott Baker2c1c4822019-10-16 11:02:41 -0700271 return true
272}
273
Neha Sharma94f16a92020-06-26 04:17:55 +0000274func (PONRMgr *PONResourceManager) UpdateRanges(ctx context.Context, StartIDx string, StartID uint32, EndIDx string, EndID uint32,
Scott Baker2c1c4822019-10-16 11:02:41 -0700275 SharedIDx string, SharedPoolID uint32, RMgr *PONResourceManager) {
276 /*
277 Update the ranges for all reosurce type in the intermnal maps
278 param: resource type start index
279 param: start ID
280 param: resource type end index
281 param: end ID
282 param: resource type shared index
283 param: shared pool id
284 param: global resource manager
285 */
Neha Sharma94f16a92020-06-26 04:17:55 +0000286 logger.Debugf(ctx, "update ranges for %s, %d", StartIDx, StartID)
Scott Baker2c1c4822019-10-16 11:02:41 -0700287
288 if StartID != 0 {
289 if (PONRMgr.PonResourceRanges[StartIDx] == nil) || (PONRMgr.PonResourceRanges[StartIDx].(uint32) < StartID) {
290 PONRMgr.PonResourceRanges[StartIDx] = StartID
291 }
292 }
293 if EndID != 0 {
294 if (PONRMgr.PonResourceRanges[EndIDx] == nil) || (PONRMgr.PonResourceRanges[EndIDx].(uint32) > EndID) {
295 PONRMgr.PonResourceRanges[EndIDx] = EndID
296 }
297 }
298 //if SharedPoolID != 0 {
299 PONRMgr.PonResourceRanges[SharedIDx] = SharedPoolID
300 //}
301 if RMgr != nil {
302 PONRMgr.SharedResourceMgrs[SharedIDx] = RMgr
303 }
304}
305
Neha Sharma94f16a92020-06-26 04:17:55 +0000306func (PONRMgr *PONResourceManager) InitDefaultPONResourceRanges(ctx context.Context,
307 ONUIDStart uint32,
Scott Baker2c1c4822019-10-16 11:02:41 -0700308 ONUIDEnd uint32,
309 ONUIDSharedPoolID uint32,
310 AllocIDStart uint32,
311 AllocIDEnd uint32,
312 AllocIDSharedPoolID uint32,
313 GEMPortIDStart uint32,
314 GEMPortIDEnd uint32,
315 GEMPortIDSharedPoolID uint32,
316 FlowIDStart uint32,
317 FlowIDEnd uint32,
318 FlowIDSharedPoolID uint32,
319 UNIIDStart uint32,
320 UNIIDEnd uint32,
321 NoOfPONPorts uint32,
322 IntfIDs []uint32) bool {
323
324 /*Initialize default PON resource ranges
325
326 :param onu_id_start_idx: onu id start index
327 :param onu_id_end_idx: onu id end index
328 :param onu_id_shared_pool_id: pool idx for id shared by all intfs or None for no sharing
329 :param alloc_id_start_idx: alloc id start index
330 :param alloc_id_end_idx: alloc id end index
331 :param alloc_id_shared_pool_id: pool idx for alloc id shared by all intfs or None for no sharing
332 :param gemport_id_start_idx: gemport id start index
333 :param gemport_id_end_idx: gemport id end index
334 :param gemport_id_shared_pool_id: pool idx for gemport id shared by all intfs or None for no sharing
335 :param flow_id_start_idx: flow id start index
336 :param flow_id_end_idx: flow id end index
337 :param flow_id_shared_pool_id: pool idx for flow id shared by all intfs or None for no sharing
338 :param num_of_pon_ports: number of PON ports
339 :param intf_ids: interfaces serviced by this manager
340 */
Neha Sharma94f16a92020-06-26 04:17:55 +0000341 PONRMgr.UpdateRanges(ctx, ONU_ID_START_IDX, ONUIDStart, ONU_ID_END_IDX, ONUIDEnd, ONU_ID_SHARED_IDX, ONUIDSharedPoolID, nil)
342 PONRMgr.UpdateRanges(ctx, ALLOC_ID_START_IDX, AllocIDStart, ALLOC_ID_END_IDX, AllocIDEnd, ALLOC_ID_SHARED_IDX, AllocIDSharedPoolID, nil)
343 PONRMgr.UpdateRanges(ctx, GEMPORT_ID_START_IDX, GEMPortIDStart, GEMPORT_ID_END_IDX, GEMPortIDEnd, GEMPORT_ID_SHARED_IDX, GEMPortIDSharedPoolID, nil)
344 PONRMgr.UpdateRanges(ctx, FLOW_ID_START_IDX, FlowIDStart, FLOW_ID_END_IDX, FlowIDEnd, FLOW_ID_SHARED_IDX, FlowIDSharedPoolID, nil)
345 PONRMgr.UpdateRanges(ctx, UNI_ID_START_IDX, UNIIDStart, UNI_ID_END_IDX, UNIIDEnd, "", 0, nil)
346 logger.Debug(ctx, "Initialize default range values")
Scott Baker2c1c4822019-10-16 11:02:41 -0700347 var i uint32
348 if IntfIDs == nil {
349 for i = 0; i < NoOfPONPorts; i++ {
350 PONRMgr.IntfIDs = append(PONRMgr.IntfIDs, i)
351 }
352 } else {
353 PONRMgr.IntfIDs = IntfIDs
354 }
355 return true
356}
357
npujar5bf737f2020-01-16 19:35:25 +0530358func (PONRMgr *PONResourceManager) InitDeviceResourcePool(ctx context.Context) error {
Scott Baker2c1c4822019-10-16 11:02:41 -0700359
360 //Initialize resource pool for all PON ports.
361
Neha Sharma94f16a92020-06-26 04:17:55 +0000362 logger.Debug(ctx, "Init resource ranges")
Scott Baker2c1c4822019-10-16 11:02:41 -0700363
364 var err error
365 for _, Intf := range PONRMgr.IntfIDs {
366 SharedPoolID := PONRMgr.PonResourceRanges[ONU_ID_SHARED_IDX].(uint32)
367 if SharedPoolID != 0 {
368 Intf = SharedPoolID
369 }
npujar5bf737f2020-01-16 19:35:25 +0530370 if err = PONRMgr.InitResourceIDPool(ctx, Intf, ONU_ID,
Scott Baker2c1c4822019-10-16 11:02:41 -0700371 PONRMgr.PonResourceRanges[ONU_ID_START_IDX].(uint32),
372 PONRMgr.PonResourceRanges[ONU_ID_END_IDX].(uint32)); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000373 logger.Error(ctx, "Failed to init ONU ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700374 return err
375 }
376 if SharedPoolID != 0 {
377 break
378 }
379 }
380
381 for _, Intf := range PONRMgr.IntfIDs {
382 SharedPoolID := PONRMgr.PonResourceRanges[ALLOC_ID_SHARED_IDX].(uint32)
383 if SharedPoolID != 0 {
384 Intf = SharedPoolID
385 }
npujar5bf737f2020-01-16 19:35:25 +0530386 if err = PONRMgr.InitResourceIDPool(ctx, Intf, ALLOC_ID,
Scott Baker2c1c4822019-10-16 11:02:41 -0700387 PONRMgr.PonResourceRanges[ALLOC_ID_START_IDX].(uint32),
388 PONRMgr.PonResourceRanges[ALLOC_ID_END_IDX].(uint32)); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000389 logger.Error(ctx, "Failed to init ALLOC ID resource pool ")
Scott Baker2c1c4822019-10-16 11:02:41 -0700390 return err
391 }
392 if SharedPoolID != 0 {
393 break
394 }
395 }
396 for _, Intf := range PONRMgr.IntfIDs {
397 SharedPoolID := PONRMgr.PonResourceRanges[GEMPORT_ID_SHARED_IDX].(uint32)
398 if SharedPoolID != 0 {
399 Intf = SharedPoolID
400 }
npujar5bf737f2020-01-16 19:35:25 +0530401 if err = PONRMgr.InitResourceIDPool(ctx, Intf, GEMPORT_ID,
Scott Baker2c1c4822019-10-16 11:02:41 -0700402 PONRMgr.PonResourceRanges[GEMPORT_ID_START_IDX].(uint32),
403 PONRMgr.PonResourceRanges[GEMPORT_ID_END_IDX].(uint32)); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000404 logger.Error(ctx, "Failed to init GEMPORT ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700405 return err
406 }
407 if SharedPoolID != 0 {
408 break
409 }
410 }
411
412 for _, Intf := range PONRMgr.IntfIDs {
413 SharedPoolID := PONRMgr.PonResourceRanges[FLOW_ID_SHARED_IDX].(uint32)
414 if SharedPoolID != 0 {
415 Intf = SharedPoolID
416 }
npujar5bf737f2020-01-16 19:35:25 +0530417 if err = PONRMgr.InitResourceIDPool(ctx, Intf, FLOW_ID,
Scott Baker2c1c4822019-10-16 11:02:41 -0700418 PONRMgr.PonResourceRanges[FLOW_ID_START_IDX].(uint32),
419 PONRMgr.PonResourceRanges[FLOW_ID_END_IDX].(uint32)); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000420 logger.Error(ctx, "Failed to init FLOW ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700421 return err
422 }
423 if SharedPoolID != 0 {
424 break
425 }
426 }
427 return err
428}
429
npujar5bf737f2020-01-16 19:35:25 +0530430func (PONRMgr *PONResourceManager) ClearDeviceResourcePool(ctx context.Context) error {
Scott Baker2c1c4822019-10-16 11:02:41 -0700431
432 //Clear resource pool for all PON ports.
433
Neha Sharma94f16a92020-06-26 04:17:55 +0000434 logger.Debug(ctx, "Clear resource ranges")
Scott Baker2c1c4822019-10-16 11:02:41 -0700435
436 for _, Intf := range PONRMgr.IntfIDs {
437 SharedPoolID := PONRMgr.PonResourceRanges[ONU_ID_SHARED_IDX].(uint32)
438 if SharedPoolID != 0 {
439 Intf = SharedPoolID
440 }
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800441 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, ONU_ID); !status {
Neha Sharma94f16a92020-06-26 04:17:55 +0000442 logger.Error(ctx, "Failed to clear ONU ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700443 return errors.New("Failed to clear ONU ID resource pool")
444 }
445 if SharedPoolID != 0 {
446 break
447 }
448 }
449
450 for _, Intf := range PONRMgr.IntfIDs {
451 SharedPoolID := PONRMgr.PonResourceRanges[ALLOC_ID_SHARED_IDX].(uint32)
452 if SharedPoolID != 0 {
453 Intf = SharedPoolID
454 }
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800455 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, ALLOC_ID); !status {
Neha Sharma94f16a92020-06-26 04:17:55 +0000456 logger.Error(ctx, "Failed to clear ALLOC ID resource pool ")
Scott Baker2c1c4822019-10-16 11:02:41 -0700457 return errors.New("Failed to clear ALLOC ID resource pool")
458 }
459 if SharedPoolID != 0 {
460 break
461 }
462 }
463 for _, Intf := range PONRMgr.IntfIDs {
464 SharedPoolID := PONRMgr.PonResourceRanges[GEMPORT_ID_SHARED_IDX].(uint32)
465 if SharedPoolID != 0 {
466 Intf = SharedPoolID
467 }
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800468 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, GEMPORT_ID); !status {
Neha Sharma94f16a92020-06-26 04:17:55 +0000469 logger.Error(ctx, "Failed to clear GEMPORT ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700470 return errors.New("Failed to clear GEMPORT ID resource pool")
471 }
472 if SharedPoolID != 0 {
473 break
474 }
475 }
476
477 for _, Intf := range PONRMgr.IntfIDs {
478 SharedPoolID := PONRMgr.PonResourceRanges[FLOW_ID_SHARED_IDX].(uint32)
479 if SharedPoolID != 0 {
480 Intf = SharedPoolID
481 }
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800482 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, FLOW_ID); !status {
Neha Sharma94f16a92020-06-26 04:17:55 +0000483 logger.Error(ctx, "Failed to clear FLOW ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700484 return errors.New("Failed to clear FLOW ID resource pool")
485 }
486 if SharedPoolID != 0 {
487 break
488 }
489 }
490 return nil
491}
492
npujar5bf737f2020-01-16 19:35:25 +0530493func (PONRMgr *PONResourceManager) InitResourceIDPool(ctx context.Context, Intf uint32, ResourceType string, StartID uint32, EndID uint32) error {
Scott Baker2c1c4822019-10-16 11:02:41 -0700494
495 /*Initialize Resource ID pool for a given Resource Type on a given PON Port
496
497 :param pon_intf_id: OLT PON interface id
498 :param resource_type: String to identify type of resource
499 :param start_idx: start index for onu id pool
500 :param end_idx: end index for onu id pool
501 :return boolean: True if resource id pool initialized else false
502 */
503
504 // delegate to the master instance if sharing enabled across instances
505 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
506 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujar5bf737f2020-01-16 19:35:25 +0530507 return SharedResourceMgr.InitResourceIDPool(ctx, Intf, ResourceType, StartID, EndID)
Scott Baker2c1c4822019-10-16 11:02:41 -0700508 }
509
Neha Sharma94f16a92020-06-26 04:17:55 +0000510 Path := PONRMgr.GetPath(ctx, Intf, ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700511 if Path == "" {
Neha Sharma94f16a92020-06-26 04:17:55 +0000512 logger.Errorf(ctx, "Failed to get path for resource type %s", ResourceType)
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800513 return fmt.Errorf("Failed to get path for resource type %s", ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700514 }
515
516 //In case of adapter reboot and reconciliation resource in kv store
517 //checked for its presence if not kv store update happens
npujar5bf737f2020-01-16 19:35:25 +0530518 Res, err := PONRMgr.GetResource(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700519 if (err == nil) && (Res != nil) {
Neha Sharma94f16a92020-06-26 04:17:55 +0000520 logger.Debugf(ctx, "Resource %s already present in store ", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700521 return nil
522 } else {
Esin Karaman5351fc52020-02-14 07:45:49 +0000523 var excluded []uint32
524 if ResourceType == GEMPORT_ID {
525 //get gem port ids defined in the KV store, if any, and exclude them from the gem port id pool
526 if reservedGemPortIds, defined := PONRMgr.getReservedGemPortIdsFromKVStore(ctx); defined {
527 excluded = reservedGemPortIds
Neha Sharma94f16a92020-06-26 04:17:55 +0000528 logger.Debugw(ctx, "Excluding some ports from GEM port id pool", log.Fields{"excluded gem ports": excluded})
Esin Karaman5351fc52020-02-14 07:45:49 +0000529 }
530 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000531 FormatResult, err := PONRMgr.FormatResource(ctx, Intf, StartID, EndID, excluded)
Scott Baker2c1c4822019-10-16 11:02:41 -0700532 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000533 logger.Errorf(ctx, "Failed to format resource")
Scott Baker2c1c4822019-10-16 11:02:41 -0700534 return err
535 }
536 // Add resource as json in kv store.
npujar5bf737f2020-01-16 19:35:25 +0530537 err = PONRMgr.KVStore.Put(ctx, Path, FormatResult)
Scott Baker2c1c4822019-10-16 11:02:41 -0700538 if err == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000539 logger.Debug(ctx, "Successfuly posted to kv store")
Scott Baker2c1c4822019-10-16 11:02:41 -0700540 return err
541 }
542 }
543
Neha Sharma94f16a92020-06-26 04:17:55 +0000544 logger.Debug(ctx, "Error initializing pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700545
546 return err
547}
548
Esin Karaman5351fc52020-02-14 07:45:49 +0000549func (PONRMgr *PONResourceManager) getReservedGemPortIdsFromKVStore(ctx context.Context) ([]uint32, bool) {
550 var reservedGemPortIds []uint32
551 // read reserved gem ports from the config path
552 KvPair, err := PONRMgr.KVStoreForConfig.Get(ctx, RESERVED_GEMPORT_IDS_PATH)
553 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000554 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 +0000555 return reservedGemPortIds, false
556 }
557 if KvPair == nil || KvPair.Value == nil {
558 //no reserved gem port defined in the store
559 return reservedGemPortIds, false
560 }
561 Val, err := kvstore.ToByte(KvPair.Value)
562 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000563 logger.Errorw(ctx, "Failed to convert reserved gem port ids into byte array", log.Fields{"err": err})
Esin Karaman5351fc52020-02-14 07:45:49 +0000564 return reservedGemPortIds, false
565 }
566 if err = json.Unmarshal(Val, &reservedGemPortIds); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000567 logger.Errorw(ctx, "Failed to unmarshal reservedGemPortIds", log.Fields{"err": err})
Esin Karaman5351fc52020-02-14 07:45:49 +0000568 return reservedGemPortIds, false
569 }
570 return reservedGemPortIds, true
571}
572
Neha Sharma94f16a92020-06-26 04:17:55 +0000573func (PONRMgr *PONResourceManager) FormatResource(ctx context.Context, IntfID uint32, StartIDx uint32, EndIDx uint32,
Esin Karaman5351fc52020-02-14 07:45:49 +0000574 Excluded []uint32) ([]byte, error) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700575 /*
576 Format resource as json.
577 :param pon_intf_id: OLT PON interface id
578 :param start_idx: start index for id pool
579 :param end_idx: end index for id pool
Esin Karaman5351fc52020-02-14 07:45:49 +0000580 :Id values to be Excluded from the pool
Scott Baker2c1c4822019-10-16 11:02:41 -0700581 :return dictionary: resource formatted as map
582 */
583 // Format resource as json to be stored in backend store
584 Resource := make(map[string]interface{})
585 Resource[PON_INTF_ID] = IntfID
586 Resource[START_IDX] = StartIDx
587 Resource[END_IDX] = EndIDx
588 /*
589 Resource pool stored in backend store as binary string.
590 Tracking the resource allocation will be done by setting the bits \
591 in the byte array. The index set will be the resource number allocated.
592 */
593 var TSData *bitmap.Threadsafe
594 if TSData = bitmap.NewTS(int(EndIDx)); TSData == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000595 logger.Error(ctx, "Failed to create a bitmap")
Scott Baker2c1c4822019-10-16 11:02:41 -0700596 return nil, errors.New("Failed to create bitmap")
597 }
Esin Karaman5351fc52020-02-14 07:45:49 +0000598 for _, excludedID := range Excluded {
599 if excludedID < StartIDx || excludedID > EndIDx {
Neha Sharma94f16a92020-06-26 04:17:55 +0000600 logger.Warnf(ctx, "Cannot reserve %d. It must be in the range of [%d, %d]", excludedID,
Esin Karaman5351fc52020-02-14 07:45:49 +0000601 StartIDx, EndIDx)
602 continue
603 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000604 PONRMgr.reserveID(ctx, TSData, StartIDx, excludedID)
Esin Karaman5351fc52020-02-14 07:45:49 +0000605 }
Scott Baker2c1c4822019-10-16 11:02:41 -0700606 Resource[POOL] = TSData.Data(false) //we pass false so as the TSData lib api does not do a copy of the data and return
607
608 Value, err := json.Marshal(Resource)
609 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000610 logger.Errorf(ctx, "Failed to marshall resource")
Scott Baker2c1c4822019-10-16 11:02:41 -0700611 return nil, err
612 }
613 return Value, err
614}
npujar5bf737f2020-01-16 19:35:25 +0530615func (PONRMgr *PONResourceManager) GetResource(ctx context.Context, Path string) (map[string]interface{}, error) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700616 /*
617 Get resource from kv store.
618
619 :param path: path to get resource
620 :return: resource if resource present in kv store else None
621 */
622 //get resource from kv store
623
624 var Value []byte
625 Result := make(map[string]interface{})
626 var Str string
627
npujar5bf737f2020-01-16 19:35:25 +0530628 Resource, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700629 if (err != nil) || (Resource == nil) {
Neha Sharma94f16a92020-06-26 04:17:55 +0000630 logger.Debugf(ctx, "Resource unavailable at %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700631 return nil, err
632 }
633
634 Value, err = ToByte(Resource.Value)
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800635 if err != nil {
636 return nil, err
637 }
Scott Baker2c1c4822019-10-16 11:02:41 -0700638
639 // decode resource fetched from backend store to dictionary
640 err = json.Unmarshal(Value, &Result)
641 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000642 logger.Error(ctx, "Failed to decode resource")
Scott Baker2c1c4822019-10-16 11:02:41 -0700643 return Result, err
644 }
645 /*
646 resource pool in backend store stored as binary string whereas to
647 access the pool to generate/release IDs it need to be converted
648 as BitArray
649 */
650 Str, err = ToString(Result[POOL])
651 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000652 logger.Error(ctx, "Failed to conver to kv pair to string")
Scott Baker2c1c4822019-10-16 11:02:41 -0700653 return Result, err
654 }
655 Decode64, _ := base64.StdEncoding.DecodeString(Str)
656 Result[POOL], err = ToByte(Decode64)
657 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000658 logger.Error(ctx, "Failed to convert resource pool to byte")
Scott Baker2c1c4822019-10-16 11:02:41 -0700659 return Result, err
660 }
661
662 return Result, err
663}
664
Neha Sharma94f16a92020-06-26 04:17:55 +0000665func (PONRMgr *PONResourceManager) GetPath(ctx context.Context, IntfID uint32, ResourceType string) string {
Scott Baker2c1c4822019-10-16 11:02:41 -0700666 /*
667 Get path for given resource type.
668 :param pon_intf_id: OLT PON interface id
669 :param resource_type: String to identify type of resource
670 :return: path for given resource type
671 */
672
673 /*
674 Get the shared pool for the given resource type.
675 all the resource ranges and the shared resource maps are initialized during the init.
676 */
677 SharedPoolID := PONRMgr.PonResourceRanges[PONRMgr.SharedIdxByType[ResourceType]].(uint32)
678 if SharedPoolID != 0 {
679 IntfID = SharedPoolID
680 }
681 var Path string
682 if ResourceType == ONU_ID {
683 Path = fmt.Sprintf(ONU_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
684 } else if ResourceType == ALLOC_ID {
685 Path = fmt.Sprintf(ALLOC_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
686 } else if ResourceType == GEMPORT_ID {
687 Path = fmt.Sprintf(GEMPORT_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
688 } else if ResourceType == FLOW_ID {
689 Path = fmt.Sprintf(FLOW_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
690 } else {
Neha Sharma94f16a92020-06-26 04:17:55 +0000691 logger.Error(ctx, "Invalid resource pool identifier")
Scott Baker2c1c4822019-10-16 11:02:41 -0700692 }
693 return Path
694}
695
npujar5bf737f2020-01-16 19:35:25 +0530696func (PONRMgr *PONResourceManager) GetResourceID(ctx context.Context, IntfID uint32, ResourceType string, NumIDs uint32) ([]uint32, error) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700697 /*
698 Create alloc/gemport/onu/flow id for given OLT PON interface.
699 :param pon_intf_id: OLT PON interface id
700 :param resource_type: String to identify type of resource
701 :param num_of_id: required number of ids
702 :return list/uint32/None: list, uint32 or None if resource type is
703 alloc_id/gemport_id, onu_id or invalid type respectively
704 */
705 if NumIDs < 1 {
Neha Sharma94f16a92020-06-26 04:17:55 +0000706 logger.Error(ctx, "Invalid number of resources requested")
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800707 return nil, fmt.Errorf("Invalid number of resources requested %d", NumIDs)
Scott Baker2c1c4822019-10-16 11:02:41 -0700708 }
709 // delegate to the master instance if sharing enabled across instances
710
711 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
712 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujar5bf737f2020-01-16 19:35:25 +0530713 return SharedResourceMgr.GetResourceID(ctx, IntfID, ResourceType, NumIDs)
Scott Baker2c1c4822019-10-16 11:02:41 -0700714 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000715 logger.Debugf(ctx, "Fetching resource from %s rsrc mgr for resource %s", PONRMgr.Globalorlocal, ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700716
Neha Sharma94f16a92020-06-26 04:17:55 +0000717 Path := PONRMgr.GetPath(ctx, IntfID, ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700718 if Path == "" {
Neha Sharma94f16a92020-06-26 04:17:55 +0000719 logger.Errorf(ctx, "Failed to get path for resource type %s", ResourceType)
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800720 return nil, fmt.Errorf("Failed to get path for resource type %s", ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700721 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000722 logger.Debugf(ctx, "Get resource for type %s on path %s", ResourceType, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700723 var Result []uint32
724 var NextID uint32
npujar5bf737f2020-01-16 19:35:25 +0530725 Resource, err := PONRMgr.GetResource(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700726 if (err == nil) && (ResourceType == ONU_ID) || (ResourceType == FLOW_ID) {
Neha Sharma94f16a92020-06-26 04:17:55 +0000727 if NextID, err = PONRMgr.GenerateNextID(ctx, Resource); err != nil {
728 logger.Error(ctx, "Failed to Generate ID")
Scott Baker2c1c4822019-10-16 11:02:41 -0700729 return Result, err
730 }
731 Result = append(Result, NextID)
732 } else if (err == nil) && ((ResourceType == GEMPORT_ID) || (ResourceType == ALLOC_ID)) {
733 if NumIDs == 1 {
Neha Sharma94f16a92020-06-26 04:17:55 +0000734 if NextID, err = PONRMgr.GenerateNextID(ctx, Resource); err != nil {
735 logger.Error(ctx, "Failed to Generate ID")
Scott Baker2c1c4822019-10-16 11:02:41 -0700736 return Result, err
737 }
738 Result = append(Result, NextID)
739 } else {
740 for NumIDs > 0 {
Neha Sharma94f16a92020-06-26 04:17:55 +0000741 if NextID, err = PONRMgr.GenerateNextID(ctx, Resource); err != nil {
742 logger.Error(ctx, "Failed to Generate ID")
Scott Baker2c1c4822019-10-16 11:02:41 -0700743 return Result, err
744 }
745 Result = append(Result, NextID)
746 NumIDs--
747 }
748 }
749 } else {
Neha Sharma94f16a92020-06-26 04:17:55 +0000750 logger.Error(ctx, "get resource failed")
Scott Baker2c1c4822019-10-16 11:02:41 -0700751 return Result, err
752 }
753
754 //Update resource in kv store
npujar5bf737f2020-01-16 19:35:25 +0530755 if PONRMgr.UpdateResource(ctx, Path, Resource) != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000756 logger.Errorf(ctx, "Failed to update resource %s", Path)
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800757 return nil, fmt.Errorf("Failed to update resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700758 }
759 return Result, nil
760}
761
762func checkValidResourceType(ResourceType string) bool {
763 KnownResourceTypes := []string{ONU_ID, ALLOC_ID, GEMPORT_ID, FLOW_ID}
764
765 for _, v := range KnownResourceTypes {
766 if v == ResourceType {
767 return true
768 }
769 }
770 return false
771}
772
npujar5bf737f2020-01-16 19:35:25 +0530773func (PONRMgr *PONResourceManager) FreeResourceID(ctx context.Context, IntfID uint32, ResourceType string, ReleaseContent []uint32) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -0700774 /*
775 Release alloc/gemport/onu/flow id for given OLT PON interface.
776 :param pon_intf_id: OLT PON interface id
777 :param resource_type: String to identify type of resource
778 :param release_content: required number of ids
779 :return boolean: True if all IDs in given release_content release else False
780 */
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800781 if !checkValidResourceType(ResourceType) {
Neha Sharma94f16a92020-06-26 04:17:55 +0000782 logger.Error(ctx, "Invalid resource type")
Scott Baker2c1c4822019-10-16 11:02:41 -0700783 return false
784 }
785 if ReleaseContent == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000786 logger.Debug(ctx, "Nothing to release")
Scott Baker2c1c4822019-10-16 11:02:41 -0700787 return true
788 }
789 // delegate to the master instance if sharing enabled across instances
790 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
791 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujar5bf737f2020-01-16 19:35:25 +0530792 return SharedResourceMgr.FreeResourceID(ctx, IntfID, ResourceType, ReleaseContent)
Scott Baker2c1c4822019-10-16 11:02:41 -0700793 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000794 Path := PONRMgr.GetPath(ctx, IntfID, ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700795 if Path == "" {
Neha Sharma94f16a92020-06-26 04:17:55 +0000796 logger.Error(ctx, "Failed to get path")
Scott Baker2c1c4822019-10-16 11:02:41 -0700797 return false
798 }
npujar5bf737f2020-01-16 19:35:25 +0530799 Resource, err := PONRMgr.GetResource(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700800 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000801 logger.Error(ctx, "Failed to get resource")
Scott Baker2c1c4822019-10-16 11:02:41 -0700802 return false
803 }
804 for _, Val := range ReleaseContent {
Neha Sharma94f16a92020-06-26 04:17:55 +0000805 PONRMgr.ReleaseID(ctx, Resource, Val)
Scott Baker2c1c4822019-10-16 11:02:41 -0700806 }
npujar5bf737f2020-01-16 19:35:25 +0530807 if PONRMgr.UpdateResource(ctx, Path, Resource) != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000808 logger.Errorf(ctx, "Free resource for %s failed", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700809 return false
810 }
811 return true
812}
813
npujar5bf737f2020-01-16 19:35:25 +0530814func (PONRMgr *PONResourceManager) UpdateResource(ctx context.Context, Path string, Resource map[string]interface{}) error {
Scott Baker2c1c4822019-10-16 11:02:41 -0700815 /*
816 Update resource in resource kv store.
817 :param path: path to update resource
818 :param resource: resource need to be updated
819 :return boolean: True if resource updated in kv store else False
820 */
821 // TODO resource[POOL] = resource[POOL].bin
822 Value, err := json.Marshal(Resource)
823 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000824 logger.Error(ctx, "failed to Marshal")
Scott Baker2c1c4822019-10-16 11:02:41 -0700825 return err
826 }
npujar5bf737f2020-01-16 19:35:25 +0530827 err = PONRMgr.KVStore.Put(ctx, Path, Value)
Scott Baker2c1c4822019-10-16 11:02:41 -0700828 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000829 logger.Error(ctx, "failed to put data to kv store %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700830 return err
831 }
832 return nil
833}
834
npujar5bf737f2020-01-16 19:35:25 +0530835func (PONRMgr *PONResourceManager) ClearResourceIDPool(ctx context.Context, contIntfID uint32, ResourceType string) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -0700836 /*
837 Clear Resource Pool for a given Resource Type on a given PON Port.
838 :return boolean: True if removed else False
839 */
840
841 // delegate to the master instance if sharing enabled across instances
842 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
843 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujar5bf737f2020-01-16 19:35:25 +0530844 return SharedResourceMgr.ClearResourceIDPool(ctx, contIntfID, ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700845 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000846 Path := PONRMgr.GetPath(ctx, contIntfID, ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700847 if Path == "" {
Neha Sharma94f16a92020-06-26 04:17:55 +0000848 logger.Error(ctx, "Failed to get path")
Scott Baker2c1c4822019-10-16 11:02:41 -0700849 return false
850 }
851
npujar5bf737f2020-01-16 19:35:25 +0530852 if err := PONRMgr.KVStore.Delete(ctx, Path); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000853 logger.Errorf(ctx, "Failed to delete resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700854 return false
855 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000856 logger.Debugf(ctx, "Cleared resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700857 return true
858}
859
npujar5bf737f2020-01-16 19:35:25 +0530860func (PONRMgr PONResourceManager) InitResourceMap(ctx context.Context, PONIntfONUID string) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700861 /*
862 Initialize resource map
863 :param pon_intf_onu_id: reference of PON interface id and onu id
864 */
865 // initialize pon_intf_onu_id tuple to alloc_ids map
866 AllocIDPath := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
867 var AllocIDs []byte
npujar5bf737f2020-01-16 19:35:25 +0530868 Result := PONRMgr.KVStore.Put(ctx, AllocIDPath, AllocIDs)
Scott Baker2c1c4822019-10-16 11:02:41 -0700869 if Result != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000870 logger.Error(ctx, "Failed to update the KV store")
Scott Baker2c1c4822019-10-16 11:02:41 -0700871 return
872 }
873 // initialize pon_intf_onu_id tuple to gemport_ids map
874 GEMPortIDPath := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
875 var GEMPortIDs []byte
npujar5bf737f2020-01-16 19:35:25 +0530876 Result = PONRMgr.KVStore.Put(ctx, GEMPortIDPath, GEMPortIDs)
Scott Baker2c1c4822019-10-16 11:02:41 -0700877 if Result != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000878 logger.Error(ctx, "Failed to update the KV store")
Scott Baker2c1c4822019-10-16 11:02:41 -0700879 return
880 }
881}
882
npujar5bf737f2020-01-16 19:35:25 +0530883func (PONRMgr PONResourceManager) RemoveResourceMap(ctx context.Context, PONIntfONUID string) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -0700884 /*
885 Remove resource map
886 :param pon_intf_onu_id: reference of PON interface id and onu id
887 */
888 // remove pon_intf_onu_id tuple to alloc_ids map
889 var err error
890 AllocIDPath := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujar5bf737f2020-01-16 19:35:25 +0530891 if err = PONRMgr.KVStore.Delete(ctx, AllocIDPath); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000892 logger.Errorf(ctx, "Failed to remove resource %s", AllocIDPath)
Scott Baker2c1c4822019-10-16 11:02:41 -0700893 return false
894 }
895 // remove pon_intf_onu_id tuple to gemport_ids map
896 GEMPortIDPath := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujar5bf737f2020-01-16 19:35:25 +0530897 err = PONRMgr.KVStore.Delete(ctx, GEMPortIDPath)
Scott Baker2c1c4822019-10-16 11:02:41 -0700898 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000899 logger.Errorf(ctx, "Failed to remove resource %s", GEMPortIDPath)
Scott Baker2c1c4822019-10-16 11:02:41 -0700900 return false
901 }
902
903 FlowIDPath := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujar5bf737f2020-01-16 19:35:25 +0530904 if FlowIDs, err := PONRMgr.KVStore.List(ctx, FlowIDPath); err != nil {
Scott Baker2c1c4822019-10-16 11:02:41 -0700905 for _, Flow := range FlowIDs {
906 FlowIDInfoPath := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, PONIntfONUID, Flow.Value)
npujar5bf737f2020-01-16 19:35:25 +0530907 if err = PONRMgr.KVStore.Delete(ctx, FlowIDInfoPath); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000908 logger.Errorf(ctx, "Failed to remove resource %s", FlowIDInfoPath)
Scott Baker2c1c4822019-10-16 11:02:41 -0700909 return false
910 }
911 }
912 }
913
npujar5bf737f2020-01-16 19:35:25 +0530914 if err = PONRMgr.KVStore.Delete(ctx, FlowIDPath); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000915 logger.Errorf(ctx, "Failed to remove resource %s", FlowIDPath)
Scott Baker2c1c4822019-10-16 11:02:41 -0700916 return false
917 }
918
919 return true
920}
921
npujar5bf737f2020-01-16 19:35:25 +0530922func (PONRMgr *PONResourceManager) GetCurrentAllocIDForOnu(ctx context.Context, IntfONUID string) []uint32 {
Scott Baker2c1c4822019-10-16 11:02:41 -0700923 /*
924 Get currently configured alloc ids for given pon_intf_onu_id
925 :param pon_intf_onu_id: reference of PON interface id and onu id
926 :return list: List of alloc_ids if available, else None
927 */
928 Path := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
929
930 var Data []uint32
npujar5bf737f2020-01-16 19:35:25 +0530931 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700932 if err == nil {
933 if Value != nil {
934 Val, err := ToByte(Value.Value)
935 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000936 logger.Errorw(ctx, "Failed to convert into byte array", log.Fields{"error": err})
Scott Baker2c1c4822019-10-16 11:02:41 -0700937 return Data
938 }
939 if err = json.Unmarshal(Val, &Data); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000940 logger.Error(ctx, "Failed to unmarshal", log.Fields{"error": err})
Scott Baker2c1c4822019-10-16 11:02:41 -0700941 return Data
942 }
943 }
944 }
945 return Data
946}
947
npujar5bf737f2020-01-16 19:35:25 +0530948func (PONRMgr *PONResourceManager) GetCurrentGEMPortIDsForOnu(ctx context.Context, IntfONUID string) []uint32 {
Scott Baker2c1c4822019-10-16 11:02:41 -0700949 /*
950 Get currently configured gemport ids for given pon_intf_onu_id
951 :param pon_intf_onu_id: reference of PON interface id and onu id
952 :return list: List of gemport IDs if available, else None
953 */
954
955 Path := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Neha Sharma94f16a92020-06-26 04:17:55 +0000956 logger.Debugf(ctx, "Getting current gemports for %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700957 var Data []uint32
npujar5bf737f2020-01-16 19:35:25 +0530958 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700959 if err == nil {
960 if Value != nil {
961 Val, _ := ToByte(Value.Value)
962 if err = json.Unmarshal(Val, &Data); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000963 logger.Errorw(ctx, "Failed to unmarshal", log.Fields{"error": err})
Scott Baker2c1c4822019-10-16 11:02:41 -0700964 return Data
965 }
966 }
967 } else {
Neha Sharma94f16a92020-06-26 04:17:55 +0000968 logger.Errorf(ctx, "Failed to get data from kvstore for %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700969 }
970 return Data
971}
972
npujar5bf737f2020-01-16 19:35:25 +0530973func (PONRMgr *PONResourceManager) GetCurrentFlowIDsForOnu(ctx context.Context, IntfONUID string) []uint32 {
Scott Baker2c1c4822019-10-16 11:02:41 -0700974 /*
975 Get currently configured flow ids for given pon_intf_onu_id
976 :param pon_intf_onu_id: reference of PON interface id and onu id
977 :return list: List of Flow IDs if available, else None
978 */
979
980 Path := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
981
982 var Data []uint32
npujar5bf737f2020-01-16 19:35:25 +0530983 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700984 if err == nil {
985 if Value != nil {
986 Val, _ := ToByte(Value.Value)
987 if err = json.Unmarshal(Val, &Data); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000988 logger.Error(ctx, "Failed to unmarshal")
Scott Baker2c1c4822019-10-16 11:02:41 -0700989 return Data
990 }
991 }
992 }
993 return Data
994}
995
npujar5bf737f2020-01-16 19:35:25 +0530996func (PONRMgr *PONResourceManager) GetFlowIDInfo(ctx context.Context, IntfONUID string, FlowID uint32, Data interface{}) error {
Scott Baker2c1c4822019-10-16 11:02:41 -0700997 /*
998 Get flow details configured for the ONU.
999 :param pon_intf_onu_id: reference of PON interface id and onu id
1000 :param flow_id: Flow Id reference
1001 :param Data: Result
1002 :return error: nil if no error in getting from KV store
1003 */
1004
1005 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
1006
npujar5bf737f2020-01-16 19:35:25 +05301007 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001008 if err == nil {
1009 if Value != nil {
1010 Val, err := ToByte(Value.Value)
1011 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001012 logger.Errorw(ctx, "Failed to convert flowinfo into byte array", log.Fields{"error": err})
Scott Baker2c1c4822019-10-16 11:02:41 -07001013 return err
1014 }
1015 if err = json.Unmarshal(Val, Data); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001016 logger.Errorw(ctx, "Failed to unmarshal", log.Fields{"error": err})
Scott Baker2c1c4822019-10-16 11:02:41 -07001017 return err
1018 }
1019 }
1020 }
1021 return err
1022}
1023
npujar5bf737f2020-01-16 19:35:25 +05301024func (PONRMgr *PONResourceManager) RemoveFlowIDInfo(ctx context.Context, IntfONUID string, FlowID uint32) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -07001025 /*
1026 Get flow_id details configured for the ONU.
1027 :param pon_intf_onu_id: reference of PON interface id and onu id
1028 :param flow_id: Flow Id reference
1029 */
1030 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
1031
npujar5bf737f2020-01-16 19:35:25 +05301032 if err := PONRMgr.KVStore.Delete(ctx, Path); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001033 logger.Errorf(ctx, "Falied to remove resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001034 return false
1035 }
1036 return true
1037}
1038
npujar5bf737f2020-01-16 19:35:25 +05301039func (PONRMgr *PONResourceManager) UpdateAllocIdsForOnu(ctx context.Context, IntfONUID string, AllocIDs []uint32) error {
Scott Baker2c1c4822019-10-16 11:02:41 -07001040 /*
1041 Update currently configured alloc ids for given pon_intf_onu_id
1042 :param pon_intf_onu_id: reference of PON interface id and onu id
1043 :param alloc_ids: list of alloc ids
1044 */
1045 var Value []byte
1046 var err error
1047 Path := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
1048 Value, err = json.Marshal(AllocIDs)
1049 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001050 logger.Error(ctx, "failed to Marshal")
Scott Baker2c1c4822019-10-16 11:02:41 -07001051 return err
1052 }
1053
npujar5bf737f2020-01-16 19:35:25 +05301054 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001055 logger.Errorf(ctx, "Failed to update resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001056 return err
1057 }
1058 return err
1059}
1060
npujar5bf737f2020-01-16 19:35:25 +05301061func (PONRMgr *PONResourceManager) UpdateGEMPortIDsForOnu(ctx context.Context, IntfONUID string, GEMPortIDs []uint32) error {
Scott Baker2c1c4822019-10-16 11:02:41 -07001062 /*
1063 Update currently configured gemport ids for given pon_intf_onu_id
1064 :param pon_intf_onu_id: reference of PON interface id and onu id
1065 :param gemport_ids: list of gem port ids
1066 */
1067
1068 var Value []byte
1069 var err error
1070 Path := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Neha Sharma94f16a92020-06-26 04:17:55 +00001071 logger.Debugf(ctx, "Updating gemport ids for %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001072 Value, err = json.Marshal(GEMPortIDs)
1073 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001074 logger.Error(ctx, "failed to Marshal")
Scott Baker2c1c4822019-10-16 11:02:41 -07001075 return err
1076 }
1077
npujar5bf737f2020-01-16 19:35:25 +05301078 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001079 logger.Errorf(ctx, "Failed to update resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001080 return err
1081 }
1082 return err
1083}
1084
1085func checkForFlowIDInList(FlowIDList []uint32, FlowID uint32) (bool, uint32) {
1086 /*
1087 Check for a flow id in a given list of flow IDs.
1088 :param FLowIDList: List of Flow IDs
1089 :param FlowID: Flowd to check in the list
1090 : return true and the index if present false otherwise.
1091 */
1092
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001093 for idx := range FlowIDList {
Scott Baker2c1c4822019-10-16 11:02:41 -07001094 if FlowID == FlowIDList[idx] {
1095 return true, uint32(idx)
1096 }
1097 }
1098 return false, 0
1099}
1100
npujar5bf737f2020-01-16 19:35:25 +05301101func (PONRMgr *PONResourceManager) UpdateFlowIDForOnu(ctx context.Context, IntfONUID string, FlowID uint32, Add bool) error {
Scott Baker2c1c4822019-10-16 11:02:41 -07001102 /*
1103 Update the flow_id list of the ONU (add or remove flow_id from the list)
1104 :param pon_intf_onu_id: reference of PON interface id and onu id
1105 :param flow_id: flow ID
1106 :param add: Boolean flag to indicate whether the flow_id should be
1107 added or removed from the list. Defaults to adding the flow.
1108 */
1109 var Value []byte
1110 var err error
1111 var RetVal bool
1112 var IDx uint32
1113 Path := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
npujar5bf737f2020-01-16 19:35:25 +05301114 FlowIDs := PONRMgr.GetCurrentFlowIDsForOnu(ctx, IntfONUID)
Scott Baker2c1c4822019-10-16 11:02:41 -07001115
1116 if Add {
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001117 if RetVal, _ = checkForFlowIDInList(FlowIDs, FlowID); RetVal {
1118 return nil
Scott Baker2c1c4822019-10-16 11:02:41 -07001119 }
1120 FlowIDs = append(FlowIDs, FlowID)
1121 } else {
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001122 if RetVal, IDx = checkForFlowIDInList(FlowIDs, FlowID); !RetVal {
1123 return nil
Scott Baker2c1c4822019-10-16 11:02:41 -07001124 }
1125 // delete the index and shift
1126 FlowIDs = append(FlowIDs[:IDx], FlowIDs[IDx+1:]...)
1127 }
1128 Value, err = json.Marshal(FlowIDs)
1129 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001130 logger.Error(ctx, "Failed to Marshal")
Scott Baker2c1c4822019-10-16 11:02:41 -07001131 return err
1132 }
1133
npujar5bf737f2020-01-16 19:35:25 +05301134 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001135 logger.Errorf(ctx, "Failed to update resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001136 return err
1137 }
1138 return err
1139}
1140
npujar5bf737f2020-01-16 19:35:25 +05301141func (PONRMgr *PONResourceManager) UpdateFlowIDInfoForOnu(ctx context.Context, IntfONUID string, FlowID uint32, FlowData interface{}) error {
Scott Baker2c1c4822019-10-16 11:02:41 -07001142 /*
1143 Update any metadata associated with the flow_id. The flow_data could be json
1144 or any of other data structure. The resource manager doesnt care
1145 :param pon_intf_onu_id: reference of PON interface id and onu id
1146 :param flow_id: Flow ID
1147 :param flow_data: Flow data blob
1148 */
1149 var Value []byte
1150 var err error
1151 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
1152 Value, err = json.Marshal(FlowData)
1153 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001154 logger.Error(ctx, "failed to Marshal")
Scott Baker2c1c4822019-10-16 11:02:41 -07001155 return err
1156 }
1157
npujar5bf737f2020-01-16 19:35:25 +05301158 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001159 logger.Errorf(ctx, "Failed to update resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001160 return err
1161 }
1162 return err
1163}
1164
Neha Sharma94f16a92020-06-26 04:17:55 +00001165func (PONRMgr *PONResourceManager) GenerateNextID(ctx context.Context, Resource map[string]interface{}) (uint32, error) {
Scott Baker2c1c4822019-10-16 11:02:41 -07001166 /*
1167 Generate unique id having OFFSET as start
1168 :param resource: resource used to generate ID
1169 :return uint32: generated id
1170 */
1171 ByteArray, err := ToByte(Resource[POOL])
1172 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001173 logger.Error(ctx, "Failed to convert resource to byte array")
Scott Baker2c1c4822019-10-16 11:02:41 -07001174 return 0, err
1175 }
1176 Data := bitmap.TSFromData(ByteArray, false)
1177 if Data == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001178 logger.Error(ctx, "Failed to get data from byte array")
Scott Baker2c1c4822019-10-16 11:02:41 -07001179 return 0, errors.New("Failed to get data from byte array")
1180 }
1181
1182 Len := Data.Len()
1183 var Idx int
1184 for Idx = 0; Idx < Len; Idx++ {
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001185 if !Data.Get(Idx) {
Scott Baker2c1c4822019-10-16 11:02:41 -07001186 break
1187 }
1188 }
1189 Data.Set(Idx, true)
1190 res := uint32(Resource[START_IDX].(float64))
1191 Resource[POOL] = Data.Data(false)
Neha Sharma94f16a92020-06-26 04:17:55 +00001192 logger.Debugf(ctx, "Generated ID for %d", (uint32(Idx) + res))
Scott Baker2c1c4822019-10-16 11:02:41 -07001193 return (uint32(Idx) + res), err
1194}
1195
Neha Sharma94f16a92020-06-26 04:17:55 +00001196func (PONRMgr *PONResourceManager) ReleaseID(ctx context.Context, Resource map[string]interface{}, Id uint32) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -07001197 /*
1198 Release unique id having OFFSET as start index.
1199 :param resource: resource used to release ID
1200 :param unique_id: id need to be released
1201 */
1202 ByteArray, err := ToByte(Resource[POOL])
1203 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001204 logger.Error(ctx, "Failed to convert resource to byte array")
Scott Baker2c1c4822019-10-16 11:02:41 -07001205 return false
1206 }
1207 Data := bitmap.TSFromData(ByteArray, false)
1208 if Data == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001209 logger.Error(ctx, "Failed to get resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -07001210 return false
1211 }
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001212 Idx := Id - uint32(Resource[START_IDX].(float64))
Scott Baker2c1c4822019-10-16 11:02:41 -07001213 Data.Set(int(Idx), false)
1214 Resource[POOL] = Data.Data(false)
1215
1216 return true
1217}
1218
Esin Karaman5351fc52020-02-14 07:45:49 +00001219/* Reserves a unique id in the specified resource pool.
1220:param Resource: resource used to reserve ID
1221:param Id: ID to be reserved
1222*/
Neha Sharma94f16a92020-06-26 04:17:55 +00001223func (PONRMgr *PONResourceManager) reserveID(ctx context.Context, TSData *bitmap.Threadsafe, StartIndex uint32, Id uint32) bool {
Esin Karaman5351fc52020-02-14 07:45:49 +00001224 Data := bitmap.TSFromData(TSData.Data(false), false)
1225 if Data == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001226 logger.Error(ctx, "Failed to get resource pool")
Esin Karaman5351fc52020-02-14 07:45:49 +00001227 return false
1228 }
1229 Idx := Id - StartIndex
1230 Data.Set(int(Idx), true)
1231 return true
1232}
1233
Scott Baker2c1c4822019-10-16 11:02:41 -07001234func (PONRMgr *PONResourceManager) GetTechnology() string {
1235 return PONRMgr.Technology
1236}
1237
1238func (PONRMgr *PONResourceManager) GetResourceTypeAllocID() string {
1239 return ALLOC_ID
1240}
1241
1242func (PONRMgr *PONResourceManager) GetResourceTypeGemPortID() string {
1243 return GEMPORT_ID
1244}
1245
1246// ToByte converts an interface value to a []byte. The interface should either be of
1247// a string type or []byte. Otherwise, an error is returned.
1248func ToByte(value interface{}) ([]byte, error) {
1249 switch t := value.(type) {
1250 case []byte:
1251 return value.([]byte), nil
1252 case string:
1253 return []byte(value.(string)), nil
1254 default:
1255 return nil, fmt.Errorf("unexpected-type-%T", t)
1256 }
1257}
1258
1259// ToString converts an interface value to a string. The interface should either be of
1260// a string type or []byte. Otherwise, an error is returned.
1261func ToString(value interface{}) (string, error) {
1262 switch t := value.(type) {
1263 case []byte:
1264 return string(value.([]byte)), nil
1265 case string:
1266 return value.(string), nil
1267 default:
1268 return "", fmt.Errorf("unexpected-type-%T", t)
1269 }
1270}
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301271
npujar5bf737f2020-01-16 19:35:25 +05301272func (PONRMgr *PONResourceManager) AddOnuGemInfo(ctx context.Context, intfID uint32, onuGemData interface{}) error {
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301273 /*
1274 Update onugem info map,
1275 :param pon_intf_id: reference of PON interface id
1276 :param onuegmdata: onugem info map
1277 */
1278 var Value []byte
1279 var err error
1280 Path := fmt.Sprintf(ONU_GEM_INFO_PATH, PONRMgr.DeviceID, intfID)
1281 Value, err = json.Marshal(onuGemData)
1282 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001283 logger.Error(ctx, "failed to Marshal")
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301284 return err
1285 }
1286
npujar5bf737f2020-01-16 19:35:25 +05301287 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001288 logger.Errorf(ctx, "Failed to update resource %s", Path)
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301289 return err
1290 }
1291 return err
1292}
1293
npujar5bf737f2020-01-16 19:35:25 +05301294func (PONRMgr *PONResourceManager) GetOnuGemInfo(ctx context.Context, IntfId uint32, onuGemInfo interface{}) error {
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301295 /*
1296 Get onugeminfo map from kvstore
1297 :param intfid: refremce pon intfid
1298 :param onuGemInfo: onugem info to return from kv strore.
1299 */
1300 var Val []byte
1301
1302 path := fmt.Sprintf(ONU_GEM_INFO_PATH, PONRMgr.DeviceID, IntfId)
npujar5bf737f2020-01-16 19:35:25 +05301303 value, err := PONRMgr.KVStore.Get(ctx, path)
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301304 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001305 logger.Errorw(ctx, "Failed to get from kv store", log.Fields{"path": path})
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301306 return err
1307 } else if value == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001308 logger.Debug(ctx, "No onuinfo for path", log.Fields{"path": path})
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301309 return nil // returning nil as this could happen if there are no onus for the interface yet
1310 }
1311 if Val, err = kvstore.ToByte(value.Value); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001312 logger.Error(ctx, "Failed to convert to byte array")
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301313 return err
1314 }
1315
1316 if err = json.Unmarshal(Val, &onuGemInfo); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001317 logger.Error(ctx, "Failed to unmarshall")
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301318 return err
1319 }
Neha Sharma94f16a92020-06-26 04:17:55 +00001320 logger.Debugw(ctx, "found onuinfo from path", log.Fields{"path": path, "onuinfo": onuGemInfo})
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301321 return err
1322}
1323
npujar5bf737f2020-01-16 19:35:25 +05301324func (PONRMgr *PONResourceManager) DelOnuGemInfoForIntf(ctx context.Context, intfId uint32) error {
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301325 /*
1326 delete onugem info for an interface from kvstore
1327 :param intfid: refremce pon intfid
1328 */
1329
1330 path := fmt.Sprintf(ONU_GEM_INFO_PATH, PONRMgr.DeviceID, intfId)
npujar5bf737f2020-01-16 19:35:25 +05301331 if err := PONRMgr.KVStore.Delete(ctx, path); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001332 logger.Errorf(ctx, "Falied to remove resource %s", path)
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301333 return err
1334 }
1335 return nil
1336}