blob: 4cccb845116bfcb3a0e4e93d8e848a4706a46700 [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"
25 "strconv"
Neha Sharma130ac6d2020-04-08 08:46:32 +000026 "time"
Scott Baker2c1c4822019-10-16 11:02:41 -070027
serkant.uluderyab38671c2019-11-01 09:35:38 -070028 bitmap "github.com/boljen/go-bitmap"
29 "github.com/opencord/voltha-lib-go/v3/pkg/db"
30 "github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore"
31 "github.com/opencord/voltha-lib-go/v3/pkg/log"
32 tp "github.com/opencord/voltha-lib-go/v3/pkg/techprofile"
Scott Baker2c1c4822019-10-16 11:02:41 -070033)
34
35const (
36 //Constants to identify resource pool
37 UNI_ID = "UNI_ID"
38 ONU_ID = "ONU_ID"
39 ALLOC_ID = "ALLOC_ID"
40 GEMPORT_ID = "GEMPORT_ID"
41 FLOW_ID = "FLOW_ID"
42
43 //Constants for passing command line arugments
44 OLT_MODEL_ARG = "--olt_model"
45 PATH_PREFIX = "service/voltha/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 */
55 PATH_PREFIX_FOR_CONFIG = "service/voltha/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
114 //Format: <device_id>/<(pon_intf_id, onu_id)>/flow_id_info/<flow_id>
115 FLOW_ID_INFO_PATH = "{%s}/{%s}/flow_id_info/{%d}"
116
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +0530117 //path on the kvstore to store onugem info map
118 //format: <device-id>/onu_gem_info/<intfid>
119 ONU_GEM_INFO_PATH = "{%s}/onu_gem_info/{%d}" // onu_gem/<(intfid)>
120
Scott Baker2c1c4822019-10-16 11:02:41 -0700121 //Constants for internal usage.
122 PON_INTF_ID = "pon_intf_id"
123 START_IDX = "start_idx"
124 END_IDX = "end_idx"
125 POOL = "pool"
126 NUM_OF_PON_INTF = 16
127
Neha Sharma130ac6d2020-04-08 08:46:32 +0000128 KVSTORE_RETRY_TIMEOUT = 5 * time.Second
Esin Karaman5351fc52020-02-14 07:45:49 +0000129 //Path on the KV store for storing reserved gem ports
130 //Format: reserved_gemport_ids
131 RESERVED_GEMPORT_IDS_PATH = "reserved_gemport_ids"
Scott Baker2c1c4822019-10-16 11:02:41 -0700132)
133
134//type ResourceTypeIndex string
135//type ResourceType string
136
137type PONResourceManager struct {
138 //Implements APIs to initialize/allocate/release alloc/gemport/onu IDs.
Esin Karaman5351fc52020-02-14 07:45:49 +0000139 Technology string
140 DeviceType string
141 DeviceID string
142 Backend string // ETCD, or consul
143 Host string // host ip of the KV store
144 Port int // port number for the KV store
145 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 Sharma130ac6d2020-04-08 08:46:32 +0000159func newKVClient(storeType string, address string, timeout time.Duration) (kvstore.Client, error) {
Girish Kumare6f45e82020-03-20 10:46:54 +0000160 logger.Infow("kv-store-type", log.Fields{"store": storeType})
Scott Baker2c1c4822019-10-16 11:02:41 -0700161 switch storeType {
162 case "consul":
163 return kvstore.NewConsulClient(address, timeout)
164 case "etcd":
Rohan Agrawalee87e642020-04-14 10:22:18 +0000165 return kvstore.NewEtcdClient(address, timeout, log.WarnLevel)
Scott Baker2c1c4822019-10-16 11:02:41 -0700166 }
167 return nil, errors.New("unsupported-kv-store")
168}
169
Esin Karaman5351fc52020-02-14 07:45:49 +0000170func SetKVClient(Technology string, Backend string, Host string, Port int, configClient bool) *db.Backend {
Scott Baker2c1c4822019-10-16 11:02:41 -0700171 addr := Host + ":" + strconv.Itoa(Port)
172 // TODO : Make sure direct call to NewBackend is working fine with backend , currently there is some
173 // issue between kv store and backend , core is not calling NewBackend directly
174 kvClient, err := newKVClient(Backend, addr, KVSTORE_RETRY_TIMEOUT)
175 if err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000176 logger.Fatalw("Failed to init KV client\n", log.Fields{"err": err})
Scott Baker2c1c4822019-10-16 11:02:41 -0700177 return nil
178 }
Esin Karaman5351fc52020-02-14 07:45:49 +0000179
180 var pathPrefix string
181 if configClient {
182 pathPrefix = PATH_PREFIX_FOR_CONFIG
183 } else {
184 pathPrefix = fmt.Sprintf(PATH_PREFIX, Technology)
185 }
186
sbarbari1e3e29c2019-11-05 10:06:50 -0500187 kvbackend := &db.Backend{
Scott Baker2c1c4822019-10-16 11:02:41 -0700188 Client: kvClient,
189 StoreType: Backend,
190 Host: Host,
191 Port: Port,
192 Timeout: KVSTORE_RETRY_TIMEOUT,
Esin Karaman5351fc52020-02-14 07:45:49 +0000193 PathPrefix: pathPrefix}
Scott Baker2c1c4822019-10-16 11:02:41 -0700194
195 return kvbackend
196}
197
198// NewPONResourceManager creates a new PON resource manager.
199func NewPONResourceManager(Technology string, DeviceType string, DeviceID string, Backend string, Host string, Port int) (*PONResourceManager, error) {
200 var PONMgr PONResourceManager
201 PONMgr.Technology = Technology
202 PONMgr.DeviceType = DeviceType
203 PONMgr.DeviceID = DeviceID
204 PONMgr.Backend = Backend
205 PONMgr.Host = Host
206 PONMgr.Port = Port
Esin Karaman5351fc52020-02-14 07:45:49 +0000207 PONMgr.KVStore = SetKVClient(Technology, Backend, Host, Port, false)
Scott Baker2c1c4822019-10-16 11:02:41 -0700208 if PONMgr.KVStore == nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000209 logger.Error("KV Client initilization failed")
Scott Baker2c1c4822019-10-16 11:02:41 -0700210 return nil, errors.New("Failed to init KV client")
211 }
Esin Karaman5351fc52020-02-14 07:45:49 +0000212 // init kv client to read from the config path
213 PONMgr.KVStoreForConfig = SetKVClient(Technology, Backend, Host, Port, true)
214 if PONMgr.KVStoreForConfig == nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000215 logger.Error("KV Config Client initilization failed")
Esin Karaman5351fc52020-02-14 07:45:49 +0000216 return nil, errors.New("Failed to init KV Config client")
217 }
Scott Baker2c1c4822019-10-16 11:02:41 -0700218 // Initialize techprofile for this technology
219 if PONMgr.TechProfileMgr, _ = tp.NewTechProfile(&PONMgr, Backend, Host, Port); PONMgr.TechProfileMgr == nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000220 logger.Error("Techprofile initialization failed")
Scott Baker2c1c4822019-10-16 11:02:41 -0700221 return nil, errors.New("Failed to init tech profile")
222 }
223 PONMgr.PonResourceRanges = make(map[string]interface{})
224 PONMgr.SharedResourceMgrs = make(map[string]*PONResourceManager)
225 PONMgr.SharedIdxByType = make(map[string]string)
226 PONMgr.SharedIdxByType[ONU_ID] = ONU_ID_SHARED_IDX
227 PONMgr.SharedIdxByType[ALLOC_ID] = ALLOC_ID_SHARED_IDX
228 PONMgr.SharedIdxByType[GEMPORT_ID] = GEMPORT_ID_SHARED_IDX
229 PONMgr.SharedIdxByType[FLOW_ID] = FLOW_ID_SHARED_IDX
230 PONMgr.IntfIDs = make([]uint32, NUM_OF_PON_INTF)
231 PONMgr.OLTModel = DeviceType
232 return &PONMgr, nil
233}
234
235/*
236 Initialize PON resource ranges with config fetched from kv store.
237 return boolean: True if PON resource ranges initialized else false
238 Try to initialize the PON Resource Ranges from KV store based on the
239 OLT model key, if available
240*/
241
npujar5bf737f2020-01-16 19:35:25 +0530242func (PONRMgr *PONResourceManager) InitResourceRangesFromKVStore(ctx context.Context) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -0700243 //Initialize PON resource ranges with config fetched from kv store.
244 //:return boolean: True if PON resource ranges initialized else false
245 // Try to initialize the PON Resource Ranges from KV store based on the
246 // OLT model key, if available
247 if PONRMgr.OLTModel == "" {
Girish Kumare6f45e82020-03-20 10:46:54 +0000248 logger.Error("Failed to get OLT model")
Scott Baker2c1c4822019-10-16 11:02:41 -0700249 return false
250 }
251 Path := fmt.Sprintf(PON_RESOURCE_RANGE_CONFIG_PATH, PONRMgr.OLTModel)
252 //get resource from kv store
npujar5bf737f2020-01-16 19:35:25 +0530253 Result, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700254 if err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000255 logger.Debugf("Error in fetching resource %s from KV strore", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700256 return false
257 }
258 if Result == nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000259 logger.Debug("There may be no resources in the KV store in case of fresh bootup, return true")
Scott Baker2c1c4822019-10-16 11:02:41 -0700260 return false
261 }
262 //update internal ranges from kv ranges. If there are missing
263 // values in the KV profile, continue to use the defaults
264 Value, err := ToByte(Result.Value)
265 if err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000266 logger.Error("Failed to convert kvpair to byte string")
Scott Baker2c1c4822019-10-16 11:02:41 -0700267 return false
268 }
269 if err := json.Unmarshal(Value, &PONRMgr.PonResourceRanges); err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000270 logger.Error("Failed to Unmarshal json byte")
Scott Baker2c1c4822019-10-16 11:02:41 -0700271 return false
272 }
Girish Kumare6f45e82020-03-20 10:46:54 +0000273 logger.Debug("Init resource ranges from kvstore success")
Scott Baker2c1c4822019-10-16 11:02:41 -0700274 return true
275}
276
277func (PONRMgr *PONResourceManager) UpdateRanges(StartIDx string, StartID uint32, EndIDx string, EndID uint32,
278 SharedIDx string, SharedPoolID uint32, RMgr *PONResourceManager) {
279 /*
280 Update the ranges for all reosurce type in the intermnal maps
281 param: resource type start index
282 param: start ID
283 param: resource type end index
284 param: end ID
285 param: resource type shared index
286 param: shared pool id
287 param: global resource manager
288 */
Girish Kumare6f45e82020-03-20 10:46:54 +0000289 logger.Debugf("update ranges for %s, %d", StartIDx, StartID)
Scott Baker2c1c4822019-10-16 11:02:41 -0700290
291 if StartID != 0 {
292 if (PONRMgr.PonResourceRanges[StartIDx] == nil) || (PONRMgr.PonResourceRanges[StartIDx].(uint32) < StartID) {
293 PONRMgr.PonResourceRanges[StartIDx] = StartID
294 }
295 }
296 if EndID != 0 {
297 if (PONRMgr.PonResourceRanges[EndIDx] == nil) || (PONRMgr.PonResourceRanges[EndIDx].(uint32) > EndID) {
298 PONRMgr.PonResourceRanges[EndIDx] = EndID
299 }
300 }
301 //if SharedPoolID != 0 {
302 PONRMgr.PonResourceRanges[SharedIDx] = SharedPoolID
303 //}
304 if RMgr != nil {
305 PONRMgr.SharedResourceMgrs[SharedIDx] = RMgr
306 }
307}
308
309func (PONRMgr *PONResourceManager) InitDefaultPONResourceRanges(ONUIDStart uint32,
310 ONUIDEnd uint32,
311 ONUIDSharedPoolID uint32,
312 AllocIDStart uint32,
313 AllocIDEnd uint32,
314 AllocIDSharedPoolID uint32,
315 GEMPortIDStart uint32,
316 GEMPortIDEnd uint32,
317 GEMPortIDSharedPoolID uint32,
318 FlowIDStart uint32,
319 FlowIDEnd uint32,
320 FlowIDSharedPoolID uint32,
321 UNIIDStart uint32,
322 UNIIDEnd uint32,
323 NoOfPONPorts uint32,
324 IntfIDs []uint32) bool {
325
326 /*Initialize default PON resource ranges
327
328 :param onu_id_start_idx: onu id start index
329 :param onu_id_end_idx: onu id end index
330 :param onu_id_shared_pool_id: pool idx for id shared by all intfs or None for no sharing
331 :param alloc_id_start_idx: alloc id start index
332 :param alloc_id_end_idx: alloc id end index
333 :param alloc_id_shared_pool_id: pool idx for alloc id shared by all intfs or None for no sharing
334 :param gemport_id_start_idx: gemport id start index
335 :param gemport_id_end_idx: gemport id end index
336 :param gemport_id_shared_pool_id: pool idx for gemport id shared by all intfs or None for no sharing
337 :param flow_id_start_idx: flow id start index
338 :param flow_id_end_idx: flow id end index
339 :param flow_id_shared_pool_id: pool idx for flow id shared by all intfs or None for no sharing
340 :param num_of_pon_ports: number of PON ports
341 :param intf_ids: interfaces serviced by this manager
342 */
343 PONRMgr.UpdateRanges(ONU_ID_START_IDX, ONUIDStart, ONU_ID_END_IDX, ONUIDEnd, ONU_ID_SHARED_IDX, ONUIDSharedPoolID, nil)
344 PONRMgr.UpdateRanges(ALLOC_ID_START_IDX, AllocIDStart, ALLOC_ID_END_IDX, AllocIDEnd, ALLOC_ID_SHARED_IDX, AllocIDSharedPoolID, nil)
345 PONRMgr.UpdateRanges(GEMPORT_ID_START_IDX, GEMPortIDStart, GEMPORT_ID_END_IDX, GEMPortIDEnd, GEMPORT_ID_SHARED_IDX, GEMPortIDSharedPoolID, nil)
346 PONRMgr.UpdateRanges(FLOW_ID_START_IDX, FlowIDStart, FLOW_ID_END_IDX, FlowIDEnd, FLOW_ID_SHARED_IDX, FlowIDSharedPoolID, nil)
347 PONRMgr.UpdateRanges(UNI_ID_START_IDX, UNIIDStart, UNI_ID_END_IDX, UNIIDEnd, "", 0, nil)
Girish Kumare6f45e82020-03-20 10:46:54 +0000348 logger.Debug("Initialize default range values")
Scott Baker2c1c4822019-10-16 11:02:41 -0700349 var i uint32
350 if IntfIDs == nil {
351 for i = 0; i < NoOfPONPorts; i++ {
352 PONRMgr.IntfIDs = append(PONRMgr.IntfIDs, i)
353 }
354 } else {
355 PONRMgr.IntfIDs = IntfIDs
356 }
357 return true
358}
359
npujar5bf737f2020-01-16 19:35:25 +0530360func (PONRMgr *PONResourceManager) InitDeviceResourcePool(ctx context.Context) error {
Scott Baker2c1c4822019-10-16 11:02:41 -0700361
362 //Initialize resource pool for all PON ports.
363
Girish Kumare6f45e82020-03-20 10:46:54 +0000364 logger.Debug("Init resource ranges")
Scott Baker2c1c4822019-10-16 11:02:41 -0700365
366 var err error
367 for _, Intf := range PONRMgr.IntfIDs {
368 SharedPoolID := PONRMgr.PonResourceRanges[ONU_ID_SHARED_IDX].(uint32)
369 if SharedPoolID != 0 {
370 Intf = SharedPoolID
371 }
npujar5bf737f2020-01-16 19:35:25 +0530372 if err = PONRMgr.InitResourceIDPool(ctx, Intf, ONU_ID,
Scott Baker2c1c4822019-10-16 11:02:41 -0700373 PONRMgr.PonResourceRanges[ONU_ID_START_IDX].(uint32),
374 PONRMgr.PonResourceRanges[ONU_ID_END_IDX].(uint32)); err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000375 logger.Error("Failed to init ONU ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700376 return err
377 }
378 if SharedPoolID != 0 {
379 break
380 }
381 }
382
383 for _, Intf := range PONRMgr.IntfIDs {
384 SharedPoolID := PONRMgr.PonResourceRanges[ALLOC_ID_SHARED_IDX].(uint32)
385 if SharedPoolID != 0 {
386 Intf = SharedPoolID
387 }
npujar5bf737f2020-01-16 19:35:25 +0530388 if err = PONRMgr.InitResourceIDPool(ctx, Intf, ALLOC_ID,
Scott Baker2c1c4822019-10-16 11:02:41 -0700389 PONRMgr.PonResourceRanges[ALLOC_ID_START_IDX].(uint32),
390 PONRMgr.PonResourceRanges[ALLOC_ID_END_IDX].(uint32)); err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000391 logger.Error("Failed to init ALLOC ID resource pool ")
Scott Baker2c1c4822019-10-16 11:02:41 -0700392 return err
393 }
394 if SharedPoolID != 0 {
395 break
396 }
397 }
398 for _, Intf := range PONRMgr.IntfIDs {
399 SharedPoolID := PONRMgr.PonResourceRanges[GEMPORT_ID_SHARED_IDX].(uint32)
400 if SharedPoolID != 0 {
401 Intf = SharedPoolID
402 }
npujar5bf737f2020-01-16 19:35:25 +0530403 if err = PONRMgr.InitResourceIDPool(ctx, Intf, GEMPORT_ID,
Scott Baker2c1c4822019-10-16 11:02:41 -0700404 PONRMgr.PonResourceRanges[GEMPORT_ID_START_IDX].(uint32),
405 PONRMgr.PonResourceRanges[GEMPORT_ID_END_IDX].(uint32)); err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000406 logger.Error("Failed to init GEMPORT ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700407 return err
408 }
409 if SharedPoolID != 0 {
410 break
411 }
412 }
413
414 for _, Intf := range PONRMgr.IntfIDs {
415 SharedPoolID := PONRMgr.PonResourceRanges[FLOW_ID_SHARED_IDX].(uint32)
416 if SharedPoolID != 0 {
417 Intf = SharedPoolID
418 }
npujar5bf737f2020-01-16 19:35:25 +0530419 if err = PONRMgr.InitResourceIDPool(ctx, Intf, FLOW_ID,
Scott Baker2c1c4822019-10-16 11:02:41 -0700420 PONRMgr.PonResourceRanges[FLOW_ID_START_IDX].(uint32),
421 PONRMgr.PonResourceRanges[FLOW_ID_END_IDX].(uint32)); err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000422 logger.Error("Failed to init FLOW ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700423 return err
424 }
425 if SharedPoolID != 0 {
426 break
427 }
428 }
429 return err
430}
431
npujar5bf737f2020-01-16 19:35:25 +0530432func (PONRMgr *PONResourceManager) ClearDeviceResourcePool(ctx context.Context) error {
Scott Baker2c1c4822019-10-16 11:02:41 -0700433
434 //Clear resource pool for all PON ports.
435
Girish Kumare6f45e82020-03-20 10:46:54 +0000436 logger.Debug("Clear resource ranges")
Scott Baker2c1c4822019-10-16 11:02:41 -0700437
438 for _, Intf := range PONRMgr.IntfIDs {
439 SharedPoolID := PONRMgr.PonResourceRanges[ONU_ID_SHARED_IDX].(uint32)
440 if SharedPoolID != 0 {
441 Intf = SharedPoolID
442 }
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800443 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, ONU_ID); !status {
Girish Kumare6f45e82020-03-20 10:46:54 +0000444 logger.Error("Failed to clear ONU ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700445 return errors.New("Failed to clear ONU ID resource pool")
446 }
447 if SharedPoolID != 0 {
448 break
449 }
450 }
451
452 for _, Intf := range PONRMgr.IntfIDs {
453 SharedPoolID := PONRMgr.PonResourceRanges[ALLOC_ID_SHARED_IDX].(uint32)
454 if SharedPoolID != 0 {
455 Intf = SharedPoolID
456 }
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800457 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, ALLOC_ID); !status {
Girish Kumare6f45e82020-03-20 10:46:54 +0000458 logger.Error("Failed to clear ALLOC ID resource pool ")
Scott Baker2c1c4822019-10-16 11:02:41 -0700459 return errors.New("Failed to clear ALLOC ID resource pool")
460 }
461 if SharedPoolID != 0 {
462 break
463 }
464 }
465 for _, Intf := range PONRMgr.IntfIDs {
466 SharedPoolID := PONRMgr.PonResourceRanges[GEMPORT_ID_SHARED_IDX].(uint32)
467 if SharedPoolID != 0 {
468 Intf = SharedPoolID
469 }
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800470 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, GEMPORT_ID); !status {
Girish Kumare6f45e82020-03-20 10:46:54 +0000471 logger.Error("Failed to clear GEMPORT ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700472 return errors.New("Failed to clear GEMPORT ID resource pool")
473 }
474 if SharedPoolID != 0 {
475 break
476 }
477 }
478
479 for _, Intf := range PONRMgr.IntfIDs {
480 SharedPoolID := PONRMgr.PonResourceRanges[FLOW_ID_SHARED_IDX].(uint32)
481 if SharedPoolID != 0 {
482 Intf = SharedPoolID
483 }
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800484 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, FLOW_ID); !status {
Girish Kumare6f45e82020-03-20 10:46:54 +0000485 logger.Error("Failed to clear FLOW ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700486 return errors.New("Failed to clear FLOW ID resource pool")
487 }
488 if SharedPoolID != 0 {
489 break
490 }
491 }
492 return nil
493}
494
npujar5bf737f2020-01-16 19:35:25 +0530495func (PONRMgr *PONResourceManager) InitResourceIDPool(ctx context.Context, Intf uint32, ResourceType string, StartID uint32, EndID uint32) error {
Scott Baker2c1c4822019-10-16 11:02:41 -0700496
497 /*Initialize Resource ID pool for a given Resource Type on a given PON Port
498
499 :param pon_intf_id: OLT PON interface id
500 :param resource_type: String to identify type of resource
501 :param start_idx: start index for onu id pool
502 :param end_idx: end index for onu id pool
503 :return boolean: True if resource id pool initialized else false
504 */
505
506 // delegate to the master instance if sharing enabled across instances
507 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
508 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujar5bf737f2020-01-16 19:35:25 +0530509 return SharedResourceMgr.InitResourceIDPool(ctx, Intf, ResourceType, StartID, EndID)
Scott Baker2c1c4822019-10-16 11:02:41 -0700510 }
511
512 Path := PONRMgr.GetPath(Intf, ResourceType)
513 if Path == "" {
Girish Kumare6f45e82020-03-20 10:46:54 +0000514 logger.Errorf("Failed to get path for resource type %s", ResourceType)
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800515 return fmt.Errorf("Failed to get path for resource type %s", ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700516 }
517
518 //In case of adapter reboot and reconciliation resource in kv store
519 //checked for its presence if not kv store update happens
npujar5bf737f2020-01-16 19:35:25 +0530520 Res, err := PONRMgr.GetResource(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700521 if (err == nil) && (Res != nil) {
Girish Kumare6f45e82020-03-20 10:46:54 +0000522 logger.Debugf("Resource %s already present in store ", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700523 return nil
524 } else {
Esin Karaman5351fc52020-02-14 07:45:49 +0000525 var excluded []uint32
526 if ResourceType == GEMPORT_ID {
527 //get gem port ids defined in the KV store, if any, and exclude them from the gem port id pool
528 if reservedGemPortIds, defined := PONRMgr.getReservedGemPortIdsFromKVStore(ctx); defined {
529 excluded = reservedGemPortIds
Girish Kumare6f45e82020-03-20 10:46:54 +0000530 logger.Debugw("Excluding some ports from GEM port id pool", log.Fields{"excluded gem ports": excluded})
Esin Karaman5351fc52020-02-14 07:45:49 +0000531 }
532 }
533 FormatResult, err := PONRMgr.FormatResource(Intf, StartID, EndID, excluded)
Scott Baker2c1c4822019-10-16 11:02:41 -0700534 if err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000535 logger.Errorf("Failed to format resource")
Scott Baker2c1c4822019-10-16 11:02:41 -0700536 return err
537 }
538 // Add resource as json in kv store.
npujar5bf737f2020-01-16 19:35:25 +0530539 err = PONRMgr.KVStore.Put(ctx, Path, FormatResult)
Scott Baker2c1c4822019-10-16 11:02:41 -0700540 if err == nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000541 logger.Debug("Successfuly posted to kv store")
Scott Baker2c1c4822019-10-16 11:02:41 -0700542 return err
543 }
544 }
545
Girish Kumare6f45e82020-03-20 10:46:54 +0000546 logger.Debug("Error initializing pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700547
548 return err
549}
550
Esin Karaman5351fc52020-02-14 07:45:49 +0000551func (PONRMgr *PONResourceManager) getReservedGemPortIdsFromKVStore(ctx context.Context) ([]uint32, bool) {
552 var reservedGemPortIds []uint32
553 // read reserved gem ports from the config path
554 KvPair, err := PONRMgr.KVStoreForConfig.Get(ctx, RESERVED_GEMPORT_IDS_PATH)
555 if err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000556 logger.Errorw("Unable to get reserved GEM port ids from the kv store", log.Fields{"err": err})
Esin Karaman5351fc52020-02-14 07:45:49 +0000557 return reservedGemPortIds, false
558 }
559 if KvPair == nil || KvPair.Value == nil {
560 //no reserved gem port defined in the store
561 return reservedGemPortIds, false
562 }
563 Val, err := kvstore.ToByte(KvPair.Value)
564 if err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000565 logger.Errorw("Failed to convert reserved gem port ids into byte array", log.Fields{"err": err})
Esin Karaman5351fc52020-02-14 07:45:49 +0000566 return reservedGemPortIds, false
567 }
568 if err = json.Unmarshal(Val, &reservedGemPortIds); err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000569 logger.Errorw("Failed to unmarshal reservedGemPortIds", log.Fields{"err": err})
Esin Karaman5351fc52020-02-14 07:45:49 +0000570 return reservedGemPortIds, false
571 }
572 return reservedGemPortIds, true
573}
574
575func (PONRMgr *PONResourceManager) FormatResource(IntfID uint32, StartIDx uint32, EndIDx uint32,
576 Excluded []uint32) ([]byte, error) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700577 /*
578 Format resource as json.
579 :param pon_intf_id: OLT PON interface id
580 :param start_idx: start index for id pool
581 :param end_idx: end index for id pool
Esin Karaman5351fc52020-02-14 07:45:49 +0000582 :Id values to be Excluded from the pool
Scott Baker2c1c4822019-10-16 11:02:41 -0700583 :return dictionary: resource formatted as map
584 */
585 // Format resource as json to be stored in backend store
586 Resource := make(map[string]interface{})
587 Resource[PON_INTF_ID] = IntfID
588 Resource[START_IDX] = StartIDx
589 Resource[END_IDX] = EndIDx
590 /*
591 Resource pool stored in backend store as binary string.
592 Tracking the resource allocation will be done by setting the bits \
593 in the byte array. The index set will be the resource number allocated.
594 */
595 var TSData *bitmap.Threadsafe
596 if TSData = bitmap.NewTS(int(EndIDx)); TSData == nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000597 logger.Error("Failed to create a bitmap")
Scott Baker2c1c4822019-10-16 11:02:41 -0700598 return nil, errors.New("Failed to create bitmap")
599 }
Esin Karaman5351fc52020-02-14 07:45:49 +0000600 for _, excludedID := range Excluded {
601 if excludedID < StartIDx || excludedID > EndIDx {
Girish Kumare6f45e82020-03-20 10:46:54 +0000602 logger.Warnf("Cannot reserve %d. It must be in the range of [%d, %d]", excludedID,
Esin Karaman5351fc52020-02-14 07:45:49 +0000603 StartIDx, EndIDx)
604 continue
605 }
606 PONRMgr.reserveID(TSData, StartIDx, excludedID)
607 }
Scott Baker2c1c4822019-10-16 11:02:41 -0700608 Resource[POOL] = TSData.Data(false) //we pass false so as the TSData lib api does not do a copy of the data and return
609
610 Value, err := json.Marshal(Resource)
611 if err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000612 logger.Errorf("Failed to marshall resource")
Scott Baker2c1c4822019-10-16 11:02:41 -0700613 return nil, err
614 }
615 return Value, err
616}
npujar5bf737f2020-01-16 19:35:25 +0530617func (PONRMgr *PONResourceManager) GetResource(ctx context.Context, Path string) (map[string]interface{}, error) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700618 /*
619 Get resource from kv store.
620
621 :param path: path to get resource
622 :return: resource if resource present in kv store else None
623 */
624 //get resource from kv store
625
626 var Value []byte
627 Result := make(map[string]interface{})
628 var Str string
629
npujar5bf737f2020-01-16 19:35:25 +0530630 Resource, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700631 if (err != nil) || (Resource == nil) {
Girish Kumare6f45e82020-03-20 10:46:54 +0000632 logger.Debugf("Resource unavailable at %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700633 return nil, err
634 }
635
636 Value, err = ToByte(Resource.Value)
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800637 if err != nil {
638 return nil, err
639 }
Scott Baker2c1c4822019-10-16 11:02:41 -0700640
641 // decode resource fetched from backend store to dictionary
642 err = json.Unmarshal(Value, &Result)
643 if err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000644 logger.Error("Failed to decode resource")
Scott Baker2c1c4822019-10-16 11:02:41 -0700645 return Result, err
646 }
647 /*
648 resource pool in backend store stored as binary string whereas to
649 access the pool to generate/release IDs it need to be converted
650 as BitArray
651 */
652 Str, err = ToString(Result[POOL])
653 if err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000654 logger.Error("Failed to conver to kv pair to string")
Scott Baker2c1c4822019-10-16 11:02:41 -0700655 return Result, err
656 }
657 Decode64, _ := base64.StdEncoding.DecodeString(Str)
658 Result[POOL], err = ToByte(Decode64)
659 if err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000660 logger.Error("Failed to convert resource pool to byte")
Scott Baker2c1c4822019-10-16 11:02:41 -0700661 return Result, err
662 }
663
664 return Result, err
665}
666
667func (PONRMgr *PONResourceManager) GetPath(IntfID uint32, ResourceType string) string {
668 /*
669 Get path for given resource type.
670 :param pon_intf_id: OLT PON interface id
671 :param resource_type: String to identify type of resource
672 :return: path for given resource type
673 */
674
675 /*
676 Get the shared pool for the given resource type.
677 all the resource ranges and the shared resource maps are initialized during the init.
678 */
679 SharedPoolID := PONRMgr.PonResourceRanges[PONRMgr.SharedIdxByType[ResourceType]].(uint32)
680 if SharedPoolID != 0 {
681 IntfID = SharedPoolID
682 }
683 var Path string
684 if ResourceType == ONU_ID {
685 Path = fmt.Sprintf(ONU_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
686 } else if ResourceType == ALLOC_ID {
687 Path = fmt.Sprintf(ALLOC_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
688 } else if ResourceType == GEMPORT_ID {
689 Path = fmt.Sprintf(GEMPORT_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
690 } else if ResourceType == FLOW_ID {
691 Path = fmt.Sprintf(FLOW_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
692 } else {
Girish Kumare6f45e82020-03-20 10:46:54 +0000693 logger.Error("Invalid resource pool identifier")
Scott Baker2c1c4822019-10-16 11:02:41 -0700694 }
695 return Path
696}
697
npujar5bf737f2020-01-16 19:35:25 +0530698func (PONRMgr *PONResourceManager) GetResourceID(ctx context.Context, IntfID uint32, ResourceType string, NumIDs uint32) ([]uint32, error) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700699 /*
700 Create alloc/gemport/onu/flow id for given OLT PON interface.
701 :param pon_intf_id: OLT PON interface id
702 :param resource_type: String to identify type of resource
703 :param num_of_id: required number of ids
704 :return list/uint32/None: list, uint32 or None if resource type is
705 alloc_id/gemport_id, onu_id or invalid type respectively
706 */
707 if NumIDs < 1 {
Girish Kumare6f45e82020-03-20 10:46:54 +0000708 logger.Error("Invalid number of resources requested")
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800709 return nil, fmt.Errorf("Invalid number of resources requested %d", NumIDs)
Scott Baker2c1c4822019-10-16 11:02:41 -0700710 }
711 // delegate to the master instance if sharing enabled across instances
712
713 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
714 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujar5bf737f2020-01-16 19:35:25 +0530715 return SharedResourceMgr.GetResourceID(ctx, IntfID, ResourceType, NumIDs)
Scott Baker2c1c4822019-10-16 11:02:41 -0700716 }
Girish Kumare6f45e82020-03-20 10:46:54 +0000717 logger.Debugf("Fetching resource from %s rsrc mgr for resource %s", PONRMgr.Globalorlocal, ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700718
719 Path := PONRMgr.GetPath(IntfID, ResourceType)
720 if Path == "" {
Girish Kumare6f45e82020-03-20 10:46:54 +0000721 logger.Errorf("Failed to get path for resource type %s", ResourceType)
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800722 return nil, fmt.Errorf("Failed to get path for resource type %s", ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700723 }
Girish Kumare6f45e82020-03-20 10:46:54 +0000724 logger.Debugf("Get resource for type %s on path %s", ResourceType, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700725 var Result []uint32
726 var NextID uint32
npujar5bf737f2020-01-16 19:35:25 +0530727 Resource, err := PONRMgr.GetResource(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700728 if (err == nil) && (ResourceType == ONU_ID) || (ResourceType == FLOW_ID) {
729 if NextID, err = PONRMgr.GenerateNextID(Resource); err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000730 logger.Error("Failed to Generate ID")
Scott Baker2c1c4822019-10-16 11:02:41 -0700731 return Result, err
732 }
733 Result = append(Result, NextID)
734 } else if (err == nil) && ((ResourceType == GEMPORT_ID) || (ResourceType == ALLOC_ID)) {
735 if NumIDs == 1 {
736 if NextID, err = PONRMgr.GenerateNextID(Resource); err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000737 logger.Error("Failed to Generate ID")
Scott Baker2c1c4822019-10-16 11:02:41 -0700738 return Result, err
739 }
740 Result = append(Result, NextID)
741 } else {
742 for NumIDs > 0 {
743 if NextID, err = PONRMgr.GenerateNextID(Resource); err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000744 logger.Error("Failed to Generate ID")
Scott Baker2c1c4822019-10-16 11:02:41 -0700745 return Result, err
746 }
747 Result = append(Result, NextID)
748 NumIDs--
749 }
750 }
751 } else {
Girish Kumare6f45e82020-03-20 10:46:54 +0000752 logger.Error("get resource failed")
Scott Baker2c1c4822019-10-16 11:02:41 -0700753 return Result, err
754 }
755
756 //Update resource in kv store
npujar5bf737f2020-01-16 19:35:25 +0530757 if PONRMgr.UpdateResource(ctx, Path, Resource) != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000758 logger.Errorf("Failed to update resource %s", Path)
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800759 return nil, fmt.Errorf("Failed to update resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700760 }
761 return Result, nil
762}
763
764func checkValidResourceType(ResourceType string) bool {
765 KnownResourceTypes := []string{ONU_ID, ALLOC_ID, GEMPORT_ID, FLOW_ID}
766
767 for _, v := range KnownResourceTypes {
768 if v == ResourceType {
769 return true
770 }
771 }
772 return false
773}
774
npujar5bf737f2020-01-16 19:35:25 +0530775func (PONRMgr *PONResourceManager) FreeResourceID(ctx context.Context, IntfID uint32, ResourceType string, ReleaseContent []uint32) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -0700776 /*
777 Release alloc/gemport/onu/flow id for given OLT PON interface.
778 :param pon_intf_id: OLT PON interface id
779 :param resource_type: String to identify type of resource
780 :param release_content: required number of ids
781 :return boolean: True if all IDs in given release_content release else False
782 */
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800783 if !checkValidResourceType(ResourceType) {
Girish Kumare6f45e82020-03-20 10:46:54 +0000784 logger.Error("Invalid resource type")
Scott Baker2c1c4822019-10-16 11:02:41 -0700785 return false
786 }
787 if ReleaseContent == nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000788 logger.Debug("Nothing to release")
Scott Baker2c1c4822019-10-16 11:02:41 -0700789 return true
790 }
791 // delegate to the master instance if sharing enabled across instances
792 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
793 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujar5bf737f2020-01-16 19:35:25 +0530794 return SharedResourceMgr.FreeResourceID(ctx, IntfID, ResourceType, ReleaseContent)
Scott Baker2c1c4822019-10-16 11:02:41 -0700795 }
796 Path := PONRMgr.GetPath(IntfID, ResourceType)
797 if Path == "" {
Girish Kumare6f45e82020-03-20 10:46:54 +0000798 logger.Error("Failed to get path")
Scott Baker2c1c4822019-10-16 11:02:41 -0700799 return false
800 }
npujar5bf737f2020-01-16 19:35:25 +0530801 Resource, err := PONRMgr.GetResource(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700802 if err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000803 logger.Error("Failed to get resource")
Scott Baker2c1c4822019-10-16 11:02:41 -0700804 return false
805 }
806 for _, Val := range ReleaseContent {
807 PONRMgr.ReleaseID(Resource, Val)
808 }
npujar5bf737f2020-01-16 19:35:25 +0530809 if PONRMgr.UpdateResource(ctx, Path, Resource) != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000810 logger.Errorf("Free resource for %s failed", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700811 return false
812 }
813 return true
814}
815
npujar5bf737f2020-01-16 19:35:25 +0530816func (PONRMgr *PONResourceManager) UpdateResource(ctx context.Context, Path string, Resource map[string]interface{}) error {
Scott Baker2c1c4822019-10-16 11:02:41 -0700817 /*
818 Update resource in resource kv store.
819 :param path: path to update resource
820 :param resource: resource need to be updated
821 :return boolean: True if resource updated in kv store else False
822 */
823 // TODO resource[POOL] = resource[POOL].bin
824 Value, err := json.Marshal(Resource)
825 if err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000826 logger.Error("failed to Marshal")
Scott Baker2c1c4822019-10-16 11:02:41 -0700827 return err
828 }
npujar5bf737f2020-01-16 19:35:25 +0530829 err = PONRMgr.KVStore.Put(ctx, Path, Value)
Scott Baker2c1c4822019-10-16 11:02:41 -0700830 if err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000831 logger.Error("failed to put data to kv store %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700832 return err
833 }
834 return nil
835}
836
npujar5bf737f2020-01-16 19:35:25 +0530837func (PONRMgr *PONResourceManager) ClearResourceIDPool(ctx context.Context, contIntfID uint32, ResourceType string) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -0700838 /*
839 Clear Resource Pool for a given Resource Type on a given PON Port.
840 :return boolean: True if removed else False
841 */
842
843 // delegate to the master instance if sharing enabled across instances
844 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
845 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujar5bf737f2020-01-16 19:35:25 +0530846 return SharedResourceMgr.ClearResourceIDPool(ctx, contIntfID, ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700847 }
npujar5bf737f2020-01-16 19:35:25 +0530848 Path := PONRMgr.GetPath(contIntfID, ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700849 if Path == "" {
Girish Kumare6f45e82020-03-20 10:46:54 +0000850 logger.Error("Failed to get path")
Scott Baker2c1c4822019-10-16 11:02:41 -0700851 return false
852 }
853
npujar5bf737f2020-01-16 19:35:25 +0530854 if err := PONRMgr.KVStore.Delete(ctx, Path); err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000855 logger.Errorf("Failed to delete resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700856 return false
857 }
Girish Kumare6f45e82020-03-20 10:46:54 +0000858 logger.Debugf("Cleared resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700859 return true
860}
861
npujar5bf737f2020-01-16 19:35:25 +0530862func (PONRMgr PONResourceManager) InitResourceMap(ctx context.Context, PONIntfONUID string) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700863 /*
864 Initialize resource map
865 :param pon_intf_onu_id: reference of PON interface id and onu id
866 */
867 // initialize pon_intf_onu_id tuple to alloc_ids map
868 AllocIDPath := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
869 var AllocIDs []byte
npujar5bf737f2020-01-16 19:35:25 +0530870 Result := PONRMgr.KVStore.Put(ctx, AllocIDPath, AllocIDs)
Scott Baker2c1c4822019-10-16 11:02:41 -0700871 if Result != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000872 logger.Error("Failed to update the KV store")
Scott Baker2c1c4822019-10-16 11:02:41 -0700873 return
874 }
875 // initialize pon_intf_onu_id tuple to gemport_ids map
876 GEMPortIDPath := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
877 var GEMPortIDs []byte
npujar5bf737f2020-01-16 19:35:25 +0530878 Result = PONRMgr.KVStore.Put(ctx, GEMPortIDPath, GEMPortIDs)
Scott Baker2c1c4822019-10-16 11:02:41 -0700879 if Result != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000880 logger.Error("Failed to update the KV store")
Scott Baker2c1c4822019-10-16 11:02:41 -0700881 return
882 }
883}
884
npujar5bf737f2020-01-16 19:35:25 +0530885func (PONRMgr PONResourceManager) RemoveResourceMap(ctx context.Context, PONIntfONUID string) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -0700886 /*
887 Remove resource map
888 :param pon_intf_onu_id: reference of PON interface id and onu id
889 */
890 // remove pon_intf_onu_id tuple to alloc_ids map
891 var err error
892 AllocIDPath := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujar5bf737f2020-01-16 19:35:25 +0530893 if err = PONRMgr.KVStore.Delete(ctx, AllocIDPath); err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000894 logger.Errorf("Failed to remove resource %s", AllocIDPath)
Scott Baker2c1c4822019-10-16 11:02:41 -0700895 return false
896 }
897 // remove pon_intf_onu_id tuple to gemport_ids map
898 GEMPortIDPath := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujar5bf737f2020-01-16 19:35:25 +0530899 err = PONRMgr.KVStore.Delete(ctx, GEMPortIDPath)
Scott Baker2c1c4822019-10-16 11:02:41 -0700900 if err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000901 logger.Errorf("Failed to remove resource %s", GEMPortIDPath)
Scott Baker2c1c4822019-10-16 11:02:41 -0700902 return false
903 }
904
905 FlowIDPath := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujar5bf737f2020-01-16 19:35:25 +0530906 if FlowIDs, err := PONRMgr.KVStore.List(ctx, FlowIDPath); err != nil {
Scott Baker2c1c4822019-10-16 11:02:41 -0700907 for _, Flow := range FlowIDs {
908 FlowIDInfoPath := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, PONIntfONUID, Flow.Value)
npujar5bf737f2020-01-16 19:35:25 +0530909 if err = PONRMgr.KVStore.Delete(ctx, FlowIDInfoPath); err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000910 logger.Errorf("Failed to remove resource %s", FlowIDInfoPath)
Scott Baker2c1c4822019-10-16 11:02:41 -0700911 return false
912 }
913 }
914 }
915
npujar5bf737f2020-01-16 19:35:25 +0530916 if err = PONRMgr.KVStore.Delete(ctx, FlowIDPath); err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000917 logger.Errorf("Failed to remove resource %s", FlowIDPath)
Scott Baker2c1c4822019-10-16 11:02:41 -0700918 return false
919 }
920
921 return true
922}
923
npujar5bf737f2020-01-16 19:35:25 +0530924func (PONRMgr *PONResourceManager) GetCurrentAllocIDForOnu(ctx context.Context, IntfONUID string) []uint32 {
Scott Baker2c1c4822019-10-16 11:02:41 -0700925 /*
926 Get currently configured alloc ids for given pon_intf_onu_id
927 :param pon_intf_onu_id: reference of PON interface id and onu id
928 :return list: List of alloc_ids if available, else None
929 */
930 Path := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
931
932 var Data []uint32
npujar5bf737f2020-01-16 19:35:25 +0530933 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700934 if err == nil {
935 if Value != nil {
936 Val, err := ToByte(Value.Value)
937 if err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000938 logger.Errorw("Failed to convert into byte array", log.Fields{"error": err})
Scott Baker2c1c4822019-10-16 11:02:41 -0700939 return Data
940 }
941 if err = json.Unmarshal(Val, &Data); err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000942 logger.Error("Failed to unmarshal", log.Fields{"error": err})
Scott Baker2c1c4822019-10-16 11:02:41 -0700943 return Data
944 }
945 }
946 }
947 return Data
948}
949
npujar5bf737f2020-01-16 19:35:25 +0530950func (PONRMgr *PONResourceManager) GetCurrentGEMPortIDsForOnu(ctx context.Context, IntfONUID string) []uint32 {
Scott Baker2c1c4822019-10-16 11:02:41 -0700951 /*
952 Get currently configured gemport ids for given pon_intf_onu_id
953 :param pon_intf_onu_id: reference of PON interface id and onu id
954 :return list: List of gemport IDs if available, else None
955 */
956
957 Path := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Girish Kumare6f45e82020-03-20 10:46:54 +0000958 logger.Debugf("Getting current gemports for %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700959 var Data []uint32
npujar5bf737f2020-01-16 19:35:25 +0530960 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700961 if err == nil {
962 if Value != nil {
963 Val, _ := ToByte(Value.Value)
964 if err = json.Unmarshal(Val, &Data); err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000965 logger.Errorw("Failed to unmarshal", log.Fields{"error": err})
Scott Baker2c1c4822019-10-16 11:02:41 -0700966 return Data
967 }
968 }
969 } else {
Girish Kumare6f45e82020-03-20 10:46:54 +0000970 logger.Errorf("Failed to get data from kvstore for %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700971 }
972 return Data
973}
974
npujar5bf737f2020-01-16 19:35:25 +0530975func (PONRMgr *PONResourceManager) GetCurrentFlowIDsForOnu(ctx context.Context, IntfONUID string) []uint32 {
Scott Baker2c1c4822019-10-16 11:02:41 -0700976 /*
977 Get currently configured flow ids for given pon_intf_onu_id
978 :param pon_intf_onu_id: reference of PON interface id and onu id
979 :return list: List of Flow IDs if available, else None
980 */
981
982 Path := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
983
984 var Data []uint32
npujar5bf737f2020-01-16 19:35:25 +0530985 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700986 if err == nil {
987 if Value != nil {
988 Val, _ := ToByte(Value.Value)
989 if err = json.Unmarshal(Val, &Data); err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +0000990 logger.Error("Failed to unmarshal")
Scott Baker2c1c4822019-10-16 11:02:41 -0700991 return Data
992 }
993 }
994 }
995 return Data
996}
997
npujar5bf737f2020-01-16 19:35:25 +0530998func (PONRMgr *PONResourceManager) GetFlowIDInfo(ctx context.Context, IntfONUID string, FlowID uint32, Data interface{}) error {
Scott Baker2c1c4822019-10-16 11:02:41 -0700999 /*
1000 Get flow details configured for the ONU.
1001 :param pon_intf_onu_id: reference of PON interface id and onu id
1002 :param flow_id: Flow Id reference
1003 :param Data: Result
1004 :return error: nil if no error in getting from KV store
1005 */
1006
1007 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
1008
npujar5bf737f2020-01-16 19:35:25 +05301009 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001010 if err == nil {
1011 if Value != nil {
1012 Val, err := ToByte(Value.Value)
1013 if err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +00001014 logger.Errorw("Failed to convert flowinfo into byte array", log.Fields{"error": err})
Scott Baker2c1c4822019-10-16 11:02:41 -07001015 return err
1016 }
1017 if err = json.Unmarshal(Val, Data); err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +00001018 logger.Errorw("Failed to unmarshal", log.Fields{"error": err})
Scott Baker2c1c4822019-10-16 11:02:41 -07001019 return err
1020 }
1021 }
1022 }
1023 return err
1024}
1025
npujar5bf737f2020-01-16 19:35:25 +05301026func (PONRMgr *PONResourceManager) RemoveFlowIDInfo(ctx context.Context, IntfONUID string, FlowID uint32) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -07001027 /*
1028 Get flow_id details configured for the ONU.
1029 :param pon_intf_onu_id: reference of PON interface id and onu id
1030 :param flow_id: Flow Id reference
1031 */
1032 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
1033
npujar5bf737f2020-01-16 19:35:25 +05301034 if err := PONRMgr.KVStore.Delete(ctx, Path); err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +00001035 logger.Errorf("Falied to remove resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001036 return false
1037 }
1038 return true
1039}
1040
npujar5bf737f2020-01-16 19:35:25 +05301041func (PONRMgr *PONResourceManager) UpdateAllocIdsForOnu(ctx context.Context, IntfONUID string, AllocIDs []uint32) error {
Scott Baker2c1c4822019-10-16 11:02:41 -07001042 /*
1043 Update currently configured alloc ids for given pon_intf_onu_id
1044 :param pon_intf_onu_id: reference of PON interface id and onu id
1045 :param alloc_ids: list of alloc ids
1046 */
1047 var Value []byte
1048 var err error
1049 Path := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
1050 Value, err = json.Marshal(AllocIDs)
1051 if err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +00001052 logger.Error("failed to Marshal")
Scott Baker2c1c4822019-10-16 11:02:41 -07001053 return err
1054 }
1055
npujar5bf737f2020-01-16 19:35:25 +05301056 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +00001057 logger.Errorf("Failed to update resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001058 return err
1059 }
1060 return err
1061}
1062
npujar5bf737f2020-01-16 19:35:25 +05301063func (PONRMgr *PONResourceManager) UpdateGEMPortIDsForOnu(ctx context.Context, IntfONUID string, GEMPortIDs []uint32) error {
Scott Baker2c1c4822019-10-16 11:02:41 -07001064 /*
1065 Update currently configured gemport ids for given pon_intf_onu_id
1066 :param pon_intf_onu_id: reference of PON interface id and onu id
1067 :param gemport_ids: list of gem port ids
1068 */
1069
1070 var Value []byte
1071 var err error
1072 Path := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Girish Kumare6f45e82020-03-20 10:46:54 +00001073 logger.Debugf("Updating gemport ids for %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001074 Value, err = json.Marshal(GEMPortIDs)
1075 if err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +00001076 logger.Error("failed to Marshal")
Scott Baker2c1c4822019-10-16 11:02:41 -07001077 return err
1078 }
1079
npujar5bf737f2020-01-16 19:35:25 +05301080 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +00001081 logger.Errorf("Failed to update resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001082 return err
1083 }
1084 return err
1085}
1086
1087func checkForFlowIDInList(FlowIDList []uint32, FlowID uint32) (bool, uint32) {
1088 /*
1089 Check for a flow id in a given list of flow IDs.
1090 :param FLowIDList: List of Flow IDs
1091 :param FlowID: Flowd to check in the list
1092 : return true and the index if present false otherwise.
1093 */
1094
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001095 for idx := range FlowIDList {
Scott Baker2c1c4822019-10-16 11:02:41 -07001096 if FlowID == FlowIDList[idx] {
1097 return true, uint32(idx)
1098 }
1099 }
1100 return false, 0
1101}
1102
npujar5bf737f2020-01-16 19:35:25 +05301103func (PONRMgr *PONResourceManager) UpdateFlowIDForOnu(ctx context.Context, IntfONUID string, FlowID uint32, Add bool) error {
Scott Baker2c1c4822019-10-16 11:02:41 -07001104 /*
1105 Update the flow_id list of the ONU (add or remove flow_id from the list)
1106 :param pon_intf_onu_id: reference of PON interface id and onu id
1107 :param flow_id: flow ID
1108 :param add: Boolean flag to indicate whether the flow_id should be
1109 added or removed from the list. Defaults to adding the flow.
1110 */
1111 var Value []byte
1112 var err error
1113 var RetVal bool
1114 var IDx uint32
1115 Path := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
npujar5bf737f2020-01-16 19:35:25 +05301116 FlowIDs := PONRMgr.GetCurrentFlowIDsForOnu(ctx, IntfONUID)
Scott Baker2c1c4822019-10-16 11:02:41 -07001117
1118 if Add {
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001119 if RetVal, _ = checkForFlowIDInList(FlowIDs, FlowID); RetVal {
1120 return nil
Scott Baker2c1c4822019-10-16 11:02:41 -07001121 }
1122 FlowIDs = append(FlowIDs, FlowID)
1123 } else {
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001124 if RetVal, IDx = checkForFlowIDInList(FlowIDs, FlowID); !RetVal {
1125 return nil
Scott Baker2c1c4822019-10-16 11:02:41 -07001126 }
1127 // delete the index and shift
1128 FlowIDs = append(FlowIDs[:IDx], FlowIDs[IDx+1:]...)
1129 }
1130 Value, err = json.Marshal(FlowIDs)
1131 if err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +00001132 logger.Error("Failed to Marshal")
Scott Baker2c1c4822019-10-16 11:02:41 -07001133 return err
1134 }
1135
npujar5bf737f2020-01-16 19:35:25 +05301136 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +00001137 logger.Errorf("Failed to update resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001138 return err
1139 }
1140 return err
1141}
1142
npujar5bf737f2020-01-16 19:35:25 +05301143func (PONRMgr *PONResourceManager) UpdateFlowIDInfoForOnu(ctx context.Context, IntfONUID string, FlowID uint32, FlowData interface{}) error {
Scott Baker2c1c4822019-10-16 11:02:41 -07001144 /*
1145 Update any metadata associated with the flow_id. The flow_data could be json
1146 or any of other data structure. The resource manager doesnt care
1147 :param pon_intf_onu_id: reference of PON interface id and onu id
1148 :param flow_id: Flow ID
1149 :param flow_data: Flow data blob
1150 */
1151 var Value []byte
1152 var err error
1153 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
1154 Value, err = json.Marshal(FlowData)
1155 if err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +00001156 logger.Error("failed to Marshal")
Scott Baker2c1c4822019-10-16 11:02:41 -07001157 return err
1158 }
1159
npujar5bf737f2020-01-16 19:35:25 +05301160 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +00001161 logger.Errorf("Failed to update resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001162 return err
1163 }
1164 return err
1165}
1166
1167func (PONRMgr *PONResourceManager) GenerateNextID(Resource map[string]interface{}) (uint32, error) {
1168 /*
1169 Generate unique id having OFFSET as start
1170 :param resource: resource used to generate ID
1171 :return uint32: generated id
1172 */
1173 ByteArray, err := ToByte(Resource[POOL])
1174 if err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +00001175 logger.Error("Failed to convert resource to byte array")
Scott Baker2c1c4822019-10-16 11:02:41 -07001176 return 0, err
1177 }
1178 Data := bitmap.TSFromData(ByteArray, false)
1179 if Data == nil {
Girish Kumare6f45e82020-03-20 10:46:54 +00001180 logger.Error("Failed to get data from byte array")
Scott Baker2c1c4822019-10-16 11:02:41 -07001181 return 0, errors.New("Failed to get data from byte array")
1182 }
1183
1184 Len := Data.Len()
1185 var Idx int
1186 for Idx = 0; Idx < Len; Idx++ {
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001187 if !Data.Get(Idx) {
Scott Baker2c1c4822019-10-16 11:02:41 -07001188 break
1189 }
1190 }
1191 Data.Set(Idx, true)
1192 res := uint32(Resource[START_IDX].(float64))
1193 Resource[POOL] = Data.Data(false)
Girish Kumare6f45e82020-03-20 10:46:54 +00001194 logger.Debugf("Generated ID for %d", (uint32(Idx) + res))
Scott Baker2c1c4822019-10-16 11:02:41 -07001195 return (uint32(Idx) + res), err
1196}
1197
1198func (PONRMgr *PONResourceManager) ReleaseID(Resource map[string]interface{}, Id uint32) bool {
1199 /*
1200 Release unique id having OFFSET as start index.
1201 :param resource: resource used to release ID
1202 :param unique_id: id need to be released
1203 */
1204 ByteArray, err := ToByte(Resource[POOL])
1205 if err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +00001206 logger.Error("Failed to convert resource to byte array")
Scott Baker2c1c4822019-10-16 11:02:41 -07001207 return false
1208 }
1209 Data := bitmap.TSFromData(ByteArray, false)
1210 if Data == nil {
Girish Kumare6f45e82020-03-20 10:46:54 +00001211 logger.Error("Failed to get resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -07001212 return false
1213 }
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001214 Idx := Id - uint32(Resource[START_IDX].(float64))
Scott Baker2c1c4822019-10-16 11:02:41 -07001215 Data.Set(int(Idx), false)
1216 Resource[POOL] = Data.Data(false)
1217
1218 return true
1219}
1220
Esin Karaman5351fc52020-02-14 07:45:49 +00001221/* Reserves a unique id in the specified resource pool.
1222:param Resource: resource used to reserve ID
1223:param Id: ID to be reserved
1224*/
1225func (PONRMgr *PONResourceManager) reserveID(TSData *bitmap.Threadsafe, StartIndex uint32, Id uint32) bool {
1226 Data := bitmap.TSFromData(TSData.Data(false), false)
1227 if Data == nil {
Girish Kumare6f45e82020-03-20 10:46:54 +00001228 logger.Error("Failed to get resource pool")
Esin Karaman5351fc52020-02-14 07:45:49 +00001229 return false
1230 }
1231 Idx := Id - StartIndex
1232 Data.Set(int(Idx), true)
1233 return true
1234}
1235
Scott Baker2c1c4822019-10-16 11:02:41 -07001236func (PONRMgr *PONResourceManager) GetTechnology() string {
1237 return PONRMgr.Technology
1238}
1239
1240func (PONRMgr *PONResourceManager) GetResourceTypeAllocID() string {
1241 return ALLOC_ID
1242}
1243
1244func (PONRMgr *PONResourceManager) GetResourceTypeGemPortID() string {
1245 return GEMPORT_ID
1246}
1247
1248// ToByte converts an interface value to a []byte. The interface should either be of
1249// a string type or []byte. Otherwise, an error is returned.
1250func ToByte(value interface{}) ([]byte, error) {
1251 switch t := value.(type) {
1252 case []byte:
1253 return value.([]byte), nil
1254 case string:
1255 return []byte(value.(string)), nil
1256 default:
1257 return nil, fmt.Errorf("unexpected-type-%T", t)
1258 }
1259}
1260
1261// ToString converts an interface value to a string. The interface should either be of
1262// a string type or []byte. Otherwise, an error is returned.
1263func ToString(value interface{}) (string, error) {
1264 switch t := value.(type) {
1265 case []byte:
1266 return string(value.([]byte)), nil
1267 case string:
1268 return value.(string), nil
1269 default:
1270 return "", fmt.Errorf("unexpected-type-%T", t)
1271 }
1272}
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301273
npujar5bf737f2020-01-16 19:35:25 +05301274func (PONRMgr *PONResourceManager) AddOnuGemInfo(ctx context.Context, intfID uint32, onuGemData interface{}) error {
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301275 /*
1276 Update onugem info map,
1277 :param pon_intf_id: reference of PON interface id
1278 :param onuegmdata: onugem info map
1279 */
1280 var Value []byte
1281 var err error
1282 Path := fmt.Sprintf(ONU_GEM_INFO_PATH, PONRMgr.DeviceID, intfID)
1283 Value, err = json.Marshal(onuGemData)
1284 if err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +00001285 logger.Error("failed to Marshal")
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301286 return err
1287 }
1288
npujar5bf737f2020-01-16 19:35:25 +05301289 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +00001290 logger.Errorf("Failed to update resource %s", Path)
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301291 return err
1292 }
1293 return err
1294}
1295
npujar5bf737f2020-01-16 19:35:25 +05301296func (PONRMgr *PONResourceManager) GetOnuGemInfo(ctx context.Context, IntfId uint32, onuGemInfo interface{}) error {
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301297 /*
1298 Get onugeminfo map from kvstore
1299 :param intfid: refremce pon intfid
1300 :param onuGemInfo: onugem info to return from kv strore.
1301 */
1302 var Val []byte
1303
1304 path := fmt.Sprintf(ONU_GEM_INFO_PATH, PONRMgr.DeviceID, IntfId)
npujar5bf737f2020-01-16 19:35:25 +05301305 value, err := PONRMgr.KVStore.Get(ctx, path)
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301306 if err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +00001307 logger.Errorw("Failed to get from kv store", log.Fields{"path": path})
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301308 return err
1309 } else if value == nil {
Girish Kumare6f45e82020-03-20 10:46:54 +00001310 logger.Debug("No onuinfo for path", log.Fields{"path": path})
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301311 return nil // returning nil as this could happen if there are no onus for the interface yet
1312 }
1313 if Val, err = kvstore.ToByte(value.Value); err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +00001314 logger.Error("Failed to convert to byte array")
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301315 return err
1316 }
1317
1318 if err = json.Unmarshal(Val, &onuGemInfo); err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +00001319 logger.Error("Failed to unmarshall")
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301320 return err
1321 }
Girish Kumare6f45e82020-03-20 10:46:54 +00001322 logger.Debugw("found onuinfo from path", log.Fields{"path": path, "onuinfo": onuGemInfo})
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301323 return err
1324}
1325
npujar5bf737f2020-01-16 19:35:25 +05301326func (PONRMgr *PONResourceManager) DelOnuGemInfoForIntf(ctx context.Context, intfId uint32) error {
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301327 /*
1328 delete onugem info for an interface from kvstore
1329 :param intfid: refremce pon intfid
1330 */
1331
1332 path := fmt.Sprintf(ONU_GEM_INFO_PATH, PONRMgr.DeviceID, intfId)
npujar5bf737f2020-01-16 19:35:25 +05301333 if err := PONRMgr.KVStore.Delete(ctx, path); err != nil {
Girish Kumare6f45e82020-03-20 10:46:54 +00001334 logger.Errorf("Falied to remove resource %s", path)
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301335 return err
1336 }
1337 return nil
1338}