blob: bbfebe39983a68594c267eaa537303e2412b36f9 [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"
44 PATH_PREFIX = "service/voltha/resource_manager/{%s}"
divyadesaid26f6b12020-03-19 06:30:28 +000045
46 /*The path under which configuration data is stored is defined as technology/device agnostic.
47 That means the path does not include any specific technology/device variable. Using technology/device
48 agnostic path also makes northbound applications, that need to write to this path,
49 technology/device agnostic.
50
51 Default kv client of PonResourceManager reads from/writes to PATH_PREFIX defined above.
52 That is why, an additional kv client (named KVStoreForConfig) is defined to read from the config path.
53 */
54 PATH_PREFIX_FOR_CONFIG = "service/voltha/resource_manager/config"
Matt Jeanneret384d8c92019-05-06 14:27:31 -040055 /*The resource ranges for a given device model should be placed
56 at 'resource_manager/<technology>/resource_ranges/<olt_model_type>'
57 path on the KV store.
58 If Resource Range parameters are to be read from the external KV store,
59 they are expected to be stored in the following format.
60 Note: All parameters are MANDATORY for now.
61 constants used as keys to reference the resource range parameters from
62 and external KV store.
63 */
64 UNI_ID_START_IDX = "uni_id_start"
65 UNI_ID_END_IDX = "uni_id_end"
66 ONU_ID_START_IDX = "onu_id_start"
67 ONU_ID_END_IDX = "onu_id_end"
68 ONU_ID_SHARED_IDX = "onu_id_shared"
69 ALLOC_ID_START_IDX = "alloc_id_start"
70 ALLOC_ID_END_IDX = "alloc_id_end"
71 ALLOC_ID_SHARED_IDX = "alloc_id_shared"
72 GEMPORT_ID_START_IDX = "gemport_id_start"
73 GEMPORT_ID_END_IDX = "gemport_id_end"
74 GEMPORT_ID_SHARED_IDX = "gemport_id_shared"
75 FLOW_ID_START_IDX = "flow_id_start"
76 FLOW_ID_END_IDX = "flow_id_end"
77 FLOW_ID_SHARED_IDX = "flow_id_shared"
78 NUM_OF_PON_PORT = "pon_ports"
Matt Jeanneretcab955f2019-04-10 15:45:57 -040079
Matt Jeanneret384d8c92019-05-06 14:27:31 -040080 /*
81 The KV store backend is initialized with a path prefix and we need to
82 provide only the suffix.
83 */
84 PON_RESOURCE_RANGE_CONFIG_PATH = "resource_ranges/%s"
Matt Jeanneretcab955f2019-04-10 15:45:57 -040085
Matt Jeanneret384d8c92019-05-06 14:27:31 -040086 //resource path suffix
87 //Path on the KV store for storing alloc id ranges and resource pool for a given interface
88 //Format: <device_id>/alloc_id_pool/<pon_intf_id>
89 ALLOC_ID_POOL_PATH = "{%s}/alloc_id_pool/{%d}"
90 //Path on the KV store for storing gemport id ranges and resource pool for a given interface
91 //Format: <device_id>/gemport_id_pool/<pon_intf_id>
92 GEMPORT_ID_POOL_PATH = "{%s}/gemport_id_pool/{%d}"
93 //Path on the KV store for storing onu id ranges and resource pool for a given interface
94 //Format: <device_id>/onu_id_pool/<pon_intf_id>
95 ONU_ID_POOL_PATH = "{%s}/onu_id_pool/{%d}"
96 //Path on the KV store for storing flow id ranges and resource pool for a given interface
97 //Format: <device_id>/flow_id_pool/<pon_intf_id>
98 FLOW_ID_POOL_PATH = "{%s}/flow_id_pool/{%d}"
Matt Jeanneretcab955f2019-04-10 15:45:57 -040099
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400100 //Path on the KV store for storing list of alloc IDs for a given ONU
101 //Format: <device_id>/<(pon_intf_id, onu_id)>/alloc_ids
102 ALLOC_ID_RESOURCE_MAP_PATH = "{%s}/{%s}/alloc_ids"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400103
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400104 //Path on the KV store for storing list of gemport IDs for a given ONU
105 //Format: <device_id>/<(pon_intf_id, onu_id)>/gemport_ids
106 GEMPORT_ID_RESOURCE_MAP_PATH = "{%s}/{%s}/gemport_ids"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400107
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400108 //Path on the KV store for storing list of Flow IDs for a given ONU
109 //Format: <device_id>/<(pon_intf_id, onu_id)>/flow_ids
110 FLOW_ID_RESOURCE_MAP_PATH = "{%s}/{%s}/flow_ids"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400111
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400112 //Flow Id info: Use to store more metadata associated with the flow_id
113 //Format: <device_id>/<(pon_intf_id, onu_id)>/flow_id_info/<flow_id>
114 FLOW_ID_INFO_PATH = "{%s}/{%s}/flow_id_info/{%d}"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400115
Scott Bakerc6e54cb2019-11-04 09:31:25 -0800116 //path on the kvstore to store onugem info map
117 //format: <device-id>/onu_gem_info/<intfid>
118 ONU_GEM_INFO_PATH = "{%s}/onu_gem_info/{%d}" // onu_gem/<(intfid)>
119
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400120 //Constants for internal usage.
121 PON_INTF_ID = "pon_intf_id"
122 START_IDX = "start_idx"
123 END_IDX = "end_idx"
124 POOL = "pool"
125 NUM_OF_PON_INTF = 16
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400126
Neha Sharmacc656962020-04-14 14:26:11 +0000127 KVSTORE_RETRY_TIMEOUT = 5 * time.Second
divyadesaid26f6b12020-03-19 06:30:28 +0000128 //Path on the KV store for storing reserved gem ports
129 //Format: reserved_gemport_ids
130 RESERVED_GEMPORT_IDS_PATH = "reserved_gemport_ids"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400131)
132
133//type ResourceTypeIndex string
134//type ResourceType string
135
136type PONResourceManager struct {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400137 //Implements APIs to initialize/allocate/release alloc/gemport/onu IDs.
divyadesaid26f6b12020-03-19 06:30:28 +0000138 Technology string
139 DeviceType string
140 DeviceID string
141 Backend string // ETCD, or consul
Neha Sharma3f221ae2020-04-29 19:02:12 +0000142 Address string // address of the KV store
divyadesaid26f6b12020-03-19 06:30:28 +0000143 OLTModel string
144 KVStore *db.Backend
145 KVStoreForConfig *db.Backend
146 TechProfileMgr tp.TechProfileIf // create object of *tp.TechProfileMgr
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400147
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400148 // Below attribute, pon_resource_ranges, should be initialized
149 // by reading from KV store.
150 PonResourceRanges map[string]interface{}
151 SharedResourceMgrs map[string]*PONResourceManager
152 SharedIdxByType map[string]string
153 IntfIDs []uint32 // list of pon interface IDs
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400154 Globalorlocal string
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400155}
156
Neha Sharma96b7bf22020-06-15 10:37:32 +0000157func newKVClient(ctx context.Context, storeType string, address string, timeout time.Duration) (kvstore.Client, error) {
158 logger.Infow(ctx, "kv-store-type", log.Fields{"store": storeType})
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400159 switch storeType {
160 case "consul":
Neha Sharma96b7bf22020-06-15 10:37:32 +0000161 return kvstore.NewConsulClient(ctx, address, timeout)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400162 case "etcd":
Neha Sharma96b7bf22020-06-15 10:37:32 +0000163 return kvstore.NewEtcdClient(ctx, address, timeout, log.WarnLevel)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400164 }
165 return nil, errors.New("unsupported-kv-store")
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400166}
167
Neha Sharma96b7bf22020-06-15 10:37:32 +0000168func SetKVClient(ctx context.Context, Technology string, Backend string, Addr string, configClient bool) *db.Backend {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400169 // TODO : Make sure direct call to NewBackend is working fine with backend , currently there is some
170 // issue between kv store and backend , core is not calling NewBackend directly
Neha Sharma96b7bf22020-06-15 10:37:32 +0000171 kvClient, err := newKVClient(ctx, Backend, Addr, KVSTORE_RETRY_TIMEOUT)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400172 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000173 logger.Fatalw(ctx, "Failed to init KV client\n", log.Fields{"err": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400174 return nil
175 }
divyadesaid26f6b12020-03-19 06:30:28 +0000176
177 var pathPrefix string
178 if configClient {
179 pathPrefix = PATH_PREFIX_FOR_CONFIG
180 } else {
181 pathPrefix = fmt.Sprintf(PATH_PREFIX, Technology)
182 }
183
sbarbaria8910ba2019-11-05 10:12:23 -0500184 kvbackend := &db.Backend{
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400185 Client: kvClient,
186 StoreType: Backend,
Neha Sharma3f221ae2020-04-29 19:02:12 +0000187 Address: Addr,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400188 Timeout: KVSTORE_RETRY_TIMEOUT,
divyadesaid26f6b12020-03-19 06:30:28 +0000189 PathPrefix: pathPrefix}
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400190
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400191 return kvbackend
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400192}
193
194// NewPONResourceManager creates a new PON resource manager.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000195func NewPONResourceManager(ctx context.Context, Technology string, DeviceType string, DeviceID string, Backend string, Address string) (*PONResourceManager, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400196 var PONMgr PONResourceManager
197 PONMgr.Technology = Technology
198 PONMgr.DeviceType = DeviceType
199 PONMgr.DeviceID = DeviceID
200 PONMgr.Backend = Backend
Neha Sharma3f221ae2020-04-29 19:02:12 +0000201 PONMgr.Address = Address
Neha Sharma96b7bf22020-06-15 10:37:32 +0000202 PONMgr.KVStore = SetKVClient(ctx, Technology, Backend, Address, false)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400203 if PONMgr.KVStore == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000204 logger.Error(ctx, "KV Client initilization failed")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400205 return nil, errors.New("Failed to init KV client")
206 }
divyadesaid26f6b12020-03-19 06:30:28 +0000207 // init kv client to read from the config path
Neha Sharma96b7bf22020-06-15 10:37:32 +0000208 PONMgr.KVStoreForConfig = SetKVClient(ctx, Technology, Backend, Address, true)
divyadesaid26f6b12020-03-19 06:30:28 +0000209 if PONMgr.KVStoreForConfig == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000210 logger.Error(ctx, "KV Config Client initilization failed")
divyadesaid26f6b12020-03-19 06:30:28 +0000211 return nil, errors.New("Failed to init KV Config client")
212 }
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400213 // Initialize techprofile for this technology
Neha Sharma96b7bf22020-06-15 10:37:32 +0000214 if PONMgr.TechProfileMgr, _ = tp.NewTechProfile(ctx, &PONMgr, Backend, Address); PONMgr.TechProfileMgr == nil {
215 logger.Error(ctx, "Techprofile initialization failed")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400216 return nil, errors.New("Failed to init tech profile")
217 }
218 PONMgr.PonResourceRanges = make(map[string]interface{})
219 PONMgr.SharedResourceMgrs = make(map[string]*PONResourceManager)
220 PONMgr.SharedIdxByType = make(map[string]string)
221 PONMgr.SharedIdxByType[ONU_ID] = ONU_ID_SHARED_IDX
222 PONMgr.SharedIdxByType[ALLOC_ID] = ALLOC_ID_SHARED_IDX
223 PONMgr.SharedIdxByType[GEMPORT_ID] = GEMPORT_ID_SHARED_IDX
224 PONMgr.SharedIdxByType[FLOW_ID] = FLOW_ID_SHARED_IDX
225 PONMgr.IntfIDs = make([]uint32, NUM_OF_PON_INTF)
226 PONMgr.OLTModel = DeviceType
227 return &PONMgr, nil
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400228}
229
230/*
231 Initialize PON resource ranges with config fetched from kv store.
232 return boolean: True if PON resource ranges initialized else false
233 Try to initialize the PON Resource Ranges from KV store based on the
234 OLT model key, if available
235*/
236
npujarec5762e2020-01-01 14:08:48 +0530237func (PONRMgr *PONResourceManager) InitResourceRangesFromKVStore(ctx context.Context) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400238 //Initialize PON resource ranges with config fetched from kv store.
239 //:return boolean: True if PON resource ranges initialized else false
240 // Try to initialize the PON Resource Ranges from KV store based on the
241 // OLT model key, if available
242 if PONRMgr.OLTModel == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000243 logger.Error(ctx, "Failed to get OLT model")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400244 return false
245 }
246 Path := fmt.Sprintf(PON_RESOURCE_RANGE_CONFIG_PATH, PONRMgr.OLTModel)
247 //get resource from kv store
npujarec5762e2020-01-01 14:08:48 +0530248 Result, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400249 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000250 logger.Debugf(ctx, "Error in fetching resource %s from KV strore", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400251 return false
252 }
253 if Result == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000254 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 -0400255 return false
256 }
257 //update internal ranges from kv ranges. If there are missing
258 // values in the KV profile, continue to use the defaults
259 Value, err := ToByte(Result.Value)
260 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000261 logger.Error(ctx, "Failed to convert kvpair to byte string")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400262 return false
263 }
264 if err := json.Unmarshal(Value, &PONRMgr.PonResourceRanges); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000265 logger.Error(ctx, "Failed to Unmarshal json byte")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400266 return false
267 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000268 logger.Debug(ctx, "Init resource ranges from kvstore success")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400269 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400270}
271
Neha Sharma96b7bf22020-06-15 10:37:32 +0000272func (PONRMgr *PONResourceManager) UpdateRanges(ctx context.Context, StartIDx string, StartID uint32, EndIDx string, EndID uint32,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400273 SharedIDx string, SharedPoolID uint32, RMgr *PONResourceManager) {
274 /*
275 Update the ranges for all reosurce type in the intermnal maps
276 param: resource type start index
277 param: start ID
278 param: resource type end index
279 param: end ID
280 param: resource type shared index
281 param: shared pool id
282 param: global resource manager
283 */
Neha Sharma96b7bf22020-06-15 10:37:32 +0000284 logger.Debugf(ctx, "update ranges for %s, %d", StartIDx, StartID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400285
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400286 if StartID != 0 {
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400287 if (PONRMgr.PonResourceRanges[StartIDx] == nil) || (PONRMgr.PonResourceRanges[StartIDx].(uint32) < StartID) {
288 PONRMgr.PonResourceRanges[StartIDx] = StartID
289 }
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400290 }
291 if EndID != 0 {
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400292 if (PONRMgr.PonResourceRanges[EndIDx] == nil) || (PONRMgr.PonResourceRanges[EndIDx].(uint32) > EndID) {
293 PONRMgr.PonResourceRanges[EndIDx] = EndID
294 }
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400295 }
296 //if SharedPoolID != 0 {
297 PONRMgr.PonResourceRanges[SharedIDx] = SharedPoolID
298 //}
299 if RMgr != nil {
300 PONRMgr.SharedResourceMgrs[SharedIDx] = RMgr
301 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400302}
303
Neha Sharma96b7bf22020-06-15 10:37:32 +0000304func (PONRMgr *PONResourceManager) InitDefaultPONResourceRanges(ctx context.Context,
305 ONUIDStart uint32,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400306 ONUIDEnd uint32,
307 ONUIDSharedPoolID uint32,
308 AllocIDStart uint32,
309 AllocIDEnd uint32,
310 AllocIDSharedPoolID uint32,
311 GEMPortIDStart uint32,
312 GEMPortIDEnd uint32,
313 GEMPortIDSharedPoolID uint32,
314 FlowIDStart uint32,
315 FlowIDEnd uint32,
316 FlowIDSharedPoolID uint32,
317 UNIIDStart uint32,
318 UNIIDEnd uint32,
319 NoOfPONPorts uint32,
320 IntfIDs []uint32) bool {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400321
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400322 /*Initialize default PON resource ranges
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400323
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400324 :param onu_id_start_idx: onu id start index
325 :param onu_id_end_idx: onu id end index
326 :param onu_id_shared_pool_id: pool idx for id shared by all intfs or None for no sharing
327 :param alloc_id_start_idx: alloc id start index
328 :param alloc_id_end_idx: alloc id end index
329 :param alloc_id_shared_pool_id: pool idx for alloc id shared by all intfs or None for no sharing
330 :param gemport_id_start_idx: gemport id start index
331 :param gemport_id_end_idx: gemport id end index
332 :param gemport_id_shared_pool_id: pool idx for gemport id shared by all intfs or None for no sharing
333 :param flow_id_start_idx: flow id start index
334 :param flow_id_end_idx: flow id end index
335 :param flow_id_shared_pool_id: pool idx for flow id shared by all intfs or None for no sharing
336 :param num_of_pon_ports: number of PON ports
337 :param intf_ids: interfaces serviced by this manager
338 */
Neha Sharma96b7bf22020-06-15 10:37:32 +0000339 PONRMgr.UpdateRanges(ctx, ONU_ID_START_IDX, ONUIDStart, ONU_ID_END_IDX, ONUIDEnd, ONU_ID_SHARED_IDX, ONUIDSharedPoolID, nil)
340 PONRMgr.UpdateRanges(ctx, ALLOC_ID_START_IDX, AllocIDStart, ALLOC_ID_END_IDX, AllocIDEnd, ALLOC_ID_SHARED_IDX, AllocIDSharedPoolID, nil)
341 PONRMgr.UpdateRanges(ctx, GEMPORT_ID_START_IDX, GEMPortIDStart, GEMPORT_ID_END_IDX, GEMPortIDEnd, GEMPORT_ID_SHARED_IDX, GEMPortIDSharedPoolID, nil)
342 PONRMgr.UpdateRanges(ctx, FLOW_ID_START_IDX, FlowIDStart, FLOW_ID_END_IDX, FlowIDEnd, FLOW_ID_SHARED_IDX, FlowIDSharedPoolID, nil)
343 PONRMgr.UpdateRanges(ctx, UNI_ID_START_IDX, UNIIDStart, UNI_ID_END_IDX, UNIIDEnd, "", 0, nil)
344 logger.Debug(ctx, "Initialize default range values")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400345 var i uint32
346 if IntfIDs == nil {
347 for i = 0; i < NoOfPONPorts; i++ {
348 PONRMgr.IntfIDs = append(PONRMgr.IntfIDs, i)
349 }
350 } else {
351 PONRMgr.IntfIDs = IntfIDs
352 }
353 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400354}
355
npujarec5762e2020-01-01 14:08:48 +0530356func (PONRMgr *PONResourceManager) InitDeviceResourcePool(ctx context.Context) error {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400357
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400358 //Initialize resource pool for all PON ports.
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400359
Neha Sharma96b7bf22020-06-15 10:37:32 +0000360 logger.Debug(ctx, "Init resource ranges")
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400361
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400362 var err error
363 for _, Intf := range PONRMgr.IntfIDs {
364 SharedPoolID := PONRMgr.PonResourceRanges[ONU_ID_SHARED_IDX].(uint32)
365 if SharedPoolID != 0 {
366 Intf = SharedPoolID
367 }
npujarec5762e2020-01-01 14:08:48 +0530368 if err = PONRMgr.InitResourceIDPool(ctx, Intf, ONU_ID,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400369 PONRMgr.PonResourceRanges[ONU_ID_START_IDX].(uint32),
370 PONRMgr.PonResourceRanges[ONU_ID_END_IDX].(uint32)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000371 logger.Error(ctx, "Failed to init ONU ID resource pool")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400372 return err
373 }
374 if SharedPoolID != 0 {
375 break
376 }
377 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400378
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400379 for _, Intf := range PONRMgr.IntfIDs {
380 SharedPoolID := PONRMgr.PonResourceRanges[ALLOC_ID_SHARED_IDX].(uint32)
381 if SharedPoolID != 0 {
382 Intf = SharedPoolID
383 }
npujarec5762e2020-01-01 14:08:48 +0530384 if err = PONRMgr.InitResourceIDPool(ctx, Intf, ALLOC_ID,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400385 PONRMgr.PonResourceRanges[ALLOC_ID_START_IDX].(uint32),
386 PONRMgr.PonResourceRanges[ALLOC_ID_END_IDX].(uint32)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000387 logger.Error(ctx, "Failed to init ALLOC ID resource pool ")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400388 return err
389 }
390 if SharedPoolID != 0 {
391 break
392 }
393 }
394 for _, Intf := range PONRMgr.IntfIDs {
395 SharedPoolID := PONRMgr.PonResourceRanges[GEMPORT_ID_SHARED_IDX].(uint32)
396 if SharedPoolID != 0 {
397 Intf = SharedPoolID
398 }
npujarec5762e2020-01-01 14:08:48 +0530399 if err = PONRMgr.InitResourceIDPool(ctx, Intf, GEMPORT_ID,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400400 PONRMgr.PonResourceRanges[GEMPORT_ID_START_IDX].(uint32),
401 PONRMgr.PonResourceRanges[GEMPORT_ID_END_IDX].(uint32)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000402 logger.Error(ctx, "Failed to init GEMPORT ID resource pool")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400403 return err
404 }
405 if SharedPoolID != 0 {
406 break
407 }
408 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400409
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400410 for _, Intf := range PONRMgr.IntfIDs {
411 SharedPoolID := PONRMgr.PonResourceRanges[FLOW_ID_SHARED_IDX].(uint32)
412 if SharedPoolID != 0 {
413 Intf = SharedPoolID
414 }
npujarec5762e2020-01-01 14:08:48 +0530415 if err = PONRMgr.InitResourceIDPool(ctx, Intf, FLOW_ID,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400416 PONRMgr.PonResourceRanges[FLOW_ID_START_IDX].(uint32),
417 PONRMgr.PonResourceRanges[FLOW_ID_END_IDX].(uint32)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000418 logger.Error(ctx, "Failed to init FLOW ID resource pool")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400419 return err
420 }
421 if SharedPoolID != 0 {
422 break
423 }
424 }
425 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400426}
427
npujarec5762e2020-01-01 14:08:48 +0530428func (PONRMgr *PONResourceManager) ClearDeviceResourcePool(ctx context.Context) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -0400429
430 //Clear resource pool for all PON ports.
431
Neha Sharma96b7bf22020-06-15 10:37:32 +0000432 logger.Debug(ctx, "Clear resource ranges")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400433
434 for _, Intf := range PONRMgr.IntfIDs {
435 SharedPoolID := PONRMgr.PonResourceRanges[ONU_ID_SHARED_IDX].(uint32)
436 if SharedPoolID != 0 {
437 Intf = SharedPoolID
438 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000439 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, ONU_ID); !status {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000440 logger.Error(ctx, "Failed to clear ONU ID resource pool")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400441 return errors.New("Failed to clear ONU ID resource pool")
442 }
443 if SharedPoolID != 0 {
444 break
445 }
446 }
447
448 for _, Intf := range PONRMgr.IntfIDs {
449 SharedPoolID := PONRMgr.PonResourceRanges[ALLOC_ID_SHARED_IDX].(uint32)
450 if SharedPoolID != 0 {
451 Intf = SharedPoolID
452 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000453 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, ALLOC_ID); !status {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000454 logger.Error(ctx, "Failed to clear ALLOC ID resource pool ")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400455 return errors.New("Failed to clear ALLOC ID resource pool")
456 }
457 if SharedPoolID != 0 {
458 break
459 }
460 }
461 for _, Intf := range PONRMgr.IntfIDs {
462 SharedPoolID := PONRMgr.PonResourceRanges[GEMPORT_ID_SHARED_IDX].(uint32)
463 if SharedPoolID != 0 {
464 Intf = SharedPoolID
465 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000466 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, GEMPORT_ID); !status {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000467 logger.Error(ctx, "Failed to clear GEMPORT ID resource pool")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400468 return errors.New("Failed to clear GEMPORT ID resource pool")
469 }
470 if SharedPoolID != 0 {
471 break
472 }
473 }
474
475 for _, Intf := range PONRMgr.IntfIDs {
476 SharedPoolID := PONRMgr.PonResourceRanges[FLOW_ID_SHARED_IDX].(uint32)
477 if SharedPoolID != 0 {
478 Intf = SharedPoolID
479 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000480 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, FLOW_ID); !status {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000481 logger.Error(ctx, "Failed to clear FLOW ID resource pool")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400482 return errors.New("Failed to clear FLOW ID resource pool")
483 }
484 if SharedPoolID != 0 {
485 break
486 }
487 }
488 return nil
489}
490
npujarec5762e2020-01-01 14:08:48 +0530491func (PONRMgr *PONResourceManager) InitResourceIDPool(ctx context.Context, Intf uint32, ResourceType string, StartID uint32, EndID uint32) error {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400492
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400493 /*Initialize Resource ID pool for a given Resource Type on a given PON Port
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400494
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400495 :param pon_intf_id: OLT PON interface id
496 :param resource_type: String to identify type of resource
497 :param start_idx: start index for onu id pool
498 :param end_idx: end index for onu id pool
499 :return boolean: True if resource id pool initialized else false
500 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400501
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400502 // delegate to the master instance if sharing enabled across instances
503 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
504 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujarec5762e2020-01-01 14:08:48 +0530505 return SharedResourceMgr.InitResourceIDPool(ctx, Intf, ResourceType, StartID, EndID)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400506 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400507
Neha Sharma96b7bf22020-06-15 10:37:32 +0000508 Path := PONRMgr.GetPath(ctx, Intf, ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400509 if Path == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000510 logger.Errorf(ctx, "Failed to get path for resource type %s", ResourceType)
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000511 return fmt.Errorf("Failed to get path for resource type %s", ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400512 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400513
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400514 //In case of adapter reboot and reconciliation resource in kv store
515 //checked for its presence if not kv store update happens
npujarec5762e2020-01-01 14:08:48 +0530516 Res, err := PONRMgr.GetResource(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400517 if (err == nil) && (Res != nil) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000518 logger.Debugf(ctx, "Resource %s already present in store ", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400519 return nil
520 } else {
divyadesaid26f6b12020-03-19 06:30:28 +0000521 var excluded []uint32
522 if ResourceType == GEMPORT_ID {
523 //get gem port ids defined in the KV store, if any, and exclude them from the gem port id pool
524 if reservedGemPortIds, defined := PONRMgr.getReservedGemPortIdsFromKVStore(ctx); defined {
525 excluded = reservedGemPortIds
Neha Sharma96b7bf22020-06-15 10:37:32 +0000526 logger.Debugw(ctx, "Excluding some ports from GEM port id pool", log.Fields{"excluded gem ports": excluded})
divyadesaid26f6b12020-03-19 06:30:28 +0000527 }
528 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000529 FormatResult, err := PONRMgr.FormatResource(ctx, Intf, StartID, EndID, excluded)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400530 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000531 logger.Errorf(ctx, "Failed to format resource")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400532 return err
533 }
534 // Add resource as json in kv store.
npujarec5762e2020-01-01 14:08:48 +0530535 err = PONRMgr.KVStore.Put(ctx, Path, FormatResult)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400536 if err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000537 logger.Debug(ctx, "Successfuly posted to kv store")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400538 return err
539 }
540 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400541
Neha Sharma96b7bf22020-06-15 10:37:32 +0000542 logger.Debug(ctx, "Error initializing pool")
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400543
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400544 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400545}
546
divyadesaid26f6b12020-03-19 06:30:28 +0000547func (PONRMgr *PONResourceManager) getReservedGemPortIdsFromKVStore(ctx context.Context) ([]uint32, bool) {
548 var reservedGemPortIds []uint32
549 // read reserved gem ports from the config path
550 KvPair, err := PONRMgr.KVStoreForConfig.Get(ctx, RESERVED_GEMPORT_IDS_PATH)
551 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000552 logger.Errorw(ctx, "Unable to get reserved GEM port ids from the kv store", log.Fields{"err": err})
divyadesaid26f6b12020-03-19 06:30:28 +0000553 return reservedGemPortIds, false
554 }
555 if KvPair == nil || KvPair.Value == nil {
556 //no reserved gem port defined in the store
557 return reservedGemPortIds, false
558 }
559 Val, err := kvstore.ToByte(KvPair.Value)
560 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000561 logger.Errorw(ctx, "Failed to convert reserved gem port ids into byte array", log.Fields{"err": err})
divyadesaid26f6b12020-03-19 06:30:28 +0000562 return reservedGemPortIds, false
563 }
564 if err = json.Unmarshal(Val, &reservedGemPortIds); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000565 logger.Errorw(ctx, "Failed to unmarshal reservedGemPortIds", log.Fields{"err": err})
divyadesaid26f6b12020-03-19 06:30:28 +0000566 return reservedGemPortIds, false
567 }
568 return reservedGemPortIds, true
569}
570
Neha Sharma96b7bf22020-06-15 10:37:32 +0000571func (PONRMgr *PONResourceManager) FormatResource(ctx context.Context, IntfID uint32, StartIDx uint32, EndIDx uint32,
divyadesaid26f6b12020-03-19 06:30:28 +0000572 Excluded []uint32) ([]byte, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400573 /*
574 Format resource as json.
575 :param pon_intf_id: OLT PON interface id
576 :param start_idx: start index for id pool
577 :param end_idx: end index for id pool
divyadesaid26f6b12020-03-19 06:30:28 +0000578 :Id values to be Excluded from the pool
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400579 :return dictionary: resource formatted as map
580 */
581 // Format resource as json to be stored in backend store
582 Resource := make(map[string]interface{})
583 Resource[PON_INTF_ID] = IntfID
584 Resource[START_IDX] = StartIDx
585 Resource[END_IDX] = EndIDx
586 /*
587 Resource pool stored in backend store as binary string.
588 Tracking the resource allocation will be done by setting the bits \
589 in the byte array. The index set will be the resource number allocated.
590 */
591 var TSData *bitmap.Threadsafe
592 if TSData = bitmap.NewTS(int(EndIDx)); TSData == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000593 logger.Error(ctx, "Failed to create a bitmap")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400594 return nil, errors.New("Failed to create bitmap")
595 }
divyadesaid26f6b12020-03-19 06:30:28 +0000596 for _, excludedID := range Excluded {
597 if excludedID < StartIDx || excludedID > EndIDx {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000598 logger.Warnf(ctx, "Cannot reserve %d. It must be in the range of [%d, %d]", excludedID,
divyadesaid26f6b12020-03-19 06:30:28 +0000599 StartIDx, EndIDx)
600 continue
601 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000602 PONRMgr.reserveID(ctx, TSData, StartIDx, excludedID)
divyadesaid26f6b12020-03-19 06:30:28 +0000603 }
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400604 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 -0400605
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400606 Value, err := json.Marshal(Resource)
607 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000608 logger.Errorf(ctx, "Failed to marshall resource")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400609 return nil, err
610 }
611 return Value, err
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400612}
npujarec5762e2020-01-01 14:08:48 +0530613func (PONRMgr *PONResourceManager) GetResource(ctx context.Context, Path string) (map[string]interface{}, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400614 /*
615 Get resource from kv store.
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400616
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400617 :param path: path to get resource
618 :return: resource if resource present in kv store else None
619 */
620 //get resource from kv store
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400621
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400622 var Value []byte
623 Result := make(map[string]interface{})
624 var Str string
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400625
npujarec5762e2020-01-01 14:08:48 +0530626 Resource, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400627 if (err != nil) || (Resource == nil) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000628 logger.Debugf(ctx, "Resource unavailable at %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400629 return nil, err
630 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400631
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400632 Value, err = ToByte(Resource.Value)
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000633 if err != nil {
634 return nil, err
635 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400636
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400637 // decode resource fetched from backend store to dictionary
638 err = json.Unmarshal(Value, &Result)
639 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000640 logger.Error(ctx, "Failed to decode resource")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400641 return Result, err
642 }
643 /*
644 resource pool in backend store stored as binary string whereas to
645 access the pool to generate/release IDs it need to be converted
646 as BitArray
647 */
648 Str, err = ToString(Result[POOL])
649 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000650 logger.Error(ctx, "Failed to conver to kv pair to string")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400651 return Result, err
652 }
653 Decode64, _ := base64.StdEncoding.DecodeString(Str)
654 Result[POOL], err = ToByte(Decode64)
655 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000656 logger.Error(ctx, "Failed to convert resource pool to byte")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400657 return Result, err
658 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400659
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400660 return Result, err
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400661}
662
Neha Sharma96b7bf22020-06-15 10:37:32 +0000663func (PONRMgr *PONResourceManager) GetPath(ctx context.Context, IntfID uint32, ResourceType string) string {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400664 /*
665 Get path for given resource type.
666 :param pon_intf_id: OLT PON interface id
667 :param resource_type: String to identify type of resource
668 :return: path for given resource type
669 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400670
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400671 /*
672 Get the shared pool for the given resource type.
673 all the resource ranges and the shared resource maps are initialized during the init.
674 */
675 SharedPoolID := PONRMgr.PonResourceRanges[PONRMgr.SharedIdxByType[ResourceType]].(uint32)
676 if SharedPoolID != 0 {
677 IntfID = SharedPoolID
678 }
679 var Path string
680 if ResourceType == ONU_ID {
681 Path = fmt.Sprintf(ONU_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
682 } else if ResourceType == ALLOC_ID {
683 Path = fmt.Sprintf(ALLOC_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
684 } else if ResourceType == GEMPORT_ID {
685 Path = fmt.Sprintf(GEMPORT_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
686 } else if ResourceType == FLOW_ID {
687 Path = fmt.Sprintf(FLOW_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
688 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000689 logger.Error(ctx, "Invalid resource pool identifier")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400690 }
691 return Path
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400692}
693
npujarec5762e2020-01-01 14:08:48 +0530694func (PONRMgr *PONResourceManager) GetResourceID(ctx context.Context, IntfID uint32, ResourceType string, NumIDs uint32) ([]uint32, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400695 /*
696 Create alloc/gemport/onu/flow id for given OLT PON interface.
697 :param pon_intf_id: OLT PON interface id
698 :param resource_type: String to identify type of resource
699 :param num_of_id: required number of ids
700 :return list/uint32/None: list, uint32 or None if resource type is
701 alloc_id/gemport_id, onu_id or invalid type respectively
702 */
703 if NumIDs < 1 {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000704 logger.Error(ctx, "Invalid number of resources requested")
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000705 return nil, fmt.Errorf("Invalid number of resources requested %d", NumIDs)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400706 }
707 // delegate to the master instance if sharing enabled across instances
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400708
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400709 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
710 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujarec5762e2020-01-01 14:08:48 +0530711 return SharedResourceMgr.GetResourceID(ctx, IntfID, ResourceType, NumIDs)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400712 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000713 logger.Debugf(ctx, "Fetching resource from %s rsrc mgr for resource %s", PONRMgr.Globalorlocal, ResourceType)
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400714
Neha Sharma96b7bf22020-06-15 10:37:32 +0000715 Path := PONRMgr.GetPath(ctx, IntfID, ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400716 if Path == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000717 logger.Errorf(ctx, "Failed to get path for resource type %s", ResourceType)
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000718 return nil, fmt.Errorf("Failed to get path for resource type %s", ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400719 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000720 logger.Debugf(ctx, "Get resource for type %s on path %s", ResourceType, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400721 var Result []uint32
722 var NextID uint32
npujarec5762e2020-01-01 14:08:48 +0530723 Resource, err := PONRMgr.GetResource(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400724 if (err == nil) && (ResourceType == ONU_ID) || (ResourceType == FLOW_ID) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000725 if NextID, err = PONRMgr.GenerateNextID(ctx, Resource); err != nil {
726 logger.Error(ctx, "Failed to Generate ID")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400727 return Result, err
728 }
729 Result = append(Result, NextID)
730 } else if (err == nil) && ((ResourceType == GEMPORT_ID) || (ResourceType == ALLOC_ID)) {
731 if NumIDs == 1 {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000732 if NextID, err = PONRMgr.GenerateNextID(ctx, Resource); err != nil {
733 logger.Error(ctx, "Failed to Generate ID")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400734 return Result, err
735 }
736 Result = append(Result, NextID)
737 } else {
738 for NumIDs > 0 {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000739 if NextID, err = PONRMgr.GenerateNextID(ctx, Resource); err != nil {
740 logger.Error(ctx, "Failed to Generate ID")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400741 return Result, err
742 }
743 Result = append(Result, NextID)
744 NumIDs--
745 }
746 }
747 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000748 logger.Error(ctx, "get resource failed")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400749 return Result, err
750 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400751
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400752 //Update resource in kv store
npujarec5762e2020-01-01 14:08:48 +0530753 if PONRMgr.UpdateResource(ctx, Path, Resource) != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000754 logger.Errorf(ctx, "Failed to update resource %s", Path)
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000755 return nil, fmt.Errorf("Failed to update resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400756 }
757 return Result, nil
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400758}
759
760func checkValidResourceType(ResourceType string) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400761 KnownResourceTypes := []string{ONU_ID, ALLOC_ID, GEMPORT_ID, FLOW_ID}
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400762
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400763 for _, v := range KnownResourceTypes {
764 if v == ResourceType {
765 return true
766 }
767 }
768 return false
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400769}
770
npujarec5762e2020-01-01 14:08:48 +0530771func (PONRMgr *PONResourceManager) FreeResourceID(ctx context.Context, IntfID uint32, ResourceType string, ReleaseContent []uint32) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400772 /*
773 Release alloc/gemport/onu/flow id for given OLT PON interface.
774 :param pon_intf_id: OLT PON interface id
775 :param resource_type: String to identify type of resource
776 :param release_content: required number of ids
777 :return boolean: True if all IDs in given release_content release else False
778 */
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000779 if !checkValidResourceType(ResourceType) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000780 logger.Error(ctx, "Invalid resource type")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400781 return false
782 }
783 if ReleaseContent == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000784 logger.Debug(ctx, "Nothing to release")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400785 return true
786 }
787 // delegate to the master instance if sharing enabled across instances
788 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
789 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujarec5762e2020-01-01 14:08:48 +0530790 return SharedResourceMgr.FreeResourceID(ctx, IntfID, ResourceType, ReleaseContent)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400791 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000792 Path := PONRMgr.GetPath(ctx, IntfID, ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400793 if Path == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000794 logger.Error(ctx, "Failed to get path")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400795 return false
796 }
npujarec5762e2020-01-01 14:08:48 +0530797 Resource, err := PONRMgr.GetResource(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400798 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000799 logger.Error(ctx, "Failed to get resource")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400800 return false
801 }
802 for _, Val := range ReleaseContent {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000803 PONRMgr.ReleaseID(ctx, Resource, Val)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400804 }
npujarec5762e2020-01-01 14:08:48 +0530805 if PONRMgr.UpdateResource(ctx, Path, Resource) != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000806 logger.Errorf(ctx, "Free resource for %s failed", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400807 return false
808 }
809 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400810}
811
npujarec5762e2020-01-01 14:08:48 +0530812func (PONRMgr *PONResourceManager) UpdateResource(ctx context.Context, Path string, Resource map[string]interface{}) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400813 /*
814 Update resource in resource kv store.
815 :param path: path to update resource
816 :param resource: resource need to be updated
817 :return boolean: True if resource updated in kv store else False
818 */
819 // TODO resource[POOL] = resource[POOL].bin
820 Value, err := json.Marshal(Resource)
821 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000822 logger.Error(ctx, "failed to Marshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400823 return err
824 }
npujarec5762e2020-01-01 14:08:48 +0530825 err = PONRMgr.KVStore.Put(ctx, Path, Value)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400826 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000827 logger.Error(ctx, "failed to put data to kv store %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400828 return err
829 }
830 return nil
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400831}
832
npujarec5762e2020-01-01 14:08:48 +0530833func (PONRMgr *PONResourceManager) ClearResourceIDPool(ctx context.Context, contIntfID uint32, ResourceType string) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400834 /*
835 Clear Resource Pool for a given Resource Type on a given PON Port.
836 :return boolean: True if removed else False
837 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400838
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400839 // delegate to the master instance if sharing enabled across instances
840 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
841 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujarec5762e2020-01-01 14:08:48 +0530842 return SharedResourceMgr.ClearResourceIDPool(ctx, contIntfID, ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400843 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000844 Path := PONRMgr.GetPath(ctx, contIntfID, ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400845 if Path == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000846 logger.Error(ctx, "Failed to get path")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400847 return false
848 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400849
npujarec5762e2020-01-01 14:08:48 +0530850 if err := PONRMgr.KVStore.Delete(ctx, Path); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000851 logger.Errorf(ctx, "Failed to delete resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400852 return false
853 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000854 logger.Debugf(ctx, "Cleared resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400855 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400856}
857
npujarec5762e2020-01-01 14:08:48 +0530858func (PONRMgr PONResourceManager) InitResourceMap(ctx context.Context, PONIntfONUID string) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400859 /*
860 Initialize resource map
861 :param pon_intf_onu_id: reference of PON interface id and onu id
862 */
863 // initialize pon_intf_onu_id tuple to alloc_ids map
864 AllocIDPath := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
865 var AllocIDs []byte
npujarec5762e2020-01-01 14:08:48 +0530866 Result := PONRMgr.KVStore.Put(ctx, AllocIDPath, AllocIDs)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400867 if Result != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000868 logger.Error(ctx, "Failed to update the KV store")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400869 return
870 }
871 // initialize pon_intf_onu_id tuple to gemport_ids map
872 GEMPortIDPath := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
873 var GEMPortIDs []byte
npujarec5762e2020-01-01 14:08:48 +0530874 Result = PONRMgr.KVStore.Put(ctx, GEMPortIDPath, GEMPortIDs)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400875 if Result != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000876 logger.Error(ctx, "Failed to update the KV store")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400877 return
878 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400879}
880
npujarec5762e2020-01-01 14:08:48 +0530881func (PONRMgr PONResourceManager) RemoveResourceMap(ctx context.Context, PONIntfONUID string) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400882 /*
883 Remove resource map
884 :param pon_intf_onu_id: reference of PON interface id and onu id
885 */
886 // remove pon_intf_onu_id tuple to alloc_ids map
887 var err error
888 AllocIDPath := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujarec5762e2020-01-01 14:08:48 +0530889 if err = PONRMgr.KVStore.Delete(ctx, AllocIDPath); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000890 logger.Errorf(ctx, "Failed to remove resource %s", AllocIDPath)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400891 return false
892 }
893 // remove pon_intf_onu_id tuple to gemport_ids map
894 GEMPortIDPath := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujarec5762e2020-01-01 14:08:48 +0530895 err = PONRMgr.KVStore.Delete(ctx, GEMPortIDPath)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400896 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000897 logger.Errorf(ctx, "Failed to remove resource %s", GEMPortIDPath)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400898 return false
899 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400900
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400901 FlowIDPath := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujarec5762e2020-01-01 14:08:48 +0530902 if FlowIDs, err := PONRMgr.KVStore.List(ctx, FlowIDPath); err != nil {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400903 for _, Flow := range FlowIDs {
904 FlowIDInfoPath := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, PONIntfONUID, Flow.Value)
npujarec5762e2020-01-01 14:08:48 +0530905 if err = PONRMgr.KVStore.Delete(ctx, FlowIDInfoPath); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000906 logger.Errorf(ctx, "Failed to remove resource %s", FlowIDInfoPath)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400907 return false
908 }
909 }
910 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400911
npujarec5762e2020-01-01 14:08:48 +0530912 if err = PONRMgr.KVStore.Delete(ctx, FlowIDPath); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000913 logger.Errorf(ctx, "Failed to remove resource %s", FlowIDPath)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400914 return false
915 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400916
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400917 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400918}
919
npujarec5762e2020-01-01 14:08:48 +0530920func (PONRMgr *PONResourceManager) GetCurrentAllocIDForOnu(ctx context.Context, IntfONUID string) []uint32 {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400921 /*
922 Get currently configured alloc ids for given pon_intf_onu_id
923 :param pon_intf_onu_id: reference of PON interface id and onu id
924 :return list: List of alloc_ids if available, else None
925 */
926 Path := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400927
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400928 var Data []uint32
npujarec5762e2020-01-01 14:08:48 +0530929 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400930 if err == nil {
931 if Value != nil {
932 Val, err := ToByte(Value.Value)
933 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000934 logger.Errorw(ctx, "Failed to convert into byte array", log.Fields{"error": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400935 return Data
936 }
937 if err = json.Unmarshal(Val, &Data); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000938 logger.Error(ctx, "Failed to unmarshal", log.Fields{"error": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400939 return Data
940 }
941 }
942 }
943 return Data
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400944}
945
npujarec5762e2020-01-01 14:08:48 +0530946func (PONRMgr *PONResourceManager) GetCurrentGEMPortIDsForOnu(ctx context.Context, IntfONUID string) []uint32 {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400947 /*
948 Get currently configured gemport ids for given pon_intf_onu_id
949 :param pon_intf_onu_id: reference of PON interface id and onu id
950 :return list: List of gemport IDs if available, else None
951 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400952
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400953 Path := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000954 logger.Debugf(ctx, "Getting current gemports for %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400955 var Data []uint32
npujarec5762e2020-01-01 14:08:48 +0530956 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400957 if err == nil {
958 if Value != nil {
959 Val, _ := ToByte(Value.Value)
960 if err = json.Unmarshal(Val, &Data); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000961 logger.Errorw(ctx, "Failed to unmarshal", log.Fields{"error": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400962 return Data
963 }
964 }
965 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000966 logger.Errorf(ctx, "Failed to get data from kvstore for %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400967 }
968 return Data
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400969}
970
npujarec5762e2020-01-01 14:08:48 +0530971func (PONRMgr *PONResourceManager) GetCurrentFlowIDsForOnu(ctx context.Context, IntfONUID string) []uint32 {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400972 /*
973 Get currently configured flow ids for given pon_intf_onu_id
974 :param pon_intf_onu_id: reference of PON interface id and onu id
975 :return list: List of Flow IDs if available, else None
976 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400977
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400978 Path := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400979
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400980 var Data []uint32
npujarec5762e2020-01-01 14:08:48 +0530981 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400982 if err == nil {
983 if Value != nil {
984 Val, _ := ToByte(Value.Value)
985 if err = json.Unmarshal(Val, &Data); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000986 logger.Error(ctx, "Failed to unmarshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400987 return Data
988 }
989 }
990 }
991 return Data
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400992}
993
npujarec5762e2020-01-01 14:08:48 +0530994func (PONRMgr *PONResourceManager) GetFlowIDInfo(ctx context.Context, IntfONUID string, FlowID uint32, Data interface{}) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400995 /*
996 Get flow details configured for the ONU.
997 :param pon_intf_onu_id: reference of PON interface id and onu id
998 :param flow_id: Flow Id reference
999 :param Data: Result
1000 :return error: nil if no error in getting from KV store
1001 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001002
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001003 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001004
npujarec5762e2020-01-01 14:08:48 +05301005 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001006 if err == nil {
1007 if Value != nil {
1008 Val, err := ToByte(Value.Value)
1009 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001010 logger.Errorw(ctx, "Failed to convert flowinfo into byte array", log.Fields{"error": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001011 return err
1012 }
1013 if err = json.Unmarshal(Val, Data); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001014 logger.Errorw(ctx, "Failed to unmarshal", log.Fields{"error": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001015 return err
1016 }
1017 }
1018 }
1019 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001020}
1021
npujarec5762e2020-01-01 14:08:48 +05301022func (PONRMgr *PONResourceManager) RemoveFlowIDInfo(ctx context.Context, IntfONUID string, FlowID uint32) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001023 /*
1024 Get flow_id details configured for the ONU.
1025 :param pon_intf_onu_id: reference of PON interface id and onu id
1026 :param flow_id: Flow Id reference
1027 */
1028 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001029
npujarec5762e2020-01-01 14:08:48 +05301030 if err := PONRMgr.KVStore.Delete(ctx, Path); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001031 logger.Errorf(ctx, "Falied to remove resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001032 return false
1033 }
1034 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001035}
1036
npujarec5762e2020-01-01 14:08:48 +05301037func (PONRMgr *PONResourceManager) UpdateAllocIdsForOnu(ctx context.Context, IntfONUID string, AllocIDs []uint32) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001038 /*
1039 Update currently configured alloc ids for given pon_intf_onu_id
1040 :param pon_intf_onu_id: reference of PON interface id and onu id
1041 :param alloc_ids: list of alloc ids
1042 */
1043 var Value []byte
1044 var err error
1045 Path := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
1046 Value, err = json.Marshal(AllocIDs)
1047 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001048 logger.Error(ctx, "failed to Marshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001049 return err
1050 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001051
npujarec5762e2020-01-01 14:08:48 +05301052 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001053 logger.Errorf(ctx, "Failed to update resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001054 return err
1055 }
1056 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001057}
1058
npujarec5762e2020-01-01 14:08:48 +05301059func (PONRMgr *PONResourceManager) UpdateGEMPortIDsForOnu(ctx context.Context, IntfONUID string, GEMPortIDs []uint32) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001060 /*
1061 Update currently configured gemport ids for given pon_intf_onu_id
1062 :param pon_intf_onu_id: reference of PON interface id and onu id
1063 :param gemport_ids: list of gem port ids
1064 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001065
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001066 var Value []byte
1067 var err error
1068 Path := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001069 logger.Debugf(ctx, "Updating gemport ids for %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001070 Value, err = json.Marshal(GEMPortIDs)
1071 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001072 logger.Error(ctx, "failed to Marshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001073 return err
1074 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001075
npujarec5762e2020-01-01 14:08:48 +05301076 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001077 logger.Errorf(ctx, "Failed to update resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001078 return err
1079 }
1080 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001081}
1082
1083func checkForFlowIDInList(FlowIDList []uint32, FlowID uint32) (bool, uint32) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001084 /*
1085 Check for a flow id in a given list of flow IDs.
1086 :param FLowIDList: List of Flow IDs
1087 :param FlowID: Flowd to check in the list
1088 : return true and the index if present false otherwise.
1089 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001090
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001091 for idx := range FlowIDList {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001092 if FlowID == FlowIDList[idx] {
1093 return true, uint32(idx)
1094 }
1095 }
1096 return false, 0
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001097}
1098
npujarec5762e2020-01-01 14:08:48 +05301099func (PONRMgr *PONResourceManager) UpdateFlowIDForOnu(ctx context.Context, IntfONUID string, FlowID uint32, Add bool) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001100 /*
1101 Update the flow_id list of the ONU (add or remove flow_id from the list)
1102 :param pon_intf_onu_id: reference of PON interface id and onu id
1103 :param flow_id: flow ID
1104 :param add: Boolean flag to indicate whether the flow_id should be
1105 added or removed from the list. Defaults to adding the flow.
1106 */
1107 var Value []byte
1108 var err error
1109 var RetVal bool
1110 var IDx uint32
1111 Path := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
npujarec5762e2020-01-01 14:08:48 +05301112 FlowIDs := PONRMgr.GetCurrentFlowIDsForOnu(ctx, IntfONUID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001113
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001114 if Add {
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001115 if RetVal, _ = checkForFlowIDInList(FlowIDs, FlowID); RetVal {
1116 return nil
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001117 }
1118 FlowIDs = append(FlowIDs, FlowID)
1119 } else {
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001120 if RetVal, IDx = checkForFlowIDInList(FlowIDs, FlowID); !RetVal {
1121 return nil
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001122 }
1123 // delete the index and shift
1124 FlowIDs = append(FlowIDs[:IDx], FlowIDs[IDx+1:]...)
1125 }
1126 Value, err = json.Marshal(FlowIDs)
1127 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001128 logger.Error(ctx, "Failed to Marshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001129 return err
1130 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001131
npujarec5762e2020-01-01 14:08:48 +05301132 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001133 logger.Errorf(ctx, "Failed to update resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001134 return err
1135 }
1136 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001137}
1138
npujarec5762e2020-01-01 14:08:48 +05301139func (PONRMgr *PONResourceManager) UpdateFlowIDInfoForOnu(ctx context.Context, IntfONUID string, FlowID uint32, FlowData interface{}) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001140 /*
1141 Update any metadata associated with the flow_id. The flow_data could be json
1142 or any of other data structure. The resource manager doesnt care
1143 :param pon_intf_onu_id: reference of PON interface id and onu id
1144 :param flow_id: Flow ID
1145 :param flow_data: Flow data blob
1146 */
1147 var Value []byte
1148 var err error
1149 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
1150 Value, err = json.Marshal(FlowData)
1151 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001152 logger.Error(ctx, "failed to Marshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001153 return err
1154 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001155
npujarec5762e2020-01-01 14:08:48 +05301156 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001157 logger.Errorf(ctx, "Failed to update resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001158 return err
1159 }
1160 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001161}
1162
Neha Sharma96b7bf22020-06-15 10:37:32 +00001163func (PONRMgr *PONResourceManager) GenerateNextID(ctx context.Context, Resource map[string]interface{}) (uint32, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001164 /*
1165 Generate unique id having OFFSET as start
1166 :param resource: resource used to generate ID
1167 :return uint32: generated id
1168 */
1169 ByteArray, err := ToByte(Resource[POOL])
1170 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001171 logger.Error(ctx, "Failed to convert resource to byte array")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001172 return 0, err
1173 }
1174 Data := bitmap.TSFromData(ByteArray, false)
1175 if Data == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001176 logger.Error(ctx, "Failed to get data from byte array")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001177 return 0, errors.New("Failed to get data from byte array")
1178 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001179
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001180 Len := Data.Len()
1181 var Idx int
1182 for Idx = 0; Idx < Len; Idx++ {
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001183 if !Data.Get(Idx) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001184 break
1185 }
1186 }
1187 Data.Set(Idx, true)
1188 res := uint32(Resource[START_IDX].(float64))
1189 Resource[POOL] = Data.Data(false)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001190 logger.Debugf(ctx, "Generated ID for %d", (uint32(Idx) + res))
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001191 return (uint32(Idx) + res), err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001192}
1193
Neha Sharma96b7bf22020-06-15 10:37:32 +00001194func (PONRMgr *PONResourceManager) ReleaseID(ctx context.Context, Resource map[string]interface{}, Id uint32) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001195 /*
1196 Release unique id having OFFSET as start index.
1197 :param resource: resource used to release ID
1198 :param unique_id: id need to be released
1199 */
1200 ByteArray, err := ToByte(Resource[POOL])
1201 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001202 logger.Error(ctx, "Failed to convert resource to byte array")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001203 return false
1204 }
1205 Data := bitmap.TSFromData(ByteArray, false)
1206 if Data == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001207 logger.Error(ctx, "Failed to get resource pool")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001208 return false
1209 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001210 Idx := Id - uint32(Resource[START_IDX].(float64))
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001211 Data.Set(int(Idx), false)
1212 Resource[POOL] = Data.Data(false)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001213
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001214 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001215}
1216
divyadesaid26f6b12020-03-19 06:30:28 +00001217/* Reserves a unique id in the specified resource pool.
1218:param Resource: resource used to reserve ID
1219:param Id: ID to be reserved
1220*/
Neha Sharma96b7bf22020-06-15 10:37:32 +00001221func (PONRMgr *PONResourceManager) reserveID(ctx context.Context, TSData *bitmap.Threadsafe, StartIndex uint32, Id uint32) bool {
divyadesaid26f6b12020-03-19 06:30:28 +00001222 Data := bitmap.TSFromData(TSData.Data(false), false)
1223 if Data == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001224 logger.Error(ctx, "Failed to get resource pool")
divyadesaid26f6b12020-03-19 06:30:28 +00001225 return false
1226 }
1227 Idx := Id - StartIndex
1228 Data.Set(int(Idx), true)
1229 return true
1230}
1231
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001232func (PONRMgr *PONResourceManager) GetTechnology() string {
1233 return PONRMgr.Technology
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001234}
1235
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001236func (PONRMgr *PONResourceManager) GetResourceTypeAllocID() string {
1237 return ALLOC_ID
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001238}
1239
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001240func (PONRMgr *PONResourceManager) GetResourceTypeGemPortID() string {
1241 return GEMPORT_ID
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001242}
1243
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001244// ToByte converts an interface value to a []byte. The interface should either be of
1245// a string type or []byte. Otherwise, an error is returned.
1246func ToByte(value interface{}) ([]byte, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001247 switch t := value.(type) {
1248 case []byte:
1249 return value.([]byte), nil
1250 case string:
1251 return []byte(value.(string)), nil
1252 default:
1253 return nil, fmt.Errorf("unexpected-type-%T", t)
1254 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001255}
1256
1257// ToString converts an interface value to a string. The interface should either be of
1258// a string type or []byte. Otherwise, an error is returned.
1259func ToString(value interface{}) (string, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001260 switch t := value.(type) {
1261 case []byte:
1262 return string(value.([]byte)), nil
1263 case string:
1264 return value.(string), nil
1265 default:
1266 return "", fmt.Errorf("unexpected-type-%T", t)
1267 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001268}
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001269
npujarec5762e2020-01-01 14:08:48 +05301270func (PONRMgr *PONResourceManager) AddOnuGemInfo(ctx context.Context, intfID uint32, onuGemData interface{}) error {
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001271 /*
1272 Update onugem info map,
1273 :param pon_intf_id: reference of PON interface id
1274 :param onuegmdata: onugem info map
1275 */
1276 var Value []byte
1277 var err error
1278 Path := fmt.Sprintf(ONU_GEM_INFO_PATH, PONRMgr.DeviceID, intfID)
1279 Value, err = json.Marshal(onuGemData)
1280 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001281 logger.Error(ctx, "failed to Marshal")
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001282 return err
1283 }
1284
npujarec5762e2020-01-01 14:08:48 +05301285 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001286 logger.Errorf(ctx, "Failed to update resource %s", Path)
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001287 return err
1288 }
1289 return err
1290}
1291
npujarec5762e2020-01-01 14:08:48 +05301292func (PONRMgr *PONResourceManager) GetOnuGemInfo(ctx context.Context, IntfId uint32, onuGemInfo interface{}) error {
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001293 /*
1294 Get onugeminfo map from kvstore
1295 :param intfid: refremce pon intfid
1296 :param onuGemInfo: onugem info to return from kv strore.
1297 */
1298 var Val []byte
1299
1300 path := fmt.Sprintf(ONU_GEM_INFO_PATH, PONRMgr.DeviceID, IntfId)
npujarec5762e2020-01-01 14:08:48 +05301301 value, err := PONRMgr.KVStore.Get(ctx, path)
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001302 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001303 logger.Errorw(ctx, "Failed to get from kv store", log.Fields{"path": path})
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001304 return err
1305 } else if value == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001306 logger.Debug(ctx, "No onuinfo for path", log.Fields{"path": path})
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001307 return nil // returning nil as this could happen if there are no onus for the interface yet
1308 }
1309 if Val, err = kvstore.ToByte(value.Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001310 logger.Error(ctx, "Failed to convert to byte array")
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001311 return err
1312 }
1313
1314 if err = json.Unmarshal(Val, &onuGemInfo); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001315 logger.Error(ctx, "Failed to unmarshall")
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001316 return err
1317 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001318 logger.Debugw(ctx, "found onuinfo from path", log.Fields{"path": path, "onuinfo": onuGemInfo})
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001319 return err
1320}
1321
npujarec5762e2020-01-01 14:08:48 +05301322func (PONRMgr *PONResourceManager) DelOnuGemInfoForIntf(ctx context.Context, intfId uint32) error {
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001323 /*
1324 delete onugem info for an interface from kvstore
1325 :param intfid: refremce pon intfid
1326 */
1327
1328 path := fmt.Sprintf(ONU_GEM_INFO_PATH, PONRMgr.DeviceID, intfId)
npujarec5762e2020-01-01 14:08:48 +05301329 if err := PONRMgr.KVStore.Delete(ctx, path); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001330 logger.Errorf(ctx, "Falied to remove resource %s", path)
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001331 return err
1332 }
1333 return nil
1334}