1
2# Copyright 2013 Red Hat, Inc.
3#
4#    Licensed under the Apache License, Version 2.0 (the "License"); you may
5#    not use this file except in compliance with the License. You may obtain
6#    a copy of the License at
7#
8#         http://www.apache.org/licenses/LICENSE-2.0
9#
10#    Unless required by applicable law or agreed to in writing, software
11#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13#    License for the specific language governing permissions and limitations
14#    under the License.
15
16
17class Target(object):
18
19    """Identifies the destination of messages.
20
21    A Target encapsulates all the information to identify where a message
22    should be sent or what messages a server is listening for.
23
24    Different subsets of the information encapsulated in a Target object is
25    relevant to various aspects of the API:
26
27      an RPC Server's target:
28        topic and server is required; exchange is optional
29      an RPC endpoint's target:
30        namespace and version is optional
31      an RPC client sending a message:
32        topic is required, all other attributes optional
33      a Notification Server's target:
34        topic is required, exchange is optional; all other attributes ignored
35      a Notifier's target:
36        topic is required, exchange is optional; all other attributes ignored
37
38    Its attributes are:
39
40    :param exchange: A scope for topics. Leave unspecified to default to the
41      control_exchange configuration option.
42    :type exchange: str
43    :param topic: A name which identifies the set of interfaces exposed by a
44      server. Multiple servers may listen on a topic and messages will be
45      dispatched to one of the servers selected in a best-effort round-robin
46      fashion (unless fanout is ``True``).
47    :type topic: str
48    :param namespace: Identifies a particular RPC interface (i.e. set of
49      methods) exposed by a server. The default interface has no namespace
50      identifier and is referred to as the null namespace.
51    :type namespace: str
52    :param version: RPC interfaces have a major.minor version number associated
53      with them. A minor number increment indicates a backwards compatible
54      change and an incompatible change is indicated by a major number bump.
55      Servers may implement multiple major versions and clients may require
56      indicate that their message requires a particular minimum minor version.
57    :type version: str
58    :param server: RPC Clients can request that a message be directed to a
59      specific server, rather than just one of a pool of servers listening on
60      the topic.
61    :type server: str
62    :param fanout: Clients may request that a copy of the message be delivered
63      to all servers listening on a topic by setting fanout to ``True``, rather
64      than just one of them.
65    :type fanout: bool
66    :param legacy_namespaces: A server always accepts messages specified via
67      the 'namespace' parameter, and may also accept messages defined via
68      this parameter. This option should be used to switch namespaces safely
69      during rolling upgrades.
70    :type legacy_namespaces: list of strings
71    """
72
73    def __init__(self, exchange=None, topic=None, namespace=None,
74                 version=None, server=None, fanout=None,
75                 legacy_namespaces=None):
76        self.exchange = exchange
77        self.topic = topic
78        self.namespace = namespace
79        self.version = version
80        self.server = server
81        self.fanout = fanout
82        self.accepted_namespaces = [namespace] + (legacy_namespaces or [])
83
84    def __call__(self, **kwargs):
85        for a in ('exchange', 'topic', 'namespace',
86                  'version', 'server', 'fanout'):
87            kwargs.setdefault(a, getattr(self, a))
88        return Target(**kwargs)
89
90    def __eq__(self, other):
91        return vars(self) == vars(other)
92
93    def __ne__(self, other):
94        return not self == other
95
96    def __repr__(self):
97        attrs = []
98        for a in ['exchange', 'topic', 'namespace',
99                  'version', 'server', 'fanout']:
100            v = getattr(self, a)
101            if v:
102                attrs.append((a, v))
103        values = ', '.join(['%s=%s' % i for i in attrs])
104        return '<Target ' + values + '>'
105
106    def __hash__(self):
107        return id(self)
108