示例#1
0
    def on_ambulance(self, clnt, userdata, msg):

        try:

            logger.debug("on_ambulance: msg = '{}'".format(
                msg.topic, msg.payload))

            # parse topic
            user, client, data, ambulance_id = self.parse_topic(msg, 4)

        except Exception as e:

            logger.debug("on_ambulance: ParseException '{}'".format(e))
            return

        try:

            # retrieve ambulance
            logger.debug('ambulance_id = {}'.format(ambulance_id))
            ambulance = Ambulance.objects.get(id=ambulance_id)

        except Ambulance.DoesNotExist:

            # send error message to user
            self.send_error_message(
                user, client, msg.topic, msg.payload,
                "Ambulance with id '{}' does not exist".format(ambulance_id))
            return

        except Exception as e:

            # send error message to user
            self.send_error_message(user, client, msg.topic, msg.payload,
                                    "Exception: '{}'".format(e))
            return

        try:

            logger.debug("on_ambulance: ambulance = '{}', data = '{}'".format(
                ambulance, data))

            is_valid = False
            if isinstance(data, (list, tuple)):

                # bulk updates must match location_client
                if ambulance.location_client is None or ambulance.location_client.client_id != client.client_id:

                    # send error message to user
                    self.send_error_message(
                        user, client, msg.topic, msg.payload,
                        "Client '{}' is not currently authorized to update ambulance '{}'"
                        .format(client.client_id, ambulance.identifier))
                    return

                # update ambulances in bulk
                serializer = AmbulanceUpdateSerializer(data=data,
                                                       many=True,
                                                       partial=True)

                if serializer.is_valid():

                    # save to database
                    serializer.save(ambulance=ambulance, updated_by=user)
                    is_valid = True

            else:

                # update ambulance
                serializer = AmbulanceSerializer(ambulance,
                                                 data=data,
                                                 partial=True)

                if serializer.is_valid():

                    try:

                        # wrap in atomic in case of errors
                        with transaction.atomic():

                            # current location client
                            old_location_client = ambulance.location_client

                            # save to database
                            serializer.save(updated_by=user)
                            is_valid = True

                            # retrieve location client
                            new_location_client = Ambulance.objects.get(
                                id=ambulance_id).location_client

                            # logger.debug("old_location_client: {}".format(old_location_client))
                            # logger.debug("new_location_client: {}".format(new_location_client))

                            # change in location client?
                            if old_location_client != new_location_client:

                                # logger.debug("location_client changed from '{}' to {}".format(old_location_client,
                                #                                                               new_location_client))

                                # log out old client
                                if old_location_client:
                                    client_ambulance = old_location_client.ambulance
                                    if client_ambulance:
                                        details = client_ambulance.identifier
                                    else:
                                        details = 'None'
                                    log = ClientLog(
                                        client=old_location_client,
                                        status=old_location_client.status,
                                        activity=ClientActivity.TL.name,
                                        details=details)
                                    log.save()

                                # log in new client
                                if new_location_client:
                                    client_ambulance = new_location_client.ambulance
                                    if client_ambulance:
                                        details = client_ambulance.identifier
                                    else:
                                        details = 'None'
                                    log = ClientLog(
                                        client=new_location_client,
                                        status=new_location_client.status,
                                        activity=ClientActivity.SL.name,
                                        details=details)
                                    log.save()

                            # otherwise must match location_client
                            elif ambulance.location_client is None or ambulance.location_client.client_id != client.client_id:

                                # raise error to rollback transaction
                                raise ClientException()

                    except ClientException:

                        # send error message to user
                        self.send_error_message(
                            user, client, msg.topic, msg.payload,
                            "Client '{}' is not currently authorized to update ambulance '{}'"
                            .format(client.client_id, ambulance.identifier))

            if not is_valid:

                logger.debug('on_ambulance: INVALID serializer')

                # send error message to user
                self.send_error_message(user, client, msg.topic, msg.payload,
                                        serializer.errors)

        except Exception as e:

            logger.debug('on_ambulance: serializer EXCEPTION')

            # send error message to user
            self.send_error_message(user, client, msg.topic, msg.payload, e)

        logger.debug('on_ambulance: DONE')
    def test(self):

        # Bulk update ambulance a1
        a = self.a1
        user = self.u1

        location0 = {'latitude': -3., 'longitude': 6.}
        location = {'latitude': -2., 'longitude': 7.}
        orientation = calculate_orientation(dict2point(location0),
                                            dict2point(location))
        data = [{
            'status': AmbulanceStatus.AH.name,
            'location': location0,
        }, {
            'location': location,
            'timestamp': timezone.now()
        }, {
            'status': AmbulanceStatus.OS.name
        }]

        serializer = AmbulanceUpdateSerializer(data=data,
                                               many=True,
                                               partial=True)
        serializer.is_valid(raise_exception=True)
        serializer.save(ambulance=Ambulance.objects.get(id=a.id),
                        updated_by=user)

        # test AmbulanceUpdateSerializer
        queryset = AmbulanceUpdate.objects.filter(ambulance=a)
        answer1 = []
        for u in queryset:
            serializer = AmbulanceUpdateSerializer(u)
            result = {
                'id': u.id,
                'ambulance_id': u.ambulance.id,
                'ambulance_identifier': u.ambulance.identifier,
                'comment': u.comment,
                'capability': u.capability,
                'status': u.status,
                'orientation': u.orientation,
                'location': point2str(u.location),
                'timestamp': date2iso(u.timestamp),
                'updated_by_username': u.updated_by.username,
                'updated_on': date2iso(u.updated_on)
            }
            answer1.append(serializer.data)
            self.assertDictEqual(serializer.data, result)

        # make sure last update is reflected in ambulance
        a = Ambulance.objects.get(id=a.id)
        serializer = AmbulanceSerializer(a)
        self.assertEqual(math.fabs(orientation - a.orientation) < 1e-4, True)
        orientation = a.orientation
        result = {
            'id': a.id,
            'identifier': a.identifier,
            'comment': a.comment,
            'capability': a.capability,
            'status': AmbulanceStatus.OS.name,
            'orientation': orientation,
            'location': point2str(location),
            'timestamp': date2iso(a.timestamp),
            'client_id': None,
            'updated_by': a.updated_by.id,
            'updated_on': date2iso(a.updated_on)
        }
        self.assertDictEqual(serializer.data, result)

        # Bulk update ambulance a2
        a = self.a3
        user = self.u3

        data = [{
            'status': AmbulanceStatus.AH.name,
            'location': location0
        }, {
            'status': AmbulanceStatus.OS.name
        }, {
            'location': location,
            'timestamp': timezone.now()
        }]

        serializer = AmbulanceUpdateSerializer(data=data,
                                               many=True,
                                               partial=True)
        serializer.is_valid(raise_exception=True)
        serializer.save(ambulance=Ambulance.objects.get(id=a.id),
                        updated_by=user)

        # test AmbulanceUpdateSerializer
        queryset = AmbulanceUpdate.objects.filter(ambulance=a)
        answer3 = []
        for u in queryset:
            serializer = AmbulanceUpdateSerializer(u)
            result = {
                'id': u.id,
                'ambulance_id': a.id,
                'ambulance_identifier': a.identifier,
                'comment': u.comment,
                'capability': u.capability,
                'status': u.status,
                'orientation': u.orientation,
                'location': point2str(u.location),
                'timestamp': date2iso(u.timestamp),
                'updated_by_username': u.updated_by.username,
                'updated_on': date2iso(u.updated_on)
            }
            answer3.append(serializer.data)
            self.assertDictEqual(serializer.data, result)

        # make sure last update is reflected in ambulance
        a = Ambulance.objects.get(id=a.id)
        serializer = AmbulanceSerializer(a)
        self.assertEqual(math.fabs(orientation - a.orientation) < 1e-4, True)
        orientation = a.orientation
        result = {
            'id': a.id,
            'identifier': a.identifier,
            'comment': a.comment,
            'capability': a.capability,
            'status': AmbulanceStatus.OS.name,
            'orientation': orientation,
            'location': point2str(location),
            'timestamp': date2iso(a.timestamp),
            'client_id': None,
            'updated_by': a.updated_by.id,
            'updated_on': date2iso(a.updated_on)
        }
        self.assertDictEqual(serializer.data, result)

        # Test api

        # instantiate client
        client = Client()

        # login as admin
        client.login(username=settings.MQTT['USERNAME'],
                     password=settings.MQTT['PASSWORD'])

        # retrieve ambulances updates
        response = client.get('/en/api/ambulance/{}/updates/'.format(
            self.a1.id),
                              follow=True)
        self.assertEqual(response.status_code, 200)
        result = JSONParser().parse(BytesIO(response.content))
        self.assertCountEqual(result, answer1)
        self.assertEqual(len(result), 4)

        # retrieve ambulances updates
        response = client.get('/en/api/ambulance/{}/updates/'.format(
            self.a3.id),
                              follow=True)
        self.assertEqual(response.status_code, 200)
        result = JSONParser().parse(BytesIO(response.content))
        self.assertCountEqual(result, answer3)
        self.assertEqual(len(result), 4)

        # logout
        client.logout()

        # login as testuser1
        client.login(username='******', password='******')

        # retrieve ambulances
        response = client.get('/en/api/ambulance/{}/updates/'.format(
            self.a1.id),
                              follow=True)
        self.assertEqual(response.status_code, 404)

        # retrieve ambulances
        response = client.get('/en/api/ambulance/{}/updates/'.format(
            self.a3.id),
                              follow=True)
        self.assertEqual(response.status_code, 404)

        # logout
        client.logout()

        # login as testuser2
        client.login(username='******', password='******')

        # retrieve ambulances
        response = client.get('/en/api/ambulance/{}/updates/'.format(
            self.a1.id),
                              follow=True)
        self.assertEqual(response.status_code, 404)

        # retrieve ambulances updates
        response = client.get('/en/api/ambulance/{}/updates/'.format(
            self.a3.id),
                              follow=True)
        self.assertEqual(response.status_code, 200)
        result = JSONParser().parse(BytesIO(response.content))
        self.assertCountEqual(result, answer3)
        self.assertEqual(len(result), 4)

        # logout
        client.logout()
示例#3
0
    def on_ambulance(self, clnt, userdata, msg):

        try:

            logger.debug("on_ambulance: msg = '{}'".format(
                msg.topic, msg.payload))

            # parse topic
            user, client, data, ambulance_id = self.parse_topic(msg, 4)

        except Exception as e:

            logger.debug("on_ambulance: ParseException '{}'".format(e))
            return

        try:

            # retrieve ambulance
            logger.debug('ambulance_id = {}'.format(ambulance_id))
            ambulance = Ambulance.objects.get(id=ambulance_id)

        except Ambulance.DoesNotExist:

            # send error message to user
            self.send_error_message(
                user, client, msg.topic, msg.payload,
                "Ambulance with id '{}' does not exist".format(ambulance_id))
            return

        except Exception as e:

            # send error message to user
            self.send_error_message(user, client, msg.topic, msg.payload,
                                    "Exception: '{}'".format(e))
            return

        try:

            logger.debug("on_ambulance: ambulance = '{}', data = '{}'".format(
                ambulance, data))

            # updates must match client
            if client.ambulance != ambulance:
                # send error message to user
                self.send_error_message(
                    user, client, msg.topic, msg.payload,
                    "Client '{}' is not currently authorized to update ambulance '{}'"
                    .format(client.client_id, ambulance.identifier))
                return

            is_valid = False
            if isinstance(data, (list, tuple)):

                # update ambulances in bulk
                serializer = AmbulanceUpdateSerializer(data=data,
                                                       many=True,
                                                       partial=True)

                if serializer.is_valid():

                    # save to database
                    serializer.save(ambulance=ambulance, updated_by=user)
                    is_valid = True

            else:

                # update ambulance
                serializer = AmbulanceSerializer(ambulance,
                                                 data=data,
                                                 partial=True)

                if serializer.is_valid():

                    # save to database
                    serializer.save(updated_by=user)
                    is_valid = True

            if not is_valid:

                logger.debug('on_ambulance: INVALID serializer')

                # send error message to user
                self.send_error_message(user, client, msg.topic, msg.payload,
                                        serializer.errors)

        except Exception as e:

            logger.debug('on_ambulance: EXCEPTION')

            # send error message to user
            self.send_error_message(user, client, msg.topic, msg.payload,
                                    "Exception '{}'".format(e))

        logger.debug('on_ambulance: DONE')
    def test(self):

        # Update ambulance a1
        a = self.a1
        user = self.u1

        status = AmbulanceStatus.AH.name
        serializer = AmbulanceSerializer(Ambulance.objects.get(id=a.id),
                                         data={
                                             'status': status,
                                         },
                                         partial=True)
        serializer.is_valid()
        serializer.save(updated_by=user)

        timestamp = timezone.now()
        location = {'latitude': -2., 'longitude': 7.}

        serializer = AmbulanceSerializer(Ambulance.objects.get(id=a.id),
                                         data={
                                             'location': location,
                                             'timestamp': timestamp
                                         },
                                         partial=True)
        serializer.is_valid()
        serializer.save(updated_by=user)

        status = AmbulanceStatus.OS.name
        serializer = AmbulanceSerializer(Ambulance.objects.get(id=a.id),
                                         data={
                                             'status': status,
                                         },
                                         partial=True)
        serializer.is_valid()
        serializer.save(updated_by=user)

        # This update does not go to AmbulanceUpdate!
        serializer = AmbulanceSerializer(Ambulance.objects.get(id=a.id),
                                         data={
                                             'identifier': 'someid',
                                         },
                                         partial=True)
        serializer.is_valid()
        serializer.save(updated_by=user)

        # test AmbulanceUpdateSerializer
        queryset = AmbulanceUpdate.objects.filter(ambulance=a)
        answer1 = []
        for u in queryset:
            serializer = AmbulanceUpdateSerializer(u)
            result = {
                'id': u.id,
                'ambulance_id': u.ambulance.id,
                'ambulance_identifier': u.ambulance.identifier,
                'comment': u.comment,
                'capability': u.capability,
                'status': u.status,
                'orientation': u.orientation,
                'location': point2str(u.location),
                'timestamp': date2iso(u.timestamp),
                'updated_by_username': u.updated_by.username,
                'updated_on': date2iso(u.updated_on)
            }
            answer1.append(serializer.data)
            self.assertDictEqual(serializer.data, result)

        # Update ambulance a2
        a = self.a3
        user = self.u3

        status = AmbulanceStatus.AH.name
        serializer = AmbulanceSerializer(a,
                                         data={
                                             'status': status,
                                         },
                                         partial=True)
        serializer.is_valid()
        serializer.save(updated_by=user)

        timestamp = timezone.now()
        location = {'latitude': -2., 'longitude': 7.}

        serializer = AmbulanceSerializer(a,
                                         data={
                                             'location': location,
                                             'timestamp': timestamp
                                         },
                                         partial=True)
        serializer.is_valid()
        serializer.save(updated_by=user)

        status = AmbulanceStatus.OS.name
        serializer = AmbulanceSerializer(a,
                                         data={
                                             'status': status,
                                         },
                                         partial=True)
        serializer.is_valid()
        serializer.save(updated_by=user)

        # test AmbulanceUpdateSerializer
        queryset = AmbulanceUpdate.objects.filter(ambulance=a)
        answer3 = []
        for u in queryset:
            serializer = AmbulanceUpdateSerializer(u)
            result = {
                'id': u.id,
                'ambulance_id': u.ambulance.id,
                'ambulance_identifier': a.identifier,
                'comment': u.comment,
                'capability': u.capability,
                'status': u.status,
                'orientation': u.orientation,
                'location': point2str(u.location),
                'timestamp': date2iso(u.timestamp),
                'updated_by_username': u.updated_by.username,
                'updated_on': date2iso(u.updated_on)
            }
            answer3.append(serializer.data)
            self.assertDictEqual(serializer.data, result)

        # Test api

        # instantiate client
        client = Client()

        # login as admin
        client.login(username=settings.MQTT['USERNAME'],
                     password=settings.MQTT['PASSWORD'])

        # retrieve ambulances updates
        response = client.get('/en/api/ambulance/{}/updates/'.format(
            self.a1.id),
                              follow=True)
        self.assertEqual(response.status_code, 200)
        result = JSONParser().parse(BytesIO(response.content))
        self.assertCountEqual(result, answer1)
        self.assertEqual(len(result), 4)

        # retrieve ambulances updates
        response = client.get('/en/api/ambulance/{}/updates/'.format(
            self.a3.id),
                              follow=True)
        self.assertEqual(response.status_code, 200)
        result = JSONParser().parse(BytesIO(response.content))
        self.assertCountEqual(result, answer3)
        self.assertEqual(len(result), 4)

        # logout
        client.logout()

        # login as testuser1
        client.login(username='******', password='******')

        # retrieve ambulances
        response = client.get('/en/api/ambulance/{}/updates/'.format(
            self.a1.id),
                              follow=True)
        self.assertEqual(response.status_code, 404)

        # retrieve ambulances
        response = client.get('/en/api/ambulance/{}/updates/'.format(
            self.a3.id),
                              follow=True)
        self.assertEqual(response.status_code, 404)

        # logout
        client.logout()

        # login as testuser2
        client.login(username='******', password='******')

        # retrieve ambulances
        response = client.get('/en/api/ambulance/{}/updates/'.format(
            self.a1.id),
                              follow=True)
        self.assertEqual(response.status_code, 404)

        # retrieve ambulances updates
        response = client.get('/en/api/ambulance/{}/updates/'.format(
            self.a3.id),
                              follow=True)
        self.assertEqual(response.status_code, 200)
        result = JSONParser().parse(BytesIO(response.content))
        self.assertCountEqual(result, answer3)
        self.assertEqual(len(result), 4)

        # logout
        client.logout()