blob: 672a814990e7cb122751f13056619e71160fd1c6 [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
Girish Gowdra322cca12020-08-09 15:55:54 -070065 @property
66 def pending_delete_pon_res_map(self):
67 return self._pending_delete_pon_res_map
68
Girish Gowdrac5117452020-08-03 11:20:53 -070069 def queue_pending_delete_pon_resource(self, res_type, res):
70 if res_type not in self._pending_delete_pon_res_map:
71 if res_type == TpState.ALLOC_ID:
72 # There is only one alloc-id for a TP
73 self._pending_delete_pon_res_map[TpState.ALLOC_ID] = res
74 elif res_type == TpState.GEM_ID:
75 # There can be more than one gem-port-id for a TP
76 self._pending_delete_pon_res_map[TpState.GEM_ID] = list()
77 self._pending_delete_pon_res_map[TpState.GEM_ID].append(res)
78 else:
79 self.log.error("unknown-res-type", res_type=res_type)
80 else:
81 if res_type == TpState.ALLOC_ID:
Girish Gowdra322cca12020-08-09 15:55:54 -070082 self.log.warn("alloc-id-already-pending-for-deletion", alloc_id=res.alloc_id)
Girish Gowdrac5117452020-08-03 11:20:53 -070083 elif res_type == TpState.GEM_ID:
84 # Make sure that we are not adding duplicate gem-port-id to the list
85 for v in self._pending_delete_pon_res_map[TpState.GEM_ID]:
86 if v.gem_id == res.gem_id:
87 self.log.warn("gem-id-already-pending-for-deletion", gem_id=res.gem_id)
88 return
89 self._pending_delete_pon_res_map[TpState.GEM_ID].append(res)
90 else:
91 self.log.error("unknown-res-type", res_type=res_type)
92
93 def pon_resource_delete_complete(self, res_type, res_id):
94 if res_type not in self._pending_delete_pon_res_map:
95 self.log.error("resource-was-not-queued-for-delete", res_type=res_type, res_id=res_id)
96 return
97 if res_type == TpState.ALLOC_ID:
98 # After removing the TCONT, remove the ALLOC_ID key
99 del self._pending_delete_pon_res_map[res_type]
100 else:
101 for v in self._pending_delete_pon_res_map[TpState.GEM_ID]:
102 if v.gem_id == res_id:
103 self._pending_delete_pon_res_map[TpState.GEM_ID].remove(v)
104 if len(self._pending_delete_pon_res_map[TpState.GEM_ID]) == 0:
105 del self._pending_delete_pon_res_map[TpState.GEM_ID]
106 return
107 self.log.warn("gem-id-was-not-queued-for-delete", gem_id=res_id)
108
109 def get_queued_resource_for_delete(self, res_type, res_id):
110 if res_type not in self._pending_delete_pon_res_map:
111 self.log.warn("resource-was-not-queued-for-delete", res_type=res_type, res_id=res_id)
112 return None
113 if res_type == TpState.ALLOC_ID:
114 # After removing the TCONT, remove the ALLOC_ID key
115 return self._pending_delete_pon_res_map[res_type]
116 elif res_type == TpState.GEM_ID:
117 for i, v in enumerate(self._pending_delete_pon_res_map[res_type]):
118 if v.gem_id == res_id:
119 return self._pending_delete_pon_res_map[res_type][i]
120 return None
121
122 def is_all_pon_resource_delete_complete(self):
123 return len(self._pending_delete_pon_res_map) == 0
124
125 def reset_tp_state(self):
126 self._tp_task_ref = None
127 self._tp_setup_done = False
128 self._is_tp_delete_pending = False
129 self._pending_delete_pon_res_map.clear()
130 self.log.info("reset-tp-success")