blob: c3a9993b9a6a08403ad717a75f4e33ba19642f15 [file] [log] [blame]
Girish Gowdruab836e92018-10-25 01:17:57 -07001#
2# Copyright 2018 the original author or authors.
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#
16import json
17import ast
18from collections import namedtuple
19import structlog
20from enum import Enum
21
22from voltha.core.config.config_backend import ConsulStore
23from voltha.core.config.config_backend import EtcdStore
24from voltha.registry import registry
25from voltha.adapters.openolt.protos import openolt_pb2
26
27
28# logger
29log = structlog.get_logger()
30
31DEFAULT_TECH_PROFILE_TABLE_ID = 64
32
33# Enums used while creating TechProfileInstance
34Direction = Enum('Direction', ['UPSTREAM', 'DOWNSTREAM', 'BIDIRECTIONAL'],
35 start=0)
36SchedulingPolicy = Enum('SchedulingPolicy',
37 ['WRR', 'StrictPriority', 'Hybrid'], start=0)
38AdditionalBW = Enum('AdditionalBW', ['None', 'NA', 'BestEffort', 'Auto'],
39 start=0)
40DiscardPolicy = Enum('DiscardPolicy',
41 ['TailDrop', 'WTailDrop', 'RED', 'WRED'], start=0)
42InferredAdditionBWIndication = Enum('InferredAdditionBWIndication',
43 ['None', 'NoneAssured', 'BestEffort'],
44 start=0)
45
46
47class InstanceControl(object):
48 # Default value constants
49 ONU_DEFAULT_INSTANCE = 'multi-instance'
50 UNI_DEFAULT_INSTANCE = 'single-instance'
51 DEFAULT_NUM_GEM_PORTS = 1
52 DEFAULT_GEM_PAYLOAD_SIZE = 'auto'
53
54 def __init__(self, onu=ONU_DEFAULT_INSTANCE,
55 uni=UNI_DEFAULT_INSTANCE,
56 num_gem_ports=DEFAULT_NUM_GEM_PORTS,
57 max_gem_payload_size=DEFAULT_GEM_PAYLOAD_SIZE):
58 self.onu = onu
59 self.uni = uni
60 self.num_gem_ports = num_gem_ports
61 self.max_gem_payload_size = max_gem_payload_size
62
63
64class Scheduler(object):
65 # Default value constants
66 DEFAULT_ADDITIONAL_BW = 'auto'
67 DEFAULT_PRIORITY = 0
68 DEFAULT_WEIGHT = 0
69 DEFAULT_Q_SCHED_POLICY = 'hybrid'
70
71 def __init__(self, direction, additional_bw=DEFAULT_ADDITIONAL_BW,
72 priority=DEFAULT_PRIORITY,
73 weight=DEFAULT_WEIGHT,
74 q_sched_policy=DEFAULT_Q_SCHED_POLICY):
75 self.direction = direction
76 self.additional_bw = additional_bw
77 self.priority = priority
78 self.weight = weight
79 self.q_sched_policy = q_sched_policy
80
81
82class GemPortAttribute(object):
83 # Default value constants
84 DEFAULT_AES_ENCRYPTION = 'True'
85 DEFAULT_PRIORITY_Q = 0
86 DEFAULT_WEIGHT = 0
87 DEFAULT_MAX_Q_SIZE = 'auto'
88 DEFAULT_DISCARD_POLICY = DiscardPolicy.TailDrop.name
89
90 def __init__(self, pbit_map, discard_config,
91 aes_encryption=DEFAULT_AES_ENCRYPTION,
92 scheduling_policy=SchedulingPolicy.WRR.name,
93 priority_q=DEFAULT_PRIORITY_Q,
94 weight=DEFAULT_WEIGHT,
95 max_q_size=DEFAULT_MAX_Q_SIZE,
96 discard_policy=DiscardPolicy.TailDrop.name):
97 self.max_q_size = max_q_size
98 self.pbit_map = pbit_map
99 self.aes_encryption = aes_encryption
100 self.scheduling_policy = scheduling_policy
101 self.priority_q = priority_q
102 self.weight = weight
103 self.discard_policy = discard_policy
104 self.discard_config = discard_config
105
106
107class DiscardConfig(object):
108 # Default value constants
109 DEFAULT_MIN_THRESHOLD = 0
110 DEFAULT_MAX_THRESHOLD = 0
111 DEFAULT_MAX_PROBABILITY = 0
112
113 def __init__(self, min_threshold=DEFAULT_MIN_THRESHOLD,
114 max_threshold=DEFAULT_MAX_THRESHOLD,
115 max_probability=DEFAULT_MAX_PROBABILITY):
116 self.min_threshold = min_threshold
117 self.max_threshold = max_threshold
118 self.max_probability = max_probability
119
120
121class TechProfile(object):
122 # Constants used in default tech profile
123 DEFAULT_TECH_PROFILE_NAME = 'Default_1tcont_1gem_Profile'
124 DEFAULT_VERSION = 1.0
125 DEFAULT_GEMPORTS_COUNT = 1
126 pbits = ['0b11111111']
127
128 # Tech profile path prefix in kv store
129 KV_STORE_TECH_PROFILE_PATH_PREFIX = 'voltha/technology_profiles'
130
131 # Tech profile path in kv store
132 TECH_PROFILE_PATH = '{}/{}' # <technology>/<table_id>
133
134 # Tech profile instance path in kv store
135 # Format: <technology>/<table_id>/<uni_port_name>
136 TECH_PROFILE_INSTANCE_PATH = '{}/{}/{}'
137
138 # Tech-Profile JSON String Keys
139 NAME = 'name'
140 PROFILE_TYPE = 'profile_type'
141 VERSION = 'version'
142 NUM_GEM_PORTS = 'num_gem_ports'
143 INSTANCE_CONTROL = 'instance_control'
144 US_SCHEDULER = 'us_scheduler'
145 DS_SCHEDULER = 'ds_scheduler'
146 UPSTREAM_GEM_PORT_ATTRIBUTE_LIST = 'upstream_gem_port_attribute_list'
147 DOWNSTREAM_GEM_PORT_ATTRIBUTE_LIST = 'downstream_gem_port_attribute_list'
148 ONU = 'onu'
149 UNI = 'uni'
150 MAX_GEM_PAYLOAD_SIZE = 'max_gem_payload_size'
151 DIRECTION = 'direction'
152 ADDITIONAL_BW = 'additional_bw'
153 PRIORITY = 'priority'
154 Q_SCHED_POLICY = 'q_sched_policy'
155 WEIGHT = 'weight'
156 PBIT_MAP = 'pbit_map'
157 DISCARD_CONFIG = 'discard_config'
158 MAX_THRESHOLD = 'max_threshold'
159 MIN_THRESHOLD = 'min_threshold'
160 MAX_PROBABILITY = 'max_probability'
161 DISCARD_POLICY = 'discard_policy'
162 PRIORITY_Q = 'priority_q'
163 SCHEDULING_POLICY = 'scheduling_policy'
164 MAX_Q_SIZE = 'max_q_size'
165 AES_ENCRYPTION = 'aes_encryption'
166
167 def __init__(self, resource_mgr):
168 try:
169 self.args = registry('main').get_args()
170 self.resource_mgr = resource_mgr
171
172 if self.args.backend == 'etcd':
173 # KV store's IP Address and PORT
174 host, port = self.args.etcd.split(':', 1)
175 self._kv_store = EtcdStore(
176 host, port, TechProfile.
177 KV_STORE_TECH_PROFILE_PATH_PREFIX)
178 elif self.args.backend == 'consul':
179 # KV store's IP Address and PORT
180 host, port = self.args.consul.split(':', 1)
181 self._kv_store = ConsulStore(
182 host, port, TechProfile.
183 KV_STORE_TECH_PROFILE_PATH_PREFIX)
184
185 # self.tech_profile_instance_store = dict()
186 except Exception as e:
187 log.exception("exception-in-init")
188 raise Exception(e)
189
190 class DefaultTechProfile(object):
191 def __init__(self, name, **kwargs):
192 self.name = name
193 self.profile_type = kwargs[TechProfile.PROFILE_TYPE]
194 self.version = kwargs[TechProfile.VERSION]
195 self.num_gem_ports = kwargs[TechProfile.NUM_GEM_PORTS]
196 self.instance_control = kwargs[TechProfile.INSTANCE_CONTROL]
197 self.us_scheduler = kwargs[TechProfile.US_SCHEDULER]
198 self.ds_scheduler = kwargs[TechProfile.DS_SCHEDULER]
199 self.upstream_gem_port_attribute_list = kwargs[
200 TechProfile.UPSTREAM_GEM_PORT_ATTRIBUTE_LIST]
201 self.downstream_gem_port_attribute_list = kwargs[
202 TechProfile.DOWNSTREAM_GEM_PORT_ATTRIBUTE_LIST]
203
204 def to_json(self):
205 return json.dumps(self, default=lambda o: o.__dict__,
206 indent=4)
207
208 def get_tp_path(self, table_id, uni_port_name):
209 return TechProfile.TECH_PROFILE_INSTANCE_PATH.format(
210 self.resource_mgr.technology, table_id, uni_port_name)
211
212 def create_tech_profile_instance(self, table_id, uni_port_name, intf_id):
213 tech_profile_instance = None
214 try:
215 # Get tech profile from kv store
216 tech_profile = self._get_tech_profile_from_kv_store(table_id)
217 path = self.get_tp_path(table_id, uni_port_name)
218
219 if tech_profile is not None:
220 tech_profile = self._get_tech_profile(tech_profile)
221 log.debug(
222 "Created-tech-profile-instance-with-values-from-kvstore")
223 else:
224 tech_profile = self._default_tech_profile()
225 log.debug(
226 "Created-tech-profile-instance-with-default-values")
227
228 tech_profile_instance = TechProfileInstance(
229 uni_port_name, tech_profile, self.resource_mgr, intf_id)
230 self._add_tech_profile_instance(path,
231 tech_profile_instance.to_json())
232 except Exception as e:
233 log.exception("Create-tech-profile-instance-failed", exception=e)
234
235 return tech_profile_instance
236
237 def get_tech_profile_instance(self, table_id, uni_port_name):
238 # path to fetch tech profile instance json from kv store
239 path = TechProfile.TECH_PROFILE_INSTANCE_PATH.format(
240 self.resource_mgr.technology, table_id, uni_port_name)
241
242 try:
243 tech_profile_instance = self._kv_store[path]
244 log.debug("Tech-profile-instance-present-in-kvstore", path=path,
245 tech_profile_instance=tech_profile_instance)
246
247 # Parse JSON into an object with attributes corresponding to dict keys.
248 tech_profile_instance = json.loads(tech_profile_instance,
249 object_hook=lambda d:
250 namedtuple('tech_profile_instance',
251 d.keys())(*d.values()))
252 log.debug("Tech-profile-instance-after-json-to-object-conversion", path=path,
253 tech_profile_instance=tech_profile_instance)
254 return tech_profile_instance
255 except BaseException as e:
256 log.debug("Tech-profile-instance-not-present-in-kvstore",
257 path=path, tech_profile_instance=None, exception=e)
258 return None
259
260 def delete_tech_profile_instance(self, table_id, uni_port_name):
261 # path to delete tech profile instance json from kv store
262 path = TechProfile.TECH_PROFILE_INSTANCE_PATH.format(
263 self.resource_mgr.technology, table_id, uni_port_name)
264
265 try:
266 del self._kv_store[path]
267 log.debug("Delete-tech-profile-instance-success", path=path)
268 return True
269 except Exception as e:
270 log.debug("Delete-tech-profile-instance-failed", path=path,
271 exception=e)
272 return False
273
274 def _get_tech_profile_from_kv_store(self, table_id):
275 """
276 Get tech profile from kv store.
277
278 :param table_id: reference to get tech profile
279 :return: tech profile if present in kv store else None
280 """
281 # get tech profile from kv store
282 path = TechProfile.TECH_PROFILE_PATH.format(self.resource_mgr.technology,
283 table_id)
284 try:
285 tech_profile = self._kv_store[path]
286 if tech_profile != '':
287 log.debug("Get-tech-profile-success", tech_profile=tech_profile)
288 return json.loads(tech_profile)
289 # return ast.literal_eval(tech_profile)
290 except KeyError as e:
291 log.info("Get-tech-profile-failed", exception=e)
292 return None
293
294 def _default_tech_profile(self):
295 # Default tech profile
296 upstream_gem_port_attribute_list = list()
297 downstream_gem_port_attribute_list = list()
298 for pbit in TechProfile.pbits:
299 upstream_gem_port_attribute_list.append(
300 GemPortAttribute(pbit_map=pbit,
301 discard_config=DiscardConfig()))
302 downstream_gem_port_attribute_list.append(
303 GemPortAttribute(pbit_map=pbit,
304 discard_config=DiscardConfig()))
305
306 return TechProfile.DefaultTechProfile(
307 TechProfile.DEFAULT_TECH_PROFILE_NAME,
308 profile_type=self.resource_mgr.technology,
309 version=TechProfile.DEFAULT_VERSION,
310 num_gem_ports=TechProfile.DEFAULT_GEMPORTS_COUNT,
311 instance_control=InstanceControl(),
312 us_scheduler=Scheduler(direction=Direction.UPSTREAM.name),
313 ds_scheduler=Scheduler(direction=Direction.DOWNSTREAM.name),
314 upstream_gem_port_attribute_list=upstream_gem_port_attribute_list,
315 downstream_gem_port_attribute_list=
316 downstream_gem_port_attribute_list)
317
318 @staticmethod
319 def _get_tech_profile(tech_profile):
320 # Tech profile fetched from kv store
321 instance_control = tech_profile[TechProfile.INSTANCE_CONTROL]
322 instance_control = InstanceControl(
323 onu=instance_control[TechProfile.ONU],
324 uni=instance_control[TechProfile.UNI],
325 max_gem_payload_size=instance_control[
326 TechProfile.MAX_GEM_PAYLOAD_SIZE])
327
328 us_scheduler = tech_profile[TechProfile.US_SCHEDULER]
329 us_scheduler = Scheduler(direction=us_scheduler[TechProfile.DIRECTION],
330 additional_bw=us_scheduler[
331 TechProfile.ADDITIONAL_BW],
332 priority=us_scheduler[TechProfile.PRIORITY],
333 weight=us_scheduler[TechProfile.WEIGHT],
334 q_sched_policy=us_scheduler[
335 TechProfile.Q_SCHED_POLICY])
336 ds_scheduler = tech_profile[TechProfile.DS_SCHEDULER]
337 ds_scheduler = Scheduler(direction=ds_scheduler[TechProfile.DIRECTION],
338 additional_bw=ds_scheduler[
339 TechProfile.ADDITIONAL_BW],
340 priority=ds_scheduler[TechProfile.PRIORITY],
341 weight=ds_scheduler[TechProfile.WEIGHT],
342 q_sched_policy=ds_scheduler[
343 TechProfile.Q_SCHED_POLICY])
344
345 upstream_gem_port_attribute_list = list()
346 downstream_gem_port_attribute_list = list()
347 us_gemport_attr_list = tech_profile[
348 TechProfile.UPSTREAM_GEM_PORT_ATTRIBUTE_LIST]
349 for i in range(len(us_gemport_attr_list)):
350 upstream_gem_port_attribute_list.append(
351 GemPortAttribute(pbit_map=us_gemport_attr_list[i][TechProfile.PBIT_MAP],
352 discard_config=DiscardConfig(
353 max_threshold=
354 us_gemport_attr_list[i][TechProfile.DISCARD_CONFIG][
355 TechProfile.MAX_THRESHOLD],
356 min_threshold=
357 us_gemport_attr_list[i][TechProfile.DISCARD_CONFIG][
358 TechProfile.MIN_THRESHOLD],
359 max_probability=
360 us_gemport_attr_list[i][TechProfile.DISCARD_CONFIG][
361 TechProfile.MAX_PROBABILITY]),
362 discard_policy=us_gemport_attr_list[i][
363 TechProfile.DISCARD_POLICY],
364 priority_q=us_gemport_attr_list[i][
365 TechProfile.PRIORITY_Q],
366 weight=us_gemport_attr_list[i][TechProfile.WEIGHT],
367 scheduling_policy=us_gemport_attr_list[i][
368 TechProfile.SCHEDULING_POLICY],
369 max_q_size=us_gemport_attr_list[i][
370 TechProfile.MAX_Q_SIZE],
371 aes_encryption=us_gemport_attr_list[i][
372 TechProfile.AES_ENCRYPTION]))
373
374 ds_gemport_attr_list = tech_profile[
375 TechProfile.DOWNSTREAM_GEM_PORT_ATTRIBUTE_LIST]
376 for i in range(len(ds_gemport_attr_list)):
377 downstream_gem_port_attribute_list.append(
378 GemPortAttribute(pbit_map=ds_gemport_attr_list[i][TechProfile.PBIT_MAP],
379 discard_config=DiscardConfig(
380 max_threshold=
381 ds_gemport_attr_list[i][TechProfile.DISCARD_CONFIG][
382 TechProfile.MAX_THRESHOLD],
383 min_threshold=
384 ds_gemport_attr_list[i][TechProfile.DISCARD_CONFIG][
385 TechProfile.MIN_THRESHOLD],
386 max_probability=
387 ds_gemport_attr_list[i][TechProfile.DISCARD_CONFIG][
388 TechProfile.MAX_PROBABILITY]),
389 discard_policy=ds_gemport_attr_list[i][
390 TechProfile.DISCARD_POLICY],
391 priority_q=ds_gemport_attr_list[i][
392 TechProfile.PRIORITY_Q],
393 weight=ds_gemport_attr_list[i][TechProfile.WEIGHT],
394 scheduling_policy=ds_gemport_attr_list[i][
395 TechProfile.SCHEDULING_POLICY],
396 max_q_size=ds_gemport_attr_list[i][
397 TechProfile.MAX_Q_SIZE],
398 aes_encryption=ds_gemport_attr_list[i][
399 TechProfile.AES_ENCRYPTION]))
400
401 return TechProfile.DefaultTechProfile(
402 tech_profile[TechProfile.NAME],
403 profile_type=tech_profile[TechProfile.PROFILE_TYPE],
404 version=tech_profile[TechProfile.VERSION],
405 num_gem_ports=tech_profile[TechProfile.NUM_GEM_PORTS],
406 instance_control=instance_control,
407 us_scheduler=us_scheduler,
408 ds_scheduler=ds_scheduler,
409 upstream_gem_port_attribute_list=upstream_gem_port_attribute_list,
410 downstream_gem_port_attribute_list=
411 downstream_gem_port_attribute_list)
412
413 def _add_tech_profile_instance(self, path, tech_profile_instance):
414 """
415 Add tech profile to kv store.
416
417 :param path: path to add tech profile
418 :param tech_profile_instance: tech profile instance need to be added
419 """
420 try:
421 self._kv_store[path] = str(tech_profile_instance)
422 log.debug("Add-tech-profile-instance-success", path=path,
423 tech_profile_instance=tech_profile_instance)
424 return True
425 except BaseException as e:
426 log.exception("Add-tech-profile-instance-failed", path=path,
427 tech_profile_instance=tech_profile_instance,
428 exception=e)
429 return False
430
431 @staticmethod
432 def get_us_scheduler(tech_profile_instance):
433 # upstream scheduler
434 us_scheduler = openolt_pb2.Scheduler(
435 direction=TechProfile.get_parameter(
436 'direction', tech_profile_instance.us_scheduler.
437 direction),
438 additional_bw=TechProfile.get_parameter(
439 'additional_bw', tech_profile_instance.
440 us_scheduler.additional_bw),
441 priority=tech_profile_instance.us_scheduler.priority,
442 weight=tech_profile_instance.us_scheduler.weight,
443 sched_policy=TechProfile.get_parameter(
444 'sched_policy', tech_profile_instance.
445 us_scheduler.q_sched_policy))
446
447 return us_scheduler
448
449 @staticmethod
450 def get_ds_scheduler(tech_profile_instance):
451 ds_scheduler = openolt_pb2.Scheduler(
452 direction=TechProfile.get_parameter(
453 'direction', tech_profile_instance.ds_scheduler.
454 direction),
455 additional_bw=TechProfile.get_parameter(
456 'additional_bw', tech_profile_instance.
457 ds_scheduler.additional_bw),
458 priority=tech_profile_instance.ds_scheduler.priority,
459 weight=tech_profile_instance.ds_scheduler.weight,
460 sched_policy=TechProfile.get_parameter(
461 'sched_policy', tech_profile_instance.ds_scheduler.
462 q_sched_policy))
463
464 return ds_scheduler
465
466 @staticmethod
467 def get_tconts(tech_profile_instance, us_scheduler=None, ds_scheduler=None):
468 if us_scheduler is None:
469 us_scheduler = TechProfile.get_us_scheduler(tech_profile_instance)
470 if ds_scheduler is None:
471 ds_scheduler = TechProfile.get_ds_scheduler(tech_profile_instance)
472
473 tconts = [openolt_pb2.Tcont(direction=TechProfile.get_parameter(
474 'direction',
475 tech_profile_instance.
476 us_scheduler.direction),
477 alloc_id=tech_profile_instance.
478 us_scheduler.alloc_id,
479 scheduler=us_scheduler),
480 openolt_pb2.Tcont(direction=TechProfile.get_parameter(
481 'direction',
482 tech_profile_instance.
483 ds_scheduler.direction),
484 alloc_id=tech_profile_instance.
485 ds_scheduler.alloc_id,
486 scheduler=ds_scheduler)]
487
488 return tconts
489
490 @staticmethod
491 def get_parameter(param_type, param_value):
492 parameter = None
493 try:
494 if param_type == 'direction':
495 for direction in openolt_pb2.Direction.keys():
496 if param_value == direction:
497 parameter = direction
498 elif param_type == 'discard_policy':
499 for discard_policy in openolt_pb2.DiscardPolicy.keys():
500 if param_value == discard_policy:
501 parameter = discard_policy
502 elif param_type == 'sched_policy':
503 for sched_policy in openolt_pb2.SchedulingPolicy.keys():
504 if param_value == sched_policy:
505 parameter = sched_policy
506 elif param_type == 'additional_bw':
507 for bw_component in openolt_pb2.AdditionalBW.keys():
508 if param_value == bw_component:
509 parameter = bw_component
510 except BaseException as e:
511 log.exception(exception=e)
512 return parameter
513
514
515class TechProfileInstance(object):
516 def __init__(self, subscriber_identifier, tech_profile, resource_mgr,
517 intf_id, num_of_tconts=1):
518 if tech_profile is not None:
519 self.subscriber_identifier = subscriber_identifier
520 self.num_of_tconts = num_of_tconts
521 self.num_of_gem_ports = tech_profile.num_gem_ports
522 self.name = tech_profile.name
523 self.profile_type = tech_profile.profile_type
524 self.version = tech_profile.version
525 self.instance_control = tech_profile.instance_control
526
527 # TODO: Fixed num_of_tconts to 1 per TP Instance.
528 # This may change in future
529 assert (num_of_tconts == 1)
530 # Get alloc id and gemport id using resource manager
531 alloc_id = resource_mgr.get_resource_id(intf_id,
532 'ALLOC_ID',
533 num_of_tconts)
534 gem_ports = resource_mgr.get_resource_id(intf_id,
535 'GEMPORT_ID',
536 self.num_of_gem_ports)
537
538 gemport_list = list()
539 if isinstance(gem_ports, int):
540 gemport_list.append(gem_ports)
541 elif isinstance(gem_ports, list):
542 for gem in gem_ports:
543 gemport_list.append(gem)
544 else:
545 raise Exception("invalid-type")
546
547 self.us_scheduler = TechProfileInstance.IScheduler(
548 alloc_id, tech_profile.us_scheduler)
549 self.ds_scheduler = TechProfileInstance.IScheduler(
550 alloc_id, tech_profile.ds_scheduler)
551
552 self.upstream_gem_port_attribute_list = list()
553 self.downstream_gem_port_attribute_list = list()
554 for i in range(self.num_of_gem_ports):
555 self.upstream_gem_port_attribute_list.append(
556 TechProfileInstance.IGemPortAttribute(
557 gemport_list[i],
558 tech_profile.upstream_gem_port_attribute_list[
559 i]))
560 self.downstream_gem_port_attribute_list.append(
561 TechProfileInstance.IGemPortAttribute(
562 gemport_list[i],
563 tech_profile.downstream_gem_port_attribute_list[
564 i]))
565
566 class IScheduler(Scheduler):
567 def __init__(self, alloc_id, scheduler):
568 super(TechProfileInstance.IScheduler, self).__init__(
569 scheduler.direction, scheduler.additional_bw,
570 scheduler.priority,
571 scheduler.weight, scheduler.q_sched_policy)
572 self.alloc_id = alloc_id
573
574 class IGemPortAttribute(GemPortAttribute):
575 def __init__(self, gemport_id, gem_port_attribute):
576 super(TechProfileInstance.IGemPortAttribute, self).__init__(
577 gem_port_attribute.pbit_map, gem_port_attribute.discard_config,
578 gem_port_attribute.aes_encryption,
579 gem_port_attribute.scheduling_policy,
580 gem_port_attribute.priority_q, gem_port_attribute.weight,
581 gem_port_attribute.max_q_size,
582 gem_port_attribute.discard_policy)
583 self.gemport_id = gemport_id
584
585 def to_json(self):
586 return json.dumps(self, default=lambda o: o.__dict__,
587 indent=4)