blob: 72bf07614d1fa6026de220be303904ef62b349fa [file] [log] [blame]
Chip Boling67b674a2019-02-08 11:42:18 -06001#
2# Copyright 2017 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#
16
17"""
18This facade handles kafka-formatted messages from the Core, extracts the kafka
19formatting and forwards the request to the concrete handler.
20"""
Zack Williams84a71e92019-11-15 09:00:19 -070021from __future__ import absolute_import
Chip Boling67b674a2019-02-08 11:42:18 -060022import structlog
23from twisted.internet.defer import inlineCallbacks
24from zope.interface import implementer
25from twisted.internet import reactor
26
27from afkak.consumer import OFFSET_LATEST, OFFSET_EARLIEST
28from pyvoltha.adapters.interface import IAdapterInterface
William Kurkianede82e92019-03-05 13:02:57 -050029from voltha_protos.inter_container_pb2 import IntType, InterAdapterMessage, StrType, Error, ErrorCode
kesavandd9ef7fe2020-01-29 20:54:13 -050030from voltha_protos.device_pb2 import Device, Port, ImageDownload, SimulateAlarmRequest
William Kurkianede82e92019-03-05 13:02:57 -050031from voltha_protos.openflow_13_pb2 import FlowChanges, FlowGroups, Flows, \
Chip Boling67b674a2019-02-08 11:42:18 -060032 FlowGroupChanges, ofp_packet_out
onkarkundargiea01eb82020-01-27 12:15:40 +053033from voltha_protos.voltha_pb2 import OmciTestRequest
Chip Boling67b674a2019-02-08 11:42:18 -060034from pyvoltha.adapters.kafka.kafka_inter_container_library import IKafkaMessagingProxy, \
khenaidoo944aee72019-02-28 11:00:24 -050035 get_messaging_proxy, KAFKA_OFFSET_LATEST, KAFKA_OFFSET_EARLIEST, ARG_FROM_TOPIC
Chip Boling67b674a2019-02-08 11:42:18 -060036
onkarkundargiea01eb82020-01-27 12:15:40 +053037
Chip Boling67b674a2019-02-08 11:42:18 -060038log = structlog.get_logger()
39
40class MacAddressError(BaseException):
41 def __init__(self, error):
42 self.error = error
43
44
45class IDError(BaseException):
46 def __init__(self, error):
47 self.error = error
48
49
50@implementer(IAdapterInterface)
51class AdapterRequestFacade(object):
52 """
53 Gate-keeper between CORE and device adapters.
54
55 On one side it interacts with Core's internal model and update/dispatch
56 mechanisms.
57
58 On the other side, it interacts with the adapters standard interface as
59 defined in
60 """
61
khenaidoo944aee72019-02-28 11:00:24 -050062 def __init__(self, adapter, core_proxy):
Chip Boling67b674a2019-02-08 11:42:18 -060063 self.adapter = adapter
khenaidoo944aee72019-02-28 11:00:24 -050064 self.core_proxy = core_proxy
Chip Boling67b674a2019-02-08 11:42:18 -060065
66 @inlineCallbacks
67 def start(self):
68 log.debug('starting')
69
70 @inlineCallbacks
71 def stop(self):
72 log.debug('stopping')
73
khenaidoo944aee72019-02-28 11:00:24 -050074 # @inlineCallbacks
75 # def createKafkaDeviceTopic(self, deviceId):
76 # log.debug("subscribing-to-topic", device_id=deviceId)
77 # kafka_proxy = get_messaging_proxy()
78 # device_topic = kafka_proxy.get_default_topic() + "_" + deviceId
79 # # yield kafka_proxy.create_topic(topic=device_topic)
80 # yield kafka_proxy.subscribe(topic=device_topic, group_id=device_topic, target_cls=self, offset=KAFKA_OFFSET_EARLIEST)
81 # log.debug("subscribed-to-topic", topic=device_topic)
Chip Boling67b674a2019-02-08 11:42:18 -060082
onkarkundargiea01eb82020-01-27 12:15:40 +053083 def start_omci_test(self, device, omcitestrequest, **kwargs):
84 if not device:
85 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
86 reason="device-invalid")
87 if not omcitestrequest:
88 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
89 reason="omcitestrequest-invalid")
90
91 d = Device()
92 device.Unpack(d)
93 omci_test = OmciTestRequest()
94 omcitestrequest.Unpack(omci_test)
95 result = self.adapter.start_omci_test(d, omci_test.uuid)
96 return True, result
97
khenaidoo944aee72019-02-28 11:00:24 -050098 def adopt_device(self, device, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -060099 d = Device()
100 if device:
101 device.Unpack(d)
102
khenaidoo944aee72019-02-28 11:00:24 -0500103 # Update the core reference for that device as it will be used
104 # by the adapter to send async messages to the Core.
105 if ARG_FROM_TOPIC in kwargs:
106 t = StrType()
107 kwargs[ARG_FROM_TOPIC].Unpack(t)
108 # Update the core reference for that device
109 self.core_proxy.update_device_core_reference(d.id, t.val)
110
111 # # Start the creation of a device specific topic to handle all
112 # # subsequent requests from the Core. This adapter instance will
113 # # handle all requests for that device.
114 # reactor.callLater(0, self.createKafkaDeviceTopic, d.id)
Chip Boling67b674a2019-02-08 11:42:18 -0600115
116 result = self.adapter.adopt_device(d)
117 # return True, self.adapter.adopt_device(d)
118
119 return True, result
120 else:
121 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
122 reason="device-invalid")
123
khenaidoo944aee72019-02-28 11:00:24 -0500124 def get_ofp_device_info(self, device, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600125 d = Device()
126 if device:
127 device.Unpack(d)
128 return True, self.adapter.get_ofp_device_info(d)
129 else:
130 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
131 reason="device-invalid")
132
khenaidoo944aee72019-02-28 11:00:24 -0500133 def get_ofp_port_info(self, device, port_no, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600134 d = Device()
135 if device:
136 device.Unpack(d)
137 else:
138 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
139 reason="device-invalid")
140 p = IntType()
141 if port_no:
142 port_no.Unpack(p)
143 else:
144 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
145 reason="port-no-invalid")
146
147 return True, self.adapter.get_ofp_port_info(d, p.val)
148
khenaidoo944aee72019-02-28 11:00:24 -0500149 def reconcile_device(self, device, **kwargs):
Matt Jeanneretec797262020-01-09 11:55:36 -0500150 d = Device()
151 if device:
152 device.Unpack(d)
153 return True, self.adapter.reconcile_device(d)
154 else:
155 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
156 reason="device-invalid")
Chip Boling67b674a2019-02-08 11:42:18 -0600157
khenaidoo944aee72019-02-28 11:00:24 -0500158 def abandon_device(self, device, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600159 return self.adapter.abandon_device(device)
160
khenaidoo944aee72019-02-28 11:00:24 -0500161 def disable_device(self, device, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600162 d = Device()
163 if device:
164 device.Unpack(d)
165 return True, self.adapter.disable_device(d)
166 else:
167 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
168 reason="device-invalid")
169
khenaidoo944aee72019-02-28 11:00:24 -0500170 def reenable_device(self, device, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600171 d = Device()
172 if device:
173 device.Unpack(d)
174 return True, self.adapter.reenable_device(d)
175 else:
176 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
177 reason="device-invalid")
178
khenaidoo944aee72019-02-28 11:00:24 -0500179 def reboot_device(self, device, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600180 d = Device()
181 if device:
182 device.Unpack(d)
183 return (True, self.adapter.reboot_device(d))
184 else:
185 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
186 reason="device-invalid")
187
khenaidoo944aee72019-02-28 11:00:24 -0500188 def download_image(self, device, request, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600189 d = Device()
190 if device:
191 device.Unpack(d)
192 else:
193 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
194 reason="device-invalid")
195 img = ImageDownload()
196 if request:
197 request.Unpack(img)
198 else:
199 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
200 reason="port-no-invalid")
201
202 return True, self.adapter.download_image(device, request)
203
khenaidoo944aee72019-02-28 11:00:24 -0500204 def get_image_download_status(self, device, request, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600205 d = Device()
206 if device:
207 device.Unpack(d)
208 else:
209 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
210 reason="device-invalid")
211 img = ImageDownload()
212 if request:
213 request.Unpack(img)
214 else:
215 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
216 reason="port-no-invalid")
217
218 return True, self.adapter.get_image_download_status(device, request)
219
khenaidoo944aee72019-02-28 11:00:24 -0500220 def cancel_image_download(self, device, request, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600221 d = Device()
222 if device:
223 device.Unpack(d)
224 else:
225 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
226 reason="device-invalid")
227 img = ImageDownload()
228 if request:
229 request.Unpack(img)
230 else:
231 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
232 reason="port-no-invalid")
233
234 return True, self.adapter.cancel_image_download(device, request)
235
khenaidoo944aee72019-02-28 11:00:24 -0500236 def activate_image_update(self, device, request, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600237 d = Device()
238 if device:
239 device.Unpack(d)
240 else:
241 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
242 reason="device-invalid")
243 img = ImageDownload()
244 if request:
245 request.Unpack(img)
246 else:
247 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
248 reason="port-no-invalid")
249
250 return True, self.adapter.activate_image_update(device, request)
251
khenaidoo944aee72019-02-28 11:00:24 -0500252 def revert_image_update(self, device, request, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600253 d = Device()
254 if device:
255 device.Unpack(d)
256 else:
257 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
258 reason="device-invalid")
259 img = ImageDownload()
260 if request:
261 request.Unpack(img)
262 else:
263 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
264 reason="port-no-invalid")
265
266 return True, self.adapter.revert_image_update(device, request)
267
kesavandd9ef7fe2020-01-29 20:54:13 -0500268 def enable_port(self, device_id, port, **kwargs):
269 if not device_id:
270 return False, Error(code=ErrorCode.INVALID_PARAMETER,
271 reason="device")
272 p = Port()
273 if port:
274 port.Unpack(p)
275 else:
276 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
277 reason="port-invalid")
278
279 return (True, self.adapter.enable_port(device_id, port))
280
281 def disable_port(self, device_id, port, **kwargs):
282 if not device_id:
283 return False, Error(code=ErrorCode.INVALID_PARAMETER,
284 reason="device")
285 p = Port()
286 if port:
287 port.Unpack(p)
288 else:
289 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
290 reason="port-invalid")
291
292 return (True, self.adapter.disable_port(device_id, port))
Chip Boling67b674a2019-02-08 11:42:18 -0600293
khenaidoo944aee72019-02-28 11:00:24 -0500294 def self_test(self, device, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600295 return self.adapter.self_test_device(device)
296
khenaidoo944aee72019-02-28 11:00:24 -0500297 def delete_device(self, device, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600298 d = Device()
299 if device:
300 device.Unpack(d)
301 result = self.adapter.delete_device(d)
302 # return (True, self.adapter.delete_device(d))
303
304 # Before we return, delete the device specific topic as we will no
305 # longer receive requests from the Core for that device
306 kafka_proxy = get_messaging_proxy()
307 device_topic = kafka_proxy.get_default_topic() + "/" + d.id
308 kafka_proxy.unsubscribe(topic=device_topic)
309
310 return (True, result)
311 else:
312 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
313 reason="device-invalid")
314
khenaidoo944aee72019-02-28 11:00:24 -0500315 def get_device_details(self, device, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600316 return self.adapter.get_device_details(device)
317
khenaidoo944aee72019-02-28 11:00:24 -0500318 def update_flows_bulk(self, device, flows, groups, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600319 d = Device()
320 if device:
321 device.Unpack(d)
322 else:
323 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
324 reason="device-invalid")
325 f = Flows()
326 if flows:
327 flows.Unpack(f)
328
329 g = FlowGroups()
330 if groups:
331 groups.Unpack(g)
332
333 return (True, self.adapter.update_flows_bulk(d, f, g))
334
khenaidoo944aee72019-02-28 11:00:24 -0500335 def update_flows_incrementally(self, device, flow_changes, group_changes, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600336 d = Device()
337 if device:
338 device.Unpack(d)
339 else:
340 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
341 reason="device-invalid")
342 f = FlowChanges()
343 if flow_changes:
344 flow_changes.Unpack(f)
345
346 g = FlowGroupChanges()
347 if group_changes:
348 group_changes.Unpack(g)
349
350 return (True, self.adapter.update_flows_incrementally(d, f, g))
351
khenaidoo944aee72019-02-28 11:00:24 -0500352 def suppress_alarm(self, filter, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600353 return self.adapter.suppress_alarm(filter)
354
khenaidoo944aee72019-02-28 11:00:24 -0500355 def unsuppress_alarm(self, filter, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600356 return self.adapter.unsuppress_alarm(filter)
357
khenaidoo944aee72019-02-28 11:00:24 -0500358 def process_inter_adapter_message(self, msg, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600359 m = InterAdapterMessage()
360 if msg:
361 msg.Unpack(m)
362 else:
363 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
364 reason="msg-invalid")
365
366 return (True, self.adapter.process_inter_adapter_message(m))
367
368
khenaidoo944aee72019-02-28 11:00:24 -0500369 def receive_packet_out(self, deviceId, outPort, packet, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600370 try:
371 d_id = StrType()
372 if deviceId:
373 deviceId.Unpack(d_id)
374 else:
375 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
376 reason="deviceid-invalid")
377
378 op = IntType()
379 if outPort:
380 outPort.Unpack(op)
381 else:
382 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
383 reason="outport-invalid")
384
385 p = ofp_packet_out()
386 if packet:
387 packet.Unpack(p)
388 else:
389 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
390 reason="packet-invalid")
391
392 return (True, self.adapter.receive_packet_out(d_id.val, op.val, p))
393 except Exception as e:
394 log.exception("error-processing-receive_packet_out", e=e)
serkant.uluderyaece067c2019-04-10 09:13:48 -0700395
396 def simulate_alarm(self, device, request, **kwargs):
397 d = Device()
398 if device:
399 device.Unpack(d)
400 else:
401 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
402 reason="device-invalid")
403 req = SimulateAlarmRequest()
404 if request:
405 request.Unpack(req)
406 else:
407 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
408 reason="simulate-alarm-request-invalid")
409
410 return True, self.adapter.simulate_alarm(d, req)
Chip Boling67b674a2019-02-08 11:42:18 -0600411