blob: b4c2fec8b69c65ce542923b2d2f3cff7b7a32ac2 [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"
Neha Sharmacc656962020-04-14 14:26:11 +000025 "time"
Matt Jeanneretcab955f2019-04-10 15:45:57 -040026
Esin Karamanccb714b2019-11-29 15:02:06 +000027 bitmap "github.com/boljen/go-bitmap"
Girish Gowdraa09aeab2020-09-14 16:30:52 -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"
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"
Matteo Scandolodfa7a972020-11-06 13:03:40 -080044
45 PATH_PREFIX = "%s/resource_manager/{%s}"
divyadesaid26f6b12020-03-19 06:30:28 +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 Scandolodfa7a972020-11-06 13:03:40 -080055
56 PATH_PREFIX_FOR_CONFIG = "%s/resource_manager/config"
Matt Jeanneret384d8c92019-05-06 14:27:31 -040057 /*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"
Matt Jeanneretcab955f2019-04-10 15:45:57 -040081
Matt Jeanneret384d8c92019-05-06 14:27:31 -040082 /*
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"
Matt Jeanneretcab955f2019-04-10 15:45:57 -040087
Matt Jeanneret384d8c92019-05-06 14:27:31 -040088 //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}"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400101
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400102 //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"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400105
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400106 //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"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400109
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400110 //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"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400113
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400114 //Flow Id info: Use to store more metadata associated with the flow_id
115 //Format: <device_id>/<(pon_intf_id, onu_id)>/flow_id_info/<flow_id>
116 FLOW_ID_INFO_PATH = "{%s}/{%s}/flow_id_info/{%d}"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400117
Scott Bakerc6e54cb2019-11-04 09:31:25 -0800118 //path on the kvstore to store onugem info map
119 //format: <device-id>/onu_gem_info/<intfid>
120 ONU_GEM_INFO_PATH = "{%s}/onu_gem_info/{%d}" // onu_gem/<(intfid)>
121
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400122 //Constants for internal usage.
123 PON_INTF_ID = "pon_intf_id"
124 START_IDX = "start_idx"
125 END_IDX = "end_idx"
126 POOL = "pool"
127 NUM_OF_PON_INTF = 16
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400128
Neha Sharmacc656962020-04-14 14:26:11 +0000129 KVSTORE_RETRY_TIMEOUT = 5 * time.Second
divyadesaid26f6b12020-03-19 06:30:28 +0000130 //Path on the KV store for storing reserved gem ports
131 //Format: reserved_gemport_ids
132 RESERVED_GEMPORT_IDS_PATH = "reserved_gemport_ids"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400133)
134
135//type ResourceTypeIndex string
136//type ResourceType string
137
138type PONResourceManager struct {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400139 //Implements APIs to initialize/allocate/release alloc/gemport/onu IDs.
divyadesaid26f6b12020-03-19 06:30:28 +0000140 Technology string
141 DeviceType string
142 DeviceID string
143 Backend string // ETCD, or consul
Neha Sharma3f221ae2020-04-29 19:02:12 +0000144 Address string // address of the KV store
divyadesaid26f6b12020-03-19 06:30:28 +0000145 OLTModel string
146 KVStore *db.Backend
147 KVStoreForConfig *db.Backend
148 TechProfileMgr tp.TechProfileIf // create object of *tp.TechProfileMgr
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400149
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400150 // Below attribute, pon_resource_ranges, should be initialized
151 // by reading from KV store.
152 PonResourceRanges map[string]interface{}
153 SharedResourceMgrs map[string]*PONResourceManager
154 SharedIdxByType map[string]string
155 IntfIDs []uint32 // list of pon interface IDs
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400156 Globalorlocal string
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400157}
158
Neha Sharma96b7bf22020-06-15 10:37:32 +0000159func newKVClient(ctx context.Context, storeType string, address string, timeout time.Duration) (kvstore.Client, error) {
160 logger.Infow(ctx, "kv-store-type", log.Fields{"store": storeType})
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400161 switch storeType {
162 case "consul":
Neha Sharma96b7bf22020-06-15 10:37:32 +0000163 return kvstore.NewConsulClient(ctx, address, timeout)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400164 case "etcd":
Neha Sharma96b7bf22020-06-15 10:37:32 +0000165 return kvstore.NewEtcdClient(ctx, address, timeout, log.WarnLevel)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400166 }
167 return nil, errors.New("unsupported-kv-store")
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400168}
169
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800170func SetKVClient(ctx context.Context, Technology string, Backend string, Addr string, configClient bool, basePathKvStore string) *db.Backend {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400171 // TODO : Make sure direct call to NewBackend is working fine with backend , currently there is some
172 // issue between kv store and backend , core is not calling NewBackend directly
Neha Sharma96b7bf22020-06-15 10:37:32 +0000173 kvClient, err := newKVClient(ctx, Backend, Addr, KVSTORE_RETRY_TIMEOUT)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400174 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000175 logger.Fatalw(ctx, "Failed to init KV client\n", log.Fields{"err": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400176 return nil
177 }
divyadesaid26f6b12020-03-19 06:30:28 +0000178
179 var pathPrefix string
180 if configClient {
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800181 pathPrefix = fmt.Sprintf(PATH_PREFIX_FOR_CONFIG, basePathKvStore)
divyadesaid26f6b12020-03-19 06:30:28 +0000182 } else {
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800183 pathPrefix = fmt.Sprintf(PATH_PREFIX, basePathKvStore, Technology)
divyadesaid26f6b12020-03-19 06:30:28 +0000184 }
185
sbarbaria8910ba2019-11-05 10:12:23 -0500186 kvbackend := &db.Backend{
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400187 Client: kvClient,
188 StoreType: Backend,
Neha Sharma3f221ae2020-04-29 19:02:12 +0000189 Address: Addr,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400190 Timeout: KVSTORE_RETRY_TIMEOUT,
divyadesaid26f6b12020-03-19 06:30:28 +0000191 PathPrefix: pathPrefix}
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400192
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400193 return kvbackend
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400194}
195
196// NewPONResourceManager creates a new PON resource manager.
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800197func NewPONResourceManager(ctx context.Context, Technology string, DeviceType string, DeviceID string, Backend string, Address string, basePathKvStore string) (*PONResourceManager, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400198 var PONMgr PONResourceManager
199 PONMgr.Technology = Technology
200 PONMgr.DeviceType = DeviceType
201 PONMgr.DeviceID = DeviceID
202 PONMgr.Backend = Backend
Neha Sharma3f221ae2020-04-29 19:02:12 +0000203 PONMgr.Address = Address
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800204 PONMgr.KVStore = SetKVClient(ctx, Technology, Backend, Address, false, basePathKvStore)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400205 if PONMgr.KVStore == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000206 logger.Error(ctx, "KV Client initilization failed")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400207 return nil, errors.New("Failed to init KV client")
208 }
divyadesaid26f6b12020-03-19 06:30:28 +0000209 // init kv client to read from the config path
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800210 PONMgr.KVStoreForConfig = SetKVClient(ctx, Technology, Backend, Address, true, basePathKvStore)
divyadesaid26f6b12020-03-19 06:30:28 +0000211 if PONMgr.KVStoreForConfig == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000212 logger.Error(ctx, "KV Config Client initilization failed")
divyadesaid26f6b12020-03-19 06:30:28 +0000213 return nil, errors.New("Failed to init KV Config client")
214 }
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400215 // Initialize techprofile for this technology
Neha Sharma96b7bf22020-06-15 10:37:32 +0000216 if PONMgr.TechProfileMgr, _ = tp.NewTechProfile(ctx, &PONMgr, Backend, Address); PONMgr.TechProfileMgr == nil {
217 logger.Error(ctx, "Techprofile initialization failed")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400218 return nil, errors.New("Failed to init tech profile")
219 }
220 PONMgr.PonResourceRanges = make(map[string]interface{})
221 PONMgr.SharedResourceMgrs = make(map[string]*PONResourceManager)
222 PONMgr.SharedIdxByType = make(map[string]string)
223 PONMgr.SharedIdxByType[ONU_ID] = ONU_ID_SHARED_IDX
224 PONMgr.SharedIdxByType[ALLOC_ID] = ALLOC_ID_SHARED_IDX
225 PONMgr.SharedIdxByType[GEMPORT_ID] = GEMPORT_ID_SHARED_IDX
226 PONMgr.SharedIdxByType[FLOW_ID] = FLOW_ID_SHARED_IDX
227 PONMgr.IntfIDs = make([]uint32, NUM_OF_PON_INTF)
228 PONMgr.OLTModel = DeviceType
229 return &PONMgr, nil
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400230}
231
232/*
233 Initialize PON resource ranges with config fetched from kv store.
234 return boolean: True if PON resource ranges initialized else false
235 Try to initialize the PON Resource Ranges from KV store based on the
236 OLT model key, if available
237*/
238
npujarec5762e2020-01-01 14:08:48 +0530239func (PONRMgr *PONResourceManager) InitResourceRangesFromKVStore(ctx context.Context) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400240 //Initialize PON resource ranges with config fetched from kv store.
241 //:return boolean: True if PON resource ranges initialized else false
242 // Try to initialize the PON Resource Ranges from KV store based on the
243 // OLT model key, if available
244 if PONRMgr.OLTModel == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000245 logger.Error(ctx, "Failed to get OLT model")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400246 return false
247 }
248 Path := fmt.Sprintf(PON_RESOURCE_RANGE_CONFIG_PATH, PONRMgr.OLTModel)
249 //get resource from kv store
npujarec5762e2020-01-01 14:08:48 +0530250 Result, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400251 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000252 logger.Debugf(ctx, "Error in fetching resource %s from KV strore", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400253 return false
254 }
255 if Result == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000256 logger.Debug(ctx, "There may be no resources in the KV store in case of fresh bootup, return true")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400257 return false
258 }
259 //update internal ranges from kv ranges. If there are missing
260 // values in the KV profile, continue to use the defaults
261 Value, err := ToByte(Result.Value)
262 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000263 logger.Error(ctx, "Failed to convert kvpair to byte string")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400264 return false
265 }
266 if err := json.Unmarshal(Value, &PONRMgr.PonResourceRanges); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000267 logger.Error(ctx, "Failed to Unmarshal json byte")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400268 return false
269 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000270 logger.Debug(ctx, "Init resource ranges from kvstore success")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400271 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400272}
273
Neha Sharma96b7bf22020-06-15 10:37:32 +0000274func (PONRMgr *PONResourceManager) UpdateRanges(ctx context.Context, StartIDx string, StartID uint32, EndIDx string, EndID uint32,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400275 SharedIDx string, SharedPoolID uint32, RMgr *PONResourceManager) {
276 /*
277 Update the ranges for all reosurce type in the intermnal maps
278 param: resource type start index
279 param: start ID
280 param: resource type end index
281 param: end ID
282 param: resource type shared index
283 param: shared pool id
284 param: global resource manager
285 */
Neha Sharma96b7bf22020-06-15 10:37:32 +0000286 logger.Debugf(ctx, "update ranges for %s, %d", StartIDx, StartID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400287
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400288 if StartID != 0 {
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400289 if (PONRMgr.PonResourceRanges[StartIDx] == nil) || (PONRMgr.PonResourceRanges[StartIDx].(uint32) < StartID) {
290 PONRMgr.PonResourceRanges[StartIDx] = StartID
291 }
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400292 }
293 if EndID != 0 {
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400294 if (PONRMgr.PonResourceRanges[EndIDx] == nil) || (PONRMgr.PonResourceRanges[EndIDx].(uint32) > EndID) {
295 PONRMgr.PonResourceRanges[EndIDx] = EndID
296 }
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400297 }
298 //if SharedPoolID != 0 {
299 PONRMgr.PonResourceRanges[SharedIDx] = SharedPoolID
300 //}
301 if RMgr != nil {
302 PONRMgr.SharedResourceMgrs[SharedIDx] = RMgr
303 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400304}
305
Neha Sharma96b7bf22020-06-15 10:37:32 +0000306func (PONRMgr *PONResourceManager) InitDefaultPONResourceRanges(ctx context.Context,
307 ONUIDStart uint32,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400308 ONUIDEnd uint32,
309 ONUIDSharedPoolID uint32,
310 AllocIDStart uint32,
311 AllocIDEnd uint32,
312 AllocIDSharedPoolID uint32,
313 GEMPortIDStart uint32,
314 GEMPortIDEnd uint32,
315 GEMPortIDSharedPoolID uint32,
316 FlowIDStart uint32,
317 FlowIDEnd uint32,
318 FlowIDSharedPoolID uint32,
319 UNIIDStart uint32,
320 UNIIDEnd uint32,
321 NoOfPONPorts uint32,
322 IntfIDs []uint32) bool {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400323
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400324 /*Initialize default PON resource ranges
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400325
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400326 :param onu_id_start_idx: onu id start index
327 :param onu_id_end_idx: onu id end index
328 :param onu_id_shared_pool_id: pool idx for id shared by all intfs or None for no sharing
329 :param alloc_id_start_idx: alloc id start index
330 :param alloc_id_end_idx: alloc id end index
331 :param alloc_id_shared_pool_id: pool idx for alloc id shared by all intfs or None for no sharing
332 :param gemport_id_start_idx: gemport id start index
333 :param gemport_id_end_idx: gemport id end index
334 :param gemport_id_shared_pool_id: pool idx for gemport id shared by all intfs or None for no sharing
335 :param flow_id_start_idx: flow id start index
336 :param flow_id_end_idx: flow id end index
337 :param flow_id_shared_pool_id: pool idx for flow id shared by all intfs or None for no sharing
338 :param num_of_pon_ports: number of PON ports
339 :param intf_ids: interfaces serviced by this manager
340 */
Neha Sharma96b7bf22020-06-15 10:37:32 +0000341 PONRMgr.UpdateRanges(ctx, ONU_ID_START_IDX, ONUIDStart, ONU_ID_END_IDX, ONUIDEnd, ONU_ID_SHARED_IDX, ONUIDSharedPoolID, nil)
342 PONRMgr.UpdateRanges(ctx, ALLOC_ID_START_IDX, AllocIDStart, ALLOC_ID_END_IDX, AllocIDEnd, ALLOC_ID_SHARED_IDX, AllocIDSharedPoolID, nil)
343 PONRMgr.UpdateRanges(ctx, GEMPORT_ID_START_IDX, GEMPortIDStart, GEMPORT_ID_END_IDX, GEMPortIDEnd, GEMPORT_ID_SHARED_IDX, GEMPortIDSharedPoolID, nil)
344 PONRMgr.UpdateRanges(ctx, FLOW_ID_START_IDX, FlowIDStart, FLOW_ID_END_IDX, FlowIDEnd, FLOW_ID_SHARED_IDX, FlowIDSharedPoolID, nil)
345 PONRMgr.UpdateRanges(ctx, UNI_ID_START_IDX, UNIIDStart, UNI_ID_END_IDX, UNIIDEnd, "", 0, nil)
346 logger.Debug(ctx, "Initialize default range values")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400347 var i uint32
348 if IntfIDs == nil {
349 for i = 0; i < NoOfPONPorts; i++ {
350 PONRMgr.IntfIDs = append(PONRMgr.IntfIDs, i)
351 }
352 } else {
353 PONRMgr.IntfIDs = IntfIDs
354 }
355 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400356}
357
npujarec5762e2020-01-01 14:08:48 +0530358func (PONRMgr *PONResourceManager) InitDeviceResourcePool(ctx context.Context) error {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400359
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400360 //Initialize resource pool for all PON ports.
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400361
Neha Sharma96b7bf22020-06-15 10:37:32 +0000362 logger.Debug(ctx, "Init resource ranges")
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400363
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400364 var err error
365 for _, Intf := range PONRMgr.IntfIDs {
366 SharedPoolID := PONRMgr.PonResourceRanges[ONU_ID_SHARED_IDX].(uint32)
367 if SharedPoolID != 0 {
368 Intf = SharedPoolID
369 }
npujarec5762e2020-01-01 14:08:48 +0530370 if err = PONRMgr.InitResourceIDPool(ctx, Intf, ONU_ID,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400371 PONRMgr.PonResourceRanges[ONU_ID_START_IDX].(uint32),
372 PONRMgr.PonResourceRanges[ONU_ID_END_IDX].(uint32)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000373 logger.Error(ctx, "Failed to init ONU ID resource pool")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400374 return err
375 }
376 if SharedPoolID != 0 {
377 break
378 }
379 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400380
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400381 for _, Intf := range PONRMgr.IntfIDs {
382 SharedPoolID := PONRMgr.PonResourceRanges[ALLOC_ID_SHARED_IDX].(uint32)
383 if SharedPoolID != 0 {
384 Intf = SharedPoolID
385 }
npujarec5762e2020-01-01 14:08:48 +0530386 if err = PONRMgr.InitResourceIDPool(ctx, Intf, ALLOC_ID,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400387 PONRMgr.PonResourceRanges[ALLOC_ID_START_IDX].(uint32),
388 PONRMgr.PonResourceRanges[ALLOC_ID_END_IDX].(uint32)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000389 logger.Error(ctx, "Failed to init ALLOC ID resource pool ")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400390 return err
391 }
392 if SharedPoolID != 0 {
393 break
394 }
395 }
396 for _, Intf := range PONRMgr.IntfIDs {
397 SharedPoolID := PONRMgr.PonResourceRanges[GEMPORT_ID_SHARED_IDX].(uint32)
398 if SharedPoolID != 0 {
399 Intf = SharedPoolID
400 }
npujarec5762e2020-01-01 14:08:48 +0530401 if err = PONRMgr.InitResourceIDPool(ctx, Intf, GEMPORT_ID,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400402 PONRMgr.PonResourceRanges[GEMPORT_ID_START_IDX].(uint32),
403 PONRMgr.PonResourceRanges[GEMPORT_ID_END_IDX].(uint32)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000404 logger.Error(ctx, "Failed to init GEMPORT ID resource pool")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400405 return err
406 }
407 if SharedPoolID != 0 {
408 break
409 }
410 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400411
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400412 for _, Intf := range PONRMgr.IntfIDs {
413 SharedPoolID := PONRMgr.PonResourceRanges[FLOW_ID_SHARED_IDX].(uint32)
414 if SharedPoolID != 0 {
415 Intf = SharedPoolID
416 }
npujarec5762e2020-01-01 14:08:48 +0530417 if err = PONRMgr.InitResourceIDPool(ctx, Intf, FLOW_ID,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400418 PONRMgr.PonResourceRanges[FLOW_ID_START_IDX].(uint32),
419 PONRMgr.PonResourceRanges[FLOW_ID_END_IDX].(uint32)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000420 logger.Error(ctx, "Failed to init FLOW ID resource pool")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400421 return err
422 }
423 if SharedPoolID != 0 {
424 break
425 }
426 }
427 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400428}
429
npujarec5762e2020-01-01 14:08:48 +0530430func (PONRMgr *PONResourceManager) ClearDeviceResourcePool(ctx context.Context) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -0400431
432 //Clear resource pool for all PON ports.
433
Neha Sharma96b7bf22020-06-15 10:37:32 +0000434 logger.Debug(ctx, "Clear resource ranges")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400435
436 for _, Intf := range PONRMgr.IntfIDs {
437 SharedPoolID := PONRMgr.PonResourceRanges[ONU_ID_SHARED_IDX].(uint32)
438 if SharedPoolID != 0 {
439 Intf = SharedPoolID
440 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000441 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, ONU_ID); !status {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000442 logger.Error(ctx, "Failed to clear ONU ID resource pool")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400443 return errors.New("Failed to clear ONU ID resource pool")
444 }
445 if SharedPoolID != 0 {
446 break
447 }
448 }
449
450 for _, Intf := range PONRMgr.IntfIDs {
451 SharedPoolID := PONRMgr.PonResourceRanges[ALLOC_ID_SHARED_IDX].(uint32)
452 if SharedPoolID != 0 {
453 Intf = SharedPoolID
454 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000455 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, ALLOC_ID); !status {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000456 logger.Error(ctx, "Failed to clear ALLOC ID resource pool ")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400457 return errors.New("Failed to clear ALLOC ID resource pool")
458 }
459 if SharedPoolID != 0 {
460 break
461 }
462 }
463 for _, Intf := range PONRMgr.IntfIDs {
464 SharedPoolID := PONRMgr.PonResourceRanges[GEMPORT_ID_SHARED_IDX].(uint32)
465 if SharedPoolID != 0 {
466 Intf = SharedPoolID
467 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000468 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, GEMPORT_ID); !status {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000469 logger.Error(ctx, "Failed to clear GEMPORT ID resource pool")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400470 return errors.New("Failed to clear GEMPORT ID resource pool")
471 }
472 if SharedPoolID != 0 {
473 break
474 }
475 }
476
477 for _, Intf := range PONRMgr.IntfIDs {
478 SharedPoolID := PONRMgr.PonResourceRanges[FLOW_ID_SHARED_IDX].(uint32)
479 if SharedPoolID != 0 {
480 Intf = SharedPoolID
481 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000482 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, FLOW_ID); !status {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000483 logger.Error(ctx, "Failed to clear FLOW ID resource pool")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400484 return errors.New("Failed to clear FLOW ID resource pool")
485 }
486 if SharedPoolID != 0 {
487 break
488 }
489 }
490 return nil
491}
492
npujarec5762e2020-01-01 14:08:48 +0530493func (PONRMgr *PONResourceManager) InitResourceIDPool(ctx context.Context, Intf uint32, ResourceType string, StartID uint32, EndID uint32) error {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400494
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400495 /*Initialize Resource ID pool for a given Resource Type on a given PON Port
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400496
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400497 :param pon_intf_id: OLT PON interface id
498 :param resource_type: String to identify type of resource
499 :param start_idx: start index for onu id pool
500 :param end_idx: end index for onu id pool
501 :return boolean: True if resource id pool initialized else false
502 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400503
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400504 // delegate to the master instance if sharing enabled across instances
505 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
506 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujarec5762e2020-01-01 14:08:48 +0530507 return SharedResourceMgr.InitResourceIDPool(ctx, Intf, ResourceType, StartID, EndID)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400508 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400509
Neha Sharma96b7bf22020-06-15 10:37:32 +0000510 Path := PONRMgr.GetPath(ctx, Intf, ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400511 if Path == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000512 logger.Errorf(ctx, "Failed to get path for resource type %s", ResourceType)
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000513 return fmt.Errorf("Failed to get path for resource type %s", ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400514 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400515
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400516 //In case of adapter reboot and reconciliation resource in kv store
517 //checked for its presence if not kv store update happens
npujarec5762e2020-01-01 14:08:48 +0530518 Res, err := PONRMgr.GetResource(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400519 if (err == nil) && (Res != nil) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000520 logger.Debugf(ctx, "Resource %s already present in store ", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400521 return nil
522 } else {
divyadesaid26f6b12020-03-19 06:30:28 +0000523 var excluded []uint32
524 if ResourceType == GEMPORT_ID {
525 //get gem port ids defined in the KV store, if any, and exclude them from the gem port id pool
526 if reservedGemPortIds, defined := PONRMgr.getReservedGemPortIdsFromKVStore(ctx); defined {
527 excluded = reservedGemPortIds
Neha Sharma96b7bf22020-06-15 10:37:32 +0000528 logger.Debugw(ctx, "Excluding some ports from GEM port id pool", log.Fields{"excluded gem ports": excluded})
divyadesaid26f6b12020-03-19 06:30:28 +0000529 }
530 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000531 FormatResult, err := PONRMgr.FormatResource(ctx, Intf, StartID, EndID, excluded)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400532 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000533 logger.Errorf(ctx, "Failed to format resource")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400534 return err
535 }
536 // Add resource as json in kv store.
npujarec5762e2020-01-01 14:08:48 +0530537 err = PONRMgr.KVStore.Put(ctx, Path, FormatResult)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400538 if err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000539 logger.Debug(ctx, "Successfuly posted to kv store")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400540 return err
541 }
542 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400543
Neha Sharma96b7bf22020-06-15 10:37:32 +0000544 logger.Debug(ctx, "Error initializing pool")
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400545
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400546 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400547}
548
divyadesaid26f6b12020-03-19 06:30:28 +0000549func (PONRMgr *PONResourceManager) getReservedGemPortIdsFromKVStore(ctx context.Context) ([]uint32, bool) {
550 var reservedGemPortIds []uint32
551 // read reserved gem ports from the config path
552 KvPair, err := PONRMgr.KVStoreForConfig.Get(ctx, RESERVED_GEMPORT_IDS_PATH)
553 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000554 logger.Errorw(ctx, "Unable to get reserved GEM port ids from the kv store", log.Fields{"err": err})
divyadesaid26f6b12020-03-19 06:30:28 +0000555 return reservedGemPortIds, false
556 }
557 if KvPair == nil || KvPair.Value == nil {
558 //no reserved gem port defined in the store
559 return reservedGemPortIds, false
560 }
561 Val, err := kvstore.ToByte(KvPair.Value)
562 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000563 logger.Errorw(ctx, "Failed to convert reserved gem port ids into byte array", log.Fields{"err": err})
divyadesaid26f6b12020-03-19 06:30:28 +0000564 return reservedGemPortIds, false
565 }
566 if err = json.Unmarshal(Val, &reservedGemPortIds); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000567 logger.Errorw(ctx, "Failed to unmarshal reservedGemPortIds", log.Fields{"err": err})
divyadesaid26f6b12020-03-19 06:30:28 +0000568 return reservedGemPortIds, false
569 }
570 return reservedGemPortIds, true
571}
572
Neha Sharma96b7bf22020-06-15 10:37:32 +0000573func (PONRMgr *PONResourceManager) FormatResource(ctx context.Context, IntfID uint32, StartIDx uint32, EndIDx uint32,
divyadesaid26f6b12020-03-19 06:30:28 +0000574 Excluded []uint32) ([]byte, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400575 /*
576 Format resource as json.
577 :param pon_intf_id: OLT PON interface id
578 :param start_idx: start index for id pool
579 :param end_idx: end index for id pool
divyadesaid26f6b12020-03-19 06:30:28 +0000580 :Id values to be Excluded from the pool
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400581 :return dictionary: resource formatted as map
582 */
583 // Format resource as json to be stored in backend store
584 Resource := make(map[string]interface{})
585 Resource[PON_INTF_ID] = IntfID
586 Resource[START_IDX] = StartIDx
587 Resource[END_IDX] = EndIDx
588 /*
589 Resource pool stored in backend store as binary string.
590 Tracking the resource allocation will be done by setting the bits \
591 in the byte array. The index set will be the resource number allocated.
592 */
593 var TSData *bitmap.Threadsafe
594 if TSData = bitmap.NewTS(int(EndIDx)); TSData == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000595 logger.Error(ctx, "Failed to create a bitmap")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400596 return nil, errors.New("Failed to create bitmap")
597 }
divyadesaid26f6b12020-03-19 06:30:28 +0000598 for _, excludedID := range Excluded {
599 if excludedID < StartIDx || excludedID > EndIDx {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000600 logger.Warnf(ctx, "Cannot reserve %d. It must be in the range of [%d, %d]", excludedID,
divyadesaid26f6b12020-03-19 06:30:28 +0000601 StartIDx, EndIDx)
602 continue
603 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000604 PONRMgr.reserveID(ctx, TSData, StartIDx, excludedID)
divyadesaid26f6b12020-03-19 06:30:28 +0000605 }
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400606 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 -0400607
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400608 Value, err := json.Marshal(Resource)
609 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000610 logger.Errorf(ctx, "Failed to marshall resource")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400611 return nil, err
612 }
613 return Value, err
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400614}
npujarec5762e2020-01-01 14:08:48 +0530615func (PONRMgr *PONResourceManager) GetResource(ctx context.Context, Path string) (map[string]interface{}, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400616 /*
617 Get resource from kv store.
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400618
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400619 :param path: path to get resource
620 :return: resource if resource present in kv store else None
621 */
622 //get resource from kv store
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400623
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400624 var Value []byte
625 Result := make(map[string]interface{})
626 var Str string
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400627
npujarec5762e2020-01-01 14:08:48 +0530628 Resource, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400629 if (err != nil) || (Resource == nil) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000630 logger.Debugf(ctx, "Resource unavailable at %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400631 return nil, err
632 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400633
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400634 Value, err = ToByte(Resource.Value)
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000635 if err != nil {
636 return nil, err
637 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400638
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400639 // decode resource fetched from backend store to dictionary
640 err = json.Unmarshal(Value, &Result)
641 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000642 logger.Error(ctx, "Failed to decode resource")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400643 return Result, err
644 }
645 /*
646 resource pool in backend store stored as binary string whereas to
647 access the pool to generate/release IDs it need to be converted
648 as BitArray
649 */
650 Str, err = ToString(Result[POOL])
651 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000652 logger.Error(ctx, "Failed to conver to kv pair to string")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400653 return Result, err
654 }
655 Decode64, _ := base64.StdEncoding.DecodeString(Str)
656 Result[POOL], err = ToByte(Decode64)
657 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000658 logger.Error(ctx, "Failed to convert resource pool to byte")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400659 return Result, err
660 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400661
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400662 return Result, err
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400663}
664
Neha Sharma96b7bf22020-06-15 10:37:32 +0000665func (PONRMgr *PONResourceManager) GetPath(ctx context.Context, IntfID uint32, ResourceType string) string {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400666 /*
667 Get path for given resource type.
668 :param pon_intf_id: OLT PON interface id
669 :param resource_type: String to identify type of resource
670 :return: path for given resource type
671 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400672
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400673 /*
674 Get the shared pool for the given resource type.
675 all the resource ranges and the shared resource maps are initialized during the init.
676 */
677 SharedPoolID := PONRMgr.PonResourceRanges[PONRMgr.SharedIdxByType[ResourceType]].(uint32)
678 if SharedPoolID != 0 {
679 IntfID = SharedPoolID
680 }
681 var Path string
682 if ResourceType == ONU_ID {
683 Path = fmt.Sprintf(ONU_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
684 } else if ResourceType == ALLOC_ID {
685 Path = fmt.Sprintf(ALLOC_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
686 } else if ResourceType == GEMPORT_ID {
687 Path = fmt.Sprintf(GEMPORT_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
688 } else if ResourceType == FLOW_ID {
689 Path = fmt.Sprintf(FLOW_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
690 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000691 logger.Error(ctx, "Invalid resource pool identifier")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400692 }
693 return Path
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400694}
695
npujarec5762e2020-01-01 14:08:48 +0530696func (PONRMgr *PONResourceManager) GetResourceID(ctx context.Context, IntfID uint32, ResourceType string, NumIDs uint32) ([]uint32, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400697 /*
698 Create alloc/gemport/onu/flow id for given OLT PON interface.
699 :param pon_intf_id: OLT PON interface id
700 :param resource_type: String to identify type of resource
701 :param num_of_id: required number of ids
702 :return list/uint32/None: list, uint32 or None if resource type is
703 alloc_id/gemport_id, onu_id or invalid type respectively
704 */
705 if NumIDs < 1 {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000706 logger.Error(ctx, "Invalid number of resources requested")
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000707 return nil, fmt.Errorf("Invalid number of resources requested %d", NumIDs)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400708 }
709 // delegate to the master instance if sharing enabled across instances
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400710
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400711 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
712 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujarec5762e2020-01-01 14:08:48 +0530713 return SharedResourceMgr.GetResourceID(ctx, IntfID, ResourceType, NumIDs)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400714 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000715 logger.Debugf(ctx, "Fetching resource from %s rsrc mgr for resource %s", PONRMgr.Globalorlocal, ResourceType)
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400716
Neha Sharma96b7bf22020-06-15 10:37:32 +0000717 Path := PONRMgr.GetPath(ctx, IntfID, ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400718 if Path == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000719 logger.Errorf(ctx, "Failed to get path for resource type %s", ResourceType)
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000720 return nil, fmt.Errorf("Failed to get path for resource type %s", ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400721 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000722 logger.Debugf(ctx, "Get resource for type %s on path %s", ResourceType, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400723 var Result []uint32
724 var NextID uint32
npujarec5762e2020-01-01 14:08:48 +0530725 Resource, err := PONRMgr.GetResource(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400726 if (err == nil) && (ResourceType == ONU_ID) || (ResourceType == FLOW_ID) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000727 if NextID, err = PONRMgr.GenerateNextID(ctx, Resource); err != nil {
728 logger.Error(ctx, "Failed to Generate ID")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400729 return Result, err
730 }
731 Result = append(Result, NextID)
732 } else if (err == nil) && ((ResourceType == GEMPORT_ID) || (ResourceType == ALLOC_ID)) {
733 if NumIDs == 1 {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000734 if NextID, err = PONRMgr.GenerateNextID(ctx, Resource); err != nil {
735 logger.Error(ctx, "Failed to Generate ID")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400736 return Result, err
737 }
738 Result = append(Result, NextID)
739 } else {
740 for NumIDs > 0 {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000741 if NextID, err = PONRMgr.GenerateNextID(ctx, Resource); err != nil {
742 logger.Error(ctx, "Failed to Generate ID")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400743 return Result, err
744 }
745 Result = append(Result, NextID)
746 NumIDs--
747 }
748 }
749 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000750 logger.Error(ctx, "get resource failed")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400751 return Result, err
752 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400753
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400754 //Update resource in kv store
npujarec5762e2020-01-01 14:08:48 +0530755 if PONRMgr.UpdateResource(ctx, Path, Resource) != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000756 logger.Errorf(ctx, "Failed to update resource %s", Path)
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000757 return nil, fmt.Errorf("Failed to update resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400758 }
759 return Result, nil
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400760}
761
762func checkValidResourceType(ResourceType string) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400763 KnownResourceTypes := []string{ONU_ID, ALLOC_ID, GEMPORT_ID, FLOW_ID}
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400764
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400765 for _, v := range KnownResourceTypes {
766 if v == ResourceType {
767 return true
768 }
769 }
770 return false
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400771}
772
npujarec5762e2020-01-01 14:08:48 +0530773func (PONRMgr *PONResourceManager) FreeResourceID(ctx context.Context, IntfID uint32, ResourceType string, ReleaseContent []uint32) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400774 /*
775 Release alloc/gemport/onu/flow id for given OLT PON interface.
776 :param pon_intf_id: OLT PON interface id
777 :param resource_type: String to identify type of resource
778 :param release_content: required number of ids
779 :return boolean: True if all IDs in given release_content release else False
780 */
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000781 if !checkValidResourceType(ResourceType) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000782 logger.Error(ctx, "Invalid resource type")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400783 return false
784 }
785 if ReleaseContent == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000786 logger.Debug(ctx, "Nothing to release")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400787 return true
788 }
789 // delegate to the master instance if sharing enabled across instances
790 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
791 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujarec5762e2020-01-01 14:08:48 +0530792 return SharedResourceMgr.FreeResourceID(ctx, IntfID, ResourceType, ReleaseContent)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400793 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000794 Path := PONRMgr.GetPath(ctx, IntfID, ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400795 if Path == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000796 logger.Error(ctx, "Failed to get path")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400797 return false
798 }
npujarec5762e2020-01-01 14:08:48 +0530799 Resource, err := PONRMgr.GetResource(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400800 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000801 logger.Error(ctx, "Failed to get resource")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400802 return false
803 }
804 for _, Val := range ReleaseContent {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000805 PONRMgr.ReleaseID(ctx, Resource, Val)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400806 }
npujarec5762e2020-01-01 14:08:48 +0530807 if PONRMgr.UpdateResource(ctx, Path, Resource) != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000808 logger.Errorf(ctx, "Free resource for %s failed", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400809 return false
810 }
811 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400812}
813
npujarec5762e2020-01-01 14:08:48 +0530814func (PONRMgr *PONResourceManager) UpdateResource(ctx context.Context, Path string, Resource map[string]interface{}) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400815 /*
816 Update resource in resource kv store.
817 :param path: path to update resource
818 :param resource: resource need to be updated
819 :return boolean: True if resource updated in kv store else False
820 */
821 // TODO resource[POOL] = resource[POOL].bin
822 Value, err := json.Marshal(Resource)
823 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000824 logger.Error(ctx, "failed to Marshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400825 return err
826 }
npujarec5762e2020-01-01 14:08:48 +0530827 err = PONRMgr.KVStore.Put(ctx, Path, Value)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400828 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000829 logger.Error(ctx, "failed to put data to kv store %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400830 return err
831 }
832 return nil
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400833}
834
npujarec5762e2020-01-01 14:08:48 +0530835func (PONRMgr *PONResourceManager) ClearResourceIDPool(ctx context.Context, contIntfID uint32, ResourceType string) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400836 /*
837 Clear Resource Pool for a given Resource Type on a given PON Port.
838 :return boolean: True if removed else False
839 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400840
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400841 // delegate to the master instance if sharing enabled across instances
842 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
843 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujarec5762e2020-01-01 14:08:48 +0530844 return SharedResourceMgr.ClearResourceIDPool(ctx, contIntfID, ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400845 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000846 Path := PONRMgr.GetPath(ctx, contIntfID, ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400847 if Path == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000848 logger.Error(ctx, "Failed to get path")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400849 return false
850 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400851
npujarec5762e2020-01-01 14:08:48 +0530852 if err := PONRMgr.KVStore.Delete(ctx, Path); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000853 logger.Errorf(ctx, "Failed to delete resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400854 return false
855 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000856 logger.Debugf(ctx, "Cleared resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400857 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400858}
859
npujarec5762e2020-01-01 14:08:48 +0530860func (PONRMgr PONResourceManager) InitResourceMap(ctx context.Context, PONIntfONUID string) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400861 /*
862 Initialize resource map
863 :param pon_intf_onu_id: reference of PON interface id and onu id
864 */
865 // initialize pon_intf_onu_id tuple to alloc_ids map
866 AllocIDPath := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
867 var AllocIDs []byte
npujarec5762e2020-01-01 14:08:48 +0530868 Result := PONRMgr.KVStore.Put(ctx, AllocIDPath, AllocIDs)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400869 if Result != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000870 logger.Error(ctx, "Failed to update the KV store")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400871 return
872 }
873 // initialize pon_intf_onu_id tuple to gemport_ids map
874 GEMPortIDPath := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
875 var GEMPortIDs []byte
npujarec5762e2020-01-01 14:08:48 +0530876 Result = PONRMgr.KVStore.Put(ctx, GEMPortIDPath, GEMPortIDs)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400877 if Result != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000878 logger.Error(ctx, "Failed to update the KV store")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400879 return
880 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400881}
882
npujarec5762e2020-01-01 14:08:48 +0530883func (PONRMgr PONResourceManager) RemoveResourceMap(ctx context.Context, PONIntfONUID string) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400884 /*
885 Remove resource map
886 :param pon_intf_onu_id: reference of PON interface id and onu id
887 */
888 // remove pon_intf_onu_id tuple to alloc_ids map
889 var err error
890 AllocIDPath := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujarec5762e2020-01-01 14:08:48 +0530891 if err = PONRMgr.KVStore.Delete(ctx, AllocIDPath); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000892 logger.Errorf(ctx, "Failed to remove resource %s", AllocIDPath)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400893 return false
894 }
895 // remove pon_intf_onu_id tuple to gemport_ids map
896 GEMPortIDPath := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujarec5762e2020-01-01 14:08:48 +0530897 err = PONRMgr.KVStore.Delete(ctx, GEMPortIDPath)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400898 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000899 logger.Errorf(ctx, "Failed to remove resource %s", GEMPortIDPath)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400900 return false
901 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400902
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400903 FlowIDPath := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujarec5762e2020-01-01 14:08:48 +0530904 if FlowIDs, err := PONRMgr.KVStore.List(ctx, FlowIDPath); err != nil {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400905 for _, Flow := range FlowIDs {
906 FlowIDInfoPath := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, PONIntfONUID, Flow.Value)
npujarec5762e2020-01-01 14:08:48 +0530907 if err = PONRMgr.KVStore.Delete(ctx, FlowIDInfoPath); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000908 logger.Errorf(ctx, "Failed to remove resource %s", FlowIDInfoPath)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400909 return false
910 }
911 }
912 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400913
npujarec5762e2020-01-01 14:08:48 +0530914 if err = PONRMgr.KVStore.Delete(ctx, FlowIDPath); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000915 logger.Errorf(ctx, "Failed to remove resource %s", FlowIDPath)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400916 return false
917 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400918
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400919 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400920}
921
npujarec5762e2020-01-01 14:08:48 +0530922func (PONRMgr *PONResourceManager) GetCurrentAllocIDForOnu(ctx context.Context, IntfONUID string) []uint32 {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400923 /*
924 Get currently configured alloc ids for given pon_intf_onu_id
925 :param pon_intf_onu_id: reference of PON interface id and onu id
926 :return list: List of alloc_ids if available, else None
927 */
928 Path := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400929
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400930 var Data []uint32
npujarec5762e2020-01-01 14:08:48 +0530931 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400932 if err == nil {
933 if Value != nil {
934 Val, err := ToByte(Value.Value)
935 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000936 logger.Errorw(ctx, "Failed to convert into byte array", log.Fields{"error": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400937 return Data
938 }
939 if err = json.Unmarshal(Val, &Data); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000940 logger.Error(ctx, "Failed to unmarshal", log.Fields{"error": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400941 return Data
942 }
943 }
944 }
945 return Data
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400946}
947
npujarec5762e2020-01-01 14:08:48 +0530948func (PONRMgr *PONResourceManager) GetCurrentGEMPortIDsForOnu(ctx context.Context, IntfONUID string) []uint32 {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400949 /*
950 Get currently configured gemport ids for given pon_intf_onu_id
951 :param pon_intf_onu_id: reference of PON interface id and onu id
952 :return list: List of gemport IDs if available, else None
953 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400954
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400955 Path := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000956 logger.Debugf(ctx, "Getting current gemports for %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400957 var Data []uint32
npujarec5762e2020-01-01 14:08:48 +0530958 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400959 if err == nil {
960 if Value != nil {
961 Val, _ := ToByte(Value.Value)
962 if err = json.Unmarshal(Val, &Data); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000963 logger.Errorw(ctx, "Failed to unmarshal", log.Fields{"error": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400964 return Data
965 }
966 }
967 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000968 logger.Errorf(ctx, "Failed to get data from kvstore for %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400969 }
970 return Data
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400971}
972
npujarec5762e2020-01-01 14:08:48 +0530973func (PONRMgr *PONResourceManager) GetCurrentFlowIDsForOnu(ctx context.Context, IntfONUID string) []uint32 {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400974 /*
975 Get currently configured flow ids for given pon_intf_onu_id
976 :param pon_intf_onu_id: reference of PON interface id and onu id
977 :return list: List of Flow IDs if available, else None
978 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400979
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400980 Path := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400981
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400982 var Data []uint32
npujarec5762e2020-01-01 14:08:48 +0530983 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400984 if err == nil {
985 if Value != nil {
986 Val, _ := ToByte(Value.Value)
987 if err = json.Unmarshal(Val, &Data); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000988 logger.Error(ctx, "Failed to unmarshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400989 return Data
990 }
991 }
992 }
993 return Data
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400994}
995
npujarec5762e2020-01-01 14:08:48 +0530996func (PONRMgr *PONResourceManager) GetFlowIDInfo(ctx context.Context, IntfONUID string, FlowID uint32, Data interface{}) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400997 /*
998 Get flow details configured for the ONU.
999 :param pon_intf_onu_id: reference of PON interface id and onu id
1000 :param flow_id: Flow Id reference
1001 :param Data: Result
1002 :return error: nil if no error in getting from KV store
1003 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001004
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001005 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001006
npujarec5762e2020-01-01 14:08:48 +05301007 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001008 if err == nil {
1009 if Value != nil {
1010 Val, err := ToByte(Value.Value)
1011 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001012 logger.Errorw(ctx, "Failed to convert flowinfo into byte array", log.Fields{"error": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001013 return err
1014 }
1015 if err = json.Unmarshal(Val, Data); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001016 logger.Errorw(ctx, "Failed to unmarshal", log.Fields{"error": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001017 return err
1018 }
1019 }
1020 }
1021 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001022}
1023
npujarec5762e2020-01-01 14:08:48 +05301024func (PONRMgr *PONResourceManager) RemoveFlowIDInfo(ctx context.Context, IntfONUID string, FlowID uint32) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001025 /*
1026 Get flow_id details configured for the ONU.
1027 :param pon_intf_onu_id: reference of PON interface id and onu id
1028 :param flow_id: Flow Id reference
1029 */
1030 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001031
npujarec5762e2020-01-01 14:08:48 +05301032 if err := PONRMgr.KVStore.Delete(ctx, Path); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001033 logger.Errorf(ctx, "Falied to remove resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001034 return false
1035 }
1036 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001037}
1038
npujarec5762e2020-01-01 14:08:48 +05301039func (PONRMgr *PONResourceManager) UpdateAllocIdsForOnu(ctx context.Context, IntfONUID string, AllocIDs []uint32) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001040 /*
1041 Update currently configured alloc ids for given pon_intf_onu_id
1042 :param pon_intf_onu_id: reference of PON interface id and onu id
1043 :param alloc_ids: list of alloc ids
1044 */
1045 var Value []byte
1046 var err error
1047 Path := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
1048 Value, err = json.Marshal(AllocIDs)
1049 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001050 logger.Error(ctx, "failed to Marshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001051 return err
1052 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001053
npujarec5762e2020-01-01 14:08:48 +05301054 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001055 logger.Errorf(ctx, "Failed to update resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001056 return err
1057 }
1058 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001059}
1060
npujarec5762e2020-01-01 14:08:48 +05301061func (PONRMgr *PONResourceManager) UpdateGEMPortIDsForOnu(ctx context.Context, IntfONUID string, GEMPortIDs []uint32) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001062 /*
1063 Update currently configured gemport ids for given pon_intf_onu_id
1064 :param pon_intf_onu_id: reference of PON interface id and onu id
1065 :param gemport_ids: list of gem port ids
1066 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001067
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001068 var Value []byte
1069 var err error
1070 Path := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001071 logger.Debugf(ctx, "Updating gemport ids for %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001072 Value, err = json.Marshal(GEMPortIDs)
1073 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001074 logger.Error(ctx, "failed to Marshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001075 return err
1076 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001077
npujarec5762e2020-01-01 14:08:48 +05301078 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001079 logger.Errorf(ctx, "Failed to update resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001080 return err
1081 }
1082 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001083}
1084
1085func checkForFlowIDInList(FlowIDList []uint32, FlowID uint32) (bool, uint32) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001086 /*
1087 Check for a flow id in a given list of flow IDs.
1088 :param FLowIDList: List of Flow IDs
1089 :param FlowID: Flowd to check in the list
1090 : return true and the index if present false otherwise.
1091 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001092
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001093 for idx := range FlowIDList {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001094 if FlowID == FlowIDList[idx] {
1095 return true, uint32(idx)
1096 }
1097 }
1098 return false, 0
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001099}
1100
npujarec5762e2020-01-01 14:08:48 +05301101func (PONRMgr *PONResourceManager) UpdateFlowIDForOnu(ctx context.Context, IntfONUID string, FlowID uint32, Add bool) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001102 /*
1103 Update the flow_id list of the ONU (add or remove flow_id from the list)
1104 :param pon_intf_onu_id: reference of PON interface id and onu id
1105 :param flow_id: flow ID
1106 :param add: Boolean flag to indicate whether the flow_id should be
1107 added or removed from the list. Defaults to adding the flow.
1108 */
1109 var Value []byte
1110 var err error
1111 var RetVal bool
1112 var IDx uint32
1113 Path := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
npujarec5762e2020-01-01 14:08:48 +05301114 FlowIDs := PONRMgr.GetCurrentFlowIDsForOnu(ctx, IntfONUID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001115
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001116 if Add {
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001117 if RetVal, _ = checkForFlowIDInList(FlowIDs, FlowID); RetVal {
1118 return nil
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001119 }
1120 FlowIDs = append(FlowIDs, FlowID)
1121 } else {
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001122 if RetVal, IDx = checkForFlowIDInList(FlowIDs, FlowID); !RetVal {
1123 return nil
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001124 }
1125 // delete the index and shift
1126 FlowIDs = append(FlowIDs[:IDx], FlowIDs[IDx+1:]...)
1127 }
1128 Value, err = json.Marshal(FlowIDs)
1129 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001130 logger.Error(ctx, "Failed to Marshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001131 return err
1132 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001133
npujarec5762e2020-01-01 14:08:48 +05301134 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001135 logger.Errorf(ctx, "Failed to update resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001136 return err
1137 }
1138 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001139}
1140
npujarec5762e2020-01-01 14:08:48 +05301141func (PONRMgr *PONResourceManager) UpdateFlowIDInfoForOnu(ctx context.Context, IntfONUID string, FlowID uint32, FlowData interface{}) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001142 /*
1143 Update any metadata associated with the flow_id. The flow_data could be json
1144 or any of other data structure. The resource manager doesnt care
1145 :param pon_intf_onu_id: reference of PON interface id and onu id
1146 :param flow_id: Flow ID
1147 :param flow_data: Flow data blob
1148 */
1149 var Value []byte
1150 var err error
1151 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
1152 Value, err = json.Marshal(FlowData)
1153 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001154 logger.Error(ctx, "failed to Marshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001155 return err
1156 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001157
npujarec5762e2020-01-01 14:08:48 +05301158 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001159 logger.Errorf(ctx, "Failed to update resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001160 return err
1161 }
1162 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001163}
1164
Neha Sharma96b7bf22020-06-15 10:37:32 +00001165func (PONRMgr *PONResourceManager) GenerateNextID(ctx context.Context, Resource map[string]interface{}) (uint32, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001166 /*
1167 Generate unique id having OFFSET as start
1168 :param resource: resource used to generate ID
1169 :return uint32: generated id
1170 */
1171 ByteArray, err := ToByte(Resource[POOL])
1172 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001173 logger.Error(ctx, "Failed to convert resource to byte array")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001174 return 0, err
1175 }
1176 Data := bitmap.TSFromData(ByteArray, false)
1177 if Data == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001178 logger.Error(ctx, "Failed to get data from byte array")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001179 return 0, errors.New("Failed to get data from byte array")
1180 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001181
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001182 Len := Data.Len()
1183 var Idx int
1184 for Idx = 0; Idx < Len; Idx++ {
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001185 if !Data.Get(Idx) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001186 break
1187 }
1188 }
1189 Data.Set(Idx, true)
1190 res := uint32(Resource[START_IDX].(float64))
1191 Resource[POOL] = Data.Data(false)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001192 logger.Debugf(ctx, "Generated ID for %d", (uint32(Idx) + res))
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001193 return (uint32(Idx) + res), err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001194}
1195
Neha Sharma96b7bf22020-06-15 10:37:32 +00001196func (PONRMgr *PONResourceManager) ReleaseID(ctx context.Context, Resource map[string]interface{}, Id uint32) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001197 /*
1198 Release unique id having OFFSET as start index.
1199 :param resource: resource used to release ID
1200 :param unique_id: id need to be released
1201 */
1202 ByteArray, err := ToByte(Resource[POOL])
1203 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001204 logger.Error(ctx, "Failed to convert resource to byte array")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001205 return false
1206 }
1207 Data := bitmap.TSFromData(ByteArray, false)
1208 if Data == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001209 logger.Error(ctx, "Failed to get resource pool")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001210 return false
1211 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001212 Idx := Id - uint32(Resource[START_IDX].(float64))
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001213 Data.Set(int(Idx), false)
1214 Resource[POOL] = Data.Data(false)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001215
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001216 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001217}
1218
divyadesaid26f6b12020-03-19 06:30:28 +00001219/* Reserves a unique id in the specified resource pool.
1220:param Resource: resource used to reserve ID
1221:param Id: ID to be reserved
1222*/
Neha Sharma96b7bf22020-06-15 10:37:32 +00001223func (PONRMgr *PONResourceManager) reserveID(ctx context.Context, TSData *bitmap.Threadsafe, StartIndex uint32, Id uint32) bool {
divyadesaid26f6b12020-03-19 06:30:28 +00001224 Data := bitmap.TSFromData(TSData.Data(false), false)
1225 if Data == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001226 logger.Error(ctx, "Failed to get resource pool")
divyadesaid26f6b12020-03-19 06:30:28 +00001227 return false
1228 }
1229 Idx := Id - StartIndex
1230 Data.Set(int(Idx), true)
1231 return true
1232}
1233
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001234func (PONRMgr *PONResourceManager) GetTechnology() string {
1235 return PONRMgr.Technology
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001236}
1237
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001238func (PONRMgr *PONResourceManager) GetResourceTypeAllocID() string {
1239 return ALLOC_ID
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001240}
1241
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001242func (PONRMgr *PONResourceManager) GetResourceTypeGemPortID() string {
1243 return GEMPORT_ID
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001244}
1245
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001246// ToByte converts an interface value to a []byte. The interface should either be of
1247// a string type or []byte. Otherwise, an error is returned.
1248func ToByte(value interface{}) ([]byte, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001249 switch t := value.(type) {
1250 case []byte:
1251 return value.([]byte), nil
1252 case string:
1253 return []byte(value.(string)), nil
1254 default:
1255 return nil, fmt.Errorf("unexpected-type-%T", t)
1256 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001257}
1258
1259// ToString converts an interface value to a string. The interface should either be of
1260// a string type or []byte. Otherwise, an error is returned.
1261func ToString(value interface{}) (string, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001262 switch t := value.(type) {
1263 case []byte:
1264 return string(value.([]byte)), nil
1265 case string:
1266 return value.(string), nil
1267 default:
1268 return "", fmt.Errorf("unexpected-type-%T", t)
1269 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001270}
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001271
npujarec5762e2020-01-01 14:08:48 +05301272func (PONRMgr *PONResourceManager) AddOnuGemInfo(ctx context.Context, intfID uint32, onuGemData interface{}) error {
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001273 /*
1274 Update onugem info map,
1275 :param pon_intf_id: reference of PON interface id
1276 :param onuegmdata: onugem info map
1277 */
1278 var Value []byte
1279 var err error
1280 Path := fmt.Sprintf(ONU_GEM_INFO_PATH, PONRMgr.DeviceID, intfID)
1281 Value, err = json.Marshal(onuGemData)
1282 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001283 logger.Error(ctx, "failed to Marshal")
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001284 return err
1285 }
1286
npujarec5762e2020-01-01 14:08:48 +05301287 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001288 logger.Errorf(ctx, "Failed to update resource %s", Path)
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001289 return err
1290 }
1291 return err
1292}
1293
npujarec5762e2020-01-01 14:08:48 +05301294func (PONRMgr *PONResourceManager) GetOnuGemInfo(ctx context.Context, IntfId uint32, onuGemInfo interface{}) error {
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001295 /*
1296 Get onugeminfo map from kvstore
1297 :param intfid: refremce pon intfid
1298 :param onuGemInfo: onugem info to return from kv strore.
1299 */
1300 var Val []byte
1301
1302 path := fmt.Sprintf(ONU_GEM_INFO_PATH, PONRMgr.DeviceID, IntfId)
npujarec5762e2020-01-01 14:08:48 +05301303 value, err := PONRMgr.KVStore.Get(ctx, path)
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001304 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001305 logger.Errorw(ctx, "Failed to get from kv store", log.Fields{"path": path})
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001306 return err
1307 } else if value == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001308 logger.Debug(ctx, "No onuinfo for path", log.Fields{"path": path})
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001309 return nil // returning nil as this could happen if there are no onus for the interface yet
1310 }
1311 if Val, err = kvstore.ToByte(value.Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001312 logger.Error(ctx, "Failed to convert to byte array")
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001313 return err
1314 }
1315
1316 if err = json.Unmarshal(Val, &onuGemInfo); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001317 logger.Error(ctx, "Failed to unmarshall")
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001318 return err
1319 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001320 logger.Debugw(ctx, "found onuinfo from path", log.Fields{"path": path, "onuinfo": onuGemInfo})
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001321 return err
1322}
1323
npujarec5762e2020-01-01 14:08:48 +05301324func (PONRMgr *PONResourceManager) DelOnuGemInfoForIntf(ctx context.Context, intfId uint32) error {
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001325 /*
1326 delete onugem info for an interface from kvstore
1327 :param intfid: refremce pon intfid
1328 */
1329
1330 path := fmt.Sprintf(ONU_GEM_INFO_PATH, PONRMgr.DeviceID, intfId)
npujarec5762e2020-01-01 14:08:48 +05301331 if err := PONRMgr.KVStore.Delete(ctx, path); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001332 logger.Errorf(ctx, "Falied to remove resource %s", path)
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001333 return err
1334 }
1335 return nil
1336}