~gandelman-a/ubuntu/precise/nova/UCA_2012.2.1

« back to all changes in this revision

Viewing changes to nova/rpc/dispatcher.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short, Chuck Short, Adam Gandelman
  • Date: 2012-06-22 12:39:57 UTC
  • mfrom: (1.1.57)
  • Revision ID: package-import@ubuntu.com-20120622123957-hbzwg84nt9rqwg8r
Tags: 2012.2~f2~20120621.14517-0ubuntu1
[ Chuck Short ]
* New upstream version.

[ Adam Gandelman ]
* debian/rules: Temporarily disable test suite while blocking
  tests are investigated. 
* debian/patches/kombu_tests_timeout.patch: Dropped.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
 
 
3
 
# Copyright 2012 Red Hat, Inc.
4
 
#
5
 
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
6
 
#    not use this file except in compliance with the License. You may obtain
7
 
#    a copy of the License at
8
 
#
9
 
#         http://www.apache.org/licenses/LICENSE-2.0
10
 
#
11
 
#    Unless required by applicable law or agreed to in writing, software
12
 
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
 
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
 
#    License for the specific language governing permissions and limitations
15
 
#    under the License.
16
 
 
17
 
"""
18
 
Code for rpc message dispatching.
19
 
 
20
 
Messages that come in have a version number associated with them.  RPC API
21
 
version numbers are in the form:
22
 
 
23
 
    Major.Minor
24
 
 
25
 
For a given message with version X.Y, the receiver must be marked as able to
26
 
handle messages of version A.B, where:
27
 
 
28
 
    A = X
29
 
 
30
 
    B >= Y
31
 
 
32
 
The Major version number would be incremented for an almost completely new API.
33
 
The Minor version number would be incremented for backwards compatible changes
34
 
to an existing API.  A backwards compatible change could be something like
35
 
adding a new method, adding an argument to an existing method (but not
36
 
requiring it), or changing the type for an existing argument (but still
37
 
handling the old type as well).
38
 
 
39
 
The conversion over to a versioned API must be done on both the client side and
40
 
server side of the API at the same time.  However, as the code stands today,
41
 
there can be both versioned and unversioned APIs implemented in the same code
42
 
base.
43
 
"""
44
 
 
45
 
from nova.rpc import common as rpc_common
46
 
 
47
 
 
48
 
class RpcDispatcher(object):
49
 
    """Dispatch rpc messages according to the requested API version.
50
 
 
51
 
    This class can be used as the top level 'manager' for a service.  It
52
 
    contains a list of underlying managers that have an API_VERSION attribute.
53
 
    """
54
 
 
55
 
    def __init__(self, callbacks):
56
 
        """Initialize the rpc dispatcher.
57
 
 
58
 
        :param callbacks: List of proxy objects that are an instance
59
 
                          of a class with rpc methods exposed.  Each proxy
60
 
                          object should have an RPC_API_VERSION attribute.
61
 
        """
62
 
        self.callbacks = callbacks
63
 
        super(RpcDispatcher, self).__init__()
64
 
 
65
 
    @staticmethod
66
 
    def _is_compatible(mversion, version):
67
 
        """Determine whether versions are compatible.
68
 
 
69
 
        :param mversion: The API version implemented by a callback.
70
 
        :param version: The API version requested by an incoming message.
71
 
        """
72
 
        version_parts = version.split('.')
73
 
        mversion_parts = mversion.split('.')
74
 
        if int(version_parts[0]) != int(mversion_parts[0]):  # Major
75
 
            return False
76
 
        if int(version_parts[1]) > int(mversion_parts[1]):  # Minor
77
 
            return False
78
 
        return True
79
 
 
80
 
    def dispatch(self, ctxt, version, method, **kwargs):
81
 
        """Dispatch a message based on a requested version.
82
 
 
83
 
        :param ctxt: The request context
84
 
        :param version: The requested API version from the incoming message
85
 
        :param method: The method requested to be called by the incoming
86
 
                       message.
87
 
        :param kwargs: A dict of keyword arguments to be passed to the method.
88
 
 
89
 
        :returns: Whatever is returned by the underlying method that gets
90
 
                  called.
91
 
        """
92
 
        if not version:
93
 
            version = '1.0'
94
 
 
95
 
        for proxyobj in self.callbacks:
96
 
            if hasattr(proxyobj, 'RPC_API_VERSION'):
97
 
                rpc_api_version = proxyobj.RPC_API_VERSION
98
 
            else:
99
 
                rpc_api_version = '1.0'
100
 
            if not hasattr(proxyobj, method):
101
 
                continue
102
 
            if self._is_compatible(rpc_api_version, version):
103
 
                return getattr(proxyobj, method)(ctxt, **kwargs)
104
 
 
105
 
        raise rpc_common.UnsupportedRpcVersion(version=version)