blob: 79fefc547f436b138246b0ab17766d24c9abf292 [file] [log] [blame]
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001/*
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 (
npujarec5762e2020-01-01 14:08:48 +053020 "context"
Matt Jeanneret384d8c92019-05-06 14:27:31 -040021 "encoding/base64"
22 "encoding/json"
23 "errors"
24 "fmt"
25 "strconv"
Matt Jeanneretcab955f2019-04-10 15:45:57 -040026
Esin Karamanccb714b2019-11-29 15:02:06 +000027 bitmap "github.com/boljen/go-bitmap"
28 "github.com/opencord/voltha-lib-go/v3/pkg/db"
29 "github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore"
30 "github.com/opencord/voltha-lib-go/v3/pkg/log"
31 tp "github.com/opencord/voltha-lib-go/v3/pkg/techprofile"
Matt Jeanneretcab955f2019-04-10 15:45:57 -040032)
33
34const (
Matt Jeanneret384d8c92019-05-06 14:27:31 -040035 //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"
Matt Jeanneretcab955f2019-04-10 15:45:57 -040041
Matt Jeanneret384d8c92019-05-06 14:27:31 -040042 //Constants for passing command line arugments
43 OLT_MODEL_ARG = "--olt_model"
44 PATH_PREFIX = "service/voltha/resource_manager/{%s}"
divyadesaid26f6b12020-03-19 06:30:28 +000045
46 /*The path under which configuration data is stored is defined as technology/device agnostic.
47 That means the path does not include any specific technology/device variable. Using technology/device
48 agnostic path also makes northbound applications, that need to write to this path,
49 technology/device agnostic.
50
51 Default kv client of PonResourceManager reads from/writes to PATH_PREFIX defined above.
52 That is why, an additional kv client (named KVStoreForConfig) is defined to read from the config path.
53 */
54 PATH_PREFIX_FOR_CONFIG = "service/voltha/resource_manager/config"
Matt Jeanneret384d8c92019-05-06 14:27:31 -040055 /*The resource ranges for a given device model should be placed
56 at 'resource_manager/<technology>/resource_ranges/<olt_model_type>'
57 path on the KV store.
58 If Resource Range parameters are to be read from the external KV store,
59 they are expected to be stored in the following format.
60 Note: All parameters are MANDATORY for now.
61 constants used as keys to reference the resource range parameters from
62 and external KV store.
63 */
64 UNI_ID_START_IDX = "uni_id_start"
65 UNI_ID_END_IDX = "uni_id_end"
66 ONU_ID_START_IDX = "onu_id_start"
67 ONU_ID_END_IDX = "onu_id_end"
68 ONU_ID_SHARED_IDX = "onu_id_shared"
69 ALLOC_ID_START_IDX = "alloc_id_start"
70 ALLOC_ID_END_IDX = "alloc_id_end"
71 ALLOC_ID_SHARED_IDX = "alloc_id_shared"
72 GEMPORT_ID_START_IDX = "gemport_id_start"
73 GEMPORT_ID_END_IDX = "gemport_id_end"
74 GEMPORT_ID_SHARED_IDX = "gemport_id_shared"
75 FLOW_ID_START_IDX = "flow_id_start"
76 FLOW_ID_END_IDX = "flow_id_end"
77 FLOW_ID_SHARED_IDX = "flow_id_shared"
78 NUM_OF_PON_PORT = "pon_ports"
Matt Jeanneretcab955f2019-04-10 15:45:57 -040079
Matt Jeanneret384d8c92019-05-06 14:27:31 -040080 /*
81 The KV store backend is initialized with a path prefix and we need to
82 provide only the suffix.
83 */
84 PON_RESOURCE_RANGE_CONFIG_PATH = "resource_ranges/%s"
Matt Jeanneretcab955f2019-04-10 15:45:57 -040085
Matt Jeanneret384d8c92019-05-06 14:27:31 -040086 //resource path suffix
87 //Path on the KV store for storing alloc id ranges and resource pool for a given interface
88 //Format: <device_id>/alloc_id_pool/<pon_intf_id>
89 ALLOC_ID_POOL_PATH = "{%s}/alloc_id_pool/{%d}"
90 //Path on the KV store for storing gemport id ranges and resource pool for a given interface
91 //Format: <device_id>/gemport_id_pool/<pon_intf_id>
92 GEMPORT_ID_POOL_PATH = "{%s}/gemport_id_pool/{%d}"
93 //Path on the KV store for storing onu id ranges and resource pool for a given interface
94 //Format: <device_id>/onu_id_pool/<pon_intf_id>
95 ONU_ID_POOL_PATH = "{%s}/onu_id_pool/{%d}"
96 //Path on the KV store for storing flow id ranges and resource pool for a given interface
97 //Format: <device_id>/flow_id_pool/<pon_intf_id>
98 FLOW_ID_POOL_PATH = "{%s}/flow_id_pool/{%d}"
Matt Jeanneretcab955f2019-04-10 15:45:57 -040099
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400100 //Path on the KV store for storing list of alloc IDs for a given ONU
101 //Format: <device_id>/<(pon_intf_id, onu_id)>/alloc_ids
102 ALLOC_ID_RESOURCE_MAP_PATH = "{%s}/{%s}/alloc_ids"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400103
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400104 //Path on the KV store for storing list of gemport IDs for a given ONU
105 //Format: <device_id>/<(pon_intf_id, onu_id)>/gemport_ids
106 GEMPORT_ID_RESOURCE_MAP_PATH = "{%s}/{%s}/gemport_ids"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400107
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400108 //Path on the KV store for storing list of Flow IDs for a given ONU
109 //Format: <device_id>/<(pon_intf_id, onu_id)>/flow_ids
110 FLOW_ID_RESOURCE_MAP_PATH = "{%s}/{%s}/flow_ids"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400111
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400112 //Flow Id info: Use to store more metadata associated with the flow_id
113 //Format: <device_id>/<(pon_intf_id, onu_id)>/flow_id_info/<flow_id>
114 FLOW_ID_INFO_PATH = "{%s}/{%s}/flow_id_info/{%d}"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400115
Scott Bakerc6e54cb2019-11-04 09:31:25 -0800116 //path on the kvstore to store onugem info map
117 //format: <device-id>/onu_gem_info/<intfid>
118 ONU_GEM_INFO_PATH = "{%s}/onu_gem_info/{%d}" // onu_gem/<(intfid)>
119
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400120 //Constants for internal usage.
121 PON_INTF_ID = "pon_intf_id"
122 START_IDX = "start_idx"
123 END_IDX = "end_idx"
124 POOL = "pool"
125 NUM_OF_PON_INTF = 16
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400126
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400127 KVSTORE_RETRY_TIMEOUT = 5
divyadesaid26f6b12020-03-19 06:30:28 +0000128 //Path on the KV store for storing reserved gem ports
129 //Format: reserved_gemport_ids
130 RESERVED_GEMPORT_IDS_PATH = "reserved_gemport_ids"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400131)
132
133//type ResourceTypeIndex string
134//type ResourceType string
135
136type PONResourceManager struct {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400137 //Implements APIs to initialize/allocate/release alloc/gemport/onu IDs.
divyadesaid26f6b12020-03-19 06:30:28 +0000138 Technology string
139 DeviceType string
140 DeviceID string
141 Backend string // ETCD, or consul
142 Host string // host ip of the KV store
143 Port int // port number for the KV store
144 OLTModel string
145 KVStore *db.Backend
146 KVStoreForConfig *db.Backend
147 TechProfileMgr tp.TechProfileIf // create object of *tp.TechProfileMgr
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400148
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400149 // Below attribute, pon_resource_ranges, should be initialized
150 // by reading from KV store.
151 PonResourceRanges map[string]interface{}
152 SharedResourceMgrs map[string]*PONResourceManager
153 SharedIdxByType map[string]string
154 IntfIDs []uint32 // list of pon interface IDs
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400155 Globalorlocal string
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400156}
157
158func newKVClient(storeType string, address string, timeout int) (kvstore.Client, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400159 log.Infow("kv-store-type", log.Fields{"store": storeType})
160 switch storeType {
161 case "consul":
162 return kvstore.NewConsulClient(address, timeout)
163 case "etcd":
164 return kvstore.NewEtcdClient(address, timeout)
165 }
166 return nil, errors.New("unsupported-kv-store")
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400167}
168
divyadesaid26f6b12020-03-19 06:30:28 +0000169func SetKVClient(Technology string, Backend string, Host string, Port int, configClient bool) *db.Backend {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400170 addr := Host + ":" + strconv.Itoa(Port)
171 // 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
173 kvClient, err := newKVClient(Backend, addr, KVSTORE_RETRY_TIMEOUT)
174 if err != nil {
175 log.Fatalw("Failed to init KV client\n", log.Fields{"err": err})
176 return nil
177 }
divyadesaid26f6b12020-03-19 06:30:28 +0000178
179 var pathPrefix string
180 if configClient {
181 pathPrefix = PATH_PREFIX_FOR_CONFIG
182 } else {
183 pathPrefix = fmt.Sprintf(PATH_PREFIX, Technology)
184 }
185
sbarbaria8910ba2019-11-05 10:12:23 -0500186 kvbackend := &db.Backend{
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400187 Client: kvClient,
188 StoreType: Backend,
189 Host: Host,
190 Port: Port,
191 Timeout: KVSTORE_RETRY_TIMEOUT,
divyadesaid26f6b12020-03-19 06:30:28 +0000192 PathPrefix: pathPrefix}
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400193
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400194 return kvbackend
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400195}
196
197// NewPONResourceManager creates a new PON resource manager.
198func NewPONResourceManager(Technology string, DeviceType string, DeviceID string, Backend string, Host string, Port int) (*PONResourceManager, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400199 var PONMgr PONResourceManager
200 PONMgr.Technology = Technology
201 PONMgr.DeviceType = DeviceType
202 PONMgr.DeviceID = DeviceID
203 PONMgr.Backend = Backend
204 PONMgr.Host = Host
205 PONMgr.Port = Port
divyadesaid26f6b12020-03-19 06:30:28 +0000206 PONMgr.KVStore = SetKVClient(Technology, Backend, Host, Port, false)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400207 if PONMgr.KVStore == nil {
208 log.Error("KV Client initilization failed")
209 return nil, errors.New("Failed to init KV client")
210 }
divyadesaid26f6b12020-03-19 06:30:28 +0000211 // init kv client to read from the config path
212 PONMgr.KVStoreForConfig = SetKVClient(Technology, Backend, Host, Port, true)
213 if PONMgr.KVStoreForConfig == nil {
214 log.Error("KV Config Client initilization failed")
215 return nil, errors.New("Failed to init KV Config client")
216 }
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400217 // Initialize techprofile for this technology
Matt Jeannereta93dbed2019-05-17 12:40:05 -0400218 if PONMgr.TechProfileMgr, _ = tp.NewTechProfile(&PONMgr, Backend, Host, Port); PONMgr.TechProfileMgr == nil {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400219 log.Error("Techprofile initialization failed")
220 return nil, errors.New("Failed to init tech profile")
221 }
222 PONMgr.PonResourceRanges = make(map[string]interface{})
223 PONMgr.SharedResourceMgrs = make(map[string]*PONResourceManager)
224 PONMgr.SharedIdxByType = make(map[string]string)
225 PONMgr.SharedIdxByType[ONU_ID] = ONU_ID_SHARED_IDX
226 PONMgr.SharedIdxByType[ALLOC_ID] = ALLOC_ID_SHARED_IDX
227 PONMgr.SharedIdxByType[GEMPORT_ID] = GEMPORT_ID_SHARED_IDX
228 PONMgr.SharedIdxByType[FLOW_ID] = FLOW_ID_SHARED_IDX
229 PONMgr.IntfIDs = make([]uint32, NUM_OF_PON_INTF)
230 PONMgr.OLTModel = DeviceType
231 return &PONMgr, nil
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400232}
233
234/*
235 Initialize PON resource ranges with config fetched from kv store.
236 return boolean: True if PON resource ranges initialized else false
237 Try to initialize the PON Resource Ranges from KV store based on the
238 OLT model key, if available
239*/
240
npujarec5762e2020-01-01 14:08:48 +0530241func (PONRMgr *PONResourceManager) InitResourceRangesFromKVStore(ctx context.Context) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400242 //Initialize PON resource ranges with config fetched from kv store.
243 //:return boolean: True if PON resource ranges initialized else false
244 // Try to initialize the PON Resource Ranges from KV store based on the
245 // OLT model key, if available
246 if PONRMgr.OLTModel == "" {
247 log.Error("Failed to get OLT model")
248 return false
249 }
250 Path := fmt.Sprintf(PON_RESOURCE_RANGE_CONFIG_PATH, PONRMgr.OLTModel)
251 //get resource from kv store
npujarec5762e2020-01-01 14:08:48 +0530252 Result, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400253 if err != nil {
254 log.Debugf("Error in fetching resource %s from KV strore", Path)
255 return false
256 }
257 if Result == nil {
258 log.Debug("There may be no resources in the KV store in case of fresh bootup, return true")
259 return false
260 }
261 //update internal ranges from kv ranges. If there are missing
262 // values in the KV profile, continue to use the defaults
263 Value, err := ToByte(Result.Value)
264 if err != nil {
265 log.Error("Failed to convert kvpair to byte string")
266 return false
267 }
268 if err := json.Unmarshal(Value, &PONRMgr.PonResourceRanges); err != nil {
269 log.Error("Failed to Unmarshal json byte")
270 return false
271 }
272 log.Debug("Init resource ranges from kvstore success")
273 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400274}
275
276func (PONRMgr *PONResourceManager) UpdateRanges(StartIDx string, StartID uint32, EndIDx string, EndID uint32,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400277 SharedIDx string, SharedPoolID uint32, RMgr *PONResourceManager) {
278 /*
279 Update the ranges for all reosurce type in the intermnal maps
280 param: resource type start index
281 param: start ID
282 param: resource type end index
283 param: end ID
284 param: resource type shared index
285 param: shared pool id
286 param: global resource manager
287 */
288 log.Debugf("update ranges for %s, %d", StartIDx, StartID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400289
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400290 if StartID != 0 {
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400291 if (PONRMgr.PonResourceRanges[StartIDx] == nil) || (PONRMgr.PonResourceRanges[StartIDx].(uint32) < StartID) {
292 PONRMgr.PonResourceRanges[StartIDx] = StartID
293 }
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400294 }
295 if EndID != 0 {
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400296 if (PONRMgr.PonResourceRanges[EndIDx] == nil) || (PONRMgr.PonResourceRanges[EndIDx].(uint32) > EndID) {
297 PONRMgr.PonResourceRanges[EndIDx] = EndID
298 }
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400299 }
300 //if SharedPoolID != 0 {
301 PONRMgr.PonResourceRanges[SharedIDx] = SharedPoolID
302 //}
303 if RMgr != nil {
304 PONRMgr.SharedResourceMgrs[SharedIDx] = RMgr
305 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400306}
307
308func (PONRMgr *PONResourceManager) InitDefaultPONResourceRanges(ONUIDStart uint32,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400309 ONUIDEnd uint32,
310 ONUIDSharedPoolID uint32,
311 AllocIDStart uint32,
312 AllocIDEnd uint32,
313 AllocIDSharedPoolID uint32,
314 GEMPortIDStart uint32,
315 GEMPortIDEnd uint32,
316 GEMPortIDSharedPoolID uint32,
317 FlowIDStart uint32,
318 FlowIDEnd uint32,
319 FlowIDSharedPoolID uint32,
320 UNIIDStart uint32,
321 UNIIDEnd uint32,
322 NoOfPONPorts uint32,
323 IntfIDs []uint32) bool {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400324
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400325 /*Initialize default PON resource ranges
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400326
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400327 :param onu_id_start_idx: onu id start index
328 :param onu_id_end_idx: onu id end index
329 :param onu_id_shared_pool_id: pool idx for id shared by all intfs or None for no sharing
330 :param alloc_id_start_idx: alloc id start index
331 :param alloc_id_end_idx: alloc id end index
332 :param alloc_id_shared_pool_id: pool idx for alloc id shared by all intfs or None for no sharing
333 :param gemport_id_start_idx: gemport id start index
334 :param gemport_id_end_idx: gemport id end index
335 :param gemport_id_shared_pool_id: pool idx for gemport id shared by all intfs or None for no sharing
336 :param flow_id_start_idx: flow id start index
337 :param flow_id_end_idx: flow id end index
338 :param flow_id_shared_pool_id: pool idx for flow id shared by all intfs or None for no sharing
339 :param num_of_pon_ports: number of PON ports
340 :param intf_ids: interfaces serviced by this manager
341 */
342 PONRMgr.UpdateRanges(ONU_ID_START_IDX, ONUIDStart, ONU_ID_END_IDX, ONUIDEnd, ONU_ID_SHARED_IDX, ONUIDSharedPoolID, nil)
343 PONRMgr.UpdateRanges(ALLOC_ID_START_IDX, AllocIDStart, ALLOC_ID_END_IDX, AllocIDEnd, ALLOC_ID_SHARED_IDX, AllocIDSharedPoolID, nil)
344 PONRMgr.UpdateRanges(GEMPORT_ID_START_IDX, GEMPortIDStart, GEMPORT_ID_END_IDX, GEMPortIDEnd, GEMPORT_ID_SHARED_IDX, GEMPortIDSharedPoolID, nil)
345 PONRMgr.UpdateRanges(FLOW_ID_START_IDX, FlowIDStart, FLOW_ID_END_IDX, FlowIDEnd, FLOW_ID_SHARED_IDX, FlowIDSharedPoolID, nil)
346 PONRMgr.UpdateRanges(UNI_ID_START_IDX, UNIIDStart, UNI_ID_END_IDX, UNIIDEnd, "", 0, nil)
347 log.Debug("Initialize default range values")
348 var i uint32
349 if IntfIDs == nil {
350 for i = 0; i < NoOfPONPorts; i++ {
351 PONRMgr.IntfIDs = append(PONRMgr.IntfIDs, i)
352 }
353 } else {
354 PONRMgr.IntfIDs = IntfIDs
355 }
356 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400357}
358
npujarec5762e2020-01-01 14:08:48 +0530359func (PONRMgr *PONResourceManager) InitDeviceResourcePool(ctx context.Context) error {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400360
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400361 //Initialize resource pool for all PON ports.
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400362
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400363 log.Debug("Init resource ranges")
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400364
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400365 var err error
366 for _, Intf := range PONRMgr.IntfIDs {
367 SharedPoolID := PONRMgr.PonResourceRanges[ONU_ID_SHARED_IDX].(uint32)
368 if SharedPoolID != 0 {
369 Intf = SharedPoolID
370 }
npujarec5762e2020-01-01 14:08:48 +0530371 if err = PONRMgr.InitResourceIDPool(ctx, Intf, ONU_ID,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400372 PONRMgr.PonResourceRanges[ONU_ID_START_IDX].(uint32),
373 PONRMgr.PonResourceRanges[ONU_ID_END_IDX].(uint32)); err != nil {
374 log.Error("Failed to init ONU ID resource pool")
375 return err
376 }
377 if SharedPoolID != 0 {
378 break
379 }
380 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400381
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400382 for _, Intf := range PONRMgr.IntfIDs {
383 SharedPoolID := PONRMgr.PonResourceRanges[ALLOC_ID_SHARED_IDX].(uint32)
384 if SharedPoolID != 0 {
385 Intf = SharedPoolID
386 }
npujarec5762e2020-01-01 14:08:48 +0530387 if err = PONRMgr.InitResourceIDPool(ctx, Intf, ALLOC_ID,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400388 PONRMgr.PonResourceRanges[ALLOC_ID_START_IDX].(uint32),
389 PONRMgr.PonResourceRanges[ALLOC_ID_END_IDX].(uint32)); err != nil {
390 log.Error("Failed to init ALLOC ID resource pool ")
391 return err
392 }
393 if SharedPoolID != 0 {
394 break
395 }
396 }
397 for _, Intf := range PONRMgr.IntfIDs {
398 SharedPoolID := PONRMgr.PonResourceRanges[GEMPORT_ID_SHARED_IDX].(uint32)
399 if SharedPoolID != 0 {
400 Intf = SharedPoolID
401 }
npujarec5762e2020-01-01 14:08:48 +0530402 if err = PONRMgr.InitResourceIDPool(ctx, Intf, GEMPORT_ID,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400403 PONRMgr.PonResourceRanges[GEMPORT_ID_START_IDX].(uint32),
404 PONRMgr.PonResourceRanges[GEMPORT_ID_END_IDX].(uint32)); err != nil {
405 log.Error("Failed to init GEMPORT ID resource pool")
406 return err
407 }
408 if SharedPoolID != 0 {
409 break
410 }
411 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400412
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400413 for _, Intf := range PONRMgr.IntfIDs {
414 SharedPoolID := PONRMgr.PonResourceRanges[FLOW_ID_SHARED_IDX].(uint32)
415 if SharedPoolID != 0 {
416 Intf = SharedPoolID
417 }
npujarec5762e2020-01-01 14:08:48 +0530418 if err = PONRMgr.InitResourceIDPool(ctx, Intf, FLOW_ID,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400419 PONRMgr.PonResourceRanges[FLOW_ID_START_IDX].(uint32),
420 PONRMgr.PonResourceRanges[FLOW_ID_END_IDX].(uint32)); err != nil {
421 log.Error("Failed to init FLOW ID resource pool")
422 return err
423 }
424 if SharedPoolID != 0 {
425 break
426 }
427 }
428 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400429}
430
npujarec5762e2020-01-01 14:08:48 +0530431func (PONRMgr *PONResourceManager) ClearDeviceResourcePool(ctx context.Context) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -0400432
433 //Clear resource pool for all PON ports.
434
435 log.Debug("Clear resource ranges")
436
437 for _, Intf := range PONRMgr.IntfIDs {
438 SharedPoolID := PONRMgr.PonResourceRanges[ONU_ID_SHARED_IDX].(uint32)
439 if SharedPoolID != 0 {
440 Intf = SharedPoolID
441 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000442 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, ONU_ID); !status {
Devmalya Paul495b94a2019-08-27 19:42:00 -0400443 log.Error("Failed to clear ONU ID resource pool")
444 return errors.New("Failed to clear ONU ID resource pool")
445 }
446 if SharedPoolID != 0 {
447 break
448 }
449 }
450
451 for _, Intf := range PONRMgr.IntfIDs {
452 SharedPoolID := PONRMgr.PonResourceRanges[ALLOC_ID_SHARED_IDX].(uint32)
453 if SharedPoolID != 0 {
454 Intf = SharedPoolID
455 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000456 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, ALLOC_ID); !status {
Devmalya Paul495b94a2019-08-27 19:42:00 -0400457 log.Error("Failed to clear ALLOC ID resource pool ")
458 return errors.New("Failed to clear ALLOC ID resource pool")
459 }
460 if SharedPoolID != 0 {
461 break
462 }
463 }
464 for _, Intf := range PONRMgr.IntfIDs {
465 SharedPoolID := PONRMgr.PonResourceRanges[GEMPORT_ID_SHARED_IDX].(uint32)
466 if SharedPoolID != 0 {
467 Intf = SharedPoolID
468 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000469 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, GEMPORT_ID); !status {
Devmalya Paul495b94a2019-08-27 19:42:00 -0400470 log.Error("Failed to clear GEMPORT ID resource pool")
471 return errors.New("Failed to clear GEMPORT ID resource pool")
472 }
473 if SharedPoolID != 0 {
474 break
475 }
476 }
477
478 for _, Intf := range PONRMgr.IntfIDs {
479 SharedPoolID := PONRMgr.PonResourceRanges[FLOW_ID_SHARED_IDX].(uint32)
480 if SharedPoolID != 0 {
481 Intf = SharedPoolID
482 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000483 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, FLOW_ID); !status {
Devmalya Paul495b94a2019-08-27 19:42:00 -0400484 log.Error("Failed to clear FLOW ID resource pool")
485 return errors.New("Failed to clear FLOW ID resource pool")
486 }
487 if SharedPoolID != 0 {
488 break
489 }
490 }
491 return nil
492}
493
npujarec5762e2020-01-01 14:08:48 +0530494func (PONRMgr *PONResourceManager) InitResourceIDPool(ctx context.Context, Intf uint32, ResourceType string, StartID uint32, EndID uint32) error {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400495
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400496 /*Initialize Resource ID pool for a given Resource Type on a given PON Port
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400497
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400498 :param pon_intf_id: OLT PON interface id
499 :param resource_type: String to identify type of resource
500 :param start_idx: start index for onu id pool
501 :param end_idx: end index for onu id pool
502 :return boolean: True if resource id pool initialized else false
503 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400504
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400505 // delegate to the master instance if sharing enabled across instances
506 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
507 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujarec5762e2020-01-01 14:08:48 +0530508 return SharedResourceMgr.InitResourceIDPool(ctx, Intf, ResourceType, StartID, EndID)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400509 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400510
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400511 Path := PONRMgr.GetPath(Intf, ResourceType)
512 if Path == "" {
513 log.Errorf("Failed to get path for resource type %s", ResourceType)
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000514 return fmt.Errorf("Failed to get path for resource type %s", ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400515 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400516
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400517 //In case of adapter reboot and reconciliation resource in kv store
518 //checked for its presence if not kv store update happens
npujarec5762e2020-01-01 14:08:48 +0530519 Res, err := PONRMgr.GetResource(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400520 if (err == nil) && (Res != nil) {
521 log.Debugf("Resource %s already present in store ", Path)
522 return nil
523 } else {
divyadesaid26f6b12020-03-19 06:30:28 +0000524 var excluded []uint32
525 if ResourceType == GEMPORT_ID {
526 //get gem port ids defined in the KV store, if any, and exclude them from the gem port id pool
527 if reservedGemPortIds, defined := PONRMgr.getReservedGemPortIdsFromKVStore(ctx); defined {
528 excluded = reservedGemPortIds
529 log.Debugw("Excluding some ports from GEM port id pool", log.Fields{"excluded gem ports": excluded})
530 }
531 }
532 FormatResult, err := PONRMgr.FormatResource(Intf, StartID, EndID, excluded)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400533 if err != nil {
534 log.Errorf("Failed to format resource")
535 return err
536 }
537 // Add resource as json in kv store.
npujarec5762e2020-01-01 14:08:48 +0530538 err = PONRMgr.KVStore.Put(ctx, Path, FormatResult)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400539 if err == nil {
540 log.Debug("Successfuly posted to kv store")
541 return err
542 }
543 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400544
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400545 log.Debug("Error initializing pool")
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400546
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400547 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400548}
549
divyadesaid26f6b12020-03-19 06:30:28 +0000550func (PONRMgr *PONResourceManager) getReservedGemPortIdsFromKVStore(ctx context.Context) ([]uint32, bool) {
551 var reservedGemPortIds []uint32
552 // read reserved gem ports from the config path
553 KvPair, err := PONRMgr.KVStoreForConfig.Get(ctx, RESERVED_GEMPORT_IDS_PATH)
554 if err != nil {
555 log.Errorw("Unable to get reserved GEM port ids from the kv store", log.Fields{"err": err})
556 return reservedGemPortIds, false
557 }
558 if KvPair == nil || KvPair.Value == nil {
559 //no reserved gem port defined in the store
560 return reservedGemPortIds, false
561 }
562 Val, err := kvstore.ToByte(KvPair.Value)
563 if err != nil {
564 log.Errorw("Failed to convert reserved gem port ids into byte array", log.Fields{"err": err})
565 return reservedGemPortIds, false
566 }
567 if err = json.Unmarshal(Val, &reservedGemPortIds); err != nil {
568 log.Errorw("Failed to unmarshal reservedGemPortIds", log.Fields{"err": err})
569 return reservedGemPortIds, false
570 }
571 return reservedGemPortIds, true
572}
573
574func (PONRMgr *PONResourceManager) FormatResource(IntfID uint32, StartIDx uint32, EndIDx uint32,
575 Excluded []uint32) ([]byte, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400576 /*
577 Format resource as json.
578 :param pon_intf_id: OLT PON interface id
579 :param start_idx: start index for id pool
580 :param end_idx: end index for id pool
divyadesaid26f6b12020-03-19 06:30:28 +0000581 :Id values to be Excluded from the pool
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400582 :return dictionary: resource formatted as map
583 */
584 // Format resource as json to be stored in backend store
585 Resource := make(map[string]interface{})
586 Resource[PON_INTF_ID] = IntfID
587 Resource[START_IDX] = StartIDx
588 Resource[END_IDX] = EndIDx
589 /*
590 Resource pool stored in backend store as binary string.
591 Tracking the resource allocation will be done by setting the bits \
592 in the byte array. The index set will be the resource number allocated.
593 */
594 var TSData *bitmap.Threadsafe
595 if TSData = bitmap.NewTS(int(EndIDx)); TSData == nil {
596 log.Error("Failed to create a bitmap")
597 return nil, errors.New("Failed to create bitmap")
598 }
divyadesaid26f6b12020-03-19 06:30:28 +0000599 for _, excludedID := range Excluded {
600 if excludedID < StartIDx || excludedID > EndIDx {
601 log.Warnf("Cannot reserve %d. It must be in the range of [%d, %d]", excludedID,
602 StartIDx, EndIDx)
603 continue
604 }
605 PONRMgr.reserveID(TSData, StartIDx, excludedID)
606 }
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400607 Resource[POOL] = TSData.Data(false) //we pass false so as the TSData lib api does not do a copy of the data and return
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400608
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400609 Value, err := json.Marshal(Resource)
610 if err != nil {
611 log.Errorf("Failed to marshall resource")
612 return nil, err
613 }
614 return Value, err
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400615}
npujarec5762e2020-01-01 14:08:48 +0530616func (PONRMgr *PONResourceManager) GetResource(ctx context.Context, Path string) (map[string]interface{}, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400617 /*
618 Get resource from kv store.
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400619
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400620 :param path: path to get resource
621 :return: resource if resource present in kv store else None
622 */
623 //get resource from kv store
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400624
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400625 var Value []byte
626 Result := make(map[string]interface{})
627 var Str string
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400628
npujarec5762e2020-01-01 14:08:48 +0530629 Resource, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400630 if (err != nil) || (Resource == nil) {
631 log.Debugf("Resource unavailable at %s", Path)
632 return nil, err
633 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400634
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400635 Value, err = ToByte(Resource.Value)
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000636 if err != nil {
637 return nil, err
638 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400639
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400640 // decode resource fetched from backend store to dictionary
641 err = json.Unmarshal(Value, &Result)
642 if err != nil {
643 log.Error("Failed to decode resource")
644 return Result, err
645 }
646 /*
647 resource pool in backend store stored as binary string whereas to
648 access the pool to generate/release IDs it need to be converted
649 as BitArray
650 */
651 Str, err = ToString(Result[POOL])
652 if err != nil {
653 log.Error("Failed to conver to kv pair to string")
654 return Result, err
655 }
656 Decode64, _ := base64.StdEncoding.DecodeString(Str)
657 Result[POOL], err = ToByte(Decode64)
658 if err != nil {
659 log.Error("Failed to convert resource pool to byte")
660 return Result, err
661 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400662
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400663 return Result, err
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400664}
665
666func (PONRMgr *PONResourceManager) GetPath(IntfID uint32, ResourceType string) string {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400667 /*
668 Get path for given resource type.
669 :param pon_intf_id: OLT PON interface id
670 :param resource_type: String to identify type of resource
671 :return: path for given resource type
672 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400673
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400674 /*
675 Get the shared pool for the given resource type.
676 all the resource ranges and the shared resource maps are initialized during the init.
677 */
678 SharedPoolID := PONRMgr.PonResourceRanges[PONRMgr.SharedIdxByType[ResourceType]].(uint32)
679 if SharedPoolID != 0 {
680 IntfID = SharedPoolID
681 }
682 var Path string
683 if ResourceType == ONU_ID {
684 Path = fmt.Sprintf(ONU_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
685 } else if ResourceType == ALLOC_ID {
686 Path = fmt.Sprintf(ALLOC_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
687 } else if ResourceType == GEMPORT_ID {
688 Path = fmt.Sprintf(GEMPORT_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
689 } else if ResourceType == FLOW_ID {
690 Path = fmt.Sprintf(FLOW_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
691 } else {
692 log.Error("Invalid resource pool identifier")
693 }
694 return Path
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400695}
696
npujarec5762e2020-01-01 14:08:48 +0530697func (PONRMgr *PONResourceManager) GetResourceID(ctx context.Context, IntfID uint32, ResourceType string, NumIDs uint32) ([]uint32, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400698 /*
699 Create alloc/gemport/onu/flow id for given OLT PON interface.
700 :param pon_intf_id: OLT PON interface id
701 :param resource_type: String to identify type of resource
702 :param num_of_id: required number of ids
703 :return list/uint32/None: list, uint32 or None if resource type is
704 alloc_id/gemport_id, onu_id or invalid type respectively
705 */
706 if NumIDs < 1 {
707 log.Error("Invalid number of resources requested")
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000708 return nil, fmt.Errorf("Invalid number of resources requested %d", NumIDs)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400709 }
710 // delegate to the master instance if sharing enabled across instances
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400711
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400712 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
713 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujarec5762e2020-01-01 14:08:48 +0530714 return SharedResourceMgr.GetResourceID(ctx, IntfID, ResourceType, NumIDs)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400715 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400716 log.Debugf("Fetching resource from %s rsrc mgr for resource %s", PONRMgr.Globalorlocal, ResourceType)
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400717
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400718 Path := PONRMgr.GetPath(IntfID, ResourceType)
719 if Path == "" {
720 log.Errorf("Failed to get path for resource type %s", ResourceType)
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000721 return nil, fmt.Errorf("Failed to get path for resource type %s", ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400722 }
723 log.Debugf("Get resource for type %s on path %s", ResourceType, Path)
724 var Result []uint32
725 var NextID uint32
npujarec5762e2020-01-01 14:08:48 +0530726 Resource, err := PONRMgr.GetResource(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400727 if (err == nil) && (ResourceType == ONU_ID) || (ResourceType == FLOW_ID) {
728 if NextID, err = PONRMgr.GenerateNextID(Resource); err != nil {
729 log.Error("Failed to Generate ID")
730 return Result, err
731 }
732 Result = append(Result, NextID)
733 } else if (err == nil) && ((ResourceType == GEMPORT_ID) || (ResourceType == ALLOC_ID)) {
734 if NumIDs == 1 {
735 if NextID, err = PONRMgr.GenerateNextID(Resource); err != nil {
736 log.Error("Failed to Generate ID")
737 return Result, err
738 }
739 Result = append(Result, NextID)
740 } else {
741 for NumIDs > 0 {
742 if NextID, err = PONRMgr.GenerateNextID(Resource); err != nil {
743 log.Error("Failed to Generate ID")
744 return Result, err
745 }
746 Result = append(Result, NextID)
747 NumIDs--
748 }
749 }
750 } else {
751 log.Error("get resource failed")
752 return Result, err
753 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400754
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400755 //Update resource in kv store
npujarec5762e2020-01-01 14:08:48 +0530756 if PONRMgr.UpdateResource(ctx, Path, Resource) != nil {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400757 log.Errorf("Failed to update resource %s", Path)
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000758 return nil, fmt.Errorf("Failed to update resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400759 }
760 return Result, nil
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400761}
762
763func checkValidResourceType(ResourceType string) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400764 KnownResourceTypes := []string{ONU_ID, ALLOC_ID, GEMPORT_ID, FLOW_ID}
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400765
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400766 for _, v := range KnownResourceTypes {
767 if v == ResourceType {
768 return true
769 }
770 }
771 return false
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400772}
773
npujarec5762e2020-01-01 14:08:48 +0530774func (PONRMgr *PONResourceManager) FreeResourceID(ctx context.Context, IntfID uint32, ResourceType string, ReleaseContent []uint32) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400775 /*
776 Release alloc/gemport/onu/flow id for given OLT PON interface.
777 :param pon_intf_id: OLT PON interface id
778 :param resource_type: String to identify type of resource
779 :param release_content: required number of ids
780 :return boolean: True if all IDs in given release_content release else False
781 */
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000782 if !checkValidResourceType(ResourceType) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400783 log.Error("Invalid resource type")
784 return false
785 }
786 if ReleaseContent == nil {
787 log.Debug("Nothing to release")
788 return true
789 }
790 // delegate to the master instance if sharing enabled across instances
791 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
792 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujarec5762e2020-01-01 14:08:48 +0530793 return SharedResourceMgr.FreeResourceID(ctx, IntfID, ResourceType, ReleaseContent)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400794 }
795 Path := PONRMgr.GetPath(IntfID, ResourceType)
796 if Path == "" {
797 log.Error("Failed to get path")
798 return false
799 }
npujarec5762e2020-01-01 14:08:48 +0530800 Resource, err := PONRMgr.GetResource(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400801 if err != nil {
802 log.Error("Failed to get resource")
803 return false
804 }
805 for _, Val := range ReleaseContent {
806 PONRMgr.ReleaseID(Resource, Val)
807 }
npujarec5762e2020-01-01 14:08:48 +0530808 if PONRMgr.UpdateResource(ctx, Path, Resource) != nil {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400809 log.Errorf("Free resource for %s failed", Path)
810 return false
811 }
812 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400813}
814
npujarec5762e2020-01-01 14:08:48 +0530815func (PONRMgr *PONResourceManager) UpdateResource(ctx context.Context, Path string, Resource map[string]interface{}) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400816 /*
817 Update resource in resource kv store.
818 :param path: path to update resource
819 :param resource: resource need to be updated
820 :return boolean: True if resource updated in kv store else False
821 */
822 // TODO resource[POOL] = resource[POOL].bin
823 Value, err := json.Marshal(Resource)
824 if err != nil {
825 log.Error("failed to Marshal")
826 return err
827 }
npujarec5762e2020-01-01 14:08:48 +0530828 err = PONRMgr.KVStore.Put(ctx, Path, Value)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400829 if err != nil {
830 log.Error("failed to put data to kv store %s", Path)
831 return err
832 }
833 return nil
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400834}
835
npujarec5762e2020-01-01 14:08:48 +0530836func (PONRMgr *PONResourceManager) ClearResourceIDPool(ctx context.Context, contIntfID uint32, ResourceType string) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400837 /*
838 Clear Resource Pool for a given Resource Type on a given PON Port.
839 :return boolean: True if removed else False
840 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400841
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400842 // delegate to the master instance if sharing enabled across instances
843 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
844 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujarec5762e2020-01-01 14:08:48 +0530845 return SharedResourceMgr.ClearResourceIDPool(ctx, contIntfID, ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400846 }
npujarec5762e2020-01-01 14:08:48 +0530847 Path := PONRMgr.GetPath(contIntfID, ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400848 if Path == "" {
849 log.Error("Failed to get path")
850 return false
851 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400852
npujarec5762e2020-01-01 14:08:48 +0530853 if err := PONRMgr.KVStore.Delete(ctx, Path); err != nil {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400854 log.Errorf("Failed to delete resource %s", Path)
855 return false
856 }
857 log.Debugf("Cleared resource %s", Path)
858 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400859}
860
npujarec5762e2020-01-01 14:08:48 +0530861func (PONRMgr PONResourceManager) InitResourceMap(ctx context.Context, PONIntfONUID string) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400862 /*
863 Initialize resource map
864 :param pon_intf_onu_id: reference of PON interface id and onu id
865 */
866 // initialize pon_intf_onu_id tuple to alloc_ids map
867 AllocIDPath := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
868 var AllocIDs []byte
npujarec5762e2020-01-01 14:08:48 +0530869 Result := PONRMgr.KVStore.Put(ctx, AllocIDPath, AllocIDs)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400870 if Result != nil {
871 log.Error("Failed to update the KV store")
872 return
873 }
874 // initialize pon_intf_onu_id tuple to gemport_ids map
875 GEMPortIDPath := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
876 var GEMPortIDs []byte
npujarec5762e2020-01-01 14:08:48 +0530877 Result = PONRMgr.KVStore.Put(ctx, GEMPortIDPath, GEMPortIDs)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400878 if Result != nil {
879 log.Error("Failed to update the KV store")
880 return
881 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400882}
883
npujarec5762e2020-01-01 14:08:48 +0530884func (PONRMgr PONResourceManager) RemoveResourceMap(ctx context.Context, PONIntfONUID string) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400885 /*
886 Remove resource map
887 :param pon_intf_onu_id: reference of PON interface id and onu id
888 */
889 // remove pon_intf_onu_id tuple to alloc_ids map
890 var err error
891 AllocIDPath := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujarec5762e2020-01-01 14:08:48 +0530892 if err = PONRMgr.KVStore.Delete(ctx, AllocIDPath); err != nil {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400893 log.Errorf("Failed to remove resource %s", AllocIDPath)
894 return false
895 }
896 // remove pon_intf_onu_id tuple to gemport_ids map
897 GEMPortIDPath := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujarec5762e2020-01-01 14:08:48 +0530898 err = PONRMgr.KVStore.Delete(ctx, GEMPortIDPath)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400899 if err != nil {
900 log.Errorf("Failed to remove resource %s", GEMPortIDPath)
901 return false
902 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400903
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400904 FlowIDPath := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujarec5762e2020-01-01 14:08:48 +0530905 if FlowIDs, err := PONRMgr.KVStore.List(ctx, FlowIDPath); err != nil {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400906 for _, Flow := range FlowIDs {
907 FlowIDInfoPath := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, PONIntfONUID, Flow.Value)
npujarec5762e2020-01-01 14:08:48 +0530908 if err = PONRMgr.KVStore.Delete(ctx, FlowIDInfoPath); err != nil {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400909 log.Errorf("Failed to remove resource %s", FlowIDInfoPath)
910 return false
911 }
912 }
913 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400914
npujarec5762e2020-01-01 14:08:48 +0530915 if err = PONRMgr.KVStore.Delete(ctx, FlowIDPath); err != nil {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400916 log.Errorf("Failed to remove resource %s", FlowIDPath)
917 return false
918 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400919
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400920 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400921}
922
npujarec5762e2020-01-01 14:08:48 +0530923func (PONRMgr *PONResourceManager) GetCurrentAllocIDForOnu(ctx context.Context, IntfONUID string) []uint32 {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400924 /*
925 Get currently configured alloc ids for given pon_intf_onu_id
926 :param pon_intf_onu_id: reference of PON interface id and onu id
927 :return list: List of alloc_ids if available, else None
928 */
929 Path := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400930
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400931 var Data []uint32
npujarec5762e2020-01-01 14:08:48 +0530932 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400933 if err == nil {
934 if Value != nil {
935 Val, err := ToByte(Value.Value)
936 if err != nil {
937 log.Errorw("Failed to convert into byte array", log.Fields{"error": err})
938 return Data
939 }
940 if err = json.Unmarshal(Val, &Data); err != nil {
941 log.Error("Failed to unmarshal", log.Fields{"error": err})
942 return Data
943 }
944 }
945 }
946 return Data
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400947}
948
npujarec5762e2020-01-01 14:08:48 +0530949func (PONRMgr *PONResourceManager) GetCurrentGEMPortIDsForOnu(ctx context.Context, IntfONUID string) []uint32 {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400950 /*
951 Get currently configured gemport ids for given pon_intf_onu_id
952 :param pon_intf_onu_id: reference of PON interface id and onu id
953 :return list: List of gemport IDs if available, else None
954 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400955
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400956 Path := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
957 log.Debugf("Getting current gemports for %s", Path)
958 var Data []uint32
npujarec5762e2020-01-01 14:08:48 +0530959 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400960 if err == nil {
961 if Value != nil {
962 Val, _ := ToByte(Value.Value)
963 if err = json.Unmarshal(Val, &Data); err != nil {
964 log.Errorw("Failed to unmarshal", log.Fields{"error": err})
965 return Data
966 }
967 }
968 } else {
969 log.Errorf("Failed to get data from kvstore for %s", Path)
970 }
971 return Data
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400972}
973
npujarec5762e2020-01-01 14:08:48 +0530974func (PONRMgr *PONResourceManager) GetCurrentFlowIDsForOnu(ctx context.Context, IntfONUID string) []uint32 {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400975 /*
976 Get currently configured flow ids for given pon_intf_onu_id
977 :param pon_intf_onu_id: reference of PON interface id and onu id
978 :return list: List of Flow IDs if available, else None
979 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400980
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400981 Path := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400982
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400983 var Data []uint32
npujarec5762e2020-01-01 14:08:48 +0530984 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400985 if err == nil {
986 if Value != nil {
987 Val, _ := ToByte(Value.Value)
988 if err = json.Unmarshal(Val, &Data); err != nil {
989 log.Error("Failed to unmarshal")
990 return Data
991 }
992 }
993 }
994 return Data
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400995}
996
npujarec5762e2020-01-01 14:08:48 +0530997func (PONRMgr *PONResourceManager) GetFlowIDInfo(ctx context.Context, IntfONUID string, FlowID uint32, Data interface{}) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400998 /*
999 Get flow details configured for the ONU.
1000 :param pon_intf_onu_id: reference of PON interface id and onu id
1001 :param flow_id: Flow Id reference
1002 :param Data: Result
1003 :return error: nil if no error in getting from KV store
1004 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001005
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001006 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001007
npujarec5762e2020-01-01 14:08:48 +05301008 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001009 if err == nil {
1010 if Value != nil {
1011 Val, err := ToByte(Value.Value)
1012 if err != nil {
1013 log.Errorw("Failed to convert flowinfo into byte array", log.Fields{"error": err})
1014 return err
1015 }
1016 if err = json.Unmarshal(Val, Data); err != nil {
1017 log.Errorw("Failed to unmarshal", log.Fields{"error": err})
1018 return err
1019 }
1020 }
1021 }
1022 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001023}
1024
npujarec5762e2020-01-01 14:08:48 +05301025func (PONRMgr *PONResourceManager) RemoveFlowIDInfo(ctx context.Context, IntfONUID string, FlowID uint32) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001026 /*
1027 Get flow_id details configured for the ONU.
1028 :param pon_intf_onu_id: reference of PON interface id and onu id
1029 :param flow_id: Flow Id reference
1030 */
1031 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001032
npujarec5762e2020-01-01 14:08:48 +05301033 if err := PONRMgr.KVStore.Delete(ctx, Path); err != nil {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001034 log.Errorf("Falied to remove resource %s", Path)
1035 return false
1036 }
1037 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001038}
1039
npujarec5762e2020-01-01 14:08:48 +05301040func (PONRMgr *PONResourceManager) UpdateAllocIdsForOnu(ctx context.Context, IntfONUID string, AllocIDs []uint32) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001041 /*
1042 Update currently configured alloc ids for given pon_intf_onu_id
1043 :param pon_intf_onu_id: reference of PON interface id and onu id
1044 :param alloc_ids: list of alloc ids
1045 */
1046 var Value []byte
1047 var err error
1048 Path := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
1049 Value, err = json.Marshal(AllocIDs)
1050 if err != nil {
1051 log.Error("failed to Marshal")
1052 return err
1053 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001054
npujarec5762e2020-01-01 14:08:48 +05301055 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001056 log.Errorf("Failed to update resource %s", Path)
1057 return err
1058 }
1059 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001060}
1061
npujarec5762e2020-01-01 14:08:48 +05301062func (PONRMgr *PONResourceManager) UpdateGEMPortIDsForOnu(ctx context.Context, IntfONUID string, GEMPortIDs []uint32) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001063 /*
1064 Update currently configured gemport ids for given pon_intf_onu_id
1065 :param pon_intf_onu_id: reference of PON interface id and onu id
1066 :param gemport_ids: list of gem port ids
1067 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001068
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001069 var Value []byte
1070 var err error
1071 Path := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
1072 log.Debugf("Updating gemport ids for %s", Path)
1073 Value, err = json.Marshal(GEMPortIDs)
1074 if err != nil {
1075 log.Error("failed to Marshal")
1076 return err
1077 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001078
npujarec5762e2020-01-01 14:08:48 +05301079 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001080 log.Errorf("Failed to update resource %s", Path)
1081 return err
1082 }
1083 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001084}
1085
1086func checkForFlowIDInList(FlowIDList []uint32, FlowID uint32) (bool, uint32) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001087 /*
1088 Check for a flow id in a given list of flow IDs.
1089 :param FLowIDList: List of Flow IDs
1090 :param FlowID: Flowd to check in the list
1091 : return true and the index if present false otherwise.
1092 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001093
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001094 for idx := range FlowIDList {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001095 if FlowID == FlowIDList[idx] {
1096 return true, uint32(idx)
1097 }
1098 }
1099 return false, 0
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001100}
1101
npujarec5762e2020-01-01 14:08:48 +05301102func (PONRMgr *PONResourceManager) UpdateFlowIDForOnu(ctx context.Context, IntfONUID string, FlowID uint32, Add bool) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001103 /*
1104 Update the flow_id list of the ONU (add or remove flow_id from the list)
1105 :param pon_intf_onu_id: reference of PON interface id and onu id
1106 :param flow_id: flow ID
1107 :param add: Boolean flag to indicate whether the flow_id should be
1108 added or removed from the list. Defaults to adding the flow.
1109 */
1110 var Value []byte
1111 var err error
1112 var RetVal bool
1113 var IDx uint32
1114 Path := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
npujarec5762e2020-01-01 14:08:48 +05301115 FlowIDs := PONRMgr.GetCurrentFlowIDsForOnu(ctx, IntfONUID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001116
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001117 if Add {
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001118 if RetVal, _ = checkForFlowIDInList(FlowIDs, FlowID); RetVal {
1119 return nil
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001120 }
1121 FlowIDs = append(FlowIDs, FlowID)
1122 } else {
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001123 if RetVal, IDx = checkForFlowIDInList(FlowIDs, FlowID); !RetVal {
1124 return nil
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001125 }
1126 // delete the index and shift
1127 FlowIDs = append(FlowIDs[:IDx], FlowIDs[IDx+1:]...)
1128 }
1129 Value, err = json.Marshal(FlowIDs)
1130 if err != nil {
1131 log.Error("Failed to Marshal")
1132 return err
1133 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001134
npujarec5762e2020-01-01 14:08:48 +05301135 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001136 log.Errorf("Failed to update resource %s", Path)
1137 return err
1138 }
1139 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001140}
1141
npujarec5762e2020-01-01 14:08:48 +05301142func (PONRMgr *PONResourceManager) UpdateFlowIDInfoForOnu(ctx context.Context, IntfONUID string, FlowID uint32, FlowData interface{}) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001143 /*
1144 Update any metadata associated with the flow_id. The flow_data could be json
1145 or any of other data structure. The resource manager doesnt care
1146 :param pon_intf_onu_id: reference of PON interface id and onu id
1147 :param flow_id: Flow ID
1148 :param flow_data: Flow data blob
1149 */
1150 var Value []byte
1151 var err error
1152 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
1153 Value, err = json.Marshal(FlowData)
1154 if err != nil {
1155 log.Error("failed to Marshal")
1156 return err
1157 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001158
npujarec5762e2020-01-01 14:08:48 +05301159 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001160 log.Errorf("Failed to update resource %s", Path)
1161 return err
1162 }
1163 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001164}
1165
1166func (PONRMgr *PONResourceManager) GenerateNextID(Resource map[string]interface{}) (uint32, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001167 /*
1168 Generate unique id having OFFSET as start
1169 :param resource: resource used to generate ID
1170 :return uint32: generated id
1171 */
1172 ByteArray, err := ToByte(Resource[POOL])
1173 if err != nil {
1174 log.Error("Failed to convert resource to byte array")
1175 return 0, err
1176 }
1177 Data := bitmap.TSFromData(ByteArray, false)
1178 if Data == nil {
1179 log.Error("Failed to get data from byte array")
1180 return 0, errors.New("Failed to get data from byte array")
1181 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001182
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001183 Len := Data.Len()
1184 var Idx int
1185 for Idx = 0; Idx < Len; Idx++ {
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001186 if !Data.Get(Idx) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001187 break
1188 }
1189 }
1190 Data.Set(Idx, true)
1191 res := uint32(Resource[START_IDX].(float64))
1192 Resource[POOL] = Data.Data(false)
1193 log.Debugf("Generated ID for %d", (uint32(Idx) + res))
1194 return (uint32(Idx) + res), err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001195}
1196
1197func (PONRMgr *PONResourceManager) ReleaseID(Resource map[string]interface{}, Id uint32) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001198 /*
1199 Release unique id having OFFSET as start index.
1200 :param resource: resource used to release ID
1201 :param unique_id: id need to be released
1202 */
1203 ByteArray, err := ToByte(Resource[POOL])
1204 if err != nil {
1205 log.Error("Failed to convert resource to byte array")
1206 return false
1207 }
1208 Data := bitmap.TSFromData(ByteArray, false)
1209 if Data == nil {
1210 log.Error("Failed to get resource pool")
1211 return false
1212 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001213 Idx := Id - uint32(Resource[START_IDX].(float64))
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001214 Data.Set(int(Idx), false)
1215 Resource[POOL] = Data.Data(false)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001216
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001217 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001218}
1219
divyadesaid26f6b12020-03-19 06:30:28 +00001220/* Reserves a unique id in the specified resource pool.
1221:param Resource: resource used to reserve ID
1222:param Id: ID to be reserved
1223*/
1224func (PONRMgr *PONResourceManager) reserveID(TSData *bitmap.Threadsafe, StartIndex uint32, Id uint32) bool {
1225 Data := bitmap.TSFromData(TSData.Data(false), false)
1226 if Data == nil {
1227 log.Error("Failed to get resource pool")
1228 return false
1229 }
1230 Idx := Id - StartIndex
1231 Data.Set(int(Idx), true)
1232 return true
1233}
1234
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001235func (PONRMgr *PONResourceManager) GetTechnology() string {
1236 return PONRMgr.Technology
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001237}
1238
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001239func (PONRMgr *PONResourceManager) GetResourceTypeAllocID() string {
1240 return ALLOC_ID
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001241}
1242
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001243func (PONRMgr *PONResourceManager) GetResourceTypeGemPortID() string {
1244 return GEMPORT_ID
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001245}
1246
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001247// ToByte converts an interface value to a []byte. The interface should either be of
1248// a string type or []byte. Otherwise, an error is returned.
1249func ToByte(value interface{}) ([]byte, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001250 switch t := value.(type) {
1251 case []byte:
1252 return value.([]byte), nil
1253 case string:
1254 return []byte(value.(string)), nil
1255 default:
1256 return nil, fmt.Errorf("unexpected-type-%T", t)
1257 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001258}
1259
1260// ToString converts an interface value to a string. The interface should either be of
1261// a string type or []byte. Otherwise, an error is returned.
1262func ToString(value interface{}) (string, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001263 switch t := value.(type) {
1264 case []byte:
1265 return string(value.([]byte)), nil
1266 case string:
1267 return value.(string), nil
1268 default:
1269 return "", fmt.Errorf("unexpected-type-%T", t)
1270 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001271}
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001272
npujarec5762e2020-01-01 14:08:48 +05301273func (PONRMgr *PONResourceManager) AddOnuGemInfo(ctx context.Context, intfID uint32, onuGemData interface{}) error {
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001274 /*
1275 Update onugem info map,
1276 :param pon_intf_id: reference of PON interface id
1277 :param onuegmdata: onugem info map
1278 */
1279 var Value []byte
1280 var err error
1281 Path := fmt.Sprintf(ONU_GEM_INFO_PATH, PONRMgr.DeviceID, intfID)
1282 Value, err = json.Marshal(onuGemData)
1283 if err != nil {
1284 log.Error("failed to Marshal")
1285 return err
1286 }
1287
npujarec5762e2020-01-01 14:08:48 +05301288 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001289 log.Errorf("Failed to update resource %s", Path)
1290 return err
1291 }
1292 return err
1293}
1294
npujarec5762e2020-01-01 14:08:48 +05301295func (PONRMgr *PONResourceManager) GetOnuGemInfo(ctx context.Context, IntfId uint32, onuGemInfo interface{}) error {
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001296 /*
1297 Get onugeminfo map from kvstore
1298 :param intfid: refremce pon intfid
1299 :param onuGemInfo: onugem info to return from kv strore.
1300 */
1301 var Val []byte
1302
1303 path := fmt.Sprintf(ONU_GEM_INFO_PATH, PONRMgr.DeviceID, IntfId)
npujarec5762e2020-01-01 14:08:48 +05301304 value, err := PONRMgr.KVStore.Get(ctx, path)
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001305 if err != nil {
1306 log.Errorw("Failed to get from kv store", log.Fields{"path": path})
1307 return err
1308 } else if value == nil {
1309 log.Debug("No onuinfo for path", log.Fields{"path": path})
1310 return nil // returning nil as this could happen if there are no onus for the interface yet
1311 }
1312 if Val, err = kvstore.ToByte(value.Value); err != nil {
1313 log.Error("Failed to convert to byte array")
1314 return err
1315 }
1316
1317 if err = json.Unmarshal(Val, &onuGemInfo); err != nil {
1318 log.Error("Failed to unmarshall")
1319 return err
1320 }
1321 log.Debugw("found onuinfo from path", log.Fields{"path": path, "onuinfo": onuGemInfo})
1322 return err
1323}
1324
npujarec5762e2020-01-01 14:08:48 +05301325func (PONRMgr *PONResourceManager) DelOnuGemInfoForIntf(ctx context.Context, intfId uint32) error {
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001326 /*
1327 delete onugem info for an interface from kvstore
1328 :param intfid: refremce pon intfid
1329 */
1330
1331 path := fmt.Sprintf(ONU_GEM_INFO_PATH, PONRMgr.DeviceID, intfId)
npujarec5762e2020-01-01 14:08:48 +05301332 if err := PONRMgr.KVStore.Delete(ctx, path); err != nil {
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001333 log.Errorf("Falied to remove resource %s", path)
1334 return err
1335 }
1336 return nil
1337}