blob: 415ce217b2f7d71996920097137fba80f3e5a2da [file] [log] [blame]
Scott Baker2c1c4822019-10-16 11:02:41 -07001/*
2 * Copyright 2019-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package ponresourcemanager
18
19import (
npujar5bf737f2020-01-16 19:35:25 +053020 "context"
Scott Baker2c1c4822019-10-16 11:02:41 -070021 "encoding/base64"
22 "encoding/json"
23 "errors"
24 "fmt"
Neha Sharma130ac6d2020-04-08 08:46:32 +000025 "time"
Scott Baker2c1c4822019-10-16 11:02:41 -070026
serkant.uluderyab38671c2019-11-01 09:35:38 -070027 bitmap "github.com/boljen/go-bitmap"
Girish Gowdra89c985b2020-10-14 15:02:09 -070028 "github.com/opencord/voltha-lib-go/v4/pkg/db"
29 "github.com/opencord/voltha-lib-go/v4/pkg/db/kvstore"
30 "github.com/opencord/voltha-lib-go/v4/pkg/log"
31 tp "github.com/opencord/voltha-lib-go/v4/pkg/techprofile"
Scott Baker2c1c4822019-10-16 11:02:41 -070032)
33
34const (
35 //Constants to identify resource pool
36 UNI_ID = "UNI_ID"
37 ONU_ID = "ONU_ID"
38 ALLOC_ID = "ALLOC_ID"
39 GEMPORT_ID = "GEMPORT_ID"
40 FLOW_ID = "FLOW_ID"
41
42 //Constants for passing command line arugments
43 OLT_MODEL_ARG = "--olt_model"
Matteo Scandolo29ff79c2020-11-06 13:03:17 -080044
45 PATH_PREFIX = "%s/resource_manager/{%s}"
Esin Karaman5351fc52020-02-14 07:45:49 +000046
47 /*The path under which configuration data is stored is defined as technology/device agnostic.
48 That means the path does not include any specific technology/device variable. Using technology/device
49 agnostic path also makes northbound applications, that need to write to this path,
50 technology/device agnostic.
51
52 Default kv client of PonResourceManager reads from/writes to PATH_PREFIX defined above.
53 That is why, an additional kv client (named KVStoreForConfig) is defined to read from the config path.
54 */
Matteo Scandolo29ff79c2020-11-06 13:03:17 -080055
56 PATH_PREFIX_FOR_CONFIG = "%s/resource_manager/config"
Scott Baker2c1c4822019-10-16 11:02:41 -070057 /*The resource ranges for a given device model should be placed
58 at 'resource_manager/<technology>/resource_ranges/<olt_model_type>'
59 path on the KV store.
60 If Resource Range parameters are to be read from the external KV store,
61 they are expected to be stored in the following format.
62 Note: All parameters are MANDATORY for now.
63 constants used as keys to reference the resource range parameters from
64 and external KV store.
65 */
66 UNI_ID_START_IDX = "uni_id_start"
67 UNI_ID_END_IDX = "uni_id_end"
68 ONU_ID_START_IDX = "onu_id_start"
69 ONU_ID_END_IDX = "onu_id_end"
70 ONU_ID_SHARED_IDX = "onu_id_shared"
71 ALLOC_ID_START_IDX = "alloc_id_start"
72 ALLOC_ID_END_IDX = "alloc_id_end"
73 ALLOC_ID_SHARED_IDX = "alloc_id_shared"
74 GEMPORT_ID_START_IDX = "gemport_id_start"
75 GEMPORT_ID_END_IDX = "gemport_id_end"
76 GEMPORT_ID_SHARED_IDX = "gemport_id_shared"
77 FLOW_ID_START_IDX = "flow_id_start"
78 FLOW_ID_END_IDX = "flow_id_end"
79 FLOW_ID_SHARED_IDX = "flow_id_shared"
80 NUM_OF_PON_PORT = "pon_ports"
81
82 /*
83 The KV store backend is initialized with a path prefix and we need to
84 provide only the suffix.
85 */
86 PON_RESOURCE_RANGE_CONFIG_PATH = "resource_ranges/%s"
87
88 //resource path suffix
89 //Path on the KV store for storing alloc id ranges and resource pool for a given interface
90 //Format: <device_id>/alloc_id_pool/<pon_intf_id>
91 ALLOC_ID_POOL_PATH = "{%s}/alloc_id_pool/{%d}"
92 //Path on the KV store for storing gemport id ranges and resource pool for a given interface
93 //Format: <device_id>/gemport_id_pool/<pon_intf_id>
94 GEMPORT_ID_POOL_PATH = "{%s}/gemport_id_pool/{%d}"
95 //Path on the KV store for storing onu id ranges and resource pool for a given interface
96 //Format: <device_id>/onu_id_pool/<pon_intf_id>
97 ONU_ID_POOL_PATH = "{%s}/onu_id_pool/{%d}"
98 //Path on the KV store for storing flow id ranges and resource pool for a given interface
99 //Format: <device_id>/flow_id_pool/<pon_intf_id>
100 FLOW_ID_POOL_PATH = "{%s}/flow_id_pool/{%d}"
101
102 //Path on the KV store for storing list of alloc IDs for a given ONU
103 //Format: <device_id>/<(pon_intf_id, onu_id)>/alloc_ids
104 ALLOC_ID_RESOURCE_MAP_PATH = "{%s}/{%s}/alloc_ids"
105
106 //Path on the KV store for storing list of gemport IDs for a given ONU
107 //Format: <device_id>/<(pon_intf_id, onu_id)>/gemport_ids
108 GEMPORT_ID_RESOURCE_MAP_PATH = "{%s}/{%s}/gemport_ids"
109
110 //Path on the KV store for storing list of Flow IDs for a given ONU
111 //Format: <device_id>/<(pon_intf_id, onu_id)>/flow_ids
112 FLOW_ID_RESOURCE_MAP_PATH = "{%s}/{%s}/flow_ids"
113
114 //Flow Id info: Use to store more metadata associated with the flow_id
Serkant Uluderya198de902020-11-16 20:29:17 +0300115 FLOW_ID_INFO_PATH_PREFIX = "{%s}/flow_id_info"
116 //Format: <device_id>/flow_id_info/<(pon_intf_id, onu_id)>
117 FLOW_ID_INFO_PATH_INTF_ONU_PREFIX = "{%s}/flow_id_info/{%s}"
118 //Format: <device_id>/flow_id_info/<(pon_intf_id, onu_id)><flow_id>
119 FLOW_ID_INFO_PATH = FLOW_ID_INFO_PATH_PREFIX + "/{%s}/{%d}"
Scott Baker2c1c4822019-10-16 11:02:41 -0700120
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +0530121 //path on the kvstore to store onugem info map
122 //format: <device-id>/onu_gem_info/<intfid>
123 ONU_GEM_INFO_PATH = "{%s}/onu_gem_info/{%d}" // onu_gem/<(intfid)>
124
Scott Baker2c1c4822019-10-16 11:02:41 -0700125 //Constants for internal usage.
126 PON_INTF_ID = "pon_intf_id"
127 START_IDX = "start_idx"
128 END_IDX = "end_idx"
129 POOL = "pool"
130 NUM_OF_PON_INTF = 16
131
Neha Sharma130ac6d2020-04-08 08:46:32 +0000132 KVSTORE_RETRY_TIMEOUT = 5 * time.Second
Esin Karaman5351fc52020-02-14 07:45:49 +0000133 //Path on the KV store for storing reserved gem ports
134 //Format: reserved_gemport_ids
135 RESERVED_GEMPORT_IDS_PATH = "reserved_gemport_ids"
Scott Baker2c1c4822019-10-16 11:02:41 -0700136)
137
138//type ResourceTypeIndex string
139//type ResourceType string
140
141type PONResourceManager struct {
142 //Implements APIs to initialize/allocate/release alloc/gemport/onu IDs.
Esin Karaman5351fc52020-02-14 07:45:49 +0000143 Technology string
144 DeviceType string
145 DeviceID string
serkant.uluderya2f2855e2021-01-30 12:43:40 +0300146 Backend string // ETCD only currently
Neha Sharmadd9af392020-04-28 09:03:57 +0000147 Address string // address of the KV store
Esin Karaman5351fc52020-02-14 07:45:49 +0000148 OLTModel string
149 KVStore *db.Backend
150 KVStoreForConfig *db.Backend
151 TechProfileMgr tp.TechProfileIf // create object of *tp.TechProfileMgr
Scott Baker2c1c4822019-10-16 11:02:41 -0700152
153 // Below attribute, pon_resource_ranges, should be initialized
154 // by reading from KV store.
155 PonResourceRanges map[string]interface{}
156 SharedResourceMgrs map[string]*PONResourceManager
157 SharedIdxByType map[string]string
158 IntfIDs []uint32 // list of pon interface IDs
159 Globalorlocal string
160}
161
Neha Sharma94f16a92020-06-26 04:17:55 +0000162func newKVClient(ctx context.Context, storeType string, address string, timeout time.Duration) (kvstore.Client, error) {
163 logger.Infow(ctx, "kv-store-type", log.Fields{"store": storeType})
Scott Baker2c1c4822019-10-16 11:02:41 -0700164 switch storeType {
Scott Baker2c1c4822019-10-16 11:02:41 -0700165 case "etcd":
Neha Sharma94f16a92020-06-26 04:17:55 +0000166 return kvstore.NewEtcdClient(ctx, address, timeout, log.WarnLevel)
Scott Baker2c1c4822019-10-16 11:02:41 -0700167 }
168 return nil, errors.New("unsupported-kv-store")
169}
170
Matteo Scandolo29ff79c2020-11-06 13:03:17 -0800171func SetKVClient(ctx context.Context, Technology string, Backend string, Addr string, configClient bool, basePathKvStore string) *db.Backend {
Scott Baker2c1c4822019-10-16 11:02:41 -0700172 // 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
Neha Sharma94f16a92020-06-26 04:17:55 +0000174 kvClient, err := newKVClient(ctx, Backend, Addr, KVSTORE_RETRY_TIMEOUT)
Scott Baker2c1c4822019-10-16 11:02:41 -0700175 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000176 logger.Fatalw(ctx, "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 {
Matteo Scandolo29ff79c2020-11-06 13:03:17 -0800182 pathPrefix = fmt.Sprintf(PATH_PREFIX_FOR_CONFIG, basePathKvStore)
Esin Karaman5351fc52020-02-14 07:45:49 +0000183 } else {
Matteo Scandolo29ff79c2020-11-06 13:03:17 -0800184 pathPrefix = fmt.Sprintf(PATH_PREFIX, basePathKvStore, Technology)
Esin Karaman5351fc52020-02-14 07:45:49 +0000185 }
186
sbarbari1e3e29c2019-11-05 10:06:50 -0500187 kvbackend := &db.Backend{
Scott Baker2c1c4822019-10-16 11:02:41 -0700188 Client: kvClient,
189 StoreType: Backend,
Neha Sharmadd9af392020-04-28 09:03:57 +0000190 Address: Addr,
Scott Baker2c1c4822019-10-16 11:02:41 -0700191 Timeout: KVSTORE_RETRY_TIMEOUT,
Esin Karaman5351fc52020-02-14 07:45:49 +0000192 PathPrefix: pathPrefix}
Scott Baker2c1c4822019-10-16 11:02:41 -0700193
194 return kvbackend
195}
196
197// NewPONResourceManager creates a new PON resource manager.
Matteo Scandolo29ff79c2020-11-06 13:03:17 -0800198func NewPONResourceManager(ctx context.Context, Technology string, DeviceType string, DeviceID string, Backend string, Address string, basePathKvStore string) (*PONResourceManager, error) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700199 var PONMgr PONResourceManager
200 PONMgr.Technology = Technology
201 PONMgr.DeviceType = DeviceType
202 PONMgr.DeviceID = DeviceID
203 PONMgr.Backend = Backend
Neha Sharmadd9af392020-04-28 09:03:57 +0000204 PONMgr.Address = Address
Matteo Scandolo29ff79c2020-11-06 13:03:17 -0800205 PONMgr.KVStore = SetKVClient(ctx, Technology, Backend, Address, false, basePathKvStore)
Scott Baker2c1c4822019-10-16 11:02:41 -0700206 if PONMgr.KVStore == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000207 logger.Error(ctx, "KV Client initilization failed")
Scott Baker2c1c4822019-10-16 11:02:41 -0700208 return nil, errors.New("Failed to init KV client")
209 }
Esin Karaman5351fc52020-02-14 07:45:49 +0000210 // init kv client to read from the config path
Matteo Scandolo29ff79c2020-11-06 13:03:17 -0800211 PONMgr.KVStoreForConfig = SetKVClient(ctx, Technology, Backend, Address, true, basePathKvStore)
Esin Karaman5351fc52020-02-14 07:45:49 +0000212 if PONMgr.KVStoreForConfig == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000213 logger.Error(ctx, "KV Config Client initilization failed")
Esin Karaman5351fc52020-02-14 07:45:49 +0000214 return nil, errors.New("Failed to init KV Config client")
215 }
Scott Baker2c1c4822019-10-16 11:02:41 -0700216 // Initialize techprofile for this technology
Matteo Scandolo866ac582020-11-09 12:18:31 -0800217 if PONMgr.TechProfileMgr, _ = tp.NewTechProfile(ctx, &PONMgr, Backend, Address, basePathKvStore); PONMgr.TechProfileMgr == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000218 logger.Error(ctx, "Techprofile initialization failed")
Scott Baker2c1c4822019-10-16 11:02:41 -0700219 return nil, errors.New("Failed to init tech profile")
220 }
221 PONMgr.PonResourceRanges = make(map[string]interface{})
222 PONMgr.SharedResourceMgrs = make(map[string]*PONResourceManager)
223 PONMgr.SharedIdxByType = make(map[string]string)
224 PONMgr.SharedIdxByType[ONU_ID] = ONU_ID_SHARED_IDX
225 PONMgr.SharedIdxByType[ALLOC_ID] = ALLOC_ID_SHARED_IDX
226 PONMgr.SharedIdxByType[GEMPORT_ID] = GEMPORT_ID_SHARED_IDX
227 PONMgr.SharedIdxByType[FLOW_ID] = FLOW_ID_SHARED_IDX
228 PONMgr.IntfIDs = make([]uint32, NUM_OF_PON_INTF)
229 PONMgr.OLTModel = DeviceType
230 return &PONMgr, nil
231}
232
233/*
234 Initialize PON resource ranges with config fetched from kv store.
235 return boolean: True if PON resource ranges initialized else false
236 Try to initialize the PON Resource Ranges from KV store based on the
237 OLT model key, if available
238*/
239
npujar5bf737f2020-01-16 19:35:25 +0530240func (PONRMgr *PONResourceManager) InitResourceRangesFromKVStore(ctx context.Context) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -0700241 //Initialize PON resource ranges with config fetched from kv store.
242 //:return boolean: True if PON resource ranges initialized else false
243 // Try to initialize the PON Resource Ranges from KV store based on the
244 // OLT model key, if available
245 if PONRMgr.OLTModel == "" {
Neha Sharma94f16a92020-06-26 04:17:55 +0000246 logger.Error(ctx, "Failed to get OLT model")
Scott Baker2c1c4822019-10-16 11:02:41 -0700247 return false
248 }
249 Path := fmt.Sprintf(PON_RESOURCE_RANGE_CONFIG_PATH, PONRMgr.OLTModel)
250 //get resource from kv store
npujar5bf737f2020-01-16 19:35:25 +0530251 Result, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700252 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000253 logger.Debugf(ctx, "Error in fetching resource %s from KV strore", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700254 return false
255 }
256 if Result == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000257 logger.Debug(ctx, "There may be no resources in the KV store in case of fresh bootup, return true")
Scott Baker2c1c4822019-10-16 11:02:41 -0700258 return false
259 }
260 //update internal ranges from kv ranges. If there are missing
261 // values in the KV profile, continue to use the defaults
262 Value, err := ToByte(Result.Value)
263 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000264 logger.Error(ctx, "Failed to convert kvpair to byte string")
Scott Baker2c1c4822019-10-16 11:02:41 -0700265 return false
266 }
267 if err := json.Unmarshal(Value, &PONRMgr.PonResourceRanges); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000268 logger.Error(ctx, "Failed to Unmarshal json byte")
Scott Baker2c1c4822019-10-16 11:02:41 -0700269 return false
270 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000271 logger.Debug(ctx, "Init resource ranges from kvstore success")
Scott Baker2c1c4822019-10-16 11:02:41 -0700272 return true
273}
274
Neha Sharma94f16a92020-06-26 04:17:55 +0000275func (PONRMgr *PONResourceManager) UpdateRanges(ctx context.Context, StartIDx string, StartID uint32, EndIDx string, EndID uint32,
Scott Baker2c1c4822019-10-16 11:02:41 -0700276 SharedIDx string, SharedPoolID uint32, RMgr *PONResourceManager) {
277 /*
278 Update the ranges for all reosurce type in the intermnal maps
279 param: resource type start index
280 param: start ID
281 param: resource type end index
282 param: end ID
283 param: resource type shared index
284 param: shared pool id
285 param: global resource manager
286 */
Neha Sharma94f16a92020-06-26 04:17:55 +0000287 logger.Debugf(ctx, "update ranges for %s, %d", StartIDx, StartID)
Scott Baker2c1c4822019-10-16 11:02:41 -0700288
289 if StartID != 0 {
290 if (PONRMgr.PonResourceRanges[StartIDx] == nil) || (PONRMgr.PonResourceRanges[StartIDx].(uint32) < StartID) {
291 PONRMgr.PonResourceRanges[StartIDx] = StartID
292 }
293 }
294 if EndID != 0 {
295 if (PONRMgr.PonResourceRanges[EndIDx] == nil) || (PONRMgr.PonResourceRanges[EndIDx].(uint32) > EndID) {
296 PONRMgr.PonResourceRanges[EndIDx] = EndID
297 }
298 }
299 //if SharedPoolID != 0 {
300 PONRMgr.PonResourceRanges[SharedIDx] = SharedPoolID
301 //}
302 if RMgr != nil {
303 PONRMgr.SharedResourceMgrs[SharedIDx] = RMgr
304 }
305}
306
Neha Sharma94f16a92020-06-26 04:17:55 +0000307func (PONRMgr *PONResourceManager) InitDefaultPONResourceRanges(ctx context.Context,
308 ONUIDStart uint32,
Scott Baker2c1c4822019-10-16 11:02:41 -0700309 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 {
324
325 /*Initialize default PON resource ranges
326
327 :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 */
Neha Sharma94f16a92020-06-26 04:17:55 +0000342 PONRMgr.UpdateRanges(ctx, ONU_ID_START_IDX, ONUIDStart, ONU_ID_END_IDX, ONUIDEnd, ONU_ID_SHARED_IDX, ONUIDSharedPoolID, nil)
343 PONRMgr.UpdateRanges(ctx, ALLOC_ID_START_IDX, AllocIDStart, ALLOC_ID_END_IDX, AllocIDEnd, ALLOC_ID_SHARED_IDX, AllocIDSharedPoolID, nil)
344 PONRMgr.UpdateRanges(ctx, GEMPORT_ID_START_IDX, GEMPortIDStart, GEMPORT_ID_END_IDX, GEMPortIDEnd, GEMPORT_ID_SHARED_IDX, GEMPortIDSharedPoolID, nil)
345 PONRMgr.UpdateRanges(ctx, FLOW_ID_START_IDX, FlowIDStart, FLOW_ID_END_IDX, FlowIDEnd, FLOW_ID_SHARED_IDX, FlowIDSharedPoolID, nil)
346 PONRMgr.UpdateRanges(ctx, UNI_ID_START_IDX, UNIIDStart, UNI_ID_END_IDX, UNIIDEnd, "", 0, nil)
347 logger.Debug(ctx, "Initialize default range values")
Scott Baker2c1c4822019-10-16 11:02:41 -0700348 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
357}
358
npujar5bf737f2020-01-16 19:35:25 +0530359func (PONRMgr *PONResourceManager) InitDeviceResourcePool(ctx context.Context) error {
Scott Baker2c1c4822019-10-16 11:02:41 -0700360
361 //Initialize resource pool for all PON ports.
362
Neha Sharma94f16a92020-06-26 04:17:55 +0000363 logger.Debug(ctx, "Init resource ranges")
Scott Baker2c1c4822019-10-16 11:02:41 -0700364
365 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 }
npujar5bf737f2020-01-16 19:35:25 +0530371 if err = PONRMgr.InitResourceIDPool(ctx, Intf, ONU_ID,
Scott Baker2c1c4822019-10-16 11:02:41 -0700372 PONRMgr.PonResourceRanges[ONU_ID_START_IDX].(uint32),
373 PONRMgr.PonResourceRanges[ONU_ID_END_IDX].(uint32)); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000374 logger.Error(ctx, "Failed to init ONU ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700375 return err
376 }
377 if SharedPoolID != 0 {
378 break
379 }
380 }
381
382 for _, Intf := range PONRMgr.IntfIDs {
383 SharedPoolID := PONRMgr.PonResourceRanges[ALLOC_ID_SHARED_IDX].(uint32)
384 if SharedPoolID != 0 {
385 Intf = SharedPoolID
386 }
npujar5bf737f2020-01-16 19:35:25 +0530387 if err = PONRMgr.InitResourceIDPool(ctx, Intf, ALLOC_ID,
Scott Baker2c1c4822019-10-16 11:02:41 -0700388 PONRMgr.PonResourceRanges[ALLOC_ID_START_IDX].(uint32),
389 PONRMgr.PonResourceRanges[ALLOC_ID_END_IDX].(uint32)); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000390 logger.Error(ctx, "Failed to init ALLOC ID resource pool ")
Scott Baker2c1c4822019-10-16 11:02:41 -0700391 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 }
npujar5bf737f2020-01-16 19:35:25 +0530402 if err = PONRMgr.InitResourceIDPool(ctx, Intf, GEMPORT_ID,
Scott Baker2c1c4822019-10-16 11:02:41 -0700403 PONRMgr.PonResourceRanges[GEMPORT_ID_START_IDX].(uint32),
404 PONRMgr.PonResourceRanges[GEMPORT_ID_END_IDX].(uint32)); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000405 logger.Error(ctx, "Failed to init GEMPORT ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700406 return err
407 }
408 if SharedPoolID != 0 {
409 break
410 }
411 }
412
413 for _, Intf := range PONRMgr.IntfIDs {
414 SharedPoolID := PONRMgr.PonResourceRanges[FLOW_ID_SHARED_IDX].(uint32)
415 if SharedPoolID != 0 {
416 Intf = SharedPoolID
417 }
npujar5bf737f2020-01-16 19:35:25 +0530418 if err = PONRMgr.InitResourceIDPool(ctx, Intf, FLOW_ID,
Scott Baker2c1c4822019-10-16 11:02:41 -0700419 PONRMgr.PonResourceRanges[FLOW_ID_START_IDX].(uint32),
420 PONRMgr.PonResourceRanges[FLOW_ID_END_IDX].(uint32)); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000421 logger.Error(ctx, "Failed to init FLOW ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700422 return err
423 }
424 if SharedPoolID != 0 {
425 break
426 }
427 }
428 return err
429}
430
npujar5bf737f2020-01-16 19:35:25 +0530431func (PONRMgr *PONResourceManager) ClearDeviceResourcePool(ctx context.Context) error {
Scott Baker2c1c4822019-10-16 11:02:41 -0700432
433 //Clear resource pool for all PON ports.
434
Neha Sharma94f16a92020-06-26 04:17:55 +0000435 logger.Debug(ctx, "Clear resource ranges")
Scott Baker2c1c4822019-10-16 11:02:41 -0700436
437 for _, Intf := range PONRMgr.IntfIDs {
438 SharedPoolID := PONRMgr.PonResourceRanges[ONU_ID_SHARED_IDX].(uint32)
439 if SharedPoolID != 0 {
440 Intf = SharedPoolID
441 }
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800442 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, ONU_ID); !status {
Neha Sharma94f16a92020-06-26 04:17:55 +0000443 logger.Error(ctx, "Failed to clear ONU ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700444 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 }
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800456 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, ALLOC_ID); !status {
Neha Sharma94f16a92020-06-26 04:17:55 +0000457 logger.Error(ctx, "Failed to clear ALLOC ID resource pool ")
Scott Baker2c1c4822019-10-16 11:02:41 -0700458 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 }
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800469 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, GEMPORT_ID); !status {
Neha Sharma94f16a92020-06-26 04:17:55 +0000470 logger.Error(ctx, "Failed to clear GEMPORT ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700471 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 }
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800483 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, FLOW_ID); !status {
Neha Sharma94f16a92020-06-26 04:17:55 +0000484 logger.Error(ctx, "Failed to clear FLOW ID resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700485 return errors.New("Failed to clear FLOW ID resource pool")
486 }
487 if SharedPoolID != 0 {
488 break
489 }
490 }
491 return nil
492}
493
npujar5bf737f2020-01-16 19:35:25 +0530494func (PONRMgr *PONResourceManager) InitResourceIDPool(ctx context.Context, Intf uint32, ResourceType string, StartID uint32, EndID uint32) error {
Scott Baker2c1c4822019-10-16 11:02:41 -0700495
496 /*Initialize Resource ID pool for a given Resource Type on a given PON Port
497
498 :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 */
504
505 // delegate to the master instance if sharing enabled across instances
506 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
507 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujar5bf737f2020-01-16 19:35:25 +0530508 return SharedResourceMgr.InitResourceIDPool(ctx, Intf, ResourceType, StartID, EndID)
Scott Baker2c1c4822019-10-16 11:02:41 -0700509 }
510
Neha Sharma94f16a92020-06-26 04:17:55 +0000511 Path := PONRMgr.GetPath(ctx, Intf, ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700512 if Path == "" {
Neha Sharma94f16a92020-06-26 04:17:55 +0000513 logger.Errorf(ctx, "Failed to get path for resource type %s", ResourceType)
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800514 return fmt.Errorf("Failed to get path for resource type %s", ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700515 }
516
517 //In case of adapter reboot and reconciliation resource in kv store
518 //checked for its presence if not kv store update happens
npujar5bf737f2020-01-16 19:35:25 +0530519 Res, err := PONRMgr.GetResource(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700520 if (err == nil) && (Res != nil) {
Neha Sharma94f16a92020-06-26 04:17:55 +0000521 logger.Debugf(ctx, "Resource %s already present in store ", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700522 return nil
523 } else {
Esin Karaman5351fc52020-02-14 07:45:49 +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
Neha Sharma94f16a92020-06-26 04:17:55 +0000529 logger.Debugw(ctx, "Excluding some ports from GEM port id pool", log.Fields{"excluded gem ports": excluded})
Esin Karaman5351fc52020-02-14 07:45:49 +0000530 }
531 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000532 FormatResult, err := PONRMgr.FormatResource(ctx, Intf, StartID, EndID, excluded)
Scott Baker2c1c4822019-10-16 11:02:41 -0700533 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000534 logger.Errorf(ctx, "Failed to format resource")
Scott Baker2c1c4822019-10-16 11:02:41 -0700535 return err
536 }
537 // Add resource as json in kv store.
npujar5bf737f2020-01-16 19:35:25 +0530538 err = PONRMgr.KVStore.Put(ctx, Path, FormatResult)
Scott Baker2c1c4822019-10-16 11:02:41 -0700539 if err == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000540 logger.Debug(ctx, "Successfuly posted to kv store")
Scott Baker2c1c4822019-10-16 11:02:41 -0700541 return err
542 }
543 }
544
Neha Sharma94f16a92020-06-26 04:17:55 +0000545 logger.Debug(ctx, "Error initializing pool")
Scott Baker2c1c4822019-10-16 11:02:41 -0700546
547 return err
548}
549
Esin Karaman5351fc52020-02-14 07:45:49 +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 {
Neha Sharma94f16a92020-06-26 04:17:55 +0000555 logger.Errorw(ctx, "Unable to get reserved GEM port ids from the kv store", log.Fields{"err": err})
Esin Karaman5351fc52020-02-14 07:45:49 +0000556 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 {
Neha Sharma94f16a92020-06-26 04:17:55 +0000564 logger.Errorw(ctx, "Failed to convert reserved gem port ids into byte array", log.Fields{"err": err})
Esin Karaman5351fc52020-02-14 07:45:49 +0000565 return reservedGemPortIds, false
566 }
567 if err = json.Unmarshal(Val, &reservedGemPortIds); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000568 logger.Errorw(ctx, "Failed to unmarshal reservedGemPortIds", log.Fields{"err": err})
Esin Karaman5351fc52020-02-14 07:45:49 +0000569 return reservedGemPortIds, false
570 }
571 return reservedGemPortIds, true
572}
573
Neha Sharma94f16a92020-06-26 04:17:55 +0000574func (PONRMgr *PONResourceManager) FormatResource(ctx context.Context, IntfID uint32, StartIDx uint32, EndIDx uint32,
Esin Karaman5351fc52020-02-14 07:45:49 +0000575 Excluded []uint32) ([]byte, error) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700576 /*
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
Esin Karaman5351fc52020-02-14 07:45:49 +0000581 :Id values to be Excluded from the pool
Scott Baker2c1c4822019-10-16 11:02:41 -0700582 :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 {
Neha Sharma94f16a92020-06-26 04:17:55 +0000596 logger.Error(ctx, "Failed to create a bitmap")
Scott Baker2c1c4822019-10-16 11:02:41 -0700597 return nil, errors.New("Failed to create bitmap")
598 }
Esin Karaman5351fc52020-02-14 07:45:49 +0000599 for _, excludedID := range Excluded {
600 if excludedID < StartIDx || excludedID > EndIDx {
Neha Sharma94f16a92020-06-26 04:17:55 +0000601 logger.Warnf(ctx, "Cannot reserve %d. It must be in the range of [%d, %d]", excludedID,
Esin Karaman5351fc52020-02-14 07:45:49 +0000602 StartIDx, EndIDx)
603 continue
604 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000605 PONRMgr.reserveID(ctx, TSData, StartIDx, excludedID)
Esin Karaman5351fc52020-02-14 07:45:49 +0000606 }
Scott Baker2c1c4822019-10-16 11:02:41 -0700607 Resource[POOL] = TSData.Data(false) //we pass false so as the TSData lib api does not do a copy of the data and return
608
609 Value, err := json.Marshal(Resource)
610 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000611 logger.Errorf(ctx, "Failed to marshall resource")
Scott Baker2c1c4822019-10-16 11:02:41 -0700612 return nil, err
613 }
614 return Value, err
615}
npujar5bf737f2020-01-16 19:35:25 +0530616func (PONRMgr *PONResourceManager) GetResource(ctx context.Context, Path string) (map[string]interface{}, error) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700617 /*
618 Get resource from kv store.
619
620 :param path: path to get resource
621 :return: resource if resource present in kv store else None
622 */
623 //get resource from kv store
624
625 var Value []byte
626 Result := make(map[string]interface{})
627 var Str string
628
npujar5bf737f2020-01-16 19:35:25 +0530629 Resource, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700630 if (err != nil) || (Resource == nil) {
Neha Sharma94f16a92020-06-26 04:17:55 +0000631 logger.Debugf(ctx, "Resource unavailable at %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700632 return nil, err
633 }
634
635 Value, err = ToByte(Resource.Value)
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800636 if err != nil {
637 return nil, err
638 }
Scott Baker2c1c4822019-10-16 11:02:41 -0700639
640 // decode resource fetched from backend store to dictionary
641 err = json.Unmarshal(Value, &Result)
642 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000643 logger.Error(ctx, "Failed to decode resource")
Scott Baker2c1c4822019-10-16 11:02:41 -0700644 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 {
Neha Sharma94f16a92020-06-26 04:17:55 +0000653 logger.Error(ctx, "Failed to conver to kv pair to string")
Scott Baker2c1c4822019-10-16 11:02:41 -0700654 return Result, err
655 }
656 Decode64, _ := base64.StdEncoding.DecodeString(Str)
657 Result[POOL], err = ToByte(Decode64)
658 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000659 logger.Error(ctx, "Failed to convert resource pool to byte")
Scott Baker2c1c4822019-10-16 11:02:41 -0700660 return Result, err
661 }
662
663 return Result, err
664}
665
Neha Sharma94f16a92020-06-26 04:17:55 +0000666func (PONRMgr *PONResourceManager) GetPath(ctx context.Context, IntfID uint32, ResourceType string) string {
Scott Baker2c1c4822019-10-16 11:02:41 -0700667 /*
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 */
673
674 /*
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 {
Neha Sharma94f16a92020-06-26 04:17:55 +0000692 logger.Error(ctx, "Invalid resource pool identifier")
Scott Baker2c1c4822019-10-16 11:02:41 -0700693 }
694 return Path
695}
696
npujar5bf737f2020-01-16 19:35:25 +0530697func (PONRMgr *PONResourceManager) GetResourceID(ctx context.Context, IntfID uint32, ResourceType string, NumIDs uint32) ([]uint32, error) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700698 /*
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 {
Neha Sharma94f16a92020-06-26 04:17:55 +0000707 logger.Error(ctx, "Invalid number of resources requested")
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800708 return nil, fmt.Errorf("Invalid number of resources requested %d", NumIDs)
Scott Baker2c1c4822019-10-16 11:02:41 -0700709 }
710 // delegate to the master instance if sharing enabled across instances
711
712 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
713 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujar5bf737f2020-01-16 19:35:25 +0530714 return SharedResourceMgr.GetResourceID(ctx, IntfID, ResourceType, NumIDs)
Scott Baker2c1c4822019-10-16 11:02:41 -0700715 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000716 logger.Debugf(ctx, "Fetching resource from %s rsrc mgr for resource %s", PONRMgr.Globalorlocal, ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700717
Neha Sharma94f16a92020-06-26 04:17:55 +0000718 Path := PONRMgr.GetPath(ctx, IntfID, ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700719 if Path == "" {
Neha Sharma94f16a92020-06-26 04:17:55 +0000720 logger.Errorf(ctx, "Failed to get path for resource type %s", ResourceType)
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800721 return nil, fmt.Errorf("Failed to get path for resource type %s", ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700722 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000723 logger.Debugf(ctx, "Get resource for type %s on path %s", ResourceType, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700724 var Result []uint32
725 var NextID uint32
npujar5bf737f2020-01-16 19:35:25 +0530726 Resource, err := PONRMgr.GetResource(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700727 if (err == nil) && (ResourceType == ONU_ID) || (ResourceType == FLOW_ID) {
Neha Sharma94f16a92020-06-26 04:17:55 +0000728 if NextID, err = PONRMgr.GenerateNextID(ctx, Resource); err != nil {
729 logger.Error(ctx, "Failed to Generate ID")
Scott Baker2c1c4822019-10-16 11:02:41 -0700730 return Result, err
731 }
732 Result = append(Result, NextID)
733 } else if (err == nil) && ((ResourceType == GEMPORT_ID) || (ResourceType == ALLOC_ID)) {
734 if NumIDs == 1 {
Neha Sharma94f16a92020-06-26 04:17:55 +0000735 if NextID, err = PONRMgr.GenerateNextID(ctx, Resource); err != nil {
736 logger.Error(ctx, "Failed to Generate ID")
Scott Baker2c1c4822019-10-16 11:02:41 -0700737 return Result, err
738 }
739 Result = append(Result, NextID)
740 } else {
741 for NumIDs > 0 {
Neha Sharma94f16a92020-06-26 04:17:55 +0000742 if NextID, err = PONRMgr.GenerateNextID(ctx, Resource); err != nil {
743 logger.Error(ctx, "Failed to Generate ID")
Scott Baker2c1c4822019-10-16 11:02:41 -0700744 return Result, err
745 }
746 Result = append(Result, NextID)
747 NumIDs--
748 }
749 }
750 } else {
Neha Sharma94f16a92020-06-26 04:17:55 +0000751 logger.Error(ctx, "get resource failed")
Scott Baker2c1c4822019-10-16 11:02:41 -0700752 return Result, err
753 }
754
755 //Update resource in kv store
npujar5bf737f2020-01-16 19:35:25 +0530756 if PONRMgr.UpdateResource(ctx, Path, Resource) != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000757 logger.Errorf(ctx, "Failed to update resource %s", Path)
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800758 return nil, fmt.Errorf("Failed to update resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700759 }
760 return Result, nil
761}
762
763func checkValidResourceType(ResourceType string) bool {
764 KnownResourceTypes := []string{ONU_ID, ALLOC_ID, GEMPORT_ID, FLOW_ID}
765
766 for _, v := range KnownResourceTypes {
767 if v == ResourceType {
768 return true
769 }
770 }
771 return false
772}
773
npujar5bf737f2020-01-16 19:35:25 +0530774func (PONRMgr *PONResourceManager) FreeResourceID(ctx context.Context, IntfID uint32, ResourceType string, ReleaseContent []uint32) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -0700775 /*
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 */
David K. Bainbridge7c75cac2020-02-19 08:53:46 -0800782 if !checkValidResourceType(ResourceType) {
Neha Sharma94f16a92020-06-26 04:17:55 +0000783 logger.Error(ctx, "Invalid resource type")
Scott Baker2c1c4822019-10-16 11:02:41 -0700784 return false
785 }
786 if ReleaseContent == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000787 logger.Debug(ctx, "Nothing to release")
Scott Baker2c1c4822019-10-16 11:02:41 -0700788 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 {
npujar5bf737f2020-01-16 19:35:25 +0530793 return SharedResourceMgr.FreeResourceID(ctx, IntfID, ResourceType, ReleaseContent)
Scott Baker2c1c4822019-10-16 11:02:41 -0700794 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000795 Path := PONRMgr.GetPath(ctx, IntfID, ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700796 if Path == "" {
Neha Sharma94f16a92020-06-26 04:17:55 +0000797 logger.Error(ctx, "Failed to get path")
Scott Baker2c1c4822019-10-16 11:02:41 -0700798 return false
799 }
npujar5bf737f2020-01-16 19:35:25 +0530800 Resource, err := PONRMgr.GetResource(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700801 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000802 logger.Error(ctx, "Failed to get resource")
Scott Baker2c1c4822019-10-16 11:02:41 -0700803 return false
804 }
805 for _, Val := range ReleaseContent {
Neha Sharma94f16a92020-06-26 04:17:55 +0000806 PONRMgr.ReleaseID(ctx, Resource, Val)
Scott Baker2c1c4822019-10-16 11:02:41 -0700807 }
npujar5bf737f2020-01-16 19:35:25 +0530808 if PONRMgr.UpdateResource(ctx, Path, Resource) != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000809 logger.Errorf(ctx, "Free resource for %s failed", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700810 return false
811 }
812 return true
813}
814
npujar5bf737f2020-01-16 19:35:25 +0530815func (PONRMgr *PONResourceManager) UpdateResource(ctx context.Context, Path string, Resource map[string]interface{}) error {
Scott Baker2c1c4822019-10-16 11:02:41 -0700816 /*
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 {
Neha Sharma94f16a92020-06-26 04:17:55 +0000825 logger.Error(ctx, "failed to Marshal")
Scott Baker2c1c4822019-10-16 11:02:41 -0700826 return err
827 }
npujar5bf737f2020-01-16 19:35:25 +0530828 err = PONRMgr.KVStore.Put(ctx, Path, Value)
Scott Baker2c1c4822019-10-16 11:02:41 -0700829 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000830 logger.Error(ctx, "failed to put data to kv store %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700831 return err
832 }
833 return nil
834}
835
npujar5bf737f2020-01-16 19:35:25 +0530836func (PONRMgr *PONResourceManager) ClearResourceIDPool(ctx context.Context, contIntfID uint32, ResourceType string) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -0700837 /*
838 Clear Resource Pool for a given Resource Type on a given PON Port.
839 :return boolean: True if removed else False
840 */
841
842 // delegate to the master instance if sharing enabled across instances
843 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
844 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujar5bf737f2020-01-16 19:35:25 +0530845 return SharedResourceMgr.ClearResourceIDPool(ctx, contIntfID, ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700846 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000847 Path := PONRMgr.GetPath(ctx, contIntfID, ResourceType)
Scott Baker2c1c4822019-10-16 11:02:41 -0700848 if Path == "" {
Neha Sharma94f16a92020-06-26 04:17:55 +0000849 logger.Error(ctx, "Failed to get path")
Scott Baker2c1c4822019-10-16 11:02:41 -0700850 return false
851 }
852
npujar5bf737f2020-01-16 19:35:25 +0530853 if err := PONRMgr.KVStore.Delete(ctx, Path); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000854 logger.Errorf(ctx, "Failed to delete resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700855 return false
856 }
Neha Sharma94f16a92020-06-26 04:17:55 +0000857 logger.Debugf(ctx, "Cleared resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700858 return true
859}
860
npujar5bf737f2020-01-16 19:35:25 +0530861func (PONRMgr PONResourceManager) InitResourceMap(ctx context.Context, PONIntfONUID string) {
Scott Baker2c1c4822019-10-16 11:02:41 -0700862 /*
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
npujar5bf737f2020-01-16 19:35:25 +0530869 Result := PONRMgr.KVStore.Put(ctx, AllocIDPath, AllocIDs)
Scott Baker2c1c4822019-10-16 11:02:41 -0700870 if Result != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000871 logger.Error(ctx, "Failed to update the KV store")
Scott Baker2c1c4822019-10-16 11:02:41 -0700872 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
npujar5bf737f2020-01-16 19:35:25 +0530877 Result = PONRMgr.KVStore.Put(ctx, GEMPortIDPath, GEMPortIDs)
Scott Baker2c1c4822019-10-16 11:02:41 -0700878 if Result != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000879 logger.Error(ctx, "Failed to update the KV store")
Scott Baker2c1c4822019-10-16 11:02:41 -0700880 return
881 }
882}
883
npujar5bf737f2020-01-16 19:35:25 +0530884func (PONRMgr PONResourceManager) RemoveResourceMap(ctx context.Context, PONIntfONUID string) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -0700885 /*
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)
npujar5bf737f2020-01-16 19:35:25 +0530892 if err = PONRMgr.KVStore.Delete(ctx, AllocIDPath); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000893 logger.Errorf(ctx, "Failed to remove resource %s", AllocIDPath)
Scott Baker2c1c4822019-10-16 11:02:41 -0700894 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)
npujar5bf737f2020-01-16 19:35:25 +0530898 err = PONRMgr.KVStore.Delete(ctx, GEMPortIDPath)
Scott Baker2c1c4822019-10-16 11:02:41 -0700899 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000900 logger.Errorf(ctx, "Failed to remove resource %s", GEMPortIDPath)
Scott Baker2c1c4822019-10-16 11:02:41 -0700901 return false
902 }
903
904 FlowIDPath := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujar5bf737f2020-01-16 19:35:25 +0530905 if FlowIDs, err := PONRMgr.KVStore.List(ctx, FlowIDPath); err != nil {
Scott Baker2c1c4822019-10-16 11:02:41 -0700906 for _, Flow := range FlowIDs {
907 FlowIDInfoPath := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, PONIntfONUID, Flow.Value)
npujar5bf737f2020-01-16 19:35:25 +0530908 if err = PONRMgr.KVStore.Delete(ctx, FlowIDInfoPath); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000909 logger.Errorf(ctx, "Failed to remove resource %s", FlowIDInfoPath)
Scott Baker2c1c4822019-10-16 11:02:41 -0700910 return false
911 }
912 }
913 }
914
npujar5bf737f2020-01-16 19:35:25 +0530915 if err = PONRMgr.KVStore.Delete(ctx, FlowIDPath); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000916 logger.Errorf(ctx, "Failed to remove resource %s", FlowIDPath)
Scott Baker2c1c4822019-10-16 11:02:41 -0700917 return false
918 }
919
920 return true
921}
922
npujar5bf737f2020-01-16 19:35:25 +0530923func (PONRMgr *PONResourceManager) GetCurrentAllocIDForOnu(ctx context.Context, IntfONUID string) []uint32 {
Scott Baker2c1c4822019-10-16 11:02:41 -0700924 /*
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)
930
931 var Data []uint32
npujar5bf737f2020-01-16 19:35:25 +0530932 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700933 if err == nil {
934 if Value != nil {
935 Val, err := ToByte(Value.Value)
936 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000937 logger.Errorw(ctx, "Failed to convert into byte array", log.Fields{"error": err})
Scott Baker2c1c4822019-10-16 11:02:41 -0700938 return Data
939 }
940 if err = json.Unmarshal(Val, &Data); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000941 logger.Error(ctx, "Failed to unmarshal", log.Fields{"error": err})
Scott Baker2c1c4822019-10-16 11:02:41 -0700942 return Data
943 }
944 }
945 }
946 return Data
947}
948
npujar5bf737f2020-01-16 19:35:25 +0530949func (PONRMgr *PONResourceManager) GetCurrentGEMPortIDsForOnu(ctx context.Context, IntfONUID string) []uint32 {
Scott Baker2c1c4822019-10-16 11:02:41 -0700950 /*
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 */
955
956 Path := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Neha Sharma94f16a92020-06-26 04:17:55 +0000957 logger.Debugf(ctx, "Getting current gemports for %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700958 var Data []uint32
npujar5bf737f2020-01-16 19:35:25 +0530959 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700960 if err == nil {
961 if Value != nil {
962 Val, _ := ToByte(Value.Value)
963 if err = json.Unmarshal(Val, &Data); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000964 logger.Errorw(ctx, "Failed to unmarshal", log.Fields{"error": err})
Scott Baker2c1c4822019-10-16 11:02:41 -0700965 return Data
966 }
967 }
968 } else {
Neha Sharma94f16a92020-06-26 04:17:55 +0000969 logger.Errorf(ctx, "Failed to get data from kvstore for %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700970 }
971 return Data
972}
973
npujar5bf737f2020-01-16 19:35:25 +0530974func (PONRMgr *PONResourceManager) GetCurrentFlowIDsForOnu(ctx context.Context, IntfONUID string) []uint32 {
Scott Baker2c1c4822019-10-16 11:02:41 -0700975 /*
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 */
980
981 Path := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
982
983 var Data []uint32
npujar5bf737f2020-01-16 19:35:25 +0530984 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -0700985 if err == nil {
986 if Value != nil {
987 Val, _ := ToByte(Value.Value)
988 if err = json.Unmarshal(Val, &Data); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +0000989 logger.Error(ctx, "Failed to unmarshal")
Scott Baker2c1c4822019-10-16 11:02:41 -0700990 return Data
991 }
992 }
993 }
994 return Data
995}
996
npujar5bf737f2020-01-16 19:35:25 +0530997func (PONRMgr *PONResourceManager) GetFlowIDInfo(ctx context.Context, IntfONUID string, FlowID uint32, Data interface{}) error {
Scott Baker2c1c4822019-10-16 11:02:41 -0700998 /*
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 */
1005
1006 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
1007
npujar5bf737f2020-01-16 19:35:25 +05301008 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001009 if err == nil {
1010 if Value != nil {
1011 Val, err := ToByte(Value.Value)
1012 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001013 logger.Errorw(ctx, "Failed to convert flowinfo into byte array", log.Fields{"error": err})
Scott Baker2c1c4822019-10-16 11:02:41 -07001014 return err
1015 }
1016 if err = json.Unmarshal(Val, Data); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001017 logger.Errorw(ctx, "Failed to unmarshal", log.Fields{"error": err})
Scott Baker2c1c4822019-10-16 11:02:41 -07001018 return err
1019 }
1020 }
1021 }
1022 return err
1023}
1024
npujar5bf737f2020-01-16 19:35:25 +05301025func (PONRMgr *PONResourceManager) RemoveFlowIDInfo(ctx context.Context, IntfONUID string, FlowID uint32) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -07001026 /*
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)
1032
npujar5bf737f2020-01-16 19:35:25 +05301033 if err := PONRMgr.KVStore.Delete(ctx, Path); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001034 logger.Errorf(ctx, "Falied to remove resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001035 return false
1036 }
1037 return true
1038}
1039
Serkant Uluderya198de902020-11-16 20:29:17 +03001040func (PONRMgr *PONResourceManager) RemoveAllFlowIDInfo(ctx context.Context, IntfONUID string) bool {
1041 /*
1042 Remove flow_id_info details configured for the ONU.
1043 :param pon_intf_onu_id: reference of PON interface id and onu id
1044 */
1045 Path := fmt.Sprintf(FLOW_ID_INFO_PATH_INTF_ONU_PREFIX, PONRMgr.DeviceID, IntfONUID)
1046
1047 if err := PONRMgr.KVStore.DeleteWithPrefix(ctx, Path); err != nil {
1048 logger.Errorf(ctx, "Falied to remove resource %s", Path)
1049 return false
1050 }
1051 return true
1052}
1053
npujar5bf737f2020-01-16 19:35:25 +05301054func (PONRMgr *PONResourceManager) UpdateAllocIdsForOnu(ctx context.Context, IntfONUID string, AllocIDs []uint32) error {
Scott Baker2c1c4822019-10-16 11:02:41 -07001055 /*
1056 Update currently configured alloc ids for given pon_intf_onu_id
1057 :param pon_intf_onu_id: reference of PON interface id and onu id
1058 :param alloc_ids: list of alloc ids
1059 */
1060 var Value []byte
1061 var err error
1062 Path := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
1063 Value, err = json.Marshal(AllocIDs)
1064 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001065 logger.Error(ctx, "failed to Marshal")
Scott Baker2c1c4822019-10-16 11:02:41 -07001066 return err
1067 }
1068
npujar5bf737f2020-01-16 19:35:25 +05301069 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001070 logger.Errorf(ctx, "Failed to update resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001071 return err
1072 }
1073 return err
1074}
1075
npujar5bf737f2020-01-16 19:35:25 +05301076func (PONRMgr *PONResourceManager) UpdateGEMPortIDsForOnu(ctx context.Context, IntfONUID string, GEMPortIDs []uint32) error {
Scott Baker2c1c4822019-10-16 11:02:41 -07001077 /*
1078 Update currently configured gemport ids for given pon_intf_onu_id
1079 :param pon_intf_onu_id: reference of PON interface id and onu id
1080 :param gemport_ids: list of gem port ids
1081 */
1082
1083 var Value []byte
1084 var err error
1085 Path := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Neha Sharma94f16a92020-06-26 04:17:55 +00001086 logger.Debugf(ctx, "Updating gemport ids for %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001087 Value, err = json.Marshal(GEMPortIDs)
1088 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001089 logger.Error(ctx, "failed to Marshal")
Scott Baker2c1c4822019-10-16 11:02:41 -07001090 return err
1091 }
1092
npujar5bf737f2020-01-16 19:35:25 +05301093 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001094 logger.Errorf(ctx, "Failed to update resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001095 return err
1096 }
1097 return err
1098}
1099
1100func checkForFlowIDInList(FlowIDList []uint32, FlowID uint32) (bool, uint32) {
1101 /*
1102 Check for a flow id in a given list of flow IDs.
1103 :param FLowIDList: List of Flow IDs
1104 :param FlowID: Flowd to check in the list
1105 : return true and the index if present false otherwise.
1106 */
1107
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001108 for idx := range FlowIDList {
Scott Baker2c1c4822019-10-16 11:02:41 -07001109 if FlowID == FlowIDList[idx] {
1110 return true, uint32(idx)
1111 }
1112 }
1113 return false, 0
1114}
1115
npujar5bf737f2020-01-16 19:35:25 +05301116func (PONRMgr *PONResourceManager) UpdateFlowIDForOnu(ctx context.Context, IntfONUID string, FlowID uint32, Add bool) error {
Scott Baker2c1c4822019-10-16 11:02:41 -07001117 /*
1118 Update the flow_id list of the ONU (add or remove flow_id from the list)
1119 :param pon_intf_onu_id: reference of PON interface id and onu id
1120 :param flow_id: flow ID
1121 :param add: Boolean flag to indicate whether the flow_id should be
1122 added or removed from the list. Defaults to adding the flow.
1123 */
1124 var Value []byte
1125 var err error
1126 var RetVal bool
1127 var IDx uint32
1128 Path := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
npujar5bf737f2020-01-16 19:35:25 +05301129 FlowIDs := PONRMgr.GetCurrentFlowIDsForOnu(ctx, IntfONUID)
Scott Baker2c1c4822019-10-16 11:02:41 -07001130
1131 if Add {
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001132 if RetVal, _ = checkForFlowIDInList(FlowIDs, FlowID); RetVal {
1133 return nil
Scott Baker2c1c4822019-10-16 11:02:41 -07001134 }
1135 FlowIDs = append(FlowIDs, FlowID)
1136 } else {
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001137 if RetVal, IDx = checkForFlowIDInList(FlowIDs, FlowID); !RetVal {
1138 return nil
Scott Baker2c1c4822019-10-16 11:02:41 -07001139 }
1140 // delete the index and shift
1141 FlowIDs = append(FlowIDs[:IDx], FlowIDs[IDx+1:]...)
1142 }
1143 Value, err = json.Marshal(FlowIDs)
1144 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001145 logger.Error(ctx, "Failed to Marshal")
Scott Baker2c1c4822019-10-16 11:02:41 -07001146 return err
1147 }
1148
npujar5bf737f2020-01-16 19:35:25 +05301149 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001150 logger.Errorf(ctx, "Failed to update resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001151 return err
1152 }
1153 return err
1154}
1155
npujar5bf737f2020-01-16 19:35:25 +05301156func (PONRMgr *PONResourceManager) UpdateFlowIDInfoForOnu(ctx context.Context, IntfONUID string, FlowID uint32, FlowData interface{}) error {
Scott Baker2c1c4822019-10-16 11:02:41 -07001157 /*
1158 Update any metadata associated with the flow_id. The flow_data could be json
1159 or any of other data structure. The resource manager doesnt care
1160 :param pon_intf_onu_id: reference of PON interface id and onu id
1161 :param flow_id: Flow ID
1162 :param flow_data: Flow data blob
1163 */
1164 var Value []byte
1165 var err error
1166 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
1167 Value, err = json.Marshal(FlowData)
1168 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001169 logger.Error(ctx, "failed to Marshal")
Scott Baker2c1c4822019-10-16 11:02:41 -07001170 return err
1171 }
1172
npujar5bf737f2020-01-16 19:35:25 +05301173 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001174 logger.Errorf(ctx, "Failed to update resource %s", Path)
Scott Baker2c1c4822019-10-16 11:02:41 -07001175 return err
1176 }
1177 return err
1178}
1179
Neha Sharma94f16a92020-06-26 04:17:55 +00001180func (PONRMgr *PONResourceManager) GenerateNextID(ctx context.Context, Resource map[string]interface{}) (uint32, error) {
Scott Baker2c1c4822019-10-16 11:02:41 -07001181 /*
1182 Generate unique id having OFFSET as start
1183 :param resource: resource used to generate ID
1184 :return uint32: generated id
1185 */
1186 ByteArray, err := ToByte(Resource[POOL])
1187 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001188 logger.Error(ctx, "Failed to convert resource to byte array")
Scott Baker2c1c4822019-10-16 11:02:41 -07001189 return 0, err
1190 }
1191 Data := bitmap.TSFromData(ByteArray, false)
1192 if Data == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001193 logger.Error(ctx, "Failed to get data from byte array")
Scott Baker2c1c4822019-10-16 11:02:41 -07001194 return 0, errors.New("Failed to get data from byte array")
1195 }
1196
1197 Len := Data.Len()
1198 var Idx int
1199 for Idx = 0; Idx < Len; Idx++ {
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001200 if !Data.Get(Idx) {
Scott Baker2c1c4822019-10-16 11:02:41 -07001201 break
1202 }
1203 }
1204 Data.Set(Idx, true)
1205 res := uint32(Resource[START_IDX].(float64))
1206 Resource[POOL] = Data.Data(false)
Neha Sharma94f16a92020-06-26 04:17:55 +00001207 logger.Debugf(ctx, "Generated ID for %d", (uint32(Idx) + res))
Scott Baker2c1c4822019-10-16 11:02:41 -07001208 return (uint32(Idx) + res), err
1209}
1210
Neha Sharma94f16a92020-06-26 04:17:55 +00001211func (PONRMgr *PONResourceManager) ReleaseID(ctx context.Context, Resource map[string]interface{}, Id uint32) bool {
Scott Baker2c1c4822019-10-16 11:02:41 -07001212 /*
1213 Release unique id having OFFSET as start index.
1214 :param resource: resource used to release ID
1215 :param unique_id: id need to be released
1216 */
1217 ByteArray, err := ToByte(Resource[POOL])
1218 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001219 logger.Error(ctx, "Failed to convert resource to byte array")
Scott Baker2c1c4822019-10-16 11:02:41 -07001220 return false
1221 }
1222 Data := bitmap.TSFromData(ByteArray, false)
1223 if Data == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001224 logger.Error(ctx, "Failed to get resource pool")
Scott Baker2c1c4822019-10-16 11:02:41 -07001225 return false
1226 }
David K. Bainbridge7c75cac2020-02-19 08:53:46 -08001227 Idx := Id - uint32(Resource[START_IDX].(float64))
Scott Baker2c1c4822019-10-16 11:02:41 -07001228 Data.Set(int(Idx), false)
1229 Resource[POOL] = Data.Data(false)
1230
1231 return true
1232}
1233
Esin Karaman5351fc52020-02-14 07:45:49 +00001234/* Reserves a unique id in the specified resource pool.
1235:param Resource: resource used to reserve ID
1236:param Id: ID to be reserved
1237*/
Neha Sharma94f16a92020-06-26 04:17:55 +00001238func (PONRMgr *PONResourceManager) reserveID(ctx context.Context, TSData *bitmap.Threadsafe, StartIndex uint32, Id uint32) bool {
Esin Karaman5351fc52020-02-14 07:45:49 +00001239 Data := bitmap.TSFromData(TSData.Data(false), false)
1240 if Data == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001241 logger.Error(ctx, "Failed to get resource pool")
Esin Karaman5351fc52020-02-14 07:45:49 +00001242 return false
1243 }
1244 Idx := Id - StartIndex
1245 Data.Set(int(Idx), true)
1246 return true
1247}
1248
Scott Baker2c1c4822019-10-16 11:02:41 -07001249func (PONRMgr *PONResourceManager) GetTechnology() string {
1250 return PONRMgr.Technology
1251}
1252
1253func (PONRMgr *PONResourceManager) GetResourceTypeAllocID() string {
1254 return ALLOC_ID
1255}
1256
1257func (PONRMgr *PONResourceManager) GetResourceTypeGemPortID() string {
1258 return GEMPORT_ID
1259}
1260
1261// ToByte converts an interface value to a []byte. The interface should either be of
1262// a string type or []byte. Otherwise, an error is returned.
1263func ToByte(value interface{}) ([]byte, error) {
1264 switch t := value.(type) {
1265 case []byte:
1266 return value.([]byte), nil
1267 case string:
1268 return []byte(value.(string)), nil
1269 default:
1270 return nil, fmt.Errorf("unexpected-type-%T", t)
1271 }
1272}
1273
1274// ToString converts an interface value to a string. The interface should either be of
1275// a string type or []byte. Otherwise, an error is returned.
1276func ToString(value interface{}) (string, error) {
1277 switch t := value.(type) {
1278 case []byte:
1279 return string(value.([]byte)), nil
1280 case string:
1281 return value.(string), nil
1282 default:
1283 return "", fmt.Errorf("unexpected-type-%T", t)
1284 }
1285}
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301286
npujar5bf737f2020-01-16 19:35:25 +05301287func (PONRMgr *PONResourceManager) AddOnuGemInfo(ctx context.Context, intfID uint32, onuGemData interface{}) error {
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301288 /*
1289 Update onugem info map,
1290 :param pon_intf_id: reference of PON interface id
1291 :param onuegmdata: onugem info map
1292 */
1293 var Value []byte
1294 var err error
1295 Path := fmt.Sprintf(ONU_GEM_INFO_PATH, PONRMgr.DeviceID, intfID)
1296 Value, err = json.Marshal(onuGemData)
1297 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001298 logger.Error(ctx, "failed to Marshal")
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301299 return err
1300 }
1301
npujar5bf737f2020-01-16 19:35:25 +05301302 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001303 logger.Errorf(ctx, "Failed to update resource %s", Path)
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301304 return err
1305 }
1306 return err
1307}
1308
npujar5bf737f2020-01-16 19:35:25 +05301309func (PONRMgr *PONResourceManager) GetOnuGemInfo(ctx context.Context, IntfId uint32, onuGemInfo interface{}) error {
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301310 /*
1311 Get onugeminfo map from kvstore
1312 :param intfid: refremce pon intfid
1313 :param onuGemInfo: onugem info to return from kv strore.
1314 */
1315 var Val []byte
1316
1317 path := fmt.Sprintf(ONU_GEM_INFO_PATH, PONRMgr.DeviceID, IntfId)
npujar5bf737f2020-01-16 19:35:25 +05301318 value, err := PONRMgr.KVStore.Get(ctx, path)
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301319 if err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001320 logger.Errorw(ctx, "Failed to get from kv store", log.Fields{"path": path})
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301321 return err
1322 } else if value == nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001323 logger.Debug(ctx, "No onuinfo for path", log.Fields{"path": path})
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301324 return nil // returning nil as this could happen if there are no onus for the interface yet
1325 }
1326 if Val, err = kvstore.ToByte(value.Value); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001327 logger.Error(ctx, "Failed to convert to byte array")
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301328 return err
1329 }
1330
1331 if err = json.Unmarshal(Val, &onuGemInfo); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001332 logger.Error(ctx, "Failed to unmarshall")
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301333 return err
1334 }
Neha Sharma94f16a92020-06-26 04:17:55 +00001335 logger.Debugw(ctx, "found onuinfo from path", log.Fields{"path": path, "onuinfo": onuGemInfo})
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301336 return err
1337}
1338
npujar5bf737f2020-01-16 19:35:25 +05301339func (PONRMgr *PONResourceManager) DelOnuGemInfoForIntf(ctx context.Context, intfId uint32) error {
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301340 /*
1341 delete onugem info for an interface from kvstore
1342 :param intfid: refremce pon intfid
1343 */
1344
1345 path := fmt.Sprintf(ONU_GEM_INFO_PATH, PONRMgr.DeviceID, intfId)
npujar5bf737f2020-01-16 19:35:25 +05301346 if err := PONRMgr.KVStore.Delete(ctx, path); err != nil {
Neha Sharma94f16a92020-06-26 04:17:55 +00001347 logger.Errorf(ctx, "Falied to remove resource %s", path)
Abhilash Laxmeshwarbbb0b2b2019-10-31 17:04:29 +05301348 return err
1349 }
1350 return nil
1351}