blob: 672a814990e7cb122751f13056619e71160fd1c6 [file] [log] [blame]
#
# Copyright 2020 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import absolute_import
import random
import structlog
from twisted.internet import reactor
class TpState:
ALLOC_ID = "alloc_id"
GEM_ID = "gem_id"
def __init__(self, handler, uni_id, tp_path):
self.log = structlog.get_logger(device_id=handler.device_id, uni_id=uni_id, tp_path=tp_path)
self._handler = handler
self._uni_id = uni_id
self._tp_path = tp_path
self._tp_task_ref = None
self._tp_setup_done = False
# When the vlan filter is being removed for a given TP ID on a given UNI,
# mark that we are expecting a tp delete to happen for this UNI.
# Unless the TP delete is complete to not allow new vlan add tasks to this TP ID
self._is_tp_delete_pending = False
# Map maintains details of PON resources (alloc_id and gem_port_id(s) to be deleted) for a given TP
self._pending_delete_pon_res_map = dict()
@property
def tp_task_ref(self):
return self._tp_task_ref
@tp_task_ref.setter
def tp_task_ref(self, tp_task_ref):
self._tp_task_ref = tp_task_ref
@property
def tp_setup_done(self):
return self._tp_setup_done
@tp_setup_done.setter
def tp_setup_done(self, tp_setup_done):
self._tp_setup_done = tp_setup_done
@property
def is_tp_delete_pending(self):
return self._is_tp_delete_pending
@is_tp_delete_pending.setter
def is_tp_delete_pending(self, is_tp_delete_pending):
self._is_tp_delete_pending = is_tp_delete_pending
@property
def pending_delete_pon_res_map(self):
return self._pending_delete_pon_res_map
def queue_pending_delete_pon_resource(self, res_type, res):
if res_type not in self._pending_delete_pon_res_map:
if res_type == TpState.ALLOC_ID:
# There is only one alloc-id for a TP
self._pending_delete_pon_res_map[TpState.ALLOC_ID] = res
elif res_type == TpState.GEM_ID:
# There can be more than one gem-port-id for a TP
self._pending_delete_pon_res_map[TpState.GEM_ID] = list()
self._pending_delete_pon_res_map[TpState.GEM_ID].append(res)
else:
self.log.error("unknown-res-type", res_type=res_type)
else:
if res_type == TpState.ALLOC_ID:
self.log.warn("alloc-id-already-pending-for-deletion", alloc_id=res.alloc_id)
elif res_type == TpState.GEM_ID:
# Make sure that we are not adding duplicate gem-port-id to the list
for v in self._pending_delete_pon_res_map[TpState.GEM_ID]:
if v.gem_id == res.gem_id:
self.log.warn("gem-id-already-pending-for-deletion", gem_id=res.gem_id)
return
self._pending_delete_pon_res_map[TpState.GEM_ID].append(res)
else:
self.log.error("unknown-res-type", res_type=res_type)
def pon_resource_delete_complete(self, res_type, res_id):
if res_type not in self._pending_delete_pon_res_map:
self.log.error("resource-was-not-queued-for-delete", res_type=res_type, res_id=res_id)
return
if res_type == TpState.ALLOC_ID:
# After removing the TCONT, remove the ALLOC_ID key
del self._pending_delete_pon_res_map[res_type]
else:
for v in self._pending_delete_pon_res_map[TpState.GEM_ID]:
if v.gem_id == res_id:
self._pending_delete_pon_res_map[TpState.GEM_ID].remove(v)
if len(self._pending_delete_pon_res_map[TpState.GEM_ID]) == 0:
del self._pending_delete_pon_res_map[TpState.GEM_ID]
return
self.log.warn("gem-id-was-not-queued-for-delete", gem_id=res_id)
def get_queued_resource_for_delete(self, res_type, res_id):
if res_type not in self._pending_delete_pon_res_map:
self.log.warn("resource-was-not-queued-for-delete", res_type=res_type, res_id=res_id)
return None
if res_type == TpState.ALLOC_ID:
# After removing the TCONT, remove the ALLOC_ID key
return self._pending_delete_pon_res_map[res_type]
elif res_type == TpState.GEM_ID:
for i, v in enumerate(self._pending_delete_pon_res_map[res_type]):
if v.gem_id == res_id:
return self._pending_delete_pon_res_map[res_type][i]
return None
def is_all_pon_resource_delete_complete(self):
return len(self._pending_delete_pon_res_map) == 0
def reset_tp_state(self):
self._tp_task_ref = None
self._tp_setup_done = False
self._is_tp_delete_pending = False
self._pending_delete_pon_res_map.clear()
self.log.info("reset-tp-success")