blob: 2159ebe75d37a3e20bbc06d9b8a90b376a3b9f03 [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
Rohan Agrawal9a028682020-06-01 09:08:14 +000030from voltha_protos.device_pb2 import Device, Port, ImageDownload, SimulateAlarmRequest, PmConfigs
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
Rohan Agrawal9a028682020-06-01 09:08:14 +0000188 def update_pm_config(self, device, pm_configs, **kwargs):
189 d = Device()
190 if device:
191 device.Unpack(d)
192 else:
193 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
194 reason="device-invalid")
195 pm = PmConfigs()
196 if pm_configs:
197 pm_configs.Unpack(pm)
198
199 return (True, self.adapter.update_pm_config(d, pm))
200
khenaidoo944aee72019-02-28 11:00:24 -0500201 def download_image(self, device, request, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600202 d = Device()
203 if device:
204 device.Unpack(d)
205 else:
206 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
207 reason="device-invalid")
208 img = ImageDownload()
209 if request:
210 request.Unpack(img)
211 else:
212 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
213 reason="port-no-invalid")
214
215 return True, self.adapter.download_image(device, request)
216
khenaidoo944aee72019-02-28 11:00:24 -0500217 def get_image_download_status(self, device, request, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600218 d = Device()
219 if device:
220 device.Unpack(d)
221 else:
222 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
223 reason="device-invalid")
224 img = ImageDownload()
225 if request:
226 request.Unpack(img)
227 else:
228 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
229 reason="port-no-invalid")
230
231 return True, self.adapter.get_image_download_status(device, request)
232
khenaidoo944aee72019-02-28 11:00:24 -0500233 def cancel_image_download(self, device, request, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600234 d = Device()
235 if device:
236 device.Unpack(d)
237 else:
238 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
239 reason="device-invalid")
240 img = ImageDownload()
241 if request:
242 request.Unpack(img)
243 else:
244 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
245 reason="port-no-invalid")
246
247 return True, self.adapter.cancel_image_download(device, request)
248
khenaidoo944aee72019-02-28 11:00:24 -0500249 def activate_image_update(self, device, request, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600250 d = Device()
251 if device:
252 device.Unpack(d)
253 else:
254 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
255 reason="device-invalid")
256 img = ImageDownload()
257 if request:
258 request.Unpack(img)
259 else:
260 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
261 reason="port-no-invalid")
262
263 return True, self.adapter.activate_image_update(device, request)
264
khenaidoo944aee72019-02-28 11:00:24 -0500265 def revert_image_update(self, device, request, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600266 d = Device()
267 if device:
268 device.Unpack(d)
269 else:
270 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
271 reason="device-invalid")
272 img = ImageDownload()
273 if request:
274 request.Unpack(img)
275 else:
276 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
277 reason="port-no-invalid")
278
279 return True, self.adapter.revert_image_update(device, request)
280
kesavandd9ef7fe2020-01-29 20:54:13 -0500281 def enable_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.enable_port(device_id, port))
293
294 def disable_port(self, device_id, port, **kwargs):
295 if not device_id:
296 return False, Error(code=ErrorCode.INVALID_PARAMETER,
297 reason="device")
298 p = Port()
299 if port:
300 port.Unpack(p)
301 else:
302 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
303 reason="port-invalid")
304
305 return (True, self.adapter.disable_port(device_id, port))
Chip Boling67b674a2019-02-08 11:42:18 -0600306
khenaidoo944aee72019-02-28 11:00:24 -0500307 def self_test(self, device, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600308 return self.adapter.self_test_device(device)
309
khenaidoo944aee72019-02-28 11:00:24 -0500310 def delete_device(self, device, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600311 d = Device()
312 if device:
313 device.Unpack(d)
314 result = self.adapter.delete_device(d)
315 # return (True, self.adapter.delete_device(d))
316
317 # Before we return, delete the device specific topic as we will no
318 # longer receive requests from the Core for that device
319 kafka_proxy = get_messaging_proxy()
320 device_topic = kafka_proxy.get_default_topic() + "/" + d.id
321 kafka_proxy.unsubscribe(topic=device_topic)
322
323 return (True, result)
324 else:
325 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
326 reason="device-invalid")
327
khenaidoo944aee72019-02-28 11:00:24 -0500328 def get_device_details(self, device, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600329 return self.adapter.get_device_details(device)
330
khenaidoo944aee72019-02-28 11:00:24 -0500331 def update_flows_bulk(self, device, flows, groups, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600332 d = Device()
333 if device:
334 device.Unpack(d)
335 else:
336 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
337 reason="device-invalid")
338 f = Flows()
339 if flows:
340 flows.Unpack(f)
341
342 g = FlowGroups()
343 if groups:
344 groups.Unpack(g)
345
346 return (True, self.adapter.update_flows_bulk(d, f, g))
347
khenaidoo944aee72019-02-28 11:00:24 -0500348 def update_flows_incrementally(self, device, flow_changes, group_changes, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600349 d = Device()
350 if device:
351 device.Unpack(d)
352 else:
353 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
354 reason="device-invalid")
355 f = FlowChanges()
356 if flow_changes:
357 flow_changes.Unpack(f)
358
359 g = FlowGroupChanges()
360 if group_changes:
361 group_changes.Unpack(g)
362
363 return (True, self.adapter.update_flows_incrementally(d, f, g))
364
khenaidoo944aee72019-02-28 11:00:24 -0500365 def suppress_alarm(self, filter, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600366 return self.adapter.suppress_alarm(filter)
367
khenaidoo944aee72019-02-28 11:00:24 -0500368 def unsuppress_alarm(self, filter, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600369 return self.adapter.unsuppress_alarm(filter)
370
khenaidoo944aee72019-02-28 11:00:24 -0500371 def process_inter_adapter_message(self, msg, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600372 m = InterAdapterMessage()
373 if msg:
374 msg.Unpack(m)
375 else:
376 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
377 reason="msg-invalid")
378
379 return (True, self.adapter.process_inter_adapter_message(m))
380
381
khenaidoo944aee72019-02-28 11:00:24 -0500382 def receive_packet_out(self, deviceId, outPort, packet, **kwargs):
Chip Boling67b674a2019-02-08 11:42:18 -0600383 try:
384 d_id = StrType()
385 if deviceId:
386 deviceId.Unpack(d_id)
387 else:
388 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
389 reason="deviceid-invalid")
390
391 op = IntType()
392 if outPort:
393 outPort.Unpack(op)
394 else:
395 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
396 reason="outport-invalid")
397
398 p = ofp_packet_out()
399 if packet:
400 packet.Unpack(p)
401 else:
402 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
403 reason="packet-invalid")
404
405 return (True, self.adapter.receive_packet_out(d_id.val, op.val, p))
406 except Exception as e:
407 log.exception("error-processing-receive_packet_out", e=e)
serkant.uluderyaece067c2019-04-10 09:13:48 -0700408
409 def simulate_alarm(self, device, request, **kwargs):
410 d = Device()
411 if device:
412 device.Unpack(d)
413 else:
414 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
415 reason="device-invalid")
416 req = SimulateAlarmRequest()
417 if request:
418 request.Unpack(req)
419 else:
420 return False, Error(code=ErrorCode.INVALID_PARAMETERS,
421 reason="simulate-alarm-request-invalid")
422
423 return True, self.adapter.simulate_alarm(d, req)
Chip Boling67b674a2019-02-08 11:42:18 -0600424