blob: 804a6f33e347eadab9a0f828f2b593babbc2f0d4 [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 Gowdra8a0bdcd2021-05-13 12:31:04 -070028 "github.com/opencord/voltha-lib-go/v5/pkg/db"
29 "github.com/opencord/voltha-lib-go/v5/pkg/db/kvstore"
30 "github.com/opencord/voltha-lib-go/v5/pkg/log"
31 tp "github.com/opencord/voltha-lib-go/v5/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
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400121 //Constants for internal usage.
122 PON_INTF_ID = "pon_intf_id"
123 START_IDX = "start_idx"
124 END_IDX = "end_idx"
125 POOL = "pool"
126 NUM_OF_PON_INTF = 16
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400127
Neha Sharmacc656962020-04-14 14:26:11 +0000128 KVSTORE_RETRY_TIMEOUT = 5 * time.Second
divyadesaid26f6b12020-03-19 06:30:28 +0000129 //Path on the KV store for storing reserved gem ports
130 //Format: reserved_gemport_ids
131 RESERVED_GEMPORT_IDS_PATH = "reserved_gemport_ids"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400132)
133
134//type ResourceTypeIndex string
135//type ResourceType string
136
137type PONResourceManager struct {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400138 //Implements APIs to initialize/allocate/release alloc/gemport/onu IDs.
divyadesaid26f6b12020-03-19 06:30:28 +0000139 Technology string
140 DeviceType string
141 DeviceID string
serkant.uluderya7b8211e2021-02-24 16:39:18 +0300142 Backend string // ETCD only currently
Neha Sharma3f221ae2020-04-29 19:02:12 +0000143 Address string // address of the KV store
divyadesaid26f6b12020-03-19 06:30:28 +0000144 OLTModel string
145 KVStore *db.Backend
146 KVStoreForConfig *db.Backend
147 TechProfileMgr tp.TechProfileIf // create object of *tp.TechProfileMgr
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400148
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400149 // Below attribute, pon_resource_ranges, should be initialized
150 // by reading from KV store.
151 PonResourceRanges map[string]interface{}
152 SharedResourceMgrs map[string]*PONResourceManager
153 SharedIdxByType map[string]string
154 IntfIDs []uint32 // list of pon interface IDs
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400155 Globalorlocal string
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400156}
157
Neha Sharma96b7bf22020-06-15 10:37:32 +0000158func newKVClient(ctx context.Context, storeType string, address string, timeout time.Duration) (kvstore.Client, error) {
159 logger.Infow(ctx, "kv-store-type", log.Fields{"store": storeType})
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400160 switch storeType {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400161 case "etcd":
Neha Sharma96b7bf22020-06-15 10:37:32 +0000162 return kvstore.NewEtcdClient(ctx, address, timeout, log.WarnLevel)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400163 }
164 return nil, errors.New("unsupported-kv-store")
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400165}
166
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800167func SetKVClient(ctx context.Context, Technology string, Backend string, Addr string, configClient bool, basePathKvStore string) *db.Backend {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400168 // TODO : Make sure direct call to NewBackend is working fine with backend , currently there is some
169 // issue between kv store and backend , core is not calling NewBackend directly
Neha Sharma96b7bf22020-06-15 10:37:32 +0000170 kvClient, err := newKVClient(ctx, Backend, Addr, KVSTORE_RETRY_TIMEOUT)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400171 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000172 logger.Fatalw(ctx, "Failed to init KV client\n", log.Fields{"err": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400173 return nil
174 }
divyadesaid26f6b12020-03-19 06:30:28 +0000175
176 var pathPrefix string
177 if configClient {
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800178 pathPrefix = fmt.Sprintf(PATH_PREFIX_FOR_CONFIG, basePathKvStore)
divyadesaid26f6b12020-03-19 06:30:28 +0000179 } else {
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800180 pathPrefix = fmt.Sprintf(PATH_PREFIX, basePathKvStore, Technology)
divyadesaid26f6b12020-03-19 06:30:28 +0000181 }
182
sbarbaria8910ba2019-11-05 10:12:23 -0500183 kvbackend := &db.Backend{
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400184 Client: kvClient,
185 StoreType: Backend,
Neha Sharma3f221ae2020-04-29 19:02:12 +0000186 Address: Addr,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400187 Timeout: KVSTORE_RETRY_TIMEOUT,
divyadesaid26f6b12020-03-19 06:30:28 +0000188 PathPrefix: pathPrefix}
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400189
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400190 return kvbackend
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400191}
192
193// NewPONResourceManager creates a new PON resource manager.
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800194func 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 -0400195 var PONMgr PONResourceManager
196 PONMgr.Technology = Technology
197 PONMgr.DeviceType = DeviceType
198 PONMgr.DeviceID = DeviceID
199 PONMgr.Backend = Backend
Neha Sharma3f221ae2020-04-29 19:02:12 +0000200 PONMgr.Address = Address
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800201 PONMgr.KVStore = SetKVClient(ctx, Technology, Backend, Address, false, basePathKvStore)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400202 if PONMgr.KVStore == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000203 logger.Error(ctx, "KV Client initilization failed")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400204 return nil, errors.New("Failed to init KV client")
205 }
divyadesaid26f6b12020-03-19 06:30:28 +0000206 // init kv client to read from the config path
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800207 PONMgr.KVStoreForConfig = SetKVClient(ctx, Technology, Backend, Address, true, basePathKvStore)
divyadesaid26f6b12020-03-19 06:30:28 +0000208 if PONMgr.KVStoreForConfig == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000209 logger.Error(ctx, "KV Config Client initilization failed")
divyadesaid26f6b12020-03-19 06:30:28 +0000210 return nil, errors.New("Failed to init KV Config client")
211 }
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400212 // Initialize techprofile for this technology
Matteo Scandoloc858ab72020-11-16 12:44:51 -0800213 if PONMgr.TechProfileMgr, _ = tp.NewTechProfile(ctx, &PONMgr, Backend, Address, basePathKvStore); PONMgr.TechProfileMgr == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000214 logger.Error(ctx, "Techprofile initialization failed")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400215 return nil, errors.New("Failed to init tech profile")
216 }
217 PONMgr.PonResourceRanges = make(map[string]interface{})
218 PONMgr.SharedResourceMgrs = make(map[string]*PONResourceManager)
219 PONMgr.SharedIdxByType = make(map[string]string)
220 PONMgr.SharedIdxByType[ONU_ID] = ONU_ID_SHARED_IDX
221 PONMgr.SharedIdxByType[ALLOC_ID] = ALLOC_ID_SHARED_IDX
222 PONMgr.SharedIdxByType[GEMPORT_ID] = GEMPORT_ID_SHARED_IDX
223 PONMgr.SharedIdxByType[FLOW_ID] = FLOW_ID_SHARED_IDX
224 PONMgr.IntfIDs = make([]uint32, NUM_OF_PON_INTF)
225 PONMgr.OLTModel = DeviceType
226 return &PONMgr, nil
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400227}
228
229/*
230 Initialize PON resource ranges with config fetched from kv store.
231 return boolean: True if PON resource ranges initialized else false
232 Try to initialize the PON Resource Ranges from KV store based on the
233 OLT model key, if available
234*/
235
npujarec5762e2020-01-01 14:08:48 +0530236func (PONRMgr *PONResourceManager) InitResourceRangesFromKVStore(ctx context.Context) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400237 //Initialize PON resource ranges with config fetched from kv store.
238 //:return boolean: True if PON resource ranges initialized else false
239 // Try to initialize the PON Resource Ranges from KV store based on the
240 // OLT model key, if available
241 if PONRMgr.OLTModel == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000242 logger.Error(ctx, "Failed to get OLT model")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400243 return false
244 }
245 Path := fmt.Sprintf(PON_RESOURCE_RANGE_CONFIG_PATH, PONRMgr.OLTModel)
246 //get resource from kv store
npujarec5762e2020-01-01 14:08:48 +0530247 Result, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400248 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000249 logger.Debugf(ctx, "Error in fetching resource %s from KV strore", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400250 return false
251 }
252 if Result == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000253 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 -0400254 return false
255 }
256 //update internal ranges from kv ranges. If there are missing
257 // values in the KV profile, continue to use the defaults
258 Value, err := ToByte(Result.Value)
259 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000260 logger.Error(ctx, "Failed to convert kvpair to byte string")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400261 return false
262 }
263 if err := json.Unmarshal(Value, &PONRMgr.PonResourceRanges); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000264 logger.Error(ctx, "Failed to Unmarshal json byte")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400265 return false
266 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000267 logger.Debug(ctx, "Init resource ranges from kvstore success")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400268 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400269}
270
Neha Sharma96b7bf22020-06-15 10:37:32 +0000271func (PONRMgr *PONResourceManager) UpdateRanges(ctx context.Context, StartIDx string, StartID uint32, EndIDx string, EndID uint32,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400272 SharedIDx string, SharedPoolID uint32, RMgr *PONResourceManager) {
273 /*
274 Update the ranges for all reosurce type in the intermnal maps
275 param: resource type start index
276 param: start ID
277 param: resource type end index
278 param: end ID
279 param: resource type shared index
280 param: shared pool id
281 param: global resource manager
282 */
Neha Sharma96b7bf22020-06-15 10:37:32 +0000283 logger.Debugf(ctx, "update ranges for %s, %d", StartIDx, StartID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400284
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400285 if StartID != 0 {
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400286 if (PONRMgr.PonResourceRanges[StartIDx] == nil) || (PONRMgr.PonResourceRanges[StartIDx].(uint32) < StartID) {
287 PONRMgr.PonResourceRanges[StartIDx] = StartID
288 }
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400289 }
290 if EndID != 0 {
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400291 if (PONRMgr.PonResourceRanges[EndIDx] == nil) || (PONRMgr.PonResourceRanges[EndIDx].(uint32) > EndID) {
292 PONRMgr.PonResourceRanges[EndIDx] = EndID
293 }
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400294 }
295 //if SharedPoolID != 0 {
296 PONRMgr.PonResourceRanges[SharedIDx] = SharedPoolID
297 //}
298 if RMgr != nil {
299 PONRMgr.SharedResourceMgrs[SharedIDx] = RMgr
300 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400301}
302
Neha Sharma96b7bf22020-06-15 10:37:32 +0000303func (PONRMgr *PONResourceManager) InitDefaultPONResourceRanges(ctx context.Context,
304 ONUIDStart uint32,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400305 ONUIDEnd uint32,
306 ONUIDSharedPoolID uint32,
307 AllocIDStart uint32,
308 AllocIDEnd uint32,
309 AllocIDSharedPoolID uint32,
310 GEMPortIDStart uint32,
311 GEMPortIDEnd uint32,
312 GEMPortIDSharedPoolID uint32,
313 FlowIDStart uint32,
314 FlowIDEnd uint32,
315 FlowIDSharedPoolID uint32,
316 UNIIDStart uint32,
317 UNIIDEnd uint32,
318 NoOfPONPorts uint32,
319 IntfIDs []uint32) bool {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400320
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400321 /*Initialize default PON resource ranges
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400322
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400323 :param onu_id_start_idx: onu id start index
324 :param onu_id_end_idx: onu id end index
325 :param onu_id_shared_pool_id: pool idx for id shared by all intfs or None for no sharing
326 :param alloc_id_start_idx: alloc id start index
327 :param alloc_id_end_idx: alloc id end index
328 :param alloc_id_shared_pool_id: pool idx for alloc id shared by all intfs or None for no sharing
329 :param gemport_id_start_idx: gemport id start index
330 :param gemport_id_end_idx: gemport id end index
331 :param gemport_id_shared_pool_id: pool idx for gemport id shared by all intfs or None for no sharing
332 :param flow_id_start_idx: flow id start index
333 :param flow_id_end_idx: flow id end index
334 :param flow_id_shared_pool_id: pool idx for flow id shared by all intfs or None for no sharing
335 :param num_of_pon_ports: number of PON ports
336 :param intf_ids: interfaces serviced by this manager
337 */
Neha Sharma96b7bf22020-06-15 10:37:32 +0000338 PONRMgr.UpdateRanges(ctx, ONU_ID_START_IDX, ONUIDStart, ONU_ID_END_IDX, ONUIDEnd, ONU_ID_SHARED_IDX, ONUIDSharedPoolID, nil)
339 PONRMgr.UpdateRanges(ctx, ALLOC_ID_START_IDX, AllocIDStart, ALLOC_ID_END_IDX, AllocIDEnd, ALLOC_ID_SHARED_IDX, AllocIDSharedPoolID, nil)
340 PONRMgr.UpdateRanges(ctx, GEMPORT_ID_START_IDX, GEMPortIDStart, GEMPORT_ID_END_IDX, GEMPortIDEnd, GEMPORT_ID_SHARED_IDX, GEMPortIDSharedPoolID, nil)
341 PONRMgr.UpdateRanges(ctx, FLOW_ID_START_IDX, FlowIDStart, FLOW_ID_END_IDX, FlowIDEnd, FLOW_ID_SHARED_IDX, FlowIDSharedPoolID, nil)
342 PONRMgr.UpdateRanges(ctx, UNI_ID_START_IDX, UNIIDStart, UNI_ID_END_IDX, UNIIDEnd, "", 0, nil)
343 logger.Debug(ctx, "Initialize default range values")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400344 var i uint32
345 if IntfIDs == nil {
346 for i = 0; i < NoOfPONPorts; i++ {
347 PONRMgr.IntfIDs = append(PONRMgr.IntfIDs, i)
348 }
349 } else {
350 PONRMgr.IntfIDs = IntfIDs
351 }
352 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400353}
354
npujarec5762e2020-01-01 14:08:48 +0530355func (PONRMgr *PONResourceManager) InitDeviceResourcePool(ctx context.Context) error {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400356
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400357 //Initialize resource pool for all PON ports.
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400358
Neha Sharma96b7bf22020-06-15 10:37:32 +0000359 logger.Debug(ctx, "Init resource ranges")
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400360
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400361 var err error
362 for _, Intf := range PONRMgr.IntfIDs {
363 SharedPoolID := PONRMgr.PonResourceRanges[ONU_ID_SHARED_IDX].(uint32)
364 if SharedPoolID != 0 {
365 Intf = SharedPoolID
366 }
npujarec5762e2020-01-01 14:08:48 +0530367 if err = PONRMgr.InitResourceIDPool(ctx, Intf, ONU_ID,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400368 PONRMgr.PonResourceRanges[ONU_ID_START_IDX].(uint32),
369 PONRMgr.PonResourceRanges[ONU_ID_END_IDX].(uint32)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000370 logger.Error(ctx, "Failed to init ONU ID resource pool")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400371 return err
372 }
373 if SharedPoolID != 0 {
374 break
375 }
376 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400377
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400378 for _, Intf := range PONRMgr.IntfIDs {
379 SharedPoolID := PONRMgr.PonResourceRanges[ALLOC_ID_SHARED_IDX].(uint32)
380 if SharedPoolID != 0 {
381 Intf = SharedPoolID
382 }
npujarec5762e2020-01-01 14:08:48 +0530383 if err = PONRMgr.InitResourceIDPool(ctx, Intf, ALLOC_ID,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400384 PONRMgr.PonResourceRanges[ALLOC_ID_START_IDX].(uint32),
385 PONRMgr.PonResourceRanges[ALLOC_ID_END_IDX].(uint32)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000386 logger.Error(ctx, "Failed to init ALLOC ID resource pool ")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400387 return err
388 }
389 if SharedPoolID != 0 {
390 break
391 }
392 }
393 for _, Intf := range PONRMgr.IntfIDs {
394 SharedPoolID := PONRMgr.PonResourceRanges[GEMPORT_ID_SHARED_IDX].(uint32)
395 if SharedPoolID != 0 {
396 Intf = SharedPoolID
397 }
npujarec5762e2020-01-01 14:08:48 +0530398 if err = PONRMgr.InitResourceIDPool(ctx, Intf, GEMPORT_ID,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400399 PONRMgr.PonResourceRanges[GEMPORT_ID_START_IDX].(uint32),
400 PONRMgr.PonResourceRanges[GEMPORT_ID_END_IDX].(uint32)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000401 logger.Error(ctx, "Failed to init GEMPORT ID resource pool")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400402 return err
403 }
404 if SharedPoolID != 0 {
405 break
406 }
407 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400408
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400409 for _, Intf := range PONRMgr.IntfIDs {
410 SharedPoolID := PONRMgr.PonResourceRanges[FLOW_ID_SHARED_IDX].(uint32)
411 if SharedPoolID != 0 {
412 Intf = SharedPoolID
413 }
npujarec5762e2020-01-01 14:08:48 +0530414 if err = PONRMgr.InitResourceIDPool(ctx, Intf, FLOW_ID,
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400415 PONRMgr.PonResourceRanges[FLOW_ID_START_IDX].(uint32),
416 PONRMgr.PonResourceRanges[FLOW_ID_END_IDX].(uint32)); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000417 logger.Error(ctx, "Failed to init FLOW ID resource pool")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400418 return err
419 }
420 if SharedPoolID != 0 {
421 break
422 }
423 }
424 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400425}
426
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700427func (PONRMgr *PONResourceManager) InitDeviceResourcePoolForIntf(ctx context.Context, intfID uint32) error {
428
429 logger.Debug(ctx, "Init resource ranges for intf %d", intfID)
430
431 var err error
432
433 if err = PONRMgr.InitResourceIDPool(ctx, intfID, ONU_ID,
434 PONRMgr.PonResourceRanges[ONU_ID_START_IDX].(uint32),
435 PONRMgr.PonResourceRanges[ONU_ID_END_IDX].(uint32)); err != nil {
436 logger.Error(ctx, "Failed to init ONU ID resource pool")
437 return err
438 }
439
440 if err = PONRMgr.InitResourceIDPool(ctx, intfID, ALLOC_ID,
441 PONRMgr.PonResourceRanges[ALLOC_ID_START_IDX].(uint32),
442 PONRMgr.PonResourceRanges[ALLOC_ID_END_IDX].(uint32)); err != nil {
443 logger.Error(ctx, "Failed to init ALLOC ID resource pool ")
444 return err
445 }
446
447 if err = PONRMgr.InitResourceIDPool(ctx, intfID, GEMPORT_ID,
448 PONRMgr.PonResourceRanges[GEMPORT_ID_START_IDX].(uint32),
449 PONRMgr.PonResourceRanges[GEMPORT_ID_END_IDX].(uint32)); err != nil {
450 logger.Error(ctx, "Failed to init GEMPORT ID resource pool")
451 return err
452 }
453
454 if err = PONRMgr.InitResourceIDPool(ctx, intfID, FLOW_ID,
455 PONRMgr.PonResourceRanges[FLOW_ID_START_IDX].(uint32),
456 PONRMgr.PonResourceRanges[FLOW_ID_END_IDX].(uint32)); err != nil {
457 logger.Error(ctx, "Failed to init FLOW ID resource pool")
458 return err
459 }
460
461 return nil
462}
463
npujarec5762e2020-01-01 14:08:48 +0530464func (PONRMgr *PONResourceManager) ClearDeviceResourcePool(ctx context.Context) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -0400465
466 //Clear resource pool for all PON ports.
467
Neha Sharma96b7bf22020-06-15 10:37:32 +0000468 logger.Debug(ctx, "Clear resource ranges")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400469
470 for _, Intf := range PONRMgr.IntfIDs {
471 SharedPoolID := PONRMgr.PonResourceRanges[ONU_ID_SHARED_IDX].(uint32)
472 if SharedPoolID != 0 {
473 Intf = SharedPoolID
474 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000475 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, ONU_ID); !status {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000476 logger.Error(ctx, "Failed to clear ONU ID resource pool")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400477 return errors.New("Failed to clear ONU ID resource pool")
478 }
479 if SharedPoolID != 0 {
480 break
481 }
482 }
483
484 for _, Intf := range PONRMgr.IntfIDs {
485 SharedPoolID := PONRMgr.PonResourceRanges[ALLOC_ID_SHARED_IDX].(uint32)
486 if SharedPoolID != 0 {
487 Intf = SharedPoolID
488 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000489 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, ALLOC_ID); !status {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000490 logger.Error(ctx, "Failed to clear ALLOC ID resource pool ")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400491 return errors.New("Failed to clear ALLOC ID resource pool")
492 }
493 if SharedPoolID != 0 {
494 break
495 }
496 }
497 for _, Intf := range PONRMgr.IntfIDs {
498 SharedPoolID := PONRMgr.PonResourceRanges[GEMPORT_ID_SHARED_IDX].(uint32)
499 if SharedPoolID != 0 {
500 Intf = SharedPoolID
501 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000502 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, GEMPORT_ID); !status {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000503 logger.Error(ctx, "Failed to clear GEMPORT ID resource pool")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400504 return errors.New("Failed to clear GEMPORT ID resource pool")
505 }
506 if SharedPoolID != 0 {
507 break
508 }
509 }
510
511 for _, Intf := range PONRMgr.IntfIDs {
512 SharedPoolID := PONRMgr.PonResourceRanges[FLOW_ID_SHARED_IDX].(uint32)
513 if SharedPoolID != 0 {
514 Intf = SharedPoolID
515 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000516 if status := PONRMgr.ClearResourceIDPool(ctx, Intf, FLOW_ID); !status {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000517 logger.Error(ctx, "Failed to clear FLOW ID resource pool")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400518 return errors.New("Failed to clear FLOW ID resource pool")
519 }
520 if SharedPoolID != 0 {
521 break
522 }
523 }
524 return nil
525}
526
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700527func (PONRMgr *PONResourceManager) ClearDeviceResourcePoolForIntf(ctx context.Context, intfID uint32) error {
528
529 logger.Debugf(ctx, "Clear resource ranges for intf %d", intfID)
530
531 if status := PONRMgr.ClearResourceIDPool(ctx, intfID, ONU_ID); !status {
532 logger.Error(ctx, "Failed to clear ONU ID resource pool")
533 return errors.New("Failed to clear ONU ID resource pool")
534 }
535
536 if status := PONRMgr.ClearResourceIDPool(ctx, intfID, ALLOC_ID); !status {
537 logger.Error(ctx, "Failed to clear ALLOC ID resource pool ")
538 return errors.New("Failed to clear ALLOC ID resource pool")
539 }
540
541 if status := PONRMgr.ClearResourceIDPool(ctx, intfID, GEMPORT_ID); !status {
542 logger.Error(ctx, "Failed to clear GEMPORT ID resource pool")
543 return errors.New("Failed to clear GEMPORT ID resource pool")
544 }
545
546 if status := PONRMgr.ClearResourceIDPool(ctx, intfID, FLOW_ID); !status {
547 logger.Error(ctx, "Failed to clear FLOW ID resource pool")
548 return errors.New("Failed to clear FLOW ID resource pool")
549 }
550
551 return nil
552}
553
npujarec5762e2020-01-01 14:08:48 +0530554func (PONRMgr *PONResourceManager) InitResourceIDPool(ctx context.Context, Intf uint32, ResourceType string, StartID uint32, EndID uint32) error {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400555
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400556 /*Initialize Resource ID pool for a given Resource Type on a given PON Port
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400557
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400558 :param pon_intf_id: OLT PON interface id
559 :param resource_type: String to identify type of resource
560 :param start_idx: start index for onu id pool
561 :param end_idx: end index for onu id pool
562 :return boolean: True if resource id pool initialized else false
563 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400564
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400565 // delegate to the master instance if sharing enabled across instances
566 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
567 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujarec5762e2020-01-01 14:08:48 +0530568 return SharedResourceMgr.InitResourceIDPool(ctx, Intf, ResourceType, StartID, EndID)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400569 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400570
Neha Sharma96b7bf22020-06-15 10:37:32 +0000571 Path := PONRMgr.GetPath(ctx, Intf, ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400572 if Path == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000573 logger.Errorf(ctx, "Failed to get path for resource type %s", ResourceType)
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000574 return fmt.Errorf("Failed to get path for resource type %s", ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400575 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400576
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400577 //In case of adapter reboot and reconciliation resource in kv store
578 //checked for its presence if not kv store update happens
npujarec5762e2020-01-01 14:08:48 +0530579 Res, err := PONRMgr.GetResource(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400580 if (err == nil) && (Res != nil) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000581 logger.Debugf(ctx, "Resource %s already present in store ", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400582 return nil
583 } else {
divyadesaid26f6b12020-03-19 06:30:28 +0000584 var excluded []uint32
585 if ResourceType == GEMPORT_ID {
586 //get gem port ids defined in the KV store, if any, and exclude them from the gem port id pool
587 if reservedGemPortIds, defined := PONRMgr.getReservedGemPortIdsFromKVStore(ctx); defined {
588 excluded = reservedGemPortIds
Neha Sharma96b7bf22020-06-15 10:37:32 +0000589 logger.Debugw(ctx, "Excluding some ports from GEM port id pool", log.Fields{"excluded gem ports": excluded})
divyadesaid26f6b12020-03-19 06:30:28 +0000590 }
591 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000592 FormatResult, err := PONRMgr.FormatResource(ctx, Intf, StartID, EndID, excluded)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400593 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000594 logger.Errorf(ctx, "Failed to format resource")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400595 return err
596 }
597 // Add resource as json in kv store.
npujarec5762e2020-01-01 14:08:48 +0530598 err = PONRMgr.KVStore.Put(ctx, Path, FormatResult)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400599 if err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000600 logger.Debug(ctx, "Successfuly posted to kv store")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400601 return err
602 }
603 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400604
Neha Sharma96b7bf22020-06-15 10:37:32 +0000605 logger.Debug(ctx, "Error initializing pool")
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400606
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400607 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400608}
609
divyadesaid26f6b12020-03-19 06:30:28 +0000610func (PONRMgr *PONResourceManager) getReservedGemPortIdsFromKVStore(ctx context.Context) ([]uint32, bool) {
611 var reservedGemPortIds []uint32
612 // read reserved gem ports from the config path
613 KvPair, err := PONRMgr.KVStoreForConfig.Get(ctx, RESERVED_GEMPORT_IDS_PATH)
614 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000615 logger.Errorw(ctx, "Unable to get reserved GEM port ids from the kv store", log.Fields{"err": err})
divyadesaid26f6b12020-03-19 06:30:28 +0000616 return reservedGemPortIds, false
617 }
618 if KvPair == nil || KvPair.Value == nil {
619 //no reserved gem port defined in the store
620 return reservedGemPortIds, false
621 }
622 Val, err := kvstore.ToByte(KvPair.Value)
623 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000624 logger.Errorw(ctx, "Failed to convert reserved gem port ids into byte array", log.Fields{"err": err})
divyadesaid26f6b12020-03-19 06:30:28 +0000625 return reservedGemPortIds, false
626 }
627 if err = json.Unmarshal(Val, &reservedGemPortIds); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000628 logger.Errorw(ctx, "Failed to unmarshal reservedGemPortIds", log.Fields{"err": err})
divyadesaid26f6b12020-03-19 06:30:28 +0000629 return reservedGemPortIds, false
630 }
631 return reservedGemPortIds, true
632}
633
Neha Sharma96b7bf22020-06-15 10:37:32 +0000634func (PONRMgr *PONResourceManager) FormatResource(ctx context.Context, IntfID uint32, StartIDx uint32, EndIDx uint32,
divyadesaid26f6b12020-03-19 06:30:28 +0000635 Excluded []uint32) ([]byte, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400636 /*
637 Format resource as json.
638 :param pon_intf_id: OLT PON interface id
639 :param start_idx: start index for id pool
640 :param end_idx: end index for id pool
divyadesaid26f6b12020-03-19 06:30:28 +0000641 :Id values to be Excluded from the pool
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400642 :return dictionary: resource formatted as map
643 */
644 // Format resource as json to be stored in backend store
645 Resource := make(map[string]interface{})
646 Resource[PON_INTF_ID] = IntfID
647 Resource[START_IDX] = StartIDx
648 Resource[END_IDX] = EndIDx
649 /*
650 Resource pool stored in backend store as binary string.
651 Tracking the resource allocation will be done by setting the bits \
652 in the byte array. The index set will be the resource number allocated.
653 */
654 var TSData *bitmap.Threadsafe
655 if TSData = bitmap.NewTS(int(EndIDx)); TSData == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000656 logger.Error(ctx, "Failed to create a bitmap")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400657 return nil, errors.New("Failed to create bitmap")
658 }
divyadesaid26f6b12020-03-19 06:30:28 +0000659 for _, excludedID := range Excluded {
660 if excludedID < StartIDx || excludedID > EndIDx {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000661 logger.Warnf(ctx, "Cannot reserve %d. It must be in the range of [%d, %d]", excludedID,
divyadesaid26f6b12020-03-19 06:30:28 +0000662 StartIDx, EndIDx)
663 continue
664 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000665 PONRMgr.reserveID(ctx, TSData, StartIDx, excludedID)
divyadesaid26f6b12020-03-19 06:30:28 +0000666 }
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400667 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 -0400668
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400669 Value, err := json.Marshal(Resource)
670 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000671 logger.Errorf(ctx, "Failed to marshall resource")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400672 return nil, err
673 }
674 return Value, err
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400675}
npujarec5762e2020-01-01 14:08:48 +0530676func (PONRMgr *PONResourceManager) GetResource(ctx context.Context, Path string) (map[string]interface{}, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400677 /*
678 Get resource from kv store.
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400679
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400680 :param path: path to get resource
681 :return: resource if resource present in kv store else None
682 */
683 //get resource from kv store
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400684
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400685 var Value []byte
686 Result := make(map[string]interface{})
687 var Str string
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400688
npujarec5762e2020-01-01 14:08:48 +0530689 Resource, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400690 if (err != nil) || (Resource == nil) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000691 logger.Debugf(ctx, "Resource unavailable at %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400692 return nil, err
693 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400694
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400695 Value, err = ToByte(Resource.Value)
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000696 if err != nil {
697 return nil, err
698 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400699
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400700 // decode resource fetched from backend store to dictionary
701 err = json.Unmarshal(Value, &Result)
702 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000703 logger.Error(ctx, "Failed to decode resource")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400704 return Result, err
705 }
706 /*
707 resource pool in backend store stored as binary string whereas to
708 access the pool to generate/release IDs it need to be converted
709 as BitArray
710 */
711 Str, err = ToString(Result[POOL])
712 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000713 logger.Error(ctx, "Failed to conver to kv pair to string")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400714 return Result, err
715 }
716 Decode64, _ := base64.StdEncoding.DecodeString(Str)
717 Result[POOL], err = ToByte(Decode64)
718 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000719 logger.Error(ctx, "Failed to convert resource pool to byte")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400720 return Result, err
721 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400722
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400723 return Result, err
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400724}
725
Neha Sharma96b7bf22020-06-15 10:37:32 +0000726func (PONRMgr *PONResourceManager) GetPath(ctx context.Context, IntfID uint32, ResourceType string) string {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400727 /*
728 Get path for given resource type.
729 :param pon_intf_id: OLT PON interface id
730 :param resource_type: String to identify type of resource
731 :return: path for given resource type
732 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400733
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400734 /*
735 Get the shared pool for the given resource type.
736 all the resource ranges and the shared resource maps are initialized during the init.
737 */
738 SharedPoolID := PONRMgr.PonResourceRanges[PONRMgr.SharedIdxByType[ResourceType]].(uint32)
739 if SharedPoolID != 0 {
740 IntfID = SharedPoolID
741 }
742 var Path string
743 if ResourceType == ONU_ID {
744 Path = fmt.Sprintf(ONU_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
745 } else if ResourceType == ALLOC_ID {
746 Path = fmt.Sprintf(ALLOC_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
747 } else if ResourceType == GEMPORT_ID {
748 Path = fmt.Sprintf(GEMPORT_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
749 } else if ResourceType == FLOW_ID {
750 Path = fmt.Sprintf(FLOW_ID_POOL_PATH, PONRMgr.DeviceID, IntfID)
751 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000752 logger.Error(ctx, "Invalid resource pool identifier")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400753 }
754 return Path
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400755}
756
npujarec5762e2020-01-01 14:08:48 +0530757func (PONRMgr *PONResourceManager) GetResourceID(ctx context.Context, IntfID uint32, ResourceType string, NumIDs uint32) ([]uint32, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400758 /*
759 Create alloc/gemport/onu/flow id for given OLT PON interface.
760 :param pon_intf_id: OLT PON interface id
761 :param resource_type: String to identify type of resource
762 :param num_of_id: required number of ids
763 :return list/uint32/None: list, uint32 or None if resource type is
764 alloc_id/gemport_id, onu_id or invalid type respectively
765 */
Matteo Scandolo84585372021-03-18 14:21:22 -0700766
767 logger.Debugw(ctx, "getting-resource-id", log.Fields{
768 "intf-id": IntfID,
769 "resource-type": ResourceType,
770 "num": NumIDs,
771 })
772
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400773 if NumIDs < 1 {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000774 logger.Error(ctx, "Invalid number of resources requested")
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000775 return nil, fmt.Errorf("Invalid number of resources requested %d", NumIDs)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400776 }
777 // delegate to the master instance if sharing enabled across instances
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400778
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400779 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
780 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujarec5762e2020-01-01 14:08:48 +0530781 return SharedResourceMgr.GetResourceID(ctx, IntfID, ResourceType, NumIDs)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400782 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000783 logger.Debugf(ctx, "Fetching resource from %s rsrc mgr for resource %s", PONRMgr.Globalorlocal, ResourceType)
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400784
Neha Sharma96b7bf22020-06-15 10:37:32 +0000785 Path := PONRMgr.GetPath(ctx, IntfID, ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400786 if Path == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000787 logger.Errorf(ctx, "Failed to get path for resource type %s", ResourceType)
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000788 return nil, fmt.Errorf("Failed to get path for resource type %s", ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400789 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000790 logger.Debugf(ctx, "Get resource for type %s on path %s", ResourceType, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400791 var Result []uint32
792 var NextID uint32
npujarec5762e2020-01-01 14:08:48 +0530793 Resource, err := PONRMgr.GetResource(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400794 if (err == nil) && (ResourceType == ONU_ID) || (ResourceType == FLOW_ID) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000795 if NextID, err = PONRMgr.GenerateNextID(ctx, Resource); err != nil {
796 logger.Error(ctx, "Failed to Generate ID")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400797 return Result, err
798 }
799 Result = append(Result, NextID)
800 } else if (err == nil) && ((ResourceType == GEMPORT_ID) || (ResourceType == ALLOC_ID)) {
801 if NumIDs == 1 {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000802 if NextID, err = PONRMgr.GenerateNextID(ctx, Resource); err != nil {
803 logger.Error(ctx, "Failed to Generate ID")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400804 return Result, err
805 }
806 Result = append(Result, NextID)
807 } else {
808 for NumIDs > 0 {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000809 if NextID, err = PONRMgr.GenerateNextID(ctx, Resource); err != nil {
810 logger.Error(ctx, "Failed to Generate ID")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400811 return Result, err
812 }
813 Result = append(Result, NextID)
814 NumIDs--
815 }
816 }
817 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000818 logger.Error(ctx, "get resource failed")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400819 return Result, err
820 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400821
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400822 //Update resource in kv store
npujarec5762e2020-01-01 14:08:48 +0530823 if PONRMgr.UpdateResource(ctx, Path, Resource) != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000824 logger.Errorf(ctx, "Failed to update resource %s", Path)
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000825 return nil, fmt.Errorf("Failed to update resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400826 }
827 return Result, nil
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400828}
829
830func checkValidResourceType(ResourceType string) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400831 KnownResourceTypes := []string{ONU_ID, ALLOC_ID, GEMPORT_ID, FLOW_ID}
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400832
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400833 for _, v := range KnownResourceTypes {
834 if v == ResourceType {
835 return true
836 }
837 }
838 return false
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400839}
840
Matteo Scandolo84585372021-03-18 14:21:22 -0700841func (PONRMgr *PONResourceManager) FreeResourceID(ctx context.Context, IntfID uint32, ResourceType string, ReleaseContent []uint32) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400842 /*
Matteo Scandolo84585372021-03-18 14:21:22 -0700843 Release alloc/gemport/onu/flow id for given OLT PON interface.
844 :param pon_intf_id: OLT PON interface id
845 :param resource_type: String to identify type of resource
846 :param release_content: required number of ids
847 :return boolean: True if all IDs in given release_content release else False
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400848 */
Matteo Scandolo84585372021-03-18 14:21:22 -0700849
850 logger.Debugw(ctx, "freeing-resource-id", log.Fields{
851 "intf-id": IntfID,
852 "resource-type": ResourceType,
853 "release-content": ReleaseContent,
854 })
855
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000856 if !checkValidResourceType(ResourceType) {
Matteo Scandolo84585372021-03-18 14:21:22 -0700857 err := fmt.Errorf("Invalid resource type: %s", ResourceType)
858 logger.Error(ctx, err.Error())
859 return err
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400860 }
861 if ReleaseContent == nil {
Matteo Scandolo84585372021-03-18 14:21:22 -0700862 err := fmt.Errorf("Nothing to release")
863 logger.Debug(ctx, err.Error())
864 return err
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400865 }
866 // delegate to the master instance if sharing enabled across instances
867 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
868 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujarec5762e2020-01-01 14:08:48 +0530869 return SharedResourceMgr.FreeResourceID(ctx, IntfID, ResourceType, ReleaseContent)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400870 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000871 Path := PONRMgr.GetPath(ctx, IntfID, ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400872 if Path == "" {
Matteo Scandolo84585372021-03-18 14:21:22 -0700873 err := fmt.Errorf("Failed to get path for IntfId %d and ResourceType %s", IntfID, ResourceType)
874 logger.Error(ctx, err.Error())
875 return err
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400876 }
npujarec5762e2020-01-01 14:08:48 +0530877 Resource, err := PONRMgr.GetResource(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400878 if err != nil {
Matteo Scandolo84585372021-03-18 14:21:22 -0700879 logger.Error(ctx, err.Error())
880 return err
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400881 }
882 for _, Val := range ReleaseContent {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000883 PONRMgr.ReleaseID(ctx, Resource, Val)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400884 }
npujarec5762e2020-01-01 14:08:48 +0530885 if PONRMgr.UpdateResource(ctx, Path, Resource) != nil {
Matteo Scandolo84585372021-03-18 14:21:22 -0700886 err := fmt.Errorf("Free resource for %s failed", Path)
887 logger.Errorf(ctx, err.Error())
888 return err
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400889 }
Matteo Scandolo84585372021-03-18 14:21:22 -0700890 return nil
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400891}
892
npujarec5762e2020-01-01 14:08:48 +0530893func (PONRMgr *PONResourceManager) UpdateResource(ctx context.Context, Path string, Resource map[string]interface{}) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400894 /*
895 Update resource in resource kv store.
896 :param path: path to update resource
897 :param resource: resource need to be updated
898 :return boolean: True if resource updated in kv store else False
899 */
900 // TODO resource[POOL] = resource[POOL].bin
901 Value, err := json.Marshal(Resource)
902 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000903 logger.Error(ctx, "failed to Marshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400904 return err
905 }
npujarec5762e2020-01-01 14:08:48 +0530906 err = PONRMgr.KVStore.Put(ctx, Path, Value)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400907 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000908 logger.Error(ctx, "failed to put data to kv store %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400909 return err
910 }
911 return nil
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400912}
913
npujarec5762e2020-01-01 14:08:48 +0530914func (PONRMgr *PONResourceManager) ClearResourceIDPool(ctx context.Context, contIntfID uint32, ResourceType string) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400915 /*
916 Clear Resource Pool for a given Resource Type on a given PON Port.
917 :return boolean: True if removed else False
918 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400919
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400920 // delegate to the master instance if sharing enabled across instances
921 SharedResourceMgr := PONRMgr.SharedResourceMgrs[PONRMgr.SharedIdxByType[ResourceType]]
922 if SharedResourceMgr != nil && PONRMgr != SharedResourceMgr {
npujarec5762e2020-01-01 14:08:48 +0530923 return SharedResourceMgr.ClearResourceIDPool(ctx, contIntfID, ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400924 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000925 Path := PONRMgr.GetPath(ctx, contIntfID, ResourceType)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400926 if Path == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000927 logger.Error(ctx, "Failed to get path")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400928 return false
929 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400930
npujarec5762e2020-01-01 14:08:48 +0530931 if err := PONRMgr.KVStore.Delete(ctx, Path); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000932 logger.Errorf(ctx, "Failed to delete resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400933 return false
934 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000935 logger.Debugf(ctx, "Cleared resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400936 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400937}
938
npujarec5762e2020-01-01 14:08:48 +0530939func (PONRMgr PONResourceManager) InitResourceMap(ctx context.Context, PONIntfONUID string) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400940 /*
941 Initialize resource map
942 :param pon_intf_onu_id: reference of PON interface id and onu id
943 */
944 // initialize pon_intf_onu_id tuple to alloc_ids map
945 AllocIDPath := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
946 var AllocIDs []byte
npujarec5762e2020-01-01 14:08:48 +0530947 Result := PONRMgr.KVStore.Put(ctx, AllocIDPath, AllocIDs)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400948 if Result != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000949 logger.Error(ctx, "Failed to update the KV store")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400950 return
951 }
952 // initialize pon_intf_onu_id tuple to gemport_ids map
953 GEMPortIDPath := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
954 var GEMPortIDs []byte
npujarec5762e2020-01-01 14:08:48 +0530955 Result = PONRMgr.KVStore.Put(ctx, GEMPortIDPath, GEMPortIDs)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400956 if Result != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000957 logger.Error(ctx, "Failed to update the KV store")
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400958 return
959 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400960}
961
npujarec5762e2020-01-01 14:08:48 +0530962func (PONRMgr PONResourceManager) RemoveResourceMap(ctx context.Context, PONIntfONUID string) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400963 /*
964 Remove resource map
965 :param pon_intf_onu_id: reference of PON interface id and onu id
966 */
967 // remove pon_intf_onu_id tuple to alloc_ids map
968 var err error
969 AllocIDPath := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujarec5762e2020-01-01 14:08:48 +0530970 if err = PONRMgr.KVStore.Delete(ctx, AllocIDPath); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000971 logger.Errorf(ctx, "Failed to remove resource %s", AllocIDPath)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400972 return false
973 }
974 // remove pon_intf_onu_id tuple to gemport_ids map
975 GEMPortIDPath := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujarec5762e2020-01-01 14:08:48 +0530976 err = PONRMgr.KVStore.Delete(ctx, GEMPortIDPath)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400977 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000978 logger.Errorf(ctx, "Failed to remove resource %s", GEMPortIDPath)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400979 return false
980 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400981
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400982 FlowIDPath := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, PONIntfONUID)
npujarec5762e2020-01-01 14:08:48 +0530983 if FlowIDs, err := PONRMgr.KVStore.List(ctx, FlowIDPath); err != nil {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400984 for _, Flow := range FlowIDs {
985 FlowIDInfoPath := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, PONIntfONUID, Flow.Value)
npujarec5762e2020-01-01 14:08:48 +0530986 if err = PONRMgr.KVStore.Delete(ctx, FlowIDInfoPath); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000987 logger.Errorf(ctx, "Failed to remove resource %s", FlowIDInfoPath)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400988 return false
989 }
990 }
991 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400992
npujarec5762e2020-01-01 14:08:48 +0530993 if err = PONRMgr.KVStore.Delete(ctx, FlowIDPath); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000994 logger.Errorf(ctx, "Failed to remove resource %s", FlowIDPath)
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400995 return false
996 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400997
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400998 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400999}
1000
npujarec5762e2020-01-01 14:08:48 +05301001func (PONRMgr *PONResourceManager) GetCurrentAllocIDForOnu(ctx context.Context, IntfONUID string) []uint32 {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001002 /*
1003 Get currently configured alloc ids for given pon_intf_onu_id
1004 :param pon_intf_onu_id: reference of PON interface id and onu id
1005 :return list: List of alloc_ids if available, else None
1006 */
1007 Path := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001008
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001009 var Data []uint32
npujarec5762e2020-01-01 14:08:48 +05301010 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001011 if err == nil {
1012 if Value != nil {
1013 Val, err := ToByte(Value.Value)
1014 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001015 logger.Errorw(ctx, "Failed to convert into byte array", log.Fields{"error": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001016 return Data
1017 }
1018 if err = json.Unmarshal(Val, &Data); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001019 logger.Error(ctx, "Failed to unmarshal", log.Fields{"error": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001020 return Data
1021 }
1022 }
1023 }
1024 return Data
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001025}
1026
npujarec5762e2020-01-01 14:08:48 +05301027func (PONRMgr *PONResourceManager) GetCurrentGEMPortIDsForOnu(ctx context.Context, IntfONUID string) []uint32 {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001028 /*
1029 Get currently configured gemport ids for given pon_intf_onu_id
1030 :param pon_intf_onu_id: reference of PON interface id and onu id
1031 :return list: List of gemport IDs if available, else None
1032 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001033
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001034 Path := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001035 logger.Debugf(ctx, "Getting current gemports for %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001036 var Data []uint32
npujarec5762e2020-01-01 14:08:48 +05301037 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001038 if err == nil {
1039 if Value != nil {
1040 Val, _ := ToByte(Value.Value)
1041 if err = json.Unmarshal(Val, &Data); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001042 logger.Errorw(ctx, "Failed to unmarshal", log.Fields{"error": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001043 return Data
1044 }
1045 }
1046 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001047 logger.Errorf(ctx, "Failed to get data from kvstore for %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001048 }
1049 return Data
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001050}
1051
npujarec5762e2020-01-01 14:08:48 +05301052func (PONRMgr *PONResourceManager) GetCurrentFlowIDsForOnu(ctx context.Context, IntfONUID string) []uint32 {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001053 /*
1054 Get currently configured flow ids for given pon_intf_onu_id
1055 :param pon_intf_onu_id: reference of PON interface id and onu id
1056 :return list: List of Flow IDs if available, else None
1057 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001058
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001059 Path := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001060
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001061 var Data []uint32
npujarec5762e2020-01-01 14:08:48 +05301062 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001063 if err == nil {
1064 if Value != nil {
1065 Val, _ := ToByte(Value.Value)
1066 if err = json.Unmarshal(Val, &Data); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001067 logger.Error(ctx, "Failed to unmarshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001068 return Data
1069 }
1070 }
1071 }
1072 return Data
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001073}
1074
npujarec5762e2020-01-01 14:08:48 +05301075func (PONRMgr *PONResourceManager) GetFlowIDInfo(ctx context.Context, IntfONUID string, FlowID uint32, Data interface{}) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001076 /*
1077 Get flow details configured for the ONU.
1078 :param pon_intf_onu_id: reference of PON interface id and onu id
1079 :param flow_id: Flow Id reference
1080 :param Data: Result
1081 :return error: nil if no error in getting from KV store
1082 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001083
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001084 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001085
npujarec5762e2020-01-01 14:08:48 +05301086 Value, err := PONRMgr.KVStore.Get(ctx, Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001087 if err == nil {
1088 if Value != nil {
1089 Val, err := ToByte(Value.Value)
1090 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001091 logger.Errorw(ctx, "Failed to convert flowinfo into byte array", log.Fields{"error": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001092 return err
1093 }
1094 if err = json.Unmarshal(Val, Data); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001095 logger.Errorw(ctx, "Failed to unmarshal", log.Fields{"error": err})
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001096 return err
1097 }
1098 }
1099 }
1100 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001101}
1102
npujarec5762e2020-01-01 14:08:48 +05301103func (PONRMgr *PONResourceManager) RemoveFlowIDInfo(ctx context.Context, IntfONUID string, FlowID uint32) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001104 /*
1105 Get flow_id details configured for the ONU.
1106 :param pon_intf_onu_id: reference of PON interface id and onu id
1107 :param flow_id: Flow Id reference
1108 */
1109 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001110
npujarec5762e2020-01-01 14:08:48 +05301111 if err := PONRMgr.KVStore.Delete(ctx, Path); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001112 logger.Errorf(ctx, "Falied to remove resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001113 return false
1114 }
1115 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001116}
1117
serkant.uluderya7b8211e2021-02-24 16:39:18 +03001118func (PONRMgr *PONResourceManager) RemoveAllFlowIDInfo(ctx context.Context, IntfONUID string) bool {
1119 /*
1120 Remove flow_id_info details configured for the ONU.
1121 :param pon_intf_onu_id: reference of PON interface id and onu id
1122 */
1123 Path := fmt.Sprintf(FLOW_ID_INFO_PATH_INTF_ONU_PREFIX, PONRMgr.DeviceID, IntfONUID)
1124
1125 if err := PONRMgr.KVStore.DeleteWithPrefix(ctx, Path); err != nil {
1126 logger.Errorf(ctx, "Falied to remove resource %s", Path)
1127 return false
1128 }
1129 return true
1130}
1131
npujarec5762e2020-01-01 14:08:48 +05301132func (PONRMgr *PONResourceManager) UpdateAllocIdsForOnu(ctx context.Context, IntfONUID string, AllocIDs []uint32) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001133 /*
1134 Update currently configured alloc ids for given pon_intf_onu_id
1135 :param pon_intf_onu_id: reference of PON interface id and onu id
1136 :param alloc_ids: list of alloc ids
1137 */
1138 var Value []byte
1139 var err error
1140 Path := fmt.Sprintf(ALLOC_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
1141 Value, err = json.Marshal(AllocIDs)
1142 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001143 logger.Error(ctx, "failed to Marshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001144 return err
1145 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001146
npujarec5762e2020-01-01 14:08:48 +05301147 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001148 logger.Errorf(ctx, "Failed to update resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001149 return err
1150 }
1151 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001152}
1153
npujarec5762e2020-01-01 14:08:48 +05301154func (PONRMgr *PONResourceManager) UpdateGEMPortIDsForOnu(ctx context.Context, IntfONUID string, GEMPortIDs []uint32) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001155 /*
1156 Update currently configured gemport ids for given pon_intf_onu_id
1157 :param pon_intf_onu_id: reference of PON interface id and onu id
1158 :param gemport_ids: list of gem port ids
1159 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001160
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001161 var Value []byte
1162 var err error
1163 Path := fmt.Sprintf(GEMPORT_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001164 logger.Debugf(ctx, "Updating gemport ids for %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001165 Value, err = json.Marshal(GEMPortIDs)
1166 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001167 logger.Error(ctx, "failed to Marshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001168 return err
1169 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001170
npujarec5762e2020-01-01 14:08:48 +05301171 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001172 logger.Errorf(ctx, "Failed to update resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001173 return err
1174 }
1175 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001176}
1177
1178func checkForFlowIDInList(FlowIDList []uint32, FlowID uint32) (bool, uint32) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001179 /*
1180 Check for a flow id in a given list of flow IDs.
1181 :param FLowIDList: List of Flow IDs
1182 :param FlowID: Flowd to check in the list
1183 : return true and the index if present false otherwise.
1184 */
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001185
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001186 for idx := range FlowIDList {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001187 if FlowID == FlowIDList[idx] {
1188 return true, uint32(idx)
1189 }
1190 }
1191 return false, 0
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001192}
1193
npujarec5762e2020-01-01 14:08:48 +05301194func (PONRMgr *PONResourceManager) UpdateFlowIDForOnu(ctx context.Context, IntfONUID string, FlowID uint32, Add bool) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001195 /*
1196 Update the flow_id list of the ONU (add or remove flow_id from the list)
1197 :param pon_intf_onu_id: reference of PON interface id and onu id
1198 :param flow_id: flow ID
1199 :param add: Boolean flag to indicate whether the flow_id should be
1200 added or removed from the list. Defaults to adding the flow.
1201 */
1202 var Value []byte
1203 var err error
1204 var RetVal bool
1205 var IDx uint32
1206 Path := fmt.Sprintf(FLOW_ID_RESOURCE_MAP_PATH, PONRMgr.DeviceID, IntfONUID)
npujarec5762e2020-01-01 14:08:48 +05301207 FlowIDs := PONRMgr.GetCurrentFlowIDsForOnu(ctx, IntfONUID)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001208
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001209 if Add {
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001210 if RetVal, _ = checkForFlowIDInList(FlowIDs, FlowID); RetVal {
1211 return nil
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001212 }
1213 FlowIDs = append(FlowIDs, FlowID)
1214 } else {
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001215 if RetVal, IDx = checkForFlowIDInList(FlowIDs, FlowID); !RetVal {
1216 return nil
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001217 }
1218 // delete the index and shift
1219 FlowIDs = append(FlowIDs[:IDx], FlowIDs[IDx+1:]...)
1220 }
1221 Value, err = json.Marshal(FlowIDs)
1222 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001223 logger.Error(ctx, "Failed to Marshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001224 return err
1225 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001226
npujarec5762e2020-01-01 14:08:48 +05301227 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001228 logger.Errorf(ctx, "Failed to update resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001229 return err
1230 }
1231 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001232}
1233
npujarec5762e2020-01-01 14:08:48 +05301234func (PONRMgr *PONResourceManager) UpdateFlowIDInfoForOnu(ctx context.Context, IntfONUID string, FlowID uint32, FlowData interface{}) error {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001235 /*
1236 Update any metadata associated with the flow_id. The flow_data could be json
1237 or any of other data structure. The resource manager doesnt care
1238 :param pon_intf_onu_id: reference of PON interface id and onu id
1239 :param flow_id: Flow ID
1240 :param flow_data: Flow data blob
1241 */
1242 var Value []byte
1243 var err error
1244 Path := fmt.Sprintf(FLOW_ID_INFO_PATH, PONRMgr.DeviceID, IntfONUID, FlowID)
1245 Value, err = json.Marshal(FlowData)
1246 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001247 logger.Error(ctx, "failed to Marshal")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001248 return err
1249 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001250
npujarec5762e2020-01-01 14:08:48 +05301251 if err = PONRMgr.KVStore.Put(ctx, Path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001252 logger.Errorf(ctx, "Failed to update resource %s", Path)
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001253 return err
1254 }
1255 return err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001256}
1257
Neha Sharma96b7bf22020-06-15 10:37:32 +00001258func (PONRMgr *PONResourceManager) GenerateNextID(ctx context.Context, Resource map[string]interface{}) (uint32, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001259 /*
1260 Generate unique id having OFFSET as start
1261 :param resource: resource used to generate ID
1262 :return uint32: generated id
1263 */
1264 ByteArray, err := ToByte(Resource[POOL])
1265 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001266 logger.Error(ctx, "Failed to convert resource to byte array")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001267 return 0, err
1268 }
1269 Data := bitmap.TSFromData(ByteArray, false)
1270 if Data == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001271 logger.Error(ctx, "Failed to get data from byte array")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001272 return 0, errors.New("Failed to get data from byte array")
1273 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001274
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001275 Len := Data.Len()
1276 var Idx int
1277 for Idx = 0; Idx < Len; Idx++ {
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001278 if !Data.Get(Idx) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001279 break
1280 }
1281 }
1282 Data.Set(Idx, true)
1283 res := uint32(Resource[START_IDX].(float64))
1284 Resource[POOL] = Data.Data(false)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001285 logger.Debugf(ctx, "Generated ID for %d", (uint32(Idx) + res))
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001286 return (uint32(Idx) + res), err
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001287}
1288
Neha Sharma96b7bf22020-06-15 10:37:32 +00001289func (PONRMgr *PONResourceManager) ReleaseID(ctx context.Context, Resource map[string]interface{}, Id uint32) bool {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001290 /*
1291 Release unique id having OFFSET as start index.
1292 :param resource: resource used to release ID
1293 :param unique_id: id need to be released
1294 */
1295 ByteArray, err := ToByte(Resource[POOL])
1296 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001297 logger.Error(ctx, "Failed to convert resource to byte array")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001298 return false
1299 }
1300 Data := bitmap.TSFromData(ByteArray, false)
1301 if Data == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001302 logger.Error(ctx, "Failed to get resource pool")
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001303 return false
1304 }
Rohan Agrawal02f784d2020-02-14 09:34:02 +00001305 Idx := Id - uint32(Resource[START_IDX].(float64))
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001306 Data.Set(int(Idx), false)
1307 Resource[POOL] = Data.Data(false)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001308
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001309 return true
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001310}
1311
divyadesaid26f6b12020-03-19 06:30:28 +00001312/* Reserves a unique id in the specified resource pool.
1313:param Resource: resource used to reserve ID
1314:param Id: ID to be reserved
1315*/
Neha Sharma96b7bf22020-06-15 10:37:32 +00001316func (PONRMgr *PONResourceManager) reserveID(ctx context.Context, TSData *bitmap.Threadsafe, StartIndex uint32, Id uint32) bool {
divyadesaid26f6b12020-03-19 06:30:28 +00001317 Data := bitmap.TSFromData(TSData.Data(false), false)
1318 if Data == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001319 logger.Error(ctx, "Failed to get resource pool")
divyadesaid26f6b12020-03-19 06:30:28 +00001320 return false
1321 }
1322 Idx := Id - StartIndex
1323 Data.Set(int(Idx), true)
1324 return true
1325}
1326
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001327func (PONRMgr *PONResourceManager) GetTechnology() string {
1328 return PONRMgr.Technology
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001329}
1330
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001331func (PONRMgr *PONResourceManager) GetResourceTypeAllocID() string {
1332 return ALLOC_ID
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001333}
1334
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001335func (PONRMgr *PONResourceManager) GetResourceTypeGemPortID() string {
1336 return GEMPORT_ID
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001337}
1338
Matteo Scandolo84585372021-03-18 14:21:22 -07001339func (PONRMgr *PONResourceManager) GetResourceTypeOnuID() string {
1340 return ONU_ID
1341}
1342
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001343// ToByte converts an interface value to a []byte. The interface should either be of
1344// a string type or []byte. Otherwise, an error is returned.
1345func ToByte(value interface{}) ([]byte, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001346 switch t := value.(type) {
1347 case []byte:
1348 return value.([]byte), nil
1349 case string:
1350 return []byte(value.(string)), nil
1351 default:
1352 return nil, fmt.Errorf("unexpected-type-%T", t)
1353 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001354}
1355
1356// ToString converts an interface value to a string. The interface should either be of
1357// a string type or []byte. Otherwise, an error is returned.
1358func ToString(value interface{}) (string, error) {
Matt Jeanneret384d8c92019-05-06 14:27:31 -04001359 switch t := value.(type) {
1360 case []byte:
1361 return string(value.([]byte)), nil
1362 case string:
1363 return value.(string), nil
1364 default:
1365 return "", fmt.Errorf("unexpected-type-%T", t)
1366 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001367}