vtn_service.py 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. # SPDX-License-Identifier: Apache-2.0
  2. # Copyright 2020 Contributors to OpenLEADR
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. # http://www.apache.org/licenses/LICENSE-2.0
  7. # Unless required by applicable law or agreed to in writing, software
  8. # distributed under the License is distributed on an "AS IS" BASIS,
  9. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. # See the License for the specific language governing permissions and
  11. # limitations under the License.
  12. from asyncio import iscoroutine
  13. from http import HTTPStatus
  14. import os
  15. from aiohttp import web
  16. from jinja2 import Environment, PackageLoader, select_autoescape
  17. from .. import errors
  18. from ..messaging import create_message, parse_message
  19. from ..utils import generate_id
  20. class VTNService:
  21. def __init__(self, vtn_id):
  22. self.vtn_id = vtn_id
  23. self.handlers = {}
  24. for method in [getattr(self, attr) for attr in dir(self) if callable(getattr(self, attr))]:
  25. if hasattr(method, '__message_type__'):
  26. self.handlers[method.__message_type__] = method
  27. async def handler(self, request):
  28. """
  29. Handle all incoming POST requests.
  30. """
  31. content = await request.read()
  32. message_type, message_payload = self._parse_message(content)
  33. if message_type in self.handlers:
  34. handler = self.handlers[message_type]
  35. result = handler(message_payload)
  36. if iscoroutine(result):
  37. result = await result
  38. if result is not None:
  39. response_type, response_payload = result
  40. else:
  41. response_type, response_payload = 'oadrResponse', {}
  42. response_payload['vtn_id'] = self.vtn_id
  43. if 'ven_id' in message_payload:
  44. response_payload['ven_id'] = message_payload['ven_id']
  45. response_payload['response'] = {'request_id': message_payload.get('request_id', None),
  46. 'response_code': 200,
  47. 'response_description': 'OK'}
  48. response_payload['request_id'] = generate_id()
  49. # Create the XML response
  50. msg = self._create_message(response_type, **response_payload)
  51. response = web.Response(text=msg,
  52. status=HTTPStatus.OK,
  53. content_type='application/xml')
  54. else:
  55. msg = self._create_message('oadrResponse',
  56. ven_id=message_payload.get('ven_id'),
  57. status_code=errorcodes.COMPLIANCE_ERROR,
  58. status_description=f"A message of type {message_type} should not be sent to this endpoint")
  59. response = web.Response(
  60. text=msg,
  61. status=HTTPStatus.BAD_REQUEST,
  62. content_type='application/xml')
  63. return response