blob: b6820eaaf9b13c31760d3eea992df14c98d26258 [file] [log] [blame]
Girish Gowdrac5117452020-08-03 11:20:53 -07001#
2# Copyright 2020 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
16from __future__ import absolute_import
17
18import random
19import structlog
20from twisted.internet import reactor
21
22
23class TpState:
24 ALLOC_ID = "alloc_id"
25 GEM_ID = "gem_id"
26
27 def __init__(self, handler, uni_id, tp_path):
28 self.log = structlog.get_logger(device_id=handler.device_id, uni_id=uni_id, tp_path=tp_path)
29 self._handler = handler
30 self._uni_id = uni_id
31 self._tp_path = tp_path
32 self._tp_task_ref = None
33 self._tp_setup_done = False
34 # When the vlan filter is being removed for a given TP ID on a given UNI,
35 # mark that we are expecting a tp delete to happen for this UNI.
36 # Unless the TP delete is complete to not allow new vlan add tasks to this TP ID
37 self._is_tp_delete_pending = False
38 # Map maintains details of PON resources (alloc_id and gem_port_id(s) to be deleted) for a given TP
39 self._pending_delete_pon_res_map = dict()
40
41 @property
42 def tp_task_ref(self):
43 return self._tp_task_ref
44
45 @tp_task_ref.setter
46 def tp_task_ref(self, tp_task_ref):
47 self._tp_task_ref = tp_task_ref
48
49 @property
50 def tp_setup_done(self):
51 return self._tp_setup_done
52
53 @tp_setup_done.setter
54 def tp_setup_done(self, tp_setup_done):
55 self._tp_setup_done = tp_setup_done
56
57 @property
58 def is_tp_delete_pending(self):
59 return self._is_tp_delete_pending
60
61 @is_tp_delete_pending.setter
62 def is_tp_delete_pending(self, is_tp_delete_pending):
63 self._is_tp_delete_pending = is_tp_delete_pending
64
65 def queue_pending_delete_pon_resource(self, res_type, res):
66 if res_type not in self._pending_delete_pon_res_map:
67 if res_type == TpState.ALLOC_ID:
68 # There is only one alloc-id for a TP
69 self._pending_delete_pon_res_map[TpState.ALLOC_ID] = res
70 elif res_type == TpState.GEM_ID:
71 # There can be more than one gem-port-id for a TP
72 self._pending_delete_pon_res_map[TpState.GEM_ID] = list()
73 self._pending_delete_pon_res_map[TpState.GEM_ID].append(res)
74 else:
75 self.log.error("unknown-res-type", res_type=res_type)
76 else:
77 if res_type == TpState.ALLOC_ID:
78 self.log.warn("alloc-id-already-pending-for-deletion", alloc_id=res)
79 elif res_type == TpState.GEM_ID:
80 # Make sure that we are not adding duplicate gem-port-id to the list
81 for v in self._pending_delete_pon_res_map[TpState.GEM_ID]:
82 if v.gem_id == res.gem_id:
83 self.log.warn("gem-id-already-pending-for-deletion", gem_id=res.gem_id)
84 return
85 self._pending_delete_pon_res_map[TpState.GEM_ID].append(res)
86 else:
87 self.log.error("unknown-res-type", res_type=res_type)
88
89 def pon_resource_delete_complete(self, res_type, res_id):
90 if res_type not in self._pending_delete_pon_res_map:
91 self.log.error("resource-was-not-queued-for-delete", res_type=res_type, res_id=res_id)
92 return
93 if res_type == TpState.ALLOC_ID:
94 # After removing the TCONT, remove the ALLOC_ID key
95 del self._pending_delete_pon_res_map[res_type]
96 else:
97 for v in self._pending_delete_pon_res_map[TpState.GEM_ID]:
98 if v.gem_id == res_id:
99 self._pending_delete_pon_res_map[TpState.GEM_ID].remove(v)
100 if len(self._pending_delete_pon_res_map[TpState.GEM_ID]) == 0:
101 del self._pending_delete_pon_res_map[TpState.GEM_ID]
102 return
103 self.log.warn("gem-id-was-not-queued-for-delete", gem_id=res_id)
104
105 def get_queued_resource_for_delete(self, res_type, res_id):
106 if res_type not in self._pending_delete_pon_res_map:
107 self.log.warn("resource-was-not-queued-for-delete", res_type=res_type, res_id=res_id)
108 return None
109 if res_type == TpState.ALLOC_ID:
110 # After removing the TCONT, remove the ALLOC_ID key
111 return self._pending_delete_pon_res_map[res_type]
112 elif res_type == TpState.GEM_ID:
113 for i, v in enumerate(self._pending_delete_pon_res_map[res_type]):
114 if v.gem_id == res_id:
115 return self._pending_delete_pon_res_map[res_type][i]
116 return None
117
118 def is_all_pon_resource_delete_complete(self):
119 return len(self._pending_delete_pon_res_map) == 0
120
121 def reset_tp_state(self):
122 self._tp_task_ref = None
123 self._tp_setup_done = False
124 self._is_tp_delete_pending = False
125 self._pending_delete_pon_res_map.clear()
126 self.log.info("reset-tp-success")