blob: 39707111e6f5a2c95c6b8b9d4142311bd9f3ba1b [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 Gowdra4c3d4602021-07-22 16:33:37 -070028 "github.com/opencord/voltha-lib-go/v6/pkg/db"
29 "github.com/opencord/voltha-lib-go/v6/pkg/db/kvstore"
30 "github.com/opencord/voltha-lib-go/v6/pkg/log"
Matt Jeanneretcab955f2019-04-10 15:45:57 -040031)
32
33const (
Matt Jeanneret384d8c92019-05-06 14:27:31 -040034 //Constants to identify resource pool
35 UNI_ID = "UNI_ID"
36 ONU_ID = "ONU_ID"
37 ALLOC_ID = "ALLOC_ID"
38 GEMPORT_ID = "GEMPORT_ID"
39 FLOW_ID = "FLOW_ID"
Matt Jeanneretcab955f2019-04-10 15:45:57 -040040
Matt Jeanneret384d8c92019-05-06 14:27:31 -040041 //Constants for passing command line arugments
42 OLT_MODEL_ARG = "--olt_model"
Matteo Scandolodfa7a972020-11-06 13:03:40 -080043
44 PATH_PREFIX = "%s/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 */
Matteo Scandolodfa7a972020-11-06 13:03:40 -080054
55 PATH_PREFIX_FOR_CONFIG = "%s/resource_manager/config"
Matt Jeanneret384d8c92019-05-06 14:27:31 -040056 /*The resource ranges for a given device model should be placed
57 at 'resource_manager/<technology>/resource_ranges/<olt_model_type>'
58 path on the KV store.
59 If Resource Range parameters are to be read from the external KV store,
60 they are expected to be stored in the following format.
61 Note: All parameters are MANDATORY for now.
62 constants used as keys to reference the resource range parameters from
63 and external KV store.
64 */
65 UNI_ID_START_IDX = "uni_id_start"
66 UNI_ID_END_IDX = "uni_id_end"
67 ONU_ID_START_IDX = "onu_id_start"
68 ONU_ID_END_IDX = "onu_id_end"
69 ONU_ID_SHARED_IDX = "onu_id_shared"
70 ALLOC_ID_START_IDX = "alloc_id_start"
71 ALLOC_ID_END_IDX = "alloc_id_end"
72 ALLOC_ID_SHARED_IDX = "alloc_id_shared"
73 GEMPORT_ID_START_IDX = "gemport_id_start"
74 GEMPORT_ID_END_IDX = "gemport_id_end"
75 GEMPORT_ID_SHARED_IDX = "gemport_id_shared"
76 FLOW_ID_START_IDX = "flow_id_start"
77 FLOW_ID_END_IDX = "flow_id_end"
78 FLOW_ID_SHARED_IDX = "flow_id_shared"
79 NUM_OF_PON_PORT = "pon_ports"
Matt Jeanneretcab955f2019-04-10 15:45:57 -040080
Matt Jeanneret384d8c92019-05-06 14:27:31 -040081 /*
82 The KV store backend is initialized with a path prefix and we need to
83 provide only the suffix.
84 */
85 PON_RESOURCE_RANGE_CONFIG_PATH = "resource_ranges/%s"
Matt Jeanneretcab955f2019-04-10 15:45:57 -040086
Matt Jeanneret384d8c92019-05-06 14:27:31 -040087 //resource path suffix
88 //Path on the KV store for storing alloc id ranges and resource pool for a given interface
89 //Format: <device_id>/alloc_id_pool/<pon_intf_id>
90 ALLOC_ID_POOL_PATH = "{%s}/alloc_id_pool/{%d}"
91 //Path on the KV store for storing gemport id ranges and resource pool for a given interface
92 //Format: <device_id>/gemport_id_pool/<pon_intf_id>
93 GEMPORT_ID_POOL_PATH = "{%s}/gemport_id_pool/{%d}"
94 //Path on the KV store for storing onu id ranges and resource pool for a given interface
95 //Format: <device_id>/onu_id_pool/<pon_intf_id>
96 ONU_ID_POOL_PATH = "{%s}/onu_id_pool/{%d}"
97 //Path on the KV store for storing flow id ranges and resource pool for a given interface
98 //Format: <device_id>/flow_id_pool/<pon_intf_id>
99 FLOW_ID_POOL_PATH = "{%s}/flow_id_pool/{%d}"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400100
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400101 //Path on the KV store for storing list of alloc IDs for a given ONU
102 //Format: <device_id>/<(pon_intf_id, onu_id)>/alloc_ids
103 ALLOC_ID_RESOURCE_MAP_PATH = "{%s}/{%s}/alloc_ids"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400104
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400105 //Path on the KV store for storing list of gemport IDs for a given ONU
106 //Format: <device_id>/<(pon_intf_id, onu_id)>/gemport_ids
107 GEMPORT_ID_RESOURCE_MAP_PATH = "{%s}/{%s}/gemport_ids"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400108
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400109 //Path on the KV store for storing list of Flow IDs for a given ONU
110 //Format: <device_id>/<(pon_intf_id, onu_id)>/flow_ids
111 FLOW_ID_RESOURCE_MAP_PATH = "{%s}/{%s}/flow_ids"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400112
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400113 //Flow Id info: Use to store more metadata associated with the flow_id
serkant.uluderya7b8211e2021-02-24 16:39:18 +0300114 FLOW_ID_INFO_PATH_PREFIX = "{%s}/flow_id_info"
115 //Format: <device_id>/flow_id_info/<(pon_intf_id, onu_id)>
116 FLOW_ID_INFO_PATH_INTF_ONU_PREFIX = "{%s}/flow_id_info/{%s}"
117 //Format: <device_id>/flow_id_info/<(pon_intf_id, onu_id)><flow_id>
118 FLOW_ID_INFO_PATH = FLOW_ID_INFO_PATH_PREFIX + "/{%s}/{%d}"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400119
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
serkant.uluderya7b8211e2021-02-24 16:39:18 +0300141 Backend string // ETCD only currently
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
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400146
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400147 // Below attribute, pon_resource_ranges, should be initialized
148 // by reading from KV store.
149 PonResourceRanges map[string]interface{}
150 SharedResourceMgrs map[string]*PONResourceManager
151 SharedIdxByType map[string]string
152 IntfIDs []uint32 // list of pon interface IDs
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400153 Globalorlocal string
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400154}
155
Neha Sharma96b7bf22020-06-15 10:37:32 +0000156func newKVClient(ctx context.Context, storeType string, address string, timeout time.Duration) (kvstore.Client, error) {
157 logger.Infow(ctx, "kv-store-type", log.Fields{"store": storeType})
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400158 switch storeType {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400159 case "etcd":
Neha Sharma96b7bf22020-06-15 10:37:32 +0000160 return kvstore.NewEtcdClient(ctx, address, timeout, log.WarnLevel)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400161 }
162 return nil, errors.New("unsupported-kv-store")
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400163}
164
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800165func SetKVClient(ctx context.Context, Technology string, Backend string, Addr string, configClient bool, basePathKvStore string) *db.Backend {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400166 // TODO : Make sure direct call to NewBackend is working fine with backend , currently there is some
167 // issue between kv store and backend , core is not calling NewBackend directly
Neha Sharma96b7bf22020-06-15 10:37:32 +0000168 kvClient, err := newKVClient(ctx, Backend, Addr, KVSTORE_RETRY_TIMEOUT)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400169 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000170 logger.Fatalw(ctx, "Failed to init KV client\n", log.Fields{"err": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400171 return nil
172 }
divyadesaid26f6b12020-03-19 06:30:28 +0000173
174 var pathPrefix string
175 if configClient {
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800176 pathPrefix = fmt.Sprintf(PATH_PREFIX_FOR_CONFIG, basePathKvStore)
divyadesaid26f6b12020-03-19 06:30:28 +0000177 } else {
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800178 pathPrefix = fmt.Sprintf(PATH_PREFIX, basePathKvStore, Technology)
divyadesaid26f6b12020-03-19 06:30:28 +0000179 }
180
sbarbaria8910ba2019-11-05 10:12:23 -0500181 kvbackend := &db.Backend{
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400182 Client: kvClient,
183 StoreType: Backend,
Neha Sharma3f221ae2020-04-29 19:02:12 +0000184 Address: Addr,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400185 Timeout: KVSTORE_RETRY_TIMEOUT,
divyadesaid26f6b12020-03-19 06:30:28 +0000186 PathPrefix: pathPrefix}
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400187
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400188 return kvbackend
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400189}
190
191// NewPONResourceManager creates a new PON resource manager.
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800192func 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 -0400193 var PONMgr PONResourceManager
194 PONMgr.Technology = Technology
195 PONMgr.DeviceType = DeviceType
196 PONMgr.DeviceID = DeviceID
197 PONMgr.Backend = Backend
Neha Sharma3f221ae2020-04-29 19:02:12 +0000198 PONMgr.Address = Address
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800199 PONMgr.KVStore = SetKVClient(ctx, Technology, Backend, Address, false, basePathKvStore)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400200 if PONMgr.KVStore == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000201 logger.Error(ctx, "KV Client initilization failed")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400202 return nil, errors.New("Failed to init KV client")
203 }
divyadesaid26f6b12020-03-19 06:30:28 +0000204 // init kv client to read from the config path
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800205 PONMgr.KVStoreForConfig = SetKVClient(ctx, Technology, Backend, Address, true, basePathKvStore)
divyadesaid26f6b12020-03-19 06:30:28 +0000206 if PONMgr.KVStoreForConfig == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000207 logger.Error(ctx, "KV Config Client initilization failed")
divyadesaid26f6b12020-03-19 06:30:28 +0000208 return nil, errors.New("Failed to init KV Config client")
209 }
Girish Gowdra4c3d4602021-07-22 16:33:37 -0700210
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400211 PONMgr.PonResourceRanges = make(map[string]interface{})
212 PONMgr.SharedResourceMgrs = make(map[string]*PONResourceManager)
213 PONMgr.SharedIdxByType = make(map[string]string)
214 PONMgr.SharedIdxByType[ONU_ID] = ONU_ID_SHARED_IDX
215 PONMgr.SharedIdxByType[ALLOC_ID] = ALLOC_ID_SHARED_IDX
216 PONMgr.SharedIdxByType[GEMPORT_ID] = GEMPORT_ID_SHARED_IDX
217 PONMgr.SharedIdxByType[FLOW_ID] = FLOW_ID_SHARED_IDX
218 PONMgr.IntfIDs = make([]uint32, NUM_OF_PON_INTF)
219 PONMgr.OLTModel = DeviceType
220 return &PONMgr, nil
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400221}
222
223/*
224 Initialize PON resource ranges with config fetched from kv store.
225 return boolean: True if PON resource ranges initialized else false
226 Try to initialize the PON Resource Ranges from KV store based on the
227 OLT model key, if available
228*/
229
npujarec5762e2020-01-01 14:08:48 +0530230func (PONRMgr *PONResourceManager) InitResourceRangesFromKVStore(ctx context.Context) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400231 //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 if PONRMgr.OLTModel == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000236 logger.Error(ctx, "Failed to get OLT model")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400237 return false
238 }
239 Path := fmt.Sprintf(PON_RESOURCE_RANGE_CONFIG_PATH, PONRMgr.OLTModel)
240 //get resource from kv store
npujarec5762e2020-01-01 14:08:48 +0530241 Result, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400242 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000243 logger.Debugf(ctx, "Error in fetching resource %s from KV strore", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400244 return false
245 }
246 if Result == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000247 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 -0400248 return false
249 }
250 //update internal ranges from kv ranges. If there are missing
251 // values in the KV profile, continue to use the defaults
252 Value, err := ToByte(Result.Value)
253 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000254 logger.Error(ctx, "Failed to convert kvpair to byte string")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400255 return false
256 }
257 if err := json.Unmarshal(Value, &PONRMgr.PonResourceRanges); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000258 logger.Error(ctx, "Failed to Unmarshal json byte")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400259 return false
260 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000261 logger.Debug(ctx, "Init resource ranges from kvstore success")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400262 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400263}
264
Neha Sharma96b7bf22020-06-15 10:37:32 +0000265func (PONRMgr *PONResourceManager) UpdateRanges(ctx context.Context, StartIDx string, StartID uint32, EndIDx string, EndID uint32,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400266 SharedIDx string, SharedPoolID uint32, RMgr *PONResourceManager) {
267 /*
268 Update the ranges for all reosurce type in the intermnal maps
269 param: resource type start index
270 param: start ID
271 param: resource type end index
272 param: end ID
273 param: resource type shared index
274 param: shared pool id
275 param: global resource manager
276 */
Neha Sharma96b7bf22020-06-15 10:37:32 +0000277 logger.Debugf(ctx, "update ranges for %s, %d", StartIDx, StartID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400278
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400279 if StartID != 0 {
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400280 if (PONRMgr.PonResourceRanges[StartIDx] == nil) || (PONRMgr.PonResourceRanges[StartIDx].(uint32) < StartID) {
281 PONRMgr.PonResourceRanges[StartIDx] = StartID
282 }
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400283 }
284 if EndID != 0 {
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400285 if (PONRMgr.PonResourceRanges[EndIDx] == nil) || (PONRMgr.PonResourceRanges[EndIDx].(uint32) > EndID) {
286 PONRMgr.PonResourceRanges[EndIDx] = EndID
287 }
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400288 }
289 //if SharedPoolID != 0 {
290 PONRMgr.PonResourceRanges[SharedIDx] = SharedPoolID
291 //}
292 if RMgr != nil {
293 PONRMgr.SharedResourceMgrs[SharedIDx] = RMgr
294 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400295}
296
Neha Sharma96b7bf22020-06-15 10:37:32 +0000297func (PONRMgr *PONResourceManager) InitDefaultPONResourceRanges(ctx context.Context,
298 ONUIDStart uint32,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400299 ONUIDEnd uint32,
300 ONUIDSharedPoolID uint32,
301 AllocIDStart uint32,
302 AllocIDEnd uint32,
303 AllocIDSharedPoolID uint32,
304 GEMPortIDStart uint32,
305 GEMPortIDEnd uint32,
306 GEMPortIDSharedPoolID uint32,
307 FlowIDStart uint32,
308 FlowIDEnd uint32,
309 FlowIDSharedPoolID uint32,
310 UNIIDStart uint32,
311 UNIIDEnd uint32,
312 NoOfPONPorts uint32,
313 IntfIDs []uint32) bool {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400314
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400315 /*Initialize default PON resource ranges
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400316
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400317 :param onu_id_start_idx: onu id start index
318 :param onu_id_end_idx: onu id end index
319 :param onu_id_shared_pool_id: pool idx for id shared by all intfs or None for no sharing
320 :param alloc_id_start_idx: alloc id start index
321 :param alloc_id_end_idx: alloc id end index
322 :param alloc_id_shared_pool_id: pool idx for alloc id shared by all intfs or None for no sharing
323 :param gemport_id_start_idx: gemport id start index
324 :param gemport_id_end_idx: gemport id end index
325 :param gemport_id_shared_pool_id: pool idx for gemport id shared by all intfs or None for no sharing
326 :param flow_id_start_idx: flow id start index
327 :param flow_id_end_idx: flow id end index
328 :param flow_id_shared_pool_id: pool idx for flow id shared by all intfs or None for no sharing
329 :param num_of_pon_ports: number of PON ports
330 :param intf_ids: interfaces serviced by this manager
331 */
Neha Sharma96b7bf22020-06-15 10:37:32 +0000332 PONRMgr.UpdateRanges(ctx, ONU_ID_START_IDX, ONUIDStart, ONU_ID_END_IDX, ONUIDEnd, ONU_ID_SHARED_IDX, ONUIDSharedPoolID, nil)
333 PONRMgr.UpdateRanges(ctx, ALLOC_ID_START_IDX, AllocIDStart, ALLOC_ID_END_IDX, AllocIDEnd, ALLOC_ID_SHARED_IDX, AllocIDSharedPoolID, nil)
334 PONRMgr.UpdateRanges(ctx, GEMPORT_ID_START_IDX, GEMPortIDStart, GEMPORT_ID_END_IDX, GEMPortIDEnd, GEMPORT_ID_SHARED_IDX, GEMPortIDSharedPoolID, nil)
335 PONRMgr.UpdateRanges(ctx, FLOW_ID_START_IDX, FlowIDStart, FLOW_ID_END_IDX, FlowIDEnd, FLOW_ID_SHARED_IDX, FlowIDSharedPoolID, nil)
336 PONRMgr.UpdateRanges(ctx, UNI_ID_START_IDX, UNIIDStart, UNI_ID_END_IDX, UNIIDEnd, "", 0, nil)
337 logger.Debug(ctx, "Initialize default range values")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400338 var i uint32
339 if IntfIDs == nil {
340 for i = 0; i < NoOfPONPorts; i++ {
341 PONRMgr.IntfIDs = append(PONRMgr.IntfIDs, i)
342 }
343 } else {
344 PONRMgr.IntfIDs = IntfIDs
345 }
346 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400347}
348
npujarec5762e2020-01-01 14:08:48 +0530349func (PONRMgr *PONResourceManager) InitDeviceResourcePool(ctx context.Context) error {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400350
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400351 //Initialize resource pool for all PON ports.
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400352
Neha Sharma96b7bf22020-06-15 10:37:32 +0000353 logger.Debug(ctx, "Init resource ranges")
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400354
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400355 var err error
356 for _, Intf := range PONRMgr.IntfIDs {
357 SharedPoolID := PONRMgr.PonResourceRanges[ONU_ID_SHARED_IDX].(uint32)
358 if SharedPoolID != 0 {
359 Intf = SharedPoolID
360 }
npujarec5762e2020-01-01 14:08:48 +0530361 if err = PONRMgr.InitResourceIDPool(ctx, Intf, ONU_ID,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400362 PONRMgr.PonResourceRanges[ONU_ID_START_IDX].(uint32),
363 PONRMgr.PonResourceRanges[ONU_ID_END_IDX].(uint32)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000364 logger.Error(ctx, "Failed to init ONU ID resource pool")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400365 return err
366 }
367 if SharedPoolID != 0 {
368 break
369 }
370 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400371
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400372 for _, Intf := range PONRMgr.IntfIDs {
373 SharedPoolID := PONRMgr.PonResourceRanges[ALLOC_ID_SHARED_IDX].(uint32)
374 if SharedPoolID != 0 {
375 Intf = SharedPoolID
376 }
npujarec5762e2020-01-01 14:08:48 +0530377 if err = PONRMgr.InitResourceIDPool(ctx, Intf, ALLOC_ID,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400378 PONRMgr.PonResourceRanges[ALLOC_ID_START_IDX].(uint32),
379 PONRMgr.PonResourceRanges[ALLOC_ID_END_IDX].(uint32)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000380 logger.Error(ctx, "Failed to init ALLOC ID resource pool ")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400381 return err
382 }
383 if SharedPoolID != 0 {
384 break
385 }
386 }
387 for _, Intf := range PONRMgr.IntfIDs {
388 SharedPoolID := PONRMgr.PonResourceRanges[GEMPORT_ID_SHARED_IDX].(uint32)
389 if SharedPoolID != 0 {
390 Intf = SharedPoolID
391 }
npujarec5762e2020-01-01 14:08:48 +0530392 if err = PONRMgr.InitResourceIDPool(ctx, Intf, GEMPORT_ID,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400393 PONRMgr.PonResourceRanges[GEMPORT_ID_START_IDX].(uint32),
394 PONRMgr.PonResourceRanges[GEMPORT_ID_END_IDX].(uint32)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000395 logger.Error(ctx, "Failed to init GEMPORT ID resource pool")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400396 return err
397 }
398 if SharedPoolID != 0 {
399 break
400 }
401 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400402
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400403 for _, Intf := range PONRMgr.IntfIDs {
404 SharedPoolID := PONRMgr.PonResourceRanges[FLOW_ID_SHARED_IDX].(uint32)
405 if SharedPoolID != 0 {
406 Intf = SharedPoolID
407 }
npujarec5762e2020-01-01 14:08:48 +0530408 if err = PONRMgr.InitResourceIDPool(ctx, Intf, FLOW_ID,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400409 PONRMgr.PonResourceRanges[FLOW_ID_START_IDX].(uint32),
410 PONRMgr.PonResourceRanges[FLOW_ID_END_IDX].(uint32)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000411 logger.Error(ctx, "Failed to init FLOW ID resource pool")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400412 return err
413 }
414 if SharedPoolID != 0 {
415 break
416 }
417 }
418 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400419}
420
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700421func (PONRMgr *PONResourceManager) InitDeviceResourcePoolForIntf(ctx context.Context, intfID uint32) error {
422
423 logger.Debug(ctx, "Init resource ranges for intf %d", intfID)
424
425 var err error
426
427 if err = PONRMgr.InitResourceIDPool(ctx, intfID, ONU_ID,
428 PONRMgr.PonResourceRanges[ONU_ID_START_IDX].(uint32),
429 PONRMgr.PonResourceRanges[ONU_ID_END_IDX].(uint32)); err != nil {
430 logger.Error(ctx, "Failed to init ONU ID resource pool")
431 return err
432 }
433
434 if err = PONRMgr.InitResourceIDPool(ctx, intfID, ALLOC_ID,
435 PONRMgr.PonResourceRanges[ALLOC_ID_START_IDX].(uint32),
436 PONRMgr.PonResourceRanges[ALLOC_ID_END_IDX].(uint32)); err != nil {
437 logger.Error(ctx, "Failed to init ALLOC ID resource pool ")
438 return err
439 }
440
441 if err = PONRMgr.InitResourceIDPool(ctx, intfID, GEMPORT_ID,
442 PONRMgr.PonResourceRanges[GEMPORT_ID_START_IDX].(uint32),
443 PONRMgr.PonResourceRanges[GEMPORT_ID_END_IDX].(uint32)); err != nil {
444 logger.Error(ctx, "Failed to init GEMPORT ID resource pool")
445 return err
446 }
447
448 if err = PONRMgr.InitResourceIDPool(ctx, intfID, FLOW_ID,
449 PONRMgr.PonResourceRanges[FLOW_ID_START_IDX].(uint32),
450 PONRMgr.PonResourceRanges[FLOW_ID_END_IDX].(uint32)); err != nil {
451 logger.Error(ctx, "Failed to init FLOW ID resource pool")
452 return err
453 }
454
455 return nil
456}
457
npujarec5762e2020-01-01 14:08:48 +0530458func (PONRMgr *PONResourceManager) ClearDeviceResourcePool(ctx context.Context) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -0400459
460 //Clear resource pool for all PON ports.
461
Neha Sharma96b7bf22020-06-15 10:37:32 +0000462 logger.Debug(ctx, "Clear resource ranges")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400463
464 for _, Intf := range PONRMgr.IntfIDs {
465 SharedPoolID := PONRMgr.PonResourceRanges[ONU_ID_SHARED_IDX].(uint32)
466 if SharedPoolID != 0 {
467 Intf = SharedPoolID
468 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000469 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, ONU_ID); !status {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000470 logger.Error(ctx, "Failed to clear ONU ID resource pool")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400471 return errors.New("Failed to clear ONU ID resource pool")
472 }
473 if SharedPoolID != 0 {
474 break
475 }
476 }
477
478 for _, Intf := range PONRMgr.IntfIDs {
479 SharedPoolID := PONRMgr.PonResourceRanges[ALLOC_ID_SHARED_IDX].(uint32)
480 if SharedPoolID != 0 {
481 Intf = SharedPoolID
482 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000483 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, ALLOC_ID); !status {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000484 logger.Error(ctx, "Failed to clear ALLOC ID resource pool ")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400485 return errors.New("Failed to clear ALLOC ID resource pool")
486 }
487 if SharedPoolID != 0 {
488 break
489 }
490 }
491 for _, Intf := range PONRMgr.IntfIDs {
492 SharedPoolID := PONRMgr.PonResourceRanges[GEMPORT_ID_SHARED_IDX].(uint32)
493 if SharedPoolID != 0 {
494 Intf = SharedPoolID
495 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000496 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, GEMPORT_ID); !status {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000497 logger.Error(ctx, "Failed to clear GEMPORT ID resource pool")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400498 return errors.New("Failed to clear GEMPORT ID resource pool")
499 }
500 if SharedPoolID != 0 {
501 break
502 }
503 }
504
505 for _, Intf := range PONRMgr.IntfIDs {
506 SharedPoolID := PONRMgr.PonResourceRanges[FLOW_ID_SHARED_IDX].(uint32)
507 if SharedPoolID != 0 {
508 Intf = SharedPoolID
509 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000510 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, FLOW_ID); !status {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000511 logger.Error(ctx, "Failed to clear FLOW ID resource pool")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400512 return errors.New("Failed to clear FLOW ID resource pool")
513 }
514 if SharedPoolID != 0 {
515 break
516 }
517 }
518 return nil
519}
520
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700521func (PONRMgr *PONResourceManager) ClearDeviceResourcePoolForIntf(ctx context.Context, intfID uint32) error {
522
523 logger.Debugf(ctx, "Clear resource ranges for intf %d", intfID)
524
525 if status := PONRMgr.ClearResourceIDPool(ctx, intfID, ONU_ID); !status {
526 logger.Error(ctx, "Failed to clear ONU ID resource pool")
527 return errors.New("Failed to clear ONU ID resource pool")
528 }
529
530 if status := PONRMgr.ClearResourceIDPool(ctx, intfID, ALLOC_ID); !status {
531 logger.Error(ctx, "Failed to clear ALLOC ID resource pool ")
532 return errors.New("Failed to clear ALLOC ID resource pool")
533 }
534
535 if status := PONRMgr.ClearResourceIDPool(ctx, intfID, GEMPORT_ID); !status {
536 logger.Error(ctx, "Failed to clear GEMPORT ID resource pool")
537 return errors.New("Failed to clear GEMPORT ID resource pool")
538 }
539
540 if status := PONRMgr.ClearResourceIDPool(ctx, intfID, FLOW_ID); !status {
541 logger.Error(ctx, "Failed to clear FLOW ID resource pool")
542 return errors.New("Failed to clear FLOW ID resource pool")
543 }
544
545 return nil
546}
547
npujarec5762e2020-01-01 14:08:48 +0530548func (PONRMgr *PONResourceManager) InitResourceIDPool(ctx context.Context, Intf uint32, ResourceType string, StartID uint32, EndID uint32) error {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400549
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400550 /*Initialize Resource ID pool for a given Resource Type on a given PON Port
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400551
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400552 :param pon_intf_id: OLT PON interface id
553 :param resource_type: String to identify type of resource
554 :param start_idx: start index for onu id pool
555 :param end_idx: end index for onu id pool
556 :return boolean: True if resource id pool initialized else false
557 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400558
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400559 // delegate to the master instance if sharing enabled across instances
560 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
561 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujarec5762e2020-01-01 14:08:48 +0530562 return SharedResourceMgr.InitResourceIDPool(ctx, Intf, ResourceType, StartID, EndID)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400563 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400564
Neha Sharma96b7bf22020-06-15 10:37:32 +0000565 Path := PONRMgr.GetPath(ctx, Intf, ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400566 if Path == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000567 logger.Errorf(ctx, "Failed to get path for resource type %s", ResourceType)
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000568 return fmt.Errorf("Failed to get path for resource type %s", ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400569 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400570
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400571 //In case of adapter reboot and reconciliation resource in kv store
572 //checked for its presence if not kv store update happens
npujarec5762e2020-01-01 14:08:48 +0530573 Res, err := PONRMgr.GetResource(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400574 if (err == nil) && (Res != nil) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000575 logger.Debugf(ctx, "Resource %s already present in store ", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400576 return nil
577 } else {
divyadesaid26f6b12020-03-19 06:30:28 +0000578 var excluded []uint32
579 if ResourceType == GEMPORT_ID {
580 //get gem port ids defined in the KV store, if any, and exclude them from the gem port id pool
581 if reservedGemPortIds, defined := PONRMgr.getReservedGemPortIdsFromKVStore(ctx); defined {
582 excluded = reservedGemPortIds
Neha Sharma96b7bf22020-06-15 10:37:32 +0000583 logger.Debugw(ctx, "Excluding some ports from GEM port id pool", log.Fields{"excluded gem ports": excluded})
divyadesaid26f6b12020-03-19 06:30:28 +0000584 }
585 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000586 FormatResult, err := PONRMgr.FormatResource(ctx, Intf, StartID, EndID, excluded)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400587 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000588 logger.Errorf(ctx, "Failed to format resource")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400589 return err
590 }
591 // Add resource as json in kv store.
npujarec5762e2020-01-01 14:08:48 +0530592 err = PONRMgr.KVStore.Put(ctx, Path, FormatResult)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400593 if err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000594 logger.Debug(ctx, "Successfuly posted to kv store")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400595 return err
596 }
597 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400598
Neha Sharma96b7bf22020-06-15 10:37:32 +0000599 logger.Debug(ctx, "Error initializing pool")
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400600
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400601 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400602}
603
divyadesaid26f6b12020-03-19 06:30:28 +0000604func (PONRMgr *PONResourceManager) getReservedGemPortIdsFromKVStore(ctx context.Context) ([]uint32, bool) {
605 var reservedGemPortIds []uint32
606 // read reserved gem ports from the config path
607 KvPair, err := PONRMgr.KVStoreForConfig.Get(ctx, RESERVED_GEMPORT_IDS_PATH)
608 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000609 logger.Errorw(ctx, "Unable to get reserved GEM port ids from the kv store", log.Fields{"err": err})
divyadesaid26f6b12020-03-19 06:30:28 +0000610 return reservedGemPortIds, false
611 }
612 if KvPair == nil || KvPair.Value == nil {
613 //no reserved gem port defined in the store
614 return reservedGemPortIds, false
615 }
616 Val, err := kvstore.ToByte(KvPair.Value)
617 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000618 logger.Errorw(ctx, "Failed to convert reserved gem port ids into byte array", log.Fields{"err": err})
divyadesaid26f6b12020-03-19 06:30:28 +0000619 return reservedGemPortIds, false
620 }
621 if err = json.Unmarshal(Val, &reservedGemPortIds); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000622 logger.Errorw(ctx, "Failed to unmarshal reservedGemPortIds", log.Fields{"err": err})
divyadesaid26f6b12020-03-19 06:30:28 +0000623 return reservedGemPortIds, false
624 }
625 return reservedGemPortIds, true
626}
627
Neha Sharma96b7bf22020-06-15 10:37:32 +0000628func (PONRMgr *PONResourceManager) FormatResource(ctx context.Context, IntfID uint32, StartIDx uint32, EndIDx uint32,
divyadesaid26f6b12020-03-19 06:30:28 +0000629 Excluded []uint32) ([]byte, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400630 /*
631 Format resource as json.
632 :param pon_intf_id: OLT PON interface id
633 :param start_idx: start index for id pool
634 :param end_idx: end index for id pool
divyadesaid26f6b12020-03-19 06:30:28 +0000635 :Id values to be Excluded from the pool
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400636 :return dictionary: resource formatted as map
637 */
638 // Format resource as json to be stored in backend store
639 Resource := make(map[string]interface{})
640 Resource[PON_INTF_ID] = IntfID
641 Resource[START_IDX] = StartIDx
642 Resource[END_IDX] = EndIDx
643 /*
644 Resource pool stored in backend store as binary string.
645 Tracking the resource allocation will be done by setting the bits \
646 in the byte array. The index set will be the resource number allocated.
647 */
648 var TSData *bitmap.Threadsafe
649 if TSData = bitmap.NewTS(int(EndIDx)); TSData == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000650 logger.Error(ctx, "Failed to create a bitmap")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400651 return nil, errors.New("Failed to create bitmap")
652 }
divyadesaid26f6b12020-03-19 06:30:28 +0000653 for _, excludedID := range Excluded {
654 if excludedID < StartIDx || excludedID > EndIDx {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000655 logger.Warnf(ctx, "Cannot reserve %d. It must be in the range of [%d, %d]", excludedID,
divyadesaid26f6b12020-03-19 06:30:28 +0000656 StartIDx, EndIDx)
657 continue
658 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000659 PONRMgr.reserveID(ctx, TSData, StartIDx, excludedID)
divyadesaid26f6b12020-03-19 06:30:28 +0000660 }
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400661 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 -0400662
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400663 Value, err := json.Marshal(Resource)
664 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000665 logger.Errorf(ctx, "Failed to marshall resource")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400666 return nil, err
667 }
668 return Value, err
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400669}
npujarec5762e2020-01-01 14:08:48 +0530670func (PONRMgr *PONResourceManager) GetResource(ctx context.Context, Path string) (map[string]interface{}, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400671 /*
672 Get resource from kv store.
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400673
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400674 :param path: path to get resource
675 :return: resource if resource present in kv store else None
676 */
677 //get resource from kv store
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400678
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400679 var Value []byte
680 Result := make(map[string]interface{})
681 var Str string
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400682
npujarec5762e2020-01-01 14:08:48 +0530683 Resource, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400684 if (err != nil) || (Resource == nil) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000685 logger.Debugf(ctx, "Resource unavailable at %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400686 return nil, err
687 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400688
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400689 Value, err = ToByte(Resource.Value)
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000690 if err != nil {
691 return nil, err
692 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400693
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400694 // decode resource fetched from backend store to dictionary
695 err = json.Unmarshal(Value, &Result)
696 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000697 logger.Error(ctx, "Failed to decode resource")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400698 return Result, err
699 }
700 /*
701 resource pool in backend store stored as binary string whereas to
702 access the pool to generate/release IDs it need to be converted
703 as BitArray
704 */
705 Str, err = ToString(Result[POOL])
706 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000707 logger.Error(ctx, "Failed to conver to kv pair to string")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400708 return Result, err
709 }
710 Decode64, _ := base64.StdEncoding.DecodeString(Str)
711 Result[POOL], err = ToByte(Decode64)
712 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000713 logger.Error(ctx, "Failed to convert resource pool to byte")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400714 return Result, err
715 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400716
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400717 return Result, err
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400718}
719
Neha Sharma96b7bf22020-06-15 10:37:32 +0000720func (PONRMgr *PONResourceManager) GetPath(ctx context.Context, IntfID uint32, ResourceType string) string {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400721 /*
722 Get path for given resource type.
723 :param pon_intf_id: OLT PON interface id
724 :param resource_type: String to identify type of resource
725 :return: path for given resource type
726 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400727
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400728 /*
729 Get the shared pool for the given resource type.
730 all the resource ranges and the shared resource maps are initialized during the init.
731 */
732 SharedPoolID := PONRMgr.PonResourceRanges[PONRMgr.SharedIdxByType[ResourceType]].(uint32)
733 if SharedPoolID != 0 {
734 IntfID = SharedPoolID
735 }
736 var Path string
737 if ResourceType == ONU_ID {
738 Path = fmt.Sprintf(ONU_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
739 } else if ResourceType == ALLOC_ID {
740 Path = fmt.Sprintf(ALLOC_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
741 } else if ResourceType == GEMPORT_ID {
742 Path = fmt.Sprintf(GEMPORT_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
743 } else if ResourceType == FLOW_ID {
744 Path = fmt.Sprintf(FLOW_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
745 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000746 logger.Error(ctx, "Invalid resource pool identifier")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400747 }
748 return Path
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400749}
750
npujarec5762e2020-01-01 14:08:48 +0530751func (PONRMgr *PONResourceManager) GetResourceID(ctx context.Context, IntfID uint32, ResourceType string, NumIDs uint32) ([]uint32, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400752 /*
753 Create alloc/gemport/onu/flow id for given OLT PON interface.
754 :param pon_intf_id: OLT PON interface id
755 :param resource_type: String to identify type of resource
756 :param num_of_id: required number of ids
757 :return list/uint32/None: list, uint32 or None if resource type is
758 alloc_id/gemport_id, onu_id or invalid type respectively
759 */
Matteo Scandolo84585372021-03-18 14:21:22 -0700760
761 logger.Debugw(ctx, "getting-resource-id", log.Fields{
762 "intf-id": IntfID,
763 "resource-type": ResourceType,
764 "num": NumIDs,
765 })
766
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400767 if NumIDs < 1 {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000768 logger.Error(ctx, "Invalid number of resources requested")
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000769 return nil, fmt.Errorf("Invalid number of resources requested %d", NumIDs)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400770 }
771 // delegate to the master instance if sharing enabled across instances
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400772
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400773 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
774 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujarec5762e2020-01-01 14:08:48 +0530775 return SharedResourceMgr.GetResourceID(ctx, IntfID, ResourceType, NumIDs)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400776 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000777 logger.Debugf(ctx, "Fetching resource from %s rsrc mgr for resource %s", PONRMgr.Globalorlocal, ResourceType)
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400778
Neha Sharma96b7bf22020-06-15 10:37:32 +0000779 Path := PONRMgr.GetPath(ctx, IntfID, ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400780 if Path == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000781 logger.Errorf(ctx, "Failed to get path for resource type %s", ResourceType)
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000782 return nil, fmt.Errorf("Failed to get path for resource type %s", ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400783 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000784 logger.Debugf(ctx, "Get resource for type %s on path %s", ResourceType, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400785 var Result []uint32
786 var NextID uint32
npujarec5762e2020-01-01 14:08:48 +0530787 Resource, err := PONRMgr.GetResource(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400788 if (err == nil) && (ResourceType == ONU_ID) || (ResourceType == FLOW_ID) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000789 if NextID, err = PONRMgr.GenerateNextID(ctx, Resource); err != nil {
790 logger.Error(ctx, "Failed to Generate ID")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400791 return Result, err
792 }
793 Result = append(Result, NextID)
794 } else if (err == nil) && ((ResourceType == GEMPORT_ID) || (ResourceType == ALLOC_ID)) {
795 if NumIDs == 1 {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000796 if NextID, err = PONRMgr.GenerateNextID(ctx, Resource); err != nil {
797 logger.Error(ctx, "Failed to Generate ID")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400798 return Result, err
799 }
800 Result = append(Result, NextID)
801 } else {
802 for NumIDs > 0 {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000803 if NextID, err = PONRMgr.GenerateNextID(ctx, Resource); err != nil {
804 logger.Error(ctx, "Failed to Generate ID")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400805 return Result, err
806 }
807 Result = append(Result, NextID)
808 NumIDs--
809 }
810 }
811 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000812 logger.Error(ctx, "get resource failed")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400813 return Result, err
814 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400815
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400816 //Update resource in kv store
npujarec5762e2020-01-01 14:08:48 +0530817 if PONRMgr.UpdateResource(ctx, Path, Resource) != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000818 logger.Errorf(ctx, "Failed to update resource %s", Path)
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000819 return nil, fmt.Errorf("Failed to update resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400820 }
821 return Result, nil
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400822}
823
824func checkValidResourceType(ResourceType string) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400825 KnownResourceTypes := []string{ONU_ID, ALLOC_ID, GEMPORT_ID, FLOW_ID}
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400826
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400827 for _, v := range KnownResourceTypes {
828 if v == ResourceType {
829 return true
830 }
831 }
832 return false
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400833}
834
Matteo Scandolo84585372021-03-18 14:21:22 -0700835func (PONRMgr *PONResourceManager) FreeResourceID(ctx context.Context, IntfID uint32, ResourceType string, ReleaseContent []uint32) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400836 /*
Matteo Scandolo84585372021-03-18 14:21:22 -0700837 Release alloc/gemport/onu/flow id for given OLT PON interface.
838 :param pon_intf_id: OLT PON interface id
839 :param resource_type: String to identify type of resource
840 :param release_content: required number of ids
841 :return boolean: True if all IDs in given release_content release else False
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400842 */
Matteo Scandolo84585372021-03-18 14:21:22 -0700843
844 logger.Debugw(ctx, "freeing-resource-id", log.Fields{
845 "intf-id": IntfID,
846 "resource-type": ResourceType,
847 "release-content": ReleaseContent,
848 })
849
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000850 if !checkValidResourceType(ResourceType) {
Matteo Scandolo84585372021-03-18 14:21:22 -0700851 err := fmt.Errorf("Invalid resource type: %s", ResourceType)
852 logger.Error(ctx, err.Error())
853 return err
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400854 }
855 if ReleaseContent == nil {
Matteo Scandolo84585372021-03-18 14:21:22 -0700856 err := fmt.Errorf("Nothing to release")
857 logger.Debug(ctx, err.Error())
858 return err
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400859 }
860 // delegate to the master instance if sharing enabled across instances
861 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
862 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujarec5762e2020-01-01 14:08:48 +0530863 return SharedResourceMgr.FreeResourceID(ctx, IntfID, ResourceType, ReleaseContent)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400864 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000865 Path := PONRMgr.GetPath(ctx, IntfID, ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400866 if Path == "" {
Matteo Scandolo84585372021-03-18 14:21:22 -0700867 err := fmt.Errorf("Failed to get path for IntfId %d and ResourceType %s", IntfID, ResourceType)
868 logger.Error(ctx, err.Error())
869 return err
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400870 }
npujarec5762e2020-01-01 14:08:48 +0530871 Resource, err := PONRMgr.GetResource(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400872 if err != nil {
Matteo Scandolo84585372021-03-18 14:21:22 -0700873 logger.Error(ctx, err.Error())
874 return err
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400875 }
876 for _, Val := range ReleaseContent {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000877 PONRMgr.ReleaseID(ctx, Resource, Val)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400878 }
npujarec5762e2020-01-01 14:08:48 +0530879 if PONRMgr.UpdateResource(ctx, Path, Resource) != nil {
Matteo Scandolo84585372021-03-18 14:21:22 -0700880 err := fmt.Errorf("Free resource for %s failed", Path)
881 logger.Errorf(ctx, err.Error())
882 return err
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400883 }
Matteo Scandolo84585372021-03-18 14:21:22 -0700884 return nil
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400885}
886
npujarec5762e2020-01-01 14:08:48 +0530887func (PONRMgr *PONResourceManager) UpdateResource(ctx context.Context, Path string, Resource map[string]interface{}) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400888 /*
889 Update resource in resource kv store.
890 :param path: path to update resource
891 :param resource: resource need to be updated
892 :return boolean: True if resource updated in kv store else False
893 */
894 // TODO resource[POOL] = resource[POOL].bin
895 Value, err := json.Marshal(Resource)
896 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000897 logger.Error(ctx, "failed to Marshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400898 return err
899 }
npujarec5762e2020-01-01 14:08:48 +0530900 err = PONRMgr.KVStore.Put(ctx, Path, Value)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400901 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000902 logger.Error(ctx, "failed to put data to kv store %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400903 return err
904 }
905 return nil
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400906}
907
npujarec5762e2020-01-01 14:08:48 +0530908func (PONRMgr *PONResourceManager) ClearResourceIDPool(ctx context.Context, contIntfID uint32, ResourceType string) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400909 /*
910 Clear Resource Pool for a given Resource Type on a given PON Port.
911 :return boolean: True if removed else False
912 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400913
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400914 // delegate to the master instance if sharing enabled across instances
915 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
916 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujarec5762e2020-01-01 14:08:48 +0530917 return SharedResourceMgr.ClearResourceIDPool(ctx, contIntfID, ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400918 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000919 Path := PONRMgr.GetPath(ctx, contIntfID, ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400920 if Path == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000921 logger.Error(ctx, "Failed to get path")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400922 return false
923 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400924
npujarec5762e2020-01-01 14:08:48 +0530925 if err := PONRMgr.KVStore.Delete(ctx, Path); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000926 logger.Errorf(ctx, "Failed to delete resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400927 return false
928 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000929 logger.Debugf(ctx, "Cleared resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400930 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400931}
932
npujarec5762e2020-01-01 14:08:48 +0530933func (PONRMgr PONResourceManager) InitResourceMap(ctx context.Context, PONIntfONUID string) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400934 /*
935 Initialize resource map
936 :param pon_intf_onu_id: reference of PON interface id and onu id
937 */
938 // initialize pon_intf_onu_id tuple to alloc_ids map
939 AllocIDPath := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
940 var AllocIDs []byte
npujarec5762e2020-01-01 14:08:48 +0530941 Result := PONRMgr.KVStore.Put(ctx, AllocIDPath, AllocIDs)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400942 if Result != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000943 logger.Error(ctx, "Failed to update the KV store")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400944 return
945 }
946 // initialize pon_intf_onu_id tuple to gemport_ids map
947 GEMPortIDPath := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
948 var GEMPortIDs []byte
npujarec5762e2020-01-01 14:08:48 +0530949 Result = PONRMgr.KVStore.Put(ctx, GEMPortIDPath, GEMPortIDs)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400950 if Result != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000951 logger.Error(ctx, "Failed to update the KV store")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400952 return
953 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400954}
955
npujarec5762e2020-01-01 14:08:48 +0530956func (PONRMgr PONResourceManager) RemoveResourceMap(ctx context.Context, PONIntfONUID string) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400957 /*
958 Remove resource map
959 :param pon_intf_onu_id: reference of PON interface id and onu id
960 */
961 // remove pon_intf_onu_id tuple to alloc_ids map
962 var err error
963 AllocIDPath := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujarec5762e2020-01-01 14:08:48 +0530964 if err = PONRMgr.KVStore.Delete(ctx, AllocIDPath); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000965 logger.Errorf(ctx, "Failed to remove resource %s", AllocIDPath)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400966 return false
967 }
968 // remove pon_intf_onu_id tuple to gemport_ids map
969 GEMPortIDPath := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujarec5762e2020-01-01 14:08:48 +0530970 err = PONRMgr.KVStore.Delete(ctx, GEMPortIDPath)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400971 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000972 logger.Errorf(ctx, "Failed to remove resource %s", GEMPortIDPath)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400973 return false
974 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400975
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400976 FlowIDPath := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujarec5762e2020-01-01 14:08:48 +0530977 if FlowIDs, err := PONRMgr.KVStore.List(ctx, FlowIDPath); err != nil {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400978 for _, Flow := range FlowIDs {
979 FlowIDInfoPath := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, PONIntfONUID, Flow.Value)
npujarec5762e2020-01-01 14:08:48 +0530980 if err = PONRMgr.KVStore.Delete(ctx, FlowIDInfoPath); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000981 logger.Errorf(ctx, "Failed to remove resource %s", FlowIDInfoPath)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400982 return false
983 }
984 }
985 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400986
npujarec5762e2020-01-01 14:08:48 +0530987 if err = PONRMgr.KVStore.Delete(ctx, FlowIDPath); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000988 logger.Errorf(ctx, "Failed to remove resource %s", FlowIDPath)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400989 return false
990 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400991
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400992 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400993}
994
npujarec5762e2020-01-01 14:08:48 +0530995func (PONRMgr *PONResourceManager) GetCurrentAllocIDForOnu(ctx context.Context, IntfONUID string) []uint32 {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400996 /*
997 Get currently configured alloc ids for given pon_intf_onu_id
998 :param pon_intf_onu_id: reference of PON interface id and onu id
999 :return list: List of alloc_ids if available, else None
1000 */
1001 Path := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001002
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001003 var Data []uint32
npujarec5762e2020-01-01 14:08:48 +05301004 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001005 if err == nil {
1006 if Value != nil {
1007 Val, err := ToByte(Value.Value)
1008 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001009 logger.Errorw(ctx, "Failed to convert into byte array", log.Fields{"error": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001010 return Data
1011 }
1012 if err = json.Unmarshal(Val, &Data); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001013 logger.Error(ctx, "Failed to unmarshal", log.Fields{"error": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001014 return Data
1015 }
1016 }
1017 }
1018 return Data
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001019}
1020
npujarec5762e2020-01-01 14:08:48 +05301021func (PONRMgr *PONResourceManager) GetCurrentGEMPortIDsForOnu(ctx context.Context, IntfONUID string) []uint32 {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001022 /*
1023 Get currently configured gemport ids for given pon_intf_onu_id
1024 :param pon_intf_onu_id: reference of PON interface id and onu id
1025 :return list: List of gemport IDs if available, else None
1026 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001027
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001028 Path := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001029 logger.Debugf(ctx, "Getting current gemports for %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001030 var Data []uint32
npujarec5762e2020-01-01 14:08:48 +05301031 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001032 if err == nil {
1033 if Value != nil {
1034 Val, _ := ToByte(Value.Value)
1035 if err = json.Unmarshal(Val, &Data); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001036 logger.Errorw(ctx, "Failed to unmarshal", log.Fields{"error": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001037 return Data
1038 }
1039 }
1040 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001041 logger.Errorf(ctx, "Failed to get data from kvstore for %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001042 }
1043 return Data
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001044}
1045
npujarec5762e2020-01-01 14:08:48 +05301046func (PONRMgr *PONResourceManager) GetCurrentFlowIDsForOnu(ctx context.Context, IntfONUID string) []uint32 {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001047 /*
1048 Get currently configured flow ids for given pon_intf_onu_id
1049 :param pon_intf_onu_id: reference of PON interface id and onu id
1050 :return list: List of Flow IDs if available, else None
1051 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001052
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001053 Path := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001054
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001055 var Data []uint32
npujarec5762e2020-01-01 14:08:48 +05301056 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001057 if err == nil {
1058 if Value != nil {
1059 Val, _ := ToByte(Value.Value)
1060 if err = json.Unmarshal(Val, &Data); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001061 logger.Error(ctx, "Failed to unmarshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001062 return Data
1063 }
1064 }
1065 }
1066 return Data
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001067}
1068
npujarec5762e2020-01-01 14:08:48 +05301069func (PONRMgr *PONResourceManager) GetFlowIDInfo(ctx context.Context, IntfONUID string, FlowID uint32, Data interface{}) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001070 /*
1071 Get flow details configured for the ONU.
1072 :param pon_intf_onu_id: reference of PON interface id and onu id
1073 :param flow_id: Flow Id reference
1074 :param Data: Result
1075 :return error: nil if no error in getting from KV store
1076 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001077
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001078 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001079
npujarec5762e2020-01-01 14:08:48 +05301080 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001081 if err == nil {
1082 if Value != nil {
1083 Val, err := ToByte(Value.Value)
1084 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001085 logger.Errorw(ctx, "Failed to convert flowinfo into byte array", log.Fields{"error": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001086 return err
1087 }
1088 if err = json.Unmarshal(Val, Data); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001089 logger.Errorw(ctx, "Failed to unmarshal", log.Fields{"error": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001090 return err
1091 }
1092 }
1093 }
1094 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001095}
1096
npujarec5762e2020-01-01 14:08:48 +05301097func (PONRMgr *PONResourceManager) RemoveFlowIDInfo(ctx context.Context, IntfONUID string, FlowID uint32) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001098 /*
1099 Get flow_id details configured for the ONU.
1100 :param pon_intf_onu_id: reference of PON interface id and onu id
1101 :param flow_id: Flow Id reference
1102 */
1103 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001104
npujarec5762e2020-01-01 14:08:48 +05301105 if err := PONRMgr.KVStore.Delete(ctx, Path); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001106 logger.Errorf(ctx, "Falied to remove resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001107 return false
1108 }
1109 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001110}
1111
serkant.uluderya7b8211e2021-02-24 16:39:18 +03001112func (PONRMgr *PONResourceManager) RemoveAllFlowIDInfo(ctx context.Context, IntfONUID string) bool {
1113 /*
1114 Remove flow_id_info details configured for the ONU.
1115 :param pon_intf_onu_id: reference of PON interface id and onu id
1116 */
1117 Path := fmt.Sprintf(FLOW_ID_INFO_PATH_INTF_ONU_PREFIX, PONRMgr.DeviceID, IntfONUID)
1118
1119 if err := PONRMgr.KVStore.DeleteWithPrefix(ctx, Path); err != nil {
1120 logger.Errorf(ctx, "Falied to remove resource %s", Path)
1121 return false
1122 }
1123 return true
1124}
1125
npujarec5762e2020-01-01 14:08:48 +05301126func (PONRMgr *PONResourceManager) UpdateAllocIdsForOnu(ctx context.Context, IntfONUID string, AllocIDs []uint32) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001127 /*
1128 Update currently configured alloc ids for given pon_intf_onu_id
1129 :param pon_intf_onu_id: reference of PON interface id and onu id
1130 :param alloc_ids: list of alloc ids
1131 */
1132 var Value []byte
1133 var err error
1134 Path := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
1135 Value, err = json.Marshal(AllocIDs)
1136 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001137 logger.Error(ctx, "failed to Marshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001138 return err
1139 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001140
npujarec5762e2020-01-01 14:08:48 +05301141 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001142 logger.Errorf(ctx, "Failed to update resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001143 return err
1144 }
1145 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001146}
1147
npujarec5762e2020-01-01 14:08:48 +05301148func (PONRMgr *PONResourceManager) UpdateGEMPortIDsForOnu(ctx context.Context, IntfONUID string, GEMPortIDs []uint32) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001149 /*
1150 Update currently configured gemport ids for given pon_intf_onu_id
1151 :param pon_intf_onu_id: reference of PON interface id and onu id
1152 :param gemport_ids: list of gem port ids
1153 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001154
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001155 var Value []byte
1156 var err error
1157 Path := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001158 logger.Debugf(ctx, "Updating gemport ids for %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001159 Value, err = json.Marshal(GEMPortIDs)
1160 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001161 logger.Error(ctx, "failed to Marshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001162 return err
1163 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001164
npujarec5762e2020-01-01 14:08:48 +05301165 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001166 logger.Errorf(ctx, "Failed to update resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001167 return err
1168 }
1169 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001170}
1171
1172func checkForFlowIDInList(FlowIDList []uint32, FlowID uint32) (bool, uint32) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001173 /*
1174 Check for a flow id in a given list of flow IDs.
1175 :param FLowIDList: List of Flow IDs
1176 :param FlowID: Flowd to check in the list
1177 : return true and the index if present false otherwise.
1178 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001179
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001180 for idx := range FlowIDList {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001181 if FlowID == FlowIDList[idx] {
1182 return true, uint32(idx)
1183 }
1184 }
1185 return false, 0
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001186}
1187
npujarec5762e2020-01-01 14:08:48 +05301188func (PONRMgr *PONResourceManager) UpdateFlowIDForOnu(ctx context.Context, IntfONUID string, FlowID uint32, Add bool) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001189 /*
1190 Update the flow_id list of the ONU (add or remove flow_id from the list)
1191 :param pon_intf_onu_id: reference of PON interface id and onu id
1192 :param flow_id: flow ID
1193 :param add: Boolean flag to indicate whether the flow_id should be
1194 added or removed from the list. Defaults to adding the flow.
1195 */
1196 var Value []byte
1197 var err error
1198 var RetVal bool
1199 var IDx uint32
1200 Path := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
npujarec5762e2020-01-01 14:08:48 +05301201 FlowIDs := PONRMgr.GetCurrentFlowIDsForOnu(ctx, IntfONUID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001202
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001203 if Add {
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001204 if RetVal, _ = checkForFlowIDInList(FlowIDs, FlowID); RetVal {
1205 return nil
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001206 }
1207 FlowIDs = append(FlowIDs, FlowID)
1208 } else {
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001209 if RetVal, IDx = checkForFlowIDInList(FlowIDs, FlowID); !RetVal {
1210 return nil
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001211 }
1212 // delete the index and shift
1213 FlowIDs = append(FlowIDs[:IDx], FlowIDs[IDx+1:]...)
1214 }
1215 Value, err = json.Marshal(FlowIDs)
1216 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001217 logger.Error(ctx, "Failed to Marshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001218 return err
1219 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001220
npujarec5762e2020-01-01 14:08:48 +05301221 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001222 logger.Errorf(ctx, "Failed to update resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001223 return err
1224 }
1225 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001226}
1227
npujarec5762e2020-01-01 14:08:48 +05301228func (PONRMgr *PONResourceManager) UpdateFlowIDInfoForOnu(ctx context.Context, IntfONUID string, FlowID uint32, FlowData interface{}) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001229 /*
1230 Update any metadata associated with the flow_id. The flow_data could be json
1231 or any of other data structure. The resource manager doesnt care
1232 :param pon_intf_onu_id: reference of PON interface id and onu id
1233 :param flow_id: Flow ID
1234 :param flow_data: Flow data blob
1235 */
1236 var Value []byte
1237 var err error
1238 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
1239 Value, err = json.Marshal(FlowData)
1240 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001241 logger.Error(ctx, "failed to Marshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001242 return err
1243 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001244
npujarec5762e2020-01-01 14:08:48 +05301245 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001246 logger.Errorf(ctx, "Failed to update resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001247 return err
1248 }
1249 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001250}
1251
Neha Sharma96b7bf22020-06-15 10:37:32 +00001252func (PONRMgr *PONResourceManager) GenerateNextID(ctx context.Context, Resource map[string]interface{}) (uint32, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001253 /*
1254 Generate unique id having OFFSET as start
1255 :param resource: resource used to generate ID
1256 :return uint32: generated id
1257 */
1258 ByteArray, err := ToByte(Resource[POOL])
1259 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001260 logger.Error(ctx, "Failed to convert resource to byte array")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001261 return 0, err
1262 }
1263 Data := bitmap.TSFromData(ByteArray, false)
1264 if Data == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001265 logger.Error(ctx, "Failed to get data from byte array")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001266 return 0, errors.New("Failed to get data from byte array")
1267 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001268
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001269 Len := Data.Len()
1270 var Idx int
1271 for Idx = 0; Idx < Len; Idx++ {
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001272 if !Data.Get(Idx) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001273 break
1274 }
1275 }
1276 Data.Set(Idx, true)
1277 res := uint32(Resource[START_IDX].(float64))
1278 Resource[POOL] = Data.Data(false)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001279 logger.Debugf(ctx, "Generated ID for %d", (uint32(Idx) + res))
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001280 return (uint32(Idx) + res), err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001281}
1282
Neha Sharma96b7bf22020-06-15 10:37:32 +00001283func (PONRMgr *PONResourceManager) ReleaseID(ctx context.Context, Resource map[string]interface{}, Id uint32) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001284 /*
1285 Release unique id having OFFSET as start index.
1286 :param resource: resource used to release ID
1287 :param unique_id: id need to be released
1288 */
1289 ByteArray, err := ToByte(Resource[POOL])
1290 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001291 logger.Error(ctx, "Failed to convert resource to byte array")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001292 return false
1293 }
1294 Data := bitmap.TSFromData(ByteArray, false)
1295 if Data == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001296 logger.Error(ctx, "Failed to get resource pool")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001297 return false
1298 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001299 Idx := Id - uint32(Resource[START_IDX].(float64))
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001300 Data.Set(int(Idx), false)
1301 Resource[POOL] = Data.Data(false)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001302
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001303 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001304}
1305
divyadesaid26f6b12020-03-19 06:30:28 +00001306/* Reserves a unique id in the specified resource pool.
1307:param Resource: resource used to reserve ID
1308:param Id: ID to be reserved
1309*/
Neha Sharma96b7bf22020-06-15 10:37:32 +00001310func (PONRMgr *PONResourceManager) reserveID(ctx context.Context, TSData *bitmap.Threadsafe, StartIndex uint32, Id uint32) bool {
divyadesaid26f6b12020-03-19 06:30:28 +00001311 Data := bitmap.TSFromData(TSData.Data(false), false)
1312 if Data == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001313 logger.Error(ctx, "Failed to get resource pool")
divyadesaid26f6b12020-03-19 06:30:28 +00001314 return false
1315 }
1316 Idx := Id - StartIndex
1317 Data.Set(int(Idx), true)
1318 return true
1319}
1320
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001321func (PONRMgr *PONResourceManager) GetTechnology() string {
1322 return PONRMgr.Technology
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001323}
1324
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001325func (PONRMgr *PONResourceManager) GetResourceTypeAllocID() string {
1326 return ALLOC_ID
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001327}
1328
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001329func (PONRMgr *PONResourceManager) GetResourceTypeGemPortID() string {
1330 return GEMPORT_ID
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001331}
1332
Matteo Scandolo84585372021-03-18 14:21:22 -07001333func (PONRMgr *PONResourceManager) GetResourceTypeOnuID() string {
1334 return ONU_ID
1335}
1336
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001337// ToByte converts an interface value to a []byte. The interface should either be of
1338// a string type or []byte. Otherwise, an error is returned.
1339func ToByte(value interface{}) ([]byte, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001340 switch t := value.(type) {
1341 case []byte:
1342 return value.([]byte), nil
1343 case string:
1344 return []byte(value.(string)), nil
1345 default:
1346 return nil, fmt.Errorf("unexpected-type-%T", t)
1347 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001348}
1349
1350// ToString converts an interface value to a string. The interface should either be of
1351// a string type or []byte. Otherwise, an error is returned.
1352func ToString(value interface{}) (string, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001353 switch t := value.(type) {
1354 case []byte:
1355 return string(value.([]byte)), nil
1356 case string:
1357 return value.(string), nil
1358 default:
1359 return "", fmt.Errorf("unexpected-type-%T", t)
1360 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001361}