예제 #1
0
    def __init__(self, plugins=None):
        """User preference for each service.

        :param list plugins: List of entry point namespaces to load.

        Create a new :class:`~openstack.profile.Profile`
        object with no preferences defined, but knowledge of the services.
        Services are identified by their service type, e.g.: 'identity',
        'compute', etc.
        """
        self._preferences = {}
        self._services = {}
        self._add_service(cluster_service.ClusterService())
        self._add_service(compute_service.ComputeService())
        self._add_service(database_service.DatabaseService())
        self._add_service(identity_service.IdentityService())
        self._add_service(image_service.ImageService())
        self._add_service(metric_service.MetricService())
        self._add_service(network_service.NetworkService())
        self._add_service(object_store_service.ObjectStoreService())
        self._add_service(orchestration_service.OrchestrationService())
        self._add_service(key_management_service.KeyManagementService())
        self._add_service(telemetry_service.TelemetryService())
        self._add_service(block_store_service.BlockStoreService())
        self._add_service(message_service.MessageService())

        if plugins:
            for plugin in plugins:
                self._load_plugin(plugin)
        self.service_names = sorted(self._services.keys())
예제 #2
0
    def __init__(self, plugins=None):
        """User preference for each service.

        :param plugins: List of entry point namespaces to load.

        Create a new :class:`~openstack.profile.Profile`
        object with no preferences defined, but knowledge of the services.
        Services are identified by their service type, e.g.: 'identity',
        'compute', etc.
        """
        self._services = {}

        self._add_service(baremetal_service.BaremetalService(version="v1"))
        self._add_service(
            block_storage_service.BlockStorageService(version="v2"))
        self._add_service(clustering_service.ClusteringService(version="v1"))
        self._add_service(compute_service.ComputeService(version="v2"))
        self._add_service(database_service.DatabaseService(version="v1"))
        self._add_service(identity_service.IdentityService(version="v3"))
        self._add_service(image_service.ImageService(version="v2"))
        self._add_service(key_manager_service.KeyManagerService(version="v1"))
        self._add_service(lb_service.LoadBalancerService(version="v2"))
        self._add_service(message_service.MessageService(version="v1"))
        self._add_service(network_service.NetworkService(version="v2"))
        self._add_service(
            object_store_service.ObjectStoreService(version="v1"))
        self._add_service(
            orchestration_service.OrchestrationService(version="v1"))
        self._add_service(workflow_service.WorkflowService(version="v2"))

        self.service_keys = sorted(self._services.keys())
예제 #3
0
 def test_service(self):
     sot = message_service.MessageService()
     self.assertEqual('messaging', sot.service_type)
     self.assertEqual('public', sot.interface)
     self.assertIsNone(sot.region)
     self.assertIsNone(sot.service_name)
     self.assertEqual(1, len(sot.valid_versions))
     self.assertEqual('v2', sot.valid_versions[0].module)
     self.assertEqual('v2', sot.valid_versions[0].path)
예제 #4
0
    def __init__(self):
        """Preferences for each service.

        Create a new :class:`~openstack.profile.Profile`
        object with no preferences defined, but knowledge of the services.
        Services are identified by their service type, e.g.: 'identity',
        'compute', etc.
        """
        self._preferences = {}
        self._services = {}
        """
        NOTE(thowe): We should probably do something more clever here rather
        than brute force create all the services.  Maybe use entry points
        or something, but I'd like to leave that work for another commit.
        """
        serv = cluster_service.ClusterService()
        serv.set_visibility(None)
        self._services[serv.service_type] = serv
        serv = compute_service.ComputeService()
        serv.set_visibility(None)
        self._services[serv.service_type] = serv
        serv = database_service.DatabaseService()
        serv.set_visibility(None)
        self._services[serv.service_type] = serv
        serv = identity_service.IdentityService()
        serv.set_visibility(None)
        self._services[serv.service_type] = serv
        serv = image_service.ImageService()
        serv.set_visibility(None)
        self._services[serv.service_type] = serv
        serv = metric_service.MetricService()
        serv.set_visibility(None)
        self._services[serv.service_type] = serv
        serv = network_service.NetworkService()
        serv.set_visibility(None)
        self._services[serv.service_type] = serv
        serv = object_store_service.ObjectStoreService()
        serv.set_visibility(None)
        self._services[serv.service_type] = serv
        serv = orchestration_service.OrchestrationService()
        serv.set_visibility(None)
        self._services[serv.service_type] = serv
        serv = keystore_service.KeystoreService()
        serv.set_visibility(None)
        self._services[serv.service_type] = serv
        serv = telemetry_service.TelemetryService()
        serv.set_visibility(None)
        self._services[serv.service_type] = serv
        serv = block_store_service.BlockStoreService()
        serv.set_visibility(None)
        self._services[serv.service_type] = serv
        serv = message_service.MessageService()
        serv.set_visibility(None)
        self._services[serv.service_type] = serv

        self.service_names = sorted(self._services.keys())
예제 #5
0
class Version(resource.Resource):
    resource_key = 'version'
    resources_key = 'versions'
    base_path = '/'
    service = message_service.MessageService(
        version=message_service.MessageService.UNVERSIONED)

    # capabilities
    allow_list = True

    # Properties
    links = resource.prop('links')
    status = resource.prop('status')
예제 #6
0
    def __init__(self, plugins=None):
        """User preference for each service.

        :param plugins: List of entry point namespaces to load.

        Create a new :class:`~openstack.profile.Profile`
        object with no preferences defined, but knowledge of the services.
        Services are identified by their service type, e.g.: 'identity',
        'compute', etc.
        """
        self._services = {}

        self._add_service(anti_ddos_service.AntiDDosService(version="v1"))
        self._add_service(alarm_service.AlarmService(version="v2"))
        self._add_service(bare_metal_service.BareMetalService(version="v1"))
        self._add_service(block_store_service.BlockStoreService(version="v2"))
        self._add_service(cluster_service.ClusterService(version="v1"))
        self._add_service(compute_service.ComputeService(version="v2"))
        self._add_service(cts_service.CTSService(version="v1"))
        self._add_service(database_service.DatabaseService(version="v1"))
        self._add_service(dms_service.DMSService(version="v1"))
        self._add_service(identity_service.IdentityService(version="v3"))
        self._add_service(image_service.ImageService(version="v2"))
        self._add_service(key_manager_service.KeyManagerService(version="v1"))
        self._add_service(kms_service.KMSService(version="v1"))
        self._add_service(lb_service.LoadBalancerService(version="v1"))
        self._add_service(maas_service.MaaSService(version="v1"))
        self._add_service(message_service.MessageService(version="v1"))
        self._add_service(network_service.NetworkService(version="v2"))
        self._add_service(
            object_store_service.ObjectStoreService(version="v1"))
        self._add_service(
            orchestration_service.OrchestrationService(version="v1"))
        self._add_service(rds_service.RDSService(version="v1"))
        self._add_service(rds_os_service.RDSService(version="v1"))
        self._add_service(smn_service.SMNService(version="v2"))
        self._add_service(telemetry_service.TelemetryService(version="v2"))
        self._add_service(workflow_service.WorkflowService(version="v2"))
        # QianBiao.NG HuaWei Services
        self._add_service(dns_service.DNSService(version="v2"))
        self._add_service(cloud_eye_service.CloudEyeService(version="v1"))
        ass = auto_scaling_service.AutoScalingService(version="v1")
        self._add_service(ass)
        vbs_v2 = volume_backup_service.VolumeBackupService(version="v2")
        self._add_service(vbs_v2)
        self._add_service(map_reduce_service.MapReduceService(version="v1"))

        if plugins:
            for plugin in plugins:
                self._load_plugin(plugin)
        self.service_keys = sorted(self._services.keys())
예제 #7
0
class Claim(resource.Resource):
    resources_key = 'claims'
    base_path = "/queues/%(queue_name)s/claims"
    service = message_service.MessageService()

    # capabilities
    allow_create = True
    allow_list = False
    allow_retrieve = False
    allow_delete = False

    #: A UUID for each client instance. The UUID must be submitted in its
    #: canonical form (for example, 3381af92-2b9e-11e3-b191-71861300734c).
    #: The client generates this UUID once. The client UUID persists between
    #: restarts of the client so the client should reuse that same UUID.
    #: All message-related operations require the use of the client UUID in
    #: the headers to ensure that messages are not echoed back to the client
    #: that posted them, unless the client explicitly requests this.
    client = None

    #: The queue this Claim belongs to.
    queue = None

    #: Specifies the number of Messages to return.
    limit = None

    #: Specifies how long the server waits before releasing the claim,
    #: in seconds.
    ttl = resource.prop("ttl")

    #: Specifies the message grace period, in seconds.
    grace = resource.prop("grace")

    @classmethod
    def claim_messages(cls, session, claim):
        """Create a remote resource from this instance."""
        url = cls._get_url({'queue_name': claim.queue})
        headers = {'Client-ID': claim.client}
        params = {'limit': claim.limit} if claim.limit else None

        resp = session.post(url,
                            service=cls.service,
                            headers=headers,
                            data=json.dumps(claim, cls=ClaimEncoder),
                            params=params)

        for message_attrs in resp.body:
            yield message.Message.new(client=claim.client,
                                      queue=claim.queue,
                                      **message_attrs)
예제 #8
0
class Queue(resource.Resource):
    id_attribute = 'name'
    resources_key = 'queues'
    base_path = '/queues'
    service = message_service.MessageService()

    # capabilities
    allow_create = True
    allow_list = False
    allow_retrieve = False
    allow_delete = True

    @classmethod
    def create_by_id(cls, session, attrs, resource_id=None, path_args=None):
        url = cls._get_url(path_args, resource_id)
        session.put(url, service=cls.service, accept=None)
        return {cls.id_attribute: resource_id}
예제 #9
0
class Queue(resource2.Resource):
    # FIXME(anyone): The name string of `location` field of Zaqar API response
    # is lower case. That is inconsistent with the guide from API-WG. This is
    # a workaround for this issue.
    location = resource2.Header("location")

    resources_key = "queues"
    base_path = "/queues"
    service = message_service.MessageService()

    # capabilities
    allow_create = True
    allow_list = True
    allow_get = True
    allow_delete = True

    # Properties
    #: The default TTL of messages defined for a queue, which will effect for
    #: any messages posted to the queue.
    default_message_ttl = resource2.Body("_default_message_ttl")
    #: Description of the queue.
    description = resource2.Body("description")
    #: The max post size of messages defined for a queue, which will effect
    #: for any messages posted to the queue.
    max_messages_post_size = resource2.Body("_max_messages_post_size")
    #: Name of the queue. The name is the unique identity of a queue. It
    #: must not exceed 64 bytes in length, and it is limited to US-ASCII
    #: letters, digits, underscores, and hyphens.
    name = resource2.Body("name", alternate_id=True)
    #: The ID to identify the client accessing Zaqar API. Must be specified
    #: in header for each API request.
    client_id = resource2.Header("Client-ID")
    #: The ID to identify the project accessing Zaqar API. Must be specified
    #: in case keystone auth is not enabled in Zaqar service.
    project_id = resource2.Header("X-PROJECT-ID")

    def create(self, session, prepend_key=True):
        request = self._prepare_request(requires_id=True,
                                        prepend_key=prepend_key)
        headers = {
            "Client-ID": self.client_id or str(uuid.uuid4()),
            "X-PROJECT-ID": self.project_id or session.get_project_id()
        }
        request.headers.update(headers)
        response = session.put(request.url,
                               json=request.body,
                               headers=request.headers)

        self._translate_response(response, has_body=False)
        return self

    @classmethod
    def list(cls, session, paginated=False, **params):
        """This method is a generator which yields queue objects.

        This is almost the copy of list method of resource2.Resource class.
        The only difference is the request header now includes `Client-ID`
        and `X-PROJECT-ID` fields which are required by Zaqar v2 API.
        """
        more_data = True
        query_params = cls._query_mapping._transpose(params)
        uri = cls.base_path % params
        headers = {
            "Client-ID":
            params.get('client_id', None) or str(uuid.uuid4()),
            "X-PROJECT-ID":
            params.get('project_id', None) or session.get_project_id()
        }

        while more_data:
            resp = session.get(uri, headers=headers, params=query_params)
            resp = resp.json()
            resp = resp[cls.resources_key]

            if not resp:
                more_data = False

            yielded = 0
            new_marker = None
            for data in resp:
                value = cls.existing(**data)
                new_marker = value.id
                yielded += 1
                yield value

            if not paginated:
                return
            if "limit" in query_params and yielded < query_params["limit"]:
                return
            query_params["limit"] = yielded
            query_params["marker"] = new_marker

    def get(self, session, requires_id=True):
        request = self._prepare_request(requires_id=requires_id)
        headers = {
            "Client-ID": self.client_id or str(uuid.uuid4()),
            "X-PROJECT-ID": self.project_id or session.get_project_id()
        }
        request.headers.update(headers)
        response = session.get(request.url, headers=headers)
        self._translate_response(response)

        return self

    def delete(self, session):
        request = self._prepare_request()
        headers = {
            "Client-ID": self.client_id or str(uuid.uuid4()),
            "X-PROJECT-ID": self.project_id or session.get_project_id()
        }
        request.headers.update(headers)
        response = session.delete(request.url, headers=headers)

        self._translate_response(response, has_body=False)
        return self
예제 #10
0
class Claim(resource.Resource):
    # FIXME(anyone): The name string of `location` field of Zaqar API response
    # is lower case. That is inconsistent with the guide from API-WG. This is
    # a workaround for this issue.
    location = resource.Header("location")

    resources_key = 'claims'
    base_path = '/queues/%(queue_name)s/claims'
    service = message_service.MessageService()

    # capabilities
    allow_create = True
    allow_fetch = True
    allow_commit = True
    allow_delete = True
    commit_method = 'PATCH'

    # Properties
    #: The value in seconds indicating how long the claim has existed.
    age = resource.Body("age")
    #: In case worker stops responding for a long time, the server will
    #: extend the lifetime of claimed messages to be at least as long as
    #: the lifetime of the claim itself, plus the specified grace period.
    #: Must between 60 and 43200 seconds(12 hours).
    grace = resource.Body("grace")
    #: The number of messages to claim. Default 10, up to 20.
    limit = resource.Body("limit")
    #: Messages have been successfully claimed.
    messages = resource.Body("messages")
    #: Number of seconds the server wait before releasing the claim. Must
    #: between 60 and 43200 seconds(12 hours).
    ttl = resource.Body("ttl")
    #: The name of queue to claim message from.
    queue_name = resource.URI("queue_name")
    #: The ID to identify the client accessing Zaqar API. Must be specified
    #: in header for each API request.
    client_id = resource.Header("Client-ID")
    #: The ID to identify the project. Must be provided when keystone
    #: authentication is not enabled in Zaqar service.
    project_id = resource.Header("X-PROJECT-ID")

    def _translate_response(self, response, has_body=True):
        super(Claim, self)._translate_response(response, has_body=has_body)
        if has_body and self.location:
            # Extract claim ID from location
            self.id = self.location.split("claims/")[1]

    def create(self, session, prepend_key=False):
        request = self._prepare_request(requires_id=False,
                                        prepend_key=prepend_key)
        headers = {
            "Client-ID": self.client_id or str(uuid.uuid4()),
            "X-PROJECT-ID": self.project_id or session.get_project_id()
        }
        request.headers.update(headers)
        response = session.post(request.url,
                                json=request.body,
                                headers=request.headers)

        # For case no message was claimed successfully, 204 No Content
        # message will be returned. In other cases, we translate response
        # body which has `messages` field(list) included.
        if response.status_code != 204:
            self._translate_response(response)

        return self

    def fetch(self, session, requires_id=True, error_message=None):
        request = self._prepare_request(requires_id=requires_id)
        headers = {
            "Client-ID": self.client_id or str(uuid.uuid4()),
            "X-PROJECT-ID": self.project_id or session.get_project_id()
        }

        request.headers.update(headers)
        response = session.get(request.url, headers=request.headers)
        self._translate_response(response)

        return self

    def commit(self, session, prepend_key=False, has_body=False):
        request = self._prepare_request(prepend_key=prepend_key)
        headers = {
            "Client-ID": self.client_id or str(uuid.uuid4()),
            "X-PROJECT-ID": self.project_id or session.get_project_id()
        }

        request.headers.update(headers)
        session.patch(request.url, json=request.body, headers=request.headers)

        return self

    def delete(self, session):
        request = self._prepare_request()
        headers = {
            "Client-ID": self.client_id or str(uuid.uuid4()),
            "X-PROJECT-ID": self.project_id or session.get_project_id()
        }

        request.headers.update(headers)
        response = session.delete(request.url, headers=request.headers)

        self._translate_response(response, has_body=False)
        return self
예제 #11
0
class Claim(resource.Resource):
    resources_key = 'claims'
    base_path = "/queues/%(queue_name)s/claims"
    service = message_service.MessageService()

    # capabilities
    allow_create = True
    allow_list = False
    allow_retrieve = False
    allow_delete = False

    #: A UUID for each client instance. The UUID must be submitted in its
    #: canonical form (for example, 3381af92-2b9e-11e3-b191-71861300734c).
    #: The client generates this UUID once. The client UUID persists between
    #: restarts of the client so the client should reuse that same UUID.
    #: All message-related operations require the use of the client UUID in
    #: the headers to ensure that messages are not echoed back to the client
    #: that posted them, unless the client explicitly requests this.
    client = None

    #: The queue this Claim belongs to.
    queue = None

    #: Specifies the number of Messages to return.
    limit = None

    #: Specifies how long the server waits before releasing the claim,
    #: in seconds.
    ttl = resource.prop("ttl")

    #: Specifies the message grace period, in seconds.
    grace = resource.prop("grace")

    @classmethod
    def claim_messages(cls, session, claim):
        """Create a remote resource from this instance."""
        url = cls._get_url({'queue_name': claim.queue})
        headers = {'Client-ID': claim.client}
        params = {'limit': claim.limit} if claim.limit else None
        body = []

        try:
            resp = session.post(url,
                                service=cls.service,
                                headers=headers,
                                data=json.dumps(claim, cls=ClaimEncoder),
                                params=params)
            body = resp.body
        except exceptions.InvalidResponse as e:
            # The Message Service will respond with a 204 and no content in
            # the body when there are no messages to claim. The transport
            # layer doesn't like that and we have to correct for it here.
            # Ultimately it's a bug in the v1.0 Message Service API.
            # TODO(etoews): API is fixed in v1.1 so fix this for message.v1_1
            # https://wiki.openstack.org/wiki/Zaqar/specs/api/v1.1
            if e.response.status_code != 204:
                raise e

        for message_attrs in body:
            yield message.Message.new(client=claim.client,
                                      queue=claim.queue,
                                      **message_attrs)
예제 #12
0
class Subscription(resource2.Resource):
    # FIXME(anyone): The name string of `location` field of Zaqar API response
    # is lower case. That is inconsistent with the guide from API-WG. This is
    # a workaround for this issue.
    location = resource2.Header("location")

    resources_key = 'subscriptions'
    base_path = '/queues/%(queue_name)s/subscriptions'
    service = message_service.MessageService()

    # capabilities
    allow_create = True
    allow_list = True
    allow_get = True
    allow_delete = True

    # Properties
    #: The value in seconds indicating how long the subscription has existed.
    age = resource2.Body("age")
    #: Alternate id of the subscription. This key is used in response of
    #: subscription create API to return id of subscription created.
    subscription_id = resource2.Body("subscription_id", alternate_id=True)
    #: The extra metadata for the subscription. The value must be a dict.
    #: If the subscriber is `mailto`. The options can contain `from` and
    #: `subject` to indicate the email's author and title.
    options = resource2.Body("options", type=dict)
    #: The queue name which the subscription is registered on.
    source = resource2.Body("source")
    #: The destination of the message. Two kinds of subscribers are supported:
    #: http/https and email. The http/https subscriber should start with
    #: `http/https`. The email subscriber should start with `mailto`.
    subscriber = resource2.Body("subscriber")
    #: Number of seconds the subscription remains alive? The ttl value must
    #: be great than 60 seconds. The default value is 3600 seconds.
    ttl = resource2.Body("ttl")
    #: The queue name which the subscription is registered on.
    queue_name = resource2.URI("queue_name")
    #: The ID to identify the client accessing Zaqar API. Must be specified
    #: in header for each API request.
    client_id = resource2.Header("Client-ID")
    #: The ID to identify the project. Must be provided when keystone
    #: authentication is not enabled in Zaqar service.
    project_id = resource2.Header("X-PROJECT-ID")

    def create(self, session, prepend_key=True):
        request = self._prepare_request(requires_id=False,
                                        prepend_key=prepend_key)
        headers = {
            "Client-ID": self.client_id or str(uuid.uuid4()),
            "X-PROJECT-ID": self.project_id or session.get_project_id()
        }
        request.headers.update(headers)
        response = session.post(request.uri, endpoint_filter=self.service,
                                json=request.body, headers=request.headers)

        self._translate_response(response)
        return self

    @classmethod
    def list(cls, session, paginated=True, **params):
        """This method is a generator which yields subscription objects.

        This is almost the copy of list method of resource2.Resource class.
        The only difference is the request header now includes `Client-ID`
        and `X-PROJECT-ID` fields which are required by Zaqar v2 API.
        """
        more_data = True
        uri = cls.base_path % params
        headers = {
            "Client-ID": params.get('client_id', None) or str(uuid.uuid4()),
            "X-PROJECT-ID": params.get('project_id', None
                                       ) or session.get_project_id()
        }

        query_params = cls._query_mapping._transpose(params)
        while more_data:
            resp = session.get(uri, endpoint_filter=cls.service,
                               headers=headers, params=query_params)
            resp = resp.json()
            resp = resp[cls.resources_key]

            if not resp:
                more_data = False

            yielded = 0
            new_marker = None
            for data in resp:
                value = cls.existing(**data)
                new_marker = value.id
                yielded += 1
                yield value

            if not paginated:
                return
            if "limit" in query_params and yielded < query_params["limit"]:
                return
            query_params["limit"] = yielded
            query_params["marker"] = new_marker

    def get(self, session, requires_id=True):
        request = self._prepare_request(requires_id=requires_id)
        headers = {
            "Client-ID": self.client_id or str(uuid.uuid4()),
            "X-PROJECT-ID": self.project_id or session.get_project_id()
        }

        request.headers.update(headers)
        response = session.get(request.uri, endpoint_filter=self.service,
                               headers=request.headers)
        self._translate_response(response)

        return self

    def delete(self, session):
        request = self._prepare_request()
        headers = {
            "Client-ID": self.client_id or str(uuid.uuid4()),
            "X-PROJECT-ID": self.project_id or session.get_project_id()
        }

        request.headers.update(headers)
        response = session.delete(request.uri, endpoint_filter=self.service,
                                  headers=request.headers)

        self._translate_response(response, has_body=False)
        return self
예제 #13
0
class Message(resource2.Resource):
    # FIXME(anyone): The name string of `location` field of Zaqar API response
    # is lower case. That is inconsistent with the guide from API-WG. This is
    # a workaround for this issue.
    location = resource2.Header("location")

    resources_key = 'messages'
    base_path = '/queues/%(queue_name)s/messages'
    service = message_service.MessageService()

    # capabilities
    allow_create = True
    allow_list = True
    allow_get = True
    allow_delete = True

    _query_mapping = resource2.QueryParameters("echo", "include_claimed")

    # Properties
    #: The value in second to specify how long the message has been
    #: posted to the queue.
    age = resource2.Body("age")
    #: A dictionary specifies an arbitrary document that constitutes the
    #: body of the message being sent.
    body = resource2.Body("body")
    #: An uri string describe the location of the message resource.
    href = resource2.Body("href")
    #: The value in seconds to specify how long the server waits before
    #: marking the message as expired and removing it from the queue.
    ttl = resource2.Body("ttl")
    #: The name of target queue message is post to or got from.
    queue_name = resource2.URI("queue_name")
    #: The ID to identify the client accessing Zaqar API. Must be specified
    #: in header for each API request.
    client_id = resource2.Header("Client-ID")
    #: The ID to identify the project accessing Zaqar API. Must be specified
    #: in case keystone auth is not enabled in Zaqar service.
    project_id = resource2.Header("X-PROJECT-ID")

    def post(self, session, messages):
        request = self._prepare_request(requires_id=False, prepend_key=True)
        headers = {
            "Client-ID": self.client_id or str(uuid.uuid4()),
            "X-PROJECT-ID": self.project_id or session.get_project_id()
        }
        request.headers.update(headers)
        request.body = {'messages': messages}
        response = session.post(request.url,
                                json=request.body,
                                headers=request.headers)

        return response.json()['resources']

    @classmethod
    def list(cls, session, paginated=True, **params):
        """This method is a generator which yields message objects.

        This is almost the copy of list method of resource2.Resource class.
        The only difference is the request header now includes `Client-ID`
        and `X-PROJECT-ID` fields which are required by Zaqar v2 API.
        """
        more_data = True
        uri = cls.base_path % params
        headers = {
            "Client-ID":
            params.get('client_id', None) or str(uuid.uuid4()),
            "X-PROJECT-ID":
            params.get('project_id', None) or session.get_project_id()
        }

        query_params = cls._query_mapping._transpose(params)
        while more_data:
            resp = session.get(uri, headers=headers, params=query_params)
            resp = resp.json()
            resp = resp[cls.resources_key]

            if not resp:
                more_data = False

            yielded = 0
            new_marker = None
            for data in resp:
                value = cls.existing(**data)
                new_marker = value.id
                yielded += 1
                yield value

            if not paginated:
                return
            if "limit" in query_params and yielded < query_params["limit"]:
                return
            query_params["limit"] = yielded
            query_params["marker"] = new_marker

    def get(self, session, requires_id=True):
        request = self._prepare_request(requires_id=requires_id)
        headers = {
            "Client-ID": self.client_id or str(uuid.uuid4()),
            "X-PROJECT-ID": self.project_id or session.get_project_id()
        }

        request.headers.update(headers)
        response = session.get(request.url, headers=headers)
        self._translate_response(response)

        return self

    def delete(self, session):
        request = self._prepare_request()
        headers = {
            "Client-ID": self.client_id or str(uuid.uuid4()),
            "X-PROJECT-ID": self.project_id or session.get_project_id()
        }

        request.headers.update(headers)
        # For Zaqar v2 API requires client to specify claim_id as query
        # parameter when deleting a message that has been claimed, we
        # rebuild the request URI if claim_id is not None.
        if self.claim_id:
            request.url += '?claim_id=%s' % self.claim_id
        response = session.delete(request.url, headers=headers)

        self._translate_response(response, has_body=False)
        return self
예제 #14
0
class Message(resource.Resource):
    resources_key = 'messages'
    base_path = "/queues/%(queue_name)s/messages"
    service = message_service.MessageService()

    # capabilities
    allow_create = True
    allow_list = False
    allow_retrieve = False
    allow_delete = False

    #: A UUID for each client instance. The UUID must be submitted in its
    #: canonical form (for example, 3381af92-2b9e-11e3-b191-71861300734c).
    #: The client generates this UUID once. The client UUID persists between
    #: restarts of the client so the client should reuse that same UUID.
    #: All message-related operations require the use of the client UUID in
    #: the headers to ensure that messages are not echoed back to the client
    #: that posted them, unless the client explicitly requests this.
    client = None

    #: The queue this Message belongs to.
    queue = None

    #: A relative href that references this Message.
    href = resource.prop("href")

    #: An arbitrary JSON document that constitutes the body of the message
    #: being sent.
    body = resource.prop("body")

    #: Specifies how long the server waits, in seconds, before marking the
    #: message as expired and removing it from the queue.
    ttl = resource.prop("ttl")

    #: Specifies how long the message has been in the queue, in seconds.
    age = resource.prop("age")

    @classmethod
    def create_messages(cls, session, messages):
        if len(messages) == 0:
            raise ValueError('messages cannot be empty')

        for i, message in enumerate(messages, -1):
            if message.queue != messages[i].queue:
                raise ValueError('All queues in messages must be equal')
            if message.client != messages[i].client:
                raise ValueError('All clients in messages must be equal')

        url = cls._get_url({'queue_name': messages[0].queue})
        headers = {'Client-ID': messages[0].client}

        resp = session.post(url,
                            service=cls.service,
                            headers=headers,
                            data=json.dumps(messages, cls=MessageEncoder))

        messages_created = []
        hrefs = resp.body['resources']

        for i, href in enumerate(hrefs):
            message = Message.existing(**messages[i])
            message.href = href
            messages_created.append(message)

        return messages_created

    @classmethod
    def _strip_version(cls, href):
        path = parse.urlparse(href).path

        if path.startswith('/v'):
            return href[href.find('/', 1):]
        else:
            return href

    @classmethod
    def delete_by_id(cls, session, message, path_args=None):
        url = cls._strip_version(message.href)
        headers = {'Client-ID': message.client}

        session.delete(url, service=cls.service, headers=headers, accept=None)
예제 #15
0
class ServicesMixin(object):

    identity = identity_service.IdentityService(service_type='identity')

    compute = compute_service.ComputeService(service_type='compute')

    image = image_service.ImageService(service_type='image')

    load_balancer = load_balancer_service.LoadBalancerService(
        service_type='load-balancer')

    object_store = object_store_service.ObjectStoreService(
        service_type='object-store')

    clustering = clustering_service.ClusteringService(
        service_type='clustering')
    resource_cluster = clustering
    cluster = clustering

    data_processing = service_description.ServiceDescription(
        service_type='data-processing')

    baremetal = baremetal_service.BaremetalService(service_type='baremetal')
    bare_metal = baremetal

    baremetal_introspection = baremetal_introspection_service.BaremetalIntrospectionService(
        service_type='baremetal-introspection')

    key_manager = key_manager_service.KeyManagerService(
        service_type='key-manager')

    resource_optimization = service_description.ServiceDescription(
        service_type='resource-optimization')
    infra_optim = resource_optimization

    message = message_service.MessageService(service_type='message')
    messaging = message

    application_catalog = service_description.ServiceDescription(
        service_type='application-catalog')

    container_infrastructure_management = service_description.ServiceDescription(
        service_type='container-infrastructure-management')
    container_infrastructure = container_infrastructure_management
    container_infra = container_infrastructure_management

    search = service_description.ServiceDescription(service_type='search')

    dns = dns_service.DnsService(service_type='dns')

    workflow = workflow_service.WorkflowService(service_type='workflow')

    rating = service_description.ServiceDescription(service_type='rating')

    operator_policy = service_description.ServiceDescription(
        service_type='operator-policy')
    policy = operator_policy

    shared_file_system = service_description.ServiceDescription(
        service_type='shared-file-system')
    share = shared_file_system

    data_protection_orchestration = service_description.ServiceDescription(
        service_type='data-protection-orchestration')

    orchestration = orchestration_service.OrchestrationService(
        service_type='orchestration')

    block_storage = block_storage_service.BlockStorageService(
        service_type='block-storage')
    block_store = block_storage
    volume = block_storage

    alarm = service_description.ServiceDescription(service_type='alarm')
    alarming = alarm

    meter = service_description.ServiceDescription(service_type='meter')
    metering = meter
    telemetry = meter

    event = service_description.ServiceDescription(service_type='event')
    events = event

    application_deployment = service_description.ServiceDescription(
        service_type='application-deployment')
    application_deployment = application_deployment

    multi_region_network_automation = service_description.ServiceDescription(
        service_type='multi-region-network-automation')
    tricircle = multi_region_network_automation

    database = database_service.DatabaseService(service_type='database')

    application_container = service_description.ServiceDescription(
        service_type='application-container')
    container = application_container

    root_cause_analysis = service_description.ServiceDescription(
        service_type='root-cause-analysis')
    rca = root_cause_analysis

    nfv_orchestration = service_description.ServiceDescription(
        service_type='nfv-orchestration')

    network = network_service.NetworkService(service_type='network')

    backup = service_description.ServiceDescription(service_type='backup')

    monitoring_logging = service_description.ServiceDescription(
        service_type='monitoring-logging')
    monitoring_log_api = monitoring_logging

    monitoring = service_description.ServiceDescription(
        service_type='monitoring')

    monitoring_events = service_description.ServiceDescription(
        service_type='monitoring-events')

    placement = service_description.ServiceDescription(
        service_type='placement')

    instance_ha = instance_ha_service.InstanceHaService(
        service_type='instance-ha')
    ha = instance_ha

    reservation = service_description.ServiceDescription(
        service_type='reservation')

    function_engine = service_description.ServiceDescription(
        service_type='function-engine')

    accelerator = accelerator_service.AcceleratorService(
        service_type='accelerator')

    admin_logic = service_description.ServiceDescription(
        service_type='admin-logic')
    registration = admin_logic