-
Jörn Künsemöller authoredJörn Künsemöller authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
views.py 5.68 KiB
"""
Handles GET / POST requests by users.
"""
from rest_framework import viewsets
from rest_framework import views
from rest_framework.response import Response
from rest_framework import status
#from serializers import TriggerSerializer
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser
from rest_framework_xml.parsers import XMLParser
from rest_framework_xml.renderers import XMLRenderer
from io import BytesIO
from rest_framework.fields import CurrentUserDefault
from lxml import etree
from StringIO import StringIO
from lofar.triggerservices.trigger_service_rpc import TriggerRPC
from lofar.specificationservices.specification_service_rpc import SpecificationRPC
from lofar.messaging import ToBus, EventMessage
import logging
import traceback
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
triggerrpc = TriggerRPC()
specrpc = SpecificationRPC()
from config import TRIGGER_SUBMISSION_NOTIFICATION_BUSNAME, TRIGGER_SUBMISSION_NOTIFICATION_SUBJECT
notification_bus = ToBus(address=TRIGGER_SUBMISSION_NOTIFICATION_BUSNAME, broker=None)
class TriggerListView(views.APIView):
def __init__(self, **kwargs):
super(TriggerListView, self).__init__(**kwargs)
notification_bus.open()
def get(self,request, format=None, **kwargs):
logger.debug('got GET from -> '+str(request.META['REMOTE_ADDR']))
return Response("Listing not implemented yet, sorry! Post trigger XML on this URL to add a new trigger.", status=status.HTTP_501_NOT_IMPLEMENTED)
def post(self, request, format=None, **kwargs):
IP = str(request.META['REMOTE_ADDR'])
logger.debug('got POST from -> '+IP)
#logger.debug('received text -> '+str(request.body))
#logger.debug('received data -> '+str(request.data))
logger.debug('from user -> '+str( request.user))
self._sendNotification(str(request.user), IP)
# OPTIONALLY USE DATA MODEL:
#serializer = TriggerSerializer(data=request.data)
#logger.debug('data is valid -> ' +str(serializer.is_valid()))
#if serializer.is_valid():
# id = serializer.save(request.user)
# #r = serializer.validated_data
# #r["trigger_id"]=id
# EITHER: RENDER FRESH XML FROM PARSED DATA:
#xml = XMLRenderer().render(request.data) # ! django replaces the root element
#xml = self._renameXMLroot(xml, "lofar:trigger")
#print xml
# OR: USE RECEIVED XML DIRECTLY:
xml = str(request.body)
logger.debug('calling trigger handler')
try:
id = self._handle_trigger(str(request.user), IP, xml)
except Exception as err:
traceback.print_exc()
return Response('Provided data has some issues! (Details: '+str(err)+")", status=status.HTTP_400_BAD_REQUEST)
# for use with data model: return Response('Provided data has some issues: ' +str(serializer.errors)+" (Accepted were: "+str(serializer.data)+")", status=status.HTTP_400_BAD_REQUEST)
return Response(id, status=status.HTTP_201_CREATED)
def _renameXMLroot(self, xml, newname):
root = etree.parse(StringIO(xml))
root.tag = newname
return etree.tostring(root)
def _handle_trigger(self, user, host, xml):
return triggerrpc.handle_trigger(user, host, xml)
def _sendNotification(self, user, IP):
msg = EventMessage(context=TRIGGER_SUBMISSION_NOTIFICATION_SUBJECT, content="Trigger received by "+str(user)+" (IP:"+IP+")")
try:
notification_bus.send(msg)
except Exception as err:
logger.error("Could not send notification ->" + str(err))
class TriggerView(views.APIView):
#def post(self, request, format=None, **kwargs):
# return Response("It is not possible to alter an existing trigger (i.e. POST for an existing trigger ID), sorry!", status=status.HTTP_405_METHOD_NOT_ALLOWED)
def get(self,request, format=None, **kwargs):
logger.debug('got GET from: '+str(request.META['REMOTE_ADDR']))
try:
if 'pk' in kwargs:
identifier = kwargs.get('pk')
logger.info('requested id is: '+str(identifier))
logger.info('requesting user is:'+ str(request.user))
xml = self._get_specification(str(request.user), str(identifier))
# EITHER DIRECT RESPONSE:
return Response(xml)
# OR USE DATA MODEL:
# data = XMLParser().parse(BytesIO(xml))
# example: data injection with validation:
# data['view_injected_get'] = 'pre-serializing'
#serializer = TriggerSerializer(data=data)
#logger.debug('returning valid data:' + str(serializer.is_valid()))
#r = serializer.validated_data
# example: data injection after validation:
# r['view_injected_get_2'] = 'post-validation'
#return Response(r)
else:
return Response("No ID provided!")
except Exception as err:
print err
return Response("Unable to retrieve the requested trigger, sorry!", status=status.HTTP_404_NOT_FOUND)
def _get_specification(self, user, identifier):
logger.info("Getting spec from specification service")
response = specrpc.get_specification(user, identifier)
return response
# test json data:
#json = '{"project_id": "p1", "triggerid": "t1", "triggerxml": "<trigger />", "status": "new", "momid": "m1", "sasid": "s1", "submittedby":"user"}'
#stream = BytesIO(json)
#data = JSONParser().parse(stream)
# return XMLRenderer().render(data)