Example #1
0
    def test_resources_reply_message(self):
        """Test encoding & decoding of ResourcesReply message."""
        data = DemoResourceData(name='demo1', version=1, ip_address="1.2.3.4")
        data.save()

        msg = ResourcesReply(request_id=0, resources=[data])
        self.validate(msg)
Example #2
0
    def test_complex_resources_reply_message(self):
        """Test encoding & decoding of ResourcesReply message."""
        data1 = DemoResourceData(name='demo1', version=1, ip_address="1.2.3.4")
        data2 = DemoResourceData(name='demo2', version=2, ip_address="1.2.3.5")
        data1.save()
        data2.save()

        resource_data = DemoComplexResourceData(name="complex",
                                                demo1=data1,
                                                demo2=data2)
        resource_data.save()

        msg = ResourcesReply(request_id=0, resources=[resource_data])
        self.validate(msg)
Example #3
0
    def query_resources(self, request):
        """Find and return the resources that answer the client's query.

        Args:
            request (Request): QueryResources request.

        Returns:
            ResourcesReply. a reply containing matching resources.
        """
        desc = ResourceDescriptor.decode(request.message.descriptors)
        self.logger.debug("Looking for resources with description %r", desc)

        # query for resources that are usable and match the descriptors
        query = (Q(is_usable=True, **desc.properties))
        matches = desc.type.objects.filter(query)

        if matches.count() == 0:
            raise ResourceDoesNotExistError("No existing resource meets "
                                            "the requirements: %r" % desc)

        query_result = [resource for resource in matches]

        return ResourcesReply(resources=query_result)
Example #4
0
    def lock_resources(self, request):
        """Lock the given resources one by one.

        Note:
            If one of the resources fails to lock, all the resources that has
            been locked until that resource will be released.

        Args:
            request (Request): LockResources request.

        Returns:
            ResourcesReply. a reply containing requested resources.

        Raises:
            ResourceDoesNotExistError. at least one of the requested resources
                doesn't exist.
            ResourceUnavailableError. when the requested resources are not
                available.
            UnknownUserError. when unknown user has tried to lock a resource.
        """
        locked_resources = []

        client = request.worker.name
        user_name, _ = client.split(":")  # splitting <user_name>:<port>

        if not auth_models.User.objects.filter(username=user_name).exists():
            raise UnknownUserError("User %r has no matching object in the DB" %
                                   user_name)

        user = auth_models.User.objects.get(username=user_name)

        groups = list(user.groups.all())

        for descriptor_dict in request.message.descriptors:

            desc = ResourceDescriptor.decode(descriptor_dict)
            self.logger.debug("Locking %r resource", desc)

            # query for resources that are usable and match the user's
            # preference, which are either belong to a group he's in or
            # don't belong to any group.
            query = (Q(is_usable=True, **desc.properties) &
                     (Q(group__isnull=True) | Q(group__in=groups)))
            matches = desc.type.objects.filter(query).order_by('-reserved')

            if matches.count() == 0:
                raise ResourceDoesNotExistError("No existing resource meets "
                                                "the requirements: %r" % desc)

            availables = (resource for resource in matches
                          if resource.is_available(client))

            try:
                resource = availables.next()

                self._lock_resource(resource, client)
                locked_resources.append(resource)
                self.logger.debug("Resource %r locked successfully", desc)

            except StopIteration:
                timeout = request.message.timeout
                waiting_time = time.time() - request.creation_time
                if timeout is not None and waiting_time > timeout:
                    raise ResourceUnavailableError("No available resource "
                                                   "meets the requirements: "
                                                   "%r" % desc)

                raise _WaitingForResourceException(
                    "Resource %r is unavailable"
                    ", waiting for it to be "
                    "released", desc)

        return ResourcesReply(resources=locked_resources)