blob: 70ed8e66297ab7f831f4260be523fa4267506327 [file] [log] [blame]
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001/*
2 * Copyright 2019-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package ponresourcemanager
18
19import (
npujarec5762e2020-01-01 14:08:48 +053020 "context"
Matt Jeanneret384d8c92019-05-06 14:27:31 -040021 "encoding/base64"
22 "encoding/json"
23 "errors"
24 "fmt"
Neha Sharmacc656962020-04-14 14:26:11 +000025 "time"
Matt Jeanneretcab955f2019-04-10 15:45:57 -040026
Esin Karamanccb714b2019-11-29 15:02:06 +000027 bitmap "github.com/boljen/go-bitmap"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070028 "github.com/opencord/voltha-lib-go/v4/pkg/db"
29 "github.com/opencord/voltha-lib-go/v4/pkg/db/kvstore"
30 "github.com/opencord/voltha-lib-go/v4/pkg/log"
31 tp "github.com/opencord/voltha-lib-go/v4/pkg/techprofile"
Matt Jeanneretcab955f2019-04-10 15:45:57 -040032)
33
34const (
Matt Jeanneret384d8c92019-05-06 14:27:31 -040035 //Constants to identify resource pool
36 UNI_ID = "UNI_ID"
37 ONU_ID = "ONU_ID"
38 ALLOC_ID = "ALLOC_ID"
39 GEMPORT_ID = "GEMPORT_ID"
40 FLOW_ID = "FLOW_ID"
Matt Jeanneretcab955f2019-04-10 15:45:57 -040041
Matt Jeanneret384d8c92019-05-06 14:27:31 -040042 //Constants for passing command line arugments
43 OLT_MODEL_ARG = "--olt_model"
Matteo Scandolodfa7a972020-11-06 13:03:40 -080044
45 PATH_PREFIX = "%s/resource_manager/{%s}"
divyadesaid26f6b12020-03-19 06:30:28 +000046
47 /*The path under which configuration data is stored is defined as technology/device agnostic.
48 That means the path does not include any specific technology/device variable. Using technology/device
49 agnostic path also makes northbound applications, that need to write to this path,
50 technology/device agnostic.
51
52 Default kv client of PonResourceManager reads from/writes to PATH_PREFIX defined above.
53 That is why, an additional kv client (named KVStoreForConfig) is defined to read from the config path.
54 */
Matteo Scandolodfa7a972020-11-06 13:03:40 -080055
56 PATH_PREFIX_FOR_CONFIG = "%s/resource_manager/config"
Matt Jeanneret384d8c92019-05-06 14:27:31 -040057 /*The resource ranges for a given device model should be placed
58 at 'resource_manager/<technology>/resource_ranges/<olt_model_type>'
59 path on the KV store.
60 If Resource Range parameters are to be read from the external KV store,
61 they are expected to be stored in the following format.
62 Note: All parameters are MANDATORY for now.
63 constants used as keys to reference the resource range parameters from
64 and external KV store.
65 */
66 UNI_ID_START_IDX = "uni_id_start"
67 UNI_ID_END_IDX = "uni_id_end"
68 ONU_ID_START_IDX = "onu_id_start"
69 ONU_ID_END_IDX = "onu_id_end"
70 ONU_ID_SHARED_IDX = "onu_id_shared"
71 ALLOC_ID_START_IDX = "alloc_id_start"
72 ALLOC_ID_END_IDX = "alloc_id_end"
73 ALLOC_ID_SHARED_IDX = "alloc_id_shared"
74 GEMPORT_ID_START_IDX = "gemport_id_start"
75 GEMPORT_ID_END_IDX = "gemport_id_end"
76 GEMPORT_ID_SHARED_IDX = "gemport_id_shared"
77 FLOW_ID_START_IDX = "flow_id_start"
78 FLOW_ID_END_IDX = "flow_id_end"
79 FLOW_ID_SHARED_IDX = "flow_id_shared"
80 NUM_OF_PON_PORT = "pon_ports"
Matt Jeanneretcab955f2019-04-10 15:45:57 -040081
Matt Jeanneret384d8c92019-05-06 14:27:31 -040082 /*
83 The KV store backend is initialized with a path prefix and we need to
84 provide only the suffix.
85 */
86 PON_RESOURCE_RANGE_CONFIG_PATH = "resource_ranges/%s"
Matt Jeanneretcab955f2019-04-10 15:45:57 -040087
Matt Jeanneret384d8c92019-05-06 14:27:31 -040088 //resource path suffix
89 //Path on the KV store for storing alloc id ranges and resource pool for a given interface
90 //Format: <device_id>/alloc_id_pool/<pon_intf_id>
91 ALLOC_ID_POOL_PATH = "{%s}/alloc_id_pool/{%d}"
92 //Path on the KV store for storing gemport id ranges and resource pool for a given interface
93 //Format: <device_id>/gemport_id_pool/<pon_intf_id>
94 GEMPORT_ID_POOL_PATH = "{%s}/gemport_id_pool/{%d}"
95 //Path on the KV store for storing onu id ranges and resource pool for a given interface
96 //Format: <device_id>/onu_id_pool/<pon_intf_id>
97 ONU_ID_POOL_PATH = "{%s}/onu_id_pool/{%d}"
98 //Path on the KV store for storing flow id ranges and resource pool for a given interface
99 //Format: <device_id>/flow_id_pool/<pon_intf_id>
100 FLOW_ID_POOL_PATH = "{%s}/flow_id_pool/{%d}"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400101
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400102 //Path on the KV store for storing list of alloc IDs for a given ONU
103 //Format: <device_id>/<(pon_intf_id, onu_id)>/alloc_ids
104 ALLOC_ID_RESOURCE_MAP_PATH = "{%s}/{%s}/alloc_ids"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400105
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400106 //Path on the KV store for storing list of gemport IDs for a given ONU
107 //Format: <device_id>/<(pon_intf_id, onu_id)>/gemport_ids
108 GEMPORT_ID_RESOURCE_MAP_PATH = "{%s}/{%s}/gemport_ids"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400109
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400110 //Path on the KV store for storing list of Flow IDs for a given ONU
111 //Format: <device_id>/<(pon_intf_id, onu_id)>/flow_ids
112 FLOW_ID_RESOURCE_MAP_PATH = "{%s}/{%s}/flow_ids"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400113
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400114 //Flow Id info: Use to store more metadata associated with the flow_id
serkant.uluderya7b8211e2021-02-24 16:39:18 +0300115 FLOW_ID_INFO_PATH_PREFIX = "{%s}/flow_id_info"
116 //Format: <device_id>/flow_id_info/<(pon_intf_id, onu_id)>
117 FLOW_ID_INFO_PATH_INTF_ONU_PREFIX = "{%s}/flow_id_info/{%s}"
118 //Format: <device_id>/flow_id_info/<(pon_intf_id, onu_id)><flow_id>
119 FLOW_ID_INFO_PATH = FLOW_ID_INFO_PATH_PREFIX + "/{%s}/{%d}"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400120
Scott Bakerc6e54cb2019-11-04 09:31:25 -0800121 //path on the kvstore to store onugem info map
122 //format: <device-id>/onu_gem_info/<intfid>
123 ONU_GEM_INFO_PATH = "{%s}/onu_gem_info/{%d}" // onu_gem/<(intfid)>
124
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400125 //Constants for internal usage.
126 PON_INTF_ID = "pon_intf_id"
127 START_IDX = "start_idx"
128 END_IDX = "end_idx"
129 POOL = "pool"
130 NUM_OF_PON_INTF = 16
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400131
Neha Sharmacc656962020-04-14 14:26:11 +0000132 KVSTORE_RETRY_TIMEOUT = 5 * time.Second
divyadesaid26f6b12020-03-19 06:30:28 +0000133 //Path on the KV store for storing reserved gem ports
134 //Format: reserved_gemport_ids
135 RESERVED_GEMPORT_IDS_PATH = "reserved_gemport_ids"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400136)
137
138//type ResourceTypeIndex string
139//type ResourceType string
140
141type PONResourceManager struct {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400142 //Implements APIs to initialize/allocate/release alloc/gemport/onu IDs.
divyadesaid26f6b12020-03-19 06:30:28 +0000143 Technology string
144 DeviceType string
145 DeviceID string
serkant.uluderya7b8211e2021-02-24 16:39:18 +0300146 Backend string // ETCD only currently
Neha Sharma3f221ae2020-04-29 19:02:12 +0000147 Address string // address of the KV store
divyadesaid26f6b12020-03-19 06:30:28 +0000148 OLTModel string
149 KVStore *db.Backend
150 KVStoreForConfig *db.Backend
151 TechProfileMgr tp.TechProfileIf // create object of *tp.TechProfileMgr
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400152
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400153 // Below attribute, pon_resource_ranges, should be initialized
154 // by reading from KV store.
155 PonResourceRanges map[string]interface{}
156 SharedResourceMgrs map[string]*PONResourceManager
157 SharedIdxByType map[string]string
158 IntfIDs []uint32 // list of pon interface IDs
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400159 Globalorlocal string
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400160}
161
Neha Sharma96b7bf22020-06-15 10:37:32 +0000162func newKVClient(ctx context.Context, storeType string, address string, timeout time.Duration) (kvstore.Client, error) {
163 logger.Infow(ctx, "kv-store-type", log.Fields{"store": storeType})
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400164 switch storeType {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400165 case "etcd":
Neha Sharma96b7bf22020-06-15 10:37:32 +0000166 return kvstore.NewEtcdClient(ctx, address, timeout, log.WarnLevel)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400167 }
168 return nil, errors.New("unsupported-kv-store")
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400169}
170
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800171func SetKVClient(ctx context.Context, Technology string, Backend string, Addr string, configClient bool, basePathKvStore string) *db.Backend {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400172 // TODO : Make sure direct call to NewBackend is working fine with backend , currently there is some
173 // issue between kv store and backend , core is not calling NewBackend directly
Neha Sharma96b7bf22020-06-15 10:37:32 +0000174 kvClient, err := newKVClient(ctx, Backend, Addr, KVSTORE_RETRY_TIMEOUT)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400175 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000176 logger.Fatalw(ctx, "Failed to init KV client\n", log.Fields{"err": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400177 return nil
178 }
divyadesaid26f6b12020-03-19 06:30:28 +0000179
180 var pathPrefix string
181 if configClient {
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800182 pathPrefix = fmt.Sprintf(PATH_PREFIX_FOR_CONFIG, basePathKvStore)
divyadesaid26f6b12020-03-19 06:30:28 +0000183 } else {
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800184 pathPrefix = fmt.Sprintf(PATH_PREFIX, basePathKvStore, Technology)
divyadesaid26f6b12020-03-19 06:30:28 +0000185 }
186
sbarbaria8910ba2019-11-05 10:12:23 -0500187 kvbackend := &db.Backend{
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400188 Client: kvClient,
189 StoreType: Backend,
Neha Sharma3f221ae2020-04-29 19:02:12 +0000190 Address: Addr,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400191 Timeout: KVSTORE_RETRY_TIMEOUT,
divyadesaid26f6b12020-03-19 06:30:28 +0000192 PathPrefix: pathPrefix}
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400193
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400194 return kvbackend
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400195}
196
197// NewPONResourceManager creates a new PON resource manager.
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800198func 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 -0400199 var PONMgr PONResourceManager
200 PONMgr.Technology = Technology
201 PONMgr.DeviceType = DeviceType
202 PONMgr.DeviceID = DeviceID
203 PONMgr.Backend = Backend
Neha Sharma3f221ae2020-04-29 19:02:12 +0000204 PONMgr.Address = Address
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800205 PONMgr.KVStore = SetKVClient(ctx, Technology, Backend, Address, false, basePathKvStore)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400206 if PONMgr.KVStore == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000207 logger.Error(ctx, "KV Client initilization failed")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400208 return nil, errors.New("Failed to init KV client")
209 }
divyadesaid26f6b12020-03-19 06:30:28 +0000210 // init kv client to read from the config path
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800211 PONMgr.KVStoreForConfig = SetKVClient(ctx, Technology, Backend, Address, true, basePathKvStore)
divyadesaid26f6b12020-03-19 06:30:28 +0000212 if PONMgr.KVStoreForConfig == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000213 logger.Error(ctx, "KV Config Client initilization failed")
divyadesaid26f6b12020-03-19 06:30:28 +0000214 return nil, errors.New("Failed to init KV Config client")
215 }
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400216 // Initialize techprofile for this technology
Matteo Scandoloc858ab72020-11-16 12:44:51 -0800217 if PONMgr.TechProfileMgr, _ = tp.NewTechProfile(ctx, &PONMgr, Backend, Address, basePathKvStore); PONMgr.TechProfileMgr == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000218 logger.Error(ctx, "Techprofile initialization failed")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400219 return nil, errors.New("Failed to init tech profile")
220 }
221 PONMgr.PonResourceRanges = make(map[string]interface{})
222 PONMgr.SharedResourceMgrs = make(map[string]*PONResourceManager)
223 PONMgr.SharedIdxByType = make(map[string]string)
224 PONMgr.SharedIdxByType[ONU_ID] = ONU_ID_SHARED_IDX
225 PONMgr.SharedIdxByType[ALLOC_ID] = ALLOC_ID_SHARED_IDX
226 PONMgr.SharedIdxByType[GEMPORT_ID] = GEMPORT_ID_SHARED_IDX
227 PONMgr.SharedIdxByType[FLOW_ID] = FLOW_ID_SHARED_IDX
228 PONMgr.IntfIDs = make([]uint32, NUM_OF_PON_INTF)
229 PONMgr.OLTModel = DeviceType
230 return &PONMgr, nil
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400231}
232
233/*
234 Initialize PON resource ranges with config fetched from kv store.
235 return boolean: True if PON resource ranges initialized else false
236 Try to initialize the PON Resource Ranges from KV store based on the
237 OLT model key, if available
238*/
239
npujarec5762e2020-01-01 14:08:48 +0530240func (PONRMgr *PONResourceManager) InitResourceRangesFromKVStore(ctx context.Context) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400241 //Initialize PON resource ranges with config fetched from kv store.
242 //:return boolean: True if PON resource ranges initialized else false
243 // Try to initialize the PON Resource Ranges from KV store based on the
244 // OLT model key, if available
245 if PONRMgr.OLTModel == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000246 logger.Error(ctx, "Failed to get OLT model")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400247 return false
248 }
249 Path := fmt.Sprintf(PON_RESOURCE_RANGE_CONFIG_PATH, PONRMgr.OLTModel)
250 //get resource from kv store
npujarec5762e2020-01-01 14:08:48 +0530251 Result, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400252 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000253 logger.Debugf(ctx, "Error in fetching resource %s from KV strore", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400254 return false
255 }
256 if Result == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000257 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 -0400258 return false
259 }
260 //update internal ranges from kv ranges. If there are missing
261 // values in the KV profile, continue to use the defaults
262 Value, err := ToByte(Result.Value)
263 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000264 logger.Error(ctx, "Failed to convert kvpair to byte string")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400265 return false
266 }
267 if err := json.Unmarshal(Value, &PONRMgr.PonResourceRanges); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000268 logger.Error(ctx, "Failed to Unmarshal json byte")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400269 return false
270 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000271 logger.Debug(ctx, "Init resource ranges from kvstore success")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400272 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400273}
274
Neha Sharma96b7bf22020-06-15 10:37:32 +0000275func (PONRMgr *PONResourceManager) UpdateRanges(ctx context.Context, StartIDx string, StartID uint32, EndIDx string, EndID uint32,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400276 SharedIDx string, SharedPoolID uint32, RMgr *PONResourceManager) {
277 /*
278 Update the ranges for all reosurce type in the intermnal maps
279 param: resource type start index
280 param: start ID
281 param: resource type end index
282 param: end ID
283 param: resource type shared index
284 param: shared pool id
285 param: global resource manager
286 */
Neha Sharma96b7bf22020-06-15 10:37:32 +0000287 logger.Debugf(ctx, "update ranges for %s, %d", StartIDx, StartID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400288
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400289 if StartID != 0 {
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400290 if (PONRMgr.PonResourceRanges[StartIDx] == nil) || (PONRMgr.PonResourceRanges[StartIDx].(uint32) < StartID) {
291 PONRMgr.PonResourceRanges[StartIDx] = StartID
292 }
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400293 }
294 if EndID != 0 {
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400295 if (PONRMgr.PonResourceRanges[EndIDx] == nil) || (PONRMgr.PonResourceRanges[EndIDx].(uint32) > EndID) {
296 PONRMgr.PonResourceRanges[EndIDx] = EndID
297 }
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400298 }
299 //if SharedPoolID != 0 {
300 PONRMgr.PonResourceRanges[SharedIDx] = SharedPoolID
301 //}
302 if RMgr != nil {
303 PONRMgr.SharedResourceMgrs[SharedIDx] = RMgr
304 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400305}
306
Neha Sharma96b7bf22020-06-15 10:37:32 +0000307func (PONRMgr *PONResourceManager) InitDefaultPONResourceRanges(ctx context.Context,
308 ONUIDStart uint32,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400309 ONUIDEnd uint32,
310 ONUIDSharedPoolID uint32,
311 AllocIDStart uint32,
312 AllocIDEnd uint32,
313 AllocIDSharedPoolID uint32,
314 GEMPortIDStart uint32,
315 GEMPortIDEnd uint32,
316 GEMPortIDSharedPoolID uint32,
317 FlowIDStart uint32,
318 FlowIDEnd uint32,
319 FlowIDSharedPoolID uint32,
320 UNIIDStart uint32,
321 UNIIDEnd uint32,
322 NoOfPONPorts uint32,
323 IntfIDs []uint32) bool {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400324
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400325 /*Initialize default PON resource ranges
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400326
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400327 :param onu_id_start_idx: onu id start index
328 :param onu_id_end_idx: onu id end index
329 :param onu_id_shared_pool_id: pool idx for id shared by all intfs or None for no sharing
330 :param alloc_id_start_idx: alloc id start index
331 :param alloc_id_end_idx: alloc id end index
332 :param alloc_id_shared_pool_id: pool idx for alloc id shared by all intfs or None for no sharing
333 :param gemport_id_start_idx: gemport id start index
334 :param gemport_id_end_idx: gemport id end index
335 :param gemport_id_shared_pool_id: pool idx for gemport id shared by all intfs or None for no sharing
336 :param flow_id_start_idx: flow id start index
337 :param flow_id_end_idx: flow id end index
338 :param flow_id_shared_pool_id: pool idx for flow id shared by all intfs or None for no sharing
339 :param num_of_pon_ports: number of PON ports
340 :param intf_ids: interfaces serviced by this manager
341 */
Neha Sharma96b7bf22020-06-15 10:37:32 +0000342 PONRMgr.UpdateRanges(ctx, ONU_ID_START_IDX, ONUIDStart, ONU_ID_END_IDX, ONUIDEnd, ONU_ID_SHARED_IDX, ONUIDSharedPoolID, nil)
343 PONRMgr.UpdateRanges(ctx, ALLOC_ID_START_IDX, AllocIDStart, ALLOC_ID_END_IDX, AllocIDEnd, ALLOC_ID_SHARED_IDX, AllocIDSharedPoolID, nil)
344 PONRMgr.UpdateRanges(ctx, GEMPORT_ID_START_IDX, GEMPortIDStart, GEMPORT_ID_END_IDX, GEMPortIDEnd, GEMPORT_ID_SHARED_IDX, GEMPortIDSharedPoolID, nil)
345 PONRMgr.UpdateRanges(ctx, FLOW_ID_START_IDX, FlowIDStart, FLOW_ID_END_IDX, FlowIDEnd, FLOW_ID_SHARED_IDX, FlowIDSharedPoolID, nil)
346 PONRMgr.UpdateRanges(ctx, UNI_ID_START_IDX, UNIIDStart, UNI_ID_END_IDX, UNIIDEnd, "", 0, nil)
347 logger.Debug(ctx, "Initialize default range values")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400348 var i uint32
349 if IntfIDs == nil {
350 for i = 0; i < NoOfPONPorts; i++ {
351 PONRMgr.IntfIDs = append(PONRMgr.IntfIDs, i)
352 }
353 } else {
354 PONRMgr.IntfIDs = IntfIDs
355 }
356 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400357}
358
npujarec5762e2020-01-01 14:08:48 +0530359func (PONRMgr *PONResourceManager) InitDeviceResourcePool(ctx context.Context) error {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400360
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400361 //Initialize resource pool for all PON ports.
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400362
Neha Sharma96b7bf22020-06-15 10:37:32 +0000363 logger.Debug(ctx, "Init resource ranges")
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400364
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400365 var err error
366 for _, Intf := range PONRMgr.IntfIDs {
367 SharedPoolID := PONRMgr.PonResourceRanges[ONU_ID_SHARED_IDX].(uint32)
368 if SharedPoolID != 0 {
369 Intf = SharedPoolID
370 }
npujarec5762e2020-01-01 14:08:48 +0530371 if err = PONRMgr.InitResourceIDPool(ctx, Intf, ONU_ID,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400372 PONRMgr.PonResourceRanges[ONU_ID_START_IDX].(uint32),
373 PONRMgr.PonResourceRanges[ONU_ID_END_IDX].(uint32)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000374 logger.Error(ctx, "Failed to init ONU ID resource pool")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400375 return err
376 }
377 if SharedPoolID != 0 {
378 break
379 }
380 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400381
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400382 for _, Intf := range PONRMgr.IntfIDs {
383 SharedPoolID := PONRMgr.PonResourceRanges[ALLOC_ID_SHARED_IDX].(uint32)
384 if SharedPoolID != 0 {
385 Intf = SharedPoolID
386 }
npujarec5762e2020-01-01 14:08:48 +0530387 if err = PONRMgr.InitResourceIDPool(ctx, Intf, ALLOC_ID,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400388 PONRMgr.PonResourceRanges[ALLOC_ID_START_IDX].(uint32),
389 PONRMgr.PonResourceRanges[ALLOC_ID_END_IDX].(uint32)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000390 logger.Error(ctx, "Failed to init ALLOC ID resource pool ")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400391 return err
392 }
393 if SharedPoolID != 0 {
394 break
395 }
396 }
397 for _, Intf := range PONRMgr.IntfIDs {
398 SharedPoolID := PONRMgr.PonResourceRanges[GEMPORT_ID_SHARED_IDX].(uint32)
399 if SharedPoolID != 0 {
400 Intf = SharedPoolID
401 }
npujarec5762e2020-01-01 14:08:48 +0530402 if err = PONRMgr.InitResourceIDPool(ctx, Intf, GEMPORT_ID,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400403 PONRMgr.PonResourceRanges[GEMPORT_ID_START_IDX].(uint32),
404 PONRMgr.PonResourceRanges[GEMPORT_ID_END_IDX].(uint32)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000405 logger.Error(ctx, "Failed to init GEMPORT ID resource pool")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400406 return err
407 }
408 if SharedPoolID != 0 {
409 break
410 }
411 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400412
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400413 for _, Intf := range PONRMgr.IntfIDs {
414 SharedPoolID := PONRMgr.PonResourceRanges[FLOW_ID_SHARED_IDX].(uint32)
415 if SharedPoolID != 0 {
416 Intf = SharedPoolID
417 }
npujarec5762e2020-01-01 14:08:48 +0530418 if err = PONRMgr.InitResourceIDPool(ctx, Intf, FLOW_ID,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400419 PONRMgr.PonResourceRanges[FLOW_ID_START_IDX].(uint32),
420 PONRMgr.PonResourceRanges[FLOW_ID_END_IDX].(uint32)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000421 logger.Error(ctx, "Failed to init FLOW ID resource pool")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400422 return err
423 }
424 if SharedPoolID != 0 {
425 break
426 }
427 }
428 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400429}
430
npujarec5762e2020-01-01 14:08:48 +0530431func (PONRMgr *PONResourceManager) ClearDeviceResourcePool(ctx context.Context) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -0400432
433 //Clear resource pool for all PON ports.
434
Neha Sharma96b7bf22020-06-15 10:37:32 +0000435 logger.Debug(ctx, "Clear resource ranges")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400436
437 for _, Intf := range PONRMgr.IntfIDs {
438 SharedPoolID := PONRMgr.PonResourceRanges[ONU_ID_SHARED_IDX].(uint32)
439 if SharedPoolID != 0 {
440 Intf = SharedPoolID
441 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000442 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, ONU_ID); !status {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000443 logger.Error(ctx, "Failed to clear ONU ID resource pool")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400444 return errors.New("Failed to clear ONU ID resource pool")
445 }
446 if SharedPoolID != 0 {
447 break
448 }
449 }
450
451 for _, Intf := range PONRMgr.IntfIDs {
452 SharedPoolID := PONRMgr.PonResourceRanges[ALLOC_ID_SHARED_IDX].(uint32)
453 if SharedPoolID != 0 {
454 Intf = SharedPoolID
455 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000456 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, ALLOC_ID); !status {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000457 logger.Error(ctx, "Failed to clear ALLOC ID resource pool ")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400458 return errors.New("Failed to clear ALLOC ID resource pool")
459 }
460 if SharedPoolID != 0 {
461 break
462 }
463 }
464 for _, Intf := range PONRMgr.IntfIDs {
465 SharedPoolID := PONRMgr.PonResourceRanges[GEMPORT_ID_SHARED_IDX].(uint32)
466 if SharedPoolID != 0 {
467 Intf = SharedPoolID
468 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000469 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, GEMPORT_ID); !status {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000470 logger.Error(ctx, "Failed to clear GEMPORT ID resource pool")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400471 return errors.New("Failed to clear GEMPORT ID resource pool")
472 }
473 if SharedPoolID != 0 {
474 break
475 }
476 }
477
478 for _, Intf := range PONRMgr.IntfIDs {
479 SharedPoolID := PONRMgr.PonResourceRanges[FLOW_ID_SHARED_IDX].(uint32)
480 if SharedPoolID != 0 {
481 Intf = SharedPoolID
482 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000483 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, FLOW_ID); !status {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000484 logger.Error(ctx, "Failed to clear FLOW ID resource pool")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400485 return errors.New("Failed to clear FLOW ID resource pool")
486 }
487 if SharedPoolID != 0 {
488 break
489 }
490 }
491 return nil
492}
493
npujarec5762e2020-01-01 14:08:48 +0530494func (PONRMgr *PONResourceManager) InitResourceIDPool(ctx context.Context, Intf uint32, ResourceType string, StartID uint32, EndID uint32) error {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400495
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400496 /*Initialize Resource ID pool for a given Resource Type on a given PON Port
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400497
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400498 :param pon_intf_id: OLT PON interface id
499 :param resource_type: String to identify type of resource
500 :param start_idx: start index for onu id pool
501 :param end_idx: end index for onu id pool
502 :return boolean: True if resource id pool initialized else false
503 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400504
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400505 // delegate to the master instance if sharing enabled across instances
506 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
507 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujarec5762e2020-01-01 14:08:48 +0530508 return SharedResourceMgr.InitResourceIDPool(ctx, Intf, ResourceType, StartID, EndID)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400509 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400510
Neha Sharma96b7bf22020-06-15 10:37:32 +0000511 Path := PONRMgr.GetPath(ctx, Intf, ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400512 if Path == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000513 logger.Errorf(ctx, "Failed to get path for resource type %s", ResourceType)
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000514 return fmt.Errorf("Failed to get path for resource type %s", ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400515 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400516
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400517 //In case of adapter reboot and reconciliation resource in kv store
518 //checked for its presence if not kv store update happens
npujarec5762e2020-01-01 14:08:48 +0530519 Res, err := PONRMgr.GetResource(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400520 if (err == nil) && (Res != nil) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000521 logger.Debugf(ctx, "Resource %s already present in store ", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400522 return nil
523 } else {
divyadesaid26f6b12020-03-19 06:30:28 +0000524 var excluded []uint32
525 if ResourceType == GEMPORT_ID {
526 //get gem port ids defined in the KV store, if any, and exclude them from the gem port id pool
527 if reservedGemPortIds, defined := PONRMgr.getReservedGemPortIdsFromKVStore(ctx); defined {
528 excluded = reservedGemPortIds
Neha Sharma96b7bf22020-06-15 10:37:32 +0000529 logger.Debugw(ctx, "Excluding some ports from GEM port id pool", log.Fields{"excluded gem ports": excluded})
divyadesaid26f6b12020-03-19 06:30:28 +0000530 }
531 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000532 FormatResult, err := PONRMgr.FormatResource(ctx, Intf, StartID, EndID, excluded)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400533 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000534 logger.Errorf(ctx, "Failed to format resource")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400535 return err
536 }
537 // Add resource as json in kv store.
npujarec5762e2020-01-01 14:08:48 +0530538 err = PONRMgr.KVStore.Put(ctx, Path, FormatResult)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400539 if err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000540 logger.Debug(ctx, "Successfuly posted to kv store")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400541 return err
542 }
543 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400544
Neha Sharma96b7bf22020-06-15 10:37:32 +0000545 logger.Debug(ctx, "Error initializing pool")
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400546
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400547 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400548}
549
divyadesaid26f6b12020-03-19 06:30:28 +0000550func (PONRMgr *PONResourceManager) getReservedGemPortIdsFromKVStore(ctx context.Context) ([]uint32, bool) {
551 var reservedGemPortIds []uint32
552 // read reserved gem ports from the config path
553 KvPair, err := PONRMgr.KVStoreForConfig.Get(ctx, RESERVED_GEMPORT_IDS_PATH)
554 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000555 logger.Errorw(ctx, "Unable to get reserved GEM port ids from the kv store", log.Fields{"err": err})
divyadesaid26f6b12020-03-19 06:30:28 +0000556 return reservedGemPortIds, false
557 }
558 if KvPair == nil || KvPair.Value == nil {
559 //no reserved gem port defined in the store
560 return reservedGemPortIds, false
561 }
562 Val, err := kvstore.ToByte(KvPair.Value)
563 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000564 logger.Errorw(ctx, "Failed to convert reserved gem port ids into byte array", log.Fields{"err": err})
divyadesaid26f6b12020-03-19 06:30:28 +0000565 return reservedGemPortIds, false
566 }
567 if err = json.Unmarshal(Val, &reservedGemPortIds); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000568 logger.Errorw(ctx, "Failed to unmarshal reservedGemPortIds", log.Fields{"err": err})
divyadesaid26f6b12020-03-19 06:30:28 +0000569 return reservedGemPortIds, false
570 }
571 return reservedGemPortIds, true
572}
573
Neha Sharma96b7bf22020-06-15 10:37:32 +0000574func (PONRMgr *PONResourceManager) FormatResource(ctx context.Context, IntfID uint32, StartIDx uint32, EndIDx uint32,
divyadesaid26f6b12020-03-19 06:30:28 +0000575 Excluded []uint32) ([]byte, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400576 /*
577 Format resource as json.
578 :param pon_intf_id: OLT PON interface id
579 :param start_idx: start index for id pool
580 :param end_idx: end index for id pool
divyadesaid26f6b12020-03-19 06:30:28 +0000581 :Id values to be Excluded from the pool
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400582 :return dictionary: resource formatted as map
583 */
584 // Format resource as json to be stored in backend store
585 Resource := make(map[string]interface{})
586 Resource[PON_INTF_ID] = IntfID
587 Resource[START_IDX] = StartIDx
588 Resource[END_IDX] = EndIDx
589 /*
590 Resource pool stored in backend store as binary string.
591 Tracking the resource allocation will be done by setting the bits \
592 in the byte array. The index set will be the resource number allocated.
593 */
594 var TSData *bitmap.Threadsafe
595 if TSData = bitmap.NewTS(int(EndIDx)); TSData == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000596 logger.Error(ctx, "Failed to create a bitmap")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400597 return nil, errors.New("Failed to create bitmap")
598 }
divyadesaid26f6b12020-03-19 06:30:28 +0000599 for _, excludedID := range Excluded {
600 if excludedID < StartIDx || excludedID > EndIDx {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000601 logger.Warnf(ctx, "Cannot reserve %d. It must be in the range of [%d, %d]", excludedID,
divyadesaid26f6b12020-03-19 06:30:28 +0000602 StartIDx, EndIDx)
603 continue
604 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000605 PONRMgr.reserveID(ctx, TSData, StartIDx, excludedID)
divyadesaid26f6b12020-03-19 06:30:28 +0000606 }
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400607 Resource[POOL] = TSData.Data(false) //we pass false so as the TSData lib api does not do a copy of the data and return
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400608
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400609 Value, err := json.Marshal(Resource)
610 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000611 logger.Errorf(ctx, "Failed to marshall resource")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400612 return nil, err
613 }
614 return Value, err
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400615}
npujarec5762e2020-01-01 14:08:48 +0530616func (PONRMgr *PONResourceManager) GetResource(ctx context.Context, Path string) (map[string]interface{}, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400617 /*
618 Get resource from kv store.
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400619
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400620 :param path: path to get resource
621 :return: resource if resource present in kv store else None
622 */
623 //get resource from kv store
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400624
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400625 var Value []byte
626 Result := make(map[string]interface{})
627 var Str string
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400628
npujarec5762e2020-01-01 14:08:48 +0530629 Resource, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400630 if (err != nil) || (Resource == nil) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000631 logger.Debugf(ctx, "Resource unavailable at %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400632 return nil, err
633 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400634
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400635 Value, err = ToByte(Resource.Value)
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000636 if err != nil {
637 return nil, err
638 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400639
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400640 // decode resource fetched from backend store to dictionary
641 err = json.Unmarshal(Value, &Result)
642 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000643 logger.Error(ctx, "Failed to decode resource")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400644 return Result, err
645 }
646 /*
647 resource pool in backend store stored as binary string whereas to
648 access the pool to generate/release IDs it need to be converted
649 as BitArray
650 */
651 Str, err = ToString(Result[POOL])
652 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000653 logger.Error(ctx, "Failed to conver to kv pair to string")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400654 return Result, err
655 }
656 Decode64, _ := base64.StdEncoding.DecodeString(Str)
657 Result[POOL], err = ToByte(Decode64)
658 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000659 logger.Error(ctx, "Failed to convert resource pool to byte")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400660 return Result, err
661 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400662
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400663 return Result, err
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400664}
665
Neha Sharma96b7bf22020-06-15 10:37:32 +0000666func (PONRMgr *PONResourceManager) GetPath(ctx context.Context, IntfID uint32, ResourceType string) string {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400667 /*
668 Get path for given resource type.
669 :param pon_intf_id: OLT PON interface id
670 :param resource_type: String to identify type of resource
671 :return: path for given resource type
672 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400673
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400674 /*
675 Get the shared pool for the given resource type.
676 all the resource ranges and the shared resource maps are initialized during the init.
677 */
678 SharedPoolID := PONRMgr.PonResourceRanges[PONRMgr.SharedIdxByType[ResourceType]].(uint32)
679 if SharedPoolID != 0 {
680 IntfID = SharedPoolID
681 }
682 var Path string
683 if ResourceType == ONU_ID {
684 Path = fmt.Sprintf(ONU_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
685 } else if ResourceType == ALLOC_ID {
686 Path = fmt.Sprintf(ALLOC_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
687 } else if ResourceType == GEMPORT_ID {
688 Path = fmt.Sprintf(GEMPORT_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
689 } else if ResourceType == FLOW_ID {
690 Path = fmt.Sprintf(FLOW_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
691 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000692 logger.Error(ctx, "Invalid resource pool identifier")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400693 }
694 return Path
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400695}
696
npujarec5762e2020-01-01 14:08:48 +0530697func (PONRMgr *PONResourceManager) GetResourceID(ctx context.Context, IntfID uint32, ResourceType string, NumIDs uint32) ([]uint32, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400698 /*
699 Create alloc/gemport/onu/flow id for given OLT PON interface.
700 :param pon_intf_id: OLT PON interface id
701 :param resource_type: String to identify type of resource
702 :param num_of_id: required number of ids
703 :return list/uint32/None: list, uint32 or None if resource type is
704 alloc_id/gemport_id, onu_id or invalid type respectively
705 */
Matteo Scandolo84585372021-03-18 14:21:22 -0700706
707 logger.Debugw(ctx, "getting-resource-id", log.Fields{
708 "intf-id": IntfID,
709 "resource-type": ResourceType,
710 "num": NumIDs,
711 })
712
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400713 if NumIDs < 1 {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000714 logger.Error(ctx, "Invalid number of resources requested")
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000715 return nil, fmt.Errorf("Invalid number of resources requested %d", NumIDs)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400716 }
717 // delegate to the master instance if sharing enabled across instances
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400718
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400719 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
720 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujarec5762e2020-01-01 14:08:48 +0530721 return SharedResourceMgr.GetResourceID(ctx, IntfID, ResourceType, NumIDs)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400722 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000723 logger.Debugf(ctx, "Fetching resource from %s rsrc mgr for resource %s", PONRMgr.Globalorlocal, ResourceType)
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400724
Neha Sharma96b7bf22020-06-15 10:37:32 +0000725 Path := PONRMgr.GetPath(ctx, IntfID, ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400726 if Path == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000727 logger.Errorf(ctx, "Failed to get path for resource type %s", ResourceType)
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000728 return nil, fmt.Errorf("Failed to get path for resource type %s", ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400729 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000730 logger.Debugf(ctx, "Get resource for type %s on path %s", ResourceType, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400731 var Result []uint32
732 var NextID uint32
npujarec5762e2020-01-01 14:08:48 +0530733 Resource, err := PONRMgr.GetResource(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400734 if (err == nil) && (ResourceType == ONU_ID) || (ResourceType == FLOW_ID) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000735 if NextID, err = PONRMgr.GenerateNextID(ctx, Resource); err != nil {
736 logger.Error(ctx, "Failed to Generate ID")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400737 return Result, err
738 }
739 Result = append(Result, NextID)
740 } else if (err == nil) && ((ResourceType == GEMPORT_ID) || (ResourceType == ALLOC_ID)) {
741 if NumIDs == 1 {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000742 if NextID, err = PONRMgr.GenerateNextID(ctx, Resource); err != nil {
743 logger.Error(ctx, "Failed to Generate ID")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400744 return Result, err
745 }
746 Result = append(Result, NextID)
747 } else {
748 for NumIDs > 0 {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000749 if NextID, err = PONRMgr.GenerateNextID(ctx, Resource); err != nil {
750 logger.Error(ctx, "Failed to Generate ID")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400751 return Result, err
752 }
753 Result = append(Result, NextID)
754 NumIDs--
755 }
756 }
757 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000758 logger.Error(ctx, "get resource failed")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400759 return Result, err
760 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400761
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400762 //Update resource in kv store
npujarec5762e2020-01-01 14:08:48 +0530763 if PONRMgr.UpdateResource(ctx, Path, Resource) != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000764 logger.Errorf(ctx, "Failed to update resource %s", Path)
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000765 return nil, fmt.Errorf("Failed to update resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400766 }
767 return Result, nil
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400768}
769
770func checkValidResourceType(ResourceType string) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400771 KnownResourceTypes := []string{ONU_ID, ALLOC_ID, GEMPORT_ID, FLOW_ID}
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400772
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400773 for _, v := range KnownResourceTypes {
774 if v == ResourceType {
775 return true
776 }
777 }
778 return false
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400779}
780
Matteo Scandolo84585372021-03-18 14:21:22 -0700781func (PONRMgr *PONResourceManager) FreeResourceID(ctx context.Context, IntfID uint32, ResourceType string, ReleaseContent []uint32) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400782 /*
Matteo Scandolo84585372021-03-18 14:21:22 -0700783 Release alloc/gemport/onu/flow id for given OLT PON interface.
784 :param pon_intf_id: OLT PON interface id
785 :param resource_type: String to identify type of resource
786 :param release_content: required number of ids
787 :return boolean: True if all IDs in given release_content release else False
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400788 */
Matteo Scandolo84585372021-03-18 14:21:22 -0700789
790 logger.Debugw(ctx, "freeing-resource-id", log.Fields{
791 "intf-id": IntfID,
792 "resource-type": ResourceType,
793 "release-content": ReleaseContent,
794 })
795
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000796 if !checkValidResourceType(ResourceType) {
Matteo Scandolo84585372021-03-18 14:21:22 -0700797 err := fmt.Errorf("Invalid resource type: %s", ResourceType)
798 logger.Error(ctx, err.Error())
799 return err
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400800 }
801 if ReleaseContent == nil {
Matteo Scandolo84585372021-03-18 14:21:22 -0700802 err := fmt.Errorf("Nothing to release")
803 logger.Debug(ctx, err.Error())
804 return err
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400805 }
806 // delegate to the master instance if sharing enabled across instances
807 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
808 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujarec5762e2020-01-01 14:08:48 +0530809 return SharedResourceMgr.FreeResourceID(ctx, IntfID, ResourceType, ReleaseContent)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400810 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000811 Path := PONRMgr.GetPath(ctx, IntfID, ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400812 if Path == "" {
Matteo Scandolo84585372021-03-18 14:21:22 -0700813 err := fmt.Errorf("Failed to get path for IntfId %d and ResourceType %s", IntfID, ResourceType)
814 logger.Error(ctx, err.Error())
815 return err
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400816 }
npujarec5762e2020-01-01 14:08:48 +0530817 Resource, err := PONRMgr.GetResource(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400818 if err != nil {
Matteo Scandolo84585372021-03-18 14:21:22 -0700819 logger.Error(ctx, err.Error())
820 return err
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400821 }
822 for _, Val := range ReleaseContent {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000823 PONRMgr.ReleaseID(ctx, Resource, Val)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400824 }
npujarec5762e2020-01-01 14:08:48 +0530825 if PONRMgr.UpdateResource(ctx, Path, Resource) != nil {
Matteo Scandolo84585372021-03-18 14:21:22 -0700826 err := fmt.Errorf("Free resource for %s failed", Path)
827 logger.Errorf(ctx, err.Error())
828 return err
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400829 }
Matteo Scandolo84585372021-03-18 14:21:22 -0700830 return nil
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400831}
832
npujarec5762e2020-01-01 14:08:48 +0530833func (PONRMgr *PONResourceManager) UpdateResource(ctx context.Context, Path string, Resource map[string]interface{}) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400834 /*
835 Update resource in resource kv store.
836 :param path: path to update resource
837 :param resource: resource need to be updated
838 :return boolean: True if resource updated in kv store else False
839 */
840 // TODO resource[POOL] = resource[POOL].bin
841 Value, err := json.Marshal(Resource)
842 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000843 logger.Error(ctx, "failed to Marshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400844 return err
845 }
npujarec5762e2020-01-01 14:08:48 +0530846 err = PONRMgr.KVStore.Put(ctx, Path, Value)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400847 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000848 logger.Error(ctx, "failed to put data to kv store %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400849 return err
850 }
851 return nil
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400852}
853
npujarec5762e2020-01-01 14:08:48 +0530854func (PONRMgr *PONResourceManager) ClearResourceIDPool(ctx context.Context, contIntfID uint32, ResourceType string) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400855 /*
856 Clear Resource Pool for a given Resource Type on a given PON Port.
857 :return boolean: True if removed else False
858 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400859
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400860 // 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.ClearResourceIDPool(ctx, contIntfID, ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400864 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000865 Path := PONRMgr.GetPath(ctx, contIntfID, ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400866 if Path == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000867 logger.Error(ctx, "Failed to get path")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400868 return false
869 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400870
npujarec5762e2020-01-01 14:08:48 +0530871 if err := PONRMgr.KVStore.Delete(ctx, Path); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000872 logger.Errorf(ctx, "Failed to delete resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400873 return false
874 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000875 logger.Debugf(ctx, "Cleared resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400876 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400877}
878
npujarec5762e2020-01-01 14:08:48 +0530879func (PONRMgr PONResourceManager) InitResourceMap(ctx context.Context, PONIntfONUID string) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400880 /*
881 Initialize resource map
882 :param pon_intf_onu_id: reference of PON interface id and onu id
883 */
884 // initialize pon_intf_onu_id tuple to alloc_ids map
885 AllocIDPath := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
886 var AllocIDs []byte
npujarec5762e2020-01-01 14:08:48 +0530887 Result := PONRMgr.KVStore.Put(ctx, AllocIDPath, AllocIDs)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400888 if Result != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000889 logger.Error(ctx, "Failed to update the KV store")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400890 return
891 }
892 // initialize pon_intf_onu_id tuple to gemport_ids map
893 GEMPortIDPath := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
894 var GEMPortIDs []byte
npujarec5762e2020-01-01 14:08:48 +0530895 Result = PONRMgr.KVStore.Put(ctx, GEMPortIDPath, GEMPortIDs)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400896 if Result != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000897 logger.Error(ctx, "Failed to update the KV store")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400898 return
899 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400900}
901
npujarec5762e2020-01-01 14:08:48 +0530902func (PONRMgr PONResourceManager) RemoveResourceMap(ctx context.Context, PONIntfONUID string) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400903 /*
904 Remove resource map
905 :param pon_intf_onu_id: reference of PON interface id and onu id
906 */
907 // remove pon_intf_onu_id tuple to alloc_ids map
908 var err error
909 AllocIDPath := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujarec5762e2020-01-01 14:08:48 +0530910 if err = PONRMgr.KVStore.Delete(ctx, AllocIDPath); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000911 logger.Errorf(ctx, "Failed to remove resource %s", AllocIDPath)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400912 return false
913 }
914 // remove pon_intf_onu_id tuple to gemport_ids map
915 GEMPortIDPath := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujarec5762e2020-01-01 14:08:48 +0530916 err = PONRMgr.KVStore.Delete(ctx, GEMPortIDPath)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400917 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000918 logger.Errorf(ctx, "Failed to remove resource %s", GEMPortIDPath)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400919 return false
920 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400921
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400922 FlowIDPath := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujarec5762e2020-01-01 14:08:48 +0530923 if FlowIDs, err := PONRMgr.KVStore.List(ctx, FlowIDPath); err != nil {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400924 for _, Flow := range FlowIDs {
925 FlowIDInfoPath := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, PONIntfONUID, Flow.Value)
npujarec5762e2020-01-01 14:08:48 +0530926 if err = PONRMgr.KVStore.Delete(ctx, FlowIDInfoPath); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000927 logger.Errorf(ctx, "Failed to remove resource %s", FlowIDInfoPath)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400928 return false
929 }
930 }
931 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400932
npujarec5762e2020-01-01 14:08:48 +0530933 if err = PONRMgr.KVStore.Delete(ctx, FlowIDPath); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000934 logger.Errorf(ctx, "Failed to remove resource %s", FlowIDPath)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400935 return false
936 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400937
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400938 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400939}
940
npujarec5762e2020-01-01 14:08:48 +0530941func (PONRMgr *PONResourceManager) GetCurrentAllocIDForOnu(ctx context.Context, IntfONUID string) []uint32 {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400942 /*
943 Get currently configured alloc ids for given pon_intf_onu_id
944 :param pon_intf_onu_id: reference of PON interface id and onu id
945 :return list: List of alloc_ids if available, else None
946 */
947 Path := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400948
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400949 var Data []uint32
npujarec5762e2020-01-01 14:08:48 +0530950 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400951 if err == nil {
952 if Value != nil {
953 Val, err := ToByte(Value.Value)
954 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000955 logger.Errorw(ctx, "Failed to convert into byte array", log.Fields{"error": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400956 return Data
957 }
958 if err = json.Unmarshal(Val, &Data); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000959 logger.Error(ctx, "Failed to unmarshal", log.Fields{"error": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400960 return Data
961 }
962 }
963 }
964 return Data
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400965}
966
npujarec5762e2020-01-01 14:08:48 +0530967func (PONRMgr *PONResourceManager) GetCurrentGEMPortIDsForOnu(ctx context.Context, IntfONUID string) []uint32 {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400968 /*
969 Get currently configured gemport ids for given pon_intf_onu_id
970 :param pon_intf_onu_id: reference of PON interface id and onu id
971 :return list: List of gemport IDs if available, else None
972 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400973
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400974 Path := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000975 logger.Debugf(ctx, "Getting current gemports for %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400976 var Data []uint32
npujarec5762e2020-01-01 14:08:48 +0530977 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400978 if err == nil {
979 if Value != nil {
980 Val, _ := ToByte(Value.Value)
981 if err = json.Unmarshal(Val, &Data); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000982 logger.Errorw(ctx, "Failed to unmarshal", log.Fields{"error": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400983 return Data
984 }
985 }
986 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000987 logger.Errorf(ctx, "Failed to get data from kvstore for %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400988 }
989 return Data
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400990}
991
npujarec5762e2020-01-01 14:08:48 +0530992func (PONRMgr *PONResourceManager) GetCurrentFlowIDsForOnu(ctx context.Context, IntfONUID string) []uint32 {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400993 /*
994 Get currently configured flow ids for given pon_intf_onu_id
995 :param pon_intf_onu_id: reference of PON interface id and onu id
996 :return list: List of Flow IDs if available, else None
997 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400998
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400999 Path := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001000
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001001 var Data []uint32
npujarec5762e2020-01-01 14:08:48 +05301002 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001003 if err == nil {
1004 if Value != nil {
1005 Val, _ := ToByte(Value.Value)
1006 if err = json.Unmarshal(Val, &Data); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001007 logger.Error(ctx, "Failed to unmarshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001008 return Data
1009 }
1010 }
1011 }
1012 return Data
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001013}
1014
npujarec5762e2020-01-01 14:08:48 +05301015func (PONRMgr *PONResourceManager) GetFlowIDInfo(ctx context.Context, IntfONUID string, FlowID uint32, Data interface{}) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001016 /*
1017 Get flow details configured for the ONU.
1018 :param pon_intf_onu_id: reference of PON interface id and onu id
1019 :param flow_id: Flow Id reference
1020 :param Data: Result
1021 :return error: nil if no error in getting from KV store
1022 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001023
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001024 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001025
npujarec5762e2020-01-01 14:08:48 +05301026 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001027 if err == nil {
1028 if Value != nil {
1029 Val, err := ToByte(Value.Value)
1030 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001031 logger.Errorw(ctx, "Failed to convert flowinfo into byte array", log.Fields{"error": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001032 return err
1033 }
1034 if err = json.Unmarshal(Val, Data); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001035 logger.Errorw(ctx, "Failed to unmarshal", log.Fields{"error": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001036 return err
1037 }
1038 }
1039 }
1040 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001041}
1042
npujarec5762e2020-01-01 14:08:48 +05301043func (PONRMgr *PONResourceManager) RemoveFlowIDInfo(ctx context.Context, IntfONUID string, FlowID uint32) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001044 /*
1045 Get flow_id details configured for the ONU.
1046 :param pon_intf_onu_id: reference of PON interface id and onu id
1047 :param flow_id: Flow Id reference
1048 */
1049 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001050
npujarec5762e2020-01-01 14:08:48 +05301051 if err := PONRMgr.KVStore.Delete(ctx, Path); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001052 logger.Errorf(ctx, "Falied to remove resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001053 return false
1054 }
1055 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001056}
1057
serkant.uluderya7b8211e2021-02-24 16:39:18 +03001058func (PONRMgr *PONResourceManager) RemoveAllFlowIDInfo(ctx context.Context, IntfONUID string) bool {
1059 /*
1060 Remove flow_id_info details configured for the ONU.
1061 :param pon_intf_onu_id: reference of PON interface id and onu id
1062 */
1063 Path := fmt.Sprintf(FLOW_ID_INFO_PATH_INTF_ONU_PREFIX, PONRMgr.DeviceID, IntfONUID)
1064
1065 if err := PONRMgr.KVStore.DeleteWithPrefix(ctx, Path); err != nil {
1066 logger.Errorf(ctx, "Falied to remove resource %s", Path)
1067 return false
1068 }
1069 return true
1070}
1071
npujarec5762e2020-01-01 14:08:48 +05301072func (PONRMgr *PONResourceManager) UpdateAllocIdsForOnu(ctx context.Context, IntfONUID string, AllocIDs []uint32) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001073 /*
1074 Update currently configured alloc ids for given pon_intf_onu_id
1075 :param pon_intf_onu_id: reference of PON interface id and onu id
1076 :param alloc_ids: list of alloc ids
1077 */
1078 var Value []byte
1079 var err error
1080 Path := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
1081 Value, err = json.Marshal(AllocIDs)
1082 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001083 logger.Error(ctx, "failed to Marshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001084 return err
1085 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001086
npujarec5762e2020-01-01 14:08:48 +05301087 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001088 logger.Errorf(ctx, "Failed to update resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001089 return err
1090 }
1091 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001092}
1093
npujarec5762e2020-01-01 14:08:48 +05301094func (PONRMgr *PONResourceManager) UpdateGEMPortIDsForOnu(ctx context.Context, IntfONUID string, GEMPortIDs []uint32) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001095 /*
1096 Update currently configured gemport ids for given pon_intf_onu_id
1097 :param pon_intf_onu_id: reference of PON interface id and onu id
1098 :param gemport_ids: list of gem port ids
1099 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001100
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001101 var Value []byte
1102 var err error
1103 Path := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001104 logger.Debugf(ctx, "Updating gemport ids for %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001105 Value, err = json.Marshal(GEMPortIDs)
1106 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001107 logger.Error(ctx, "failed to Marshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001108 return err
1109 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001110
npujarec5762e2020-01-01 14:08:48 +05301111 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001112 logger.Errorf(ctx, "Failed to update resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001113 return err
1114 }
1115 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001116}
1117
1118func checkForFlowIDInList(FlowIDList []uint32, FlowID uint32) (bool, uint32) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001119 /*
1120 Check for a flow id in a given list of flow IDs.
1121 :param FLowIDList: List of Flow IDs
1122 :param FlowID: Flowd to check in the list
1123 : return true and the index if present false otherwise.
1124 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001125
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001126 for idx := range FlowIDList {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001127 if FlowID == FlowIDList[idx] {
1128 return true, uint32(idx)
1129 }
1130 }
1131 return false, 0
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001132}
1133
npujarec5762e2020-01-01 14:08:48 +05301134func (PONRMgr *PONResourceManager) UpdateFlowIDForOnu(ctx context.Context, IntfONUID string, FlowID uint32, Add bool) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001135 /*
1136 Update the flow_id list of the ONU (add or remove flow_id from the list)
1137 :param pon_intf_onu_id: reference of PON interface id and onu id
1138 :param flow_id: flow ID
1139 :param add: Boolean flag to indicate whether the flow_id should be
1140 added or removed from the list. Defaults to adding the flow.
1141 */
1142 var Value []byte
1143 var err error
1144 var RetVal bool
1145 var IDx uint32
1146 Path := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
npujarec5762e2020-01-01 14:08:48 +05301147 FlowIDs := PONRMgr.GetCurrentFlowIDsForOnu(ctx, IntfONUID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001148
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001149 if Add {
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001150 if RetVal, _ = checkForFlowIDInList(FlowIDs, FlowID); RetVal {
1151 return nil
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001152 }
1153 FlowIDs = append(FlowIDs, FlowID)
1154 } else {
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001155 if RetVal, IDx = checkForFlowIDInList(FlowIDs, FlowID); !RetVal {
1156 return nil
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001157 }
1158 // delete the index and shift
1159 FlowIDs = append(FlowIDs[:IDx], FlowIDs[IDx+1:]...)
1160 }
1161 Value, err = json.Marshal(FlowIDs)
1162 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001163 logger.Error(ctx, "Failed to Marshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001164 return err
1165 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001166
npujarec5762e2020-01-01 14:08:48 +05301167 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001168 logger.Errorf(ctx, "Failed to update resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001169 return err
1170 }
1171 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001172}
1173
npujarec5762e2020-01-01 14:08:48 +05301174func (PONRMgr *PONResourceManager) UpdateFlowIDInfoForOnu(ctx context.Context, IntfONUID string, FlowID uint32, FlowData interface{}) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001175 /*
1176 Update any metadata associated with the flow_id. The flow_data could be json
1177 or any of other data structure. The resource manager doesnt care
1178 :param pon_intf_onu_id: reference of PON interface id and onu id
1179 :param flow_id: Flow ID
1180 :param flow_data: Flow data blob
1181 */
1182 var Value []byte
1183 var err error
1184 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
1185 Value, err = json.Marshal(FlowData)
1186 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001187 logger.Error(ctx, "failed to Marshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001188 return err
1189 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001190
npujarec5762e2020-01-01 14:08:48 +05301191 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001192 logger.Errorf(ctx, "Failed to update resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001193 return err
1194 }
1195 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001196}
1197
Neha Sharma96b7bf22020-06-15 10:37:32 +00001198func (PONRMgr *PONResourceManager) GenerateNextID(ctx context.Context, Resource map[string]interface{}) (uint32, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001199 /*
1200 Generate unique id having OFFSET as start
1201 :param resource: resource used to generate ID
1202 :return uint32: generated id
1203 */
1204 ByteArray, err := ToByte(Resource[POOL])
1205 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001206 logger.Error(ctx, "Failed to convert resource to byte array")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001207 return 0, err
1208 }
1209 Data := bitmap.TSFromData(ByteArray, false)
1210 if Data == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001211 logger.Error(ctx, "Failed to get data from byte array")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001212 return 0, errors.New("Failed to get data from byte array")
1213 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001214
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001215 Len := Data.Len()
1216 var Idx int
1217 for Idx = 0; Idx < Len; Idx++ {
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001218 if !Data.Get(Idx) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001219 break
1220 }
1221 }
1222 Data.Set(Idx, true)
1223 res := uint32(Resource[START_IDX].(float64))
1224 Resource[POOL] = Data.Data(false)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001225 logger.Debugf(ctx, "Generated ID for %d", (uint32(Idx) + res))
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001226 return (uint32(Idx) + res), err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001227}
1228
Neha Sharma96b7bf22020-06-15 10:37:32 +00001229func (PONRMgr *PONResourceManager) ReleaseID(ctx context.Context, Resource map[string]interface{}, Id uint32) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001230 /*
1231 Release unique id having OFFSET as start index.
1232 :param resource: resource used to release ID
1233 :param unique_id: id need to be released
1234 */
1235 ByteArray, err := ToByte(Resource[POOL])
1236 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001237 logger.Error(ctx, "Failed to convert resource to byte array")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001238 return false
1239 }
1240 Data := bitmap.TSFromData(ByteArray, false)
1241 if Data == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001242 logger.Error(ctx, "Failed to get resource pool")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001243 return false
1244 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001245 Idx := Id - uint32(Resource[START_IDX].(float64))
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001246 Data.Set(int(Idx), false)
1247 Resource[POOL] = Data.Data(false)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001248
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001249 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001250}
1251
divyadesaid26f6b12020-03-19 06:30:28 +00001252/* Reserves a unique id in the specified resource pool.
1253:param Resource: resource used to reserve ID
1254:param Id: ID to be reserved
1255*/
Neha Sharma96b7bf22020-06-15 10:37:32 +00001256func (PONRMgr *PONResourceManager) reserveID(ctx context.Context, TSData *bitmap.Threadsafe, StartIndex uint32, Id uint32) bool {
divyadesaid26f6b12020-03-19 06:30:28 +00001257 Data := bitmap.TSFromData(TSData.Data(false), false)
1258 if Data == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001259 logger.Error(ctx, "Failed to get resource pool")
divyadesaid26f6b12020-03-19 06:30:28 +00001260 return false
1261 }
1262 Idx := Id - StartIndex
1263 Data.Set(int(Idx), true)
1264 return true
1265}
1266
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001267func (PONRMgr *PONResourceManager) GetTechnology() string {
1268 return PONRMgr.Technology
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001269}
1270
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001271func (PONRMgr *PONResourceManager) GetResourceTypeAllocID() string {
1272 return ALLOC_ID
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001273}
1274
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001275func (PONRMgr *PONResourceManager) GetResourceTypeGemPortID() string {
1276 return GEMPORT_ID
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001277}
1278
Matteo Scandolo84585372021-03-18 14:21:22 -07001279func (PONRMgr *PONResourceManager) GetResourceTypeOnuID() string {
1280 return ONU_ID
1281}
1282
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001283// ToByte converts an interface value to a []byte. The interface should either be of
1284// a string type or []byte. Otherwise, an error is returned.
1285func ToByte(value interface{}) ([]byte, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001286 switch t := value.(type) {
1287 case []byte:
1288 return value.([]byte), nil
1289 case string:
1290 return []byte(value.(string)), nil
1291 default:
1292 return nil, fmt.Errorf("unexpected-type-%T", t)
1293 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001294}
1295
1296// ToString converts an interface value to a string. The interface should either be of
1297// a string type or []byte. Otherwise, an error is returned.
1298func ToString(value interface{}) (string, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001299 switch t := value.(type) {
1300 case []byte:
1301 return string(value.([]byte)), nil
1302 case string:
1303 return value.(string), nil
1304 default:
1305 return "", fmt.Errorf("unexpected-type-%T", t)
1306 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001307}
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001308
npujarec5762e2020-01-01 14:08:48 +05301309func (PONRMgr *PONResourceManager) AddOnuGemInfo(ctx context.Context, intfID uint32, onuGemData interface{}) error {
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001310 /*
1311 Update onugem info map,
1312 :param pon_intf_id: reference of PON interface id
1313 :param onuegmdata: onugem info map
1314 */
1315 var Value []byte
1316 var err error
1317 Path := fmt.Sprintf(ONU_GEM_INFO_PATH, PONRMgr.DeviceID, intfID)
1318 Value, err = json.Marshal(onuGemData)
1319 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001320 logger.Error(ctx, "failed to Marshal")
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001321 return err
1322 }
1323
npujarec5762e2020-01-01 14:08:48 +05301324 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001325 logger.Errorf(ctx, "Failed to update resource %s", Path)
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001326 return err
1327 }
1328 return err
1329}
1330
npujarec5762e2020-01-01 14:08:48 +05301331func (PONRMgr *PONResourceManager) GetOnuGemInfo(ctx context.Context, IntfId uint32, onuGemInfo interface{}) error {
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001332 /*
1333 Get onugeminfo map from kvstore
1334 :param intfid: refremce pon intfid
1335 :param onuGemInfo: onugem info to return from kv strore.
1336 */
1337 var Val []byte
1338
1339 path := fmt.Sprintf(ONU_GEM_INFO_PATH, PONRMgr.DeviceID, IntfId)
npujarec5762e2020-01-01 14:08:48 +05301340 value, err := PONRMgr.KVStore.Get(ctx, path)
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001341 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001342 logger.Errorw(ctx, "Failed to get from kv store", log.Fields{"path": path})
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001343 return err
1344 } else if value == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001345 logger.Debug(ctx, "No onuinfo for path", log.Fields{"path": path})
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001346 return nil // returning nil as this could happen if there are no onus for the interface yet
1347 }
1348 if Val, err = kvstore.ToByte(value.Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001349 logger.Error(ctx, "Failed to convert to byte array")
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001350 return err
1351 }
1352
1353 if err = json.Unmarshal(Val, &onuGemInfo); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001354 logger.Error(ctx, "Failed to unmarshall")
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001355 return err
1356 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001357 logger.Debugw(ctx, "found onuinfo from path", log.Fields{"path": path, "onuinfo": onuGemInfo})
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001358 return err
1359}
1360
npujarec5762e2020-01-01 14:08:48 +05301361func (PONRMgr *PONResourceManager) DelOnuGemInfoForIntf(ctx context.Context, intfId uint32) error {
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001362 /*
1363 delete onugem info for an interface from kvstore
1364 :param intfid: refremce pon intfid
1365 */
1366
1367 path := fmt.Sprintf(ONU_GEM_INFO_PATH, PONRMgr.DeviceID, intfId)
npujarec5762e2020-01-01 14:08:48 +05301368 if err := PONRMgr.KVStore.Delete(ctx, path); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001369 logger.Errorf(ctx, "Falied to remove resource %s", path)
Scott Bakerc6e54cb2019-11-04 09:31:25 -08001370 return err
1371 }
1372 return nil
1373}